2014-09-11 08:54 AM
Im using STM32Cube_FW_L0_V1.1.0 on a STM32L052C8T6
Why there is some loops into TX and RX IT functions? For example: inUART_Receive_IT()
At the end of the reception there is:while(HAL_IS_BIT_SET(huart->Instance->ISR, UART_FLAG_RXNE))
{
} and in
UART_Transmit_IT()
at the end of the sending there is a call to:UART_WaitOnFlagUntilTimeout().
which is a blocking function It is very dangerous to have such loop in a IRQ handler it can cause an overrun or worst. For example when the last Byte is transmit you can't receive any byte without having an overrun because the IT handler is waiting for the TX Byte to be transmit :( Is it done on purpose or have you an explanation for this? Gwendal #rtfm #stm32cube-stm32l0xx2014-09-11 12:06 PM
''It is very dangerous to have such loop in a IRQ handler''
Yes, but these arenot
Interrupt handlers!2014-09-12 12:37 AM
Before answer to quickly you must read twice my question:
I'm not talking aboutHAL_UART_Transmit_IT() which
is not an IRQ handler, butUART_Transmit_IT()
which is called byHAL_UART_IRQHandler()
-> IRQ handler. Documentation for this function: /** * @brief Send an amount of data in interrupt mode *Function called under interruption only,
once * interruptions have been enabled by HAL_UART_Transmit_IT() * @param huart: UART handle * @retval HAL status */ (same forUART_Receive_IT()
) So before answer with RTFM please read carefully the question.2014-09-12 10:05 AM
HiGwendal,
We understand that this is a limitationthat some of you are experiencing, and we have it already in the STM32Cube HAL bugs list that will be fixed in next releases of STM32CubeL0. In the meantime, you can find below the UART_Transmit_IT() and UART_Receive_IT() APIs to avoid the waiting loop under IRQ:/**
* @brief Sends an amount of data in non blocking mode.
* @param huart: Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart)
{
uint16_t* tmp;
uint32_t tmp1 = 0;
tmp1 = huart->State;
if((tmp1 == HAL_UART_STATE_BUSY_TX) || (tmp1 == HAL_UART_STATE_BUSY_TX_RX))
{
if(huart->Init.WordLength == UART_WORDLENGTH_9B)
{
tmp = (uint16_t*) huart->pTxBuffPtr;
huart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
if(huart->Init.Parity == UART_PARITY_NONE)
{
huart->pTxBuffPtr += 2;
}
else
{
huart->pTxBuffPtr += 1;
}
}
else
{
huart->Instance->DR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0x00FF);
}
if(--huart->TxXferCount == 0)
{
/* Disable the UART Transmit Complete Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
/* Enable the UART Transmit Complete Interrupt */
__HAL_UART_ENABLE_IT(huart, UART_IT_TC);
}
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
/**
* @brief Wraps up transmission in non blocking mode.
* @param huart: pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart)
{
/* Disable the UART Transmit Complete Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_TC);
/* Check if a receive process is ongoing or not */
if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
{
huart->State = HAL_UART_STATE_BUSY_RX;
}
else
{
/* Disable the UART Parity Error Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_PE);
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
huart->State = HAL_UART_STATE_READY;
}
HAL_UART_TxCpltCallback(huart);
return HAL_OK;
}
/**
* @brief Receives an amount of data in non blocking mode
* @param huart: Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{
uint16_t* tmp;
uint32_t tmp1 = 0;
tmp1 = huart->State;
if((tmp1 == HAL_UART_STATE_BUSY_RX) || (tmp1 == HAL_UART_STATE_BUSY_TX_RX))
{
if(huart->Init.WordLength == UART_WORDLENGTH_9B)
{
tmp = (uint16_t*) huart->pRxBuffPtr;
if(huart->Init.Parity == UART_PARITY_NONE)
{
*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
huart->pRxBuffPtr += 2;
}
else
{
*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
huart->pRxBuffPtr += 1;
}
}
else
{
if(huart->Init.Parity == UART_PARITY_NONE)
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
}
else
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
}
}
if(--huart->RxXferCount == 0)
{
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
/* Check if a transmit process is ongoing or not */
if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
{
huart->State = HAL_UART_STATE_BUSY_TX;
}
else
{
/* Disable the UART Parity Error Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_PE);
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
huart->State = HAL_UART_STATE_READY;
}
HAL_UART_RxCpltCallback(huart);
return HAL_OK;
}
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
Thanks for the report.Keep an eye out for the next update!
2014-10-27 11:48 PM
trying to check UART_Hyperterminal_IT example provided with HAL. Sometime code loops inside HAL_UART_IRQHandler in UART_Transmit_IT with huart->State as HAL_UART_STATE_READY. Is there any bug with this HAL lib code. Also Can you provide me the pending bug list with HAL.
I am migrating my code from STD lib to HAL and really stuck whether to do it or not.
Chetan2014-10-28 01:19 AM
Hi Chetan,
Please try to write your post in a new discussion.Regards,Heisenberg.