2020-11-23 01:49 AM
I'm currently trying to get a message from another can device and I can't figure out why my callback isn't triggering.
I can transmit a message without any problem however I can't receive any. I am using vector CANalyzer to check my bus.
I was trying to make something that looks like a ping, when i transmit, if the stm32 get the message, it transmit something on the bus. This is just to check my ability to communicate before going further in my development.
If I uncoment the lines in my filter config, I can read message by polling but not by interrupt.
Here is how I configure my CAN :
void CAN_Config(void)
{
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
//sFilterConfig.FilterIdHigh = 0x320 << 5; // Ici, 320 est l'adresse de la carte. Il peux être différent pour chaque carte.
sFilterConfig.FilterIdHigh = 0;
sFilterConfig.FilterIdLow = 0;
//sFilterConfig.FilterMaskIdHigh = 0xFFF << 5; // Le masque peux servir à accepter une plage d'adresse au lieu d'une adresse unique.
sFilterConfig.FilterMaskIdHigh = 0;
sFilterConfig.FilterMaskIdLow = 0;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING); // Active le mode interruption
TxHeader.StdId = 0x030; // Détermine l'adresse du périphérique au quel la trame est destiné.
// Si plusieurs périphériques sur le bus comprennent cette adresse dans leur filtre, ils recevront tous la trame.
TxHeader.ExtId = 0x00; // Adresse étendue, non utilisée dans note cas
TxHeader.RTR = CAN_RTR_DATA; // Précise que la trame contient des données
TxHeader.IDE = CAN_ID_STD; // Précise que la trame est de type Standard
TxHeader.DLC = 2; // Précise le nombre d'octets de données que la trame transporte ( De 0 à 8 )
TxHeader.TransmitGlobalTime = DISABLE;
/*
RxHeader.StdId = 0x030; // Détermine l'adresse du périphérique au quel la trame est destiné.
// Si plusieurs périphériques sur le bus comprennent cette adresse dans leur filtre, ils recevront tous la trame.
RxHeader.ExtId = 0x00; // Adresse étendue, non utilisée dans note cas
RxHeader.RTR = CAN_RTR_DATA; // Précise que la trame contient des données
RxHeader.IDE = CAN_ID_STD; // Précise que la trame est de type Standard
RxHeader.DLC = 2; // Précise le nombre d'octets de données que la trame transporte ( De 0 à 8 )
*/
//TxData[0] = 0x55; // Vous pouvez changer toutes les valeurs de Txdata[0] à Txdata[TxHeader.DLC - 1] (TxHeader.DLC étant défini ci dessus)
HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig); // Configure le filtre comme ci-dessus
HAL_CAN_Start(&hcan1); // Démarre le périphérique CAN
}
How it's initiated :
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 = 20;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_3TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_4TQ;
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();
}
/* USER CODE BEGIN CAN1_Init 2 */
/* USER CODE END CAN1_Init 2 */
}
My callback function that I want to be called whenever I have a message with id 320
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
uint8_t csend[] = {0x22,0x1e,0x13,0x14,0x15,0x16,0x17,0x18}; // Tx Buffer
HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData); //Receive CAN bus message to canRX buffer
CAN_Transmit(0x100,8,csend);
}
```
I guess the link to use the callback is made by this function :
```
HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan, uint32_t ActiveITs)
{
HAL_CAN_StateTypeDef state = hcan->State;
/* Check function parameters */
assert_param(IS_CAN_IT(ActiveITs));
if ((state == HAL_CAN_STATE_READY) ||
(state == HAL_CAN_STATE_LISTENING))
{
/* Enable the selected interrupts */
__HAL_CAN_ENABLE_IT(hcan, ActiveITs);
/* Return function status */
return HAL_OK;
}
else
{
/* Update error code */
hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
return HAL_ERROR;
}
}
The stm32 HAL library describes HAL_CAN_RxFifo0MsgPendingCallback as follows :
/**
* @brief Rx FIFO 0 message pending callback.
* @param hcan pointer to a CAN_HandleTypeDef structure that contains
* the configuration information for the specified CAN.
* @retval None
*/
__weak void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hcan);
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_CAN_RxFifo0MsgPendingCallback could be implemented in the
user file
*/
}
Thanks
2020-11-23 02:56 AM
Check the return codes (status) of all functions. Guess: you call HAL_CAN_ActivateNotification too early and it returns error. Debug-step though the code, you'll find it.