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_UART, Enable/disable assertions in the UART module, type=bool, default=0, group=hardware_uart
14 #ifndef PARAM_ASSERTIONS_ENABLED_UART
15 #define PARAM_ASSERTIONS_ENABLED_UART 0
16 #endif
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 // PICO_CONFIG: PICO_UART_ENABLE_CRLF_SUPPORT, Enable/disable CR/LF translation support, type=bool, default=1, group=hardware_uart
23 #ifndef PICO_UART_ENABLE_CRLF_SUPPORT
24 #define PICO_UART_ENABLE_CRLF_SUPPORT 1
25 #endif
26 
27 // 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
28 #ifndef PICO_UART_DEFAULT_CRLF
29 #define PICO_UART_DEFAULT_CRLF 0
30 #endif
31 
32 // PICO_CONFIG: PICO_DEFAULT_UART, Define the default UART used for printf etc, default=0, group=hardware_uart
33 #ifndef PICO_DEFAULT_UART
34 #define PICO_DEFAULT_UART 0     ///< Default UART instance
35 #endif
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 // PICO_CONFIG: PICO_DEFAULT_UART_TX_PIN, Define the default UART TX pin, min=0, max=29, default=0, group=hardware_uart
43 #ifndef PICO_DEFAULT_UART_TX_PIN
44 #define PICO_DEFAULT_UART_TX_PIN 0           ///< Default TX pin
45 #endif
46 
47 // PICO_CONFIG: PICO_DEFAULT_UART_RX_PIN, Define the default UART RX pin, min=0, max=29, default=1, group=hardware_uart
48 #ifndef PICO_DEFAULT_UART_RX_PIN
49 #define PICO_DEFAULT_UART_RX_PIN 1           ///< Default RX pin
50 #endif
51 
52 /** \file hardware/uart.h
53  *  \defgroup hardware_uart hardware_uart
54  *
55  * Hardware UART API
56  *
57  * RP2040 has 2 identical instances of a UART peripheral, based on the ARM PL011. Each UART can be connected to a number
58  * of GPIO pins as defined in the GPIO muxing.
59  *
60  * Only the TX, RX, RTS, and CTS signals are
61  * connected, meaning that the modem mode and IrDA mode of the PL011 are not supported.
62  *
63  * \subsection uart_example Example
64  * \addtogroup hardware_uart
65  *
66  *  \code
67  *  int main() {
68  *
69  *     // Initialise UART 0
70  *     uart_init(uart0, 115200);
71  *
72  *     // Set the GPIO pin mux to the UART - 0 is TX, 1 is RX
73  *     gpio_set_function(0, GPIO_FUNC_UART);
74  *     gpio_set_function(1, GPIO_FUNC_UART);
75  *
76  *     uart_puts(uart0, "Hello world!");
77  * }
78  * \endcode
79  */
80 
81 // Currently always a pointer to hw but it might not be in the future
82 typedef struct uart_inst uart_inst_t;
83 
84 /** The UART identifiers for use in UART functions.
85  *
86  * e.g. uart_init(uart1, 48000)
87  *
88  *  \ingroup hardware_uart
89  * @{
90  */
91 #define uart0 ((uart_inst_t * const)uart0_hw) ///< Identifier for UART instance 0
92 #define uart1 ((uart_inst_t * const)uart1_hw) ///< Identifier for UART instance 1
93 
94 /** @} */
95 
96 #ifndef PICO_DEFAULT_UART_INSTANCE
97 #define PICO_DEFAULT_UART_INSTANCE (__CONCAT(uart,PICO_DEFAULT_UART))
98 #endif
99 
100 #define uart_default PICO_DEFAULT_UART_INSTANCE
101 
102 /*! \brief Convert UART instance to hardware instance number
103  *  \ingroup hardware_uart
104  *
105  * \param uart UART instance
106  * \return Number of UART, 0 or 1.
107  */
uart_get_index(uart_inst_t * uart)108 static inline uint uart_get_index(uart_inst_t *uart) {
109     invalid_params_if(UART, uart != uart0 && uart != uart1);
110     return uart == uart1 ? 1 : 0;
111 }
112 
uart_get_hw(uart_inst_t * uart)113 static inline uart_hw_t *uart_get_hw(uart_inst_t *uart) {
114     uart_get_index(uart); // check it is a hw uart
115     return (uart_hw_t *)uart;
116 }
117 
118 /** \brief UART Parity enumeration
119  *  \ingroup hardware_uart
120  */
121 typedef enum {
122     UART_PARITY_NONE,
123     UART_PARITY_EVEN,
124     UART_PARITY_ODD
125 } uart_parity_t;
126 
127 // ----------------------------------------------------------------------------
128 // Setup
129 
130 /*! \brief Initialise a UART
131  *  \ingroup hardware_uart
132  *
133  * Put the UART into a known state, and enable it. Must be called before other
134  * functions.
135  *
136  * \note There is no guarantee that the baudrate requested will be possible, the nearest will be chosen,
137  * and this function will return the configured baud rate.
138  *
139  * \param uart UART instance. \ref uart0 or \ref uart1
140  * \param baudrate Baudrate of UART in Hz
141  * \return Actual set baudrate
142  */
143 uint uart_init(uart_inst_t *uart, uint baudrate);
144 
145 /*! \brief DeInitialise a UART
146  *  \ingroup hardware_uart
147  *
148  * Disable the UART if it is no longer used. Must be reinitialised before
149  * being used again.
150  *
151  * \param uart UART instance. \ref uart0 or \ref uart1
152  */
153 void uart_deinit(uart_inst_t *uart);
154 
155 /*! \brief Set UART baud rate
156  *  \ingroup hardware_uart
157  *
158  * Set baud rate as close as possible to requested, and return actual rate selected.
159  *
160  * \param uart UART instance. \ref uart0 or \ref uart1
161  * \param baudrate Baudrate in Hz
162  * \return Actual set baudrate
163  */
164 uint uart_set_baudrate(uart_inst_t *uart, uint baudrate);
165 
166 /*! \brief Set UART flow control CTS/RTS
167  *  \ingroup hardware_uart
168  *
169  * \param uart UART instance. \ref uart0 or \ref uart1
170  * \param cts If true enable flow control of TX  by clear-to-send input
171  * \param rts If true enable assertion of request-to-send output by RX flow control
172  */
uart_set_hw_flow(uart_inst_t * uart,bool cts,bool rts)173 static inline void uart_set_hw_flow(uart_inst_t *uart, bool cts, bool rts) {
174     hw_write_masked(&uart_get_hw(uart)->cr,
175                    (!!cts << UART_UARTCR_CTSEN_LSB) | (!!rts << UART_UARTCR_RTSEN_LSB),
176                    UART_UARTCR_RTSEN_BITS | UART_UARTCR_CTSEN_BITS);
177 }
178 
179 /*! \brief Set UART data format
180  *  \ingroup hardware_uart
181  *
182  * Configure the data format (bits etc() for the UART
183  *
184  * \param uart UART instance. \ref uart0 or \ref uart1
185  * \param data_bits Number of bits of data. 5..8
186  * \param stop_bits Number of stop bits 1..2
187  * \param parity Parity option.
188  */
uart_set_format(uart_inst_t * uart,uint data_bits,uint stop_bits,uart_parity_t parity)189 static inline void uart_set_format(uart_inst_t *uart, uint data_bits, uint stop_bits, uart_parity_t parity) {
190     invalid_params_if(UART, data_bits < 5 || data_bits > 8);
191     invalid_params_if(UART, stop_bits != 1 && stop_bits != 2);
192     invalid_params_if(UART, parity != UART_PARITY_NONE && parity != UART_PARITY_EVEN && parity != UART_PARITY_ODD);
193     hw_write_masked(&uart_get_hw(uart)->lcr_h,
194                    ((data_bits - 5) << UART_UARTLCR_H_WLEN_LSB) |
195                    ((stop_bits - 1) << UART_UARTLCR_H_STP2_LSB) |
196                    ((parity != UART_PARITY_NONE) << UART_UARTLCR_H_PEN_LSB) |
197                    ((parity == UART_PARITY_EVEN) << UART_UARTLCR_H_EPS_LSB),
198                    UART_UARTLCR_H_WLEN_BITS |
199                    UART_UARTLCR_H_STP2_BITS |
200                    UART_UARTLCR_H_PEN_BITS |
201                    UART_UARTLCR_H_EPS_BITS);
202 }
203 
204 /*! \brief Setup UART interrupts
205  *  \ingroup hardware_uart
206  *
207  * Enable the UART's interrupt output. An interrupt handler will need to be installed prior to calling
208  * this function.
209  *
210  * \param uart UART instance. \ref uart0 or \ref uart1
211  * \param rx_has_data If true an interrupt will be fired when the RX FIFO contain data.
212  * \param tx_needs_data If true an interrupt will be fired when the TX FIFO needs data.
213  */
uart_set_irq_enables(uart_inst_t * uart,bool rx_has_data,bool tx_needs_data)214 static inline void uart_set_irq_enables(uart_inst_t *uart, bool rx_has_data, bool tx_needs_data) {
215     uart_get_hw(uart)->imsc = (!!tx_needs_data << UART_UARTIMSC_TXIM_LSB) |
216                               (!!rx_has_data << UART_UARTIMSC_RXIM_LSB);
217     if (rx_has_data) {
218         // Set minimum threshold
219         hw_write_masked(&uart_get_hw(uart)->ifls, 0 << UART_UARTIFLS_RXIFLSEL_LSB,
220                         UART_UARTIFLS_RXIFLSEL_BITS);
221     }
222     if (tx_needs_data) {
223         // Set maximum threshold
224         hw_write_masked(&uart_get_hw(uart)->ifls, 0 << UART_UARTIFLS_TXIFLSEL_LSB,
225                         UART_UARTIFLS_TXIFLSEL_BITS);
226     }
227 }
228 
229 /*! \brief Test if specific UART is enabled
230  *  \ingroup hardware_uart
231  *
232  * \param uart UART instance. \ref uart0 or \ref uart1
233  * \return true if the UART is enabled
234  */
uart_is_enabled(uart_inst_t * uart)235 static inline bool uart_is_enabled(uart_inst_t *uart) {
236     return !!(uart_get_hw(uart)->cr & UART_UARTCR_UARTEN_BITS);
237 }
238 
239 /*! \brief Enable/Disable the FIFOs on specified UART
240  *  \ingroup hardware_uart
241  *
242  * \param uart UART instance. \ref uart0 or \ref uart1
243  * \param enabled true to enable FIFO (default), false to disable
244  */
uart_set_fifo_enabled(uart_inst_t * uart,bool enabled)245 static inline void uart_set_fifo_enabled(uart_inst_t *uart, bool enabled) {
246     hw_write_masked(&uart_get_hw(uart)->lcr_h,
247                    (!!enabled << UART_UARTLCR_H_FEN_LSB),
248                    UART_UARTLCR_H_FEN_BITS);
249 }
250 
251 
252 // ----------------------------------------------------------------------------
253 // Generic input/output
254 
255 /*! \brief Determine if space is available in the TX FIFO
256  *  \ingroup hardware_uart
257  *
258  * \param uart UART instance. \ref uart0 or \ref uart1
259  * \return false if no space available, true otherwise
260  */
uart_is_writable(uart_inst_t * uart)261 static inline bool uart_is_writable(uart_inst_t *uart) {
262     return !(uart_get_hw(uart)->fr & UART_UARTFR_TXFF_BITS);
263 }
264 
265 /*! \brief Wait for the UART TX fifo to be drained
266  *  \ingroup hardware_uart
267  *
268  * \param uart UART instance. \ref uart0 or \ref uart1
269  */
uart_tx_wait_blocking(uart_inst_t * uart)270 static inline void uart_tx_wait_blocking(uart_inst_t *uart) {
271     while (uart_get_hw(uart)->fr & UART_UARTFR_BUSY_BITS) tight_loop_contents();
272 }
273 
274 /*! \brief Determine whether data is waiting in the RX FIFO
275  *  \ingroup hardware_uart
276  *
277  * \param uart UART instance. \ref uart0 or \ref uart1
278  * \return 0 if no data available, otherwise the number of bytes, at least, that can be read
279  *
280  * \note HW limitations mean this function will return either 0 or 1.
281  */
uart_is_readable(uart_inst_t * uart)282 static inline bool uart_is_readable(uart_inst_t *uart) {
283     // PL011 doesn't expose levels directly, so return values are only 0 or 1
284     return !(uart_get_hw(uart)->fr & UART_UARTFR_RXFE_BITS);
285 }
286 
287 /*! \brief  Write to the UART for transmission.
288  *  \ingroup hardware_uart
289  *
290  * This function will block until all the data has been sent to the UART
291  *
292  * \param uart UART instance. \ref uart0 or \ref uart1
293  * \param src The bytes to send
294  * \param len The number of bytes to send
295  */
uart_write_blocking(uart_inst_t * uart,const uint8_t * src,size_t len)296 static inline void uart_write_blocking(uart_inst_t *uart, const uint8_t *src, size_t len) {
297     for (size_t i = 0; i < len; ++i) {
298         while (!uart_is_writable(uart))
299             tight_loop_contents();
300         uart_get_hw(uart)->dr = *src++;
301     }
302 }
303 
304 /*! \brief  Read from the UART
305  *  \ingroup hardware_uart
306  *
307  * This function will block until all the data has been received from the UART
308  *
309  * \param uart UART instance. \ref uart0 or \ref uart1
310  * \param dst Buffer to accept received bytes
311  * \param len The number of bytes to receive.
312  */
uart_read_blocking(uart_inst_t * uart,uint8_t * dst,size_t len)313 static inline void uart_read_blocking(uart_inst_t *uart, uint8_t *dst, size_t len) {
314     for (size_t i = 0; i < len; ++i) {
315         while (!uart_is_readable(uart))
316             tight_loop_contents();
317         *dst++ = uart_get_hw(uart)->dr;
318     }
319 }
320 
321 // ----------------------------------------------------------------------------
322 // UART-specific operations and aliases
323 
324 /*! \brief  Write single character to UART for transmission.
325  *  \ingroup hardware_uart
326  *
327  * This function will block until all the character has been sent
328  *
329  * \param uart UART instance. \ref uart0 or \ref uart1
330  * \param c The character  to send
331  */
uart_putc_raw(uart_inst_t * uart,char c)332 static inline void uart_putc_raw(uart_inst_t *uart, char c) {
333     uart_write_blocking(uart, (const uint8_t *) &c, 1);
334 }
335 
336 /*! \brief  Write single character to UART for transmission, with optional CR/LF conversions
337  *  \ingroup hardware_uart
338  *
339  * This function will block until the character has been sent
340  *
341  * \param uart UART instance. \ref uart0 or \ref uart1
342  * \param c The character  to send
343  */
uart_putc(uart_inst_t * uart,char c)344 static inline void uart_putc(uart_inst_t *uart, char c) {
345 #if PICO_UART_ENABLE_CRLF_SUPPORT
346     extern short uart_char_to_line_feed[NUM_UARTS];
347     if (uart_char_to_line_feed[uart_get_index(uart)] == c)
348         uart_putc_raw(uart, '\r');
349 #endif
350     uart_putc_raw(uart, c);
351 }
352 
353 /*! \brief  Write string to UART for transmission, doing any CR/LF conversions
354  *  \ingroup hardware_uart
355  *
356  * This function will block until the entire string has been sent
357  *
358  * \param uart UART instance. \ref uart0 or \ref uart1
359  * \param s The null terminated string to send
360  */
uart_puts(uart_inst_t * uart,const char * s)361 static inline void uart_puts(uart_inst_t *uart, const char *s) {
362 #if PICO_UART_ENABLE_CRLF_SUPPORT
363     bool last_was_cr = false;
364     while (*s) {
365         // Don't add extra carriage returns if one is present
366         if (last_was_cr)
367             uart_putc_raw(uart, *s);
368         else
369             uart_putc(uart, *s);
370         last_was_cr = *s++ == '\r';
371     }
372 #else
373     while (*s)
374         uart_putc(uart, *s++);
375 #endif
376 }
377 
378 /*! \brief  Read a single character to UART
379  *  \ingroup hardware_uart
380  *
381  * This function will block until the character has been read
382  *
383  * \param uart UART instance. \ref uart0 or \ref uart1
384  * \return The character read.
385  */
uart_getc(uart_inst_t * uart)386 static inline char uart_getc(uart_inst_t *uart) {
387     char c;
388     uart_read_blocking(uart, (uint8_t *) &c, 1);
389     return c;
390 }
391 
392 /*! \brief Assert a break condition on the UART transmission.
393  *  \ingroup hardware_uart
394  *
395  * \param uart UART instance. \ref uart0 or \ref uart1
396  * \param en Assert break condition (TX held low) if true. Clear break condition if false.
397  */
uart_set_break(uart_inst_t * uart,bool en)398 static inline void uart_set_break(uart_inst_t *uart, bool en) {
399     if (en)
400         hw_set_bits(&uart_get_hw(uart)->lcr_h, UART_UARTLCR_H_BRK_BITS);
401     else
402         hw_clear_bits(&uart_get_hw(uart)->lcr_h, UART_UARTLCR_H_BRK_BITS);
403 }
404 
405 /*! \brief Set CR/LF conversion on UART
406  *  \ingroup hardware_uart
407  *
408  * \param uart UART instance. \ref uart0 or \ref uart1
409  * \param translate If true, convert line feeds to carriage return on transmissions
410  */
411 void uart_set_translate_crlf(uart_inst_t *uart, bool translate);
412 
413 /*! \brief Wait for the default UART'S TX fifo to be drained
414  *  \ingroup hardware_uart
415  */
uart_default_tx_wait_blocking(void)416 static inline void uart_default_tx_wait_blocking(void) {
417     uart_tx_wait_blocking(uart_default);
418 }
419 
420 /*! \brief Wait for up to a certain number of microseconds for the RX FIFO to be non empty
421  *  \ingroup hardware_uart
422  *
423  * \param uart UART instance. \ref uart0 or \ref uart1
424  * \param us the number of microseconds to wait at most (may be 0 for an instantaneous check)
425  * \return true if the RX FIFO became non empty before the timeout, false otherwise
426  */
427 bool uart_is_readable_within_us(uart_inst_t *uart, uint32_t us);
428 
429 #ifdef __cplusplus
430 }
431 #endif
432 
433 #endif
434