Skip to main content
Associate
July 9, 2024
Solved

CAN1 loopback does not work on STM32F427

  • July 9, 2024
  • 3 replies
  • 1616 views

Hello everyone,

I have recently been trying to get the CAN1 bus working on the STM32F427. So far, however, it has not worked in either loopback or normal mode. For the normal mode I had a CANCaseXL Analyzer available. The problem, however, is that not even the loopback works. I have attached the main.c file and the ioc project file.

When I call HAL_CAN_AddTxMessage(), I get HAL_OK back, so that seems to work. However, I have set a breakpoint in the CAN interrupt handler (HAL_CAN_IRQHandler() in file stm32f4xx_hal_can.c) and there I see that the TERR0 bit gets set. Accordingly, the transmission process has failed. I have already tried many other possibilities, which unfortunately did not work either.

Maybe someone has an idea. Many thanks in advance!

Louis

Best answer by mƎALLEm

Hello,

At first check at your ioc file, I don't recommend these values for CAN bit timing:

 

hcan1.Init.Prescaler = 16;
hcan1.Init.TimeSeg1 = CAN_BS1_1TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;

 

BS1_1TQ and BS2_2TQ are very low. You need to increase them as much as possible by decreasing the prescaler as much as possible.

I recommend these values for 500kb/s:

SofLit_0-1720537708434.png

Also, we don't recommend HSI as clock source when using CAN in Normal mode. You need to use HSE with an external crystal otherwise you may face communication issues.

SofLit_0-1720537957478.png

 

 

 

3 replies

mƎALLEm
mƎALLEmBest answer
ST Technical Moderator
July 9, 2024

Hello,

At first check at your ioc file, I don't recommend these values for CAN bit timing:

 

hcan1.Init.Prescaler = 16;
hcan1.Init.TimeSeg1 = CAN_BS1_1TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;

 

BS1_1TQ and BS2_2TQ are very low. You need to increase them as much as possible by decreasing the prescaler as much as possible.

I recommend these values for 500kb/s:

SofLit_0-1720537708434.png

Also, we don't recommend HSI as clock source when using CAN in Normal mode. You need to use HSE with an external crystal otherwise you may face communication issues.

SofLit_0-1720537957478.png

 

 

 

To give better visibility on the answered topics, please click "Best answer" on the reply which solved your issue or answered your question.
Karl Yamashita
Principal
July 9, 2024

Segment 1 should be larger than Segment 2. Use this online calculator http://www.bittiming.can-wiki.info/

 

I did some test with your code and found an issue. If you're using polling method then don't use HAL_CAN_ActivateNotification else you'll get stuck in while(HAL_CAN_IsTxMessagePending(&hcan1, TxMailbox));

 

Here is what I did to get either Interrupt or Polling method to work. Interrupt mode blinks the LED fast while polling blinks the LED slowly. I moved your code out of main.c and created separate functions.

 

main.c

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 PollingInit();
 while (1)
 {
	 PollingRoutine();
 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */

 

PollingRoutine.c

/*
 * PollingRoutine.c
 *
 * Created on: Oct 24, 2023
 * Author: karl.yamashita
 *
 *
 * Template for projects.
 *
 */


#include "main.h"


//#define USE_CAN_INTERRUPT


extern CAN_HandleTypeDef hcan1;


CAN_TxHeaderTypeDef TxHeader;
CAN_RxHeaderTypeDef RxHeader;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
bool CAN_MsgRdy = false;


void PollingInit(void)
{
	CAN_FilterInit();
}

void PollingRoutine(void)
{
	CAN_SendTxMessage();
#ifdef USE_CAN_INTERRUPT
	CAN_CheckMsg();
#else
	CAN_ReceiveMessage();
#endif
	HAL_Delay(100);
}

void led1_on(void)
{
	HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_SET);
}

void led1_off(void)
{
	HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_RESET);
}


void CAN_FilterInit(void)
{
	CAN_FilterTypeDef CAN1_Filter;

	CAN1_Filter.FilterBank = 0;
	CAN1_Filter.FilterMode = CAN_FILTERMODE_IDMASK;
	CAN1_Filter.FilterScale = CAN_FILTERSCALE_32BIT;
	CAN1_Filter.FilterIdHigh = 0x0000;
	CAN1_Filter.FilterIdLow = 0x0000;
	CAN1_Filter.FilterMaskIdHigh = 0x0000;
	CAN1_Filter.FilterMaskIdLow = 0x0000;
	CAN1_Filter.FilterFIFOAssignment = CAN_RX_FIFO0;
	CAN1_Filter.FilterActivation = ENABLE;
	CAN1_Filter.SlaveStartFilterBank = 14;

	if (HAL_CAN_ConfigFilter(&hcan1, &CAN1_Filter) != HAL_OK)
	{
	 Error_Handler();
	}

	if (HAL_CAN_Start(&hcan1) != HAL_OK)
	{
	 Error_Handler();
	}
#ifdef USE_CAN_INTERRUPT
	if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_TX_MAILBOX_EMPTY | CAN_IT_ERROR) != HAL_OK)
	{
	 Error_Handler();
	}
#endif
}

void CAN_SendTxMessage(void)
{
	TxHeader.StdId = 0x11;
	TxHeader.RTR = CAN_RTR_DATA;
	TxHeader.IDE = CAN_ID_STD;
	TxHeader.DLC = 2;
	TxHeader.TransmitGlobalTime = DISABLE;
	TxData[0] = 0xCA;
	TxData[1] = 0xFE;

	if (HAL_CAN_AddTxMessage(&hcan1, &TxHeader, TxData, &TxMailbox) != HAL_OK)
	{
	 Error_Handler();
	}
}

#ifdef USE_CAN_INTERRUPT
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
	// currently not used as we use polling for test purposes
	if(hcan == &hcan1)
	{
		if (HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
		{
		 Error_Handler();
		}
		CAN_MsgRdy = true;
	}
}

void CAN_CheckMsg(void)
{
	if(CAN_MsgRdy)
	{
		CAN_MsgRdy = false;
		if(RxHeader.StdId == 0x11)
		{
			if((RxData[0]<<8 | RxData[1]) == 0xCAFE)
			{
				led1_on();
				HAL_Delay(100);
				led1_off();
				HAL_Delay(100);
			}
		}
	}
}

#else // Polling
void CAN_ReceiveMessage(void)
{
	while(HAL_CAN_IsTxMessagePending(&hcan1, TxMailbox));
	while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) != 3);

	HAL_Delay(20);

	if (HAL_CAN_GetRxFifoFillLevel(&hcan1, CAN_RX_FIFO0) != 1)
	{
	 Error_Handler();
	}

	if (HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
	{
	 Error_Handler();
	}

	if(RxHeader.StdId == 0x11)
	{
		if((RxData[0]<<8 | RxData[1]) == 0xCAFE)
		{
			led1_on();
			HAL_Delay(500);
			led1_off();
			HAL_Delay(500);
		}
	}
}
#endif

 

 

 

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
Louis00Author
Associate
July 10, 2024

Thanks to both of you, both answers were very helpful!

With the bit timing provided by @mƎALLEm, the TX no longer failed. With the code from @Karl Yamashita , the reception also worked.