cancel
Showing results for 
Search instead for 
Did you mean: 

(FD)CAN module resends with ACK visible on bus

finally
Associate II

Hello everybody, 

I am new here so please let me know, if there is important information missing. Thank you already for you time! 

I set up a STM32U575I-EV board for communication with CAN. The STM Board, a PCAN-USB dongle and an Oszilloskope are connected to the bus. The Bus is terminated correctly with two 120 Ohm resistors. I use the HAL libraries to interface with the FDCAN peripherie. The jumpers from the eval board are set to connect PB9 and PB8 with the CAN transceiver and to disconnect PB8 from the USB-C PD-interface. 

To test the setup I send dummy frames (ID: 0x000, DLC: 1, Data: 0x00). The frame is visible on the Bus and also the ACK from PCAN is visibile. PCAN USB has a 200mV higher voltage on CAN High 0 level. 

Here is the dummy frame on the Oszi: 

Oszi_ACK.png

As you see on the the screenshot, the ACK is there and even though I put only one message in the Tx-Buffer of the FDCAN, it retransmitted. 

Here is my code: 

main.c

int main(void)
{
  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the System Power */
  SystemPower_Config();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_FDCAN1_Init();
  MX_ICACHE_Init();
  MX_RTC_Init();
  MX_TAMP_RTC_Init();
  MX_TSC_Init();
  /* USER CODE BEGIN 2 */
  //
  HAL_FDCAN_Start(&hfdcan1);
  while (hfdcan1.State != HAL_FDCAN_STATE_BUSY); /* Wait until FDCAN1 is ready */

  while(1) {
	  uint16_t can_id = 0x000; // Example CAN ID for motor control
	  uint8_t data[1] = {0x00}; // Example command data
	  send_CAN_frame(can_id, data, sizeof(data));
	  FDCAN_ProtocolStatusTypeDef status;
	  HAL_FDCAN_GetProtocolStatus(&hfdcan1, &status);
	  FDCAN_ProtocolStatusTypeDef status2 = status; // so status is not optimized out

	  HAL_Delay(1000);
  }
}

send_CAN_frame(...) : 

void send_CAN_frame(uint16_t id, uint8_t *data, uint8_t length)
{
	// Create a CAN message
	FDCAN_TxHeaderTypeDef TxHeader;

	TxHeader.Identifier = id;                 // CAN ID
	TxHeader.IdType = FDCAN_STANDARD_ID;         // 11 Bit ID
	TxHeader.TxFrameType = FDCAN_DATA_FRAME;     // dataframe
	if (length > 8)
		length = 8; // Maximal 8 Bytes für Classic CAN
	TxHeader.DataLength = length;     // 8 Bytes
	TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
	TxHeader.BitRateSwitch = FDCAN_BRS_OFF;      // only relevant for FDCAN
	TxHeader.FDFormat = FDCAN_CLASSIC_CAN;       // Classic CAN
	TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
	TxHeader.MessageMarker = 0;

	HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, data) 
	FDCAN_ProtocolStatusTypeDef status;
	HAL_FDCAN_GetProtocolStatus(&hfdcan1, &status);
	printf("%lu\n", status.LastErrorCode);
	return;
}

MX_FDCAN1_Init(...) : 

static void MX_FDCAN1_Init(void)
{
  hfdcan1.Instance = FDCAN1;
  hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1;
  hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
  hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
  hfdcan1.Init.AutoRetransmission = DISABLE;
  hfdcan1.Init.TransmitPause = DISABLE;
  hfdcan1.Init.ProtocolException = DISABLE;
  hfdcan1.Init.NominalPrescaler = 4;
  hfdcan1.Init.NominalSyncJumpWidth = 1;
  hfdcan1.Init.NominalTimeSeg1 = 255;
  hfdcan1.Init.NominalTimeSeg2 = 64;
  hfdcan1.Init.DataPrescaler = 1;
  hfdcan1.Init.DataSyncJumpWidth = 1;
  hfdcan1.Init.DataTimeSeg1 = 1;
  hfdcan1.Init.DataTimeSeg2 = 1;
  hfdcan1.Init.StdFiltersNbr = 0;
  hfdcan1.Init.ExtFiltersNbr = 0;
  hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
  if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
  {
    Error_Handler();
  }

}


"status" from main() gives me a LastErrorCode of Stuff error, Form error and Acknowledge error (0b0..0111). 

What I have tried: 
- Run release build instead of Debug -> same result

- run FDCAN in external loopback mode -> same result (?!). So the CAN module does resend the frames even though it should ignore ACK errors ( reference manual page 3034) 
- When I poll for Rx frames and send frames via PCAN I receive every ~10th frame 

Anybody has an idea? 

1 ACCEPTED SOLUTION

Accepted Solutions
finally
Associate II

I kind of found a solution. I now use the configuration from the Example "FDCAN_Loopback" in CubeMX. You can find it by filtering examples for the board "STM32U575I-EV" and look through the listed examples. 

I dont find any differences in the clock or FDCAN configuration between the one in the example and mine. Maybe some of the other peripherals I had configured (and do not need in the first place) interefered. But I dont want to invest time to check that out. 


View solution in original post

4 REPLIES 4
finally
Associate II

I forgot to add the clock configuration:
FDCAN gets a 160MHz clock from PLL1Q

finally
Associate II

I kind of found a solution. I now use the configuration from the Example "FDCAN_Loopback" in CubeMX. You can find it by filtering examples for the board "STM32U575I-EV" and look through the listed examples. 

I dont find any differences in the clock or FDCAN configuration between the one in the example and mine. Maybe some of the other peripherals I had configured (and do not need in the first place) interefered. But I dont want to invest time to check that out. 


Hello @finally and welcome to the ST community,

I don't know if U2 is present in your board. In thar case you need to remove the jumpers JP14 and JP15.

 

screenshot.png

Otherwise that's weird if the loopback mode has issues ..

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.

Hi @mƎALLEm , 
these jumpers were removed.