2020-05-04 02:15 AM
Hello !
I have some trouble implementing a FDCAN internal loopback on the STM32MP157c-dk2.
I have linked the FDCAN1 Instance to the cortex M4 and I don't have any can bus to connect it to yet so I'm trying to implement an internal loopback. I took the exemple code that came with the stm32cube (STM32CubeMP1/Projects/STM32MP157C-DK2/Examples) tool and I replaced the external loopback mode with the internal one.
The code blocks after having put the messages in the tx fifo (function HAL_FDCAN_IsTxBufferMessagePending() ).
The messages are written in memory but they are never sent.
I found that the FDCAN never ended it's init phase (FDCAN_CCCR_INIT stays set even after HAL_FDCAN_Start() function is called)
I tried to force using the same protocol used to set it but it causes a timeout.
Is anyone knowing why it won't switch to the normal operation mode ?
Thanks in advance.
Paul
ps : here is the code, I'm not in engineering mode so the device tree is managed by zephyr, I added the correct FDCAN address to it, don't know if something is missing
can1: can@4400e000 {
compatible = "st,stm32-can-fd";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x4400e000 0x400>;
interrupts = <19 0>, <21 0>;
interrupt-names = "LINE_1", "LINE_0";
clocks = <&rcc STM32_CLOCK_BUS_APB2 0x01000000>;
status = "disabled";
label = "CAN_1";
};
MX_GPIO_Init();
MX_FDCAN1_Init();
/*##-1 Configure the FDCAN filters ########################################*/
/* Configure standard ID reception filter to Rx FIFO 0 */
sFilterConfig.IdType = FDCAN_STANDARD_ID;
sFilterConfig.FilterIndex = 0;
sFilterConfig.FilterType = FDCAN_FILTER_DUAL;
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
sFilterConfig.FilterID1 = 0x444;
sFilterConfig.FilterID2 = 0x555;
if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
/* Configure extended ID reception filter to Rx FIFO 1 */
sFilterConfig.IdType = FDCAN_EXTENDED_ID;
sFilterConfig.FilterIndex = 0;
sFilterConfig.FilterType = FDCAN_FILTER_RANGE_NO_EIDM;
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
sFilterConfig.FilterID1 = 0x1111111;
sFilterConfig.FilterID2 = 0x2222222;
if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
/*##-2 Start FDCAN controller (continuous listening CAN bus) ##############*/
if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK)
{
Error_Handler();
}
/*##-3 Transmit messages ##################################################*/
/* Add message to Tx FIFO */
TxHeader.Identifier = 0x444;
TxHeader.IdType = FDCAN_STANDARD_ID;
TxHeader.TxFrameType = FDCAN_DATA_FRAME;
TxHeader.DataLength = FDCAN_DLC_BYTES_12;
TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
TxHeader.BitRateSwitch = FDCAN_BRS_ON;
TxHeader.FDFormat = FDCAN_FD_CAN;
TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
TxHeader.MessageMarker = 0x52;
if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData0) != HAL_OK)
{
Error_Handler();
}
/* Add second message to Tx FIFO */
TxHeader.Identifier = 0x1111112;
TxHeader.IdType = FDCAN_EXTENDED_ID;
TxHeader.TxFrameType = FDCAN_DATA_FRAME;
TxHeader.DataLength = FDCAN_DLC_BYTES_12;
TxHeader.ErrorStateIndicator = FDCAN_ESI_PASSIVE;
TxHeader.BitRateSwitch = FDCAN_BRS_ON;
TxHeader.FDFormat = FDCAN_FD_CAN;
TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
TxHeader.MessageMarker = 0xCC;
if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData1) != HAL_OK)
{
Error_Handler();
}
/* Add third message to Tx FIFO */
TxHeader.Identifier = 0x1111113;
TxHeader.IdType = FDCAN_EXTENDED_ID;
TxHeader.TxFrameType = FDCAN_DATA_FRAME;
TxHeader.DataLength = FDCAN_DLC_BYTES_12;
TxHeader.ErrorStateIndicator = FDCAN_ESI_PASSIVE;
TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
TxHeader.FDFormat = FDCAN_FD_CAN;
TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
TxHeader.MessageMarker = 0xDD;
if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData2) != HAL_OK)
{
Error_Handler();
}
/* Get tick */
Tickstart = HAL_GetTick();
/* Check transmission occurred before timeout */
while(HAL_FDCAN_IsTxBufferMessagePending(&hfdcan1, FDCAN_TX_BUFFER0 | FDCAN_TX_BUFFER1 | FDCAN_TX_BUFFER2) != 0)
{
if((HAL_GetTick() - Tickstart) > TX_FAST_TIMEOUT)
{
Error_Handler();
break;
}
}
/*##-4 Receive messages ###################################################*/
/* Get tick */
Tickstart = HAL_GetTick();
/* Check one message is received in Rx FIFO 0 */
while(HAL_FDCAN_GetRxFifoFillLevel(&hfdcan1, FDCAN_RX_FIFO0) != 1)
{
if((HAL_GetTick() - Tickstart) > RX_FAST_TIMEOUT)
{
Error_Handler();
break;
}
}
/* Retrieve message from Rx FIFO 0 */
if (HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
{
Error_Handler();
}
/* Compare payload to expected data */
if (BufferCmp8b(TxData0, RxData, 12) != 0)
{
Error_Handler();
}
/* Get tick */
Tickstart = HAL_GetTick();
/* Check two messages are received in Rx FIFO 1 */
while(HAL_FDCAN_GetRxFifoFillLevel(&hfdcan1, FDCAN_RX_FIFO1) != 2)
{
if((HAL_GetTick() - Tickstart) > RX_FAST_TIMEOUT)
{
Error_Handler();
break;
}
}
/* Retrieve message from Rx FIFO 1 */
if (HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_FIFO1, &RxHeader, RxData) != HAL_OK)
{
Error_Handler();
}
/* Compare payload to expected data */
if (BufferCmp8b(TxData1, RxData, 12) != 0)
{
Error_Handler();
}
/* Retrieve next message from Rx FIFO 1 */
if (HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_FIFO1, &RxHeader, RxData) != HAL_OK)
{
Error_Handler();
}
/* Compare payload to expected data */
if (BufferCmp8b(TxData2, RxData, 12) != 0)
{
Error_Handler();
}
static void MX_FDCAN1_Init(void)
{
/* USER CODE BEGIN FDCAN1_Init 0 */
/* USER CODE END FDCAN1_Init 0 */
/* USER CODE BEGIN FDCAN1_Init 1 */
/* USER CODE END FDCAN1_Init 1 */
hfdcan1.Instance = FDCAN1;
hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_BRS;
hfdcan1.Init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK;
hfdcan1.Init.AutoRetransmission = ENABLE;
hfdcan1.Init.TransmitPause = DISABLE;
hfdcan1.Init.ProtocolException = ENABLE;
/* Bit time configuration:
************************
Bit time parameter | Nominal | Data
---------------------------|--------------|--------------
fdcan_ker_ck | 80 MHz | 80 MHz
Time_quantum (tq) | 12.5 ns | 12.5 ns
Prescaler | 2 | 1
Synchronization_segment | 1 tq | 1 tq
Propagation_segment | 19 tq | 5 tq
Phase_segment_1 | 10 tq | 2 tq
Phase_segment_2 | 10 tq | 2 tq
Synchronization_Jump_width | 10 tq | 2 tq
Bit_length | 80 tq = 1 �s | 10 tq = 0.125 �s
Bit_rate | 1 MBit/s | 8 MBit/s
*/
hfdcan1.Init.NominalPrescaler = 0x2;
hfdcan1.Init.NominalSyncJumpWidth = 0xA;
hfdcan1.Init.NominalTimeSeg1 = 0x1D;
hfdcan1.Init.NominalTimeSeg2 = 0xA;
hfdcan1.Init.DataPrescaler = 0x1;
hfdcan1.Init.DataSyncJumpWidth = 0x2;
hfdcan1.Init.DataTimeSeg1 = 0x7;
hfdcan1.Init.DataTimeSeg2 = 0x2;
hfdcan1.Init.MessageRAMOffset = 0;
hfdcan1.Init.StdFiltersNbr = 1;
hfdcan1.Init.ExtFiltersNbr = 1;
hfdcan1.Init.RxFifo0ElmtsNbr = 8;
hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_12;
hfdcan1.Init.RxFifo1ElmtsNbr = 2;
hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_12;
hfdcan1.Init.RxBuffersNbr = 8;
hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_12;
hfdcan1.Init.TxEventsNbr = 2;
hfdcan1.Init.TxBuffersNbr = 8;
hfdcan1.Init.TxFifoQueueElmtsNbr = 8;
hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_12;
if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN FDCAN1_Init 2 */
/* USER CODE END FDCAN1_Init 2 */
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOI_CLK_ENABLE();
}
/* USER CODE BEGIN 4 */
/**
* @brief Compares two buffers.
* @par Input
* - pBuffer1, pBuffer2: buffers to be compared.
* - BufferLength: buffer's length
* @par Output
* None.
* @retval
* 0: pBuffer1 identical to pBuffer2
* 1: pBuffer1 differs from pBuffer2
*/
static uint32_t BufferCmp8b(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)
{
while(BufferLength--)
{
if(*pBuffer1 != *pBuffer2)
{
return 1;
}
pBuffer1++;
pBuffer2++;
}
return 0;
}
2020-05-04 07:49 AM
Hi @PNgou.1
This sentence "I'm not in engineering mode so the device tree is managed by zephyr" is puzzling me.
Can you clarify your software architecture Linux A7 + M4 Zephyr ? Or else ?
Thanks
Olivier
2020-05-04 08:14 AM
Hi @Community member, Thanks for responding,
Indeed I'm actually running linux on the A7 and Zephyr on the M4.
I asked on Zephyr forums for the FDCAN support but no driver has been developed yet. I took example on a pull request for the device tree modification (https://github.com/zephyrproject-rtos/zephyr/pull/22832).
Paul
2022-04-13 02:58 AM
I have the same problem (but with a bare metal project). Have you found any solution?