0
\$\begingroup\$

I'm new to CAN communication and trying to setup CAN (normal mode) between two identical custom boards having STM32F072 controllers. Code generated using CubeMX (STM32Cube_FW_F0_V1.9.0) drivers.

Here is the setup diagram. TJA1050 RS pin is grounded & VREF is NC.

connection diagram

In the main while(1) calling HAL_CAN_Transmit(&hcan, 100) gives timeout result (0x03) at both boards, from the following portion of code in stm32f0xx_hal_can.c

  /* Check End of transmission flag */
   while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
  {
        /* Check for the Timeout */
         if(Timeout != HAL_MAX_DELAY)
  {
    if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
    {
      hcan->State = HAL_CAN_STATE_TIMEOUT;

      /* Cancel transmission */
      __HAL_CAN_CANCEL_TRANSMIT(hcan, transmitmailbox);

      /* Process unlocked */
      __HAL_UNLOCK(hcan);
      return HAL_TIMEOUT;
    }
  }
}

main.c

      int main(void)
      {

          HAL_Init();
          SystemClock_Config();
          MX_GPIO_Init();
          MX_USART2_UART_Init();
          printf("### debug started ####\r\n");
          MX_CAN_Init();

          if (HAL_CAN_Receive_IT(&hcan, CAN_FIFO0) != HAL_OK)
          {
             /* Reception Error */
             _Error_Handler(__FILE__, __LINE__);
          }

          /* USER CODE END 2 */

          /* Infinite loop */
          /* USER CODE BEGIN WHILE */
          printf("In mail while loop\r\n");

          while (1)
          {
                /*##-3- Start the Transmission process ###############################*/
                int stat = HAL_CAN_Transmit(&hcan, 10);
                if ( stat != HAL_OK)
                {
                  printf("stat: %x\r\n", stat);
                  /* Transmission Error */
                  Error_Handler();
                }
                HAL_Delay(10);

          }
    }

    void SystemClock_Config(void)
    {


        RCC_ClkInitTypeDef RCC_ClkInitStruct;
        RCC_OscInitTypeDef RCC_OscInitStruct;
        RCC_PeriphCLKInitTypeDef PeriphClkInit;

        /* 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.PREDIV = RCC_PREDIV_DIV1;
        RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;
        if (HAL_RCC_OscConfig(&RCC_OscInitStruct)!= HAL_OK)
        {
        /* Initialization Error */
            while(1);
        }

        /* Select PLL as system clock source and configure the HCLK, PCLK1 clocks dividers */
        RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | 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)
        {
        /* Initialization Error */
            while(1);
        }

        PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
        PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
        if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
        {
        _Error_Handler(__FILE__, __LINE__);
        }

        /**Configure the Systick interrupt time
        */
        HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

        /**Configure the Systick
        */
        HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

        /* SysTick_IRQn interrupt configuration */
        HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

    }
    static void MX_CAN_Init(void)
    {
        CAN_FilterConfTypeDef  sFilterConfig;
        static CanTxMsgTypeDef        TxMessage;
        static CanRxMsgTypeDef        RxMessage;

        /*##-1- Configure the CAN peripheral #######################################*/
        hcan.Instance = CAN;
        hcan.pTxMsg = &TxMessage;
        hcan.pRxMsg = &RxMessage;

        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.Init.Mode = CAN_MODE_NORMAL;
        hcan.Init.SJW = CAN_SJW_1TQ;
        hcan.Init.BS1 = CAN_BS1_5TQ;
        hcan.Init.BS2 = CAN_BS2_6TQ;
        hcan.Init.Prescaler = 4;

        if (HAL_CAN_Init(&hcan) != 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(&hcan, &sFilterConfig) != HAL_OK)
        {
        /* Filter configuration Error */
        Error_Handler();
        }

        /*##-3- Configure Transmission process #####################################*/
        hcan.pTxMsg->StdId = 0x321;
        hcan.pTxMsg->ExtId = 0x01;
        hcan.pTxMsg->RTR = CAN_RTR_DATA;
        hcan.pTxMsg->IDE = CAN_ID_STD;
        hcan.pTxMsg->DLC = 8;

        TxMessage.Data[0] = 0x00;
        TxMessage.Data[1] = 0x01;
        TxMessage.Data[2] = 0x02;
        TxMessage.Data[3] = 0x03;
        TxMessage.Data[4] = 0x04;
        TxMessage.Data[5] = 0x05;
        TxMessage.Data[6] = 0x06;
        TxMessage.Data[7] = 0x07;
    }

    void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
    {

     printf("**\r\n");

     if ((hcan->pRxMsg->StdId == 0x321) && (hcan->pRxMsg->IDE == CAN_ID_STD) && (hcan->pRxMsg->DLC == 8))
     {

         printf("$$\r\n");
         printf("data[0]: %x\r\n", hcan->pRxMsg->Data[0]);
         printf("data[1]: %x\r\n", hcan->pRxMsg->Data[1]);
         printf("data[2]: %x\r\n", hcan->pRxMsg->Data[2]);
         printf("data[3]: %x\r\n", hcan->pRxMsg->Data[3]);
         printf("data[4]: %x\r\n", hcan->pRxMsg->Data[4]);
         printf("data[5]: %x\r\n", hcan->pRxMsg->Data[5]);
         printf("data[6]: %x\r\n", hcan->pRxMsg->Data[6]);
         printf("data[7]: %x\r\n", hcan->pRxMsg->Data[7]);

     }

       /* Receive */
     if (HAL_CAN_Receive_IT(&hcan, CAN_FIFO0) != HAL_OK)
       {
         /* Reception Error */
         Error_Handler();
       }
    }

    static void MX_GPIO_Init(void)
    {

      /* GPIO Ports Clock Enable */
      __HAL_RCC_GPIOC_CLK_ENABLE();
      __HAL_RCC_GPIOF_CLK_ENABLE();
      __HAL_RCC_GPIOA_CLK_ENABLE();

    }

