AnsweredAssumed Answered

STM32F2x7IG -- CAN IT failure --

Question asked by alvarez.francisco on Feb 2, 2016
Hello, I am new with ST. I am learning to work with CAN BUS with ST. 

I have random functioning, it works when it stops or when start, and randomly when it is in normal function mode. It could be without response 15 minutes and suddenly send 1 packet response. 

I have source: 

#include "main.h"

/* Private typedef -----------------------------------------------------------*/
struct {      
    uint32_t   prioridad:3; 
    uint32_t   destiny:7;
    uint32_t   tipo:3;
    uint32_t   canal:9;
    uint32_t   source:7;
    }identCan1;


struct {
    uint32_t      ident;
    uint8_t       ldato:3;
    uint8_t       dato[8];
    }stack_entrada;


/* Private define ------------------------------------------------------------*/
#define MY_ID  0x44


/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/

CAN_HandleTypeDef    CanHandle;
uint32_t IDsend;
uint32_t lect_an = 1234;
uint8_t intcancom = 0;

/* Private function prototypes -----------------------------------------------*/
static void SystemClock_Config(void);
static void CAN_Config(void);
static void Error_Handler(void);
static void NVIC_Config(void);


/* Private functions ---------------------------------------------------------*/
static void proccess_data_CAN(void);

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  /* STM32F2xx HAL library initialization:
       - Configure the Flash prefetch, instruction and Data caches
       - Configure the Systick to generate an interrupt each 1 msec
       - Set NVIC Group Priority to 4
       - Global MSP (MCU Support Package) initialization
     */ 
  HAL_Init();
  
  /* Configure the system clock to 120 MHz */
  SystemClock_Config();
  

  /* Configure Priority*/
  NVIC_Config();
  
  /*  1- Configure the CAN peripherical */
  CAN_Config();
  
 /* 2- Start the Reception process and enable reception interrupt */
if(HAL_CAN_Receive_IT(&CanHandle, CAN_FIFO0) != HAL_OK)
{
     Error_Handler();
}
  
HAL_CAN_IRQHandler(&CanHandle);

  /* Infinite loop */

  while(1)
  { 
      BSP_LED_On(LED2);
         if (intcancom == 1)
              {
                  proccess_data_CAN();
                     intcancom=0;
          }
  }
}

/**
  * @brief  System Clock Configuration
  *         The system Clock is configured as follow : 
  *            System Clock source            = PLL (HSE)
  *            SYSCLK(Hz)                     = 120000000
  *            HCLK(Hz)                       = 120000000
  *            AHB Prescaler                  = 1
  *            APB1 Prescaler                 = 4
  *            APB2 Prescaler                 = 2
  *            HSE Frequency(Hz)              = 25000000
  *            PLL_M                          = 25
  *            PLL_N                          = 240
  *            PLL_P                          = 2
  *            PLL_Q                          = 5
  *            VDD(V)                         = 3.3
  *            Flash Latency(WS)              = 3
  * @param  None
  * @retval None
  */
static void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;


  /* Enable HSE Oscillator and activate PLL with HSE as source */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 25;
  RCC_OscInitStruct.PLL.PLLN = 240;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 5;
  if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  
  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 
     clocks dividers */
 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief  This function is executed in case of error occurrence.
  * @param  None
  * @retval None
  */

static void Error_Handler(void)
{
  while(1)
  {
  }
}


/**
  * @brief  Configures the CAN.
  * @param  None
  * @retval None
  */
