2022-03-01 12:56 PM
NUCLEO-H723ZG dev. kit.
I need take over the full control of the USARTx. I need a TX interrupt and the RX interrupt handled manually independently the HAL_UART_*** functions. The HAL_UART_Receive_IT() and the HAL_UART_Transmit_IT() is useless for me.
During initialization I need to enable the receiver. When one byte is received then I need an interrupt and I will store the received bytes in the RXBuffer. The main() loop periodically checks the received bytes. If it finds a complete message in the RXBuffer[] then it processes the message, then creates the answer into the TXBuffer[], enables the TX interrupt and sends back answer.
To do this I need a TX interrupt when the TX buffer becomes empty. I simply send the next byte. When I get the TX buffer empty interrupt and I have no more bytes to send I disable the TX interrupt, clear the RXBuffer and re-enable the RX interrupt.
I am sure it is possible to do with STM32H723ZG MCU but I could not find such an example. How can I do this? Thanks for your help.
Louis
Solved! Go to Solution.
2022-03-01 03:31 PM
At a register level the Reference Manual has the detail, the source to the libraries is also available.
For the L0 for example I have this
void USART2_IRQHandler(void)
{
uint32_t isr = USART2->ISR;
if (isr & USART_ISR_RXNE) // Received character?
{
uint16_t Data = USART2->RDR;
Fifo_Insert(FifoIn2, 1, (void *)&Data);
}
if (isr & (USART_ISR_ORE | USART_ISR_NE | USART_ISR_FE)) // Pending Errors
{
if (isr & USART_ISR_ORE)
USART2->ICR = USART_ICR_ORECF;
if (isr & USART_ISR_NE)
USART2->ICR = USART_ICR_NCF;
if (isr & USART_ISR_FE)
USART2->ICR = USART_ICR_FECF;
}
if (isr & USART_ISR_TXE) // Transmit empty
{
uint32_t Used = Fifo_Used(FifoOut2);
if (Used)
{
uint16_t Data = 0;
if (Fifo_Extract(FifoOut2, 1, (void *)&Data))
USART2->TDR = Data;
if (Used > 1)
USART2->CR1 |= USART_CR1_TXEIE;
else
USART2->CR1 &= ~USART_CR1_TXEIE; // Disable as empty
}
else
USART2->CR1 &= ~USART_CR1_TXEIE; // Disable as empty
}
}
When pushing data into the output FIFO you enable the TXE interrupt, and it will fire immediately. You disable it so it doesn't saturate/loop with interrupts when there's not data available to push into the TDR
2022-03-01 03:31 PM
At a register level the Reference Manual has the detail, the source to the libraries is also available.
For the L0 for example I have this
void USART2_IRQHandler(void)
{
uint32_t isr = USART2->ISR;
if (isr & USART_ISR_RXNE) // Received character?
{
uint16_t Data = USART2->RDR;
Fifo_Insert(FifoIn2, 1, (void *)&Data);
}
if (isr & (USART_ISR_ORE | USART_ISR_NE | USART_ISR_FE)) // Pending Errors
{
if (isr & USART_ISR_ORE)
USART2->ICR = USART_ICR_ORECF;
if (isr & USART_ISR_NE)
USART2->ICR = USART_ICR_NCF;
if (isr & USART_ISR_FE)
USART2->ICR = USART_ICR_FECF;
}
if (isr & USART_ISR_TXE) // Transmit empty
{
uint32_t Used = Fifo_Used(FifoOut2);
if (Used)
{
uint16_t Data = 0;
if (Fifo_Extract(FifoOut2, 1, (void *)&Data))
USART2->TDR = Data;
if (Used > 1)
USART2->CR1 |= USART_CR1_TXEIE;
else
USART2->CR1 &= ~USART_CR1_TXEIE; // Disable as empty
}
else
USART2->CR1 &= ~USART_CR1_TXEIE; // Disable as empty
}
}
When pushing data into the output FIFO you enable the TXE interrupt, and it will fire immediately. You disable it so it doesn't saturate/loop with interrupts when there's not data available to push into the TDR
2022-03-02 10:27 AM
Dear Tesla DeLorean,
Excellent, thank you!
Best regards,
Louis