diff options
Diffstat (limited to 'shared')
-rw-r--r-- | shared/include.cmake | 5 | ||||
-rw-r--r-- | shared/pb.cmake | 20 | ||||
-rw-r--r-- | shared/pb/drv/arduino/mod.cpp | 33 | ||||
-rw-r--r-- | shared/pb/drv/arduino/mod.h | 19 | ||||
-rw-r--r-- | shared/pb/moddrv.c | 108 | ||||
-rw-r--r-- | shared/pb/moddrv.h | 38 |
6 files changed, 92 insertions, 131 deletions
diff --git a/shared/include.cmake b/shared/include.cmake deleted file mode 100644 index c4b01c2..0000000 --- a/shared/include.cmake +++ /dev/null @@ -1,5 +0,0 @@ -include_directories(${CMAKE_CURRENT_LIST_DIR}) -add_library(puzbus STATIC - ${CMAKE_CURRENT_LIST_DIR}/pb/moddrv.c - ) - diff --git a/shared/pb.cmake b/shared/pb.cmake new file mode 100644 index 0000000..71a28cb --- /dev/null +++ b/shared/pb.cmake @@ -0,0 +1,20 @@ +if(DEFINED ARDUINO) + set(PBDRV_ARDUINO true) +endif() + +include_directories(${CMAKE_CURRENT_LIST_DIR}) + +list(APPEND PBDRV_SRCS "${CMAKE_CURRENT_LIST_DIR}/pb/moddrv.c") + +if(PBDRV_ARDUINO) + list(APPEND PBDRV_SRCS "${CMAKE_CURRENT_LIST_DIR}/pb/drv/arduino/mod.cpp") +endif() + +add_library(pbdrv-mod STATIC ${PBDRV_SRCS}) + +if(PBDRV_ARDUINO) + target_link_arduino_libraries(pbdrv-mod + core + Wire + ) +endif() diff --git a/shared/pb/drv/arduino/mod.cpp b/shared/pb/drv/arduino/mod.cpp new file mode 100644 index 0000000..c7bbe45 --- /dev/null +++ b/shared/pb/drv/arduino/mod.cpp @@ -0,0 +1,33 @@ +#ifndef ARDUINO +#error This driver only works on the Arduino platform! +#endif + +#include <Arduino.h> +#include <Wire.h> + +#include <stdlib.h> +#include <stdint.h> + +#include "mod.h" + +static void recv_event(int bytes) { + uint8_t * data = (uint8_t *) malloc(bytes); + size_t size = 0; + while (Wire.available()) { + data[size++] = Wire.read(); + } + + pbdrv_i2c_recv(data, size); +} + +void pbdrv_setup() { + Wire.begin((int) PBDRV_MOD_ADDR); + Wire.onReceive(recv_event); +} + +__weak void pbdrv_i2c_send(i2c_addr_t addr, const uint8_t * buf, size_t sz) { + Wire.beginTransmission((int) addr); + Wire.write(buf, sz); + Wire.endTransmission(); +} + diff --git a/shared/pb/drv/arduino/mod.h b/shared/pb/drv/arduino/mod.h new file mode 100644 index 0000000..e2e3b6d --- /dev/null +++ b/shared/pb/drv/arduino/mod.h @@ -0,0 +1,19 @@ +#pragma once + +#include "../../moddrv.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief puzzle bus driver setup + * + * This function should be called from the Arduino \c setup() function. + */ +void pbdrv_setup(); + +#ifdef __cplusplus +} +#endif + diff --git a/shared/pb/moddrv.c b/shared/pb/moddrv.c index 9677341..b17b7ac 100644 --- a/shared/pb/moddrv.c +++ b/shared/pb/moddrv.c @@ -1,101 +1,25 @@ -#include <memory.h> - #include "types.h" #include "moddrv.h" -/** \brief [private] placeholder global state variable */ -static enum pb_state _global_state = PB_GS_NOINIT; - -/** \brief [private] main controller global state */ -static enum pb_state _main_state = PB_GS_NOINIT; +//! fallback module name +__weak const char * PBDRV_MOD_NAME = "???"; -__weak enum pb_state pbdrv_hook_mod_state_read() { - return _global_state; -} +//! [private] placeholder global state variable +static pb_global_state_t _global_state = PB_GS_NOINIT; -__weak void pbdrv_hook_mod_state_write(enum pb_state state) { - _global_state = state; -} - -__weak void pbdrv_i2c_recv(const char * buf, size_t sz) { - return; -} +//! [private] main controller global state +static pb_global_state_t _main_state = PB_GS_NOINIT; -__weak void pbdrv_handle_read(uint16_t i2c_addr, const char * buf, size_t sz) { - if (sz == 0) return; - pb_cmd_read_t * cmd = (pb_cmd_read_t *) buf; +// __weak enum pb_state pbdrv_hook_mod_state_read() { +// return _global_state; +// } - // allow user to addrimplement custom read handlers - if (pbdrv_hook_read(i2c_addr, cmd->address)) - return; - - switch (cmd->address) { - case PB_ADDR_GS: { - char res[] = { - PB_CMD_READ, - PB_ADDR_GS, - pbdrv_hook_mod_state_read(), - }; - return pbdrv_i2c_send(i2c_addr, res, sizeof(res)); - } - default: return; - } -} - -__weak void pbdrv_handle_write(uint16_t i2c_addr, const char * buf, size_t sz) { - if (sz < 2) return; // must have address and at least 1 byte data - pb_cmd_write_t * cmd = (pb_cmd_write_t *) buf; - - // allow user to implement custom read handlers - if (pbdrv_hook_write(i2c_addr, cmd->address, (char *) cmd->data, sz - 1)) - return; - - switch (cmd->address) { - case PB_ADDR_GS: - pbdrv_hook_mod_state_write(cmd->data[0]); - break; - default: return; - } -} +// __weak void pbdrv_hook_mod_state_write(enum pb_state state) { +// _global_state = state; +// } -__weak void pbdrv_handle_magic(uint16_t i2c_addr, const char * buf, size_t sz) { - if (sz != sizeof(pb_magic_msg)) return; - if (memcmp(buf, pb_magic_msg, sizeof(pb_magic_msg)) != 0) return; - - size_t res_size = sizeof(pb_cmd_t) + sizeof(pb_magic_res); - char res[res_size]; - res[0] = PB_CMD_MAGIC; - memcpy(res, pb_magic_res, sizeof(pb_magic_res)); - - pbdrv_i2c_send(i2c_addr, res, res_size); -} - -__weak void pbdrv_handle_sex(uint16_t i2c_addr, const char * buf, size_t sz) { - if (sz == 0) return; - pb_cmd_sex_t * cmd = (pb_cmd_sex_t *) buf; - - // send own state - char res[] = { - PB_CMD_SEX, - pbdrv_hook_mod_state_read(), - }; - pbdrv_i2c_send(i2c_addr, res, sizeof(res)); - - if (cmd->main_state == _main_state) return; - // keep main controller state - _main_state = cmd->main_state; - // call update if main state changed - pbdrv_hook_main_state_update(_main_state); -} - -__weak void pbdrv_hook_main_state_update(enum pb_state state) { } -__weak bool pbdrv_hook_cmd(uint16_t i2c_addr, enum pb_state cmd, const char * buf, size_t sz) { - return false; -} -__weak bool pbdrv_hook_read(uint16_t i2c_addr, uint8_t addr) { - return false; -} -__weak bool pbdrv_hook_write(uint16_t i2c_addr, uint8_t addr, const char * buf, size_t sz) { - return false; +__weak void pbdrv_i2c_recv(const uint8_t * buf, size_t sz) { + return; } - + +__weak void pbdrv_hook_main_state_update(pb_global_state_t state) { } diff --git a/shared/pb/moddrv.h b/shared/pb/moddrv.h index d2e2d97..b48f4db 100644 --- a/shared/pb/moddrv.h +++ b/shared/pb/moddrv.h @@ -16,45 +16,15 @@ #include "types.h" -#ifndef PBDRV_MOD_NAME -#define PBDRV_MOD_NAME "???" -#endif +extern const char * PBDRV_MOD_NAME; +extern const i2c_addr_t PBDRV_MOD_ADDR; #ifdef __cplusplus extern "C" { #endif -void pbdrv_i2c_recv(const char * buf, size_t sz); -void pbdrv_i2c_send(uint16_t i2c_addr, const char * buf, size_t sz); - -enum pb_state pbdrv_hook_mod_state_read(); -void pbdrv_hook_mod_state_write(enum pb_state state); -void pbdrv_hook_main_state_update(enum pb_state state); - -/** - * \name hooks - * - * Implementing this function allows you to use the weak implementation of \c - * pbdrv_i2c_recv() while being able to implement custom command handlers. - * - * \return true if the cmd was recognized, or false to forward the command to - * the default handlers - * - * \{ - */ - -/** \brief cmd receive hook */ -bool pbdrv_hook_cmd(uint16_t i2c_addr, enum pb_state cmd, const char * buf, size_t sz); -/** \brief read cmd hook */ -bool pbdrv_hook_read(uint16_t i2c_addr, uint8_t addr); -/** \brief write cmd hook */ -bool pbdrv_hook_write(uint16_t i2c_addr, uint8_t addr, const char * buf, size_t sz); -//! \} - -void pbdrv_handle_read(uint16_t i2c_addr, const char * buf, size_t sz); -void pbdrv_handle_write(uint16_t i2c_addr, const char * buf, size_t sz); -void pbdrv_handle_magic(uint16_t i2c_addr, const char * buf, size_t sz); -void pbdrv_handle_sex(uint16_t i2c_addr, const char * buf, size_t sz); +void pbdrv_i2c_recv(const uint8_t * buf, size_t sz); +void pbdrv_i2c_send(i2c_addr_t i2c_addr, const uint8_t * buf, size_t sz); #ifdef __cplusplus } |