Building my own board from Adafruit RP2040


I am looking into designing my own board but referencing the Adafruit Feather RP2040 design for starting. So far, I have the Adafruit board working w/platformio in vscode. I am using the earlephilhower platform (link) and was wondering if this platform will be able to support my own design since I am basing it off the Adafruit design?

Do I keep the same board name in my ini file for my own design? Right now, my board is the adafruit_feather because I am testing the Adafruit Feather RP2040, but later down the road it will be my board which does not have a name yet.

platform =
framework = arduino
monitor_speed = 115200
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m

board = adafruit_feather

Sure, why not. People add boards to the EarlePhilhower core all the time. All board definitions are conveniently auto generated, so you basically PR your change in that script plus the variant files that define the pins for your board. is a good PR to look at.

If you don’t yet have custom hardware though, try to stick with the boards that are already there.

This question also largely overlaps what has already been asked at

1 Like

Thanks for your feedback and the resources you’ve provided. I will look into this.

I do have a question about defining the pins on my board. For example, the datasheet for the RP2040 shows that all 30 of the pins can be connected to either SPI0 (SCK, TX, RX) or SPI1 (SCK, TX, RX). Are one of the files that needs to be included in the EarlePhilhower core supposed to configure the RP2040 to recognize that I want specific pin numbers as SPI pins?

The defines

// SPI
#define PIN_SPI0_MISO  (16u)
#define PIN_SPI0_MOSI  (19u)
#define PIN_SPI0_SCK   (18u)
#define PIN_SPI0_SS    (17u)

#define PIN_SPI1_MISO  (12u)
#define PIN_SPI1_MOSI  (15u)
#define PIN_SPI1_SCK   (14u)
#define PIN_SPI1_SS    (13u)

in pins_arduino.h for the board are default values for the creation of the SPI and SPI1 object. The user can still call SPI.setTX() etc to change these to another pin that supports that function. These functions accept any valid pin that supports that function.

If the board does have on-board SPI devices, it would be useful to set the default SPI pins as such. Otherwise, it doesn’t matter much.

1 Like

I haven’t gotten to this step yet, but I will take your advice when I get there. Thanks for the information.

I am currently confused on the pwr parameter in the

def MakeBoardJSON(name, vendor_name, product_name, vid, pid, pwr, boarddefine, flashsizemb, boot2, extra, board_url)

It’s the max power of the usb in mA, and I see a lot of 250 and 500. I am trying to charge my lithium-ion battery at 750 mA so I assume I should do 750. I just didn’t see any other variation other than 250 or 500 so I am not sure if those are min and max values.

As you can see in the usage of the macro that this option sets (USBD_MAX_POWER_MA):

It creates a USB configuration descriptor, which in turn fully expanded turns into

This is in turn e.g. explained in USB Component: Configuration Descriptor, where it is the the bMaxPower member.

As this is a uint8_t, the value range is 0 to 255, and since each “count” is 2mA, the maximum is technically 255 * 2mA = 510mA.

The USB 2.0 specification however also says:

that the maximum current out of a high-power hub is 500mA at nominally 5V. So maybe values higher than 500 are rejected by operating systems.

1 Like

As I anticipated, there must be something in place that I am not aware of for pwr. I need to study this more, but this essentially it is a spec from USB 2.0. I guess if I want up to 750 mA I need to use USB 3.0.

On another note, I was following the post that you shared to me which overlaps with my post and I was wondering by doing this does it read the preconfigured pin_arduino.h file? Because the my_custom_rp2040_board.json file is generated before editing or adding to the pin_arduino.h file.

If not, is the only way to get the pin_arduino.h to preconfigure my pins is to PR the changes to:

But the RP2040 only has a USB 2.0 capable USB peripheral with a USB 1.1. PHY, so this is not easily possible. On the other hand, I’ve heard that USB hubs still deliver more than 500mA current, to make USB devices that need it “just work”, instead of arbitrarily limiting it. But such a device that exceeds the maximum current would probably not be USB 2.0 compliant. For USB 3.0, see here.

