cancel
Showing results for 
Search instead for 
Did you mean: 

LIN BUS non blocking HAL_LIN_SendBreak?

JBond.1
Senior

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
}
1 ACCEPTED SOLUTION

Accepted Solutions
Andrew Neil
Super User

@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.

View solution in original post

2 REPLIES 2
Andrew Neil
Super User

@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.

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