v2.0.0
uart.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _HARDWARE_UART_H
8#define _HARDWARE_UART_H
9
10#include "pico.h"
11#include "hardware/structs/uart.h"
12
13// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_HARDWARE_UART, Enable/disable assertions in the hardware_uart module, type=bool, default=0, group=hardware_uart
14#ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_UART
15#ifdef PARAM_ASSERTIONS_ENABLED_UART // backwards compatibility with SDK < 2.0.0
16#define PARAM_ASSERTIONS_ENABLED_HARDWARE_UART PARAM_ASSERTIONS_ENABLED_UART
17#else
18#define PARAM_ASSERTIONS_ENABLED_HARDWARE_UART 0
19#endif
20#endif
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26// PICO_CONFIG: PICO_UART_ENABLE_CRLF_SUPPORT, Enable/disable CR/LF translation support, type=bool, default=1, group=hardware_uart
27#ifndef PICO_UART_ENABLE_CRLF_SUPPORT
28#define PICO_UART_ENABLE_CRLF_SUPPORT 1
29#endif
30
31// PICO_CONFIG: PICO_UART_DEFAULT_CRLF, Enable/disable CR/LF translation on UART, type=bool, default=0, depends=PICO_UART_ENABLE_CRLF_SUPPORT, group=hardware_uart
32#ifndef PICO_UART_DEFAULT_CRLF
33#define PICO_UART_DEFAULT_CRLF 0
34#endif
35
36// PICO_CONFIG: PICO_DEFAULT_UART, Define the default UART used for printf etc, min=0, max=1, default=Usually provided via board header, group=hardware_uart
37// PICO_CONFIG: PICO_DEFAULT_UART_TX_PIN, Define the default UART TX pin, min=0, max=29, default=Usually provided via board header, group=hardware_uart
38// PICO_CONFIG: PICO_DEFAULT_UART_RX_PIN, Define the default UART RX pin, min=0, max=29, default=Usually provided via board header, group=hardware_uart
39
40// PICO_CONFIG: PICO_DEFAULT_UART_BAUD_RATE, Define the default UART baudrate, max=921600, default=115200, group=hardware_uart
41#ifndef PICO_DEFAULT_UART_BAUD_RATE
42#define PICO_DEFAULT_UART_BAUD_RATE 115200
43#endif
44
76// Currently always a pointer to hw but it might not be in the future
77typedef struct uart_inst uart_inst_t;
78
86#define uart0 ((uart_inst_t *)uart0_hw)
87#define uart1 ((uart_inst_t *)uart1_hw)
88
97#if !defined(PICO_DEFAULT_UART_INSTANCE) && defined(PICO_DEFAULT_UART)
98#define PICO_DEFAULT_UART_INSTANCE() (__CONCAT(uart,PICO_DEFAULT_UART))
99#endif
100
108#ifdef PICO_DEFAULT_UART_INSTANCE
109#define uart_default PICO_DEFAULT_UART_INSTANCE()
110#endif
111
120#ifndef UART_NUM
121static_assert(NUM_UARTS == 2, "");
122#define UART_NUM(uart) ((uart) == uart1)
123#endif
124
133#ifndef UART_INSTANCE
134static_assert(NUM_UARTS == 2, "");
135#define UART_INSTANCE(num) ((num) ? uart1 : uart0)
136#endif
137
147#ifndef UART_DREQ_NUM
148#include "hardware/regs/dreq.h"
149static_assert(DREQ_UART0_RX == DREQ_UART0_TX + 1, "");
150static_assert(DREQ_UART1_RX == DREQ_UART1_TX + 1, "");
151static_assert(DREQ_UART1_TX == DREQ_UART0_TX + 2, "");
152#define UART_DREQ_NUM(uart, is_tx) ({ \
153 DREQ_UART0_TX + UART_NUM(uart) * 2 + !(is_tx); \
154})
155#endif
156
165#ifndef UART_CLOCK_NUM
166#define UART_CLOCK_NUM(uart) clk_peri
167#endif
168
177#ifndef UART_FUNCSEL_NUM
178#if PICO_RP2040
179#define UART_FUNCSEL_NUM(uart, gpio) GPIO_FUNC_UART
180#else
181#define UART_FUNCSEL_NUM(uart, gpio) ((gpio) & 0x2 ? GPIO_FUNC_UART_AUX : GPIO_FUNC_UART)
182#endif
183#endif
184
193#ifndef UART_IRQ_NUM
194#include "hardware/regs/intctrl.h"
195static_assert(UART1_IRQ == UART0_IRQ + 1, "");
196#define UART_IRQ_NUM(uart) (UART0_IRQ + UART_NUM(uart))
197#endif
198
207#ifndef UART_RESET_NUM
208#include "hardware/resets.h"
209#define UART_RESET_NUM(uart) (uart_get_index(uart) ? RESET_UART1 : RESET_UART0)
210#endif
211
218 static inline uint uart_get_index(uart_inst_t *uart) {
219 invalid_params_if(HARDWARE_UART, uart != uart0 && uart != uart1);
220 return UART_NUM(uart);
221}
222
229 static inline uart_inst_t *uart_get_instance(uint num) {
230 invalid_params_if(HARDWARE_UART, num >= NUM_UARTS);
231 return UART_INSTANCE(num);
232}
233
243 static inline uart_hw_t *uart_get_hw(uart_inst_t *uart) {
244 uart_get_index(uart); // check it is a hw uart
245 return (uart_hw_t *)uart;
246}
247
251 typedef enum {
252 UART_PARITY_NONE,
253 UART_PARITY_EVEN,
254 UART_PARITY_ODD
255} uart_parity_t;
256
257// ----------------------------------------------------------------------------
258// Setup
259
280uint uart_init(uart_inst_t *uart, uint baudrate);
281
290void uart_deinit(uart_inst_t *uart);
291
312uint uart_set_baudrate(uart_inst_t *uart, uint baudrate);
313
321 static inline void uart_set_hw_flow(uart_inst_t *uart, bool cts, bool rts) {
322 hw_write_masked(&uart_get_hw(uart)->cr,
323 (bool_to_bit(cts) << UART_UARTCR_CTSEN_LSB) | (bool_to_bit(rts) << UART_UARTCR_RTSEN_LSB),
324 UART_UARTCR_RTSEN_BITS | UART_UARTCR_CTSEN_BITS);
325}
326
348void uart_set_format(uart_inst_t *uart, uint data_bits, uint stop_bits, uart_parity_t parity);
349
360 static inline void uart_set_irqs_enabled(uart_inst_t *uart, bool rx_has_data, bool tx_needs_data) {
361 // Both UARTRXINTR (RX) and UARTRTINTR (RX timeout) interrupts are
362 // required for rx_has_data. RX asserts when >=4 characters are in the RX
363 // FIFO (for RXIFLSEL=0). RT asserts when there are >=1 characters and no
364 // more have been received for 32 bit periods.
365 uart_get_hw(uart)->imsc = (bool_to_bit(tx_needs_data) << UART_UARTIMSC_TXIM_LSB) |
366 (bool_to_bit(rx_has_data) << UART_UARTIMSC_RXIM_LSB) |
367 (bool_to_bit(rx_has_data) << UART_UARTIMSC_RTIM_LSB);
368 if (rx_has_data) {
369 // Set minimum threshold
370 hw_write_masked(&uart_get_hw(uart)->ifls, 0 << UART_UARTIFLS_RXIFLSEL_LSB,
371 UART_UARTIFLS_RXIFLSEL_BITS);
372 }
373 if (tx_needs_data) {
374 // Set maximum threshold
375 hw_write_masked(&uart_get_hw(uart)->ifls, 0 << UART_UARTIFLS_TXIFLSEL_LSB,
376 UART_UARTIFLS_TXIFLSEL_BITS);
377 }
378}
379
380// backwards compatibility with SDK version < 2.0.0
381static inline void uart_set_irq_enables(uart_inst_t *uart, bool rx_has_data, bool tx_needs_data) {
382 uart_set_irqs_enabled(uart, rx_has_data, tx_needs_data);
383}
384
391 static inline bool uart_is_enabled(uart_inst_t *uart) {
392 return uart_get_hw(uart)->cr & UART_UARTCR_UARTEN_BITS;
393}
394
411void uart_set_fifo_enabled(uart_inst_t *uart, bool enabled);
412
413// ----------------------------------------------------------------------------
414// Generic input/output
415
422 static inline bool uart_is_writable(uart_inst_t *uart) {
423 return !(uart_get_hw(uart)->fr & UART_UARTFR_TXFF_BITS);
424}
425
431 static inline void uart_tx_wait_blocking(uart_inst_t *uart) {
432 while (uart_get_hw(uart)->fr & UART_UARTFR_BUSY_BITS) tight_loop_contents();
433}
434
442 static inline bool uart_is_readable(uart_inst_t *uart) {
443 // PL011 doesn't expose levels directly, so return values are only 0 or 1
444 return !(uart_get_hw(uart)->fr & UART_UARTFR_RXFE_BITS);
445}
446
459 static inline void uart_write_blocking(uart_inst_t *uart, const uint8_t *src, size_t len) {
460 for (size_t i = 0; i < len; ++i) {
461 while (!uart_is_writable(uart))
462 tight_loop_contents();
463 uart_get_hw(uart)->dr = *src++;
464 }
465}
466
476 static inline void uart_read_blocking(uart_inst_t *uart, uint8_t *dst, size_t len) {
477 for (size_t i = 0; i < len; ++i) {
478 while (!uart_is_readable(uart))
479 tight_loop_contents();
480 *dst++ = (uint8_t) uart_get_hw(uart)->dr;
481 }
482}
483
484// ----------------------------------------------------------------------------
485// UART-specific operations and aliases
486
495 static inline void uart_putc_raw(uart_inst_t *uart, char c) {
496 uart_write_blocking(uart, (const uint8_t *) &c, 1);
497}
498
507 static inline void uart_putc(uart_inst_t *uart, char c) {
508#if PICO_UART_ENABLE_CRLF_SUPPORT
509 extern short uart_char_to_line_feed[NUM_UARTS];
510 if (uart_char_to_line_feed[uart_get_index(uart)] == c)
511 uart_putc_raw(uart, '\r');
512#endif
513 uart_putc_raw(uart, c);
514}
515
524 static inline void uart_puts(uart_inst_t *uart, const char *s) {
525#if PICO_UART_ENABLE_CRLF_SUPPORT
526 bool last_was_cr = false;
527 while (*s) {
528 // Don't add extra carriage returns if one is present
529 if (last_was_cr)
530 uart_putc_raw(uart, *s);
531 else
532 uart_putc(uart, *s);
533 last_was_cr = *s++ == '\r';
534 }
535#else
536 while (*s)
537 uart_putc(uart, *s++);
538#endif
539}
540
549 static inline char uart_getc(uart_inst_t *uart) {
550 char c;
551 uart_read_blocking(uart, (uint8_t *) &c, 1);
552 return c;
553}
554
561void uart_set_break(uart_inst_t *uart, bool en);
562
569void uart_set_translate_crlf(uart_inst_t *uart, bool translate);
570
574 static inline void uart_default_tx_wait_blocking(void) {
575#ifdef uart_default
576 uart_tx_wait_blocking(uart_default);
577#else
578 assert(false);
579#endif
580}
581
589bool uart_is_readable_within_us(uart_inst_t *uart, uint32_t us);
590
597 static inline uint uart_get_dreq_num(uart_inst_t *uart, bool is_tx) {
598 return UART_DREQ_NUM(uart, is_tx);
599}
600
607 static inline uint uart_get_reset_num(uart_inst_t *uart) {
608 return UART_RESET_NUM(uart);
609}
610
611// backwards compatibility
612static inline uint uart_get_dreq(uart_inst_t *uart, bool is_tx) {
613 return uart_get_dreq_num(uart, is_tx);
614}
615
616#ifdef __cplusplus
617}
618#endif
619
620#endif
hw_write_masked
static __force_inline void hw_write_masked(io_rw_32 *addr, uint32_t values, uint32_t write_mask)
Set new values for a sub-set of the bits in a HW register.
Definition: address_mapped.h:171
DREQ_UART0_RX
@ DREQ_UART0_RX
Select UART0's RX FIFO as DREQ.
Definition: dreq.h:111
DREQ_UART0_TX
@ DREQ_UART0_TX
Select UART0's TX FIFO as DREQ.
Definition: dreq.h:110
DREQ_UART1_TX
@ DREQ_UART1_TX
Select UART1's TX FIFO as DREQ.
Definition: dreq.h:112
DREQ_UART1_RX
@ DREQ_UART1_RX
Select UART1's RX FIFO as DREQ.
Definition: dreq.h:113
UART1_IRQ
@ UART1_IRQ
Select UART1's IRQ output.
Definition: intctrl.h:108
UART0_IRQ
@ UART0_IRQ
Select UART0's IRQ output.
Definition: intctrl.h:107
uart_is_readable_within_us
bool uart_is_readable_within_us(uart_inst_t *uart, uint32_t us)
Wait for up to a certain number of microseconds for the RX FIFO to be non empty.
Definition: uart.c:229
uart_get_index
static uint uart_get_index(uart_inst_t *uart)
Convert UART instance to hardware instance number.
Definition: uart.h:218
uart_get_reset_num
static uint uart_get_reset_num(uart_inst_t *uart)
Return the reset_num_t to use for pacing transfers to/from a particular UART instance.
Definition: uart.h:607
uart_set_format
void uart_set_format(uart_inst_t *uart, uint data_bits, uint stop_bits, uart_parity_t parity)
Set UART data format.
Definition: uart.c:183
UART_DREQ_NUM
#define UART_DREQ_NUM(uart, is_tx)
Returns the dreq_num_t used for pacing DMA transfers to or from this UART instance....
Definition: uart.h:152
UART_NUM
#define UART_NUM(uart)
Returns the UART number for a UART instance.
Definition: uart.h:122
uart_set_irqs_enabled
static void uart_set_irqs_enabled(uart_inst_t *uart, bool rx_has_data, bool tx_needs_data)
Enable/Disable UART interrupt outputs.
Definition: uart.h:360
uart_putc
static void uart_putc(uart_inst_t *uart, char c)
Write single character to UART for transmission, with optional CR/LF conversions.
Definition: uart.h:507
uart_get_hw
static uart_hw_t * uart_get_hw(uart_inst_t *uart)
Get the real hardware UART instance from a UART instance.
Definition: uart.h:243
uart_is_readable
static bool uart_is_readable(uart_inst_t *uart)
Determine whether data is waiting in the RX FIFO.
Definition: uart.h:442
uart0
#define uart0
Identifier for UART instance 0.
Definition: uart.h:86
uart_set_translate_crlf
void uart_set_translate_crlf(uart_inst_t *uart, bool translate)
Set CR/LF conversion on UART.
Definition: uart.c:221
uart_set_hw_flow
static void uart_set_hw_flow(uart_inst_t *uart, bool cts, bool rts)
Set UART flow control CTS/RTS.
Definition: uart.h:321
uart_init
uint uart_init(uart_inst_t *uart, uint baudrate)
Initialise a UART.
Definition: uart.c:42
uart_is_enabled
static bool uart_is_enabled(uart_inst_t *uart)
Test if specific UART is enabled.
Definition: uart.h:391
uart_putc_raw
static void uart_putc_raw(uart_inst_t *uart, char c)
Write single character to UART for transmission.
Definition: uart.h:495
uart_getc
static char uart_getc(uart_inst_t *uart)
Read a single character from the UART.
Definition: uart.h:549
uart_parity_t
uart_parity_t
UART Parity enumeration.
Definition: uart.h:251
uart_deinit
void uart_deinit(uart_inst_t *uart)
DeInitialise a UART.
Definition: uart.c:95
uart_puts
static void uart_puts(uart_inst_t *uart, const char *s)
Write string to UART for transmission, doing any CR/LF conversions.
Definition: uart.h:524
uart_is_writable
static bool uart_is_writable(uart_inst_t *uart)
Determine if space is available in the TX FIFO.
Definition: uart.h:422
uart_default_tx_wait_blocking
static void uart_default_tx_wait_blocking(void)
Wait for the default UART's TX FIFO to be drained.
Definition: uart.h:574
uart_set_baudrate
uint uart_set_baudrate(uart_inst_t *uart, uint baudrate)
Set UART baud rate.
Definition: uart.c:155
uart_set_fifo_enabled
void uart_set_fifo_enabled(uart_inst_t *uart, bool enabled)
Enable/Disable the FIFOs on specified UART.
Definition: uart.c:199
uart1
#define uart1
Identifier for UART instance 1.
Definition: uart.h:87
uart_write_blocking
static void uart_write_blocking(uart_inst_t *uart, const uint8_t *src, size_t len)
Write to the UART for transmission.
Definition: uart.h:459
UART_INSTANCE
#define UART_INSTANCE(num)
Returns the UART instance with the given UART number.
Definition: uart.h:135
uart_set_break
void uart_set_break(uart_inst_t *uart, bool en)
Assert a break condition on the UART transmission.
Definition: uart.c:210
uart_read_blocking
static void uart_read_blocking(uart_inst_t *uart, uint8_t *dst, size_t len)
Read from the UART.
Definition: uart.h:476
uart_get_dreq_num
static uint uart_get_dreq_num(uart_inst_t *uart, bool is_tx)
Return the dreq_num_t to use for pacing transfers to/from a particular UART instance.
Definition: uart.h:597
uart_get_instance
static uart_inst_t * uart_get_instance(uint num)
Get the UART instance from an instance number.
Definition: uart.h:229
uart_tx_wait_blocking
static void uart_tx_wait_blocking(uart_inst_t *uart)
Wait for the UART TX fifo to be drained.
Definition: uart.h:431
UART_RESET_NUM
#define UART_RESET_NUM(uart)
Returns the reset_num_t used to reset a given UART instance.
Definition: uart.h:209
tight_loop_contents
static __force_inline void tight_loop_contents(void)
No-op function for the body of tight loops.
Definition: platform.h:67
pico.h
resets.h
uart_hw_t
Definition: uart.h:26