Implemented RX on Node

This commit is contained in:
AlexanderHD27
2025-01-06 03:28:10 +01:00
parent caf7586b5b
commit 1e317adedd
29 changed files with 1646 additions and 2298 deletions

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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
)

View File

@@ -1,3 +1,5 @@
#include "crc16.hpp"
#define POLY 0x8408
/*
// 16 12 5

View File

@@ -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);

View File

@@ -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();
};

View File

@@ -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;

View File

@@ -0,0 +1,66 @@
#include "node_interface.hpp"
#include "FreeRTOS.h"
#include "task.h"
#include <string.h>
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);
}

View File

@@ -0,0 +1,124 @@
#include "node_interface_hardware.hpp"
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include <string.h>
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);
}

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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) {

Binary file not shown.

View File

@@ -0,0 +1 @@
/home/alexander/Projects/gobot/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc

View File

@@ -7,8 +7,8 @@
"${userHome}/.pico-sdk/sdk/2.1.0/**"
],
"forcedInclude": [
"${userHome}/.pico-sdk/sdk/2.1.0/src/common/pico_base_headers/include/pico.h",
"${workspaceFolder}/build/generated/pico_base/pico/config_autogen.h"
"${workspaceFolder}/build/generated/pico_base/pico/config_autogen.h",
"${userHome}/.pico-sdk/sdk/2.1.0/src/common/pico_base_headers/include/pico.h"
],
"defines": [],
"compilerPath": "${userHome}/.pico-sdk/toolchain/13_3_Rel1/bin/arm-none-eabi-gcc",
@@ -19,4 +19,4 @@
}
],
"version": 4
}
}

View File

@@ -9,8 +9,12 @@
"args": ["-C", "${workspaceFolder}/build"],
"group": "build",
"presentation": {
"echo": true,
"reveal": "always",
"panel": "dedicated"
"focus": true,
"panel": "dedicated",
"showReuseMessage": true,
"clear": true
},
"problemMatcher": "$gcc",
"windows": {
@@ -27,8 +31,12 @@
"-fx"
],
"presentation": {
"echo": true,
"reveal": "always",
"panel": "dedicated"
"focus": true,
"panel": "shared",
"showReuseMessage": true,
"clear": true
},
"problemMatcher": [],
"windows": {
@@ -39,16 +47,51 @@
"label": "Flash",
"type": "process",
"command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
"args": [
"-s",
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
"-f", "interface/cmsis-dap.cfg",
"-f", "target/${command:raspberry-pi-pico.getTarget}.cfg",
"-c", "adapter speed 5000; program \"${command:raspberry-pi-pico.launchTargetPath}\" reset exit",
],
"presentation": {
"echo": true,
"reveal": "always",
"focus": true,
"panel": "shared",
"showReuseMessage": true,
"clear": true
},
"dependsOn": ["Compile Project"],
"problemMatcher": [],
"windows": {
"command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
}
},
{
"label": "Reset",
"type": "process",
"command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
"args": [
"-s",
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
"-f",
"interface/cmsis-dap.cfg",
"-f",
"target/${command:raspberry-pi-pico.getTarget}.cfg",
"-c",
"adapter speed 5000; program \"${command:raspberry-pi-pico.launchTargetPath}\" verify reset exit"
"-f", "target/${command:raspberry-pi-pico.getTarget}.cfg",
"-c", "adapter speed 5000; init; reset halt;",
"-c", "rp2040.core1 arp_reset assert 0",
"-c", "rp2040.core0 arp_reset assert 0",
"-c", "exit"
],
"presentation": {
"echo": true,
"reveal": "always",
"focus": true,
"panel": "shared",
"showReuseMessage": true,
"clear": true
},
"problemMatcher": [],
"windows": {
"command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",

View File

@@ -34,6 +34,9 @@ project(vacum-control-firmware C CXX ASM)
set(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/lib/FreeRTOS-Kernel)
include(cmake/FreeRTOS_Kernel_import.cmake)
# Adding GobotRPC Node Library
include(lib/gobotrpc/cmake/gobotRPC_Node.cmake)
# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()
@@ -54,6 +57,7 @@ pico_enable_stdio_usb(vacum-control-firmware 0)
# Add the standard library to the build
target_link_libraries(vacum-control-firmware
pico_stdlib
GobotRPC_Node_RP2040_I2C
FreeRTOS-Kernel-Heap4
)

View File

@@ -72,8 +72,8 @@
/* Memory allocation related definitions. */
#define configSUPPORT_STATIC_ALLOCATION 0
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configTOTAL_HEAP_SIZE (1024 * 64)
#define configAPPLICATION_ALLOCATED_HEAP (1024 * 32)
#define configTOTAL_HEAP_SIZE (1024 * 128)
#define configAPPLICATION_ALLOCATED_HEAP (1024 * 64)
/* Hook function related definitions. */
#define configCHECK_FOR_STACK_OVERFLOW 0
@@ -104,11 +104,11 @@
#if FREE_RTOS_KERNEL_SMP // set by the RP2040 SMP port of FreeRTOS
/* SMP port only */
#define configUSE_PASSIVE_IDLE_HOOK 0
#define configNUMBER_OF_CORES 1
#define configNUMBER_OF_CORES 2
#define configTICK_CORE 0
#define configRUN_MULTIPLE_PRIORITIES 1
//#define configUSE_CORE_AFFINITY 1
#define configUSE_CORE_AFFINITY 1
#define configUSE_PASSIVE_IDLE_HOOK 0
#endif
/* RP2040 specific */

View File

@@ -1,10 +1,13 @@
#pragma once
#define CORE_MASK_GOBOTRPC 0b10
#define CORE_MASK_VACUM 0b01
#define LED1_PIN 16
#define LED2_PIN 25
#define RELAY_PIN 15
#define GORPC_INT_PIN 3
#define GORPC_INT_PIN 2
#define GORPC_SDA_PIN 4
#define GORPC_SCL_PIN 5

View File

@@ -1,5 +1,5 @@
#pragma once
#include "pinConfig.hpp"
#include "pinConfigNode.hpp"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
@@ -9,6 +9,7 @@ void vButtonTaskFn(void *pvParameters);
class VacumControl {
private:
uint coreMask;
bool state = false;
xSemaphoreHandle vacumMutex;
xSemaphoreHandle interruptionSemaphore;
@@ -16,7 +17,7 @@ private:
xTaskHandle interruptionTask;
xTaskHandle buttonTask;
public:
VacumControl();
VacumControl(uint coreMask);
void initVacumPins();
void setState(bool on);

View File

@@ -0,0 +1 @@
/home/alexander/Projects/gobot/i2c-hub/firmware/i2c-hub-firmware/src/gobotrpc

View File

@@ -1,5 +1,5 @@
#include "vacum.hpp"
#include "pinConfig.hpp"
#include "pinConfigNode.hpp"
#include "FreeRTOS.h"
#include "task.h"
@@ -17,13 +17,14 @@ void vButtonTaskFn(void *pvParameters) {
vacumControl->buttonTaskFn();
}
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() {

View File

@@ -1,4 +1,5 @@
#include <stdio.h>
#include <string.h>
#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) {