diff options
Diffstat (limited to 'lib/pbdrv/drv/arduino/mod.cpp')
-rw-r--r-- | lib/pbdrv/drv/arduino/mod.cpp | 67 |
1 files changed, 57 insertions, 10 deletions
diff --git a/lib/pbdrv/drv/arduino/mod.cpp b/lib/pbdrv/drv/arduino/mod.cpp index 8a38a5b..9130334 100644 --- a/lib/pbdrv/drv/arduino/mod.cpp +++ b/lib/pbdrv/drv/arduino/mod.cpp @@ -4,34 +4,81 @@ #include <Arduino.h> #include <Wire.h> +#include <avr/delay.h> -#include <stdlib.h> -#include <stdint.h> +#include <FreeRTOS.h> +#include <timers.h> +#include <task.h> #include "../../pb.h" #include "../../pb-mod.h" -#include "mod.h" +#include "../../pb-types.h" +#include "../../pb-buf.h" +#include "../../pb-mem.h" + +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); + pb_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 *) pb_malloc(sizeof(pb_buf_t)); + msg->data = (char *) pb_malloc(bytes); + msg->size = 0; while (Wire.available()) - data[size++] = Wire.read(); + msg->data[msg->size++] = Wire.read(); - pbdrv_i2c_recv(data, size); + // defer pb_i2c_recv call + xTimerPendFunctionCallFromISR(async_pb_i2c_recv, msg, 0, NULL); } -void pbdrv_setup() { - Wire.begin((int) PBDRV_MOD_ADDR); +static 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); } -__weak void pbdrv_i2c_send(i2c_addr_t addr, const uint8_t * buf, size_t sz) { +__weak void pb_i2c_send(i2c_addr_t addr, const uint8_t * buf, size_t sz) { Wire.beginTransmission((int) addr); Wire.write(buf, sz); Wire.endTransmission(true); Wire.setWireTimeout(PB_TIMEOUT_US, true); } +//! Arduino setup function +extern void setup(void); +//! Arduino loop function +extern void loop(void); +//! Arduino internal initialization +void init(void); + +//! FreeRTOS loop task +void loop_task() { + for(;;) { + loop(); + if (serialEventRun) serialEventRun(); + } +} + +//! Application entrypoint +int main(void) { + init(); // call arduino internal setup + setup(); // call regular arduino setup + pb_setup(); // call pbdrv-mod setup + xTaskCreate((TaskFunction_t) loop_task, "loop", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL); + vTaskStartScheduler(); // start freertos scheduler + return 0; +} + +/** + * \note I should really be able to use Arduino's initVariant function for + * this, but I can't seem to get it to link properly using the CMake setup in + * this repository. Overriding the main() function seems to work, and the + * USBCON thing in the default Arduino main() function isn't needed because + * puzzle modules are likely not using USB. + */ + |