Custom nRF52832 board pinout

is it possible to modify nRF52-DK pinout in Arduino framework so that it matches my custom-board design, instead of the original DK? For example, the original DK has UART RX and TX dedicated at pins 12 and 13, while my board has them on 22, 23. Would love to be able to change that?
Could it maybe be done in the special UART class?


I’ve done this for some SAMD21 custom boards I made from adaptor boards and the 32 pin version of the chip (see project in Github ) which has a different pinout than the Arduino boards with that chip (as they use the 48 pin version).

Have a look at the “boards” and the “variants” directories of the project:

  • You need to add a local board definition inside “boards” which for you should contain the same as the original definition from a board with the same chip in PlatformIO with your own “variant” name and the addition of a “variants_dir” entry that point as the “variants” directory in your project.
  • You need to copy over the “variants” directory of the board with that chip in PlatformIO to your project “variants” directory, rename it to whatever variant name you choose to use and then change the pins configuration (for the SAMD chips that was mostly changing what’s inside “variant.cpp”, but the structure of this might be slightly different in the Arduino Core that supports the nRF52832)

The code inside the existing variant should be self-explanatory and since you’re just changing a small number of pins the complexity of that change should be a lot less than it was for me (as I effectivelly had to create an entirely new mapping to fit a chip with a different number of pins), especially if all you do is swap the existing definitions in 22 and 23 for the ones in 12 and 13. Make sure that the pin capabilities in the new pin definitions correctly matches what the pins can do and that the places where the TX and RX ping are linked to the Serial object in Arduino ( they might be #defines in one of the include files or explicitly done inside variant.cpp ) are also updated.

For me a large part of the complexity of the task was figuring out how to get the configuration right for PlatformIO, so hopefully the example of my project can flatten that part of the work for you.

1 Like

Hey, thanks for the explanation! Your cool project is really helping in understanding the process.

So I guess I need to dig into the backbone of platformio instead of just defining class like
Uart serial(22,23); which I was hoping to get.

I guess it’s simmilar like in the nrf sdk examples.

Now, where do I find original board and variants folders? How can I make sure that Platformio uses my modified files instead of the original ones?

Well, the backbone of PlatformIO is really just the boards definition file and how you convince it to pick up variant information from your directory, and the technique for that you can pick up from my project as I’ve already went through the pain of figuring it out so hopefully you need not :slight_smile:

The bit were I expect you will have to do a bit of work is the pin definitions inside the variant directory and all that stuff comes from Arduino itself as it’s the way microcontroller pins are mapped to Arduino pins to make up the “board” - Arduino pins are a pretty arbitrary assignment of numbers to microcontroller pins and if you look at my project you can see that they need not even match the hardware board pins.

Only two big things matter in the making of the pins definition:

  1. You correctly match the port and port bit with the characteristics of a pin (i.e. indicating if the pin with that port and port bit can it be a timer output for PWM, does an ADC connect to it for analogRead and so on)
  2. In the peripheral’s definitions (Serial, I2C, SPI) as well as in the formula that identifies analog pins, you need to make sure you match the right Arduino pin number to the correct defines or initialization (i.e. where the TX and RX pins of Serial are defined/set they must match the Arduino pin numbers you gave them when defining the PinDescriptions array).

In your case you probably can copy the existing stuff and just switch a few things around, check in there that Serial uses the right pins and possibly make sure that the formula that converts analog ids to arduino pin ids (in the SAMD Arduino Core used in my project that’s analogInputToDigitalPin(), defined in variant.h) is still doing it correctly.

PS: The original boards file would be inside the PlatformIO platforms directory for your platform, which for example in Windows is in “c:\Users\<yourwindowsuser>\.platformio\platforms”, probably the “platform-nordicnrf52” subdirectory: there’s a “boards” directory there.

The variants data should be under the PlatformIO packages dir (i.e. “c:\Users\<yourwindowsuser>\.platformio\packages”) under the arduino dir for the core used by that processor (maybe “arduino-nRF5”???) which should have a “variants” directory there and you’ll find the files inside the subdirectory of it for the board you want to clone.

As for getting PlatformIO to pick up your stuff, merelly put your board definition file in a “boards” subdirectory of your project and used the file name (minus “.json”) as the board name in your platformio.ini and it will pick the rest up from there (remember that in the board definition file you add a “variants_dir” parameter, and this is how PlatformIO knows where to find the variant directory for your custom board).

PPS: So I had a look some variants definitions in the source code for the nrf52 Arduino core and the pins definition in that looks spectacularly simpler than for the SAMD core. You probably might only need to change the defines for PIN_SERIAL_RX and PIN_SERIAL_TX in variant.h and that’s probably it. The SAMD Arduino pin definition stuff is way, way more complex.

1 Like

Hey man, thanks for the extensive explanation! I think I got i right:
I copied the board file I based my design on (nrf52_dk.json) into the “boards” folder of my PIO project. In it, I added a specific variant of the board, and specified “variants_dir” and as “variants” which is the folder I also created in the PIO project. In “variants” I created my custom board name folder and copied .cpp and .h files from the original variant. To wrap it up, the folder structure looks somewhat like this:

  - custom_board.json  // here is the "variant" = "my_variant", and "variant_dir" = "variants"

 - my_variant
     - pins_arduino.h
     - variant.h
     - variant.cpp

If I may add, it is also necessary to include variants folder in the build process by adding
build_flags = -I variants/my_variant into the platformio.ini

So, the compilation itself runs just fine, everything seems to be compiled nicely, but the build process ends in error. For some reason linker script fails, and it doesn’t display any error. Any idea what might be behind that?

Well, this is the bit I had hopped you would not have to go through.

You will probably need to run the “pio” build command from a command line (from powershell if you’re using PlatformIO from within Visual Studio Code), adding -v at the end to get a verbose output.

There should be some error message in there somewhere.

If it’s not self explanatory you’ll have to look around in the PlatformIO documentation for that platform to see if there are instructions there for adding custom board variants - you see the build process in PlatformIO is implemented inside each platform directory so it will not be the same for the one I made my own project for (samd) as it if for yours.

If you can’t fix the build from what’s in the verbose build output alone or the documentation for your platform, then you’ll have to look at the python build code for that platform, which should be under the “builder” subdirectory of that platform’s directory, I believe inside

In this I can’t really help you as I have no experience with those chips and that platform.

1 Like

Hey, thanks for still sticking around, trying to help!
I tried building in the command line shell. Unfortunately, and funny enough, error messages and no explanations still popping up.

What is funny, is that when I check my installled boards (pio boards --installed) I get to see my custom board in all of the platforms: in nordicnrf52, espressif8266, atmelavr and native. All these platforms for some reason list my custom board in there.

EDIT: Hey, I think I got it! Well, it seems that platformio prefers to have its variants in the original folder, that is C:\Users<user>.platformio\packages/… Only when I moved my “my_variant” folder there, did it finish the build without errors! Any thoughts why is that so?
BTW, the platformio docs about system directories mentions nothing about “variants_dir” that you used in your board.json file. How did you make it to search in your project directory?

Support of the board_build.variants_dir is builder-script dependent.

The builder scripts for NordicNRF52 + Arduino do not allow changing the variant directory. It is constantly pointed to the actual framework package’s variants directory.

This is in contrast to Atmel SAM + Arduino where build.variants_dir is used

And hence you observe that difference.

An issue about this has been opened in Support build.variants_dir · Issue #11 · platformio/builder-framework-arduino-nrf5 · GitHub.

Hey, thanks for clarification, and opening the issue!

Out of the curiosity, what is going to happen now? Is someone going to fix the issue?
Is it going to be eventaully updated in new PIO version, or something?

Genuinely asking, since I’ve no clue how big software projects like Platformio flow…

Well generally when issues are opened it should get fixed – the small change the issue is about should be trivial.

When GitHub - platformio/builder-framework-arduino-nrf5: Arduino (Nordic nRF5) build script for PlatformIO Build System is fixed, GitHub - platformio/platform-nordicnrf52: Nordic nRF52: development platform for PlatformIO will be updated to point at the new version of the first repo (see arduino @ ...). As soon as that is done users can already use the upstream version to get the feature.

Then some time later a new platform-nordicnrf52 release will be made (new stable version") which users can update to as normal through the PlatformIO Home → Platforms → Updates GUI or the CLI with pio platform update nordicnrf52.

1 Like

cool! thanks for the explanation.
Have a great day!

In fact I’ve opened PR Expand builder scripts to use build.variants_dir by maxgerhardt · Pull Request #12 · platformio/builder-framework-arduino-nrf5 · GitHub in an attempt to solve the problem.

Can you do the following:

  1. Edit your platformio.ini in regards to the platform = .. value to
platform =
  1. Add the instruction
board_build.variants_dir = custom_variants

to your platformio.ini.

  1. In your local project directory, create the folder custom_variants. In this folder, move your created board variant folder (my_variant) that is currently in the PlatformIO Arduino core package. Move your old my_variant folder from the core package to somewhere else (so that it definitely fails if it does not use your local variant)
  2. Attempt compilation.

EDIT: Had to correct a Python error, use CLI → pio platform update nordicnrf52 to update again.

The PR has already been merged so

platform =
; other options...
board_build.variants_dir = custom_variants

can already be used.

1 Like

Hey man, thanks for the effort. I tried what you said, and I am happy to confirm it worked like a charm. I have the variants defined only in my project directory, not in core_dir anymore. My platformio.ini is modified as you advised, and build finished with no errors. So, good job, my friend!

Question: I have “variants_dir” defined in my json manifest and in my platformio.ini. What to make of it? Is it redundant to have defined in both places?

EDIT: I have also tried with platform = nordicnrf52 instead of this long github link, and it also worked just fine. Ofc, I did that pio platform update command beforehand.

Hm this is probably working by-accident because GitHub - platformio/platform-nordicnrf52: Nordic nRF52: development platform for PlatformIO has not made a new stable release yet. Likely it’s using the git version obtained earlier. For now, platform = is the correct, portable way, until you see a new release after 9.0.0 at here.

The variants_dir is only valid / respected in the platformio.ini, not in the board’s JSON manifest. In the JSON manifest, the variant field is important.

Great to hear it works.

Good to see that it all ended well :fu:

Hello again,

unfortunately, I have to open the case one more time. Actually, I moved my framework from sandeepmistry’s to Adafruit’s following our discussion here, and this advices didn’t work anymore.

The build scripts do not recognize my custom board that is set according to the instructions here. (json manifest in the /boards, variants h/.cpp in the variants/my_variants directory).
The compilation only works with the native Adafruit board like adafruit_feather_nrf52832, and I changed my json and variant files according to it. Not even putting those into the PIO core directory make it work.

All of the errors I get in the build process are related to the Adafruit TinyUSB library, like this one:

C:\users\krivi\.platformio\packages\framework-arduinoadafruitnrf52\libraries\Adafruit_TinyUSB_Arduino\src\arduino/Adafruit_USBD_CDC.h:90:26: error: conflicting declaration 'Adafruit_USBD_CDC Serial'

Got any advice on how to solve this?

This should be the way to go, does it not run / upload if you treat your board as a adafruit_feather_nrf52832?

yes it, does, but we’re discussing custom boards here, and when I put time in the platformio.ini, it doesnt work anymore.

Please show the complete board JSON file, platformio.ini and code with which you’re testing.