cancel
Showing results for 
Search instead for 
Did you mean: 

STM32MP1 FDCAN not leaving init mode (Zephyr os project)

PNgou.1
Associate

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;
}

3 REPLIES 3
Olivier GALLIEN
ST Employee

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

Olivier GALLIEN
In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
PNgou.1
Associate

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

AKoza.1
Associate

I have the same problem (but with a bare metal project). Have you found any solution?