cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F0 CAN Stops communication

eng23
Senior
Posted on August 16, 2017 at 21:39

Hello,

I'm working with STM32F0 and CAN communication, sometimes the CAN peripheral stops, doesn't send or receive messages.

In the past I asked the same issue and the answer was that it could be the HAL_LOCK funtion and it will be fix in the next revision. My version of stm32f0xx_hal_can.c is * @version V1.4.0, and now I've updated to V1.8, but the problem still happens.

Has anyone experienced this problem? How  can I fix it?

Thanks.

#can #busy #stm32
12 REPLIES 12
Posted on August 16, 2017 at 22:00

So is it due to the software lock/mutex? or not?

Do the CAN peripheral registers look normal, or are they flagging errors, or stuffed FIFOs?

>>How can I fix it?

The entire library is provided in source form, dig into it a little, if it is a lock issue, check that you and the library properly bracket the usages, and there are no return paths that fail to release it.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on August 16, 2017 at 22:15

Thanks for reply Clive,

So is it due to the software lock/mutex? or not?

No, is in normal operation.

Do the CAN peripheral registers look normal, or are they flagging errors, or stuffed FIFOs?

I have a CAN analyser and osciloscope plugged in and doesn't show any error. How can I check if the FIFOs are stuffed?

Debbuging the mcu, the error returned in the function HAL_CAN_Receive_IT is HAL_CAN_STATE_BUSY_RX0, and stay there forever...

Posted on August 16, 2017 at 22:23

>>I have a CAN analyser and osciloscope plugged in and doesn't show any error.

Ok, but that's a bit external facing, the software is likely reflecting an internal state, and you'll need to look within the part rather than without.

>>How can I check if the FIFOs are stuffed?

You would need to inspect the internal CAN peripheral registers more directly, the Reference Manual describes the bulk of these, but is a bit opaque due to ST using third-party IP for the bxCAN implementation.

I'd probably use the printf() method to dump internal state, but a peripheral view in the debugger might also provide some insight at the expense of being a bit invasive.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on August 16, 2017 at 22:28

Start by inspecting these registers

CAN1->CAN_MSR

CAN1->CAN_TSR

CAN1->CAN_RF0R

CAN1->CAN_RF1R

Make sure the interrupt and callback functions are completing quickly and not blocking, or missing packets.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on August 17, 2017 at 00:34

You could set the ABOM bit for a quick and dirty test and see whether that resolves it.

(Automatic bus off management -> auto restart in case of bus failure).

Posted on August 17, 2017 at 13:47

I've checked this register when the can frame is ok and not, and the difference was basically in the CAN_IER register:

frame ok: CAN_IER = 1000111100000010

frame nok: CAN_IER = 1000111100000000

FMPIE0: No interrupt generated when state of FMP[1:0] bits are not 00b.

Posted on August 17, 2017 at 13:59

Thanks for help Valentin,

I will set ABOM bit and verify if the problem continues.

Something that is strange is if I use the function  if (HAL_CAN_Transmit(&CanHandle, CANTIMEOUT) != HAL_OK) to send can messages sometimes I get problems to send, so I changed to if (HAL_CAN_Transmit_IT(&CanHandle) != HAL_OK). With this I haven't problems anymore, but the receive one continues.

Below is my code basically:

void CAN_Init(unsigned long baudrate)

{

 

  /* Enable CAN module */

  __HAL_RCC_CAN1_CLK_ENABLE();

  /* if we have a wrong baudrate value */

  if((baudrate!=CAN250KBPS) || (baudrate!=CAN1000KBPS)) baudrate=CAN250KBPS;

 

  CAN_FilterConfTypeDef  sFilterConfig;

  static CanTxMsgTypeDef        TxMessage;

  static CanRxMsgTypeDef        RxMessage;

  /* How to calculate Quantum time */

  /* CAN_BitRate = CAN_CLK / (CAN_Prescaler * (CAN_SJW + CAN_BS1 + CAN_BS2)) */

  /* 250kbps     = 48MHz   / (    12         * (   1    +    7    +    8   )) */

  /* 1000kbps    = 48MHz   / (    3        * (   1    +    7    +    8   )) */

 

  /*♯♯-1- Configure the CAN peripheral ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

  CanHandle.Instance = CAN;

  CanHandle.pTxMsg = &TxMessage;

  CanHandle.pRxMsg = &RxMessage;

 

  CanHandle.Init.TTCM = DISABLE;

  CanHandle.Init.ABOM = DISABLE;

  CanHandle.Init.AWUM = DISABLE;

  CanHandle.Init.NART = DISABLE;

  CanHandle.Init.RFLM = DISABLE;

  CanHandle.Init.TXFP = ENABLE;

  CanHandle.Init.Mode = CAN_MODE_NORMAL;

  CanHandle.Init.SJW = CAN_SJW_1TQ;

  CanHandle.Init.BS1 = CAN_BS1_7TQ;

  CanHandle.Init.BS2 = CAN_BS2_8TQ;

  CanHandle.Init.Prescaler = baudrate;

  if (HAL_CAN_Init(&CanHandle) != HAL_OK)

  {

    /* Initiliazation Error */

    Error_Handler();

  }

  /*♯♯-2- Configure the CAN Filter ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

  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 = 14;

  if (HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig) != HAL_OK)

  {

    /* Filter configuration Error */

    Error_Handler();

  }

  /*♯♯-3- Configure Transmission process ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

  CanHandle.pTxMsg->StdId = 0x321;

  CanHandle.pTxMsg->ExtId = 0x01;

  CanHandle.pTxMsg->RTR = CAN_RTR_DATA;

  CanHandle.pTxMsg->IDE = CAN_ID_EXT;

  CanHandle.pTxMsg->DLC = 8;

 

  /*♯♯-3- Configure the NVIC ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

  /* NVIC configuration for CAN1 Reception complete interrupt */

  HAL_NVIC_SetPriority(CANx_RX_IRQn, 1, 0);

  HAL_NVIC_EnableIRQ(CANx_RX_IRQn);

 

  /*♯♯-4- Start the Reception process and enable reception interrupt ♯♯♯♯♯♯♯♯♯*/

  if (HAL_CAN_Receive_IT(&CanHandle, CAN_FIFO0) != HAL_OK)

  {

    /* Reception Error */

    Error_Handler();

  }

}

To transmit:

if (HAL_CAN_Transmit_IT(&CanHandle) != HAL_OK)

{

}

To receive:

if (HAL_CAN_Receive_IT(CanHandle2, CAN_FIFO0) != HAL_OK)

{

}

Posted on August 17, 2017 at 14:44

You could set the ABOM bit for a quick and dirty test and see whether that resolves it.

(Automatic bus off management -> auto restart in case of bus failure).

I've tested with ABOM enabled but the problem continues. The receive process stops receive messages. It seems like not a CAN bus problem, but something in the firmware/interruption.

eng23
Senior
Posted on August 17, 2017 at 21:41

Any other idea? Thanks