555 lines
18 KiB
C
555 lines
18 KiB
C
//
|
|
// Created by cfif on 16.03.2024.
|
|
//
|
|
#include <SystemDelayInterface.h>
|
|
#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;
|
|
} |