Paritailly implement UART for RP2040 for the GobotRPC Controller Interface
This commit is contained in:
@@ -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
|
||||
)
|
||||
@@ -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;
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
@@ -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
|
||||
};
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user