cancel
Showing results for 
Search instead for 
Did you mean: 

Canbus callback not working on stm32f429

SGasp.1
Senior

Hi amazing community. 

 

I am working with stm32f429 and cube ide. 

This is my configuration for the project 

 

SGasp1_0-1712731213125.pngSGasp1_1-1712731235661.png

 

 

 

/**
  * @brief CAN1 Initialization Function
  *  None
  * @retval None
  */
static void MX_CAN1_Init(void)
{

  /* USER CODE BEGIN CAN1_Init 0 */

  /* USER CODE END CAN1_Init 0 */

  /* USER CODE BEGIN CAN1_Init 1 */

  /* USER CODE END CAN1_Init 1 */
  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 18;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan1.Init.TimeSeg1 = CAN_BS1_13TQ;
  hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
  hcan1.Init.TimeTriggeredMode = DISABLE;
  hcan1.Init.AutoBusOff = DISABLE;
  hcan1.Init.AutoWakeUp = DISABLE;
  hcan1.Init.AutoRetransmission = ENABLE;
  hcan1.Init.ReceiveFifoLocked = DISABLE;
  hcan1.Init.TransmitFifoPriority = ENABLE;
  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN1_Init 2 */

  /* USER CODE END CAN1_Init 2 */

}

 

 

 

SGasp1_2-1712731325207.png

With the configuration above i am not able to enter inside the following callback funxtion sending messages wit canbus 

 

 

 

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    CAN_RxHeaderTypeDef header;
    uint8_t data[8];
    uint32_t cmd_id;

    if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &header, data) == HAL_OK)
    {
    	if ((can_dev.rx_queue_in+1)%CAN_RX_QUEUE != can_dev.rx_queue_out && header.IDE == CAN_ID_EXT)
    	{
    		// filtro messaggi destinati al nodo
    		cmd_id = header.ExtId;

    		if (cmd_id == can_dev.cfg_id || (can_dev.base != 0 &&
    				(
    						cmd_id == can_dev.base + can_dev.rec_offset*MSG_CFG_STATUS ||
							cmd_id == can_dev.base + can_dev.rec_offset*MSG_OUT_ENABLE ||
							cmd_id == can_dev.base + can_dev.rec_offset*MSG_INP_ENABLE ||
							cmd_id == can_dev.base + can_dev.rec_offset*MSG_HW_VER    ||
							cmd_id == can_dev.base + can_dev.rec_offset*MSG_FW_VER    ||
							cmd_id == can_dev.base + can_dev.rec_offset*MSG_OUT_FREE

    				))) {
    			can_dev.rx++;

    			memcpy(&can_dev.rx_msg_queue[can_dev.rx_queue_in].header, &header, sizeof(CAN_RxHeaderTypeDef));
    			memcpy(can_dev.rx_msg_queue[can_dev.rx_queue_in].data, data, sizeof(data));
    			can_dev.rx_queue_in = (can_dev.rx_queue_in + 1) % CAN_RX_QUEUE;
    		}
    	}

    	can_dev.error_glb = 0;
    	can_dev.tot_rx++;
    }
}

 

 

 

Can you please tell me if you see mistakes in the configuration or something else ? 

 

Thanks a lot

1 ACCEPTED SOLUTION

Accepted Solutions

Double check NVIC settings, Vector Table entries, and linkage, the IRQHandler's themselves and that they call back into the HAL subsystem with the correct instance, that in turn calls your call back.

 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

11 REPLIES 11
SofLit
ST Employee

Hello, 

1- From the screenshot it seems you’re using an old version of CubeMx tool. Could you please tell which version you have?

2- Where is the CAN filters config?

3- I don’t see RX fifo 0 notification interrupt config in the code you shared.

4- Which board are you using? Custom board? How about your hardware? Transceiver? Bus config etc..?

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.
Karl Yamashita
Lead II

You haven't shown if you've set your filters using HAL_CAN_ConfigFilter and also calling  HAL_CAN_Start and HAL_CAN_ActivateNotification?

 

If you find my answers useful, click the accept button so that way others can see the solution.

Hi @Karl Yamashita 

 

