|
In this series, I design a programmable lab switch based on RP2040, that can turn a set of signals or supplies on or off. Over USB. SCPI compatible.
|
Understand RP2040 UART and Interrupts
The RP2040 FreeRTOS port doesn't include wrappers for the peripherals. It's not uncommon - a port is good if it supports running the RTOS. Making the peripherals RTOS aware isn't needed. We can do that ourselves.
A few things to consider:
- protect UART resources from multi-task access, where needed
- write tasks for receiving data and incoming traffic interrupt handling. Maybe for sending data?
To do this, I first need to understand how the UARTs of the RP2040 work. There's an excellent example: uart_advanced. The example uses interrupts for both receive and send, but I'm looking for receive only.
Review pico-examples UART interrupt example
Enable RX Interrupt
This is straightforward:
// Turn off FIFO's - we want to do this character by character
uart_set_fifo_enabled(UART_ID, false);
// Set up a RX interrupt
// We need to set up the handler first
// Select correct interrupt for the UART we are using
int UART_IRQ = UART_ID == uart0 ? UART0_IRQ : UART1_IRQ;
// And set up and enable the interrupt handlers
irq_set_exclusive_handler(UART_IRQ, on_uart_rx);
irq_set_enabled(UART_IRQ, true);
// Now enable the UART to send interrupts - RX only
uart_set_irq_enables(UART_ID, true, false);
// OK, all set up.
Single-char is set, and that matches what I'll want to do: I want to shoot each character to the SCPI library later.
Then, the interrupt is registered and activated.
Handle RX Interrupt
Again simple:
// RX interrupt handler
void on_uart_rx() {
while (uart_is_readable(UART_ID)) {
uint8_t ch = uart_getc(UART_ID);
// TODO: handle
}
}
The handle retrieves any available character from the UART. I haven't reviewed RP2040 SDK in depth, but it seems you don't have to clear the interrupt ...
Port to FreeRTOS
This will not be hard to translate to RTOS:
- make the "UART read task" wait on a direct task message
- in the "UART RX interrupt handler", notify the read task, so that it wakes up.
- in the "UART read task", get the character from UART, send it to the business logic (SCPI parser),
- go back to start
In the next blog, I'll implement most of this. The business logic will not be there yet. I'll toggle the LED whenever you type a 'b' character ...
