cancel
Showing results for 
Search instead for 
Did you mean: 

CAN2 interrupt not working

user 143
Associate III
Posted on October 26, 2017 at 11:03

Hey guys,

I've got some issues with the CAN2 interrupt on the STM32F107 controller, I don't getan interrupt.

I'm using CubeMX and a STM32F10C Eval board.

First I tried CAN1 an this works fine so far. Everytime there is a message on the CAN Bus, I get an interrupt and can read out the data.

Then I configuried CAN2 in CubeMX with the same parameter as CAN1, and I have left CAN1 active.

I know that I need CAN1 active to use CAN2, because CAN2 hasn't direct access to the SRAM.

I also enabled RX0 and RX1 interrupt.

Then I add this lines to my main() function:

if(HAL_CAN_Receive_IT(&hcan2, CAN_FIFO0) != HAL_OK)
{
 Error_Handler();
}�?�?�?�?

Andafter all I configuried the Filter for CAN2:

CAN_FilterConfTypeDef sFilterConfig;
hcan2.Instance = CAN2;
hcan2.pTxMsg = &TxMessage;
hcan2.pRxMsg = &RxMessage;
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 = 0;
if(HAL_CAN_ConfigFilter(&hcan2, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

I just want to use CAN2, because of that I set the BankNumber to 0, which (I think) means, that every bank is available for CAN2.

And here is my interrupt routine:

void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
{
HAL_GPIO_TogglePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin);
if(HAL_CAN_Receive_IT(hcan, CAN_FIFO0) != HAL_OK)
{
Error_Handler();
}
}�?�?�?�?�?�?�?�?�?

Sending data on CAN2 is no problem, this works fine.

I also see on the oscilloscope that the transceiver is transmitting the data to the controller.

When I change hcan2 to hcan1, then I can use this code with CAN1, which workes fine.

In both cases I have configuried CAN1 and CAN2 with CubeMX.

Where could be my mistake?

Thank you

5 REPLIES 5
Szymon PANECKI
Senior III
Posted on October 26, 2017 at 12:03

Hello Jurij,

In STM32 MCUs CAN1 and CAN2 share some resources (mainly SRAM memory) and these common resources are managed by CAN1. This is in fact the explanation why CAN1 is called Master in ST doucmentation and CAN2 is called Slave. This naming can be a bit misleading, because both these CAN interfaces are fully Multi-Master (not Master-Slave), like it is defined by CAN architecture. Anyway in such situation when you use CAN2 and CAN1 is not used, it may happen, that CAN2 has no access to these resources. Based on 

STM32F107 reference manual:

0690X00000608kzQAA.png

To overcome this limitation it should be enought to enable the clock for CAN1. Could you please check this solution and let me know if this solves the problem?

Best regards

Szymon

user 143
Associate III
Posted on October 27, 2017 at 07:56

Hey 

Szymon,

thank you for your quick response.

For testing, I disabled the call of MX_CAN1_Init() in the main and replaced it with __HAL_RCC_CAN1_CLK_ENABLE(); just for to be sure, the clock is enabled. 

But there is still no interrupt. 

I looked into the HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle) function, and there is allready the call of 

__HAL_RCC_CAN1_CLK_ENABLE() in the CAN2 part, so for my understanding CAN2 should work. 

I'm using PB5 for CAN2_RX and PB6 for CAN2_TX, because in the future I'm gooing to need the CAN bootloader. 

Posted on October 29, 2017 at 23:07

HiJurij,

Thanks for your feedback. I was just reviewing

https://community.st.com/0D50X00009XkYFkSAN

and I figured out, that it may provide a solution for your problem. Could you please change in your code a CAN filter bank number from 0 to 14? Like in the code below:

sFilterConfig.BankNumber = 14;

Best regards

Szymon

user 143
Associate III
Posted on November 02, 2017 at 08:57

Hi

Szymon,

thanks for your response, but this didn't work out.

I just tried something different. I created a new CubeMX project, where I only configuried the clock, serial debugging, the four LEDs and CAN2.

First I tried just to send a message, that works fine. On the

oscilloscopeI see the message and can recieve it with another board. But recieving in interrupt mode on this board is still not working.

So I tried the loopback mode like in the example from your link. For this, I disabled the interrupt mode of CAN2. Sending works fine, The message is on the bus. Then I checked the PB6 pin, which is the CAN2_TX pin. The message is there and looks fine. Then I checked the PB5 pin (CAN2_RX), there is also the message. So the loopback mode works fine.

But I can not recieve the message.

Here is my CAN2_Init code:

