title: STM32 CAN loop back mode
body: <p>I am starting a basic use of HAL drivers for loop back mode of CAN peripheral in STM32F103xx MCU. Base on the user manual of the MCU, when the transmission is fully accomplished and the data becomes available in the CAN bus, TME, RQCP and TXOK bits of the CAN_TSR Register are set by the hardware showing that the corresponding mail box has become empty and the transmission is done successfully.</p>
  
  <p>When I debug the following program, none of the mentioned changes happen in the CAN_TSR register. I can only see that the TME bit gets set that means a mail box is provided for transmission but never transmitted. </p>
  
  <p>This piece of my code causes an infinitive loop in the program:</p>
  
  <pre><code>while(HAL_CAN_IsTxMessagePending(&amp;hcan, TxMailbox));
  </code></pre>
  
  <p>Could you please explain me what is my problem and what I should do. Thanks for your ideas.</p>
  
  <p>This is the full code:</p>
  
  <pre><code>#include "main.h"
  CAN_HandleTypeDef hcan;
  
  void SystemClock_Config(void);
  static void MX_GPIO_Init(void);
  static void MX_CAN_Init(void);
  
  /* USER CODE BEGIN PFP */
  void Can_TX(void);
  /* USER CODE END PFP */
  
  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();
  
    /* USER CODE BEGIN 2 */
    LCD1602_Begin4BIT(RS_GPIO_Port, RS_Pin, E_Pin, D4_GPIO_Port, D4_Pin, D5_Pin, D6_Pin, D7_Pin);
    LCD1602_print("Sending...");
    Can_TX();
    /* USER CODE END 2 */
  
    /* Infinite loop */
    while (1)
    {
      for (int i = 0; i &lt;= 1000; i++);
    }
  }
  
  void SystemClock_Config(void)
  {
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
    if (HAL_RCC_OscConfig(&amp;RCC_OscInitStruct) != HAL_OK)
    {
      Error_Handler();
    }
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    if (HAL_RCC_ClockConfig(&amp;RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
    {
      Error_Handler();
    }
  }
  
  static void MX_CAN_Init(void)
  {
    hcan.Instance = CAN1;
    hcan.Init.Prescaler = 1;
    hcan.Init.Mode = CAN_MODE_LOOPBACK;
    hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
    hcan.Init.TimeSeg1 = CAN_BS1_13TQ;
    hcan.Init.TimeSeg2 = CAN_BS2_2TQ;
    hcan.Init.TimeTriggeredMode = DISABLE;
    hcan.Init.AutoBusOff = DISABLE;
    hcan.Init.AutoWakeUp = DISABLE;
    hcan.Init.AutoRetransmission = ENABLE;
    hcan.Init.ReceiveFifoLocked = DISABLE;
    hcan.Init.TransmitFifoPriority = DISABLE;
    if (HAL_CAN_Init(&amp;hcan) != HAL_OK)
    {
      Error_Handler();
    }
  }
  
  static void MX_GPIO_Init(void)
  {
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    __HAL_RCC_GPIOA_CLK_ENABLE();
    HAL_GPIO_WritePin(GPIOA, RS_Pin|E_Pin|D4_Pin|D5_Pin|D6_Pin|D7_Pin, GPIO_PIN_RESET);
    GPIO_InitStruct.Pin = RS_Pin|E_Pin|D4_Pin|D5_Pin|D6_Pin|D7_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &amp;GPIO_InitStruct);
  }
  
  void Can_TX(void)
  {
    CAN_TxHeaderTypeDef TxHeader;
    uint8_t our_message[5] = {'H','E','L','L','O'};
    uint32_t TxMailbox;
    TxHeader.DLC = 1;
    TxHeader.StdId = 0x65D;
    TxHeader.IDE = CAN_ID_STD;
    TxHeader.RTR = CAN_RTR_DATA;
    HAL_CAN_AddTxMessage(&amp;hcan, &amp;TxHeader, our_message, &amp;TxMailbox);
    if(HAL_CAN_AddTxMessage(&amp;hcan, &amp;TxHeader, our_message, &amp;TxMailbox) != HAL_OK)
    {
      Error_Handler();
    }
    while(HAL_CAN_IsTxMessagePending(&amp;hcan, TxMailbox));
    LCD1602_print("Message is sent");
  }
  
  void Error_Handler(void) { }
  </code></pre>