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
20 extern "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
72 typedef struct uart_inst uart_inst_t;
73 
81 #define uart0 ((uart_inst_t *)uart0_hw)
82 #define uart1 ((uart_inst_t *)uart1_hw)
83 
84 
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 
100 static 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 
105 static 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 
111 static 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 
119 typedef enum {
120  UART_PARITY_NONE,
121  UART_PARITY_EVEN,
122  UART_PARITY_ODD
123 } uart_parity_t;
124 
125 // ----------------------------------------------------------------------------
126 // Setup
127 
141 uint uart_init(uart_inst_t *uart, uint baudrate);
142 
151 void uart_deinit(uart_inst_t *uart);
152 
162 uint uart_set_baudrate(uart_inst_t *uart, uint baudrate);
163 
171 static inline void uart_set_hw_flow(uart_inst_t *uart, bool cts, bool rts) {
172  hw_write_masked(&uart_get_hw(uart)->cr,
173  (bool_to_bit(cts) << UART_UARTCR_CTSEN_LSB) | (bool_to_bit(rts) << UART_UARTCR_RTSEN_LSB),
174  UART_UARTCR_RTSEN_BITS | UART_UARTCR_CTSEN_BITS);
175 }
176 
187 static inline void uart_set_format(uart_inst_t *uart, uint data_bits, uint stop_bits, uart_parity_t parity) {
188  invalid_params_if(UART, data_bits < 5 || data_bits > 8);
189  invalid_params_if(UART, stop_bits != 1 && stop_bits != 2);
190  invalid_params_if(UART, parity != UART_PARITY_NONE && parity != UART_PARITY_EVEN && parity != UART_PARITY_ODD);
191  hw_write_masked(&uart_get_hw(uart)->lcr_h,
192  ((data_bits - 5u) << UART_UARTLCR_H_WLEN_LSB) |
193  ((stop_bits - 1u) << UART_UARTLCR_H_STP2_LSB) |
194  (bool_to_bit(parity != UART_PARITY_NONE) << UART_UARTLCR_H_PEN_LSB) |
195  (bool_to_bit(parity == UART_PARITY_EVEN) << UART_UARTLCR_H_EPS_LSB),
196  UART_UARTLCR_H_WLEN_BITS |
197  UART_UARTLCR_H_STP2_BITS |
198  UART_UARTLCR_H_PEN_BITS |
199  UART_UARTLCR_H_EPS_BITS);
200 }
201 
212 static inline void uart_set_irq_enables(uart_inst_t *uart, bool rx_has_data, bool tx_needs_data) {
213  // Both UARTRXINTR (RX) and UARTRTINTR (RX timeout) interrupts are
214  // required for rx_has_data. RX asserts when >=4 characters are in the RX
215  // FIFO (for RXIFLSEL=0). RT asserts when there are >=1 characters and no
216  // more have been received for 32 bit periods.
217  uart_get_hw(uart)->imsc = (bool_to_bit(tx_needs_data) << UART_UARTIMSC_TXIM_LSB) |
218  (bool_to_bit(rx_has_data) << UART_UARTIMSC_RXIM_LSB) |
219  (bool_to_bit(rx_has_data) << UART_UARTIMSC_RTIM_LSB);
220  if (rx_has_data) {
221  // Set minimum threshold
222  hw_write_masked(&uart_get_hw(uart)->ifls, 0 << UART_UARTIFLS_RXIFLSEL_LSB,
223  UART_UARTIFLS_RXIFLSEL_BITS);
224  }
225  if (tx_needs_data) {
226  // Set maximum threshold
227  hw_write_masked(&uart_get_hw(uart)->ifls, 0 << UART_UARTIFLS_TXIFLSEL_LSB,
228  UART_UARTIFLS_TXIFLSEL_BITS);
229  }
230 }
231 
238 static inline bool uart_is_enabled(uart_inst_t *uart) {
239  return !!(uart_get_hw(uart)->cr & UART_UARTCR_UARTEN_BITS);
240 }
241 
248 static inline void uart_set_fifo_enabled(uart_inst_t *uart, bool enabled) {
249  hw_write_masked(&uart_get_hw(uart)->lcr_h,
250  (bool_to_bit(enabled) << UART_UARTLCR_H_FEN_LSB),
251  UART_UARTLCR_H_FEN_BITS);
252 }
253 
254 
255 // ----------------------------------------------------------------------------
256 // Generic input/output
257 
264 static inline bool uart_is_writable(uart_inst_t *uart) {
265  return !(uart_get_hw(uart)->fr & UART_UARTFR_TXFF_BITS);
266 }
267 
273 static inline void uart_tx_wait_blocking(uart_inst_t *uart) {
274  while (uart_get_hw(uart)->fr & UART_UARTFR_BUSY_BITS) tight_loop_contents();
275 }
276 
284 static inline bool uart_is_readable(uart_inst_t *uart) {
285  // PL011 doesn't expose levels directly, so return values are only 0 or 1
286  return !(uart_get_hw(uart)->fr & UART_UARTFR_RXFE_BITS);
287 }
288 
298 static inline void uart_write_blocking(uart_inst_t *uart, const uint8_t *src, size_t len) {
299  for (size_t i = 0; i < len; ++i) {
300  while (!uart_is_writable(uart))
302  uart_get_hw(uart)->dr = *src++;
303  }
304 }
305 
315 static inline void uart_read_blocking(uart_inst_t *uart, uint8_t *dst, size_t len) {
316  for (size_t i = 0; i < len; ++i) {
317  while (!uart_is_readable(uart))
319  *dst++ = (uint8_t) uart_get_hw(uart)->dr;
320  }
321 }
322 
323 // ----------------------------------------------------------------------------
324 // UART-specific operations and aliases
325 
334 static inline void uart_putc_raw(uart_inst_t *uart, char c) {
335  uart_write_blocking(uart, (const uint8_t *) &c, 1);
336 }
337 
346 static inline void uart_putc(uart_inst_t *uart, char c) {
347 #if PICO_UART_ENABLE_CRLF_SUPPORT
348  extern short uart_char_to_line_feed[NUM_UARTS];
349  if (uart_char_to_line_feed[uart_get_index(uart)] == c)
350  uart_putc_raw(uart, '\r');
351 #endif
352  uart_putc_raw(uart, c);
353 }
354 
363 static inline void uart_puts(uart_inst_t *uart, const char *s) {
364 #if PICO_UART_ENABLE_CRLF_SUPPORT
365  bool last_was_cr = false;
366  while (*s) {
367  // Don't add extra carriage returns if one is present
368  if (last_was_cr)
369  uart_putc_raw(uart, *s);
370  else
371  uart_putc(uart, *s);
372  last_was_cr = *s++ == '\r';
373  }
374 #else
375  while (*s)
376  uart_putc(uart, *s++);
377 #endif
378 }
379 
388 static inline char uart_getc(uart_inst_t *uart) {
389  char c;
390  uart_read_blocking(uart, (uint8_t *) &c, 1);
391  return c;
392 }
393 
400 static inline void uart_set_break(uart_inst_t *uart, bool en) {
401  if (en)
402  hw_set_bits(&uart_get_hw(uart)->lcr_h, UART_UARTLCR_H_BRK_BITS);
403  else
404  hw_clear_bits(&uart_get_hw(uart)->lcr_h, UART_UARTLCR_H_BRK_BITS);
405 }
406 
413 void uart_set_translate_crlf(uart_inst_t *uart, bool translate);
414 
418 static inline void uart_default_tx_wait_blocking(void) {
419 #ifdef uart_default
420  uart_tx_wait_blocking(uart_default);
421 #else
422  assert(false);
423 #endif
424 }
425 
433 bool uart_is_readable_within_us(uart_inst_t *uart, uint32_t us);
434 
441 static inline uint uart_get_dreq(uart_inst_t *uart, bool is_tx) {
442  static_assert(DREQ_UART0_RX == DREQ_UART0_TX + 1, "");
443  static_assert(DREQ_UART1_RX == DREQ_UART1_TX + 1, "");
444  static_assert(DREQ_UART1_TX == DREQ_UART0_TX + 2, "");
445  return DREQ_UART0_TX + uart_get_index(uart) * 2 + !is_tx;
446 }
447 
448 #ifdef __cplusplus
449 }
450 #endif
451 
452 #endif
hw_clear_bits
static __force_inline void hw_clear_bits(io_rw_32 *addr, uint32_t mask)
Atomically clear the specified bits to 0 in a HW register.
Definition: address_mapped.h:131
uart_parity_t
uart_parity_t
UART Parity enumeration.
Definition: uart.h:119
uart_getc
static char uart_getc(uart_inst_t *uart)
Read a single character from the UART.
Definition: uart.h:388
uart_putc_raw
static void uart_putc_raw(uart_inst_t *uart, char c)
Write single character to UART for transmission.
Definition: uart.h:334
uart_get_index
static uint uart_get_index(uart_inst_t *uart)
Convert UART instance to hardware instance number.
Definition: uart.h:100
uart_set_baudrate
uint uart_set_baudrate(uart_inst_t *uart, uint baudrate)
Set UART baud rate.
Definition: uart.c:73
uart_set_translate_crlf
void uart_set_translate_crlf(uart_inst_t *uart, bool translate)
Set CR/LF conversion on UART.
Definition: uart.c:102
uart_set_fifo_enabled
static void uart_set_fifo_enabled(uart_inst_t *uart, bool enabled)
Enable/Disable the FIFOs on specified UART.
Definition: uart.h:248
uart_set_irq_enables
static void uart_set_irq_enables(uart_inst_t *uart, bool rx_has_data, bool tx_needs_data)
Setup UART interrupts.
Definition: uart.h:212
uart0
#define uart0
Identifier for UART instance 0.
Definition: uart.h:81
uart_is_readable
static bool uart_is_readable(uart_inst_t *uart)
Determine whether data is waiting in the RX FIFO.
Definition: uart.h:284
uart_is_enabled
static bool uart_is_enabled(uart_inst_t *uart)
Test if specific UART is enabled.
Definition: uart.h:238
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:157
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:110
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:315
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:273
uart_deinit
void uart_deinit(uart_inst_t *uart)
DeInitialise a UART.
Definition: uart.c:67
uart_set_format
static void uart_set_format(uart_inst_t *uart, uint data_bits, uint stop_bits, uart_parity_t parity)
Set UART data format.
Definition: uart.h:187
uart_hw_t
Definition: uart.h:23
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:171
hw_set_bits
static __force_inline void hw_set_bits(io_rw_32 *addr, uint32_t mask)
Atomically set the specified bits to 1 in a HW register.
Definition: address_mapped.h:121
uart_get_dreq
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:441
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:346
uart_init
uint uart_init(uart_inst_t *uart, uint baudrate)
Initialise a UART.
Definition: uart.c:39
tight_loop_contents
static __always_inline void tight_loop_contents(void)
No-op function for the body of tight loops.
Definition: platform.h:358
uart1
#define uart1
Identifier for UART instance 1.
Definition: uart.h:82
pico.h
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:363
uart_is_writable
static bool uart_is_writable(uart_inst_t *uart)
Determine if space is available in the TX FIFO.
Definition: uart.h:264
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:418
uart_set_break
static void uart_set_break(uart_inst_t *uart, bool en)
Assert a break condition on the UART transmission.
Definition: uart.h:400
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:298