aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-06-15 13:30:45 +0200
committerLoek Le Blansch <loek@pipeframe.xyz>2024-06-15 13:30:45 +0200
commit20f442e5f5aa6a4fcf07f65e2f446a3c0ff8e4f2 (patch)
tree99f2422681eaa34a6f21b54d86e67115c291d5ce /lib
parentdbe08a8cd3d29cee7ba1adae4841c0a831784f31 (diff)
WIP freertos + Arduino workaround
Diffstat (limited to 'lib')
-rw-r--r--lib/pbdrv/CMakeLists.txt12
-rw-r--r--lib/pbdrv/drv/arduino/mod.cpp41
-rw-r--r--lib/pbdrv/drv/arduino/mod.h11
-rw-r--r--lib/pbdrv/pb-mod.c4
-rw-r--r--lib/pbdrv/pb-mod.h10
-rw-r--r--lib/pbdrv/pb-route.c19
-rw-r--r--lib/pbdrv/pb-send.c4
-rw-r--r--lib/pbdrv/pb-send.h2
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);