cancel
Showing results for 
Search instead for 
Did you mean: 

BxCAN Frame and Form Errors Help

AMont.4
Associate

Hi Stm Forums. I'm a college student working on my capstone project that requires CAN bus communication between two STM32F1 and one STM32F4. For a little background each of the STM32F1's job is to read in sensor information, filter, and send that data when requested. The STM32F4 is the main controller which requests the data from each of the STM32F1's.

To develop my software I'm using STM Nucleo boards for the F1 and F4 with SN65HVD230 CAN transceivers. I'm also using CANOpenNode to handle the can protocol for me. The project is writin in C using the STM32 HAL library.

Now to my question. I'm having problems with the MCU's on the network going into silent mode and bus off mode. Using an oscilloscope I can see that there are frame errors that are causing the internal error counters to rise up past 127 for receive and 256 for transmit. I have included screen shots from the oscilloscope to show you what the wave forms look like.

0693W000008y4OsQAI.pngHere I'm getting form errors and I think the oscilliscope can't identify that bit. From what I understand about CAN that should be the acknowledge bit (?). The message being sent is a sync request message from the F4 to the F1's.

Below is another screen shot showing a response message to the sync. The response comes from a F1.0693W000008y4P2QAI.pngThe last bit looks very weird compared to the rest. Then the whole second message cannot be identified. I don't know enough about CAN to understand what is a happening.

Below is another screen shot of the oscilloscope output. Here I have two F1's and one F4 connected to the network. This message was sent by one of the F1's. This one also has a form error

ff0693W000008y4P7QAI.png 

My final screen shot is a full sync response message with that weird last bit. This time the oscilloscope is able to decode the entire message. This leads me to think that the weird last bit isn't causing the form and frame errors.

To get more information about the BxCAN errors I print out the ESR register whenever the error interrupt is ran. I sometimes get large busts of errors and times without any. The time between starting and having the BxCAN modules turn off is random.

My two theories are that there is something wrong with the clocking into the BxCAN module or the BxCAN settings are wrong. Below is the code for the F1 clocking and BxCAN settings

RCC_ClkInitTypeDef clkinitstruct = {0};
  RCC_OscInitTypeDef oscinitstruct = {0};
  
  /* Configure PLL ------------------------------------------------------*/
  /* PLL configuration: PLLCLK = (HSE / 2) * PLLMUL = (8 / 2) * 16 = 64 MHz */
  /* PREDIV1 configuration: PREDIV1CLK = PLLCLK / HSEPredivValue = 64 / 1 = 64 MHz */
  /* Enable HSI and activate PLL with HSi_DIV2 as source */
  oscinitstruct.OscillatorType  = RCC_OSCILLATORTYPE_HSE;
  oscinitstruct.HSEState        = RCC_HSE_ON;
  oscinitstruct.LSEState        = RCC_LSE_OFF;
  oscinitstruct.HSIState        = RCC_HSI_OFF;
  oscinitstruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  oscinitstruct.HSEPredivValue    = RCC_HSE_PREDIV_DIV2;
  oscinitstruct.PLL.PLLState    = RCC_PLL_ON;
  oscinitstruct.PLL.PLLSource   = RCC_PLLSOURCE_HSE;
  oscinitstruct.PLL.PLLMUL      = RCC_PLL_MUL16;
 
  if (HAL_RCC_OscConfig(&oscinitstruct)!= HAL_OK)
  {
    /* Initialization Error */
    while(1); 
  }
 
  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 
     clocks dividers */
  clkinitstruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  clkinitstruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  clkinitstruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  clkinitstruct.APB2CLKDivider = RCC_HCLK_DIV1;
  clkinitstruct.APB1CLKDivider = RCC_HCLK_DIV2;  
  if (HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2)!= HAL_OK)
  {
    /* Initialization Error */
    while(1); 
  }

And here is the BxCAN settings

CanHandle->Instance = CANx;
	CanHandle->Init.Mode = CAN_MODE_NORMAL;
	CanHandle->Init.SyncJumpWidth = CAN_SJW_1TQ;
	CanHandle->Init.TimeTriggeredMode = DISABLE;
	CanHandle->Init.AutoBusOff = DISABLE;
	CanHandle->Init.AutoWakeUp = DISABLE;
	CanHandle->Init.AutoRetransmission = ENABLE;
	CanHandle->Init.ReceiveFifoLocked = DISABLE;
	CanHandle->Init.TransmitFifoPriority = DISABLE;
 
    /* Configure CAN timing */
    // Hard coded in rn
    CanHandle->Init.TimeSeg1 = CAN_BS1_13TQ;
    CanHandle->Init.TimeSeg2 = CAN_BS2_2TQ;
 
    switch(CANbitRate) {
        case 500:
            CanHandle->Init.Prescaler = 4;
            break;
        case 1000:
            CanHandle->Init.Prescaler = 2;
            break;
        default:
         return CO_ERROR_ILLEGAL_BAUDRATE;
    }

Right now I have the program set to a baud rate of 500kbps. Lastly here is the MSP_Init function for the CAN module

// Set up of this function was found here
  // https://os.mbed.com/users/hudakz/code/CANnucleo//file/cebc6f21046e/stm32f1xx_hal_msp.c/
  GPIO_InitTypeDef   GPIO_InitStruct;
  
  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* CAN1 Periph clock enable */
  CANx_CLK_ENABLE();
  /* Enable GPIO clock ****************************************/
  CANx_GPIO_CLK_ENABLE();
 
  // Need to enable the alternate function clock
  __HAL_RCC_AFIO_CLK_ENABLE();
 
  // Switch the interal CAN rx/tx pins to be on PA11 and PA12
  __HAL_AFIO_REMAP_CAN1_1();
 
  // Switch the interal CAN rx/tx pins to be on PB8 and PB9
  // Share the same pins with I2C so swap to different pins
  //__HAL_AFIO_REMAP_CAN1_2();
 
  /*##-2- Configure peripheral GPIO ##########################################*/ 
  /* CAN1 TX GPIO pin configuration */
  GPIO_InitStruct.Pin = CANx_TX_PIN;
 
  // Need to set these pins as alternate function as they default
  // to timer channels
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  
  HAL_GPIO_Init(CANx_TX_GPIO_PORT, &GPIO_InitStruct);
  
  /* CAN1 RX GPIO pin configuration */
  GPIO_InitStruct.Pin = CANx_RX_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_INPUT;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  
  HAL_GPIO_Init(CANx_RX_GPIO_PORT, &GPIO_InitStruct);
 
  /* CAN1 interrupt Init */
  HAL_NVIC_SetPriority(CAN1_TX_IRQn, CAN1_TX_IRQ_PRIORITY, 0);
  HAL_NVIC_EnableIRQ(CAN1_TX_IRQn);
  HAL_NVIC_SetPriority(CAN1_RX0_IRQn, CAN1_RX0_IRQ_PRIORITY, 1);
  HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);

I hope this is enough information to generate more questions. I'm stuck trying to solve this issue.

If any other information is needed please let me know. I also included the links to the GitHub projects if other parts of the code are needed

STM32F1 Code

STM32F4 Code

Thank you!

1 REPLY 1
AJane.1
Associate

I have checked all the information you provided, I am facing the same issue and looking to resolve for this page as soon as possible. I will appreciate if someone could help. Thank you!