Assembly examples for Red-V Thing Plus (SiFive FE310-G002)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
flabbergast 930b40bef2 Add debugging info into README. 5 months ago
Makefile Add 07-uart0irq. 5 months ago Add 07-uart0irq. 5 months ago
macros.s Add top-of-file comments. 5 months ago
main.s Fix some bugs (write/irq). 5 months ago
memmap Add 07-uart0irq. 5 months ago
p_clock.s Add top-of-file comments. 5 months ago
p_delay.s Add top-of-file comments. 5 months ago
p_interrupts.s Fix some bugs (write/irq). 5 months ago
p_uart0irq.s Add top-of-file comments. 5 months ago Add 07-uart0irq. 5 months ago
write.s Fix some bugs (write/irq). 5 months ago


Flesh out the interrupt handler a bit more - rewrite UART0 into a buffered, interrupt-based version.


The peripheral interrupt handling seems to be somewhat peculiar - when compared with the ones I've had some experience with so far (e.g. ARM or msp430). As mentioned in the previous example, all peripheral irqs go through PLIC. That needs some setup; and it seems relatively configurable (priority levels; claim/complete mechanism). (PLIC registers seem to not be reset to 0 but to a whole bunch of various values...) Every peripheral seems to have just one signal to PLIC - so in the main isr we check if the cause was PLIC; then check if PLIC source was UART0. If yes, call irq_handler_uart0.

So, in that one we need to distinguish between TX and RX interrupts. This is also laid out a little unexpectedly for me. Internally, both tx and rx have 8 byte buffers; the interrupt configuration involves setting "watermark" levels for each. For rx it works as expected: if there are more than rx watermark bytes in the rx buffer, raise an interrupt. The default level of 0 works exactly as on other microcontrollers (with a little more slack because of the 8 byte internal buffer).

For tx, the interrupt-pending flag is set whenever there are strictly fewer bytes in the internal-tx-buffer than tx watermark. So: the default value of 0 means there isn't any tx interrupt ever. But when this is raised to 1, the tx-interrupt-pending flag is pretty much always on, even when tx interrupts themselves are disabled. Since the uart0 isr gets called on both tx and rx irqs, in addition to checking the tx-interrupt-pending flag we also need to check the tx-interrupts-enabled flag. (Another option would be to use tx watermark to effectively disable/enable tx interrupts, keeping the tx-interrupt-enabled flag always on.)

So, all in all, if you do not need large asynchronous uart buffers, or you do not intend to use wfi for waiting, doing interrupt-based uart is not really worth the effort.