/**
 * @brief Configure CAN message filter list.
 *
 * This function configures a CAN message filter list based on the provided parameters.
 *
 * @param filter_id_0 The ID for the first filter.
 * @param filter_id_1 The ID for the second filter.
 * @param flt_num The filter number to be configured.
 * @param rtr Flag indicating whether Remote Transmission Request (RTR) is enabled (1) or not (0).
 * @return HAL status indicating success or failure of the filter configuration.
 */
static HAL_StatusTypeDef CnMsgFilterList(uint32_t filter_id_0, uint32_t filter_id_1, uint16_t flt_num, uint8_t rtr)
{
	CAN_FilterTypeDef can_filter = {0};
	uint32_t option = 0x04; // IDE pag 666 "Filter bank scale configuration - register organization"

	if (rtr) {
		option |= 0x02; // RTR pag 666 "Filter bank scale configuration - register organization"
	}

	can_filter.FilterIdHigh = filter_id_0 >> 13;
	can_filter.FilterIdLow = ((filter_id_0<<3) & 0x0FFFF) | option; // EXID
	can_filter.FilterMaskIdHigh = filter_id_1 >> 13;
	if (filter_id_0 == filter_id_1)
	{
		option |= 0x02;
	}
	can_filter.FilterMaskIdLow = ((filter_id_1<<3) & 0x0FFFF) | option; // EXID
	can_filter.FilterMode = CAN_FILTERMODE_IDLIST;
	can_filter.FilterScale = CAN_FILTERSCALE_32BIT;
	can_filter.FilterBank = flt_num;
	can_filter.SlaveStartFilterBank = flt_num;
	can_filter.FilterActivation = ENABLE;
	can_filter.FilterFIFOAssignment = CAN_RX_FIFO0;

	return HAL_CAN_ConfigFilter(&hcan1, &can_filter);
}
/**
 * @brief Initialize CAN peripheral and configure message filters.
 *
 * This function initializes the CAN peripheral and configures message filters for receiving messages.
 * It also sets up various parameters such as base addresses, offsets, and message filters.
 *
 * @return void
 */
static void CanInit(void)
{
	uint16_t val_h, val_l;
	CAN_FilterTypeDef can_filter;
	HAL_StatusTypeDef res;

	// inizializzazione fifo per la ricezione dei messaggio con i vari ID
	can_dev.cfg_id = CAN_BUS_CFG_ID;
	can_dev.base = 0;
	can_dev.base_send = 0;
	// default offset
	can_dev.send_offset = 1;
	can_dev.rec_offset = 1;

	/*retrieve from memory all id needed for canbus*/

	// msg receive filters
	res = CnMsgFilterList(can_dev.cfg_id, can_dev.cfg_id, 0, 0);

	if (res == HAL_OK)
	{
		res = CnMsgFilterList(can_dev.cfg_id, can_dev.cfg_id, 11, 1); // per rtr
	}

	if (res != HAL_OK)
	{
		// impostazione filtro piglia tutto
		can_filter.FilterIdHigh = CAN_BUS_CFG_ID>>13;  // vedi pg 827 manuale uC
		can_filter.FilterIdLow = (CAN_BUS_CFG_ID<<3) & 0x0000FFFF;
		can_filter.FilterMaskIdHigh = 0;//0xFFFF;
		can_filter.FilterMaskIdLow = 0;//0xFFF8;
		can_filter.FilterMode = CAN_FILTERMODE_IDMASK;
		can_filter.FilterScale = CAN_FILTERSCALE_32BIT;
		can_filter.FilterBank = 0;
		can_filter.SlaveStartFilterBank = 0;
		can_filter.FilterActivation = ENABLE;
		can_filter.FilterFIFOAssignment = CAN_RX_FIFO0;
		HAL_CAN_ConfigFilter(&hcan1, &can_filter);
	}

	if (HAL_CAN_Start(&hcan1) != HAL_OK) {
		printf_err("HAL_CAN_Start: FAIL\r\n");
	}

	if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_TX_MAILBOX_EMPTY | CAN_IT_RX_FIFO0_FULL | CAN_IT_ERROR | CAN_IT_BUSOFF | CAN_IT_ERROR_PASSIVE | CAN_IT_ERROR_WARNING | CAN_IT_LAST_ERROR_CODE) != HAL_OK) {
		printf_err("HAL_CAN_ActivateNotification: FAIL\r\n");
	}

    // reset errore in CAN
    can_dev.error_glb = 0;

    // abilita l'invio
    can_dev.send_en = 1;
}

 

