@web-font-path: "roboto-debian.css";
Loading...
Searching...
No Matches
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#include "hardware/regs/dreq.h"
13
14// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_UART, Enable/disable assertions in the UART module, type=bool, default=0, group=hardware_uart
15#ifndef PARAM_ASSERTIONS_ENABLED_UART
16#define PARAM_ASSERTIONS_ENABLED_UART 0
17#endif
18
19#ifdef __cplusplus
20extern "C" {
21#endif
22
23// PICO_CONFIG: PICO_UART_ENABLE_CRLF_SUPPORT, Enable/disable CR/LF translation support, type=bool, default=1, group=hardware_uart
24#ifndef PICO_UART_ENABLE_CRLF_SUPPORT
25#define PICO_UART_ENABLE_CRLF_SUPPORT 1
26#endif
27
28// 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
29#ifndef PICO_UART_DEFAULT_CRLF
30#define PICO_UART_DEFAULT_CRLF 0
31#endif
32
33// PICO_CONFIG: PICO_DEFAULT_UART, Define the default UART used for printf etc, min=0, max=1, group=hardware_uart
34// PICO_CONFIG: PICO_DEFAULT_UART_TX_PIN, Define the default UART TX pin, min=0, max=29, group=hardware_uart
35// PICO_CONFIG: PICO_DEFAULT_UART_RX_PIN, Define the default UART RX pin, min=0, max=29, group=hardware_uart
36
37// PICO_CONFIG: PICO_DEFAULT_UART_BAUD_RATE, Define the default UART baudrate, max=921600, default=115200, group=hardware_uart
38#ifndef PICO_DEFAULT_UART_BAUD_RATE
39#define PICO_DEFAULT_UART_BAUD_RATE 115200
40#endif
41
71// Currently always a pointer to hw but it might not be in the future
72typedef struct uart_inst uart_inst_t;
73
81#define uart0 ((uart_inst_t *)uart0_hw)
82#define uart1 ((uart_inst_t *)uart1_hw)
83
86#if !defined(PICO_DEFAULT_UART_INSTANCE) && defined(PICO_DEFAULT_UART)
87#define PICO_DEFAULT_UART_INSTANCE (__CONCAT(uart,PICO_DEFAULT_UART))
88#endif
89
90#ifdef PICO_DEFAULT_UART_INSTANCE
91#define uart_default PICO_DEFAULT_UART_INSTANCE
92#endif
93
100static inline uint uart_get_index(uart_inst_t *uart) {
101 invalid_params_if(UART, uart != uart0 && uart != uart1);
102 return uart == uart1 ? 1 : 0;
103}
104
105static inline uart_inst_t *uart_get_instance(uint instance) {
106 static_assert(NUM_UARTS == 2, "");
107 invalid_params_if(UART, instance >= NUM_UARTS);
108 return instance ? uart1 : uart0;
109}
110
111static inline uart_hw_t *uart_get_hw(uart_inst_t *uart) {
112 uart_get_index(uart); // check it is a hw uart
113 return (uart_hw_t *)uart;
114}
115
119typedef enum {
120 UART_PARITY_NONE,
121 UART_PARITY_EVEN,
122 UART_PARITY_ODD
124
125// ----------------------------------------------------------------------------
126// Setup
127
148uint uart_init(uart_inst_t *uart, uint baudrate);
149
158void uart_deinit(uart_inst_t *uart);
159
180uint uart_set_baudrate(uart_inst_t *uart, uint baudrate);
181
189static inline void uart_set_hw_flow(uart_inst_t *uart, bool cts, bool rts) {
190 hw_write_masked(&uart_get_hw(uart)->cr,
191 (bool_to_bit(cts) << UART_UARTCR_CTSEN_LSB) | (bool_to_bit(rts) << UART_UARTCR_RTSEN_LSB),
192 UART_UARTCR_RTSEN_BITS | UART_UARTCR_CTSEN_BITS);
193}
194
216void uart_set_format(uart_inst_t *uart, uint data_bits, uint stop_bits, uart_parity_t parity);
217
228static inline void uart_set_irq_enables(uart_inst_t *uart, bool rx_has_data, bool tx_needs_data) {
229 // Both UARTRXINTR (RX) and UARTRTINTR (RX timeout) interrupts are
230 // required for rx_has_data. RX asserts when >=4 characters are in the RX
231 // FIFO (for RXIFLSEL=0). RT asserts when there are >=1 characters and no
232 // more have been received for 32 bit periods.
233 uart_get_hw(uart)->imsc = (bool_to_bit(tx_needs_data) << UART_UARTIMSC_TXIM_LSB) |
234 (bool_to_bit(rx_has_data) << UART_UARTIMSC_RXIM_LSB) |
235 (bool_to_bit(rx_has_data) << UART_UARTIMSC_RTIM_LSB);
236 if (rx_has_data) {
237 // Set minimum threshold
238 hw_write_masked(&uart_get_hw(uart)->ifls, 0 << UART_UARTIFLS_RXIFLSEL_LSB,
239 UART_UARTIFLS_RXIFLSEL_BITS);
240 }
241 if (tx_needs_data) {
242 // Set maximum threshold
243 hw_write_masked(&uart_get_hw(uart)->ifls, 0 << UART_UARTIFLS_TXIFLSEL_LSB,
244 UART_UARTIFLS_TXIFLSEL_BITS);
245 }
246}
247
254static inline bool uart_is_enabled(uart_inst_t *uart) {
255 return !!(uart_get_hw(uart)->cr & UART_UARTCR_UARTEN_BITS);
256}
257
274void uart_set_fifo_enabled(uart_inst_t *uart, bool enabled);
275
276// ----------------------------------------------------------------------------
277// Generic input/output
278
285static inline bool uart_is_writable(uart_inst_t *uart) {
286 return !(uart_get_hw(uart)->fr & UART_UARTFR_TXFF_BITS);
287}
288
294static inline void uart_tx_wait_blocking(uart_inst_t *uart) {
295 while (uart_get_hw(uart)->fr & UART_UARTFR_BUSY_BITS) tight_loop_contents();
296}
297
305static inline bool uart_is_readable(uart_inst_t *uart) {
306 // PL011 doesn't expose levels directly, so return values are only 0 or 1
307 return !(uart_get_hw(uart)->fr & UART_UARTFR_RXFE_BITS);
308}
309
319static inline void uart_write_blocking(uart_inst_t *uart, const uint8_t *src, size_t len) {
320 for (size_t i = 0; i < len; ++i) {
321 while (!uart_is_writable(uart))
323 uart_get_hw(uart)->dr = *src++;
324 }
325}
326
336static inline void uart_read_blocking(uart_inst_t *uart, uint8_t *dst, size_t len) {
337 for (size_t i = 0; i < len; ++i) {
338 while (!uart_is_readable(uart))
340 *dst++ = (uint8_t) uart_get_hw(uart)->dr;
341 }
342}
343
344// ----------------------------------------------------------------------------
345// UART-specific operations and aliases
346
355static inline void uart_putc_raw(uart_inst_t *uart, char c) {
356 uart_write_blocking(uart, (const uint8_t *) &c, 1);
357}
358
367static inline void uart_putc(uart_inst_t *uart, char c) {
368#if PICO_UART_ENABLE_CRLF_SUPPORT
369 extern short uart_char_to_line_feed[NUM_UARTS];
370 if (uart_char_to_line_feed[uart_get_index(uart)] == c)
371 uart_putc_raw(uart, '\r');
372#endif
373 uart_putc_raw(uart, c);
374}
375
384static inline void uart_puts(uart_inst_t *uart, const char *s) {
385#if PICO_UART_ENABLE_CRLF_SUPPORT
386 bool last_was_cr = false;
387 while (*s) {
388 // Don't add extra carriage returns if one is present
389 if (last_was_cr)
390 uart_putc_raw(uart, *s);
391 else
392 uart_putc(uart, *s);
393 last_was_cr = *s++ == '\r';
394 }
395#else
396 while (*s)
397 uart_putc(uart, *s++);
398#endif
399}
400
409static inline char uart_getc(uart_inst_t *uart) {
410 char c;
411 uart_read_blocking(uart, (uint8_t *) &c, 1);
412 return c;
413}
414
421void uart_set_break(uart_inst_t *uart, bool en);
422
429void uart_set_translate_crlf(uart_inst_t *uart, bool translate);
430
434static inline void uart_default_tx_wait_blocking(void) {
435#ifdef uart_default
436 uart_tx_wait_blocking(uart_default);
437#else
438 assert(false);
439#endif
440}
441
449bool uart_is_readable_within_us(uart_inst_t *uart, uint32_t us);
450
457static inline uint uart_get_dreq(uart_inst_t *uart, bool is_tx) {
458 static_assert(DREQ_UART0_RX == DREQ_UART0_TX + 1, "");
459 static_assert(DREQ_UART1_RX == DREQ_UART1_TX + 1, "");
460 static_assert(DREQ_UART1_TX == DREQ_UART0_TX + 2, "");
461 return DREQ_UART0_TX + uart_get_index(uart) * 2 + !is_tx;
462}
463
464#ifdef __cplusplus
465}
466#endif
467
468#endif
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:157
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:202
static uint uart_get_index(uart_inst_t *uart)
Convert UART instance to hardware instance number.
Definition uart.h:100
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:156
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:367
static bool uart_is_readable(uart_inst_t *uart)
Determine whether data is waiting in the RX FIFO.
Definition uart.h:305
#define uart0
Identifier for UART instance 0.
Definition uart.h:81
void uart_set_translate_crlf(uart_inst_t *uart, bool translate)
Set CR/LF conversion on UART.
Definition uart.c:194
static void uart_set_hw_flow(uart_inst_t *uart, bool cts, bool rts)
Set UART flow control CTS/RTS.
Definition uart.h:189
uint uart_init(uart_inst_t *uart, uint baudrate)
Initialise a UART.
Definition uart.c:39
static bool uart_is_enabled(uart_inst_t *uart)
Test if specific UART is enabled.
Definition uart.h:254
static void uart_putc_raw(uart_inst_t *uart, char c)
Write single character to UART for transmission.
Definition uart.h:355
static char uart_getc(uart_inst_t *uart)
Read a single character from the UART.
Definition uart.h:409
uart_parity_t
UART Parity enumeration.
Definition uart.h:119
void uart_deinit(uart_inst_t *uart)
DeInitialise a UART.
Definition uart.c:68
static void uart_set_irq_enables(uart_inst_t *uart, bool rx_has_data, bool tx_needs_data)
Setup UART interrupts.
Definition uart.h:228
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:384
static bool uart_is_writable(uart_inst_t *uart)
Determine if space is available in the TX FIFO.
Definition uart.h:285
static void uart_default_tx_wait_blocking(void)
Wait for the default UART's TX FIFO to be drained.
Definition uart.h:434
uint uart_set_baudrate(uart_inst_t *uart, uint baudrate)
Set UART baud rate.
Definition uart.c:128
void uart_set_fifo_enabled(uart_inst_t *uart, bool enabled)
Enable/Disable the FIFOs on specified UART.
Definition uart.c:172
#define uart1
Identifier for UART instance 1.
Definition uart.h:82
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:319
void uart_set_break(uart_inst_t *uart, bool en)
Assert a break condition on the UART transmission.
Definition uart.c:183
static void uart_read_blocking(uart_inst_t *uart, uint8_t *dst, size_t len)
Read from the UART.
Definition uart.h:336
static uint uart_get_dreq(uart_inst_t *uart, bool is_tx)
Return the DREQ to use for pacing transfers to/from a particular UART instance.
Definition uart.h:457
static void uart_tx_wait_blocking(uart_inst_t *uart)
Wait for the UART TX fifo to be drained.
Definition uart.h:294
static __always_inline void tight_loop_contents(void)
No-op function for the body of tight loops.
Definition platform.h:434
Definition uart.h:23