0

I am attempting to use my STM32H7B3I-EVAL evaluation board to send and receive CAN communication messages. I am communicating with a Vector CANalayzer (16.0, VN1630A). The CANalyzer is being used both to display messages received from the evaluation board, as well as transmit its own data and send it to the evaluation board.

I am currently running the following C code attached to this.

The CANalyzer sees the data that is being sent in the bode for lines 111-138 in the code. However, when I try to receive data from the CANalyzer and make an LED blink on the evaluation board, it does not work.

The data I'm sending from the CANalyzer:

Message ID: 0x123

Data Length: 8

Data: Alternates between 0x2233445566778899 to 0x1223344556677889 every 2 seconds

I'm unsure why this code is successfully sending data to the CANalyzer but not receiving the data sent from it.

Have I not configured the Rx properly?

Test Code:

while(1)
{
  for (uint16_t i = 0; i < 0xFFFF; i++)
          {

              uint16_t TxData1[] = {i, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};

              //Add message to Tx FIFO
                TxHeader.Identifier = 0x111;
                TxHeader.IdType = FDCAN_STANDARD_ID;
                TxHeader.TxFrameType = FDCAN_DATA_FRAME;
                TxHeader.DataLength = FDCAN_DLC_BYTES_8;
                TxHeader.ErrorStateIndicator = FDCAN_ESI_PASSIVE;
                TxHeader.BitRateSwitch = FDCAN_BRS_ON;
                TxHeader.FDFormat = FDCAN_FD_CAN;
                TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
                TxHeader.MessageMarker = 0xCC;
                HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData1);
                HAL_Delay(5);

                uint16_t TxData2[] = {i, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};

                TxHeader.Identifier = 0x135;
                TxHeader.IdType = FDCAN_STANDARD_ID;
                TxHeader.TxFrameType = FDCAN_DATA_FRAME;
                TxHeader.DataLength = FDCAN_DLC_BYTES_8;
                TxHeader.ErrorStateIndicator = FDCAN_ESI_PASSIVE;
                TxHeader.BitRateSwitch = FDCAN_BRS_ON;
                TxHeader.FDFormat = FDCAN_FD_CAN;
                TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
                TxHeader.MessageMarker = 0xCC;
                HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData2);
                HAL_Delay(5);


                HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_BUFFER0, &RxHeader, RxData);

                if(BufferCmp8b(TxData3,RxData,8)==0){
                    BSP_LED_Toggle(LED1);
                }
          }

}

CAN Initialization:

static void CAN_Init(){
/* Initializes the FDCAN peripheral in loopback mode */
  hfdcan1.Instance = FDCAN1;
  hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
  hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
  hfdcan1.Init.AutoRetransmission = ENABLE;
  hfdcan1.Init.TransmitPause = ENABLE;
  hfdcan1.Init.ProtocolException = DISABLE;
  /* Bit time configuration:
    ************************
    Bit time parameter         | Nominal      |  Data
    ---------------------------|--------------|----------------
    fdcan_ker_ck               | 20 MHz       | 20 MHz
    Time_quantum (tq)          | 50 ns        | 50 ns
    Synchronization_segment    | 1 tq         | 1 tq
    Propagation_segment        | 23 tq        | 23 tq
    Phase_segment_1            | 8 tq         | 8 tq
    Phase_segment_2            | 8 tq         | 8 tq
    Synchronization_Jump_width | 8 tq         | 8 tq
    Bit_length                 | 40 tq = 2 �s | 40 tq = 2 �s
    Bit_rate                   | 0.5 MBit/s   | 0.5 MBit/s
  */
  hfdcan1.Init.NominalPrescaler = 0x1; /* tq = NominalPrescaler x (1/fdcan_ker_ck) */
  hfdcan1.Init.NominalSyncJumpWidth = 0x8;
  hfdcan1.Init.NominalTimeSeg1 = 0x1F; /* NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */
  hfdcan1.Init.NominalTimeSeg2 = 0x8;
  hfdcan1.Init.DataPrescaler = 0x1;
  hfdcan1.Init.DataSyncJumpWidth = 0x8;
  hfdcan1.Init.DataTimeSeg1 = 0x1F; /* DataTimeSeg1 = Propagation_segment + Phase_segment_1 */
  hfdcan1.Init.DataTimeSeg2 = 0x8;
  hfdcan1.Init.MessageRAMOffset = 0;
  hfdcan1.Init.StdFiltersNbr = 1;
  hfdcan1.Init.ExtFiltersNbr = 1;
  hfdcan1.Init.RxFifo0ElmtsNbr = 1;
  hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
  hfdcan1.Init.RxFifo1ElmtsNbr = 2;
  hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
  hfdcan1.Init.RxBuffersNbr = 1;
  hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
  hfdcan1.Init.TxEventsNbr = 2;
  hfdcan1.Init.TxBuffersNbr = 1;
  hfdcan1.Init.TxFifoQueueElmtsNbr = 2;
  hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
  hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
  HAL_FDCAN_Init(&hfdcan1);
  }

