cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_CAN_Init() returns HAL_TIMEOUT on STM32F042

voyvoda .
Senior

Hello,

I generated a fresh CubeMX project which has can bus. HAL_CAN_Init() returns HAL_TIMEOUT.

What could be the possible solution ?

/* CAN init function */

static void MX_CAN_Init(void)

{

 CAN_FilterConfTypeDef sFilterConfig;

 static CanTxMsgTypeDef    TxMessage;

 static CanRxMsgTypeDef    RxMessage;

 /*##-1- Configure the CAN peripheral #######################################*/

 hcan.Instance = CAN;

 hcan.pTxMsg = &TxMessage;

 hcan.pRxMsg = &RxMessage;

 hcan.Init.TTCM = DISABLE;

 hcan.Init.ABOM = DISABLE;

 hcan.Init.AWUM = DISABLE;

 hcan.Init.NART = DISABLE;

 hcan.Init.RFLM = DISABLE;

 hcan.Init.TXFP = DISABLE;

 hcan.Init.Mode = CAN_MODE_NORMAL;

 hcan.Init.SJW = CAN_SJW_1TQ;

 hcan.Init.BS1 = CAN_BS1_4TQ;

 hcan.Init.BS2 = CAN_BS2_3TQ;

 hcan.Init.Prescaler = 48;

 if (HAL_CAN_Init(&hcan) != HAL_OK)

 {

  /* Initialization Error */

  Error_Handler();

 }

 /*##-2- Configure the CAN Filter ###########################################*/

 sFilterConfig.FilterNumber = 0;

 sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;

 sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;

 sFilterConfig.FilterIdHigh = 0x0000;

 sFilterConfig.FilterIdLow = 0x0000;

 sFilterConfig.FilterMaskIdHigh = 0x0000;

 sFilterConfig.FilterMaskIdLow = 0x0000;

 sFilterConfig.FilterFIFOAssignment = 0;

 sFilterConfig.FilterActivation = ENABLE;

 sFilterConfig.BankNumber = 14;

 if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)

 {

  /* Filter configuration Error */

  Error_Handler();

 }

 /*##-3- Configure Transmission process #####################################*/

 hcan.pTxMsg->StdId = 0x321;

 hcan.pTxMsg->ExtId = 0x01;

 hcan.pTxMsg->RTR = CAN_RTR_DATA;

 hcan.pTxMsg->IDE = CAN_ID_STD;

 hcan.pTxMsg->DLC = 2;

  

}

11 REPLIES 11
voyvoda .
Senior

I pulled high to the CAN RX pin and HAL_CAN_Init() returns HAL_OK

Now, HAL_CAN_Transmit returns HAL_TIMEOUT

T J
Lead

if you needed to pull the Rx pin high that implies that you have transceiver.

that implies that you have no other device on the TTLCanBus

and that is why your Tx is timing out, because no slave has signaled the message has been received.

if you check the scope, you will see the Tx pin continuously outputting data, waiting for a slave to accept the packet.

voyvoda .
Senior

When I check the canbus by osilascope, I see nothing. There is no data output at the Tx pin. What could be the problem.

T J
Lead

ABOM should be enabled,

where is the code that is failing ?

voyvoda .
Senior

ABOM is enabled. However I see no Tx data at the output.

voyvoda .
Senior

I still get "HAL_CAN_Transmit returns HAL_TIMEOUT"

T J
Lead
I can see the init code, but I cannot see where you are transmitting ?


Here if there is room in the CanTx buffer

if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) // (1) check empty
{
CAN->sTxMailBox[0].TDTR = 0x08; // (2) length
CAN->sTxMailBox[0].TDLR = 0x01020304; // (3) 4bytes
CAN->sTxMailBox[0].TDHR = 0x05060708; // (3) 4bytes
CAN->sTxMailBox[0].TIR =
((uint32_t)MsgID << 21 | CAN_TI0R_TXRQ); // (4) // send it now if the line is idle // must be last
}

Looks like you forgot the very last part.. the sending bit..
voyvoda .
Senior

here you can see my code.

int main(void)

{

 /* USER CODE BEGIN 1 */

 /* USER CODE END 1 */

 /* MCU Configuration----------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

 HAL_Init();

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

 /* Configure the system clock */

 SystemClock_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */

 MX_GPIO_Init();

 MX_USB_DEVICE_Init();

 MX_CAN_Init();

 /* USER CODE BEGIN 2 */

 /* USER CODE END 2 */

 /* Infinite loop */

 /* USER CODE BEGIN WHILE */

 while (1)

 {

 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */

   HAL_CAN_Transmit(&hcan, 10);

   HAL_Delay(100);

   HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);

 }

 /* USER CODE END 3 */

}

T J
Lead
Ok,

When the processor is locked up, you may need to power down to clear a fault.
If ABOM is ENABLED the chip will recover from bus noise.
Do you have transceivers ?
Do you have a save device connected?
You need a slave device to receive the packet.
Do you have a scope, can you see the data leaving the pin ? or pounding the pin ?


I cannot see where you enable the interrupts,
__HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP1); // receive interrupts..
__HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP0);

I gave you code that works, did you try it ?