AnsweredAssumed Answered

STM32F072 hang-up by CAN-Bus RX interrupt

Question asked by Frank Weng on Feb 21, 2017
Latest reply on Jul 11, 2017 by m ikhlas

Hi,

 

I am trying to implement CAN Bus communication between two STMF072 boards and find that the communication will be lost randomly. While this situation occurs, the MCU routine loop also be stop just like chip hang-up.

 

The model is STM32F072-Discovery and here is my code.

 

===========================================================================
#include "stm32f0xx_hal.h"
#include "usb_device.h"
#include "usbd_cdc_if.h"
/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan;
static CanTxMsgTypeDef TxMessage;
static CanRxMsgTypeDef RxMessage;
uint32_t Timer_100ms = 0;
uint32_t Timer_Routing = 0;
uint32_t Flag_CAN_RX_item = 0;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_CAN_Init(void);
void broadcast1(void)
{
TxMessage.DLC = 0;
HAL_CAN_Transmit_IT(&hcan);
}
void broadcast2(void)
{
TxMessage.DLC = 8;
TxMessage.Data[0] = 1;
TxMessage.Data[1] = 1;
TxMessage.Data[2] = 1;
TxMessage.Data[3] = 1;
TxMessage.Data[4] = 1;
TxMessage.Data[5] = 1;
TxMessage.Data[6] = 1;
TxMessage.Data[7] = 1;
HAL_CAN_Transmit_IT(&hcan);
}
void responding(void)
{
if (RxMessage.DLC == 8)
{
TxMessage.DLC = 1;
TxMessage.Data[0] = 1;
HAL_CAN_Transmit_IT(&hcan);
}
}
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_CAN_Init();
MX_USB_DEVICE_Init();
if (HAL_CAN_Receive_IT(&hcan, CAN_FIFO0) != HAL_OK)
{
/* Reception Error */
Error_Handler();
}
Timer_Routing = HAL_GetTick();
Timer_100ms = Timer_Routing;
/* Infinite loop */
while (1)
{
if (Flag_CAN_RX_item)
{
responding();
Flag_CAN_RX_item = 0;
}
// delay 100ms
if ((Timer_Routing - Timer_100ms) > 100)
{
#if 0
broadcast1();
#else
broadcast2();
#endif
// act LED to show routine loop
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8);
Timer_100ms = Timer_Routing;
}
Timer_Routing = HAL_GetTick();
}
}
/** System Clock Configuration
*/

void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI48;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL3;
RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* CAN init function */
static void MX_CAN_Init(void)
{
CAN_FilterConfTypeDef sFilterConfig;
hcan.Instance = CAN;
hcan.Init.Prescaler = 9;
hcan.Init.Mode = CAN_MODE_NORMAL;
hcan.Init.SJW = CAN_SJW_1TQ;
hcan.Init.BS1 = CAN_BS1_13TQ;
hcan.Init.BS2 = CAN_BS2_2TQ;
hcan.Init.TTCM = DISABLE;
hcan.Init.ABOM = DISABLE;
hcan.Init.AWUM = DISABLE;
hcan.Init.NART = DISABLE;
hcan.Init.RFLM = DISABLE;
hcan.Init.TXFP = DISABLE;
hcan.pTxMsg = &TxMessage;
hcan.pRxMsg = &RxMessage;
if (HAL_CAN_Init(&hcan) != HAL_OK)
{
Error_Handler();
}
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(&hcan, &sFilterConfig) != HAL_OK)
{
/* Filter configuration Error */
Error_Handler();
}
sFilterConfig.FilterNumber = 1;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = 1;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.BankNumber = 14;
if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
/* Filter configuration Error */
Error_Handler();
}
hcan.pTxMsg->StdId = 0x3FC;
hcan.pTxMsg->ExtId = 0x01;
hcan.pTxMsg->RTR = CAN_RTR_DATA;
hcan.pTxMsg->IDE = CAN_ID_EXT;
}
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/

static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_RESET);
/*Configure GPIO pins : PC8 PC9 */
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef *CanHandle)
{
// active LED to show CAN RX
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9);
Flag_CAN_RX_item = 1;
/* Receive */
if (HAL_CAN_Receive_IT(CanHandle, CAN_FIFO0) != HAL_OK)
{
/* Reception Error */
Error_Handler();
}
}
/**
* @brief This function is executed in case of error occurrence.
* @param None
* @retval None
*/

void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler */
/* User can add his own implementation to report the HAL error return state */
while(1)
{
}
/* USER CODE END Error_Handler */
}
=====================================================

I write broadcast1() for one board and broadcast2() for the other, and build the related FW using #if in main().

Also, I try to trice this issue by debug mode via Keil. When the issue is reproduced, code stop in Error_Handler() and it should be called only by HAL_CAN_Receive_IT() while main while routine. Are there any ideas?

 

Thanks for your reading.

Outcomes