// // 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) { while (AtCmdReceiveNextLine(&env->At, SystemWaitForever) == AT_OK) { if (AtCmdRxBeginWithStatic(&env->At, "T")) { uint8_t data[8]; uint32_t adr = iAsciiStringParseUnsignedLongDecimalNumber(&env->At.rxBuffer.data[1], &env->At.rxBuffer.data[7]); uint8_t len = &env->At.rxBuffer.data[env->At.rxBuffer.len] - &env->At.rxBuffer.data[7] - 2; if (len > 16) { len = 16; } uint8_t size = iAsciiStringParseHexBytes(data, &env->At.rxBuffer.data[7], 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); sendOk(&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(1); } } 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(1); } } void TaskSerialUSB_StartThread(tTaskSerial *env) { if (!env->thread.id) { env->thread.id = osThreadNew((osThreadFunc_t) (Serial_USB_Thread), (void *) (env), &env->thread.attr); } }