Skip to main content
JBond.1
Senior
Jan 3, 2026 9:54 AM UTC
Solved

LIN BUS non blocking HAL_LIN_SendBreak?

Hi, HAL_LIN_SendBreak seems to be blocking CPU, is there a way to bring UART TX pin down then wait for timer and bring it up? I have done it making GPIO pin GPIO_MODE_OUTPUT_PP then back to GPIO_MODE_AF_PP but init after takes long time. I was wondering is it possible to do it within UART without changing pin mode? Or reducing the time pin mode init is required?

 

void LIN_SendFrame_IT(void)
{
 __HAL_UART_DISABLE(&huart2);

 GPIO_InitTypeDef g = {0};
 g.Pin = LIN_TX_Pin;
 g.Mode = GPIO_MODE_OUTPUT_PP;
 g.Speed = GPIO_SPEED_FREQ_HIGH;
 HAL_GPIO_Init(LIN_TX_GPIO_Port, &g);

 HAL_GPIO_WritePin(LIN_TX_GPIO_Port, LIN_TX_Pin, GPIO_PIN_RESET);

 TIM2->ARR = 900; // 900us break
 TIM2->CNT = 0;
 TIM2->CR1 |= TIM_CR1_OPM;
 HAL_TIM_Base_Start_IT(&htim2);
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
 if (htim != &htim2) return;

 HAL_GPIO_WritePin(LIN_TX_GPIO_Port, LIN_TX_Pin, GPIO_PIN_SET);

 GPIO_InitTypeDef g = {0};
 g.Pin = LIN_TX_Pin;
 g.Mode = GPIO_MODE_AF_PP;

 // This takes way too long to retunt to UART
 HAL_GPIO_Init(LIN_TX_GPIO_Port, &g);
 __HAL_UART_ENABLE(&huart2);

 HAL_UART_Transmit_DMA(&huart2, &DATA, 1); //Transmit
}
Andrew Neil
Andrew NeilBest answer
Super User
Jan 3, 2026 10:01 AM UTC

@JBond.1 wrote:

HAL_LIN_SendBreak seems to be blocking CPU

What makes you say that?

The source doesn't seem to suggest it:

/**
 * @brief Transmits break characters.
 * @PAram huart Pointer to a UART_HandleTypeDef structure that contains
 * the configuration information for the specified UART module.
 * @retval HAL status
 */
HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
{
 /* Check the parameters */
 assert_param(IS_UART_INSTANCE(huart->Instance));

 /* Process Locked */
 __HAL_LOCK(huart);

 huart->gState = HAL_UART_STATE_BUSY;

 /* Send break characters */
 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_SBK);

 huart->gState = HAL_UART_STATE_READY;

 /* Process Unlocked */
 __HAL_UNLOCK(huart);

 return HAL_OK;
}

https://github.com/STMicroelectronics/stm32l1xx-hal-driver/blob/master/Src/stm32l1xx_hal_uart.c#L2774

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.

2 replies

Andrew Neil
Andrew NeilBest answer
Super User
Jan 3, 2026 10:01 AM UTC

@JBond.1 wrote:

HAL_LIN_SendBreak seems to be blocking CPU

What makes you say that?

The source doesn't seem to suggest it:

/**
 * @brief Transmits break characters.
 * @PAram huart Pointer to a UART_HandleTypeDef structure that contains
 * the configuration information for the specified UART module.
 * @retval HAL status
 */
HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
{
 /* Check the parameters */
 assert_param(IS_UART_INSTANCE(huart->Instance));

 /* Process Locked */
 __HAL_LOCK(huart);

 huart->gState = HAL_UART_STATE_BUSY;

 /* Send break characters */
 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_SBK);

 huart->gState = HAL_UART_STATE_READY;

 /* Process Unlocked */
 __HAL_UNLOCK(huart);

 return HAL_OK;
}

https://github.com/STMicroelectronics/stm32l1xx-hal-driver/blob/master/Src/stm32l1xx_hal_uart.c#L2774

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
JBond.1
JBond.1Author
Senior
Jan 14, 2026 4:51 PM UTC

Seems to be my bad, looks like its not blocking, which is ok, just maybe wanted longer pause at start than 13 bits