diff --git a/i2c-hub/firmware/i2c-hub-firmware/CMakeLists.txt b/i2c-hub/firmware/i2c-hub-firmware/CMakeLists.txt index cb95956..fabc90e 100644 --- a/i2c-hub/firmware/i2c-hub-firmware/CMakeLists.txt +++ b/i2c-hub/firmware/i2c-hub-firmware/CMakeLists.txt @@ -58,7 +58,7 @@ target_link_libraries(i2c-hub-firmware GobotRPC pico_stdlib ) - + # Add the standard include files to the build target_include_directories(i2c-hub-firmware PRIVATE ${CMAKE_CURRENT_LIST_DIR} 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 6768d38..fca7327 100644 --- a/i2c-hub/firmware/i2c-hub-firmware/docs/.$NetworkStack.drawio.bkp +++ b/i2c-hub/firmware/i2c-hub-firmware/docs/.$NetworkStack.drawio.bkp @@ -1,6 +1,6 @@ - + @@ -627,7 +627,7 @@ - + @@ -735,8 +735,8 @@ - - + + @@ -751,25 +751,204 @@ - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/i2c-hub/firmware/i2c-hub-firmware/docs/NetworkStack.drawio b/i2c-hub/firmware/i2c-hub-firmware/docs/NetworkStack.drawio index a3ca9d7..25e1878 100644 --- a/i2c-hub/firmware/i2c-hub-firmware/docs/NetworkStack.drawio +++ b/i2c-hub/firmware/i2c-hub-firmware/docs/NetworkStack.drawio @@ -1,6 +1,6 @@ - + @@ -535,10 +535,10 @@ - + - + @@ -627,7 +627,7 @@ - + @@ -822,6 +822,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 3666edb..df66bba 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 @@ -1,14 +1,8 @@ add_library(GobotRPC STATIC - ${CMAKE_CURRENT_LIST_DIR}/../rx.cpp - ${CMAKE_CURRENT_LIST_DIR}/../init.cpp - ${CMAKE_CURRENT_LIST_DIR}/../protocol.cpp - ${CMAKE_CURRENT_LIST_DIR}/../error_msg.cpp - - ${CMAKE_CURRENT_LIST_DIR}/../ctrl_interface/ctrl_interface_base.cpp - ${CMAKE_CURRENT_LIST_DIR}/../ctrl_interface/ctrl_interface_registers.cpp - ${CMAKE_CURRENT_LIST_DIR}/../ctrl_interface/ctrl_interface_rx.cpp - ${CMAKE_CURRENT_LIST_DIR}/../ctrl_interface/ctrl_interface_tx.cpp - ${CMAKE_CURRENT_LIST_DIR}/../ctrl_interface/ctrl_interface_hardware_rp2040.cpp + ${CMAKE_CURRENT_LIST_DIR}/../ctrl_interface/base.cpp + ${CMAKE_CURRENT_LIST_DIR}/../ctrl_interface/hardware_rp2040_uart.cpp + ${CMAKE_CURRENT_LIST_DIR}/../ctrl_interface/hardware_base.cpp + ${CMAKE_CURRENT_LIST_DIR}/../crc16.cpp ) target_include_directories(GobotRPC PUBLIC diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/crc16.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/crc16.cpp new file mode 100644 index 0000000..f3ff135 --- /dev/null +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/crc16.cpp @@ -0,0 +1,37 @@ +#define POLY 0x8408 +/* +// 16 12 5 +// this is the CCITT CRC 16 polynomial X + X + X + 1. +// This works out to be 0x1021, but the way the algorithm works +// lets us use 0x8408 (the reverse of the bit pattern). The high +// bit is always assumed to be set, thus we only use 16 bits to +// represent the 17 bit value. +*/ + +unsigned short crc16(char *data_p, unsigned short length) +{ + unsigned char i; + unsigned int data; + unsigned int crc = 0xffff; + + if (length == 0) + return (~crc); + + do + { + for (i=0, data=(unsigned int)0xff & *data_p++; + i < 8; + i++, data >>= 1) + { + if ((crc & 0x0001) ^ (data & 0x0001)) + crc = (crc >> 1) ^ POLY; + else crc >>= 1; + } + } while (--length); + + crc = ~crc; + data = crc; + crc = (crc << 8) | (data >> 8 & 0xff); + + return (crc); +} diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/base.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/base.cpp new file mode 100644 index 0000000..3252a81 --- /dev/null +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/base.cpp @@ -0,0 +1,59 @@ +#include "ctrl_interface.hpp" +#include "pinConfig.hpp" + +#include "FreeRTOSConfig.h" +#include "FreeRTOS.h" +#include "task.h" + + +GobotRPC_CI::GobotRPC_CI(I_GobotRPC_CI_Hardware *hardware) { + this->hardware = hardware; + this->hardware->registerCB_RxData(GobotRPC_CI_rxData_cb, this); + + xTaskCreate(GobotRPC_CI_heartBeatTaskFn, "Heartbeat Task", 2048, this, 2, &this->heartBeatTaskHandle); +} + +// Rx Side +void GobotRPC_CI_rxData_cb(void * args, char *data, size_t len) { + GobotRPC_CI *gobotRPC = (GobotRPC_CI *)args; + gobotRPC->onRxData(data, len); +} + +void GobotRPC_CI::onRxData(char *data, size_t len) { + GobotRPC_CI_CMD cmd = (GobotRPC_CI_CMD)data[0]; + switch (cmd) { + case TX_CI_PACKET: + if(this->cb_TxPacket != NULL) { + this->cb_TxPacket(this->cb_TxPacket_args, data+1, len-1); + } + break; + default: + break; + } +} + +void GobotRPC_CI::registerCB_TxPacket(callback_TxPacket cb, void *args) { + this->cb_TxPacket = cb; + this->cb_TxPacket_args = args; +} + +void GobotRPC_CI::send_RxPacket(char *data, size_t len) { + data[0] = RX_CI_PACKET; + + this->hardware->send(data, len+1); +} + +// Heartbeat Task + +void GobotRPC_CI_heartBeatTaskFn(void *args) { + GobotRPC_CI *gobotRPC = (GobotRPC_CI *)args; + gobotRPC->heartBeartTaskFn(); +} + +void GobotRPC_CI::heartBeartTaskFn() { + char heartBeatPacket[] = {0xff}; + while(1) { + this->hardware->send(heartBeatPacket, 1); + vTaskDelay(GOBOTRPC_HEARTBEAT_INTERVAL / portTICK_PERIOD_MS); + } +} \ No newline at end of file diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/ctrl_interface_base.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/ctrl_interface_base.cpp deleted file mode 100644 index 1fa2796..0000000 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/ctrl_interface_base.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "ctrl_interface.hpp" -#include -#include -#include - -GobotRPC_CtrlInterface::GobotRPC_CtrlInterface(I_GobotRPC_CtrlInterface_HardwareHandler *ctrlInterface) { - this->handler = ctrlInterface; - handler->registerCallback(externalCallback_RX, this); - handler->registerHeartBeatCallback(externalCallback_HeartBeat, this); - - packetCallback = nullptr; - performScanCallback = nullptr; - getInfoCallback = nullptr; - reqSlotUpdateCallback = nullptr; - - packetCallbackArgs = nullptr; - performScanCallbackArgs = nullptr; - getInfoCallbackArgs = nullptr; - reqSlotUpdateCallbackArgs = nullptr; -} - -void GobotRPC_CtrlInterface::printf(const char *fmt, ...) { - char buffer[256]; - va_list args; - va_start(args, fmt); - - vsnprintf(buffer, 256, fmt, args); - handler->send(buffer, strlen(buffer)); -} - -// Sending HeartBeat -void GobotRPC_CtrlInterface::onHeartBeat() { - char buffer = GOBOTRPC_CTRL_CMD_HEART_BEAT; - handler->send(&buffer, 1); -} - -void externalCallback_HeartBeat(void * args) { - GobotRPC_CtrlInterface *ctrlInterface = (GobotRPC_CtrlInterface *)args; - ctrlInterface->onHeartBeat(); -} \ No newline at end of file diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/ctrl_interface_hardware_rp2040.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/ctrl_interface_hardware_rp2040.cpp deleted file mode 100644 index 5ee5931..0000000 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/ctrl_interface_hardware_rp2040.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include "ctrl_interface.hpp" - -#ifdef GOBOTRPC_PLATFORM_RP2040 -#include "pico/stdlib.h" -#include "hardware/uart.h" -#include "hardware/irq.h" - -#include "FreeRTOS.h" -#include "semphr.h" -#include "task.h" - -#define STOP_BITS 1 -#define PARITY UART_PARITY_ODD - -GobotRPC_CtrlInterface_HardwareHandler_RP2040 * g_uart_hardware_handler; - -GobotRPC_CtrlInterface_HardwareHandler_RP2040::GobotRPC_CtrlInterface_HardwareHandler_RP2040( - uart_inst_t * uart_instance, uint baudrate, uint heartBeatDelay, - uint tx_pin, uint rx_pin) { - - callback_rx = nullptr; - callback_args = nullptr; - callback_heart_beat = nullptr; - callback_heart_beat_args = nullptr; - - this->heartBeatDelay = heartBeatDelay; - - this->rxSemphrHandle = xSemaphoreCreateCounting(16, 0); - g_uart_hardware_handler = this; - xTaskCreate(vTaskRxHandler, "gobotrpc_ctrl_interface_uart_rx", 1024, this, 3, &this->rxTaskHandle); - xTaskCreate(vTaskHeartBeat, "gobotrpc_ctrl_interface_heart_beat", 1024, this, 2, &this->heartBeatTaskHandle); - - gpio_set_function(tx_pin, UART_FUNCSEL_NUM(uart_instance, tx_pin)); - gpio_set_function(rx_pin, UART_FUNCSEL_NUM(uart_instance, rx_pin)); - - uart_init(uart_instance, baudrate); - this->uart_instance = uart_instance; - - uart_set_format(uart_instance, 8, STOP_BITS, PARITY); - - this->UART_IRQ = uart_instance == uart0 ? UART0_IRQ : UART1_IRQ; - irq_set_exclusive_handler(UART_IRQ, isrUartRX); - irq_set_enabled(UART_IRQ, true); - - uart_set_irq_enables(uart_instance, true, false); - uart_set_fifo_enabled(uart_instance, true); -} - -void GobotRPC_CtrlInterface_HardwareHandler_RP2040::send(char * data, size_t length) { - uart_write_blocking(uart_instance, (const uint8_t *)data, length); - uart_tx_wait_blocking(uart_instance); -} - -void GobotRPC_CtrlInterface_HardwareHandler_RP2040::registerCallback(GobotRPC_CtrlInterface_Callback_RX callback, void * args) { - this->callback_rx = callback; - this->callback_args = args; -} - -void GobotRPC_CtrlInterface_HardwareHandler_RP2040::rxTaskHandler() { - char inputBuffer[128]; - size_t length = 0; - - while (true) { - xSemaphoreTake(rxSemphrHandle, portMAX_DELAY); - - for(length = 0; length<128 && uart_is_readable(uart_instance); length++) { - inputBuffer[length] = uart_getc(uart_instance); - } - - if (length > 0 && this->callback_rx != nullptr) { - this->callback_rx(this->callback_args, inputBuffer, length); - } - } -} - -void GobotRPC_CtrlInterface_HardwareHandler_RP2040::heartBeatTaskHandler() { - while (true) { - if (this->callback_heart_beat != nullptr) { - this->callback_heart_beat(this->callback_heart_beat_args); - } - - vTaskDelay(this->heartBeatDelay / portTICK_PERIOD_MS); - } -} - -void GobotRPC_CtrlInterface_HardwareHandler_RP2040::registerHeartBeatCallback(GobotRPC_CtrlInterface_Callback_HeartBeat callback, void * args) { - this->callback_heart_beat = callback; - this->callback_heart_beat_args = args; -} - -void GobotRPC_CtrlInterface_HardwareHandler_RP2040::scheduleRXHandler(BaseType_t * higher_priority_task_woken) { - irq_clear(this->UART_IRQ); - if (this->callback_rx != nullptr) { - xSemaphoreGiveFromISR(rxSemphrHandle, higher_priority_task_woken); - } -} - -void vTaskRxHandler(void * pvParameters) { - g_uart_hardware_handler->rxTaskHandler(); -} - -void vTaskHeartBeat(void * pvParameters) { - g_uart_hardware_handler->heartBeatTaskHandler(); -} - -void isrUartRX() { - static BaseType_t higher_priority_task_woken = pdFALSE; - g_uart_hardware_handler->scheduleRXHandler(&higher_priority_task_woken); - portYIELD_FROM_ISR(higher_priority_task_woken); -} - - -#endif \ No newline at end of file diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/ctrl_interface_registers.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/ctrl_interface_registers.cpp deleted file mode 100644 index 0037ba2..0000000 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/ctrl_interface_registers.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "ctrl_interface.hpp" -#include - -void GobotRPC_CtrlInterface::registerCallback_Packet(GobotRPC_CtrlInterface_Callback_Packet callback, void *args) { - packetCallback = callback; - packetCallbackArgs = args; -} - -void GobotRPC_CtrlInterface::registerCallback_PerformScan(GobotRPC_CtrlInterface_Callback_PerformScan callback, void *args) { - performScanCallback = callback; - performScanCallbackArgs = args; -} - -void GobotRPC_CtrlInterface::registerCallback_ReqSlotUpdate(GobotRPC_CtrlInterface_Callback_ReqSlotUpdate callback, void *args) { - reqSlotUpdateCallback = callback; - reqSlotUpdateCallbackArgs = args; -} - -void GobotRPC_CtrlInterface::registerCallback_GetInfo(GobotRPC_CtrlInterface_Callback_GetInfo callback, void *args) { - getInfoCallback = callback; - getInfoCallbackArgs = args; -} \ No newline at end of file diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/ctrl_interface_rx.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/ctrl_interface_rx.cpp deleted file mode 100644 index a0e85c0..0000000 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/ctrl_interface_rx.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include "ctrl_interface.hpp" -#include "gobotrpc.hpp" -#include - -void externalCallback_RX(void * args, char * data, size_t length) { - GobotRPC_CtrlInterface *interface = (GobotRPC_CtrlInterface *)args; - interface->onRX(data, length); -} - -void GobotRPC_CtrlInterface::onRX(char * data, size_t length) { - uint8_t cmd = data[0]; - switch (cmd) { - case GOBOTRPC_CTRL_CMD_PACKET: - onRX_Packet(data, length); - break; - - case GOBOTRPC_CTRL_CMD_PERFORM_SCAN: - onRX_PerformScan(data, length); - break; - - case GOBOTRPC_CTRL_CMD_REQ_SLOT_UPDATE: - onRX_ReqSlotUpdate(data, length); - break; - - case GOBOTRPC_CTRL_CMD_INFO: - onRX_GetInfo(data, length); - break; - - default: - break; - } -} - -void GobotRPC_CtrlInterface::onRX_Packet(char *data, size_t length) { - if(length < 7) - return; - - - if (packetCallback != nullptr) { - RPCPackage package; - package.length = data[1]; - package.type = RPCType(data[2] & 0b11); - package.rpcNum = RPCNumber(data[2] >> 4); - memcpy(&package.addr, &data[3], 4); - memcpy(package.buffer, &data[7], package.length); - - packetCallback(packetCallbackArgs, package); - } -} - -void GobotRPC_CtrlInterface::onRX_PerformScan(char *data, size_t length) { - if(length < 2) - return; - - if (performScanCallback != nullptr) - performScanCallback(performScanCallbackArgs, data[1] == 1); -} - -void GobotRPC_CtrlInterface::onRX_ReqSlotUpdate(char *data, size_t length) { - if (length < 2) - return; - - if (reqSlotUpdateCallback != nullptr) - reqSlotUpdateCallback(reqSlotUpdateCallbackArgs, data[1] == 1); -} - -void GobotRPC_CtrlInterface::onRX_GetInfo(char *data, size_t length) { - if (length < 1) - return; - - if (getInfoCallback != nullptr) - getInfoCallback(getInfoCallbackArgs); -} \ No newline at end of file diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/ctrl_interface_tx.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/ctrl_interface_tx.cpp deleted file mode 100644 index d374c73..0000000 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/ctrl_interface_tx.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "ctrl_interface.hpp" -#include - -// This function should be called when a package is sent -void GobotRPC_CtrlInterface::pushPacket(RPCPackage package) { - char buffer[MAX_PAGE_SIZES + 7]; - - buffer[0] = GOBOTRPC_CTRL_CMD_PACKET; - buffer[1] = package.length - 7; - buffer[2] = package.type | (package.rpcNum << 4); - memcpy(&buffer[3], &package.addr, 4); - memcpy(&buffer[7], package.buffer, package.length); - - handler->send(buffer, package.length + 2); -} - -void GobotRPC_CtrlInterface::pushScanResulst(uint32_t addr, bool running) { - char buffer[7]; - - buffer[0] = GOBOTRPC_CTRL_CMD_SCAN_RESULT; - buffer[1] = running ? 1 : 0; - memcpy(&buffer[2], &addr, 4); - buffer[6] = 0; // This is where the type would go - - handler->send(buffer, 7); -} - -void GobotRPC_CtrlInterface::pushPackageSlotUpdate(bool complete, bool inUse, uint32_t slot, uint32_t addr, uint32_t timestamp, uint32_t bits) { - char buffer[16]; - - buffer[0] = GOBOTRPC_CTRL_CMD_SLOT_UPDATE; - buffer[1] = complete ? 1 : 0; - buffer[2] = inUse ? 1 : 0; - buffer[3] = slot; - memcpy(&buffer[4], &addr, 4); - memcpy(&buffer[8], ×tamp, 4); - memcpy(&buffer[12], &bits, 4); - - handler->send(buffer, 14); -} - -void GobotRPC_CtrlInterface::pushInfo(uint8_t slotNumbers) { - char buffer[2]; - - buffer[0] = GOBOTRPC_CTRL_CMD_INFO; - buffer[1] = slotNumbers; - - handler->send(buffer, 2); -} \ No newline at end of file diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/hardware_base.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/hardware_base.cpp new file mode 100644 index 0000000..0251667 --- /dev/null +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/hardware_base.cpp @@ -0,0 +1,2 @@ +#include "ctrl_interface_hardware.hpp" + diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/hardware_rp2040_uart.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/hardware_rp2040_uart.cpp new file mode 100644 index 0000000..e5c1a6b --- /dev/null +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/ctrl_interface/hardware_rp2040_uart.cpp @@ -0,0 +1,107 @@ +#include "ctrl_interface_hardware.hpp" +#include "pinConfig.hpp" + +#include "pico/stdlib.h" +#include "hardware/uart.h" + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include + +// Initialize stuff +GobotRPC_CI_Hardware_RP2040_UART * g_GobotRPC_CI_Hardware_RP2040_UART; + +GobotRPC_CI_Hardware_RP2040_UART::GobotRPC_CI_Hardware_RP2040_UART(uart_inst_t *uart, uint baudrate) { + g_GobotRPC_CI_Hardware_RP2040_UART = this; + + emptyInputBuffersQueue = xQueueCreate(NUM_INPUT_BUFFERS, sizeof(inputBuffers_t *)); + filledInputBuffersQueue = xQueueCreate(NUM_INPUT_BUFFERS, sizeof(inputBuffers_t *)); + + for(int i = 0; i < NUM_INPUT_BUFFERS; i++) { + inputBuffers_t * p = &inputBufferPool[i]; + memset(p->data, 0xff, 256); + p->len = 0; + xQueueSend(emptyInputBuffersQueue, &p, portMAX_DELAY); + } + + txMutex = xSemaphoreCreateMutex(); + + this->uart = uart; + uart_init(this->uart, baudrate); + + gpio_set_function(GOBOTRPC_CI_UART_RX, UART_FUNCSEL_NUM(uart, GOBOTRPC_CI_UART_RX)); + gpio_set_function(GOBOTRPC_CI_UART_TX, UART_FUNCSEL_NUM(uart, GOBOTRPC_CI_UART_TX)); + + uart_set_hw_flow(uart, false, false); + uart_set_format(uart, 8, 1, UART_PARITY_NONE); + uart_set_baudrate(uart, baudrate); + uart_set_fifo_enabled(uart, true); + + int UART_IRQ = uart == uart0 ? UART0_IRQ : UART1_IRQ; + + irq_set_exclusive_handler(UART_IRQ, GobotRPC_CI_Hardware_RP2040_UART_isr); + irq_set_enabled(UART_IRQ, true); + + uart_set_irq_enables(uart, true, false); + + + xTaskCreate(GobotRPC_CI_Hardware_RP2040_UART_RXTaskFn, "UART RX Task", 2048, this, 4, &this->rxTaskHandle); +} + +void GobotRPC_CI_Hardware_RP2040_UART::registerCB_RxData(callback_rxData cb, void *args) { + this->cb_rxData = cb; + this->cb_rxData_args = args; +} + + +// Sending data +void GobotRPC_CI_Hardware_RP2040_UART::send(char *data, size_t len) { + xSemaphoreTake(txMutex, portMAX_DELAY); + uart_write_blocking(this->uart, (uint8_t *)(data), len); + xSemaphoreGive(txMutex); +} + +// Rx ISR +void GobotRPC_CI_Hardware_RP2040_UART_isr() { + GobotRPC_CI_Hardware_RP2040_UART *uart = (GobotRPC_CI_Hardware_RP2040_UART *)g_GobotRPC_CI_Hardware_RP2040_UART; + uart->rxISR(); +}; + +void GobotRPC_CI_Hardware_RP2040_UART::rxISR() { + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + inputBuffers_t * inputBuffer; + + xQueueReceiveFromISR(emptyInputBuffersQueue, &inputBuffer, &xHigherPriorityTaskWoken); + + int i; + for(i = 0; uart_is_readable(this->uart) && i < 256; i++) { + volatile uint8_t c = uart_getc(this->uart); + inputBuffer->data[i] = c; + } + inputBuffer->len = i; + + xQueueSendFromISR(filledInputBuffersQueue, &inputBuffer, &xHigherPriorityTaskWoken); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +} + +// Rx Task +void GobotRPC_CI_Hardware_RP2040_UART_RXTaskFn(void *args) { + GobotRPC_CI_Hardware_RP2040_UART *uart = (GobotRPC_CI_Hardware_RP2040_UART *)args; + uart->rxTask(); +}; + +void GobotRPC_CI_Hardware_RP2040_UART::rxTask() { + inputBuffers_t * inputBuffer; + + while (1) { + xQueueReceive(filledInputBuffersQueue, &inputBuffer, portMAX_DELAY); + + if(inputBuffer->len > 0) { + cb_rxData(cb_rxData_args, inputBuffer->data, inputBuffer->len); + } + + xQueueSend(emptyInputBuffersQueue, &inputBuffer, portMAX_DELAY); + } +} diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/error_msg.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/error_msg.cpp deleted file mode 100644 index 4773219..0000000 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/error_msg.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "gobotrpc.hpp" -#include - -const char * TEST_MSG_RPC_RESULT_GOOD = "Good"; -const char * TEST_MSG_RPC_RESULT_PACKAGE_READY = "Package Ready"; -const char * TEST_MSG_RPC_RESULT_ERROR_INVALID_FRAMESUBMITIONRESULT = "Invalid FrameSubmitionResult"; -const char * TEST_MSG_RPC_RESULT_ERROR_INVALID_RPC_TYPE = "Invalid RPC Type (0b10)"; -const char * TEST_MSG_RPC_RESULT_ERROR_INVALID_RPC_NUMBER = "Invalid RPC Number"; -const char * TEST_MSG_RPC_RESULT_ERROR_NO_EMPTY_OR_FITTING_SLOT = "No empty or fitting slot for submitted frame"; - -char * mapFrameSubmitionResult2String(FrameSubmitionResult res) { - - switch (res) { - case PENDING: return (char *)(TEST_MSG_RPC_RESULT_GOOD); - case COMPLEATE: return (char *) TEST_MSG_RPC_RESULT_PACKAGE_READY; - - case ERROR_INVALID_RPC_TYPE: return (char *) TEST_MSG_RPC_RESULT_ERROR_INVALID_RPC_TYPE; - case ERROR_INVALID_RPC_NUMBER: return (char *) TEST_MSG_RPC_RESULT_ERROR_INVALID_RPC_NUMBER; - case ERROR_NO_EMPTY_OR_FITTING_SLOT: return (char *) TEST_MSG_RPC_RESULT_ERROR_INVALID_FRAMESUBMITIONRESULT; - } - return (char *) TEST_MSG_RPC_RESULT_ERROR_INVALID_FRAMESUBMITIONRESULT; -} - -void GobotRPCParser::print_out_slots() { - for(int i = 0; i < NUM_SLOTS; i++) { - printf("[%d] %d%d (%x-%d) %d T%08x S=%02d ", i, - buffer[i].is_complete, buffer[i].is_in_use, buffer[i].sender_address, - buffer[i].rpcNum, buffer[i].type, buffer[i].timestamp, buffer[i].length - ); - - for(int j = 0; j < MAX_PAGE_SIZES; j++) { - printf("%02x", buffer[i].buffer[j]); - } - - printf(" "); - - for(int j = 0; j < 32; j++) { - printf("%d", (buffer[i].used_bit_masked >> (31-j)) & 1); - } - - printf("\n"); - } -} diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/crc16.hpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/crc16.hpp new file mode 100644 index 0000000..f3caa33 --- /dev/null +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/crc16.hpp @@ -0,0 +1,2 @@ +#pragma once +unsigned short crc16(char *data_p, unsigned short length); \ No newline at end of file diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/ctrl_interface.hpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/ctrl_interface.hpp index 6d8dfac..4ab5416 100644 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/ctrl_interface.hpp +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/ctrl_interface.hpp @@ -1,63 +1,34 @@ #pragma once -#include -#include "gobotrpc_datatypes.hpp" #include "ctrl_interface_hardware.hpp" +#include -struct HubInfo { - uint8_t slotNumbers; +enum GobotRPC_CI_CMD { + TX_CI_PACKET = 0x01, + RX_CI_PACKET = 0x02, + PERFORM_SCAN_CI_PACKET = 0x03, + SCAN_RESULT_CI_PACKET = 0x04, }; -typedef void (*GobotRPC_CtrlInterface_Callback_Packet)(void * args, RPCPackage package); -typedef void (*GobotRPC_CtrlInterface_Callback_PerformScan)(void * args, bool enable); -typedef void (*GobotRPC_CtrlInterface_Callback_ReqSlotUpdate)(void * args, bool enable); -typedef HubInfo (*GobotRPC_CtrlInterface_Callback_GetInfo)(void * args); +typedef void (*callback_TxPacket)(void * args, char *data, size_t len); +void GobotRPC_CI_rxData_cb(void * args, char *data, size_t len); +void GobotRPC_CI_heartBeatTaskFn(void *args); -void externalCallback_RX(void * args, char * data, size_t length); -void externalCallback_HeartBeat(void * args); - -class GobotRPC_CtrlInterface { +class GobotRPC_CI { private: - GobotRPC_CtrlInterface_Callback_Packet packetCallback; - GobotRPC_CtrlInterface_Callback_PerformScan performScanCallback; - GobotRPC_CtrlInterface_Callback_ReqSlotUpdate reqSlotUpdateCallback; - GobotRPC_CtrlInterface_Callback_GetInfo getInfoCallback; - void * packetCallbackArgs; - void * performScanCallbackArgs; - void * reqSlotUpdateCallbackArgs; - void * getInfoCallbackArgs; + I_GobotRPC_CI_Hardware *hardware; - I_GobotRPC_CtrlInterface_HardwareHandler * handler; -protected: - void onRX_Packet(char * data, size_t length); - void onRX_PerformScan(char * data, size_t length); - void onRX_ReqSlotUpdate(char * data, size_t length); - void onRX_GetInfo(char * data, size_t length); + callback_TxPacket cb_TxPacket; + void * cb_TxPacket_args; + + TaskHandle_t heartBeatTaskHandle; public: - GobotRPC_CtrlInterface(I_GobotRPC_CtrlInterface_HardwareHandler * handler); - void printf(const char *fmt, ...); + GobotRPC_CI(I_GobotRPC_CI_Hardware *hardware); - void onRX(char * data, size_t length); - void onHeartBeat(); + void registerCB_TxPacket(callback_TxPacket cb, void *args); + void send_RxPacket(char *data, size_t len); - void pushPacket(RPCPackage package); - void pushScanResulst(uint32_t addr, bool running); - void pushPackageSlotUpdate(bool complete, bool inUse, uint32_t slot, uint32_t addr, uint32_t timestamp, uint32_t bits); - void pushInfo(uint8_t slotNumbers); + void onRxData(char *data, size_t len); - void registerCallback_Packet(GobotRPC_CtrlInterface_Callback_Packet callback, void * args); - void registerCallback_PerformScan(GobotRPC_CtrlInterface_Callback_PerformScan callback, void * args); - void registerCallback_ReqSlotUpdate(GobotRPC_CtrlInterface_Callback_ReqSlotUpdate callback, void * args); - void registerCallback_GetInfo(GobotRPC_CtrlInterface_Callback_GetInfo callback, void * args); -}; - - -enum UART_CTRL_Command_ID { - GOBOTRPC_CTRL_CMD_PACKET = 0x81, // Host <-> Hub - GOBOTRPC_CTRL_CMD_PERFORM_SCAN = 0x82, // Host -> Hub - GOBOTRPC_CTRL_CMD_SCAN_RESULT = 0x83, // Hub -> Host - GOBOTRPC_CTRL_CMD_SLOT_UPDATE = 0x84, // Hub -> Host - GOBOTRPC_CTRL_CMD_REQ_SLOT_UPDATE = 0x85, // Host -> Hub - GOBOTRPC_CTRL_CMD_HEART_BEAT = 0xfe, // Host <- Hub - GOBOTRPC_CTRL_CMD_INFO = 0xff, // Host -> Hub, Hub -> Host + void heartBeartTaskFn(); }; \ No newline at end of file diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/ctrl_interface_hardware.hpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/ctrl_interface_hardware.hpp index 9500306..372007a 100644 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/ctrl_interface_hardware.hpp +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/ctrl_interface_hardware.hpp @@ -1,58 +1,56 @@ #pragma once -#include +#include -typedef void (*GobotRPC_CtrlInterface_Callback_RX)(void * args, char * data, size_t length); -typedef void (*GobotRPC_CtrlInterface_Callback_HeartBeat)(void * args); - - -class I_GobotRPC_CtrlInterface_HardwareHandler { -public: - virtual void send(char * data, size_t length) = 0; - virtual void registerCallback(GobotRPC_CtrlInterface_Callback_RX, void * args) = 0; - virtual void registerHeartBeatCallback(GobotRPC_CtrlInterface_Callback_HeartBeat, void * args) = 0; -}; - - -#define GOBOTRPC_PLATFORM_RP2040 -#ifdef GOBOTRPC_PLATFORM_RP2040 +#include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" #include "semphr.h" -#include "hardware/uart.h" +#include "queue.h" -class GobotRPC_CtrlInterface_HardwareHandler_RP2040 : public I_GobotRPC_CtrlInterface_HardwareHandler { -private: - uart_inst_t * uart_instance; - int UART_IRQ; - - GobotRPC_CtrlInterface_Callback_RX callback_rx; - void * callback_args; - - GobotRPC_CtrlInterface_Callback_HeartBeat callback_heart_beat; - void * callback_heart_beat_args; - - xSemaphoreHandle rxSemphrHandle; - TaskHandle_t rxTaskHandle; - TaskHandle_t heartBeatTaskHandle; - - uint heartBeatDelay; +typedef void (*callback_rxData)(void * args, char *data, size_t len); +class I_GobotRPC_CI_Hardware { public: - GobotRPC_CtrlInterface_HardwareHandler_RP2040(uart_inst_t * uart_instance, uint baudrate, uint heartBeatDelay, uint tx_pin, uint rx_pin); - void send(char * data, size_t length) override; - void registerCallback(GobotRPC_CtrlInterface_Callback_RX, void * args) override; - void registerHeartBeatCallback(GobotRPC_CtrlInterface_Callback_HeartBeat, void * args); - - void rxTaskHandler(); - void heartBeatTaskHandler(); - void scheduleRXHandler(BaseType_t * higher_priority_task_woken); + virtual void send(char *data, size_t len) = 0; + virtual void registerCB_RxData(callback_rxData cb, void *args) = 0; }; -extern GobotRPC_CtrlInterface_HardwareHandler_RP2040 * g_uart_hardware_handler; -void isrUartRX(); +#include "hardware/uart.h" -void vTaskRxHandler(void * pvParameters); -void vTaskHeartBeat(void * pvParameters); +void GobotRPC_CI_Hardware_RP2040_UART_isr(); +void GobotRPC_CI_Hardware_RP2040_UART_RXTaskFn(void *args); + +#define NUM_INPUT_BUFFERS 16 + +struct inputBuffers_t { + char data[256]; + size_t len; +}; + +class GobotRPC_CI_Hardware_RP2040_UART : public I_GobotRPC_CI_Hardware { +private: + uart_inst_t *uart; + + inputBuffers_t inputBufferPool[NUM_INPUT_BUFFERS]; + + TaskHandle_t rxTaskHandle; + SemaphoreHandle_t txMutex; + + QueueHandle_t emptyInputBuffersQueue; + QueueHandle_t filledInputBuffersQueue; + + callback_rxData cb_rxData; + void * cb_rxData_args; + +public: + GobotRPC_CI_Hardware_RP2040_UART(uart_inst_t *uart, uint baudrate); + void send(char *data, size_t len) override; + void registerCB_RxData(callback_rxData cb, void *args); + + void rxISR(); + void rxTask(); +}; + +extern GobotRPC_CI_Hardware_RP2040_UART * g_GobotRPC_CI_Hardware_RP2040_UART; -#endif \ No newline at end of file diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/gobotrpc.hpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/gobotrpc.hpp deleted file mode 100644 index 686e274..0000000 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/gobotrpc.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -#include -#include - -#include "gobotrpc_datatypes.hpp" -#include "ctrl_interface.hpp" -#include "ctrl_interface_hardware.hpp" - -class GobotRPC_CtrlInterface; -class GobotRPCParser { -private: - RPC_RX_PackageSlot buffer[NUM_SLOTS]; - uint32_t masked [NUM_SLOTS]; - uint32_t address_mask; - - size_t finishedScanIndex; - - GobotRPC_CtrlInterface * ctrlInterface; - - void find_fitting_slot(RPCHeader header, uint32_t addr, int * fitting_slot, int * empty_slot); - static void insertFrameInPackageSlot(RPC_RX_PackageSlot * package, char * data, size_t segment, size_t length); - void freePackageSlot(size_t index); - -public: - GobotRPCParser(GobotRPC_CtrlInterface * ctrlInterface); - - void print_out_slots(); - enum FrameSubmitionResult submit_frame(char * data, size_t length, uint32_t addr, uint32_t timestamp); - - int getFinishedIndexPackages(); - void retrivePackage(RPCPackage * dest, int index); -}; - -char * mapFrameSubmitionResult2String(FrameSubmitionResult res); - -FrameSubmitionResult getPackageStatus(RPC_RX_PackageSlot * package); diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/gobotrpc_datatypes.hpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/gobotrpc_datatypes.hpp deleted file mode 100644 index 0d67ddb..0000000 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/gobotrpc_datatypes.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -#include "protocol.hpp" - -#define MAX_PAGE_SIZES 4*7 -#define NUM_SLOTS 8 - -enum FrameSubmitionResult { - PENDING, - COMPLEATE, - ERROR_INVALID_RPC_TYPE, - ERROR_INVALID_RPC_NUMBER, - ERROR_NO_EMPTY_OR_FITTING_SLOT, -}; - -struct RPC_RX_PackageSlot { - char buffer[MAX_PAGE_SIZES]; - - bool is_complete; - bool is_in_use; - - uint32_t sender_address; - enum RPCNumber rpcNum; - enum RPCType type; - uint32_t used_bit_masked; - uint32_t timestamp; - size_t length; -}; - -struct RPCPackage { - char buffer[MAX_PAGE_SIZES]; - size_t length; - uint32_t addr; - RPCNumber rpcNum; - RPCType type; -}; \ No newline at end of file diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/pinConfig.hpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/pinConfig.hpp new file mode 100644 index 0000000..78f20c6 --- /dev/null +++ b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/pinConfig.hpp @@ -0,0 +1,6 @@ +#pragma once + +#define GOBOTRPC_CI_UART_RX 0 +#define GOBOTRPC_CI_UART_TX 1 + +#define GOBOTRPC_HEARTBEAT_INTERVAL 3000 \ No newline at end of file diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/protocol.hpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/protocol.hpp deleted file mode 100644 index 27945d3..0000000 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/include/protocol.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once -#include -#include - -enum RPCNumber { - Get_Info = 0x0, - Home = 0x01, - Move_Step = 0x2, - Move_XY = 0x3, - Set_Padding = 0x4, - Release_Motors = 0x5, - Drop_Stone = 0x6, - Get_Stone_Status = 0x7, - Move_Z_Axis = 0x8, - Set_Vacum = 0x9, - Invalid = 0xf -}; - -const uint32_t RPC_NUMBER_MAX = 0x9; - -enum RPCType { - REQUEST = 0b00, - RESPONSE_RPC = 0b01, - INVALID = 0b10, - ERROR = 0b11 -}; - -struct RPCHeader { - RPCNumber rpcNum : 4; - RPCType type : 2; - unsigned char segment: 2; -}; diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/init.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/init.cpp deleted file mode 100644 index a6c7591..0000000 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/init.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "gobotrpc.hpp" -#include - -GobotRPCParser::GobotRPCParser(GobotRPC_CtrlInterface * ctrlInterface) { - this->ctrlInterface = ctrlInterface; - - for(int i = 0; i < NUM_SLOTS; i++) { - buffer[i].timestamp = 0; - buffer[i].is_complete = false; - buffer[i].is_in_use = false; - buffer[i].used_bit_masked = 0; - buffer[i].sender_address = 0; - buffer[i].rpcNum = Invalid; - buffer[i].type = INVALID; - buffer[i].length = 0; - - memset(buffer[i].buffer, 0, MAX_PAGE_SIZES); - } - - finishedScanIndex = 0; - address_mask = 0xFFFFFFFF; -} diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/protocol.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/protocol.cpp deleted file mode 100644 index 65510f6..0000000 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/protocol.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include "protocol.hpp" -#include "gobotrpc.hpp" -#include - -uint32_t getRpcRequestCompleteMask(RPCNumber rpcNum) { - switch (rpcNum) { - case Get_Info: return 0b00000000000000000000000000000000; - case Home: return 0b00000000000000000000000000000011; - case Move_Step: return 0b00000000000000000000000000111111; - case Move_XY: return 0b00000000000000000000000000111111; - case Set_Padding: return 0b00000000000000001101111110111111; - case Release_Motors: return 0b00000000000000000000000001111111; - case Drop_Stone: return 0b00000000000000000000000000000000; - case Get_Stone_Status: return 0b00000000000000000000000000000000; - case Move_Z_Axis: return 0b00000000000000000000000000000001; - case Set_Vacum: return 0b00000000000000000000000000000001; - default: return 0b00000000000000000000000000000000; - } -} - -uint32_t getRpcResponseCompleteMask(RPCNumber rpcNum) { - switch (rpcNum) { - case Get_Info: return 0b00001111111111111111111111111111; - case Home: return 0b00000000000000000000000000111111; - case Move_Step: return 0b00000000000000000000000000000000; - case Move_XY: return 0b00000000000000000000000000000000; - case Set_Padding: return 0b00000000000000000000000000000000; - case Release_Motors: return 0b00000000000000000000000000000000; - case Drop_Stone: return 0b00000000000000000000000000000000; - case Get_Stone_Status: return 0b00000000000000000000000000000000; - case Move_Z_Axis: return 0b00000000000000000000000000000000; - case Set_Vacum: return 0b00000000000000000000000000000000; - default: return 0b00000000000000000000000000000000; - } -} - -uint32_t ERROR_MASK = 0b00000000000000000000000000000000; - -FrameSubmitionResult getPackageStatus(RPC_RX_PackageSlot * package) { - - uint32_t mask; - - switch (package->type) { - case REQUEST: - mask = getRpcRequestCompleteMask(package->rpcNum); - break; - case RESPONSE_RPC: - mask = getRpcResponseCompleteMask(package->rpcNum); - break; - case ERROR: - mask = ERROR_MASK; - break; - default: - return ERROR_INVALID_RPC_TYPE; - }; - - uint32_t masked_bits = package->used_bit_masked & mask; - - if(masked_bits == mask) { - return COMPLEATE; - } - - return PENDING; -} \ No newline at end of file diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/rx.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/rx.cpp deleted file mode 100644 index 042623f..0000000 --- a/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc/rx.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#include "gobotrpc.hpp" -#include "protocol.hpp" -#include - -RPCHeader parseRPCHeader(char data) -{ - RPCHeader header; - header.rpcNum = (RPCNumber)(data & 0b00001111); - header.type = (RPCType)((data & 0b00110000) >> 4); - header.segment = (data & 0b11000000) >> 6; - - return header; -} - -FrameSubmitionResult GobotRPCParser::submit_frame(char *data, size_t length, uint32_t addr, uint32_t timestamp) -{ - RPCHeader header = parseRPCHeader(data[0]); - - if (header.type == INVALID) { - return ERROR_INVALID_RPC_TYPE; - } - - if (header.rpcNum > RPC_NUMBER_MAX) { - return ERROR_INVALID_RPC_NUMBER; - } - - int fitting_slot; - int empty_slot; - find_fitting_slot(header, addr, &fitting_slot, &empty_slot); - - int slotNum; - - // Check if packageSlot is complete - - if (fitting_slot != -1) { - slotNum = fitting_slot; - } - else if (empty_slot != -1) { - slotNum = empty_slot; - - this->buffer[slotNum].is_in_use = true; - this->buffer[slotNum].is_complete = false; - this->buffer[slotNum].sender_address = addr; - this->buffer[slotNum].rpcNum = header.rpcNum; - this->buffer[slotNum].type = header.type; - } - else { - return ERROR_NO_EMPTY_OR_FITTING_SLOT; - } - - insertFrameInPackageSlot(&this->buffer[slotNum], data, header.segment, length); - this->buffer[slotNum].timestamp = timestamp; - this->buffer[slotNum].length = MAX(this->buffer[slotNum].length, header.segment*7 + (length - 1)); - volatile FrameSubmitionResult res = getPackageStatus(&(this->buffer[slotNum])); - - // Push the update to the control interface - ctrlInterface->pushPackageSlotUpdate(res == COMPLEATE, this->buffer[slotNum].is_in_use, slotNum, addr, timestamp, this->buffer[slotNum].used_bit_masked); - -y if (res == COMPLEATE) { - this->buffer[slotNum].is_complete = true; - } - - return res; -} - -void GobotRPCParser::insertFrameInPackageSlot(RPC_RX_PackageSlot *packageSlot, char *data, size_t segment, size_t length) -{ - size_t offset = segment * 7; - - for (int i = 0; i < length - 1; i++) { - packageSlot->buffer[offset + i] = data[i + 1]; - packageSlot->used_bit_masked |= 1 << (offset + i); - } -} - -void GobotRPCParser::find_fitting_slot(RPCHeader header, uint32_t addr, int *fitting_slot, int *empty_slot) -{ - uint32_t masked_addr = addr & this->address_mask; - - *fitting_slot = -1; - *empty_slot = -1; - - for (int i = 0; i < NUM_SLOTS; i++) { - if (this->buffer[i].is_complete) { - continue; - } - - uint32_t masked_slot_addr = this->buffer[i].sender_address & this->address_mask; - - if (masked_slot_addr == masked_addr && header.rpcNum == this->buffer[i].rpcNum) { - *fitting_slot = i; - return; - } - - if (*empty_slot == -1 && !buffer[i].is_in_use) { - *empty_slot = i; - } - } -} - -int GobotRPCParser::getFinishedIndexPackages() { - - for (int i = 0; i < NUM_SLOTS; i++) { - size_t index = (i + this->finishedScanIndex) % NUM_SLOTS; - if (this->buffer[i].is_complete) { - this->finishedScanIndex = (index + 1) % NUM_SLOTS; - return index; - } - } - - return -1; -} - -void GobotRPCParser::retrivePackage(RPCPackage *dest, int index) { - memcpy(dest->buffer, buffer[index].buffer, MAX_PAGE_SIZES); - dest->addr = buffer[index].sender_address; - dest->rpcNum = buffer[index].rpcNum; - dest->type = buffer[index].type; - dest->length = buffer[index].length; - - this->ctrlInterface->pushPacket(*dest); - freePackageSlot(index); -} - -void GobotRPCParser::freePackageSlot(size_t index) { - this->buffer[index].timestamp = 0; - this->buffer[index].is_complete = false; - this->buffer[index].is_in_use = false; - this->buffer[index].used_bit_masked = 0; - this->buffer[index].sender_address = 0; - this->buffer[index].rpcNum = Invalid; - this->buffer[index].type = INVALID; - this->buffer[index].length = 0; -} \ No newline at end of file diff --git a/i2c-hub/firmware/i2c-hub-firmware/src/main.cpp b/i2c-hub/firmware/i2c-hub-firmware/src/main.cpp index 8e5333a..da2f908 100644 --- a/i2c-hub/firmware/i2c-hub-firmware/src/main.cpp +++ b/i2c-hub/firmware/i2c-hub-firmware/src/main.cpp @@ -1,65 +1,49 @@ #include #include "pico/stdlib.h" +#include "ctrl_interface.hpp" +#include "ctrl_interface_hardware.hpp" + #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" +#include "crc16.hpp" + #define LED_PIN 25 - -#include "gobotrpc/include/gobotrpc.hpp" -#include "ctrl_interface_hardware.hpp" - -void vTaskMain(void * args) { - GobotRPC_CtrlInterface_HardwareHandler_RP2040 uartHandler(uart0, 9600, 1500, 0, 1); - GobotRPC_CtrlInterface ctrlInterface(&uartHandler); - GobotRPCParser rpcRXParser(&ctrlInterface); - - ctrlInterface.printf("Hello World!\n"); - - char data0[] = "\x04\x01\x02\x03\x04\x05\x06"; - char data1[] = "\x44\x11\x12\x13\x14\x15\x16"; - char data3[] = "\x11\xaa\xbb\xcc\xdd\xee\xff"; - char data2[] = "\x84\xaa\xbb"; - - rpcRXParser.submit_frame(data2, 3, 0x42, xTaskGetTickCount()); - rpcRXParser.submit_frame(data3, 7, 0x43, xTaskGetTickCount()); - rpcRXParser.submit_frame(data1, 7, 0x42, xTaskGetTickCount()); - - - ctrlInterface.printf("This is Random Text\n"); - - vTaskDelay(10 / portTICK_PERIOD_MS); - - rpcRXParser.submit_frame(data3, 7, 0x43, xTaskGetTickCount()); - rpcRXParser.submit_frame(data0, 7, 0x42, xTaskGetTickCount()); - - size_t index = rpcRXParser.getFinishedIndexPackages(); - - RPCPackage package; - rpcRXParser.retrivePackage(&package, index); - - while (true) { - gpio_put(LED_PIN, false); - vTaskDelay(500 / portTICK_PERIOD_MS); - gpio_put(LED_PIN, true); - vTaskDelay(500 / portTICK_PERIOD_MS); +void vTaskMain(void * pvParameters) { + while(1) { + gpio_put(LED_PIN, 1); + vTaskDelay(pdMS_TO_TICKS(500)); + gpio_put(LED_PIN, 0); + vTaskDelay(pdMS_TO_TICKS(500)); } - +} + +void onTxPacket(void * args, char *data, size_t len) { + GobotRPC_CI * gobotRPC_ci = (GobotRPC_CI *)args; + + char buffer[] = {0x00, 0x74, 0x04, 0x00, 0x00}; + unsigned short crc = crc16(buffer + 1, 2); + + buffer[4] = crc & 0xff; + buffer[3] = (crc >> 8) & 0xff; + + gobotRPC_ci->send_RxPacket(buffer, 4); } int main() { - stdio_init_all(); - printf("============================================\n"); - printf(" Gobot RPC Hub \n"); - printf("============================================\n"); - gpio_init(LED_PIN); gpio_set_dir(LED_PIN, true); + GobotRPC_CI_Hardware_RP2040_UART gobotrpc_ci_hardware(uart0, 115200); + GobotRPC_CI gobotRPC_ci(&gobotrpc_ci_hardware); + + gobotRPC_ci.registerCB_TxPacket(onTxPacket, &gobotRPC_ci); + TaskHandle_t taskHandle; - xTaskCreate(vTaskMain, "Main Task", 2048, NULL, 1, &taskHandle); + xTaskCreate(vTaskMain, "Main Task", 2048, &gobotRPC_ci, 1, &taskHandle); vTaskStartScheduler(); while(1) {} diff --git a/i2c-hub/uart-adapter/src/gobotrpc/__init__.py b/i2c-hub/uart-adapter/src/gobotrpc/__init__.py index cbed664..452d96d 100644 --- a/i2c-hub/uart-adapter/src/gobotrpc/__init__.py +++ b/i2c-hub/uart-adapter/src/gobotrpc/__init__.py @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5c7cf9ffe35204723406003792543d90145246bd02bc517b210085ebc6b82a35 -size 873 +oid sha256:7f45183f4cf8d60047dafa83c65b5dfa953a10bd4017b5a5be89bde0a94153df +size 877 diff --git a/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/__init__.cpython-312.pyc b/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/__init__.cpython-312.pyc index 750d60d..5dbe92a 100644 Binary files a/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/__init__.cpython-312.pyc and b/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/__init__.cpython-312.pyc differ diff --git a/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/mapping.cpython-312.pyc b/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/mapping.cpython-312.pyc index 1495e8c..8133403 100644 Binary files a/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/mapping.cpython-312.pyc and b/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/mapping.cpython-312.pyc differ diff --git a/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/packages.cpython-312.pyc b/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/packages.cpython-312.pyc index 3982e02..c338c94 100644 Binary files a/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/packages.cpython-312.pyc and b/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/packages.cpython-312.pyc differ diff --git a/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/rpc_packages.cpython-312.pyc b/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/rpc_packages.cpython-312.pyc new file mode 100644 index 0000000..f704140 Binary files /dev/null and b/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/rpc_packages.cpython-312.pyc differ diff --git a/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/util.cpython-312.pyc b/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/util.cpython-312.pyc index f94f5da..f79dc47 100644 Binary files a/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/util.cpython-312.pyc and b/i2c-hub/uart-adapter/src/gobotrpc/__pycache__/util.cpython-312.pyc differ diff --git a/i2c-hub/uart-adapter/src/gobotrpc/mapping.py b/i2c-hub/uart-adapter/src/gobotrpc/mapping.py index 8c66263..ada35f0 100644 --- a/i2c-hub/uart-adapter/src/gobotrpc/mapping.py +++ b/i2c-hub/uart-adapter/src/gobotrpc/mapping.py @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7d1fb1046bfa78e4dd74f9ae6289cf174102cf67061d6f57a51a270a71aad765 -size 1380 +oid sha256:f2084100e09a2b7c0ca7c4f98e9372ecd69b6c1dad2980436c2963c5fee175ee +size 1379 diff --git a/i2c-hub/uart-adapter/src/gobotrpc/packages.py b/i2c-hub/uart-adapter/src/gobotrpc/packages.py deleted file mode 100644 index 7bc873c..0000000 --- a/i2c-hub/uart-adapter/src/gobotrpc/packages.py +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b01239135b735979e6bb209b0fcaf4d288d6663a04272c6e961af6eca12da10c -size 3559 diff --git a/i2c-hub/uart-adapter/src/gobotrpc/rpc_packages.py b/i2c-hub/uart-adapter/src/gobotrpc/rpc_packages.py new file mode 100644 index 0000000..197e9dd --- /dev/null +++ b/i2c-hub/uart-adapter/src/gobotrpc/rpc_packages.py @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:94a2f416ae25bc6bec4b97285346eb5557c1025f821da274cb063442d4aaaaa3 +size 4491 diff --git a/i2c-hub/uart-adapter/src/gobotrpc/util.py b/i2c-hub/uart-adapter/src/gobotrpc/util.py index b396865..d7248e3 100644 --- a/i2c-hub/uart-adapter/src/gobotrpc/util.py +++ b/i2c-hub/uart-adapter/src/gobotrpc/util.py @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a33697a141edc34c0153f1103c2f5973389f51ff856659e8d6708f4642c68400 -size 1077 +oid sha256:e6c50a0d555b1c8e86908fd7004c1ea3015ded95c0dc01b40cc75331becbafd7 +size 1624 diff --git a/i2c-hub/uart-adapter/src/main.py b/i2c-hub/uart-adapter/src/main.py index 0ce2a19..a0567fb 100644 --- a/i2c-hub/uart-adapter/src/main.py +++ b/i2c-hub/uart-adapter/src/main.py @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3c3def00d98139980f8091af6f966a9f2a56daa839a1f5276f426e7bde9460da -size 454 +oid sha256:f3d9810f5770ec45007e8eccd750759b2849dc5ce54aeaef8de390d30b84a6fd +size 884 diff --git a/i2c-hub/uart-adapter/src/uart_interface/__init__.py b/i2c-hub/uart-adapter/src/uart_interface/__init__.py index 2189223..90bdb11 100644 --- a/i2c-hub/uart-adapter/src/uart_interface/__init__.py +++ b/i2c-hub/uart-adapter/src/uart_interface/__init__.py @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:13f97c2174b90485ea33c5bbaad1f1ca8438b64f7c0b126173f9108e467310ab -size 560 +oid sha256:46eec6f0f350fa5d86ec5443a734e0d08f1f22e9ca684fad520cce916f8e9346 +size 1069 diff --git a/i2c-hub/uart-adapter/src/uart_interface/__pycache__/__init__.cpython-312.pyc b/i2c-hub/uart-adapter/src/uart_interface/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..68032b6 Binary files /dev/null and b/i2c-hub/uart-adapter/src/uart_interface/__pycache__/__init__.cpython-312.pyc differ diff --git a/i2c-hub/uart-adapter/src/uart_interface/__pycache__/ci_packages.cpython-312.pyc b/i2c-hub/uart-adapter/src/uart_interface/__pycache__/ci_packages.cpython-312.pyc new file mode 100644 index 0000000..ac10889 Binary files /dev/null and b/i2c-hub/uart-adapter/src/uart_interface/__pycache__/ci_packages.cpython-312.pyc differ diff --git a/i2c-hub/uart-adapter/src/uart_interface/__pycache__/package.cpython-312.pyc b/i2c-hub/uart-adapter/src/uart_interface/__pycache__/package.cpython-312.pyc new file mode 100644 index 0000000..c2d19e2 Binary files /dev/null and b/i2c-hub/uart-adapter/src/uart_interface/__pycache__/package.cpython-312.pyc differ diff --git a/i2c-hub/uart-adapter/src/uart_interface/__pycache__/pares_packages.cpython-312.pyc b/i2c-hub/uart-adapter/src/uart_interface/__pycache__/pares_packages.cpython-312.pyc new file mode 100644 index 0000000..f64a169 Binary files /dev/null and b/i2c-hub/uart-adapter/src/uart_interface/__pycache__/pares_packages.cpython-312.pyc differ diff --git a/i2c-hub/uart-adapter/src/uart_interface/__pycache__/serial.cpython-312.pyc b/i2c-hub/uart-adapter/src/uart_interface/__pycache__/serial.cpython-312.pyc new file mode 100644 index 0000000..34b7188 Binary files /dev/null and b/i2c-hub/uart-adapter/src/uart_interface/__pycache__/serial.cpython-312.pyc differ diff --git a/i2c-hub/uart-adapter/src/uart_interface/ci_packages.py b/i2c-hub/uart-adapter/src/uart_interface/ci_packages.py new file mode 100644 index 0000000..155e6e0 --- /dev/null +++ b/i2c-hub/uart-adapter/src/uart_interface/ci_packages.py @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05f5ad9f0af15d0134a52d785b8ed5f3d66ebb88a1896982e3179a61c483c17f +size 2047 diff --git a/i2c-hub/uart-adapter/src/uart_interface/pares_packages.py b/i2c-hub/uart-adapter/src/uart_interface/pares_packages.py new file mode 100644 index 0000000..f5073fe --- /dev/null +++ b/i2c-hub/uart-adapter/src/uart_interface/pares_packages.py @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d761d7d2aebd255e82220088b72630e5e05f805fd72b50fba9d482af758779d +size 611 diff --git a/i2c-hub/uart-adapter/src/uart_interface/serial.py b/i2c-hub/uart-adapter/src/uart_interface/serial.py index 2b1dfc2..0167038 100644 --- a/i2c-hub/uart-adapter/src/uart_interface/serial.py +++ b/i2c-hub/uart-adapter/src/uart_interface/serial.py @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e3c86dfb86541d77b49e2471d1b7042ea9f7bc1559429f282636fae4b369af1e -size 1413 +oid sha256:c3a0046b2cde7b7d3029bacb87a8702ee0444919b8ac159b12791c4685ee0319 +size 1485