Hi @SofLit 

1 -Cube mx version is 6.9.2

2-  

/**
 * @brief Configure CAN message filter list.
 *
 * This function configures a CAN message filter list based on the provided parameters.
 *
 * @PAram filter_id_0 The ID for the first filter.
 * @PAram filter_id_1 The ID for the second filter.
 * @PAram flt_num The filter number to be configured.
 * @PAram rtr Flag indicating whether Remote Transmission Request (RTR) is enabled (1) or not (0).
 * @return HAL status indicating success or failure of the filter configuration.
 */
static HAL_StatusTypeDef CnMsgFilterList(uint32_t filter_id_0, uint32_t filter_id_1, uint16_t flt_num, uint8_t rtr)
{
	CAN_FilterTypeDef can_filter = {0};
	uint32_t option = 0x04; // IDE pag 666 "Filter bank scale configuration - register organization"

	if (rtr) {
		option |= 0x02; // RTR pag 666 "Filter bank scale configuration - register organization"
	}

	can_filter.FilterIdHigh = filter_id_0 >> 13;
	can_filter.FilterIdLow = ((filter_id_0<<3) & 0x0FFFF) | option; // EXID
	can_filter.FilterMaskIdHigh = filter_id_1 >> 13;
	if (filter_id_0 == filter_id_1)
	{
		option |= 0x02;
	}
	can_filter.FilterMaskIdLow = ((filter_id_1<<3) & 0x0FFFF) | option; // EXID
	can_filter.FilterMode = CAN_FILTERMODE_IDLIST;
	can_filter.FilterScale = CAN_FILTERSCALE_32BIT;
	can_filter.FilterBank = flt_num;
	can_filter.SlaveStartFilterBank = flt_num;
	can_filter.FilterActivation = ENABLE;
	can_filter.FilterFIFOAssignment = CAN_RX_FIFO0;

	return HAL_CAN_ConfigFilter(&hcan1, &can_filter);
}

3 - where should it be ? 

4- it is a custom board with a nxp transceiver

 

My answers in blue:

1 -Cube mx version is 6.9.2: an old version but it's OK

2- This code doesn't help as it's your implementation and needs to look at all shifts and masks (tough task)
Needs to start by a passing all messages filter to isolate the issue: is it a filter config issue or something else?

 

/**
 * @brief Configure CAN message filter list.
 *
 * This function configures a CAN message filter list based on the provided parameters.
 *
 *  filter_id_0 The ID for the first filter.
 *  filter_id_1 The ID for the second filter.
 *  flt_num The filter number to be configured.
 *  rtr Flag indicating whether Remote Transmission Request (RTR) is enabled (1) or not (0).
 * @return HAL status indicating success or failure of the filter configuration.
 */
static HAL_StatusTypeDef CnMsgFilterList(uint32_t filter_id_0, uint32_t filter_id_1, uint16_t flt_num, uint8_t rtr)
{
	CAN_FilterTypeDef can_filter = {0};
	uint32_t option = 0x04; // IDE pag 666 "Filter bank scale configuration - register organization"

	if (rtr) {
		option |= 0x02; // RTR pag 666 "Filter bank scale configuration - register organization"
	}

	can_filter.FilterIdHigh = filter_id_0 >> 13;
	can_filter.FilterIdLow = ((filter_id_0<<3) & 0x0FFFF) | option; // EXID
	can_filter.FilterMaskIdHigh = filter_id_1 >> 13;
	if (filter_id_0 == filter_id_1)
	{
		option |= 0x02;
	}
	can_filter.FilterMaskIdLow = ((filter_id_1<<3) & 0x0FFFF) | option; // EXID
	can_filter.FilterMode = CAN_FILTERMODE_IDLIST;
	can_filter.FilterScale = CAN_FILTERSCALE_32BIT;
	can_filter.FilterBank = flt_num;
	can_filter.SlaveStartFilterBank = flt_num;
	can_filter.FilterActivation = ENABLE;
	can_filter.FilterFIFOAssignment = CAN_RX_FIFO0;

	return HAL_CAN_ConfigFilter(&hcan1, &can_filter);
}

 

