cancel
Showing results for 
Search instead for 
Did you mean: 

My STM32F446RE CAN controller declares a message on the bus (transmits SOF), but then never transmits anything else in the frame (bus just stays idle). Why is this?

juliancarneiro
Associate

I have implemented a CAN controller on the STM32F4 where it successfully transmits a SOF bit, but then the bus stays idle for the rest of the message. The values loaded into the registers are all correct and verified that they have been successfully copied into the registers, but they never get transmitted.

The CAN and associated GPIO init is as follows:

  //can init
  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 16;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan1.Init.TimeSeg1 = CAN_BS1_1TQ;
  hcan1.Init.TimeSeg2 = CAN_BS2_1TQ;
  hcan1.Init.TimeTriggeredMode = DISABLE;
  hcan1.Init.AutoBusOff = DISABLE;
  hcan1.Init.AutoWakeUp = DISABLE;
  hcan1.Init.AutoRetransmission = DISABLE;
  hcan1.Init.ReceiveFifoLocked = DISABLE;
  hcan1.Init.TransmitFifoPriority = DISABLE;
  if(HAL_CAN_Init(&hcan1) != HAL_OK)
  {
      _Error_Handler(__FILE__, __LINE__);
  }
 
  //...
 
  //gpio init for can1
  GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

I then generate 2 "modules" which are just generic arbitrary CAN message structures

  CAN_TxHeaderTypeDef module;
  module.StdId = 0b11001001000; //arbitrary id, just used to verify message correctness
  module.ExtId = 0; //std message anyways, unimportant field
  module.IDE = CAN_ID_STD; //message id type
  module.DLC = 8; //sending 8 bytes of data in this frame
  module.RTR = CAN_RTR_DATA; //data frame
  module.TransmitGlobalTime = DISABLE;
 
  CAN_TxHeaderTypeDef module2;
  module2.StdId = 0b00110110111;
  module2.ExtId = 0;
  module2.IDE = CAN_ID_STD;
  module2.DLC = 8;
  module2.RTR = CAN_RTR_DATA;
  module2.TransmitGlobalTime = DISABLE;

Then I fill two buffers with numbers 0-7 (buffer1) and 8-15 (buffer2)

I then call HAL_CAN_Start(&hcan1) to start the CAN controller. My while loop is as follows:

while (1)
  {
	  HAL_CAN_AddTxMessage(&hcan1, &module, buffer1, &txMailbox);
	  while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) == 0U);
	  HAL_Delay(500);
	  HAL_CAN_AddTxMessage(&hcan1, &module2, buffer2, &txMailbox);
	  while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) == 0U);
	  HAL_Delay(500);
  }

HAL_CAN_AddTxMessage(...) fills a free mailbox with all the message information and sets the hardware bit to transmit. The output is being monitored and as soon as this bit is set is cleared by hardware (as it should) and the SOF is transmitted alone with no data. The blocking while is to wait for a free mailbox at which point it tries to send another message.

I can verify that the values I fill out in the structs and buffers are being properly copied into the registers, and the transmission clearly begins because the SOF bit is transmitted on the bus, but I can't figure out why the data is not being transmitted as well.

Can anyone see what's wrong with this? I believe it is an issue with my hardware initialization on the controller but that's only because I don't see what could be wrong with the software. Please tell me if this is wrong though!! Thank you very much.

0 REPLIES 0