CS 452/652 Winter 2024 - Lecture 11
UART Interrupt Handling
Feb 13, 2024 prev next
BCM - Broadcom BCM2711 data sheet
PLM - PrimeCell UART (PL011) Technical Reference Manual
UART Interrupts
- see BCM, Chap 11
- interrupt sources:
- TX (transmit) - room in the transmit buffer
- RX (receive) - data in the receive buffer
- status change
- error condition
- control interrupts:
- IMSC (Interrupt Mask Set Clear) controls which interrupts are generated
one bit per interrupt: 1 enables interrupt, 0 disables it
- ICR (Interrupt Clear Rgister) clears pending interrupt
one bit per interrupt: 1 clears interrupt
- one interrupt signal at GIC (Interrupt ID = 153)
- logical OR of all interrupts from all UARTs (BCM Page 87)
- configure at GIC (like timer interrupt) - enable and target core
UART Operation
- naive: wait for interrupt → action
- better: wait for interrupt → check status → action → repeat
- best: check status → action or wait for interrupt → repeat
- actual reading/writing is done in user task
- remember possible infinite loop with level interrupt signals...
- default mode for level signal is interrupt disabled
- example: input
- try read; done?
- else enable RX interrupt
- RX interrupt arrives → disable
- repeat
- similar for output
- UART interrupt handling in detail
- read GICC_IAR to find the InterruptID
- if it is the UART interrupt
- read UART MIS register(s) to find out which UART interrupt(s)
- disable interrupt at IMSC
- clear interrupt using UART ICR
- write to GICC_EOIR when finished in kernel (as for the timer interrupt)
- user task eliminates cause of interrupt, if necessary (RX/TX level)
AwaitEvent()
enables level interrupt using IMSC
UART FIFOs
- 32 characters for Tx and 32 for Rx
- can be enabled or disabled (together)
- interrupt "trigger levels" are 1,2,4,6,7/8 full (see UART IFLS register)
- should enable Tx FIFO?
- allows for small bursts of writes
but cannot control when queued writes are sent
- should enable Rx FIFO?
- helps buffer bursts of incoming data
but additional delay on reception (1 byte > 4ms @ 2400 baud)
- timeout interrupt: FIFO non-empty and 32 bit quiet time (see PLM for details)
- recommendation: disable FIFOs for UART3 (Marklin)
- UART Tx interrupt generated when output buffer is empty
but this only tells you that a character has been sent (not processed)
- UART Rx interrupt generated when input buffer is full
Flow Control
- match communication speed to processing speed
- mostly a problem for Marklin, not console
Marklin needs to finish processing previous request before the next request can be sent
- terminal receiver is normally fast enough to handle communication at channel speed
- serial communication provides explicit flow control signal for
- UART's 'TX ready' status only means the communication buffer has room
- Clear-To-Send (CTS) signalled on separate wire when the receiver is able to receive and process the next byte
- available at UART via FR register
- in principle, before sending:
- check TX up (cf. TX interrupt)
- check CTS up (cf. status interrupt)
- in theory, hardware flow control should do that
in practice, Marklin might not de-assert CTS fast enough!
CTS Quirk
- expected order of events and actions is:
TX & CTS up → write → TX & CTS down → wait → TX & CTS up (repeat)
- due to different internal clock rates at ARM board and Marklin controller:
TX & CTS up → write → TX down → TX up PROBLEM → CTS down → CTS up
- i.e., TX might go back up before CTS goes down
- a simple status check might send next command too early
- need state machine (triggered by status interrupts) to track CTS state after each sent byte
- An earlier description by Bill Cowan is available here
Notes
- write test code to verify UART interrupt functionality!
- check error interrupts and conditions?