3 - where should it be ? Need to call HAL_CAN_ActivateNotification() : from one of the examples provided in the Cube package:

 

  /*##-4- Activate CAN RX notification #######################################*/
  if (HAL_CAN_ActivateNotification(&CanHandle, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
  {
    /* Notification Error */
    Error_Handler();
  }

 

4- it is a custom board with a nxp transceiver. Which tranceiver? but Need to check points 1, 2 and 3 before.

Did you succeed the transmission?

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 SofLit .. I checked again the cube configuration ..

and numbers are ok for 125 kbit/s

SGasp1_0-1712925887464.png

 

 

 

 

/**
  * @brief CAN1 Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_CAN1_Init(void)
{

  /* USER CODE BEGIN CAN1_Init 0 */

  /* USER CODE END CAN1_Init 0 */

  /* USER CODE BEGIN CAN1_Init 1 */

  /* USER CODE END CAN1_Init 1 */
  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 21;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan1.Init.TimeSeg1 = CAN_BS1_10TQ;
  hcan1.Init.TimeSeg2 = CAN_BS2_5TQ;
  hcan1.Init.TimeTriggeredMode = DISABLE;
  hcan1.Init.AutoBusOff = DISABLE;
  hcan1.Init.AutoWakeUp = DISABLE;
  hcan1.Init.AutoRetransmission = ENABLE;
  hcan1.Init.ReceiveFifoLocked = DISABLE;
  hcan1.Init.TransmitFifoPriority = ENABLE;
  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }

 

 

ma still not enter inside here  transmitting at 125 kbitS

 

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    CAN_RxHeaderTypeDef header;
    uint8_t data[8];
    uint32_t cmd_id;

    if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &header, data) == HAL_OK)
    {
    	if ((can_dev.rx_queue_in+1)%CAN_RX_QUEUE != can_dev.rx_queue_out && header.IDE == CAN_ID_EXT)
    	{
    		// filtro messaggi destinati al nodo
    		cmd_id = header.ExtId;

    		if (cmd_id == can_dev.cfg_id || (can_dev.base != 0 &&
    				(
    						cmd_id == can_dev.base + can_dev.rec_offset*MSG_CFG_STATUS ||
							cmd_id == can_dev.base + can_dev.rec_offset*MSG_OUT_ENABLE ||
							cmd_id == can_dev.base + can_dev.rec_offset*MSG_INP_ENABLE ||
							cmd_id == can_dev.base + can_dev.rec_offset*MSG_HW_VER    ||
							cmd_id == can_dev.base + can_dev.rec_offset*MSG_FW_VER    ||
							cmd_id == can_dev.base + can_dev.rec_offset*MSG_OUT_FREE

    				))) {
    			can_dev.rx++;

    			memcpy(&can_dev.rx_msg_queue[can_dev.rx_queue_in].header, &header, sizeof(CAN_RxHeaderTypeDef));
    			memcpy(can_dev.rx_msg_queue[can_dev.rx_queue_in].data, data, sizeof(data));
    			can_dev.rx_queue_in = (can_dev.rx_queue_in + 1) % CAN_RX_QUEUE;
    		}
    	}

    	can_dev.error_glb = 0;
    	can_dev.tot_rx++;
    }
}

 

 

and this is my caninit function  

 

 