void MX_CAN2_Init(void)
{
 hcan2.Instance = CAN2;
 hcan2.Init.Prescaler = 4;
 hcan2.Init.Mode = CAN_MODE_LOOPBACK;
 hcan2.Init.SJW = CAN_SJW_1TQ;
 hcan2.Init.BS1 = CAN_BS1_5TQ;
 hcan2.Init.BS2 = CAN_BS2_3TQ;
 hcan2.Init.TTCM = DISABLE;
 hcan2.Init.ABOM = DISABLE;
 hcan2.Init.AWUM = DISABLE;
 hcan2.Init.NART = DISABLE;
 hcan2.Init.RFLM = DISABLE;
 hcan2.Init.TXFP = DISABLE;
 if (HAL_CAN_Init(&hcan2) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

And myHAL_CAN_MspInit:

void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{
 GPIO_InitTypeDef GPIO_InitStruct;
 if(canHandle->Instance==CAN2)
 {
 /* USER CODE BEGIN CAN2_MspInit 0 */
 /* USER CODE END CAN2_MspInit 0 */
 /* CAN2 clock enable */
 __HAL_RCC_CAN2_CLK_ENABLE();
 __HAL_RCC_CAN1_CLK_ENABLE();
 
 /**CAN2 GPIO Configuration 
 PB5 ------> CAN2_R
X PB6 ------> CAN2_TX 
 */
 GPIO_InitStruct.Pin = GPIO_PIN_5;
 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 GPIO_InitStruct.Pin = GPIO_PIN_6;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 __HAL_AFIO_REMAP_CAN2_ENABLE();
 /* USER CODE BEGIN CAN2_MspInit 1 */
 /* USER CODE END CAN2_MspInit 1 */
 }
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

And finaly, my routine for sending and recieving a message:

HAL_StatusTypeDef CAN_Polling(void)
{
 CAN_FilterConfTypeDef sFilterConfig;
 static CanTxMsgTypeDef TxMessage;
 static CanRxMsgTypeDef RxMessage;
 hcan2.pTxMsg = &TxMessage;
 hcan2.pRxMsg = &RxMessage;
 if(HAL_CAN_Init(&hcan2) != HAL_OK)
 {
 /* Initialization Error */
 Error_Handler();
 }
 sFilterConfig.FilterNumber = 14;
 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(&hcan2, &sFilterConfig) != HAL_OK)
 {
 /* Filter configuration Error */
 Error_Handler();
 }
 hcan2.pTxMsg->StdId = 0x11;
 hcan2.pTxMsg->RTR = CAN_RTR_DATA;
 hcan2.pTxMsg->IDE = CAN_ID_STD;
 hcan2.pTxMsg->DLC = 2;
 hcan2.pTxMsg->Data[0] = 0xCA;
 hcan2.pTxMsg->Data[1] = 0xFE;
 if(HAL_CAN_Transmit(&hcan2, 10) != HAL_OK)
 {
 /* Transmition Error */
 Error_Handler();
 }
 if(HAL_CAN_GetState(&hcan2) != HAL_CAN_STATE_READY)
 {
 return HAL_ERROR;
 }
 if(HAL_CAN_Receive(&hcan2, CAN_FIFO0, 100) != HAL_OK)
 {
 /* Reception Error */
 Error_Handler();
 }
 if(HAL_CAN_GetState(&hcan2) != HAL_CAN_STATE_READY)
 {
 return HAL_ERROR;
 }
 return HAL_OK; /* Test Passed */
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

HAL_CAN_Recieve is recieving a HAL_TIME_OUT.

Any idea where my mistake could be?

Thank you very much

user 143
Associate III
Posted on November 02, 2017 at 16:49

Hello,

well, I found my mistake, but it's not a real mistake I made, it's more a bug in the HAL driver.

I found this thread:

https://community.st.com/0D50X00009Xkf8XSAR

I tried again the loopback mode, and changed the instance of hcan2 before initialising the filter:

hcan2.Instance = CAN1;�?

Now I can recieve messages in loopback mode, but interrupts are still not working with CAN2.

So I tried a bit with different instances, and find a way, that interrupts are working with CAN2.

First I added the RX and TX buffer:

 hcan2.Instance = CAN2; hcan2.pTxMsg = &TxMessage; hcan2.pRxMsg = &RxMessage; if(HAL_CAN_Init(&hcan2) != HAL_OK) { /* Initialization Error */ Error_Handler(); }�?�?�?�?�?�?�?�?�?

After that, I configuried the filter and add it also, but before that I had to change the hcan2.Instance:

 CAN_FilterConfTypeDef sFilterConfig; hcan2.Instance = CAN1;sFilterConfig.FilterNumber = 27;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 = 0; if(HAL_CAN_ConfigFilter(&hcan2, &sFilterConfig) != HAL_OK) { /* Filter configuration Error */ Error_Handler(); }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

With setting BankNumber to 0, every available filter is conntected to the CAN2.

Finaly, I enabled the interrupts for CAN2, but had again to change the hcan.Instance - back to CAN2.

 hcan2.Instance = CAN2; if(HAL_CAN_Receive_IT(&hcan2, CAN_FIFO0) != HAL_OK) { /* Reception Error */ Error_Handler(); }�?�?�?�?�?�?�?

Now is everything working as I want it.

Thanks.