From e608ba3855e48330ae2cc2f9a20317f0160770c8 Mon Sep 17 00:00:00 2001 From: cfif Date: Fri, 13 Mar 2026 16:25:26 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B0=D1=87=D0=B0=D0=BB=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ArbiterCommand.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++ ArbiterCommand.h | 49 +++++++++++++++ modular.json | 10 +++ 3 files changed, 220 insertions(+) create mode 100644 ArbiterCommand.c create mode 100644 ArbiterCommand.h create mode 100644 modular.json diff --git a/ArbiterCommand.c b/ArbiterCommand.c new file mode 100644 index 0000000..abd6e4f --- /dev/null +++ b/ArbiterCommand.c @@ -0,0 +1,161 @@ +// +// Created by cfif on 13.03.2026. +// +#include "ArbiterCommand.h" +#include "CmsisRtosThreadUtils.h" +#include "SystemDelayInterface.h" +#include "SerialPort.h" +#include "AtCmdCommonProtected.h" +#include "AsciiStringParsingUtils.h" + +void sendOk(tAtCmd *AtCmd) { + AtCmdPrepare(AtCmd); + AtCmdTxClear(AtCmd); + AtCmdTxAddStatic(AtCmd, "OK"); + AtCmdTxSendLn(AtCmd); + AtCmdRxClear(AtCmd); +} + +void sendVers(tAtCmd *AtCmd) { + AtCmdPrepare(AtCmd); + AtCmdTxClear(AtCmd); + AtCmdTxAddStatic(AtCmd, "v001"); + AtCmdTxSendLn(AtCmd); + AtCmdRxClear(AtCmd); +} + +void SerialCommand_Scheduler(tTaskSerial *env) { + + if (AtCmdRxBeginWithStatic(&env->At, "T")) { + + uint8_t data[8]; + uint32_t adr = iAsciiStringParseUnsignedLongDecimalNumber(&env->At.rxBuffer.data[1], &env->At.rxBuffer.data[9]); + + uint8_t len = &env->At.rxBuffer.data[env->At.rxBuffer.len] - &env->At.rxBuffer.data[9] - 2; + + if (len > 16) { + len = 16; + } + + uint8_t size = iAsciiStringParseHexBytes(data, &env->At.rxBuffer.data[9], len); + + env->ioCAN->transmit(env->ioCAN->env, data, size, adr, 0, env->numberMailBox, 1000); + + sendOk(&env->At); + } + + if (AtCmdRxBeginWithStatic(&env->At, "t")) { + + uint8_t data[8]; + uint32_t adr = iAsciiStringParseUnsignedLongDecimalNumber(&env->At.rxBuffer.data[1], &env->At.rxBuffer.data[9]); + + uint8_t len = &env->At.rxBuffer.data[env->At.rxBuffer.len] - &env->At.rxBuffer.data[9] - 2; + + if (len > 16) { + len = 16; + } + + uint8_t size = iAsciiStringParseHexBytes(data, &env->At.rxBuffer.data[9], len); + + env->ioCAN->transmit(env->ioCAN->env, data, size, adr, 1, env->numberMailBox, 1000); + + sendOk(&env->At); + } + + if (AtCmdRxBeginWithStatic(&env->At, "V")) { + sendVers(&env->At); + } + +} + + +void TaskSerialUART_Init(tTaskSerial *env, + uint8_t numberMailBox, + tSerialPortIO *ioUART, + tSerialPortFrameIO *ioCAN +) { + + env->access = osMutexNew(NULL); + env->numberMailBox = numberMailBox; + + env->ioUART = ioUART; + env->ioCAN = ioCAN; + + SerialPortClearRxBuffer(env->ioUART); + + AtCmdInit( + &env->At, env->ioUART, + env->AtRx, sizeof(env->AtRx), + env->AtTx, sizeof(env->AtTx), + 2000, 2000 + ); + + InitThreadAtrStatic(&env->thread.attr, "SerialUART", env->thread.controlBlock, env->thread.stack, osPriorityNormal); +} + + +static _Noreturn void Serial_UART_Thread(tTaskSerial *env) { + for (;;) { + + if (osMutexAcquire(env->access, 1000) == osOK) { + + SerialCommand_Scheduler(env); + + osMutexRelease(env->access); + } + + SystemDelayMs(1000); + } +} + +void TaskSerialUART_StartThread(tTaskSerial *env) { + if (!env->thread.id) { + env->thread.id = osThreadNew((osThreadFunc_t) (Serial_UART_Thread), (void *) (env), &env->thread.attr); + } +} + + +void TaskSerialUSB_Init(tTaskSerial *env, + uint8_t numberMailBox, + tSerialPortIO *ioUART, + tSerialPortFrameIO *ioCAN +) { + + env->access = osMutexNew(NULL); + env->numberMailBox = numberMailBox; + + env->ioUART = ioUART; + env->ioCAN = ioCAN; + + SerialPortClearRxBuffer(env->ioUART); + + AtCmdInit( + &env->At, env->ioUART, + env->AtRx, sizeof(env->AtRx), + env->AtTx, sizeof(env->AtTx), + 2000, 2000 + ); + + InitThreadAtrStatic(&env->thread.attr, "SerialUSB", env->thread.controlBlock, env->thread.stack, osPriorityNormal); +} + + +static _Noreturn void Serial_USB_Thread(tTaskSerial *env) { + for (;;) { + + if (osMutexAcquire(env->access, 1000) == osOK) { + + SerialCommand_Scheduler(env); + + osMutexRelease(env->access); + } + + SystemDelayMs(1000); + } +} + +void TaskSerialUSB_StartThread(tTaskSerial *env) { + if (!env->thread.id) { + env->thread.id = osThreadNew((osThreadFunc_t) (Serial_USB_Thread), (void *) (env), &env->thread.attr); + } +} \ No newline at end of file diff --git a/ArbiterCommand.h b/ArbiterCommand.h new file mode 100644 index 0000000..3282423 --- /dev/null +++ b/ArbiterCommand.h @@ -0,0 +1,49 @@ +// +// Created by cfif on 13.03.2026. +// + +#ifndef HVAC_DEV_ARBITERCOMMAND_H +#define HVAC_DEV_ARBITERCOMMAND_H + +#include +#include "SerialPortIO.h" +#include "AtCmdCommon.h" +#include "CanSerialPortFrame.h" + +typedef struct { + + tAtCmd At; + uint8_t AtRx[255]; + uint8_t AtTx[255]; + + tSerialPortIO *ioUART; + tSerialPortFrameIO *ioCAN; + uint8_t numberMailBox; + osMutexId_t access; + + struct { + osThreadId_t id; + uint32_t stack[512]; + StaticTask_t controlBlock; + osThreadAttr_t attr; + } thread; + + +} tTaskSerial; + +void TaskSerialUART_Init(tTaskSerial *env, + uint8_t numberMailBox, + tSerialPortIO *ioUART, + tSerialPortFrameIO *ioCAN +); +void TaskSerialUART_StartThread(tTaskSerial *env); + +void TaskSerialUSB_Init(tTaskSerial *env, + uint8_t numberMailBox, + tSerialPortIO *ioUART, + tSerialPortFrameIO *ioCAN +); +void TaskSerialUSB_StartThread(tTaskSerial *env); + + +#endif //HVAC_DEV_ARBITERCOMMAND_H diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..0dd1901 --- /dev/null +++ b/modular.json @@ -0,0 +1,10 @@ +{ + "cmake": { + "inc_dirs": [ + "./" + ], + "srcs": [ + "./**.c" + ] + } +} \ No newline at end of file