diff options
Diffstat (limited to 'lib/pbdrv')
-rw-r--r-- | lib/pbdrv/drv/rp2040/mod.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/lib/pbdrv/drv/rp2040/mod.c b/lib/pbdrv/drv/rp2040/mod.c index 26882f7..b572c4e 100644 --- a/lib/pbdrv/drv/rp2040/mod.c +++ b/lib/pbdrv/drv/rp2040/mod.c @@ -11,12 +11,13 @@ #define PBDRV_I2C i2c0 #define BUF_SIZE 256 -// NOTE: this function is called from the I2C ISR, and should return as quickly -// as possible. +/** + * \note this function is called from the I2C ISR, and should return as quickly + * as possible. + */ static void recv_event(i2c_inst_t *i2c, i2c_slave_event_t event) { - uint8_t data[BUF_SIZE]; - size_t size = 0; - // pbdrv_i2c_recv(NULL, 0); + static uint8_t data[BUF_SIZE]; + static size_t size = 0; switch (event) { case I2C_SLAVE_RECEIVE: { @@ -39,6 +40,18 @@ void pbdrv_setup() { i2c_slave_init(PBDRV_I2C, PBDRV_MOD_ADDR, &recv_event); } +/** + * While the RP2040's datasheet claims it supports multi-master configurations + * by implementing bus arbitration, it does not natively support a mode where + * it is configured as a (multi-)master with a slave address, such that it can + * be addressed by other multi-masters. This function includes a hacky + * workaround that teporarily sets the RP2040 to I2C master mode to send a + * message, and then restores it back to slave mode. + * + * This approach results in some received frames being (partially) dropped in + * the time period between the invocation of this function and the bus becoming + * idle (and the message is sent). + */ __weak void pbdrv_i2c_send(i2c_addr_t addr, const uint8_t * buf, size_t sz) { i2c_set_slave_mode(PBDRV_I2C, false, PBDRV_MOD_ADDR); |