Paritailly implement UART for RP2040 for the GobotRPC Controller Interface

This commit is contained in:
AlexanderHD27
2024-12-30 16:09:39 +01:00
parent 65df7b1912
commit 58043ee0d5
14 changed files with 562 additions and 430 deletions

View File

@@ -4,10 +4,11 @@ add_library(GobotRPC STATIC
${CMAKE_CURRENT_LIST_DIR}/../protocol.cpp
${CMAKE_CURRENT_LIST_DIR}/../error_msg.cpp
${CMAKE_CURRENT_LIST_DIR}/../uart_ctrl/uart_ctrl_base.cpp
${CMAKE_CURRENT_LIST_DIR}/../uart_ctrl/uart_ctrl_registers.cpp
${CMAKE_CURRENT_LIST_DIR}/../uart_ctrl/uart_ctrl_rx.cpp
${CMAKE_CURRENT_LIST_DIR}/../uart_ctrl/uart_ctrl_tx.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
)
target_include_directories(GobotRPC PUBLIC
@@ -17,4 +18,7 @@ target_include_directories(GobotRPC PUBLIC
target_link_libraries(GobotRPC
FreeRTOS-Kernel-Heap4
pico_stdlib
hardware_uart
hardware_irq
)

View File

@@ -1,9 +1,9 @@
#include "uart_ctrl.hpp"
#include <stdint.h>
UART_CTRL_Interface::UART_CTRL_Interface(I_UART_CTRL_Hardware_Handler *handler) {
GobotRPC_CtrlInterface::GobotRPC_CtrlInterface(GobotRPC_CtrlInterface_HardwareHandler *handler) {
this->handler = handler;
handler->registerCallback(externalCallback_RX);
handler->registerCallback(externalCallback_RX, this);
packetCallback = nullptr;
performScanCallback = nullptr;

View File

@@ -0,0 +1,87 @@
#include "uart_ctrl_hardware.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 tx_pin, uint rx_pin) {
this->rxSemphrHandle = xSemaphoreCreateCounting(16, 0);
g_uart_hardware_handler = this;
xTaskCreate(vTaskRxHandler, "gobotrpc_ctrl_interface_uart_rx", 512, this, 3, &this->rxTaskHandle);
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);
}
// TODO: Implement this!
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(UART_CTRL_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::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 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

View File

@@ -0,0 +1,22 @@
#include "uart_ctrl.hpp"
#include <string.h>
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;
}

View File

@@ -3,26 +3,26 @@
#include <string.h>
void externalCallback_RX(void * args, char * data, size_t length) {
UART_CTRL_Interface *interface = (UART_CTRL_Interface *)args;
GobotRPC_CtrlInterface *interface = (GobotRPC_CtrlInterface *)args;
interface->onRX(data, length);
}
void UART_CTRL_Interface::onRX(char * data, size_t length) {
void GobotRPC_CtrlInterface::onRX(char * data, size_t length) {
uint8_t cmd = data[0];
switch (cmd) {
case UART_CMD_PACKET:
case GOBOTRPC_CTRL_CMD_PACKET:
onRX_Packet(data, length);
break;
case UART_CMD_PERFORM_SCAN:
case GOBOTRPC_CTRL_CMD_PERFORM_SCAN:
onRX_PerformScan(data, length);
break;
case UART_CMD_REQ_SLOT_UPDATE:
case GOBOTRPC_CTRL_CMD_REQ_SLOT_UPDATE:
onRX_ReqSlotUpdate(data, length);
break;
case UART_CMD_INFO:
case GOBOTRPC_CTRL_CMD_INFO:
onRX_GetInfo(data, length);
break;
@@ -31,7 +31,7 @@ void UART_CTRL_Interface::onRX(char * data, size_t length) {
}
}
void UART_CTRL_Interface::onRX_Packet(char *data, size_t length) {
void GobotRPC_CtrlInterface::onRX_Packet(char *data, size_t length) {
if(length < 7)
return;
@@ -48,7 +48,7 @@ void UART_CTRL_Interface::onRX_Packet(char *data, size_t length) {
}
}
void UART_CTRL_Interface::onRX_PerformScan(char *data, size_t length) {
void GobotRPC_CtrlInterface::onRX_PerformScan(char *data, size_t length) {
if(length < 2)
return;
@@ -56,7 +56,7 @@ void UART_CTRL_Interface::onRX_PerformScan(char *data, size_t length) {
performScanCallback(performScanCallbackArgs, data[1] == 1);
}
void UART_CTRL_Interface::onRX_ReqSlotUpdate(char *data, size_t length) {
void GobotRPC_CtrlInterface::onRX_ReqSlotUpdate(char *data, size_t length) {
if (length < 2)
return;
@@ -64,7 +64,7 @@ void UART_CTRL_Interface::onRX_ReqSlotUpdate(char *data, size_t length) {
reqSlotUpdateCallback(reqSlotUpdateCallbackArgs, data[1] == 1);
}
void UART_CTRL_Interface::onRX_GetInfo(char *data, size_t length) {
void GobotRPC_CtrlInterface::onRX_GetInfo(char *data, size_t length) {
if (length < 1)
return;

View File

@@ -2,10 +2,10 @@
#include <string.h>
// This function should be called when a package is sent
void UART_CTRL_Interface::pushPacket(RPCPackage package) {
void GobotRPC_CtrlInterface::pushPacket(RPCPackage package) {
char buffer[MAX_PAGE_SIZES + 7];
buffer[0] = UART_CMD_PACKET;
buffer[0] = GOBOTRPC_CTRL_CMD_PACKET;
buffer[1] = package.length;
buffer[2] = package.type | (package.rpcNum << 4);
memcpy(&buffer[3], &package.addr, 4);
@@ -14,10 +14,10 @@ void UART_CTRL_Interface::pushPacket(RPCPackage package) {
handler->send(buffer, package.length + 2);
}
void UART_CTRL_Interface::pushScanResulst(uint32_t addr, bool running) {
void GobotRPC_CtrlInterface::pushScanResulst(uint32_t addr, bool running) {
char buffer[7];
buffer[0] = UART_CMD_SCAN_RESULT;
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
@@ -25,10 +25,10 @@ void UART_CTRL_Interface::pushScanResulst(uint32_t addr, bool running) {
handler->send(buffer, 7);
}
void UART_CTRL_Interface::pushPackageSlotUpdate(bool complete, bool inUse, uint32_t slot, uint32_t addr, uint32_t timestamp, uint32_t bits) {
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] = UART_CMD_SLOT_UPDATE;
buffer[0] = GOBOTRPC_CTRL_CMD_SLOT_UPDATE;
buffer[1] = complete ? 1 : 0;
buffer[2] = inUse ? 1 : 0;
buffer[3] = slot;
@@ -39,10 +39,10 @@ void UART_CTRL_Interface::pushPackageSlotUpdate(bool complete, bool inUse, uint3
handler->send(buffer, 14);
}
void UART_CTRL_Interface::pushInfo(uint8_t slotNumbers) {
void GobotRPC_CtrlInterface::pushInfo(uint8_t slotNumbers) {
char buffer[2];
buffer[0] = UART_CMD_INFO;
buffer[0] = GOBOTRPC_CTRL_CMD_INFO;
buffer[1] = slotNumbers;
handler->send(buffer, 2);

View File

@@ -7,25 +7,25 @@ struct HubInfo {
uint8_t slotNumbers;
};
typedef void (*UART_CTRL_Callback_Packet)(void * args, RPCPackage package);
typedef void (*UART_CTRL_Callback_PerformScan)(void * args, bool enable);
typedef void (*UART_CTRL_Callback_ReqSlotUpdate)(void * args, bool enable);
typedef HubInfo (*UART_CTRL_Callback_GetInfo)(void * args);
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);
void externalCallback_RX(void * args, char * data, size_t length);
class UART_CTRL_Interface {
class GobotRPC_CtrlInterface {
private:
UART_CTRL_Callback_Packet packetCallback;
UART_CTRL_Callback_PerformScan performScanCallback;
UART_CTRL_Callback_ReqSlotUpdate reqSlotUpdateCallback;
UART_CTRL_Callback_GetInfo getInfoCallback;
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_UART_CTRL_Hardware_Handler * handler;
GobotRPC_CtrlInterface_HardwareHandler * handler;
protected:
void onRX_Packet(char * data, size_t length);
void onRX_PerformScan(char * data, size_t length);
@@ -33,7 +33,7 @@ protected:
void onRX_GetInfo(char * data, size_t length);
public:
UART_CTRL_Interface(I_UART_CTRL_Hardware_Handler * handler);
GobotRPC_CtrlInterface(GobotRPC_CtrlInterface_HardwareHandler * handler);
void onRX(char * data, size_t length);
void pushPacket(RPCPackage package);
@@ -41,18 +41,18 @@ public:
void pushPackageSlotUpdate(bool complete, bool inUse, uint32_t slot, uint32_t addr, uint32_t timestamp, uint32_t bits);
void pushInfo(uint8_t slotNumbers);
void registerCallback_Packet(UART_CTRL_Callback_Packet callback, void * args);
void registerCallback_PerformScan(UART_CTRL_Callback_PerformScan callback, void * args);
void registerCallback_ReqSlotUpdate(UART_CTRL_Callback_ReqSlotUpdate callback, void * args);
void registerCallback_GetInfo(UART_CTRL_Callback_GetInfo callback, void * args);
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 {
UART_CMD_PACKET = 0x01, // Host <-> Hub
UART_CMD_PERFORM_SCAN = 0x02, // Host -> Hub
UART_CMD_SCAN_RESULT = 0x03, // Hub -> Host
UART_CMD_SLOT_UPDATE = 0x04, // Hub -> Host
UART_CMD_REQ_SLOT_UPDATE = 0x05, // Host -> Hub
UART_CMD_INFO = 0xff, // Host -> Hub, Hub -> Host
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_INFO = 0xff, // Host -> Hub, Hub -> Host
};

View File

@@ -1,8 +1,45 @@
#pragma once
#include <string.h>
typedef void (*UART_CTRL_Callback_RX)(void * args, char * data, size_t length);
class I_UART_CTRL_Hardware_Handler {
class GobotRPC_CtrlInterface_HardwareHandler {
public:
virtual void send(char * data, size_t length) = 0;
virtual void registerCallback(UART_CTRL_Callback_RX) = 0;
virtual void registerCallback(UART_CTRL_Callback_RX, void * args) = 0;
};
#define GOBOTRPC_PLATFORM_RP2040
#ifdef GOBOTRPC_PLATFORM_RP2040
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "hardware/uart.h"
class GobotRPC_CtrlInterface_HardwareHandler_RP2040 : public GobotRPC_CtrlInterface_HardwareHandler {
private:
uart_inst_t * uart_instance;
int UART_IRQ;
UART_CTRL_Callback_RX callback_rx;
void * callback_args;
xSemaphoreHandle rxSemphrHandle;
TaskHandle_t rxTaskHandle;
public:
GobotRPC_CtrlInterface_HardwareHandler_RP2040(uart_inst_t * uart_instance, uint baudrate, uint tx_pin, uint rx_pin);
void send(char * data, size_t length) override;
void registerCallback(UART_CTRL_Callback_RX, void * args) override;
void rxTaskHandler();
void scheduleRXHandler(BaseType_t * higher_priority_task_woken);
};
extern GobotRPC_CtrlInterface_HardwareHandler_RP2040 * g_uart_hardware_handler;
void isrUartRX();
void vTaskRxHandler(void * pvParameters);
#endif

View File

@@ -1,22 +0,0 @@
#include "uart_ctrl.hpp"
#include <string.h>
void UART_CTRL_Interface::registerCallback_Packet(UART_CTRL_Callback_Packet callback, void *args) {
packetCallback = callback;
packetCallbackArgs = args;
}
void UART_CTRL_Interface::registerCallback_PerformScan(UART_CTRL_Callback_PerformScan callback, void *args) {
performScanCallback = callback;
performScanCallbackArgs = args;
}
void UART_CTRL_Interface::registerCallback_ReqSlotUpdate(UART_CTRL_Callback_ReqSlotUpdate callback, void *args) {
reqSlotUpdateCallback = callback;
reqSlotUpdateCallbackArgs = args;
}
void UART_CTRL_Interface::registerCallback_GetInfo(UART_CTRL_Callback_GetInfo callback, void *args) {
getInfoCallback = callback;
getInfoCallbackArgs = args;
}

View File

@@ -7,11 +7,15 @@
#define LED_PIN 25
#include "gobotrpc/include/gobotrpc.hpp"
#include "uart_ctrl_hardware.hpp"
void TaskFn(void * args) {
printf("\n\n\n\n");
printf("%d\n", xPortGetFreeHeapSize());
GobotRPC_CtrlInterface_HardwareHandler_RP2040 uartHandler(uart0, 115200, 0, 1);
GobotRPCParser rpcRXParser;