2023-01-06 07:12 AM
Hello,
I am currently working on a motor setup between an STM32H750VBT6 with a CJMCU-1051 and a motordriver VESC mini FESC 4.20. I have 5 PDO messages coming from de Motor controller which I can read in normal mode. However, after a while the STM32H7xx seems to stop with sending can messages. The error code, which it returns, is 512 (HAL_FDCAN_ERROR_FIFO_FULL).
I tried to set the mode to external_loopback, which eliminated the problem. However, I cannot receive any messages coming from the canbus, because this mode blocks incoming data. The problem is that the Motor controller won’t acknowledge my messages.
Is there a way to automatically acknowledge the transmitted messages, while receiving can messages as well. or configure FDCAN without ack requirements? Thanks a lot.
init code:
void STM32_CANFD_DRIVER::can_init(uint16_t id)
{
UNUSED(id);
_hfdcan.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
_hfdcan.Init.Mode = FDCAN_MODE_NORMAL;
_hfdcan.Init.TransmitPause = DISABLE;
_hfdcan.Init.ProtocolException = DISABLE;
_hfdcan.Init.NominalPrescaler = prescaler;
_hfdcan.Init.NominalSyncJumpWidth = 15;
_hfdcan.Init.NominalTimeSeg1 = bs1;
_hfdcan.Init.NominalTimeSeg2 = bs2;
_hfdcan.Init.DataPrescaler = prescaler;
_hfdcan.Init.DataSyncJumpWidth = 15;
_hfdcan.Init.DataTimeSeg1 = bs1;
_hfdcan.Init.DataTimeSeg2 = bs2;
_hfdcan.Init.AutoRetransmission = DISABLE;
_hfdcan.Init.MessageRAMOffset = _hfdcan.Instance == FDCAN1 ? 0 : 1024;
_hfdcan.Init.StdFiltersNbr = 8;
_hfdcan.Init.ExtFiltersNbr = 0;
_hfdcan.Init.RxFifo0ElmtsNbr = 8;
_hfdcan.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
_hfdcan.Init.RxFifo1ElmtsNbr = 0;
_hfdcan.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
_hfdcan.Init.RxBuffersNbr = 8;
_hfdcan.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
_hfdcan.Init.TxEventsNbr = 8;
_hfdcan.Init.TxBuffersNbr = 8;
_hfdcan.Init.TxFifoQueueElmtsNbr = 8;
_hfdcan.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
_hfdcan.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
if (HAL_FDCAN_Init(&_hfdcan) != HAL_OK)
{
Error_Handler();
}
bus_state = BUS_OFF;
}
void STM32_CANFD_DRIVER::can_enable(void)
{
if (bus_state == BUS_OFF) {
if (HAL_FDCAN_Start(&_hfdcan) != HAL_OK)
{
Error_Handler();
}
bus_state = BUS_OK;
}
}
Transmit code:
CanState STM32_CANFD_DRIVER::can_tx(CAN_FRAME* tx_frame, uint32_t timeout)
{
FDCAN_TxHeaderTypeDef tx_header;
tx_header.BitRateSwitch = FDCAN_BRS_OFF;
switch (tx_frame->length) {
case 0:
tx_header.DataLength = FDCAN_DLC_BYTES_0;
break;
case 1:
tx_header.DataLength = FDCAN_DLC_BYTES_1;
break;
case 2:
tx_header.DataLength = FDCAN_DLC_BYTES_2;
break;
case 3:
tx_header.DataLength = FDCAN_DLC_BYTES_3;
break;
case 4:
tx_header.DataLength = FDCAN_DLC_BYTES_4;
break;
case 5:
tx_header.DataLength = FDCAN_DLC_BYTES_5;
break;
case 6:
tx_header.DataLength = FDCAN_DLC_BYTES_6;
break;
case 7:
tx_header.DataLength = FDCAN_DLC_BYTES_7;
break;
case 8:
tx_header.DataLength = FDCAN_DLC_BYTES_8;
break;
default:
Error_Handler();
break;
}
tx_header.FDFormat = FDCAN_CLASSIC_CAN;
tx_header.Identifier = tx_frame->id;
if (tx_frame->extended) {
tx_header.IdType = FDCAN_EXTENDED_ID;
}
else {
tx_header.IdType = FDCAN_STANDARD_ID;
}
tx_header.TxFrameType = tx_frame->rtr ? FDCAN_REMOTE_FRAME : FDCAN_DATA_FRAME;
tx_header.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
tx_header.MessageMarker = 0;
tx_header.TxEventFifoControl = FDCAN_NO_TX_EVENTS; // Should we do this or the other
if (HAL_FDCAN_AddMessageToTxFifoQ(&_hfdcan, &tx_header, tx_frame->data.uint8) != HAL_OK) {
LOGGER_PRINTF("CANFD FAILED TO TRANSMIT MESSAGE STM32_CANFD_driver:%d\n", __LINE__);
}
return DATA_OK;
}