From 88ae345a2753c8bf1adf02c6e1d3e7c133dc7326 Mon Sep 17 00:00:00 2001 From: cfif Date: Mon, 24 Feb 2025 10:57:44 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=20?= =?UTF-8?q?=D0=B4=D1=80=D0=B0=D0=B9=D0=B2=D0=B5=D1=80=20CAN=20=D1=84=D1=80?= =?UTF-8?q?=D0=B5=D0=B9=D0=BC=D0=BE=D0=B2=D1=8B=D1=85=20=D1=81=D0=BE=D0=BE?= =?UTF-8?q?=D0=B1=D1=89=D0=B5=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Inc/CanSerialPortFrame.h | 84 ++++++ Src/CanSerialPortFrame.c | 555 +++++++++++++++++++++++++++++++++++++++ modular.json | 17 ++ 3 files changed, 656 insertions(+) create mode 100644 Inc/CanSerialPortFrame.h create mode 100644 Src/CanSerialPortFrame.c create mode 100644 modular.json diff --git a/Inc/CanSerialPortFrame.h b/Inc/CanSerialPortFrame.h new file mode 100644 index 0000000..45d2447 --- /dev/null +++ b/Inc/CanSerialPortFrame.h @@ -0,0 +1,84 @@ +// +// Created by cfif on 16.03.2024. +// + +#ifndef ARTERY_CAN_MODULE_CAN_FRAME_H +#define ARTERY_CAN_MODULE_CAN_FRAME_H + +#include "SerialPortFrameIO.h" +#include "SerialPortIO.h" +#include "cmsis_os2.h" +#include "n32g45x.h" + +typedef enum { + CAN_BAUD_RATE_1000K, + CAN_BAUD_RATE_500K, + CAN_BAUD_RATE_250K, + CAN_BAUD_RATE_125K +} eCanBaudRate; + +typedef enum { + CAN_STD_ID, + CAN_EXT_ID +} eCanTypeFrame; + +typedef enum +{ + CAN_TX_MAILBOX0 = 0x00, + CAN_TX_MAILBOX1 = 0x01, + CAN_TX_MAILBOX2 = 0x02 +} can_tx_mailbox_num_type; + +typedef struct { + CAN_Module *can; + + uint32_t id; + uint32_t id1; + + eCanTypeFrame canTypeFrame; + + bool reInit; + + eCanBaudRate canBaudRate; + + osMessageQueueId_t rxDataQueue0; + osMessageQueueId_t rxDataQueue1; + + osMessageQueueId_t rxDataSnifferQueue0; + osMessageQueueId_t rxDataSnifferQueue1; + + osMessageQueueId_t txAccessQueue1; + osMessageQueueId_t txAccessQueue2; + +} tCanSerialPortFrameNation; + +void CanSerialPortFrameIrqRxProcessing0(tCanSerialPortFrameNation *env); +void CanSerialPortFrameIrqRxProcessing1(tCanSerialPortFrameNation *env); + +void vCanSerialPortFrameInit( + tCanSerialPortFrameNation *env, + CAN_Module *CANx, + eCanBaudRate canBaudRate, + uint8_t irqSubPriority, + eCanTypeFrame canTypeFrame, + uint32_t canId, + uint32_t rxBufferLength0, + uint32_t rxSnifferLength0, + uint32_t rxBufferLength1, + uint32_t rxSnifferLength1 +); + +void CanSerialPortFrameSetId(tCanSerialPortFrameNation *env, uint32_t id); +void CanSerialPortFrameSetId1(tCanSerialPortFrameNation *env, uint32_t id); +void CanSerialPortFrameSetType(tCanSerialPortFrameNation *env, eCanTypeFrame canTypeFrame); +tSerialPortFrameIO CanPortFrame_GetIo(tCanSerialPortFrameNation *env); +tSerialPortFrameIO CanPortFrame_GetSnifferIo(tCanSerialPortFrameNation *env); + +void CanSerialPortFrameSetFilter(tCanSerialPortFrameNation *env, + bool canFilterEnable, + uint32_t canFilter0Id, + uint32_t canFilter0Mask, + uint32_t canFilter1Id, + uint32_t canFilter1Mask); + +#endif //ARTERY_CAN_MODULE_CAN_FRAME_H diff --git a/Src/CanSerialPortFrame.c b/Src/CanSerialPortFrame.c new file mode 100644 index 0000000..ec005ed --- /dev/null +++ b/Src/CanSerialPortFrame.c @@ -0,0 +1,555 @@ +// +// Created by cfif on 16.03.2024. +// +#include +#include "CanSerialPortFrame.h" +#include "memory.h" + +#define CAN_FRAME_FILTER_STDID(STDID) ((STDID & 0x7FF) << 5) +#define CAN_FRAME_FILTER_EXTID_H(EXTID) ((uint16_t)(((EXTID << 3) | CAN_ID_EXT) >> 16)) +#define CAN_FRAME_FILTER_EXTID_L(EXTID) ((uint16_t)(( EXTID << 3) | CAN_ID_EXT)) + + +#define CAN_FRAME_FILTER_STDMASK(STDMASK) ((STDMASK & 0x7FF) << 5) +#define CAN_FRAME_FILTER_EXTMASK_H(EXTMASK) ((uint16_t)(((EXTMASK << 3) >> 16))) +#define CAN_FRAME_FILTER_EXTMASK_L(EXTMASK) ((uint16_t)(EXTMASK << 3)) + + +static void vCanSerialPortFrameInitNVICEnable(CAN_Module *CANx, uint8_t irqSubPriority) { + + NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); + + if (CANx == CAN1) { + NVIC_EnableIRQ(CAN1_SCE_IRQn); + NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn); + NVIC_EnableIRQ(CAN1_RX1_IRQn); + NVIC_SetPriority(CAN1_SCE_IRQn, irqSubPriority); + NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, irqSubPriority); + NVIC_SetPriority(CAN1_RX1_IRQn, irqSubPriority); + + CAN_INTConfig(CAN1, CAN_INT_FMP0, ENABLE); + CAN_INTConfig(CAN1, CAN_INT_FMP1, ENABLE); + + CAN_INTConfig(CAN1, CAN_INT_LEC, ENABLE); +// CAN_INTConfig(CAN1, CAN_INT_ERR, ENABLE); + } + + if (CANx == CAN2) { + NVIC_EnableIRQ(CAN2_SCE_IRQn); + NVIC_EnableIRQ(CAN2_RX0_IRQn); + NVIC_EnableIRQ(CAN2_RX1_IRQn); + NVIC_SetPriority(CAN2_SCE_IRQn, irqSubPriority); + NVIC_SetPriority(CAN2_RX0_IRQn, irqSubPriority); + NVIC_SetPriority(CAN2_RX1_IRQn, irqSubPriority); + + CAN_INTConfig(CAN2, CAN_INT_FMP0, ENABLE); + CAN_INTConfig(CAN2, CAN_INT_FMP1, ENABLE); + + CAN_INTConfig(CAN2, CAN_INT_LEC, ENABLE); +// CAN_INTConfig(CAN2, CAN_INT_ERR, ENABLE); + } + + +} + +void CanSerialPortFrameSetFilter(tCanSerialPortFrameNation *env, + bool canFilterEnable, + uint32_t canFilter0Id, + uint32_t canFilter0Mask, + uint32_t canFilter1Id, + uint32_t canFilter1Mask) { + + CAN_FilterInitType CAN_FilterInitStructure0; + + CAN_FilterInitStructure0.Filter_Num = 0; + CAN_FilterInitStructure0.Filter_Mode = CAN_Filter_IdMaskMode; + CAN_FilterInitStructure0.Filter_Scale = CAN_Filter_32bitScale; + + if (env->canTypeFrame == CAN_STD_ID) { + CAN_FilterInitStructure0.Filter_HighId = CAN_FRAME_FILTER_STDID(canFilter0Id); + CAN_FilterInitStructure0.Filter_LowId = CAN_FRAME_FILTER_STDID(canFilter0Id); + CAN_FilterInitStructure0.FilterMask_HighId = CAN_FRAME_FILTER_STDMASK(canFilter0Mask); + CAN_FilterInitStructure0.FilterMask_LowId = CAN_FRAME_FILTER_STDMASK(canFilter0Mask); + } + + if (env->canTypeFrame == CAN_EXT_ID) { + CAN_FilterInitStructure0.Filter_HighId = CAN_FRAME_FILTER_EXTID_H(canFilter0Id); + CAN_FilterInitStructure0.Filter_LowId = CAN_FRAME_FILTER_EXTID_L(canFilter0Id); + CAN_FilterInitStructure0.FilterMask_HighId = CAN_FRAME_FILTER_EXTMASK_H(canFilter0Mask); + CAN_FilterInitStructure0.FilterMask_LowId = CAN_FRAME_FILTER_EXTMASK_L(canFilter0Mask); + } + + CAN_FilterInitStructure0.Filter_FIFOAssignment = CAN_FIFO0; + + if (canFilterEnable) { + CAN_FilterInitStructure0.Filter_Act = ENABLE; + } else { + CAN_FilterInitStructure0.Filter_Act = DISABLE; + } + + + CAN_FilterInitType CAN_FilterInitStructure1; + + CAN_FilterInitStructure1.Filter_Num = 1; + CAN_FilterInitStructure1.Filter_Mode = CAN_Filter_IdMaskMode; + CAN_FilterInitStructure1.Filter_Scale = CAN_Filter_32bitScale; + + if (env->canTypeFrame == CAN_STD_ID) { + CAN_FilterInitStructure1.Filter_HighId = CAN_FRAME_FILTER_STDID(canFilter1Id); + CAN_FilterInitStructure1.Filter_LowId = CAN_FRAME_FILTER_STDID(canFilter1Id); + CAN_FilterInitStructure1.FilterMask_HighId = CAN_FRAME_FILTER_STDMASK(canFilter1Mask); + CAN_FilterInitStructure1.FilterMask_LowId = CAN_FRAME_FILTER_STDMASK(canFilter1Mask); + } + + if (env->canTypeFrame == CAN_EXT_ID) { + CAN_FilterInitStructure1.Filter_HighId = CAN_FRAME_FILTER_EXTID_H(canFilter1Id); + CAN_FilterInitStructure1.Filter_LowId = CAN_FRAME_FILTER_EXTID_L(canFilter1Id); + CAN_FilterInitStructure1.FilterMask_HighId = CAN_FRAME_FILTER_EXTMASK_H(canFilter1Mask); + CAN_FilterInitStructure1.FilterMask_LowId = CAN_FRAME_FILTER_EXTMASK_L(canFilter1Mask); + } + + CAN_FilterInitStructure1.Filter_FIFOAssignment = CAN_FIFO1; + + if (canFilterEnable) { + CAN_FilterInitStructure1.Filter_Act = ENABLE; + } else { + CAN_FilterInitStructure1.Filter_Act = DISABLE; + } + + + if (env->can == CAN1) { + CAN1_InitFilter(&CAN_FilterInitStructure0); + CAN1_InitFilter(&CAN_FilterInitStructure1); + } + + if (env->can == CAN2) { + CAN2_InitFilter(&CAN_FilterInitStructure0); + CAN2_InitFilter(&CAN_FilterInitStructure1); + } +} + +void CanSerialPortFrameSetId(tCanSerialPortFrameNation *env, uint32_t id) { + env->id = id; +} + +void CanSerialPortFrameSetId1(tCanSerialPortFrameNation *env, uint32_t id) { + env->id1 = id; +} + +void CanSerialPortFrameSetType(tCanSerialPortFrameNation *env, eCanTypeFrame canTypeFrame) { + env->canTypeFrame = canTypeFrame; +} + +static void vCanSerialPortFrameInitStructure( + tCanSerialPortFrameNation *env, + CAN_Module *CANx, + uint32_t rxBufferLength0, + uint32_t rxSnifferLength0, + uint32_t rxBufferLength1, + uint32_t rxSnifferLength1 +) { + env->rxDataQueue0 = osMessageQueueNew(rxBufferLength0, sizeof(CanRxMessage), NULL); + if (rxSnifferLength0) { + env->rxDataSnifferQueue0 = osMessageQueueNew(rxSnifferLength0, sizeof(CanRxMessage), NULL); + } else { + env->rxDataSnifferQueue0 = 0; + } + + env->rxDataQueue1 = osMessageQueueNew(rxBufferLength1, sizeof(CanRxMessage), NULL); + if (rxSnifferLength1) { + env->rxDataSnifferQueue1 = osMessageQueueNew(rxSnifferLength1, sizeof(CanRxMessage), NULL); + } else { + env->rxDataSnifferQueue1 = 0; + } +} + +void vCanSerialPortFrameInit( + tCanSerialPortFrameNation *env, + CAN_Module *CANx, + eCanBaudRate canBaudRate, + uint8_t irqSubPriority, + eCanTypeFrame canTypeFrame, + uint32_t canId, + uint32_t rxBufferLength0, + uint32_t rxSnifferLength0, + uint32_t rxBufferLength1, + uint32_t rxSnifferLength1 +) { + + env->can = CANx; + + if (!env->reInit) { + env->reInit = true; + vCanSerialPortFrameInitStructure(env, CANx, rxBufferLength0, rxSnifferLength0, rxBufferLength1, + rxSnifferLength1); + + CanSerialPortFrameSetType(env, canTypeFrame); + CanSerialPortFrameSetId(env, canId); + + env->canBaudRate = canBaudRate; + } + + + CAN_InitType CAN_InitStructure; + CAN_DeInit(CANx); + + CAN_InitStruct(&CAN_InitStructure); + CAN_InitStructure.TTCM = DISABLE; + CAN_InitStructure.ABOM = DISABLE; + CAN_InitStructure.AWKUM = DISABLE; + CAN_InitStructure.NART = DISABLE; + CAN_InitStructure.RFLM = DISABLE; + CAN_InitStructure.TXFP = ENABLE; + CAN_InitStructure.OperatingMode = CAN_Normal_Mode; + + if (canBaudRate == CAN_BAUD_RATE_1000K) { + CAN_InitStructure.RSJW = CAN_RSJW_1tq; + CAN_InitStructure.TBS1 = CAN_TBS1_5tq; + CAN_InitStructure.TBS2 = CAN_TBS2_3tq; + CAN_InitStructure.BaudRatePrescaler = 4; + } + + if (canBaudRate == CAN_BAUD_RATE_500K) { + CAN_InitStructure.RSJW = CAN_RSJW_1tq; + CAN_InitStructure.TBS1 = CAN_TBS1_5tq; + CAN_InitStructure.TBS2 = CAN_TBS2_2tq; + CAN_InitStructure.BaudRatePrescaler = 9; + } + + if (canBaudRate == CAN_BAUD_RATE_250K) { + CAN_InitStructure.RSJW = CAN_RSJW_1tq; + CAN_InitStructure.TBS1 = CAN_TBS1_4tq; + CAN_InitStructure.TBS2 = CAN_TBS2_3tq; + CAN_InitStructure.BaudRatePrescaler = 18; + } + + if (canBaudRate == CAN_BAUD_RATE_125K) { + CAN_InitStructure.RSJW = CAN_RSJW_1tq; + CAN_InitStructure.TBS1 = CAN_TBS1_13tq; + CAN_InitStructure.TBS2 = CAN_TBS2_4tq; + CAN_InitStructure.BaudRatePrescaler = 16; + } + + CAN_Init(CANx, &CAN_InitStructure); + + CanSerialPortFrameSetFilter(env, true, 0, 0, 0, 0); + + vCanSerialPortFrameInitNVICEnable(CANx, irqSubPriority); +} + + +void CanSerialPortFrameIrqRxProcessing0(tCanSerialPortFrameNation *env) { + CanRxMessage rx_message_struct; + + CAN_ReceiveMessage(env->can, CAN_FIFO0, &rx_message_struct); + + osMessageQueuePut(env->rxDataQueue0, &rx_message_struct, 0x0, 0U); + + if (env->rxDataSnifferQueue0) { + osMessageQueuePut(env->rxDataSnifferQueue0, &rx_message_struct, 0x0, 0U); + } + +} + +void CanSerialPortFrameIrqRxProcessing1(tCanSerialPortFrameNation *env) { + CanRxMessage rx_message_struct; + + CAN_ReceiveMessage(env->can, CAN_FIFO1, &rx_message_struct); + + osMessageQueuePut(env->rxDataQueue1, &rx_message_struct, 0x0, 0U); + + if (env->rxDataSnifferQueue1) { + osMessageQueuePut(env->rxDataSnifferQueue1, &rx_message_struct, 0x0, 0U); + } + +} + +static uint16_t vSerialPortFrameReceiveQueue( + tCanSerialPortFrameNation *env, uint8_t *data, uint16_t size, uint32_t timeout, osMessageQueueId_t queueId +) { + uint16_t received = 0; + + if (timeout) { + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs; + + while (size && ((timeout == SystemWaitForever) || (endMs > SystemGetMs()))) { + leftMs = endMs - SystemGetMs(); + if (osMessageQueueGet(queueId, data, NULL, leftMs) == osOK) { + --size; + ++received; + ++data; + } + } + } else { + while (size) { + if (osMessageQueueGet(queueId, data, NULL, 0) == osOK) { + --size; + ++received; + ++data; + } else { + return received; + } + } + } + + return received; +} + +static uint16_t +vCanSerialPortFrameReceive0(tCanSerialPortFrameNation *env, uint8_t *data, uint16_t size, uint32_t timeout) { + return vSerialPortFrameReceiveQueue(env, data, size, timeout, env->rxDataQueue0); +} + + +static uint16_t +vCanSerialPortFrameReceive1(tCanSerialPortFrameNation *env, uint8_t *data, uint16_t size, uint32_t timeout) { + return vSerialPortFrameReceiveQueue(env, data, size, timeout, env->rxDataQueue1); +} + + +static uint16_t +vCanSerialPortFrameReceiveSniffer0(tCanSerialPortFrameNation *env, uint8_t *data, uint16_t size, uint32_t timeout) { + + return env->rxDataSnifferQueue0 + ? vSerialPortFrameReceiveQueue(env, data, size, timeout, env->rxDataSnifferQueue0) + : 0; +} + +static uint16_t +vCanSerialPortFrameReceiveSniffer1(tCanSerialPortFrameNation *env, uint8_t *data, uint16_t size, uint32_t timeout) { + + return env->rxDataSnifferQueue1 + ? vSerialPortFrameReceiveQueue(env, data, size, timeout, env->rxDataSnifferQueue1) + : 0; +} + +uint8_t can_message_transmitExt(CAN_Module* CANx, CanTxMessage* TxMessage, can_tx_mailbox_num_type mailbox) +{ + uint8_t transmit_mailbox = CAN_TxSTS_NoMailBox; + + if (mailbox == CAN_TX_MAILBOX0) { + if (CANx->TSTS & CAN_TSTS_TMEM0) { + transmit_mailbox = CAN_TX_MAILBOX0; + } else { + transmit_mailbox = CAN_TxSTS_NoMailBox; + } + } + + if (mailbox == CAN_TX_MAILBOX1) { + if (CANx->TSTS & CAN_TSTS_TMEM1) { + transmit_mailbox = CAN_TX_MAILBOX1; + } else { + transmit_mailbox = CAN_TxSTS_NoMailBox; + } + } + + if (mailbox == CAN_TX_MAILBOX2) { + if (CANx->TSTS & CAN_TSTS_TMEM2) { + transmit_mailbox = CAN_TX_MAILBOX2; + } else { + transmit_mailbox = CAN_TxSTS_NoMailBox; + } + } + + + if (transmit_mailbox != CAN_TxSTS_NoMailBox) + { + CANx->sTxMailBox[transmit_mailbox].TMI &= 1; + if (TxMessage->IDE == CAN_Standard_Id) + { + assert_param(IS_CAN_STDID(TxMessage->StdId)); + CANx->sTxMailBox[transmit_mailbox].TMI |= ((TxMessage->StdId << 21) | TxMessage->RTR); + } + else + { + assert_param(IS_CAN_EXTID(TxMessage->ExtId)); + CANx->sTxMailBox[transmit_mailbox].TMI |= ((TxMessage->ExtId << 3) | TxMessage->IDE | TxMessage->RTR); + } + + TxMessage->DLC &= (uint8_t)0x0000000F; + CANx->sTxMailBox[transmit_mailbox].TMDT &= (uint32_t)0xFFFFFFF0; + CANx->sTxMailBox[transmit_mailbox].TMDT |= TxMessage->DLC; + + CANx->sTxMailBox[transmit_mailbox].TMDL = + (((uint32_t)TxMessage->Data[3] << 24) | ((uint32_t)TxMessage->Data[2] << 16) + | ((uint32_t)TxMessage->Data[1] << 8) | ((uint32_t)TxMessage->Data[0])); + + CANx->sTxMailBox[transmit_mailbox].TMDH = + (((uint32_t)TxMessage->Data[7] << 24) | ((uint32_t)TxMessage->Data[6] << 16) + | ((uint32_t)TxMessage->Data[5] << 8) | ((uint32_t)TxMessage->Data[4])); + + CANx->sTxMailBox[transmit_mailbox].TMI |= 1; + } + + return transmit_mailbox; +} + + +uint16_t vCanSerialPortFrameTransmit(tCanSerialPortFrameNation *env, uint8_t *data, uint16_t size, uint32_t timeout) { + uint16_t sent = 0; + uint32_t endMs = SystemGetMs() + timeout; + + uint16_t fullSize = size / 8; + uint8_t tailSize = size % 8; + + uint8_t transmit_mailbox; + CanTxMessage TxMessage; + + + if (env->canTypeFrame == CAN_STD_ID) { + TxMessage.StdId = env->id; + TxMessage.ExtId = 0; + TxMessage.IDE = CAN_ID_STD; + } + + if (env->canTypeFrame == CAN_EXT_ID) { + TxMessage.StdId = 0; + TxMessage.ExtId = env->id; + TxMessage.IDE = CAN_ID_EXT; + } + + TxMessage.RTR = CAN_RTRQ_DATA; + TxMessage.DLC = 8; + + while (size && ((timeout == SystemWaitForever) || (endMs > SystemGetMs()))) { + + uint16_t len = 0; + for (uint16_t i = 0; i < fullSize; ++i) { + + memcpy(TxMessage.Data, &data[len], 8); + len += 8; + + transmit_mailbox = can_message_transmitExt(env->can, &TxMessage, CAN_TX_MAILBOX0); + + while (CAN_TransmitSTS(env->can, 0) != CANTXSTSOK) { + if (!((timeout == SystemWaitForever) || (endMs > SystemGetMs()))) { + return sent; + } + } + + sent += 8; + size -= 8; + } + + if (tailSize) { + TxMessage.DLC = tailSize; + memcpy(TxMessage.Data, &data[len], tailSize); + + transmit_mailbox = can_message_transmitExt(env->can, &TxMessage, CAN_TX_MAILBOX0); + + uint8_t status = CAN_TransmitSTS(env->can, (can_tx_mailbox_num_type) transmit_mailbox); + + while (status != CANTXSTSOK) { + + status = CAN_TransmitSTS(env->can, (can_tx_mailbox_num_type) transmit_mailbox); + + if (!((timeout == SystemWaitForever) || (endMs > SystemGetMs()))) { + return sent; + } + + } + + sent += tailSize; + size -= tailSize; + } + + } + + return sent; +} + +uint16_t vCanSerialPortFrameTransmit1(tCanSerialPortFrameNation *env, uint8_t *data, uint16_t size, uint32_t timeout) { + uint16_t sent = 0; + uint32_t endMs = SystemGetMs() + timeout; + + uint16_t fullSize = size / 8; + uint8_t tailSize = size % 8; + + uint8_t transmit_mailbox; + CanTxMessage TxMessage; + + + if (env->canTypeFrame == CAN_STD_ID) { + TxMessage.StdId = env->id; + TxMessage.ExtId = 0; + TxMessage.IDE = CAN_ID_STD; + } + + if (env->canTypeFrame == CAN_EXT_ID) { + TxMessage.StdId = 0; + TxMessage.ExtId = env->id; + TxMessage.IDE = CAN_ID_EXT; + } + + TxMessage.RTR = CAN_RTRQ_DATA; + TxMessage.DLC = 8; + + while (size && ((timeout == SystemWaitForever) || (endMs > SystemGetMs()))) { + + uint16_t len = 0; + for (uint16_t i = 0; i < fullSize; ++i) { + + memcpy(TxMessage.Data, &data[len], 8); + len += 8; + + transmit_mailbox = can_message_transmitExt(env->can, &TxMessage, CAN_TX_MAILBOX1); + + while (CAN_TransmitSTS(env->can, 0) != CANTXSTSOK) { + if (!((timeout == SystemWaitForever) || (endMs > SystemGetMs()))) { + return sent; + } + } + + sent += 8; + size -= 8; + } + + if (tailSize) { + TxMessage.DLC = tailSize; + memcpy(TxMessage.Data, &data[len], tailSize); + + transmit_mailbox = can_message_transmitExt(env->can, &TxMessage, CAN_TX_MAILBOX1); + + uint8_t status = CAN_TransmitSTS(env->can, (can_tx_mailbox_num_type) transmit_mailbox); + + while (status != CANTXSTSOK) { + + status = CAN_TransmitSTS(env->can, (can_tx_mailbox_num_type) transmit_mailbox); + + if (!((timeout == SystemWaitForever) || (endMs > SystemGetMs()))) { + return sent; + } + + } + + sent += tailSize; + size -= tailSize; + } + + } + + return sent; +} + +tSerialPortFrameIO CanPortFrame_GetIo(tCanSerialPortFrameNation *env) { + tSerialPortFrameIO io = { + .env = env, + .receive0 = (SerialPortFrameIOTransaction) vCanSerialPortFrameReceive0, + .receive1 = (SerialPortFrameIOTransaction) vCanSerialPortFrameReceive1, + .transmit = (SerialPortFrameIOTransaction) vCanSerialPortFrameTransmit, + .transmit1 = (SerialPortFrameIOTransaction) vCanSerialPortFrameTransmit1 + }; + return io; +} + +tSerialPortFrameIO CanPortFrame_GetSnifferIo(tCanSerialPortFrameNation *env) { + tSerialPortFrameIO io = { + .env = env, + .receive0 = (SerialPortFrameIOTransaction) vCanSerialPortFrameReceiveSniffer0, + .receive1 = (SerialPortFrameIOTransaction) vCanSerialPortFrameReceiveSniffer1, + .transmit = (SerialPortFrameIOTransaction) vCanSerialPortFrameTransmit, + .transmit1 = (SerialPortFrameIOTransaction) vCanSerialPortFrameTransmit1 + }; + return io; +} \ No newline at end of file diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..b630424 --- /dev/null +++ b/modular.json @@ -0,0 +1,17 @@ +{ + "dep": [ + { + "type": "git", + "provider": "NAVIGATOR_UVEOS_NATION_TELIT", + "repo": "SerialPort" + } + ], + "cmake": { + "inc_dirs": [ + "Inc" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file