aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-06-14 17:23:22 +0200
committerLoek Le Blansch <loek@pipeframe.xyz>2024-06-14 17:23:22 +0200
commit15ee8bd8885c8b3d0b4650fe609c253780f04bdf (patch)
treedf952b8f62dce49283a8f3937771ccc572fc13ad
parentef162ca3445d9adb000d7dfd1b68b181ef958926 (diff)
WIP more puzzle bus driver code
-rw-r--r--lib/pbdrv/drv/arduino/mod.cpp1
-rw-r--r--lib/pbdrv/pb-msg.c12
-rw-r--r--lib/pbdrv/pb-msg.h12
-rw-r--r--lib/pbdrv/pb-serial.c54
-rw-r--r--lib/pbdrv/pb-types.h4
-rw-r--r--main/i2c.c57
-rw-r--r--main/init.c3
-rw-r--r--main/pbdrv.c19
-rw-r--r--main/pbdrv.h11
-rw-r--r--puzzle/dummy/main.cpp6
-rw-r--r--test/CMakeLists.txt2
-rw-r--r--test/pbdrv/msg.cpp21
12 files changed, 144 insertions, 58 deletions
diff --git a/lib/pbdrv/drv/arduino/mod.cpp b/lib/pbdrv/drv/arduino/mod.cpp
index fab9dd5..ac051db 100644
--- a/lib/pbdrv/drv/arduino/mod.cpp
+++ b/lib/pbdrv/drv/arduino/mod.cpp
@@ -25,6 +25,7 @@ void pb_setup() {
Wire.begin((int) PB_MOD_ADDR);
Wire.setWireTimeout(PB_TIMEOUT_US, true);
Wire.setClock(PB_CLOCK_SPEED_HZ);
+ // TODO: check if onReceive replaces or appends a handler function
Wire.onReceive(recv_event);
}
diff --git a/lib/pbdrv/pb-msg.c b/lib/pbdrv/pb-msg.c
index 8ffd7cc..8bf96ef 100644
--- a/lib/pbdrv/pb-msg.c
+++ b/lib/pbdrv/pb-msg.c
@@ -35,3 +35,15 @@ void pb_msg_free(pb_msg_t * msg) {
free(msg);
}
+pb_buf_t pb_msg_write_req_magic() {
+ pb_cmd_req_magic_t content = {
+ .magic = (char *) &pb_cmd_magic_req[0],
+ ._magic_size = sizeof(pb_cmd_magic_req),
+ };
+ pb_msg_t msg_write = {
+ .type = PB_CMD_REQ_MAGIC,
+ .sender = 0,
+ .msg = &content,
+ };
+ return pb_msg_write(&msg_write);
+}
diff --git a/lib/pbdrv/pb-msg.h b/lib/pbdrv/pb-msg.h
index f27d4c4..6759b7c 100644
--- a/lib/pbdrv/pb-msg.h
+++ b/lib/pbdrv/pb-msg.h
@@ -11,6 +11,18 @@ pb_buf_t pb_msg_write(const pb_msg_t * msg);
pb_msg_t * pb_msg_read(const pb_buf_t * buf);
void pb_msg_free(pb_msg_t * msg);
+// pb_buf_t pb_msg_write_cmd_req_read(const pb_cmd_req_read_t);
+// pb_buf_t pb_msg_write_cmd_res_read(const pb_cmd_res_read_t);
+// pb_buf_t pb_msg_write_cmd_req_write
+// pb_buf_t pb_msg_write_cmd_req_state
+// pb_buf_t pb_msg_write_cmd_res_state
+// pb_buf_t pb_msg_write_cmd_req_set_state
+// pb_buf_t pb_msg_write_cmd_req_magic
+// pb_buf_t pb_msg_write_cmd_res_magic
+
+pb_buf_t pb_msg_write_req_magic();
+pb_buf_t pb_msg_write_res_magic();
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/pbdrv/pb-serial.c b/lib/pbdrv/pb-serial.c
index 9b20bf9..7eb738b 100644
--- a/lib/pbdrv/pb-serial.c
+++ b/lib/pbdrv/pb-serial.c
@@ -9,6 +9,8 @@ void pb_ser_w(mpack_writer_t * writer, const pb_msg_t * msg) {
switch (msg->type) {
case PB_CMD_REQ_READ: return pb_ser_w_cmd_req_read(writer, msg);
case PB_CMD_RES_READ: return pb_ser_w_cmd_res_read(writer, msg);
+ case PB_CMD_REQ_MAGIC: return pb_ser_w_cmd_req_magic(writer, msg);
+ case PB_CMD_RES_MAGIC: return pb_ser_w_cmd_res_magic(writer, msg);
default: break;
}
}
@@ -17,6 +19,8 @@ void pb_ser_r(mpack_reader_t * reader, pb_msg_t * msg) {
switch (msg->type) {
case PB_CMD_REQ_READ: return pb_ser_r_cmd_req_read(reader, msg);
case PB_CMD_RES_READ: return pb_ser_r_cmd_res_read(reader, msg);
+ case PB_CMD_REQ_MAGIC: return pb_ser_r_cmd_req_magic(reader, msg);
+ case PB_CMD_RES_MAGIC: return pb_ser_r_cmd_res_magic(reader, msg);
default: break;
}
}
@@ -26,6 +30,8 @@ void pb_ser_free(pb_msg_t * msg) {
switch (msg->type) {
case PB_CMD_REQ_READ: return pb_ser_free_cmd_req_read(msg);
case PB_CMD_RES_READ: return pb_ser_free_cmd_res_read(msg);
+ case PB_CMD_REQ_MAGIC: return pb_ser_free_cmd_req_magic(msg);
+ case PB_CMD_RES_MAGIC: return pb_ser_free_cmd_res_magic(msg);
default: break;
}
pb_ser_free_msg_header(msg);
@@ -84,3 +90,51 @@ void pb_ser_free_cmd_res_read(pb_msg_t * _msg) {
}
}
+void pb_ser_w_cmd_req_magic(mpack_writer_t * writer, const pb_msg_t * _msg) {
+ pb_cmd_req_magic_t * msg = _msg->msg;
+
+ mpack_write_bin(writer, (char *) msg->magic, msg->_magic_size);
+}
+void pb_ser_r_cmd_req_magic(mpack_reader_t * reader, pb_msg_t * _msg) {
+ pb_cmd_req_magic_t * msg = _msg->msg = malloc(sizeof(pb_cmd_req_magic_t));
+
+ msg->_magic_size = mpack_expect_bin(reader);
+ msg->magic = mpack_read_bytes_alloc(reader, msg->_magic_size);
+ mpack_done_bin(reader);
+}
+void pb_ser_free_cmd_req_magic(pb_msg_t * _msg) {
+ if (_msg->msg != NULL) {
+ pb_cmd_req_magic_t * msg = _msg->msg;
+ if (msg->magic != NULL) {
+ MPACK_FREE(msg->magic);
+ msg->magic = NULL;
+ }
+ free(_msg->msg);
+ _msg->msg = NULL;
+ }
+}
+
+void pb_ser_w_cmd_res_magic(mpack_writer_t * writer, const pb_msg_t * _msg) {
+ pb_cmd_res_magic_t * msg = _msg->msg;
+
+ mpack_write_bin(writer, (char *) msg->magic, msg->_magic_size);
+}
+void pb_ser_r_cmd_res_magic(mpack_reader_t * reader, pb_msg_t * _msg) {
+ pb_cmd_res_magic_t * msg = _msg->msg = malloc(sizeof(pb_cmd_res_magic_t));
+
+ msg->_magic_size = mpack_expect_bin(reader);
+ msg->magic = mpack_read_bytes_alloc(reader, msg->_magic_size);
+ mpack_done_bin(reader);
+}
+void pb_ser_free_cmd_res_magic(pb_msg_t * _msg) {
+ if (_msg->msg != NULL) {
+ pb_cmd_res_magic_t * msg = _msg->msg;
+ if (msg->magic != NULL) {
+ MPACK_FREE(msg->magic);
+ msg->magic = NULL;
+ }
+ free(_msg->msg);
+ _msg->msg = NULL;
+ }
+}
+
diff --git a/lib/pbdrv/pb-types.h b/lib/pbdrv/pb-types.h
index 7156272..53060ae 100644
--- a/lib/pbdrv/pb-types.h
+++ b/lib/pbdrv/pb-types.h
@@ -88,13 +88,13 @@ typedef struct {
//! PB_CMD_REQ_MAGIC data
typedef struct {
- const char * magic; //!< magic value
+ char * magic; //!< magic value
size_t _magic_size;
} pb_cmd_req_magic_t;
//! PB_CMD_RES_MAGIC data
typedef struct {
- const char * magic; //!< magic value
+ char * magic; //!< magic value
size_t _magic_size;
} pb_cmd_res_magic_t;
diff --git a/main/i2c.c b/main/i2c.c
index 77f4750..cb42ca4 100644
--- a/main/i2c.c
+++ b/main/i2c.c
@@ -8,63 +8,12 @@
#include "i2c.h"
#include "pb-mod.h"
-
-// uint8_t* scan_bus(uint8_t *array) {
-// int ret;
-// int i = 0;
-// uint8_t rxdata;
-//
-// for(int addr = 0; addr < (1<<7); addr++) {
-// // ignore reserved addresses
-// // These are any addresses of the form 000 0xxx or 111 1xxx
-// // ret = i2c_read_blocking(I2C_PORT, addr, &rxdata, 1, false);
-//
-// // if acknowledged -> ret == number of bytes sent
-// if(ret > 0){
-// printf("found i2c slave on addr: %d\n", addr);
-// array[i] = addr;
-// i++;
-// }
-// }
-//
-// return array;
-// }
-
-void pb_i2c_recv(const uint8_t * a, size_t b) {
- printf("%.*s", b, a);
-}
+#include "pbdrv.h"
void bus_task() {
- // scan bus for slaves
- // send updates at regular intervals
vTaskDelay(1000 / portTICK_PERIOD_MS);
- // int i = 0;
- // uint8_t found[MAX_SLAVES];
- // init_addr_array(found, MAX_SLAVES);
-
- while (true) {
- vTaskDelay(10 / portTICK_PERIOD_MS);
- pb_i2c_send(0x69, (uint8_t *) "bbbbbbbb", 9);
- }
-
- // while(1) {
- // // printf("Bus scan!");
- // scan_bus(found);
-
- // for(int i = 0; i < MAX_SLAVES; i++){
- // if( found[i] == 0x00 )
- // break;
- //
- // uint8_t data = 0x01;
- // // send data to found slave address
- // write_i2c(found[i], &data, 1);
-
- // data = 0x02;
- // write_i2c(found[i], &data, 1);
- // // request update from slave addr at found[i]
- // //write_i2c();
- // }
- // }
+ bus_scan();
+ vTaskDelete(NULL);
}
diff --git a/main/init.c b/main/init.c
index 2d6f33d..6d29d19 100644
--- a/main/init.c
+++ b/main/init.c
@@ -32,6 +32,9 @@ static void init_i2c() {
gpio_set_function(CFG_SDA_PIN, GPIO_FUNC_I2C);
gpio_set_function(CFG_SCL_PIN, GPIO_FUNC_I2C);
+ gpio_pull_up(CFG_SDA_PIN);
+ gpio_pull_up(CFG_SCL_PIN);
+
pb_setup();
}
diff --git a/main/pbdrv.c b/main/pbdrv.c
index 323afbe..d809b86 100644
--- a/main/pbdrv.c
+++ b/main/pbdrv.c
@@ -3,12 +3,15 @@
#include "pb.h"
#include "pb-types.h"
#include "pb-mod.h"
+#include "pb-msg.h"
#include <hardware/i2c.h>
#include <hardware/gpio.h>
#include <pico/i2c_slave.h>
+#include <pico/stdio.h>
#include <FreeRTOS.h>
+#include <stdio.h>
#include <timers.h>
#define PB_I2C i2c0
@@ -70,3 +73,19 @@ __weak void pb_i2c_send(i2c_addr_t addr, const uint8_t * buf, size_t sz) {
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_msg_write_req_magic();
+
+ // 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);
+}
+
diff --git a/main/pbdrv.h b/main/pbdrv.h
index 0b4ca21..a751000 100644
--- a/main/pbdrv.h
+++ b/main/pbdrv.h
@@ -35,6 +35,17 @@ 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.
+ *
+ * As a result of the RP2040 hardware limitations detailed at the top of this
+ * file, this function is also implemented in this file, even through it does
+ * not belong to the puzzle bus driver. In order to not miss any handshake
+ * responses, the bus should remain busy during the entire scan.
+ */
+void bus_scan();
+
#ifdef __cplusplus
}
#endif
diff --git a/puzzle/dummy/main.cpp b/puzzle/dummy/main.cpp
index ab10760..e5f5e24 100644
--- a/puzzle/dummy/main.cpp
+++ b/puzzle/dummy/main.cpp
@@ -4,6 +4,8 @@
#include "drv/arduino/mod.h"
#include "pb-mod.h"
+#define TEST_A
+
#ifdef TEST_A
#define ADDR_RX 0x69
#define ADDR_TX 0x20
@@ -28,8 +30,8 @@ void setup() {
}
void loop() {
- pb_i2c_send(ADDR_TX, (uint8_t *) MSG, MSG_SIZE);
- delay(MSG_DELAY);
+ // pb_i2c_send(ADDR_TX, (uint8_t *) MSG, MSG_SIZE);
+ // delay(MSG_DELAY);
}
void pb_i2c_recv(const uint8_t * data, size_t size) { }
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 9b1f40e..a01d2b0 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -4,6 +4,8 @@ set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
+set(CMAKE_BUILD_TYPE Debug)
+
project(pbtest C CXX ASM)
add_executable(test
diff --git a/test/pbdrv/msg.cpp b/test/pbdrv/msg.cpp
index 320d6b3..38df8f4 100644
--- a/test/pbdrv/msg.cpp
+++ b/test/pbdrv/msg.cpp
@@ -28,3 +28,24 @@ TEST(pb_msg_rw, cmd_req_read) {
pb_msg_free(msg_read);
}
+TEST(pb_msg_rw, cmd_req_magic) {
+ pb_buf_t buf = pb_msg_write_req_magic();
+
+ ASSERT_NE(buf.data, nullptr);
+ ASSERT_GE(buf.size, 0);
+
+ pb_msg_t * msg_read = pb_msg_read(&buf);
+ pb_buf_free(&buf);
+
+ ASSERT_EQ(buf.data, nullptr);
+
+ EXPECT_EQ(msg_read->type, PB_CMD_REQ_MAGIC);
+ EXPECT_EQ(msg_read->sender, 0);
+ EXPECT_NE(msg_read->msg, nullptr);
+ pb_cmd_res_magic_t * magic = (pb_cmd_res_magic_t *) msg_read->msg;
+ EXPECT_EQ(magic->_magic_size, sizeof(pb_cmd_magic_req));
+ EXPECT_EQ(0, memcmp(pb_cmd_magic_req, magic->magic, magic->_magic_size));
+
+ pb_msg_free(msg_read);
+}
+