Depot RP2040 Firmware
This page details the firmware which runs on RP2040-based Depot multi-bus adaptor boards. When running, the firmware listens to the UART hosted by the RP2040’s USB connection for the following commands and for read/write indicators.
The current version is 1.3.0. Read the release notes.
The buses currently supported:
Caution
Build the firmware with Pico SDK 1.5.0 or above.
Processing Incoming Data
The first received byte is checked by the firmware. If the value is less than 0x80
,
the code checks for a command, otherwise it processes the bytes as
a read or write operation.
Generic Commands
Command |
Arguments |
Description |
---|---|---|
|
Set the bus-host’s current mode |
|
|
Get bus-host device info |
|
|
|
Set the bus-host’s LED state1 |
|
||
|
Get last device error. Returns an error code byte |
1 If SHOW_HEARTBEAT
is not defined in CmakeLists.txt
, this call will respond with an ERR
signal.
I²C Commands
Command |
Arguments |
Description |
---|---|---|
|
|
Configure the I²C bus. This must be performed before the bus is |
|
Set I²C bus frequency to 100kHz |
|
|
Set I²C bus frequency to 400kHz |
|
|
Initialise the I²C bus for use |
|
|
Reset the I²C bus |
|
|
Manually issue an I²C |
|
|
|
Start an I²C read or write operation targeting a specific device |
|
Scan the I²C bus for devices. If the bus is not initialised when this |
2 Bits 7 through 1 are the target device’s I²C address. Bit 0 is the operation required: 1
for read, 0
for write.
1-Wire Commands
Command |
Arguments |
Description |
---|---|---|
|
|
Configure the 1-Wire bus’ data pint. This must be performed before the |
|
Initialise the 1-Wire bus for use and discover devices |
|
|
Reset the 1-Wire bus |
|
|
Scan the 1-Wire bus for devices. If the bus is not initialised when this |
GPIO Commands
Command |
Arguments |
Description |
---|---|---|
|
|
Set or get a GPIO pin. The pins can’t be those already used for buses |
Command Responses
Commands are acknowledged with an ACK (0x0F
) or an ERR (0xF0
). Note that these values may change.
Commands that return arbitrary amounts of data append the data with \r\n
as an end-of-sequence marker.
Modes
The multi-bus adaptor starts up in I²C mode, ie. ready for I²C operations. To switch to 1-Wire mode, send the #
command followed by a character byte indicating the required mode.
Mode |
Code |
LED Colour |
---|---|---|
I²C |
|
Cyan |
1-Wire |
|
Yellow |
None |
N/A |
Red |
Selecting a mode affects a number of operations, including device scans, info requests, reads, writes and bus initialisations.
The Adaptor’s Initial Response
Client code should first issue the connect request command, !
.
In versions prior to 1.2.0, the response to this command would be four bytes: OK\r\n
, or 4F4B0D0A
in hex integers. From version 1.2.0, the adaptor continues to return four bytes, but now the final two bytes are, respectively, the adaptor’s firmware major and minor version numbers: 4F4B0102
. Only four bytes are issued, so your code need not check for \r\n
.
This data can be used to ensure the adaptor firmware is up to date and to determine what features are supported. For example, if an adaptor responds with OK\r\n
, the client knows the firmware is less than 1.2.0 so it should not attempt to access 1-Wire functionality.
Read and Write Operations
The outcome depends on the value of the first byte in the sequence.
If the value is in the range 0x80
to 0xBF
, it is a read operation and the number of bytes to read is given by: value - 0x80
+ 1.
If the value is in the range 0xC0
to 0xFF
, it is a write operation and the number of bytes to write is given by: value - 0xC0
+ 1.
These bytes follow the state byte.
Only 64 bytes can be requested/written at a time. This is usually sufficient, but for larger amounts, issue subsequent requests for 64 bytes or less.
GPIO
You configure a GPIO pin, or read its value, by issuing the g
command followed by up to two bytes of data to indicate the target pin and the desired operation. GPIO features are available in all modes.
The first byte is formatted as follows:
Bit |
Role |
---|---|
0-4 |
The GPIO pin number, 0-31 |
5 |
Is the operation a read ( |
6 |
Is the pin an output ( |
7 |
The pin’s state: high ( |
For example, to configure pin 11 to a digital output initially set to logic High, you would pass 0xCB
, ie. 11001011
.
To configure pin 24 as an input, send 0x58
, or 01011000
. To subsequently read the pin’s value, send 0x38
, or 00111000
.
The adaptor will respond with ACK
or ERR
on all configuration, or output state setting operations.
Read operations will return the value read as an 8-bit integer.
Device Scan Format
Requesting a peripheral device scan by issuing the d
command in I²C mode returns is a string of I²C addresses separated by full-stops. Each address is a 7-bit value encoded as two-digit hex numbers.
If the adaptor is in 1-Wire mode, the returned string comprises 16 hex pairs for each included 1-Wire device. This is the 1-Wire device’s unique 64-bit ID.
Both strings are terminated by \r\n
.
If no peripherals are present, Z\r\n
is returned whatever mode is selected.
Adaptor Information Format
Requesting adaptor information by issuing the ?
command returns a sequence of integers and strings separated by full stops and followed by \r\n
. The sequence of fields is bus dependent.
For I²C mode:
Field |
Size |
Notes |
---|---|---|
Is I²C ready? |
2 |
Binary value: |
Is I²C being used? |
2 |
Binary value: |
I²C bus ID |
2 |
|
I²C SDA pin |
2-3 |
0-31 in decimal form |
I²C SCL pin |
2-3 |
0-31 in decimal form |
I²C bus frequency |
2 |
|
I²C address |
2-4 |
8-127 in decimal form |
Firmware version |
6-12 |
Major, minor and patch values as separate fields |
Firmware build |
2-4 |
1-999 |
Unique RP20240 ID |
17 |
16-byte value as two-digit hex values |
Board type |
2-17 |
Per board ID string, eg. |
For 1-Wire mode:
Field |
Size |
Notes |
---|---|---|
Is 1-Wire ready? |
2 |
Binary value: |
1-Wire data pin |
2-3 |
0-31 in decimal form |
Firmware version |
6-12 |
Major, minor and patch values as separate fields |
Firmware build |
2-4 |
1-999 |
Unique RP20240 ID |
17 |
16-byte value as two-digit hex values |
Board type |
2-17 |
Per board ID string, eg. |
Note Size includes the post-value separator.
Error Codes
The following errors are defined in the file errors.h
:
Error |
Code |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The format is as follows:
Bits 6-8 — The mode.
Bits 1-5 — A mode-specific error code.
Mode |
Mode Bits |
---|---|
General |
|
I²C |
|
SPI |
|
UART |
|
1-Wire |
|
GPIO |
|
Reserved |
|
Source code
The multi-bus adaptor firmware source code can be found in this GitHub repo.
Build and Deploy the Adaptor Firmware
Note
The following assumes you have the Pico SDK installed on your build machine and that the PICO_SDK_PATH
environment variable is set.
Clone the repo.
Navigate to the repo directory.
Run
cmake -S . -B firmwarebuild
.Run
cmake --build firmwarebuild
.Write the firmware depending on which board you are using:
./deploy.sh /path/to/device firmwarebuild/firmware/pico/firmware_pico_rp2040.uf2
./deploy.sh /path/to/device firmwarebuild/firmware/qtpy/firmware_qtpy_rp2040.uf2
./deploy.sh /path/to/device firmwarebuild/firmware/promicro/firmware_promicro.uf2
./deploy.sh /path/to/device firmwarebuild/firmware/tiny/firmware_tiny2040.uf2
./deploy.sh /path/to/device firmwarebuild/firmware/trinkey/firmware_trinkey2040.uf2
The deploy script tricks the RP2040-based board into booting into disk mode, then copies over the newly build firmware. When the copy completes, the RP2040 automatically reboots. This saves of a lot of tedious power-cycling with the BOOT button held down.
Note
From version 1.2.2, Depot’s build system respects the value of the Pico SDK environment variable PICO_BOARD
if you have set one. In this case, only firmware for the target board will be built. If the setting references a board not yet supported by Depot, all supported firmware versions will be built.