cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103C8 (BluePill) does not get passed HAL_CAN_Init

NikolasZ
Associate II

I have read about this problems in sooo many other posts both in this forum and in other. I have also tried the various solutions that have been proposed as answers.

I will try to do my best in explaining what I have done. Please bear with me, as I am a total noob.

Ok, so the setup is one BluePill (STM32F103C8) MCU and the MCP2551 CAN-transceiver.

Transceiver is connected like this:

Pin1 - PA12

Pin4 - PA11 (I have tried switching pins here as well)

Pin3 - GND

Pin2 - 5V (5k1 resistor to the Rx pin from here as well for pull-up - tried with and without)

Pin5 - NC

Pin6 - CAN Low

Pin7 - CAN High (With and without a 120Ohm resistor to Pin6)

Pin8 - GND (No resistor and no slope)

The Code is straight out of the CubeIDE guide, without any modificcations. I haven't inserted any private code anywhere. Just the code that was generated by CubeIde.

I have tried 1.8.0, 1.8.3 and the latest 1.8.4

RCC clocks and timings are set as standard, with the 8Mhz external crystal (BluePill), and 72Mhz HCLK internal clock and 36MHz clock for APB1 peripherials. THe LSE is set to Disabled. (I have set it ti enabled also but there was no difference).

I have tried several CAN settings and Baud rates. Always inserted the recommended values from CAN Bit Time Calculation (can-wiki.info). Bit rates I have tried are 10kbit/s, 100kbit/s (which is what I want), 125kBit/s, 500kbit/s and 1Mbit/s.

Test modes I have tried are all of them, Normal, Loopback, Silent and Silent with Loopback.

When set to Loopback I have tried with and without the CAN transceiver, with and without the external pull-up resistor to 3,3V. I have tried direct connection between Rx and Tx (PA11-PA12). I have tried the alternative pins PB8 and PB9 as well, with all combinations of transceiver/no transceiver.

I think that I have tried all imaginable combinations there are.

I have tried variants of changes in the code in the libraries, like this:

HAL_CAN_Init() returns error after firmware migration from V1.8.0 to V1.8.4 on STM32F103C8T6

I feel that it is pointless to add any filter-settings or even the HAL_CAN_Start function, since it does not pass the HAL_CAN_Init

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
 
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
 
/* USER CODE END Includes */
 
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
 
/* USER CODE END PTD */
 
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
 
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
 
/* USER CODE END PM */
 
/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan;
 
/* USER CODE BEGIN PV */
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN_Init(void);
/* USER CODE BEGIN PFP */
 
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_CAN_Init();
  /* USER CODE BEGIN 2 */
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
		HAL_GPIO_TogglePin(LED_ON_INDICATOR_GPIO_Port, LED_ON_INDICATOR_Pin);
		HAL_Delay(2000);
		HAL_GPIO_TogglePin(LED_ON_INDICATOR_GPIO_Port, LED_ON_INDICATOR_Pin);
		HAL_Delay(500);
  }
  /* USER CODE END 3 */
}
 
/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}
 
/**
  * @brief CAN Initialization Function
  * @param None
  * @retval None
  */
static void MX_CAN_Init(void)
{
 
  /* USER CODE BEGIN CAN_Init 0 */
 
  /* USER CODE END CAN_Init 0 */
 
  /* USER CODE BEGIN CAN_Init 1 */
 
  /* USER CODE END CAN_Init 1 */
  hcan.Instance = CAN1;
  hcan.Init.Prescaler = 20;
  hcan.Init.Mode = CAN_MODE_LOOPBACK;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_15TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_2TQ;
  hcan.Init.TimeTriggeredMode = DISABLE;
  hcan.Init.AutoBusOff = DISABLE;
  hcan.Init.AutoWakeUp = DISABLE;
  hcan.Init.AutoRetransmission = DISABLE;
  hcan.Init.ReceiveFifoLocked = DISABLE;
  hcan.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN_Init 2 */
 
  /* USER CODE END CAN_Init 2 */
 
}
 
/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED_ON_INDICATOR_GPIO_Port, LED_ON_INDICATOR_Pin, GPIO_PIN_RESET);
 
  /*Configure GPIO pin : LED_ON_INDICATOR_Pin */
  GPIO_InitStruct.Pin = LED_ON_INDICATOR_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED_ON_INDICATOR_GPIO_Port, &GPIO_InitStruct);
 
}
 
/* USER CODE BEGIN 4 */
 
/* USER CODE END 4 */
 
/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  //__disable_irq(); //Disabling this row, since it otherwise halts here
  while (1)
  {
		HAL_GPIO_TogglePin(LED_ON_INDICATOR_GPIO_Port, LED_ON_INDICATOR_Pin);
		HAL_Delay(500);
		HAL_GPIO_TogglePin(LED_ON_INDICATOR_GPIO_Port, LED_ON_INDICATOR_Pin);
		HAL_Delay(50);
		HAL_GPIO_TogglePin(LED_ON_INDICATOR_GPIO_Port, LED_ON_INDICATOR_Pin);
		HAL_Delay(50);
		HAL_GPIO_TogglePin(LED_ON_INDICATOR_GPIO_Port, LED_ON_INDICATOR_Pin);
		HAL_Delay(50);
 
  }
  /* USER CODE END Error_Handler_Debug */
}
 