stm32f0xx_hal_msp.c

    void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
    {


      GPIO_InitTypeDef GPIO_InitStruct;
      if(hcan->Instance==CAN)
      {
          __HAL_RCC_CAN1_CLK_ENABLE();
          __HAL_RCC_GPIOB_CLK_ENABLE();

          /*##-2- Configure peripheral GPIO ##########################################*/
          /* CAN1 TX GPIO pin configuration */
          GPIO_InitStruct.Pin = GPIO_PIN_9; //GPIO_PIN_12;
          GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
          GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
          GPIO_InitStruct.Pull = GPIO_PULLUP;
          GPIO_InitStruct.Alternate =  GPIO_AF4_CAN;

          HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

          /* CAN1 RX GPIO pin configuration */
          GPIO_InitStruct.Pin = GPIO_PIN_8; //GPIO_PIN_11;
          GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
          GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
          GPIO_InitStruct.Pull = GPIO_PULLUP;
          GPIO_InitStruct.Alternate =  GPIO_AF4_CAN;

          HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

          /*##-3- Configure the NVIC #################################################*/
          /* NVIC configuration for CAN1 Reception complete interrupt */
          HAL_NVIC_SetPriority(CEC_CAN_IRQn, 1, 0);
          HAL_NVIC_EnableIRQ(CEC_CAN_IRQn);     
        }
    }

stm32f0xx_it.c

    void CEC_CAN_IRQHandler(void)
    {
      HAL_CAN_IRQHandler(&hcan);

    }

What am I missing in my setup? Thanks in advance.


Here is my stm32f4xx CAN working source code link.

https://drive.google.com/open?id=1t6H3i-Wt5iFTc95UQn_TMpF0CTy3IBF5

IDE : atollic CubeMx : 4.24.0

\$\endgroup\$
  • \$\begingroup\$ It seems that your second uC is not accepting, or in correct terms ACKnowleding the CAN frame. I would check the IDs, the second uC must have an ID that it populates its mailbox with. In addition, I would look at the can bus with a scope, to see whether it is a valid CAN frame or not. Can you share that? \$\endgroup\$ – mehmet.ali.anil Mar 14 at 8:05
  • \$\begingroup\$ @mehmet.ali.anil yes you are right it strucks while waiting for ACK. I've attached the code. Used the same code for both transmitter & receiver. Do i need to use different ExtId for transmitter & receiver. \$\endgroup\$ – Lingaraj Mar 14 at 8:22
  • \$\begingroup\$ Check with your scope or CAN listener which baudrate you actually get on the lines. Your TQ settings look fishy but that might just be a naming problem in the bloatware. \$\endgroup\$ – Lundin Mar 14 at 13:37
  • 1
    \$\begingroup\$ @DogusUral I've posted my f4 reference link.[link](www.youtube.com/watch?v=GYhsHJi6pKE),[link]( www.youtube.com/watch?v=ymD3F0h-ilE). \$\endgroup\$ – Lingaraj May 10 at 7:07
  • 1
    \$\begingroup\$ @DogusUral new one. CubeMx 4.24.0. I've shared the source code drive link above. \$\endgroup\$ – Lingaraj May 11 at 8:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.