static void CAN_Config(void)
{
  
  CAN_FilterConfTypeDef  sFilterConfig;
  static CanTxMsgTypeDef        TxMessage;
  static CanRxMsgTypeDef        RxMessage;
  
  /*##-1- Configure the CAN peripheral #######################################*/
  CanHandle.Instance = CANx;
  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 = DISABLE;
  CanHandle.Init.Mode = CAN_MODE_NORMAL;
  CanHandle.Init.SJW = CAN_SJW_1TQ;
  CanHandle.Init.BS1 = CAN_BS1_6TQ;
  CanHandle.Init.BS2 = CAN_BS2_8TQ;
  CanHandle.Init.Prescaler = 2;
  
 
  
  if(HAL_CAN_Init(&CanHandle) != HAL_OK)
  {
    /* Initialization 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 = 2;
}


/**
  * @brief  Configures the NVIC for CAN.
  * @param  None
  * @retval None
  */
void NVIC_Config(void)
{

  NVIC_InitTypeDef  NVIC_InitStructure;
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

/* Assigh priority to CAN1 */  
  HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 1, 0);
  HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
}




/** 
          Receive CAN 
  */


/**
  * @brief  Transmission  complete callback in non blocking mode 
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  *         the configuration information for the specified CAN.
  * @retval None
  */
 void HAL_CAN_TxCpltCallback(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_TxCpltCallback could be implemented in the user file
   */
  
}


/**
  * @brief  Transmission  complete callback in non blocking mode 
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  *         the configuration information for the specified CAN.
  * @retval None
  */
void HAL_CAN_RxCpltCallback(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_RxCpltCallback could be implemented in the user file
   */
  proccess_data_CAN();
}






static void proccess_data_CAN(void)
{
  stack_entrada.ident = CanHandle.pRxMsg->ExtId;
  stack_entrada.ldato = CanHandle.pRxMsg->DLC;

  stack_entrada.dato[0]=CanHandle.pRxMsg->Data[0];
  stack_entrada.dato[1]=CanHandle.pRxMsg->Data[1];
  stack_entrada.dato[2]=CanHandle.pRxMsg->Data[2];
  stack_entrada.dato[3]=CanHandle.pRxMsg->Data[3];
  stack_entrada.dato[4]=CanHandle.pRxMsg->Data[4];
  stack_entrada.dato[5]=CanHandle.pRxMsg->Data[5];
  stack_entrada.dato[6]=CanHandle.pRxMsg->Data[6];
  stack_entrada.dato[7]=CanHandle.pRxMsg->Data[7];

 __HAL_CAN_FIFO_RELEASE(&CanHandle, CAN_FIFO0);


  identCan1.prioridad =  (stack_entrada.ident >> 26);
  identCan1.destiny = ((stack_entrada.ident & 0x03f80000) >> 19);
  identCan1.tipo = ((stack_entrada.ident  & 0x70000) >> 16);
  identCan1.canal = ((stack_entrada.ident & 0xFF80) >> 7);
  identCan1.source= (stack_entrada.ident & 0x7F);
  IDsend =  (identCan1.prioridad << 26) + (identCan1.source << 19) + (identCan1.tipo << 16) + (identCan1.canal << 7) + identCan1.destiny ;
  
  switch(identCan1.destiny)
  {
    case (MY_ID):
       switch (identCan1.canal)
        {
/*
511 is my order to repy with the same that i receiped to response in DATA Frame, making a change  of ExtId
*/
          case (511):
          BSP_LED_On(LED4);
        
          CanHandle.pTxMsg->ExtId = IDsend;
          CanHandle.pTxMsg->Data[0]=stack_entrada.dato[0];
          CanHandle.pTxMsg->Data[1]=stack_entrada.dato[1];
          CanHandle.pTxMsg->Data[2]=stack_entrada.dato[2];
          CanHandle.pTxMsg->Data[3]=stack_entrada.dato[3];
          CanHandle.pTxMsg->Data[4]=stack_entrada.dato[4];
          CanHandle.pTxMsg->Data[5]=stack_entrada.dato[5];
          CanHandle.pTxMsg->Data[6]=stack_entrada.dato[6];      
          CanHandle.pTxMsg->Data[7]=stack_entrada.dato[7];
          CanHandle.pTxMsg->DLC = 8;
          HAL_CAN_Transmit(&CanHandle, 1);
          break;
/* 
0x1 is my ident to response analog lecture in my variable lect_an that is not 
implemented yet
*/
          case(0x1):
          lect_an = 0x0123;
          CanHandle.pTxMsg->ExtId = IDsend;
          CanHandle.pTxMsg->Data[0] = ((lect_an & 0xFF00) >> 8);
          CanHandle.pTxMsg->Data[1] = ((lect_an & 0x00FF));
          CanHandle.pTxMsg->DLC = 2;
          HAL_CAN_Transmit(&CanHandle, 0);
          break;
/* 
When it is not 511 or 0x01 its a faulty case and my error msg is 0x0000
in the data 
*/
          default:
          CanHandle.pTxMsg->ExtId = IDsend;
          CanHandle.pTxMsg->Data[0] = 0;
          CanHandle.pTxMsg->Data[1] = 0;
          CanHandle.pTxMsg->DLC = 2;
          HAL_CAN_Transmit(&CanHandle, 0);
          break;
        }
   }
}


#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)

  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */


  /* Infinite loop */
  while (1)
  {
  }
}
#endif


/**
  * @}
  */

Outcomes