renode-infrastructure
renode-infrastructure copied to clipboard
Add support for LPC USART TX IDLE IRQ + TX IDLE status flag
This adds support for the LPC USART TX IDLE IRQ and TX IDLE status flag which enables the support for the USART non-blocking API which is part of the standard LPC SDK.
More info is available in the raised github issue: https://github.com/renode/renode/issues/761
Reproduction using the renode-template
It is based on the lpcxpresso55s16 board which is running some zephyr examples using renode: https://designer.antmicro.com/hardware/devices/lpcxpresso55s16?software=zephyr|lpcxpresso55s16| the repo has a binary compiled from the LPC SDK for the usart_interrupt_transfer driver example. It's basically a echo-example using the non-blocking usart API. Whatever we write to the uart, should be printed back to us.
Failing
A failing example with the current LPC_USART C# peripheral can be found here: https://github.com/laurensmiers/renode-issue-reproduction-template/tree/761-lpc-usart-txidle-irq-not-firing
Passing
The passing example uses the updated LPC_USART driver of this PR (copied into the other repo and dynamically included): https://github.com/laurensmiers/renode-issue-reproduction-template/tree/761-lpc-usart-txidle-irq
If more info or changes are required, let me know.
Hi @laurensmiers , thanks for the contribution.
One thing I'm wondering about - should the STATUS.TXIDLE flag also follow the same logic you added to the interrupt status register?
Hi @PiotrZierhoffer ,
Good question, I find the explanation of that register a bit ambiguous. From my understanding from the explanation of the STAT register in the user manual, page 583, table 609:
The STAT register primarily provides a set of USART status flags (not including FIFO
status) for software to read.
...
Transmitter Idle. When 0, indicates that the transmitter is currently in the
process of sending data.When 1, indicate that the transmitter is not currently in
the process of sending data.
If I understand correctly, this register does NOT include FIFO status but is a 'general' status register.
My guess is that this is for the case where the FIFO (or possible DMA) operation is completed, so FIFO is empty, but the actual UART HW is still sending data. If this is true, than it would be '0' for a (very?) small period of time before the UART operation is actually done. I'm unsure how long this period is. On the other hand, since the sending is instant in the emulator, it should be fine to always return 'true' since the operation is technically done. But I'm not sure how this is handled in other peripherals?
I pushed one fix for an issue in a proprietary app which popped up, sometimes the firmware disables the TXIDLE interrupt and just looks at the TXLVL register like the SDK examples. However, sometimes it leaves the TXIDLE interrupt enabled and it wasn't de-asserted properly by the C# peripheral.