static void CanInit(void)
{
	uint16_t val_h, val_l;
	CAN_FilterTypeDef can_filter;
	HAL_StatusTypeDef res;

	// inizializzazione fifo per la ricezione dei messaggio con i vari ID
	can_dev.cfg_id = CAN_BUS_CFG_ID;
	can_dev.base = 0x9000;
	can_dev.base_send = 0x11000;
	can_dev.send_offset = 0x50;
	can_dev.rec_offset = 0x50;

	/*retrieve from memory all id needed for canbus*/

	// msg receive filters
	res = CnMsgFilterList(can_dev.cfg_id, can_dev.cfg_id, 0, 0);

	if (res == HAL_OK)
	{
		res = CnMsgFilterList(can_dev.cfg_id, can_dev.cfg_id, 11, 1); // per rtr
	}

	if (res != HAL_OK)
	{
		// impostazione filtro piglia tutto
		can_filter.FilterIdHigh = CAN_BUS_CFG_ID>>13;  // vedi pg 827 manuale uC
		can_filter.FilterIdLow = (CAN_BUS_CFG_ID<<3) & 0x0000FFFF;
		can_filter.FilterMaskIdHigh = 0;//0xFFFF;
		can_filter.FilterMaskIdLow = 0;//0xFFF8;
		can_filter.FilterMode = CAN_FILTERMODE_IDMASK;
		can_filter.FilterScale = CAN_FILTERSCALE_32BIT;
		can_filter.FilterBank = 0;
		can_filter.SlaveStartFilterBank = 0;
		can_filter.FilterActivation = ENABLE;
		can_filter.FilterFIFOAssignment = CAN_RX_FIFO0;
		HAL_CAN_ConfigFilter(&hcan1, &can_filter);
	}

	if (HAL_CAN_Start(&hcan1) != HAL_OK)
	{
		printf_err("HAL_CAN_Start: FAIL\r\n");
	}

	if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_TX_MAILBOX_EMPTY | CAN_IT_RX_FIFO0_FULL | CAN_IT_ERROR | CAN_IT_BUSOFF | CAN_IT_ERROR_PASSIVE | CAN_IT_ERROR_WARNING | CAN_IT_LAST_ERROR_CODE) != HAL_OK)
	{
		printf_err("HAL_CAN_ActivateNotification: FAIL\r\n");
	}

    // reset errore in CAN
    can_dev.error_glb = 0;

    // abilita l'invio
    can_dev.send_en = 1;
}

 

 

As you can see at row 45 it is mentioned  

CAN_IT_RX_FIFO0_MSG_PENDING

 

Any ideas ?

 

Thanks a lot

As I said before, very tough for me to look at your filter implementation. You need to start with a very basic filter config: Passing all messages with Mask and ID = 0. This is just to isolate an issue with your HW or CAN config. Then when all is fine you need to check your filter implementation.

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.

Hello,

Just noticed these two lines:

 

	can_filter.FilterBank = flt_num;
	can_filter.SlaveStartFilterBank = flt_num;

 

Why are you setting FilterBank = SlaveStartFilterBank?? normally SlaveStartFilterBank has a fixed value.

and:

		can_filter.FilterBank = 0;
		can_filter.SlaveStartFilterBank = 0;

If SlaveStartFilterBank  = 0 (CAN2SB = 0) -> all filters are allocated to CAN2.

Please refer to this thread which explains the relationship between FilterBank  and SlaveStartFilterBank.

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 @SofLit .. thanks for your commnet. 

I was expecting to enter inside the callback function reported here reported below without caring what is set in the canbus filter you mentioned.. 

Am i wrong ?

 

Thanks

 

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    CAN_RxHeaderTypeDef header;
    uint8_t data[8];
    uint32_t cmd_id;

    if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &header, data) == HAL_OK)
    {
    	if ((can_dev.rx_queue_in+1)%CAN_RX_QUEUE != can_dev.rx_queue_out && header.IDE == CAN_ID_EXT)
    	{
    		// filtro messaggi destinati al nodo
    		cmd_id = header.ExtId;

    		if (cmd_id == can_dev.cfg_id || (can_dev.base != 0 &&
    				(
    						cmd_id == can_dev.base + can_dev.rec_offset*MSG_CFG_STATUS ||
							cmd_id == can_dev.base + can_dev.rec_offset*MSG_OUT_ENABLE ||
							cmd_id == can_dev.base + can_dev.rec_offset*MSG_INP_ENABLE ||
							cmd_id == can_dev.base + can_dev.rec_offset*MSG_HW_VER    ||
							cmd_id == can_dev.base + can_dev.rec_offset*MSG_FW_VER    ||
							cmd_id == can_dev.base + can_dev.rec_offset*MSG_OUT_FREE

    				))) {
    			can_dev.rx++;

    			memcpy(&can_dev.rx_msg_queue[can_dev.rx_queue_in].header, &header, sizeof(CAN_RxHeaderTypeDef));
    			memcpy(can_dev.rx_msg_queue[can_dev.rx_queue_in].data, data, sizeof(data));
    			can_dev.rx_queue_in = (can_dev.rx_queue_in + 1) % CAN_RX_QUEUE;
    		}