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   ///< Default baud rate
40 #endif
41 
42 /** \file hardware/uart.h
43  *  \defgroup hardware_uart hardware_uart
44  *
45  * Hardware UART API
46  *
47  * RP2040 has 2 identical instances of a UART peripheral, based on the ARM PL011. Each UART can be connected to a number
48  * of GPIO pins as defined in the GPIO muxing.
49  *
50  * Only the TX, RX, RTS, and CTS signals are
51  * connected, meaning that the modem mode and IrDA mode of the PL011 are not supported.
52  *
53  * \subsection uart_example Example
54  * \addtogroup hardware_uart
55  *
56  *  \code
57  *  int main() {
58  *
59  *     // Initialise UART 0
60  *     uart_init(uart0, 115200);
61  *
62  *     // Set the GPIO pin mux to the UART - 0 is TX, 1 is RX
63  *     gpio_set_function(0, GPIO_FUNC_UART);
64  *     gpio_set_function(1, GPIO_FUNC_UART);
65  *
66  *     uart_puts(uart0, "Hello world!");
67  * }
68  * \endcode
69  */
70 
71 // Currently always a pointer to hw but it might not be in the future
72 typedef struct uart_inst uart_inst_t;
73 
74 /** The UART identifiers for use in UART functions.
75  *
76  * e.g. uart_init(uart1, 48000)
77  *
78  *  \ingroup hardware_uart
79  * @{
80  */
81 #define uart0 ((uart_inst_t *)uart0_hw) ///< Identifier for UART instance 0
82 #define uart1 ((uart_inst_t *)uart1_hw) ///< Identifier for UART instance 1
83 
84 /** @} */
85 
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 
94 /*! \brief Convert UART instance to hardware instance number
95  *  \ingroup hardware_uart
96  *
97  * \param uart UART instance
98  * \return Number of UART, 0 or 1.
99  */
uart_get_index(uart_inst_t * uart)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 
uart_get_instance(uint instance)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 
uart_get_hw(uart_inst_t * uart)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 
116 /** \brief UART Parity enumeration
117  *  \ingroup hardware_uart
118  */
119 typedef enum {
120     UART_PARITY_NONE,
121     UART_PARITY_EVEN,
122     UART_PARITY_ODD
123 } uart_parity_t;
124 
125 // ----------------------------------------------------------------------------
126 // Setup
127 
128 /*! \brief Initialise a UART
129  *  \ingroup hardware_uart
130  *
131  * Put the UART into a known state, and enable it. Must be called before other
132  * functions.
133  *
134  * \note There is no guarantee that the baudrate requested will be possible, the nearest will be chosen,
135  * and this function will return the configured baud rate.
136  *
137  * \param uart UART instance. \ref uart0 or \ref uart1
138  * \param baudrate Baudrate of UART in Hz
139  * \return Actual set baudrate
140  */
141 uint uart_init(uart_inst_t *uart, uint baudrate);
142 
143 /*! \brief DeInitialise a UART
144  *  \ingroup hardware_uart
145  *
146  * Disable the UART if it is no longer used. Must be reinitialised before
147  * being used again.
148  *
149  * \param uart UART instance. \ref uart0 or \ref uart1
150  */
151 void uart_deinit(uart_inst_t *uart);
152 
153 /*! \brief Set UART baud rate
154  *  \ingroup hardware_uart
155  *
156  * Set baud rate as close as possible to requested, and return actual rate selected.
157  *
158  * \param uart UART instance. \ref uart0 or \ref uart1
159  * \param baudrate Baudrate in Hz
160  * \return Actual set baudrate
161  */
162 uint uart_set_baudrate(uart_inst_t *uart, uint baudrate);
163 
164 /*! \brief Set UART flow control CTS/RTS
165  *  \ingroup hardware_uart
166  *
167  * \param uart UART instance. \ref uart0 or \ref uart1
168  * \param cts If true enable flow control of TX  by clear-to-send input
169  * \param rts If true enable assertion of request-to-send output by RX flow control
170  */
uart_set_hw_flow(uart_inst_t * uart,bool cts,bool rts)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 
177 /*! \brief Set UART data format
178  *  \ingroup hardware_uart
179  *
180  * Configure the data format (bits etc() for the UART
181  *
182  * \param uart UART instance. \ref uart0 or \ref uart1
183  * \param data_bits Number of bits of data. 5..8
184  * \param stop_bits Number of stop bits 1..2
185  * \param parity Parity option.
186  */
uart_set_format(uart_inst_t * uart,uint data_bits,uint stop_bits,uart_parity_t parity)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 
202 /*! \brief Setup UART interrupts
203  *  \ingroup hardware_uart
204  *
205  * Enable the UART's interrupt output. An interrupt handler will need to be installed prior to calling
206  * this function.
207  *
208  * \param uart UART instance. \ref uart0 or \ref uart1
209  * \param rx_has_data If true an interrupt will be fired when the RX FIFO contains data.
210  * \param tx_needs_data If true an interrupt will be fired when the TX FIFO needs data.
211  */
uart_set_irq_enables(uart_inst_t * uart,bool rx_has_data,bool tx_needs_data)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 
232 /*! \brief Test if specific UART is enabled
233  *  \ingroup hardware_uart
234  *
235  * \param uart UART instance. \ref uart0 or \ref uart1
236  * \return true if the UART is enabled
237  */
uart_is_enabled(uart_inst_t * uart)238 static inline bool uart_is_enabled(uart_inst_t *uart) {
239     return !!(uart_get_hw(uart)->cr & UART_UARTCR_UARTEN_BITS);
240 }
241 
242 /*! \brief Enable/Disable the FIFOs on specified UART
243  *  \ingroup hardware_uart
244  *
245  * \param uart UART instance. \ref uart0 or \ref uart1
246  * \param enabled true to enable FIFO (default), false to disable
247  */
uart_set_fifo_enabled(uart_inst_t * uart,bool enabled)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 
258 /*! \brief Determine if space is available in the TX FIFO
259  *  \ingroup hardware_uart
260  *
261  * \param uart UART instance. \ref uart0 or \ref uart1
262  * \return false if no space available, true otherwise
263  */
uart_is_writable(uart_inst_t * uart)264 static inline bool uart_is_writable(uart_inst_t *uart) {
265     return !(uart_get_hw(uart)->fr & UART_UARTFR_TXFF_BITS);
266 }
267 
268 /*! \brief Wait for the UART TX fifo to be drained
269  *  \ingroup hardware_uart
270  *
271  * \param uart UART instance. \ref uart0 or \ref uart1
272  */
uart_tx_wait_blocking(uart_inst_t * uart)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 
277 /*! \brief Determine whether data is waiting in the RX FIFO
278  *  \ingroup hardware_uart
279  *
280  * \param uart UART instance. \ref uart0 or \ref uart1
281  * \return true if the RX FIFO is not empty, otherwise false.
282  *
283  */
uart_is_readable(uart_inst_t * uart)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 
289 /*! \brief  Write to the UART for transmission.
290  *  \ingroup hardware_uart
291  *
292  * This function will block until all the data has been sent to the UART
293  *
294  * \param uart UART instance. \ref uart0 or \ref uart1
295  * \param src The bytes to send
296  * \param len The number of bytes to send
297  */
uart_write_blocking(uart_inst_t * uart,const uint8_t * src,size_t len)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))
301             tight_loop_contents();
302         uart_get_hw(uart)->dr = *src++;
303     }
304 }
305 
306 /*! \brief  Read from the UART
307  *  \ingroup hardware_uart
308  *
309  * This function blocks until len characters have been read from the UART
310  *
311  * \param uart UART instance. \ref uart0 or \ref uart1
312  * \param dst Buffer to accept received bytes
313  * \param len The number of bytes to receive.
314  */
uart_read_blocking(uart_inst_t * uart,uint8_t * dst,size_t len)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))
318             tight_loop_contents();
319         *dst++ = (uint8_t) uart_get_hw(uart)->dr;
320     }
321 }
322 
323 // ----------------------------------------------------------------------------
324 // UART-specific operations and aliases
325 
326 /*! \brief  Write single character to UART for transmission.
327  *  \ingroup hardware_uart
328  *
329  * This function will block until the entire character has been sent
330  *
331  * \param uart UART instance. \ref uart0 or \ref uart1
332  * \param c The character  to send
333  */
uart_putc_raw(uart_inst_t * uart,char c)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 
338 /*! \brief  Write single character to UART for transmission, with optional CR/LF conversions
339  *  \ingroup hardware_uart
340  *
341  * This function will block until the character has been sent
342  *
343  * \param uart UART instance. \ref uart0 or \ref uart1
344  * \param c The character  to send
345  */
uart_putc(uart_inst_t * uart,char c)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 
355 /*! \brief  Write string to UART for transmission, doing any CR/LF conversions
356  *  \ingroup hardware_uart
357  *
358  * This function will block until the entire string has been sent
359  *
360  * \param uart UART instance. \ref uart0 or \ref uart1
361  * \param s The null terminated string to send
362  */
uart_puts(uart_inst_t * uart,const char * s)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 
380 /*! \brief  Read a single character from the UART
381  *  \ingroup hardware_uart
382  *
383  * This function will block until a character has been read
384  *
385  * \param uart UART instance. \ref uart0 or \ref uart1
386  * \return The character read.
387  */
uart_getc(uart_inst_t * uart)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 
394 /*! \brief Assert a break condition on the UART transmission.
395  *  \ingroup hardware_uart
396  *
397  * \param uart UART instance. \ref uart0 or \ref uart1
398  * \param en Assert break condition (TX held low) if true. Clear break condition if false.
399  */
uart_set_break(uart_inst_t * uart,bool en)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 
407 /*! \brief Set CR/LF conversion on UART
408  *  \ingroup hardware_uart
409  *
410  * \param uart UART instance. \ref uart0 or \ref uart1
411  * \param translate If true, convert line feeds to carriage return on transmissions
412  */
413 void uart_set_translate_crlf(uart_inst_t *uart, bool translate);
414 
415 /*! \brief Wait for the default UART's TX FIFO to be drained
416  *  \ingroup hardware_uart
417  */
uart_default_tx_wait_blocking(void)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 
426 /*! \brief Wait for up to a certain number of microseconds for the RX FIFO to be non empty
427  *  \ingroup hardware_uart
428  *
429  * \param uart UART instance. \ref uart0 or \ref uart1
430  * \param us the number of microseconds to wait at most (may be 0 for an instantaneous check)
431  * \return true if the RX FIFO became non empty before the timeout, false otherwise
432  */
433 bool uart_is_readable_within_us(uart_inst_t *uart, uint32_t us);
434 
435 /*! \brief Return the DREQ to use for pacing transfers to/from a particular UART instance
436  *  \ingroup hardware_uart
437  *
438  * \param uart UART instance. \ref uart0 or \ref uart1
439  * \param is_tx true for sending data to the UART instance, false for receiving data from the UART instance
440  */
uart_get_dreq(uart_inst_t * uart,bool is_tx)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
453