What does “it” refer to in the “does it read the preconfigured file”? None of the .py scripts such as ever read the pin_arduino.h file. You need to create the pins_arduino.h file yourself in the variant folder that is used for your board in the script.

1 Like

What does “it” refer to in the “does it read the preconfigured file”? None of the .py scripts such as ever read the pin_arduino.h file. You need to create the pins_arduino.h file yourself in the variant folder that is used for your board in the script.

I should be clearer. I’ve recursively cloned the arduino-pico as my local fork on my desktop (Windows 10), did my changes appropriately to get the JSON file, and I’ve created a board folder at the same level at the platformio.ini. I also copied the JSON file into the board folder. Next i’ve successfully tested my generated board locally on platformIO by making a new project in my Projects folder with my board name in the platformio.ini file.

platform =
framework = arduino
monitor_speed = 115200
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m

board = upt_rp2040

So, my question about the pin_arduino.h file is, how does platformIO know what I configured in my pin_arduino.h file if it only exists in my local fork which is on my desktop and has no path on the project directory of my project. I understand platformio.ini gets the board name because I copied the JSON file into the project directory in the folder named board but what about the pin_arduino.h?

For example, how does platformIO know I changed the SPI0 pins away from their default to different pins that suites me better?

If the variants/upt_rp2040/pins_arduino.h (and releated) file only exist in a folder on your Desktop and is not referenced by the platform or your platformio.ini, it will not know about it all. In fact, building should fail hard if tries to access that file.

You need to point your local folder as described here.

It was a bit confusing reading through the post you linked. It looks like they were asked to copy their arduino-pico fork into the VScode workspace and do the changes, adds, and commits via VScode, but I am assuming those changes where the changes I did using Git Bash on my local fork that is now in my documents folder instead of my desktop. Therefore, I did not do any changes, adds, and commits in VScode.

I did add the lines in my platformio.ini file to point to the local fork like so,

platform_packages =

But I get an error once I build. It looks like an integer conversion issue… Is this from missing something during my changes of the arduino-pico?

In file included from C:\Users\UserName\Documents\Dev\arduino-pico/pico-sdk/lib/tinyusb/src/tusb.h:67,
                 from C:\Users\UserName\Documents\Dev\arduino-pico\cores\rp2040\RP2040USB.cpp:28:
C:\Users\UserName\Documents\Dev\arduino-pico\cores\rp2040\RP2040USB.cpp: In function 'void __SetupUSBDescriptor()':
C:\Users\UserName\Documents\Dev\arduino-pico/pico-sdk/lib/tinyusb/src/device/usbd.h:200:125: error: narrowing conversion of '375' from 'int' to 'uint8_t' {aka 'unsigned char'} [-Wnarrowing]
  200 |   9, TUSB_DESC_CONFIGURATION, U16_TO_U8S_LE(_total_len), _itfcount, config_num, _stridx, TU_BIT(7) | _attribute, (_power_ma)/2
      |                                                                                                                  ~~~~~~~~~~~^~
C:\Users\UserName\Documents\Dev\arduino-pico\cores\rp2040\RP2040USB.cpp:288:13: note: in expansion of macro 'TUD_CONFIG_DESCRIPTOR'
  288 |             TUD_CONFIG_DESCRIPTOR(1, interface_count, USBD_STR_0, usbd_desc_len, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, USBD_MAX_POWER_MA)
      |             ^~~~~~~~~~~~~~~~~~~~~
Compiling .pio\build\upt_rp2040\FrameworkArduino\api\IPAddress.cpp.o
Compiling .pio\build\upt_rp2040\FrameworkArduino\api\PluggableUSB.cpp.o
*** [.pio\build\upt_rp2040\FrameworkArduino\RP2040USB.cpp.o] Error 1

This implies you tried to set USBD_MAX_POWER_MA to 750, since the USB descriptor has bMaxPower as a uint8_t field (0 to 255) in units of 2mA, the number 375 cannot be stored in a uint8_t. It exceeds it value range. You can only set USBD_MAX_POWER_MA to 500 as discussed previously.

1 Like

Okay so turns out I forgot to replace the JSON file in the boards folder after I changed USBD_MAX_POWER_MA from 750 to 250.