Software APIs
dif_uart.h
Go to the documentation of this file.
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_UART_H_
6 #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_UART_H_
7 
8 /**
9  * @file
10  * @brief <a href="/hw/ip/uart/doc/">UART</a> Device Interface Functions
11  */
12 
13 #include <stdint.h>
14 
16 
18 #include "uart_regs.h"
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif // __cplusplus
23 
24 /**
25  * A parity state: odd, or even.
26  */
27 typedef enum dif_uart_parity {
28  /**
29  * Indicates the "odd" parity.
30  */
32  /**
33  * Indicates the "even" parity.
34  */
37 
38 /**
39  * Number of characters that the UART RX line should be held low for to trigger
40  * a line break error.
41  */
43  kDifUartRxBreakLevel2 = UART_CTRL_RXBLVL_VALUE_BREAK2,
44  kDifUartRxBreakLevel4 = UART_CTRL_RXBLVL_VALUE_BREAK4,
45  kDifUartRxBreakLevel8 = UART_CTRL_RXBLVL_VALUE_BREAK8,
46  kDifUartRxBreakLevel16 = UART_CTRL_RXBLVL_VALUE_BREAK16,
48 
49 /**
50  * Runtime configuration for UART.
51  *
52  * This struct describes runtime information for one-time configuration of the
53  * hardware.
54  */
55 typedef struct dif_uart_config {
56  /**
57  * The UART baudrate.
58  */
59  uint32_t baudrate;
60  /**
61  * The frequency of the clock driving the UART.
62  */
63  uint32_t clk_freq_hz;
64  /**
65  * Whether to enable parity checking.
66  */
68  /**
69  * The parity to set.
70  */
72  /**
73  * Whether to enable TX datapath.
74  */
76  /**
77  * Whether to enable RX datapath.
78  */
80  /**
81  * Number of characters at which the RX line break error is triggered.
82  */
85 
86 /**
87  * A UART FIFO watermark depth configuration.
88  */
89 typedef enum dif_uart_watermark {
90  /**
91  * Indicates a one-byte watermark.
92  */
94  /**
95  * Indicates a two-byte watermark.
96  */
98  /**
99  * Indicates a four-byte watermark.
100  */
102  /**
103  * Indicates an eight-byte watermark.
104  */
106  /**
107  * Indicates a sixteen-byte watermark.
108  */
110  /**
111  * Indicates a thirty-two-byte watermark.
112  */
114  /**
115  * Indicates a sixty-four-byte watermark.
116  */
119 
120 /**
121  * A UART datapath to select various enables / FIFO resets.
122  */
123 typedef enum dif_uart_datapath {
124  /**
125  * Selects the RX datapath for enablement / reset.
126  */
128  /**
129  * Selects the TX datapath for enablement / reset.
130  */
132  /**
133  * Selects both the RX and TX datapaths for enablement / reset.
134  */
137 
138 /**
139  * A UART system/line loopback configuration.
140  */
141 typedef enum dif_uart_loopback {
142  /**
143  * Indicates that outgoing TX bits should be recieved through RX.
144  */
146  /**
147  * Indicates that incoming RX bits should be forwarded to TX.
148  */
151 
152 /**
153  * The size of the UART TX and RX FIFOs, in bytes.
154  */
155 extern const uint32_t kDifUartFifoSizeBytes;
156 
157 /**
158  * Configures UART with runtime information.
159  *
160  * This function should need to be called once for the lifetime of `handle`.
161  *
162  * @param uart A UART handle.
163  * @param config Runtime configuration parameters.
164  * @return The result of the operation.
165  */
168  dif_uart_config_t config);
169 
170 /**
171  * Set the RX break level.
172  *
173  * This is the number of characters that the RX line must be held low for to
174  * trigger the RX break error.
175  *
176  * @param uart A UART handle.
177  * @param rx_break_level The level to configure.
178  * @return The result of the operation.
179  */
182  const dif_uart_t *uart, dif_uart_rx_break_level_t rx_break_level);
183 
184 /**
185  * Sets the RX FIFO watermark.
186  *
187  * This function is only useful when the corresponding interrupt is enabled.
188  * When the queued RX FIFO number of bytes rises to or above this
189  * level, the RX watermark interrupt is raised.
190  *
191  * @param uart A UART handle.
192  * @param watermark RX FIFO watermark.
193  * @return The result of the operation.
194  */
197  dif_uart_watermark_t watermark);
198 
199 /**
200  * Sets the TX FIFO watermark.
201  *
202  * This function is only useful when the corresponding interrupt is enabled.
203  * When the queued RX FIFO number of bytes rises to or above this
204  * level, the RX watermark interrupt is raised.
205  *
206  * @param uart A UART handle.
207  * @param watermark TX FIFO watermark.
208  * @return The result of the operation.
209  */
212  dif_uart_watermark_t watermark);
213 
214 /**
215  * Sets the enablement state of one or both (TX/RX) datapaths.
216  *
217  * @param uart A UART handle.
218  * @param datapath The datapath to set the enablement state of (RX, TX or both).
219  * @param enabled The enablement state to set.
220  * @return The result of the operation.
221  */
224  dif_uart_datapath_t datapath,
225  dif_toggle_t enabled);
226 /**
227  * Sends bytes over UART.
228  *
229  * Can be used from inside an UART ISR.
230  *
231  * This function attempts to write `bytes_requested` number of bytes to the
232  * UART TX FIFO from `bytes_requested`, and passes `bytes_written` back to
233  * the caller. `bytes_written` is optional, NULL should be passed in if the
234  * value is not needed.
235  *
236  * @param uart A UART handle.
237  * @param data Data to be written.
238  * @param bytes_requested Number of bytes requested to be written by the caller.
239  * @param[out] bytes_written Number of bytes written (optional).
240  * @return The result of the operation.
241  */
243 dif_result_t dif_uart_bytes_send(const dif_uart_t *uart, const uint8_t *data,
244  size_t bytes_requested, size_t *bytes_written);
245 
246 /**
247  * Recieves bytes over UART.
248  *
249  * Can be used from inside an UART ISR.
250  *
251  * This function attempts to read `bytes_requested` number of bytes from the
252  * UART RX FIFO into `data`, and passes `bytes_read` back to the caller.
253  * `bytes_read` is optional, NULL should be passed in if the value is not
254  * needed.
255  *
256  * @param uart A UART handle.
257  * @param bytes_requested Number of bytes requested to be read by the caller.
258  * @param[out] data Buffer for up to `bytes_requested` bytes of read data.
259  * @param[out] bytes_read Number of bytes read (optional).
260  * @return The result of the operation.
261  */
264  size_t bytes_requested, uint8_t *data,
265  size_t *bytes_read);
266 
267 /**
268  * Transmits a single UART byte (polled).
269  *
270  * This operation is polled, and will busy wait until a byte has been sent.
271  *
272  * Must not be used inside an ISR.
273  *
274  * @param uart A UART handle.
275  * @param byte Byte to be transmitted.
276  * @return The result of the operation.
277  */
279 dif_result_t dif_uart_byte_send_polled(const dif_uart_t *uart, uint8_t byte);
280 
281 /**
282  * Receives a single UART byte (polled).
283  *
284  * This operation is polled, and will busy wait until a byte has been read.
285  *
286  * Must not be used inside an ISR.
287  *
288  * @param uart A UART handle.
289  * @param[out] byte Received byte.
290  * @return The result of the operation.
291  */
294  uint8_t *byte);
295 
296 /**
297  * Gets the number of bytes available to be read from the UART RX FIFO.
298  *
299  * This function can be used to check FIFO full and empty conditions.
300  *
301  * @param uart A UART handle.
302  * @param[out] num_bytes Number of bytes available to be read.
303  * @return The result of the operation.
304  */
307  size_t *num_bytes);
308 
309 /**
310  * Gets the number of bytes available to be written from the UART TX FIFO.
311  *
312  * This function can be used to check FIFO full and empty conditions.
313  *
314  * @param uart A UART handle.
315  * @param[out] num_bytes Number of bytes available to be written.
316  * @return The result of the operation.
317  */
320  size_t *num_bytes);
321 
322 /**
323  * Resets one or both datapath FIFOs. If the byte is in transit, this function
324  * will not abort the operation.
325  *
326  * @param uart A UART handle.
327  * @param fifo The FIFO to reset (RX, TX or both).
328  * @return The result of the operation.
329  */
332  dif_uart_datapath_t fifo);
333 
334 /**
335  * Enables or disables a transmit/receive loopback.
336  *
337  * This API can be used for testing, such as to validate transmit and receive
338  * routines.
339  *
340  * Loopback should only be enabled when device is in the IDLE state to prevent
341  * data loss/coruption. Behaviour depends on the `loopback` parameter:
342  * - `kDifUartLoopbackSystem`:
343  * Receives the data that is being transmitted. No external data can be
344  * received (from the RX line). When enabled the TX line goes high.
345  * - `kDifUartLoopbackLine`:
346  * Transmits the data that is being received. No internal data can be
347  * sent out (from the TX FIFO). When enabled the RX line goes high.
348  *
349  * @param uart A UART handle.
350  * @param loopback Loopback type (transmit/receive).
351  * @param enable Enable/disable control flag.
352  * @return The result of the operation.
353  */
356  dif_uart_loopback_t loopback,
357  dif_toggle_t enable);
358 
359 /**
360  * Enables the RX timeout with the given duration.
361  *
362  * @param uart A UART handle.
363  * @param duration_ticks RX timeout value in UART bit times (using the baud rate
364  * clock as reference) in the range [0,0xffffff].
365  * @return The result of the operation.
366  */
369  uint32_t duration_ticks);
370 
371 /**
372  * Disables the RX timeout.
373  *
374  * In addition to disabling the RX timeout the timeout duration is reset to 0
375  * ticks.
376  *
377  * @param uart A UART handle.
378  * @return The result of the operation.
379  */
382 
383 /**
384  * Gets the current status of the RX timeout control.
385  *
386  * @param uart A UART handle.
387  * @param[out] status The status of the RX timeout control (enabled or
388  * disabled).
389  * @param[out] duration_ticks RX timeout value in UART bit times (using the baud
390  * rate clock as reference) in the range [0,0xffffff] (optional).
391  * @return The result of the operation.
392  */
396  uint32_t *duration_ticks);
397 
398 #ifdef __cplusplus
399 } // extern "C"
400 #endif // __cplusplus
401 
402 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_UART_H_