samd: fix UART IRQ events#19215
Conversation
The UART DRE flag is always set if the DATA register is empty. That would lead to a TXIDLE event each time the IRQ handler was run. To fix that, only fire the TXIDLE event if the DRE interrupt flag is enabled. Partially fixes the `tests/extmod/machine_uart_irq_txidle.py` test on `ADAFRUIT_ITSYBITSY_M0_EXPRESS`. Signed-off-by: Damien George <damien@micropython.org>
The C IRQ handler can be called with multiple IRQ flags active, eg both RXC and DRE set. But the Python IRQ handler should only see the events that it registered. So mask the flags as appropriate. Combined with the parent commit, `tests/extmod/machine_uart_irq_txidle.py` now passes on `ADAFRUIT_ITSYBITSY_M0_EXPRESS`. Signed-off-by: Damien George <damien@micropython.org>
|
Code size report: |
| // The handler for RXIDLE is called in the timer callback | ||
| if (self->mp_irq_trigger & mp_irq_flags) { | ||
| self->mp_irq_flags = mp_irq_flags; | ||
| self->mp_irq_flags = self->mp_irq_trigger & mp_irq_flags; |
| ringbuf_get(&self->write_buffer) | (ringbuf_get(&self->write_buffer) << 8); | ||
| } | ||
| } else { | ||
| } else if (uart->USART.INTENCLR.bit.DRE != 0) { |
There was a problem hiding this comment.
Confirmed that this bit is static and therefore the code path after line 160 is executed even if UART TX IRQ is not enabled. That causes the SERCOM_USART_INTFLAG_TXC to be set. However, with the masking in line 187 this has no effect.
If UART_TX IRQ is enabled, the code path below line 170 would be executed.
So this change seems to save executing 2 statements at the cost of an additional compare.
There was a problem hiding this comment.
Without this change tests/extmod/machine_uart_irq_txidle.py would fail because two IRQ_TXIDLE events would be fired instead of just one.
There was a problem hiding this comment.
That is reasonable. Otherwise the handler would be again at every RX IRQ event again. Verified that w/o the change the machine_uart_irq_txidle.py test fails.
There was a problem hiding this comment.
Otherwise the handler would be again at every RX IRQ event again.
Yes, exactly. If any IRQ comes in to this function and DATA is empty then DRE is set and so it previously would fire a TXIDLE interrupt to the Python handler.
Summary
This PR fixes two related issues with UART Python IRQ events:
Testing
tests/extmod/machine_uart_irq_txidle.pynow passes onADAFRUIT_ITSYBITSY_M0_EXPRESSThere are no regressions to other tests.
Generative AI
I did not use generative AI tools when creating this PR.