diff options
author | Loek Le Blansch <loek@pipeframe.xyz> | 2024-06-15 13:30:45 +0200 |
---|---|---|
committer | Loek Le Blansch <loek@pipeframe.xyz> | 2024-06-15 13:30:45 +0200 |
commit | 20f442e5f5aa6a4fcf07f65e2f446a3c0ff8e4f2 (patch) | |
tree | 99f2422681eaa34a6f21b54d86e67115c291d5ce /lib/pbdrv | |
parent | dbe08a8cd3d29cee7ba1adae4841c0a831784f31 (diff) |
WIP freertos + Arduino workaround
Diffstat (limited to 'lib/pbdrv')
-rw-r--r-- | lib/pbdrv/CMakeLists.txt | 12 | ||||
-rw-r--r-- | lib/pbdrv/drv/arduino/mod.cpp | 41 | ||||
-rw-r--r-- | lib/pbdrv/drv/arduino/mod.h | 11 | ||||
-rw-r--r-- | lib/pbdrv/pb-mod.c | 4 | ||||
-rw-r--r-- | lib/pbdrv/pb-mod.h | 10 | ||||
-rw-r--r-- | lib/pbdrv/pb-route.c | 19 | ||||
-rw-r--r-- | lib/pbdrv/pb-send.c | 4 | ||||
-rw-r--r-- | lib/pbdrv/pb-send.h | 2 |
8 files changed, 84 insertions, 19 deletions
diff --git a/lib/pbdrv/CMakeLists.txt b/lib/pbdrv/CMakeLists.txt index b048ec7..59a1f25 100644 --- a/lib/pbdrv/CMakeLists.txt +++ b/lib/pbdrv/CMakeLists.txt @@ -21,13 +21,21 @@ add_library(pbdrv STATIC target_link_libraries(pbdrv mpack) target_include_directories(pbdrv SYSTEM INTERFACE .) -# puzzle bus module specific code (superset of pbdrv) +# puzzle bus *module* specific code add_library(pbdrv-mod STATIC pb-mod.c pb-send.c pb-route.c ) -target_link_libraries(pbdrv-mod pbdrv) +target_link_libraries(pbdrv-mod + # freertos is used to defer the handling of i2c messages outside the receive + # interrupt service routine + freertos_kernel + freertos_kernel_include + freertos_config + # pbdrv-mod is a superset of pbdrv + pbdrv + ) target_include_directories(pbdrv-mod SYSTEM INTERFACE .) # supported puzzle bus drivers diff --git a/lib/pbdrv/drv/arduino/mod.cpp b/lib/pbdrv/drv/arduino/mod.cpp index ac051db..d281495 100644 --- a/lib/pbdrv/drv/arduino/mod.cpp +++ b/lib/pbdrv/drv/arduino/mod.cpp @@ -4,24 +4,43 @@ #include <Arduino.h> #include <Wire.h> +#include <avr/delay.h> + +#include <FreeRTOS.h> +#include <timers.h> +#include <task.h> #include <stdlib.h> #include <stdint.h> #include "../../pb.h" #include "../../pb-mod.h" +#include "../../pb-buf.h" #include "mod.h" +//! Arduino setup function +extern void setup(void); +void loop(void) {} + +static void async_pb_i2c_recv(void * _msg, uint32_t _) { + pb_buf_t * msg = (pb_buf_t *) _msg; + pb_i2c_recv((uint8_t *) msg->data, msg->size); + pb_buf_free(msg); + free(msg); +} + static void recv_event(int bytes) { - uint8_t * data = (uint8_t *) malloc(bytes); - size_t size = 0; + pb_buf_t * msg = (pb_buf_t *) malloc(sizeof(pb_buf_t)); + msg->data = (char *) malloc(bytes); + msg->size = 0; while (Wire.available()) - data[size++] = Wire.read(); + msg->data[msg->size++] = Wire.read(); - pb_i2c_recv(data, size); + // defer pb_i2c_recv call + xTimerPendFunctionCallFromISR(async_pb_i2c_recv, msg, 0, NULL); } -void pb_setup() { +static void pb_setup() { Wire.begin((int) PB_MOD_ADDR); Wire.setWireTimeout(PB_TIMEOUT_US, true); Wire.setClock(PB_CLOCK_SPEED_HZ); @@ -29,6 +48,18 @@ void pb_setup() { Wire.onReceive(recv_event); } +void initVariant(void) { + // call regular arduino setup + setup(); + Serial.print("regular setup done and in initVariant\r\n"); // DEBUG + + // call pbdrv-mod setup + pb_setup(); + + // start freertos scheduler + vTaskStartScheduler(); +} + __weak void pb_i2c_send(i2c_addr_t addr, const uint8_t * buf, size_t sz) { Wire.beginTransmission((int) addr); Wire.write(buf, sz); diff --git a/lib/pbdrv/drv/arduino/mod.h b/lib/pbdrv/drv/arduino/mod.h index c4cb9ce..87b5724 100644 --- a/lib/pbdrv/drv/arduino/mod.h +++ b/lib/pbdrv/drv/arduino/mod.h @@ -4,12 +4,17 @@ extern "C" { #endif +//! Arduino init variant (called before user setup) +void initVariant(void); + /** - * \brief puzzle bus driver setup + * \brief Arduino loop function * - * This function should be called from the Arduino \c setup() function. + * Loop won't run because everything is handled by the freertos scheduler. It + * is defined in this driver to cause compiler warnings if the user has defined + * the loop() function anyways. */ -void pb_setup(); +extern void loop(void); #ifdef __cplusplus } diff --git a/lib/pbdrv/pb-mod.c b/lib/pbdrv/pb-mod.c index faa321e..c27194e 100644 --- a/lib/pbdrv/pb-mod.c +++ b/lib/pbdrv/pb-mod.c @@ -32,7 +32,3 @@ __weak void pb_i2c_recv(const uint8_t * data, size_t sz) { pb_msg_free(msg); } -void pb_reply(pb_msg_t * msg, pb_buf_t * reply) { - return pb_i2c_send(msg->sender, (uint8_t *) reply->data, reply->size); -} - diff --git a/lib/pbdrv/pb-mod.h b/lib/pbdrv/pb-mod.h index 4fb3456..a2da421 100644 --- a/lib/pbdrv/pb-mod.h +++ b/lib/pbdrv/pb-mod.h @@ -14,7 +14,6 @@ #include <stddef.h> #include <stdbool.h> -#include "pb-buf.h" #include "pb-types.h" #ifdef __cplusplus @@ -29,11 +28,16 @@ extern const i2c_addr_t PB_MOD_ADDR; void pb_i2c_recv(const uint8_t * buf, size_t sz); void pb_i2c_send(i2c_addr_t i2c_addr, const uint8_t * buf, size_t sz); -void pb_reply(pb_msg_t * msg, pb_buf_t * reply); - pb_global_state_t pb_hook_mod_state_read(); void pb_hook_mod_state_write(pb_global_state_t state); +/** + * \brief platform-specific blocking delay function + * + * FIXME: this should be removed (see handover: RP2040 I2C limitations) + */ +void pb_mod_blocking_delay_ms(unsigned long ms); + #ifdef __cplusplus } #endif diff --git a/lib/pbdrv/pb-route.c b/lib/pbdrv/pb-route.c index f26d45c..279b430 100644 --- a/lib/pbdrv/pb-route.c +++ b/lib/pbdrv/pb-route.c @@ -1,6 +1,13 @@ #include "pb-route.h" #include "pb-mod.h" #include "pb-send.h" +#include "pb-types.h" + +#include <string.h> + +// FIXME: this should be removed (see handover: RP2040 I2C limitations) +#include <FreeRTOS.h> +#include <task.h> __weak bool pb_hook_route_msg(pb_msg_t * msg) { return false; } __weak void pb_route_msg(pb_msg_t * msg) { @@ -59,7 +66,7 @@ __weak void pb_hook_main_state_update(pb_global_state_t state) {} __weak void pb_route_cmd_state_req(pb_msg_t * msg) { pb_global_state_t own_state = pb_hook_mod_state_read(); pb_buf_t buf = pb_send_state_res(own_state); - pb_reply(msg, &buf); + pb_send_reply(msg, &buf); pb_buf_free(&buf); // notify of new global state variable @@ -77,8 +84,16 @@ __weak void pb_route_cmd_state_set(pb_msg_t * msg) { } __weak void pb_route_cmd_magic_req(pb_msg_t * msg) { + pb_cmd_magic_t * cmd = msg->cmd; + // return early if magic is invalid + if (cmd->_magic_size != sizeof(pb_cmd_magic_req)) return; + if (memcmp(cmd->magic, pb_cmd_magic_req, cmd->_magic_size) != 0) return; + + // FIXME: this should be removed (see handover: RP2040 I2C limitations) + vTaskDelay(2000 / portTICK_PERIOD_MS); + pb_buf_t buf = pb_send_magic_res(); - pb_reply(msg, &buf); + pb_send_reply(msg, &buf); pb_buf_free(&buf); } diff --git a/lib/pbdrv/pb-send.c b/lib/pbdrv/pb-send.c index f0d5004..b70af3a 100644 --- a/lib/pbdrv/pb-send.c +++ b/lib/pbdrv/pb-send.c @@ -2,6 +2,10 @@ #include "pb-mod.h" #include "pb-msg.h" +void pb_send_reply(pb_msg_t * msg, pb_buf_t * reply) { + return pb_i2c_send(msg->sender, (uint8_t *) reply->data, reply->size); +} + pb_buf_t pb_send_read_req(uint8_t propid) { pb_cmd_prop_t cmd = { .propid = propid, diff --git a/lib/pbdrv/pb-send.h b/lib/pbdrv/pb-send.h index 83051e2..2f8be1e 100644 --- a/lib/pbdrv/pb-send.h +++ b/lib/pbdrv/pb-send.h @@ -7,6 +7,8 @@ extern "C" { #endif +void pb_send_reply(pb_msg_t * msg, pb_buf_t * reply); + pb_buf_t pb_send_read_req(uint8_t propid); pb_buf_t pb_send_read_res(uint8_t propid, uint8_t * value, size_t size); pb_buf_t pb_send_write_req(uint8_t propid, uint8_t * value, size_t size); |