static void CAN_RxStdFilter_Init(){
  sFilterConfig.IdType = FDCAN_STANDARD_ID;
  sFilterConfig.FilterIndex = 0;
  sFilterConfig.FilterType = FDCAN_FILTER_DUAL;
  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXBUFFER;
  sFilterConfig.FilterID1 = 0x111;
  sFilterConfig.FilterID2 = 0x555;
  sFilterConfig.RxBufferIndex = 0;
  HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig);

}

static void CAN_RxExtFilter_Init(){
  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;
  HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig);

}

static void CAN_TxFilter_Init(){
  TxHeader.Identifier = 0x111;
  TxHeader.IdType = FDCAN_STANDARD_ID;
  TxHeader.TxFrameType = FDCAN_DATA_FRAME;
  TxHeader.DataLength = FDCAN_DLC_BYTES_8;
  TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
  TxHeader.BitRateSwitch = FDCAN_BRS_ON;
  TxHeader.FDFormat = FDCAN_FD_CAN;
  TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
  TxHeader.MessageMarker = 0x52;
  HAL_FDCAN_AddMessageToTxBuffer(&hfdcan1, &TxHeader, TxData0, FDCAN_TX_BUFFER0);

}

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • I also have included my declaration of TxData3 as well, for clarification: uint8_t TxData3[] = {0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89}; – Kyle Muehlegg Sep 20 '22 at 16:13
  • Does the Canalyzer passively listen to the bus or does it participate with ACK? Are you getting any error frames? What does the Rx signal from your CAN Transceiver look like when the Canalyzer is sending? Have you terminated the bus with 2 x 120ohm? – Lundin Sep 22 '22 at 08:14
  • Also the first thing to do is to disable all message filters and then check if everything suddenly stops working. Message filters are usually more trouble than they are worth & it's an obsolete technology - modern CAN controllers use mailbox slots instead. – Lundin Sep 22 '22 at 08:20
  • Hello, thank you for the reply! Currently, the CANalyzer is passively listening and sending data periodically to address 0x123 (every 2s). I do not witness any error frames currently. The Rx signal I will have to get tomorrow when I have access to my oscilloscope again. I have it terminated with a single 120 ohm resistor at the moment. Also, is there an easy way to turn off the filters? Can I just call CAN_RxStdFilter_Init. CAN_RxExtFilter_Init and CAN_TxFilter_Init? Or is there a specific setting that has to be added? – Kyle Muehlegg Sep 22 '22 at 13:51

1 Answers1

0

I have no clue about how that HAL you use handles it, but, there is an AppNote for STM32 FDCAN [https://www.st.com/resource/en/application_note/an5348-fdcan-peripheral-on-stm32-devices-stmicroelectronics.pdf], and on page 14 table 5, it has 4 example filters.

The "Second" filter has SFT = "01 - DUAL" and ID1 and ID2 each contain a CAN-ID, which are filtered for 2 messages, and they are stored then to Rx FIFO1 (SFEC = "010 - Store in FIFO1").

The "Third" filter has SFT being ignored ("xx - Don't care"), because SFEC = "111 - Store in Rx Buffer"), where in ID1 the CAN-ID is configured, and ID2 is used to set the BufferId to store that message to.

But in both of these filters, I think ID1 should contain 0x123, since this is the message, you want to receive from your CANalyzer.

static void CAN_RxStdFilter_Init(){
    sFilterConfig.IdType = FDCAN_STANDARD_ID;
    sFilterConfig.FilterIndex = 0;
    sFilterConfig.FilterType = FDCAN_FILTER_DUAL; // <- AppNote SFT field - how does the HAL handle it?
    sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXBUFFER; // <- AppNote SFEC field 
    sFilterConfig.FilterID1 = 0x111; // <-- 0x123 ??
    sFilterConfig.FilterID2 = 0x555; // <-- 0 ( == RxBufferIndex, when filter to buffer)?
    sFilterConfig.RxBufferIndex = 0;
    HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig);
}

Not sure, how the HAL handles the FilterType and FilterConfig, there might be a documentation?

kesselhaus
  • 1,241
  • 8
  • 9
  • Hello, thank you for the reply! So based on my understanding of your reply, the Filter ID to MATCH the messages you receive? In other words, if I want to receive more than two message IDs, I have to change the filter? Is there a way to have the filters accept a range of IDs instead? – Kyle Muehlegg Sep 26 '22 at 15:40