aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-06-22 18:32:06 +0200
committerLoek Le Blansch <loek@pipeframe.xyz>2024-06-22 18:32:06 +0200
commitccdcf5001c47820c41e9b962d8498602870289b5 (patch)
tree92c5fc878931e0a792975340f06a12bb6d4585a9
parentd6440954806d381dae5b3df65b43192f897018c6 (diff)
WIP RP2040 I2C workaround code
-rw-r--r--lib/pbdrv/pb-route.c3
-rw-r--r--main/config.def.h20
-rw-r--r--main/i2c.c16
-rw-r--r--main/init.c12
-rw-r--r--main/pbdrv.c36
-rw-r--r--main/pbdrv.h15
6 files changed, 45 insertions, 57 deletions
diff --git a/lib/pbdrv/pb-route.c b/lib/pbdrv/pb-route.c
index f5c32d6..5a7bd67 100644
--- a/lib/pbdrv/pb-route.c
+++ b/lib/pbdrv/pb-route.c
@@ -93,9 +93,6 @@ __weak void pb_route_cmd_magic_req(pb_msg_t * msg) {
// // return early if magic doesn't match
if (pb_memcmp(cmd->magic, pb_cmd_magic_req, sizeof(pb_cmd_magic_req)) != 0) return;
- // FIXME: this should be removed (see handover: RP2040 I2C limitations)
- pb_mod_blocking_delay_ms(2000);
-
pb_buf_t buf = pb_send_magic_res();
pb_send_reply(msg, &buf);
pb_buf_free(&buf);
diff --git a/main/config.def.h b/main/config.def.h
index 0dae608..b3be5ed 100644
--- a/main/config.def.h
+++ b/main/config.def.h
@@ -72,13 +72,21 @@
* \name I2C configuration
* \{
*/
-#ifndef CFG_SDA_PIN
-//! I2C SDA pin
-#define CFG_SDA_PIN 16
+#ifndef CFG_SDA0_PIN
+//! I2C 0 SDA pin
+#define CFG_SDA0_PIN 16
#endif
-#ifndef CFG_SCL_PIN
-//! I2C SCL pin
-#define CFG_SCL_PIN 17
+#ifndef CFG_SCL0_PIN
+//! I2C 0 SCL pin
+#define CFG_SCL0_PIN 17
+#endif
+#ifndef CFG_SDA1_PIN
+//! I2C 1 SDA pin
+#define CFG_SDA1_PIN 18
+#endif
+#ifndef CFG_SCL1_PIN
+//! I2C 1 SCL pin
+#define CFG_SCL1_PIN 19
#endif
/// \}
diff --git a/main/i2c.c b/main/i2c.c
index 2503560..0f23a13 100644
--- a/main/i2c.c
+++ b/main/i2c.c
@@ -16,6 +16,18 @@
i2c_addr_t modules[CFG_PB_MOD_MAX];
size_t modules_size = 0;
+static void bus_scan() {
+ pb_buf_t buf = pb_send_magic_req();
+
+ // check for all 7-bit addresses
+ uint16_t addr_max = 1 << 7;
+ for (uint16_t addr = 0x00; addr < addr_max; addr++) {
+ pb_i2c_send(addr, (uint8_t *) buf.data, buf.size);
+ }
+
+ pb_buf_free(&buf);
+}
+
static void state_exchange() {
for (size_t i = 0; i < modules_size; i++) {
pb_buf_t buf = pb_send_state_req();
@@ -28,10 +40,6 @@ void bus_task() {
// do a scan of the bus
bus_scan();
- // FIXME: this should be removed (see handover: RP2040 I2C limitations)
- // wait for 5 seconds until all handshake responses are received
- pb_mod_blocking_delay_ms(5e3);
-
while(1) {
// send my state to all puzzle modules
state_exchange();
diff --git a/main/init.c b/main/init.c
index 6d29d19..d85c94d 100644
--- a/main/init.c
+++ b/main/init.c
@@ -29,11 +29,15 @@ static void init_wifi() {
}
static void init_i2c() {
- gpio_set_function(CFG_SDA_PIN, GPIO_FUNC_I2C);
- gpio_set_function(CFG_SCL_PIN, GPIO_FUNC_I2C);
+ gpio_set_function(CFG_SDA0_PIN, GPIO_FUNC_I2C);
+ gpio_set_function(CFG_SCL0_PIN, GPIO_FUNC_I2C);
+ gpio_set_function(CFG_SDA1_PIN, GPIO_FUNC_I2C);
+ gpio_set_function(CFG_SCL1_PIN, GPIO_FUNC_I2C);
- gpio_pull_up(CFG_SDA_PIN);
- gpio_pull_up(CFG_SCL_PIN);
+ gpio_pull_up(CFG_SDA0_PIN);
+ gpio_pull_up(CFG_SCL0_PIN);
+ gpio_pull_up(CFG_SDA1_PIN);
+ gpio_pull_up(CFG_SCL1_PIN);
pb_setup();
}
diff --git a/main/pbdrv.c b/main/pbdrv.c
index 0624897..6a89253 100644
--- a/main/pbdrv.c
+++ b/main/pbdrv.c
@@ -14,7 +14,9 @@
#include <stdio.h>
#include <timers.h>
-#define PB_I2C i2c0
+#define PB_I2C_S i2c0
+#define PB_I2C_M i2c1
+
#define BUF_SIZE 256
#define MSGS_MAX 4
@@ -32,6 +34,8 @@ static void async_pb_i2c_recv(void * _msg, uint32_t _) {
}
static void msg_complete(i2c_msg_buf_t * msg) {
+ return pb_i2c_recv(msg->data, msg->size);
+
// defer pb_i2c_recv call to FreeRTOS scheduler as pb_i2c_recv takes
// too long to return from an ISR
xTimerPendFunctionCallFromISR(async_pb_i2c_recv, msg, 0, NULL);
@@ -48,7 +52,7 @@ static void recv_event(i2c_inst_t *i2c, i2c_slave_event_t event) {
switch (event) {
case I2C_SLAVE_RECEIVE: {
if (msg->size == BUF_SIZE) return;
- msg->data[msg->size++] = i2c_read_byte_raw(PB_I2C);
+ msg->data[msg->size++] = i2c_read_byte_raw(PB_I2C_S);
break;
}
case I2C_SLAVE_FINISH: {
@@ -60,33 +64,15 @@ static void recv_event(i2c_inst_t *i2c, i2c_slave_event_t event) {
}
void pb_setup() {
- i2c_init(PB_I2C, PB_CLOCK_SPEED_HZ);
- i2c_slave_init(PB_I2C, PB_MOD_ADDR, &recv_event);
+ i2c_init(PB_I2C_S, PB_CLOCK_SPEED_HZ);
+ i2c_init(PB_I2C_M, PB_CLOCK_SPEED_HZ);
+
+ i2c_slave_init(PB_I2C_S, PB_MOD_ADDR, &recv_event);
}
__weak void pb_i2c_send(i2c_addr_t addr, const uint8_t * buf, size_t sz) {
- i2c_set_slave_mode(PB_I2C, false, PB_MOD_ADDR);
-
// false to write stop condition to i2c bus
- i2c_write_timeout_us(PB_I2C, addr, buf, sz, false, PB_TIMEOUT_US);
-
- i2c_set_slave_mode(PB_I2C, true, PB_MOD_ADDR);
-}
-
-void bus_scan() {
- i2c_set_slave_mode(PB_I2C, false, PB_MOD_ADDR);
-
- pb_buf_t buf = pb_send_magic_req();
-
- // check for all 7-bit addresses
- uint16_t addr_max = 1 << 7;
- for (uint16_t addr = 0x00; addr < addr_max; addr++) {
- i2c_write_timeout_us(PB_I2C, addr, (uint8_t *) buf.data, buf.size, false, PB_TIMEOUT_US);
- }
-
- pb_buf_free(&buf);
-
- i2c_set_slave_mode(PB_I2C, true, PB_MOD_ADDR);
+ i2c_write_timeout_us(PB_I2C_M, addr, buf, sz, false, PB_TIMEOUT_US);
}
void pb_mod_blocking_delay_ms(unsigned long ms) {
diff --git a/main/pbdrv.h b/main/pbdrv.h
index 9496aa9..89a4870 100644
--- a/main/pbdrv.h
+++ b/main/pbdrv.h
@@ -41,21 +41,6 @@ void pb_setup();
*/
void pb_i2c_send(i2c_addr_t addr, const uint8_t * buf, size_t sz);
-/**
- * \brief Scan the bus for I2C slaves, and send handshake messages to ACK-ing
- * slaves.
- *
- * \note As a result of the RP2040 hardware limitations, this function is also
- * implemented in this file, even though it does not belong to the puzzle bus
- * driver.
- *
- * \warning In order to not miss any handshake responses, the bus should remain
- * busy during the entire scan. The \c nostop parameter of the \c
- * i2c_write_timeout_us() function from the pico-sdk does not seem to keep the
- * bus busy.
- */
-void bus_scan();
-
/// \}
#ifdef __cplusplus