diff options
author | Loek Le Blansch <loek@pipeframe.xyz> | 2024-06-14 17:23:22 +0200 |
---|---|---|
committer | Loek Le Blansch <loek@pipeframe.xyz> | 2024-06-14 17:23:22 +0200 |
commit | 15ee8bd8885c8b3d0b4650fe609c253780f04bdf (patch) | |
tree | df952b8f62dce49283a8f3937771ccc572fc13ad | |
parent | ef162ca3445d9adb000d7dfd1b68b181ef958926 (diff) |
WIP more puzzle bus driver code
-rw-r--r-- | lib/pbdrv/drv/arduino/mod.cpp | 1 | ||||
-rw-r--r-- | lib/pbdrv/pb-msg.c | 12 | ||||
-rw-r--r-- | lib/pbdrv/pb-msg.h | 12 | ||||
-rw-r--r-- | lib/pbdrv/pb-serial.c | 54 | ||||
-rw-r--r-- | lib/pbdrv/pb-types.h | 4 | ||||
-rw-r--r-- | main/i2c.c | 57 | ||||
-rw-r--r-- | main/init.c | 3 | ||||
-rw-r--r-- | main/pbdrv.c | 19 | ||||
-rw-r--r-- | main/pbdrv.h | 11 | ||||
-rw-r--r-- | puzzle/dummy/main.cpp | 6 | ||||
-rw-r--r-- | test/CMakeLists.txt | 2 | ||||
-rw-r--r-- | test/pbdrv/msg.cpp | 21 |
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; @@ -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); +} + |