2024-04-09 11:45 PM - last edited on 2024-04-10 12:54 AM by SofLit
Hi amazing community.
I am working with stm32f429 and cube ide.
This is my configuration for the project
/**
* @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 */
}
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
Solved! Go to Solution.
2024-04-13 10:20 AM
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.
2024-04-10 12:19 AM - edited 2024-04-10 01:07 AM
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..?
2024-04-10 10:33 AM
You haven't shown if you've set your filters using HAL_CAN_ConfigFilter and also calling HAL_CAN_Start and HAL_CAN_ActivateNotification?
2024-04-10 11:42 PM
/**
* @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;
}
2024-04-10 11:54 PM
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
2024-04-11 03:14 AM - edited 2024-04-11 03:19 AM
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?
2024-04-12 05:50 AM
Hi SofLit .. I checked again the cube configuration ..
and numbers are ok for 125 kbit/s
/**
* @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
2024-04-12 09:10 AM - edited 2024-04-12 09:10 AM
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.
2024-04-12 10:24 AM - edited 2024-04-12 01:21 PM
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.
2024-04-13 01:30 AM
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; }