From 1e317adeddc1bf99df8eb5aa16e8533494c3bc90 Mon Sep 17 00:00:00 2001 From: AlexanderHD27 Date: Mon, 6 Jan 2025 03:28:10 +0100 Subject: [PATCH] Implemented RX on Node --- .../firmware/i2c-hub-firmware/CMakeLists.txt | 1 + .../docs/.$NetworkStack.drawio.bkp | 935 ++++++----- .../docs/.$NetworkStack.drawio.dtmp | 1479 ----------------- .../i2c-hub-firmware/docs/NetworkStack.drawio | 918 +++++----- .../{src/gobotrpc => }/include/pinConfig.hpp | 0 .../src/gobotrpc/cmake/CMakeLists.txt | 2 + .../src/gobotrpc/cmake/gobotRPC_Node.cmake | 19 + .../i2c-hub-firmware/src/gobotrpc/crc16.cpp | 2 + .../gobotrpc/include/si/slave_interface.hpp | 0 .../src/gobotrpc/include/{ => util}/crc16.hpp | 0 .../gobotrpc/include/{ => util}/protocol.hpp | 5 + .../node_interface/include/node_interface.hpp | 32 + .../include/node_interface_hardware.hpp | 78 + .../src/gobotrpc/node_interface/init.cpp | 66 + .../node_interface/rp2040/i2c/init.cpp | 124 ++ .../node_interface/rp2040/i2c/rx_tx.cpp | 98 ++ .../src/gobotrpc/protocol_base.cpp | 6 + .../transmission_interface/rp2040_i2c_tx.cpp | 2 +- i2c-hub/pulseview-i2c-session | Bin 0 -> 490 bytes motor-control/core-xy-firmware/lib/gobotrpc | 1 + .../.vscode/c_cpp_properties.json | 6 +- .../vacum-control-firmware/.vscode/tasks.json | 55 +- .../vacum-control-firmware/CMakeLists.txt | 4 + .../vacum-control-firmware/FreeRTOSConfig.h | 10 +- .../{pinConfig.hpp => pinConfigNode.hpp} | 5 +- .../vacum-control-firmware/include/vacum.hpp | 5 +- .../vacum-control-firmware/lib/gobotrpc | 1 + .../vacum-control-firmware/src/base.cpp | 9 +- .../vacum-control-firmware/src/main.cpp | 81 +- 29 files changed, 1646 insertions(+), 2298 deletions(-) delete mode 100644 i2c-hub/firmware/i2c-hub-firmware/docs/.$NetworkStack.drawio.dtmp rename i2c-hub/firmware/i2c-hub-firmware/{src/gobotrpc => }/include/pinConfig.hpp (100%) create mode 100644 i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/cmake/gobotRPC_Node.cmake delete mode 100644 i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/si/slave_interface.hpp rename i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/{ => util}/crc16.hpp (100%) rename i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/{ => util}/protocol.hpp (85%) create mode 100644 i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/include/node_interface.hpp create mode 100644 i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/include/node_interface_hardware.hpp create mode 100644 i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/init.cpp create mode 100644 i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/rp2040/i2c/init.cpp create mode 100644 i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/rp2040/i2c/rx_tx.cpp create mode 100644 i2c-hub/pulseview-i2c-session create mode 120000 motor-control/core-xy-firmware/lib/gobotrpc rename vacum-control/vacum-control-firmware/include/{pinConfig.hpp => pinConfigNode.hpp} (72%) create mode 120000 vacum-control/vacum-control-firmware/lib/gobotrpc diff --git a/i2c-hub/firmware/i2c-hub-firmware/CMakeLists.txt b/i2c-hub/firmware/i2c-hub-firmware/CMakeLists.txt index 25e5853..3f7b3e4 100644 --- a/i2c-hub/firmware/i2c-hub-firmware/CMakeLists.txt +++ b/i2c-hub/firmware/i2c-hub-firmware/CMakeLists.txt @@ -63,6 +63,7 @@ target_link_libraries(i2c-hub-firmware # Add the standard include files to the build target_include_directories(i2c-hub-firmware PRIVATE ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_LIST_DIR}/include ) # Add any user requested libraries diff --git a/i2c-hub/firmware/i2c-hub-firmware/docs/.$NetworkStack.drawio.bkp b/i2c-hub/firmware/i2c-hub-firmware/docs/.$NetworkStack.drawio.bkp index c86c49a..9cedd64 100644 --- a/i2c-hub/firmware/i2c-hub-firmware/docs/.$NetworkStack.drawio.bkp +++ b/i2c-hub/firmware/i2c-hub-firmware/docs/.$NetworkStack.drawio.bkp @@ -1,19 +1,16 @@ - + - + - - - - + - + - + @@ -124,973 +121,973 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1099,15 +1096,15 @@ - + - + - + @@ -1117,39 +1114,39 @@ - + - + - + - - + + - + - + - + - + - + @@ -1158,96 +1155,99 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + - + - + - + @@ -1256,12 +1256,12 @@ - + - + @@ -1271,123 +1271,131 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - + - - + + - + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1395,78 +1403,217 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/i2c-hub/firmware/i2c-hub-firmware/docs/.$NetworkStack.drawio.dtmp b/i2c-hub/firmware/i2c-hub-firmware/docs/.$NetworkStack.drawio.dtmp deleted file mode 100644 index d3f0b54..0000000 --- a/i2c-hub/firmware/i2c-hub-firmware/docs/.$NetworkStack.drawio.dtmp +++ /dev/null @@ -1,1479 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/i2c-hub/firmware/i2c-hub-firmware/docs/NetworkStack.drawio b/i2c-hub/firmware/i2c-hub-firmware/docs/NetworkStack.drawio index afe80be..32af737 100644 --- a/i2c-hub/firmware/i2c-hub-firmware/docs/NetworkStack.drawio +++ b/i2c-hub/firmware/i2c-hub-firmware/docs/NetworkStack.drawio @@ -1,19 +1,16 @@ - + - + - - - - + - + - + @@ -124,973 +121,973 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1099,15 +1096,15 @@ - + - + - + @@ -1117,39 +1114,39 @@ - + - + - + - - + + - + - + - + - + - + @@ -1158,99 +1155,99 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1259,12 +1256,12 @@ - + - + @@ -1274,123 +1271,131 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - + - - + + - + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1398,81 +1403,202 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/pinConfig.hpp b/i2c-hub/firmware/i2c-hub-firmware/include/pinConfig.hpp similarity index 100% rename from i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/pinConfig.hpp rename to i2c-hub/firmware/i2c-hub-firmware/include/pinConfig.hpp diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/cmake/CMakeLists.txt b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/cmake/CMakeLists.txt index 24ff872..cb30f32 100644 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/cmake/CMakeLists.txt +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/cmake/CMakeLists.txt @@ -14,8 +14,10 @@ add_library(GobotRPC STATIC target_include_directories(GobotRPC PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../include + ${CMAKE_CURRENT_LIST_DIR}/../include/util ${CMAKE_CURRENT_LIST_DIR}/../include/ti ${CMAKE_CURRENT_LIST_DIR}/../../.. + ${CMAKE_CURRENT_LIST_DIR}/../../../include ) target_link_libraries(GobotRPC diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/cmake/gobotRPC_Node.cmake b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/cmake/gobotRPC_Node.cmake new file mode 100644 index 0000000..29ee670 --- /dev/null +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/cmake/gobotRPC_Node.cmake @@ -0,0 +1,19 @@ +add_library(GobotRPC_Node_RP2040_I2C STATIC + ${CMAKE_CURRENT_LIST_DIR}/../node_interface/rp2040/i2c/init.cpp + ${CMAKE_CURRENT_LIST_DIR}/../node_interface/rp2040/i2c/rx_tx.cpp + ${CMAKE_CURRENT_LIST_DIR}/../crc16.cpp + ${CMAKE_CURRENT_LIST_DIR}/../protocol_base.cpp + ${CMAKE_CURRENT_LIST_DIR}/../node_interface/init.cpp +) +target_include_directories(GobotRPC_Node_RP2040_I2C PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/../node_interface/include + ${CMAKE_CURRENT_LIST_DIR}/../include/util + ${CMAKE_CURRENT_LIST_DIR}/../../.. +) + +target_link_libraries(GobotRPC_Node_RP2040_I2C + FreeRTOS-Kernel-Heap4 + pico_stdlib + hardware_i2c + hardware_irq +) \ No newline at end of file diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/crc16.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/crc16.cpp index f3ff135..cb24220 100644 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/crc16.cpp +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/crc16.cpp @@ -1,3 +1,5 @@ +#include "crc16.hpp" + #define POLY 0x8408 /* // 16 12 5 diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/si/slave_interface.hpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/si/slave_interface.hpp deleted file mode 100644 index e69de29..0000000 diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/crc16.hpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/util/crc16.hpp similarity index 100% rename from i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/crc16.hpp rename to i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/util/crc16.hpp diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/protocol.hpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/util/protocol.hpp similarity index 85% rename from i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/protocol.hpp rename to i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/util/protocol.hpp index 3173946..38149d7 100644 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/protocol.hpp +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/util/protocol.hpp @@ -12,6 +12,10 @@ enum GobotRPCTypes { ERROR = 0b10 }; +struct GobotRPCPackage_Req_Vacum { + uint8_t enable : 8; +}; + #define GobotRPC_Package_DATA_OFFSET 2 #define CALC_SIZE_GobotRPC_PACKAGE(data_len) (data_len + GobotRPC_Package_DATA_OFFSET + 2) @@ -24,5 +28,6 @@ public: void assembleGobotRPCHeader(char * buffer, GobotRPCNumber number, GobotRPCTypes data_size, size_t); void assembleCRC(char * buffer, size_t data_len); +bool checkCRC(char * buffer, size_t data_len); GobotRPCHeaderInfo extractGobotRPCHeader(char * buffer); \ No newline at end of file diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/include/node_interface.hpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/include/node_interface.hpp new file mode 100644 index 0000000..17d90db --- /dev/null +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/include/node_interface.hpp @@ -0,0 +1,32 @@ +#pragma once +#include "protocol.hpp" +#include "node_interface_hardware.hpp" + +#include "FreeRTOSConfig.h" +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +typedef void (*onPackageRxCallback)(void * args, char *data, uint16_t len, GobotRPCTypes type, GobotRPCNumber number); + +class GobotRPC_NI { +private: + onPackageRxCallback onPackageRx; + void *onPackageRxArgs; + + QueueHandle_t txQueue; + QueueHandle_t rxQueue; + TaskHandle_t rxTaskHandle; + + unsigned int core; + +public: + GobotRPC_NI(unsigned int core, QueueHandle_t txQueue, QueueHandle_t rxQueue); + + void registerOnPackageRxCallback(onPackageRxCallback callback, void *context); + void sendPackage(char *data, size_t len, GobotRPCTypes type, GobotRPCNumber number); + + void rxTask(); + + +}; \ No newline at end of file diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/include/node_interface_hardware.hpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/include/node_interface_hardware.hpp new file mode 100644 index 0000000..3dbae54 --- /dev/null +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/include/node_interface_hardware.hpp @@ -0,0 +1,78 @@ +#pragma once + +#include "FreeRTOSConfig.h" +#include "FreeRTOS.h" +#include "queue.h" + +#include "pico/stdlib.h" +#include "hardware/i2c.h" +#include "hardware/irq.h" + +struct GobotRPC_NI_Package_Transport { + char data[32]; + uint length; + uint index; +}; + +enum I2C_WRITE_STATE { + I2C_WRITE_STATE_FIRST, + I2C_WRITE_STATE_LENGTH, + I2C_WRITE_STATE_DATA, +}; + +enum I2C_READ_STATE { + I2C_READ_STAGE_FIRST, + I2C_READ_STAGE_DONE, + I2C_READ_STAGE_WIP, + I2C_READ_STAGE_INVALID +}; + +enum I2C_SLAVE_EVENT { + I2C_SLAVE_RECEIVE, + I2C_SLAVE_REQUEST, + I2C_SLAVE_FINISH +}; + +class GobotRPC_NI_Hardware { + +}; + +struct GobotRPC_NI_Hardware_RP2040_I2C_PreTxQueues { + QueueHandle_t isrPreTxQueue; + QueueHandle_t isrTXQueue; +}; + +class GobotRPC_NI_Hardware_RP2040_I2C : public GobotRPC_NI_Hardware { + uint core; + + QueueHandle_t isrPreTxQueue; + QueueHandle_t isrTXQueue; + QueueHandle_t isrRXQueue; + TaskHandle_t preTxTaskHandle; + + uint i2cSDA_PIN; + uint i2cSCL_PIN; + uint int_PIN; + uint8_t i2cAddress; + + I2C_WRITE_STATE writeState = I2C_WRITE_STATE_FIRST; + I2C_READ_STATE readState = I2C_READ_STAGE_INVALID; + + GobotRPC_NI_Package_Transport rxPackage; + GobotRPC_NI_Package_Transport txPackage; + +public: + i2c_inst_t * i2c_inst; + + GobotRPC_NI_Hardware_RP2040_I2C( + xQueueHandle TXQueue, xQueueHandle RXQueue, uint core, + i2c_inst_t * i2c_inst, + uint8_t i2cAddress, + uint i2cSDA_PIN, uint i2cSCL_PIN, uint int_PIN + ); + + void onI2CIRQ(I2C_SLAVE_EVENT event, BaseType_t * xHigherPriorityTaskWoken); + void preTxTask(); +}; + +extern GobotRPC_NI_Hardware_RP2040_I2C * g_gobotrpc_ni_hardware_rp2040_i2c; diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/init.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/init.cpp new file mode 100644 index 0000000..676b3f2 --- /dev/null +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/init.cpp @@ -0,0 +1,66 @@ +#include "node_interface.hpp" + +#include "FreeRTOS.h" +#include "task.h" +#include + +static void rxTaskFn(void *pvParameters) { + GobotRPC_NI *ni = (GobotRPC_NI *)pvParameters; + ni->rxTask(); +} + +GobotRPC_NI::GobotRPC_NI(unsigned int core, QueueHandle_t txQueue, QueueHandle_t rxQueue) { + this->core = core; + + this->txQueue = txQueue; + this->rxQueue = rxQueue; + + this->onPackageRx = NULL; + this->onPackageRxArgs = NULL; + + xTaskCreateAffinitySet( + rxTaskFn, + "GobotRPC_NI RX Task", + 2048, + this, + 4, + this->core, + &this->rxTaskHandle + ); +} + +void GobotRPC_NI::registerOnPackageRxCallback(onPackageRxCallback callback, void *context) { + this->onPackageRx = callback; + this->onPackageRxArgs = context; +} + +void GobotRPC_NI::rxTask() { + while (true) { + GobotRPC_NI_Package_Transport package; + + if (xQueueReceive(this->rxQueue, &package, portMAX_DELAY) == pdTRUE) { + GobotRPCHeaderInfo header = extractGobotRPCHeader(package.data); + + if(this->onPackageRx != NULL) { + if (!checkCRC(package.data, header.len)) { + volatile int a = 0; + continue; + } + + this->onPackageRx( + onPackageRxArgs, + package.data + GobotRPC_Package_DATA_OFFSET, + header.len, header.type, header.number + ); + } + } + } +} + +void GobotRPC_NI::sendPackage(char *data, size_t len, GobotRPCTypes type, GobotRPCNumber number) { + GobotRPC_NI_Package_Transport package; + memcpy(package.data + GobotRPC_Package_DATA_OFFSET, data, len); + assembleGobotRPCHeader(package.data, number, type, len); + assembleCRC(package.data, len); + xQueueSend(this->txQueue, &package, portMAX_DELAY); +} diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/rp2040/i2c/init.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/rp2040/i2c/init.cpp new file mode 100644 index 0000000..3bf2ea1 --- /dev/null +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/rp2040/i2c/init.cpp @@ -0,0 +1,124 @@ +#include "node_interface_hardware.hpp" +#include "pico/stdlib.h" +#include "hardware/i2c.h" +#include + +GobotRPC_NI_Hardware_RP2040_I2C * g_gobotrpc_ni_hardware_rp2040_i2c; +i2c_inst_t * g_i2c_inst; +bool g_transfer_in_progress = false; + +static void finish_transfer(BaseType_t * xHigherPriorityTaskWoken) { + if(g_transfer_in_progress) { + GobotRPC_NI_Hardware_RP2040_I2C * gobotrpc_ni = g_gobotrpc_ni_hardware_rp2040_i2c; + g_transfer_in_progress = false; + gobotrpc_ni->onI2CIRQ(I2C_SLAVE_FINISH, xHigherPriorityTaskWoken); + } +} + +static void i2c_isr() { + GobotRPC_NI_Hardware_RP2040_I2C * gobotrpc_ni = g_gobotrpc_ni_hardware_rp2040_i2c; + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + i2c_hw_t * hw = i2c_get_hw(g_i2c_inst); + uint32_t intr_stat = hw->intr_stat; + + if (intr_stat == 0) { + return; + } + + if (intr_stat & I2C_IC_INTR_STAT_R_TX_ABRT_BITS) { + hw->clr_tx_abrt; + finish_transfer(&xHigherPriorityTaskWoken); + } + + if (intr_stat & I2C_IC_INTR_STAT_R_START_DET_BITS) { + hw->clr_start_det; + finish_transfer(&xHigherPriorityTaskWoken); + } + + if (intr_stat & I2C_IC_INTR_STAT_R_STOP_DET_BITS) { + hw->clr_stop_det; + finish_transfer(&xHigherPriorityTaskWoken); + } + + if (intr_stat & I2C_IC_INTR_STAT_R_RX_FULL_BITS) { + g_transfer_in_progress = true; + gobotrpc_ni->onI2CIRQ(I2C_SLAVE_RECEIVE, &xHigherPriorityTaskWoken); + } + + if (intr_stat & I2C_IC_INTR_STAT_R_RD_REQ_BITS) { + hw->clr_rd_req; + g_transfer_in_progress = true; + gobotrpc_ni->onI2CIRQ(I2C_SLAVE_REQUEST, &xHigherPriorityTaskWoken); + } + + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +} + +static void preTxTaskFn(void *pvParameters) { + GobotRPC_NI_Hardware_RP2040_I2C * hw = (GobotRPC_NI_Hardware_RP2040_I2C *)(pvParameters); + hw->preTxTask(); +}; + +GobotRPC_NI_Hardware_RP2040_I2C::GobotRPC_NI_Hardware_RP2040_I2C( + xQueueHandle TXQueue, xQueueHandle RXQueue, uint core, + i2c_inst_t * i2c_inst, + uint8_t i2cAddress, + uint i2cSDA_PIN, uint i2cSCL_PIN, uint int_PIN +) { + g_gobotrpc_ni_hardware_rp2040_i2c = this; + g_i2c_inst = i2c_inst; + + this->core = core; + + this->isrRXQueue = RXQueue; + this->isrPreTxQueue = TXQueue; + this->isrTXQueue = xQueueCreate(3, sizeof(GobotRPC_NI_Package_Transport)); + + xTaskCreateAffinitySet( + preTxTaskFn, + "GobotRPC_NI Hardware RP2040 I2C PreTx Task", + 2048, + this, + 4, + this->core, + &this->preTxTaskHandle + ); + + this->i2cSDA_PIN = i2cSDA_PIN; + this->i2cSCL_PIN = i2cSCL_PIN; + this->int_PIN = int_PIN; + + this->i2cAddress = i2cAddress; + this->i2c_inst = i2c_inst; + + memset(&rxPackage.data, 0, sizeof(GobotRPC_NI_Package_Transport::data)); + memset(&txPackage.data, 0, sizeof(GobotRPC_NI_Package_Transport::data)); + + gpio_init(i2cSDA_PIN); + gpio_init(i2cSCL_PIN); + gpio_set_function(i2cSDA_PIN, GPIO_FUNC_I2C); + gpio_set_function(i2cSCL_PIN, GPIO_FUNC_I2C); + + gpio_init(int_PIN); + gpio_set_dir(int_PIN, GPIO_OUT); + gpio_put(int_PIN, 0); + + // Note: The I2C slave does clock stretching implicitly after a RD_REQ, while the Tx FIFO is empty. + // There is also an option to enable clock stretching while the Rx FIFO is full, but we leave it + // disabled since the Rx FIFO should never fill up (unless slave->handler() is way too slow). + i2c_set_slave_mode(i2c_inst, true, i2cAddress); + + i2c_hw_t *hw = i2c_get_hw(i2c_inst); + // unmask necessary interrupts + hw->intr_mask = I2C_IC_INTR_MASK_M_RX_FULL_BITS |\ + I2C_IC_INTR_MASK_M_RD_REQ_BITS |\ + I2C_IC_RAW_INTR_STAT_TX_ABRT_BITS |\ + I2C_IC_INTR_MASK_M_STOP_DET_BITS |\ + I2C_IC_INTR_MASK_M_START_DET_BITS; + + // enable interrupt for current core + unsigned int intNum = i2c_inst == i2c0 ? I2C0_IRQ : I2C1_IRQ; + irq_set_exclusive_handler(intNum, i2c_isr); + irq_set_enabled(intNum, true); +} diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/rp2040/i2c/rx_tx.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/rp2040/i2c/rx_tx.cpp new file mode 100644 index 0000000..91c1c8d --- /dev/null +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/node_interface/rp2040/i2c/rx_tx.cpp @@ -0,0 +1,98 @@ +#include "node_interface_hardware.hpp" +#include "hardware/irq.h" + +void GobotRPC_NI_Hardware_RP2040_I2C::onI2CIRQ(I2C_SLAVE_EVENT event, BaseType_t * xHigherPriorityTaskWoken) { + + switch (event) { + case I2C_SLAVE_RECEIVE: { // I2C Write from Master + char data = i2c_read_byte_raw(i2c_inst); + + switch (writeState) { + case I2C_WRITE_STATE_FIRST: + writeState = I2C_WRITE_STATE_LENGTH; + rxPackage.index = 0; + rxPackage.length = 0; + rxPackage.data[rxPackage.index++] = data; + break; + + case I2C_WRITE_STATE_LENGTH: + rxPackage.data[rxPackage.index++] = data; + rxPackage.length = data; + writeState = I2C_WRITE_STATE_DATA; + break; + + case I2C_WRITE_STATE_DATA: + rxPackage.data[rxPackage.index++] = data; + + if(rxPackage.index == rxPackage.length) { + xQueueSendFromISR(isrRXQueue, &rxPackage, xHigherPriorityTaskWoken); + writeState = I2C_WRITE_STATE_FIRST; + } else { + writeState = I2C_WRITE_STATE_DATA; + } + + break; + + default: + break; + } + + break; + } + + case I2C_SLAVE_REQUEST: { // I2C Read from Master + if(xQueueIsQueueEmptyFromISR(isrTXQueue) == pdFALSE) { + readState = I2C_READ_STAGE_INVALID; + } + + switch (readState) { + case I2C_READ_STAGE_INVALID: + i2c_write_byte_raw(i2c_inst, 0x00); + break; + + case I2C_READ_STAGE_FIRST: + xQueueReceiveFromISR(isrTXQueue, &txPackage, xHigherPriorityTaskWoken); + txPackage.index = 0; + i2c_write_byte_raw(i2c_inst, txPackage.data[txPackage.index++]); + readState = I2C_READ_STAGE_WIP; + break; + + case I2C_READ_STAGE_WIP: + if(txPackage.index == txPackage.length - 1) { + readState = I2C_READ_STAGE_DONE; + } else { + i2c_write_byte_raw(i2c_inst, txPackage.data[txPackage.index++]); + } + break; + + case I2C_READ_STAGE_DONE: + i2c_write_byte_raw(i2c_inst, 0x00); + break; + + default: + break; + } + + break; + } + + case I2C_SLAVE_FINISH: + writeState = I2C_WRITE_STATE_FIRST; + readState = I2C_READ_STAGE_FIRST; + rxPackage.index = 0; + break; + + default: + break; + } +} + +void GobotRPC_NI_Hardware_RP2040_I2C::preTxTask() { + GobotRPC_NI_Package_Transport pkg; + + while (1) { + xQueueReceive(isrPreTxQueue, &pkg, portMAX_DELAY); + xQueueSend(isrTXQueue, &pkg, portMAX_DELAY); + gpio_put(int_PIN, 1); + } +} \ No newline at end of file diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/protocol_base.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/protocol_base.cpp index 71e5eda..c3825c3 100644 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/protocol_base.cpp +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/protocol_base.cpp @@ -22,4 +22,10 @@ void assembleCRC(char * buffer, size_t data_len) { unsigned short crc = crc16(buffer, data_len + GobotRPC_Package_DATA_OFFSET); buffer[GobotRPC_Package_DATA_OFFSET + data_len + 1] = crc & 0xff; buffer[GobotRPC_Package_DATA_OFFSET + data_len + 0] = (crc >> 8) & 0xff; +} + +bool checkCRC(char * buffer, size_t data_len) { + unsigned short crc = crc16(buffer, data_len - 2); + unsigned short crc_received = buffer[data_len - GobotRPC_Package_DATA_OFFSET + 1] | (buffer[data_len - GobotRPC_Package_DATA_OFFSET + 0] << 8); + return crc == crc_received; } \ No newline at end of file diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/transmission_interface/rp2040_i2c_tx.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/transmission_interface/rp2040_i2c_tx.cpp index 4014354..5fd113e 100644 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/transmission_interface/rp2040_i2c_tx.cpp +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/transmission_interface/rp2040_i2c_tx.cpp @@ -17,7 +17,7 @@ void GobotRPC_TI_Hardware_RP2040_I2C::i2cTxTask() { pullPackageCB(&pkg, pullPackageCBArgs); xSemaphoreTake(i2cMutex, portMAX_DELAY); - unsigned int res = i2c_write_burst_blocking(i2c, pkg.addr & 0x7f, (uint8_t *)(&pkg.data), pkg.len); + unsigned int res = i2c_write_blocking(i2c, pkg.addr & 0x7f, (uint8_t * )(pkg.data), pkg.len, false); xSemaphoreGive(i2cMutex); if(res == PICO_ERROR_GENERIC) { diff --git a/i2c-hub/pulseview-i2c-session b/i2c-hub/pulseview-i2c-session new file mode 100644 index 0000000000000000000000000000000000000000..a778a22ef93a533eb24d5da36619fc030483cd8a GIT binary patch literal 490 zcmWIWW@Zs#00Dy*l_=hQSEU$%Y!GG#;`R!qX4ifCI$|$DjlBF1yg~tXMmUk zh;vg*5>paO5_L~+taRwo(Zm;1~xAZj13JBt=YbXy-LzM<8RWl?uI9mx8-oxE$WbU z`Fl@?buNeM^PIi&|2tX#jh%2%5CsiEm?m672+_j8 nu&q%I$bbuttonTaskFn(); } -VacumControl::VacumControl() { +VacumControl::VacumControl(uint coreMask) { + this->coreMask = coreMask; initVacumPins(); state = false; vacumMutex = xSemaphoreCreateMutex(); interruptionSemaphore = xSemaphoreCreateBinary(); - xTaskCreate(vInterruptionTaskFn, "Interruption Task", 1024, this, 3, &interruptionTask); - xTaskCreate(vButtonTaskFn, "Button Task", 1024, this, 2, &buttonTask); + xTaskCreateAffinitySet(vInterruptionTaskFn, "Interruption Task", 1024, this, 3, coreMask, &interruptionTask); + xTaskCreateAffinitySet(vButtonTaskFn, "Button Task", 1024, this, 2, coreMask, &buttonTask); } void VacumControl::initVacumPins() { diff --git a/vacum-control/vacum-control-firmware/src/main.cpp b/vacum-control/vacum-control-firmware/src/main.cpp index 39a2e1c..2523927 100644 --- a/vacum-control/vacum-control-firmware/src/main.cpp +++ b/vacum-control/vacum-control-firmware/src/main.cpp @@ -1,4 +1,5 @@ #include +#include #include "pico/stdlib.h" #include "vacum.hpp" @@ -6,22 +7,88 @@ #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" +#include "queue.h" -void vTaskFunction(void *pvParameters) { - while (true) { - printf("Button: %d\n", gpio_get(BUTTON_PIN)); - vTaskDelay(pdMS_TO_TICKS(1000)); +#include "hardware/i2c.h" + +#include "pinConfigNode.hpp" +#include "node_interface_hardware.hpp" +#include "node_interface.hpp" +#include "protocol.hpp" + +struct AppData { + xQueueHandle txQueue; + xQueueHandle rxQueue; + VacumControl * vacumControl; + GobotRPC_NI * gobotrpc_ni; +}; + +AppData g_appData; + +void onRxPackage(void * args, char *data, uint16_t len, GobotRPCTypes type, GobotRPCNumber number) { + AppData * appData = (AppData *) args; + char txBuffer[32]; + + switch (number) { + case GobotRPCNumber::VACUM: { + GobotRPCPackage_Req_Vacum * pkg = (GobotRPCPackage_Req_Vacum *) data; + appData->vacumControl->setState(pkg->enable); + g_appData.gobotrpc_ni->sendPackage(txBuffer, 0, GobotRPCTypes::RESPONSE, GobotRPCNumber::VACUM); + break; + } + + default: { + break; + } } } +void core1_main(void *pvParameters) { + AppData * appData = (AppData *) pvParameters; + GobotRPC_NI_Hardware_RP2040_I2C gobotrpc_ni_hardware( + appData->txQueue, appData->rxQueue, CORE_MASK_VACUM, + i2c0, 0x21, GORPC_SDA_PIN, GORPC_SCL_PIN, GORPC_INT_PIN + ); + + while (true) { + gpio_put(LED2_PIN, 0); + vTaskDelay(500 / portTICK_PERIOD_MS); + gpio_put(LED2_PIN, 1); + vTaskDelay(500 / portTICK_PERIOD_MS); + } +} + +TaskHandle_t xCore0TaskHandle = NULL; +TaskHandle_t xCore1TaskHandle = NULL; + int main() { stdio_init_all(); printf("Hello, world!\n"); - VacumControl vacumControl; + gpio_init(LED1_PIN); + gpio_set_dir(LED1_PIN, GPIO_OUT); + gpio_put(LED1_PIN, 1); + + gpio_init(LED2_PIN); + gpio_set_dir(LED2_PIN, GPIO_OUT); + gpio_put(LED2_PIN, 1); + + g_appData.txQueue = xQueueCreate(16, sizeof(GobotRPC_NI_Package_Transport)); + g_appData.rxQueue = xQueueCreate(16, sizeof(GobotRPC_NI_Package_Transport)); + + VacumControl vacumControl = VacumControl(CORE_MASK_VACUM); vacumControl.setState(false); - - xTaskCreate(vTaskFunction, "Main Task", 1024, NULL, tskIDLE_PRIORITY, NULL); + g_appData.vacumControl = &vacumControl; + + GobotRPC_NI gobotrpc_ni(CORE_MASK_VACUM, g_appData.txQueue, g_appData.rxQueue); + gobotrpc_ni.registerOnPackageRxCallback(onRxPackage, &g_appData); + + g_appData.gobotrpc_ni = &gobotrpc_ni; + + xTaskCreateAffinitySet( + core1_main, "Core 1 Main", 2048, &g_appData, 1, CORE_MASK_VACUM, &xCore1TaskHandle + ); + vTaskStartScheduler(); while (true) {