#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 CODE BEGIN 6 */
  /* 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) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

14 REPLIES 14
NikolasZ
Associate II

The code above is the one that is generated almost "as is". I have only added some LED (PC13) indications for my own convinience. The baud rate is set for 100kbit/s.

NikolasZ
Associate II

The stm32f1xx_hal_msp.c-file:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file         stm32f1xx_hal_msp.c
  * @brief        This file provides code for the MSP Initialization
  *               and de-Initialization codes.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
 
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
 
/* USER CODE END Includes */
 
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
 
/* USER CODE END TD */
 
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN Define */
 
/* USER CODE END Define */
 
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN Macro */
 
/* USER CODE END Macro */
 
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
 
/* USER CODE END PFP */
 
/* External functions --------------------------------------------------------*/
/* USER CODE BEGIN ExternalFunctions */
 
/* USER CODE END ExternalFunctions */
 
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
/**
  * Initializes the Global MSP.
  */
void HAL_MspInit(void)
{
  /* USER CODE BEGIN MspInit 0 */
 
  /* USER CODE END MspInit 0 */
 
  __HAL_RCC_AFIO_CLK_ENABLE();
  __HAL_RCC_PWR_CLK_ENABLE();
 
  /* System interrupt init*/
 
  /** NOJTAG: JTAG-DP Disabled and SW-DP Enabled
  */
  __HAL_AFIO_REMAP_SWJ_NOJTAG();
 
  /* USER CODE BEGIN MspInit 1 */
 
  /* USER CODE END MspInit 1 */
}
 
/**
* @brief CAN MSP Initialization
* This function configures the hardware resources used in this example
* @param hcan: CAN handle pointer
* @retval None
*/
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(hcan->Instance==CAN1)
  {
  /* USER CODE BEGIN CAN1_MspInit 0 */
 
  /* USER CODE END CAN1_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_CAN1_CLK_ENABLE();
 
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**CAN GPIO Configuration
    PA11     ------> CAN_RX
    PA12     ------> CAN_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
  /* USER CODE BEGIN CAN1_MspInit 1 */
 
  /* USER CODE END CAN1_MspInit 1 */
  }
 
}
 
/**
* @brief CAN MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hcan: CAN handle pointer
* @retval None
*/
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
{
  if(hcan->Instance==CAN1)
  {
  /* USER CODE BEGIN CAN1_MspDeInit 0 */
 
  /* USER CODE END CAN1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_CAN1_CLK_DISABLE();
 
    /**CAN GPIO Configuration
    PA11     ------> CAN_RX
    PA12     ------> CAN_TX
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
 
  /* USER CODE BEGIN CAN1_MspDeInit 1 */
 
  /* USER CODE END CAN1_MspDeInit 1 */
  }
 
}
 
/* USER CODE BEGIN 1 */
 
/* USER CODE END 1 */

 The error appears as for many others that I have read about here:

  /* Request initialisation */
  SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
 
  /* Get tick */
  tickstart = HAL_GetTick();
 
  /* Wait initialisation acknowledge */
  while ((hcan->Instance->MSR & CAN_MSR_INAK) == 0U)
  {
    if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
    {
      /* Update error code */
      hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
 
      /* Change CAN state */
      hcan->State = HAL_CAN_STATE_ERROR;
 
      return HAL_ERROR;
    }
  }

NikolasZ
Associate II

What am I doing wrong????

gbm
Lead III

No idea on what you are doing wrong, but BluePill has PA11/12 pins connected to USB socket and USB DP line has a strong pullup on it due to USB requirements. Maybe you should remove the USB pull-up resistor for CAN?

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

I will definitely try that. Do you know which of the resistors I should remove?​

Although I still get the same behavior if I select the PB8&PB9 pins for CAN.​

NikolasZ
Associate II

I removed the USB pull-up resistor (R10), but it did not help. I still can't get passed the 11-bit recessive state where CAN_MSR_INAK gets cleared.

I have tried 2 different Bluepill boards with the same (bad) result.

I have even connected 2 sets of boards-transceivers connected with a CAN-bus and 2x 120ohm resistors, in both Normal mode and Silent mode. With the Rx pull-up resistor, no pull-up resistor, switching Rx and Tx-wires. Still the same.

Where in the code can I find the part where it looks for the 11 recessive bits?

STM32F103 Bluepill?

This has been discussed here many times. I would not be surprised if this is also due to the STM32F103 counterfeits that have been used on the Bluepills for a long time, i.e. they are usually not original parts from STMicroelectronics.

There are many websites that have already dealt with this topic, e.g. hackaday.io or eevblog.com.

Regards

/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Watch that the F103 can't do USB and CAN concurrently as they share a RAM buffer and conflict.

AFIO clock needs enabling if pin remapping is used.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I have heard about counterfeit chips. Never crossed my mind though this time, as I bought the boards from a reputable (?) source in Germany ("Bluepill" Development Board Modul mit ARM Cortex M3 Prozessor – AZ-Delivery).

Would they be selling boards with counterfeit chips?

This is the board I have (I have 3 of them).

0693W00000WI26KQAT.jpg0693W00000WI26FQAT.jpg