Software APIs
dif_uart.h
Go to the documentation of this file.
1 // Copyright lowRISC contributors.
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 
17 
18 // Header Extern Guard (so header can be used from C and C++)
19 #ifdef __cplusplus
20 extern "C" {
21 #endif // __cplusplus
22 
23 /**
24  * A toggle state: enabled, or disabled.
25  *
26  * This enum may be used instead of a `bool` when describing an enabled/disabled
27  * state.
28  */
29 typedef enum dif_uart_toggle {
30  /**
31  * The "enabled" state.
32  */
34  /**
35  * The "disabled" state.
36  */
39 
40 /**
41  * A parity state: odd, or even.
42  */
43 typedef enum dif_uart_parity {
44  /**
45  * Indicates the "odd" parity.
46  */
48  /**
49  * Indicates the "even" parity.
50  */
53 
54 /**
55  * Hardware instantiation parameters for UART.
56  *
57  * This struct describes information about the underlying hardware that is
58  * not determined until the hardware design is used as part of a top-level
59  * design.
60  */
61 typedef struct dif_uart_params {
62  /**
63  * The base address for the UART hardware registers.
64  */
67 
68 /**
69  * Runtime configuration for UART.
70  *
71  * This struct describes runtime information for one-time configuration of the
72  * hardware.
73  */
74 typedef struct dif_uart_config {
75  /**
76  * The UART baudrate.
77  */
78  uint32_t baudrate;
79  /**
80  * The frequency of the clock driving the UART.
81  */
82  uint32_t clk_freq_hz;
83  /**
84  * Whether to enable parity checking.
85  */
86  dif_uart_toggle_t parity_enable;
87  /**
88  * The parity to set.
89  */
90  dif_uart_parity_t parity;
92 
93 /**
94  * A handle to UART.
95  *
96  * This type should be treated as opaque by users.
97  */
98 typedef struct dif_uart { dif_uart_params_t params; } dif_uart_t;
99 
100 /**
101  * The result of a UART operation.
102  */
103 typedef enum dif_uart_result {
104  /**
105  * Indicates that the operation succeeded.
106  */
108  /**
109  * Indicates some unspecified failure.
110  */
112  /**
113  * Indicates that some parameter passed into a function failed a
114  * precondition.
115  *
116  * When this value is returned, no hardware operations occured.
117  */
120 
121 /**
122  * The result of a UART operation.
123  */
125  /**
126  * Indicates that the operation succeeded.
127  */
129  /**
130  * Indicates some unspecified failure.
131  */
133  /**
134  * Indicates that some parameter passed into a function failed a
135  * precondition.
136  *
137  * When this value is returned, no hardware operations occured.
138  */
140  /**
141  * Indicates that the given configuration parameters are not valid.
142  */
144  /**
145  * Indicates that the calculated NCO value was not valid.
146  */
149 
150 /**
151  * A UART interrupt request type.
152  */
153 typedef enum dif_uart_irq {
154  /**
155  * Fired when the TX FIFO dips below its watermark.
156  */
158  /**
159  * Fired when the RX FIFO goes over its watermark.
160  */
162  /**
163  * Fired when the TX FIFO is empty.
164  */
166  /**
167  * Fired when the RX FIFO overflows.
168  */
170  /**
171  * Fired when an RX framing error occurs.
172  */
174  /**
175  * Fired to indicate an RX break condition.
176  */
178  /**
179  * Fired when the RX FIFO timeout expires before it is emptied.
180  */
182  /**
183  * Fired when an RX parity error is detected.
184  */
187 
188 /**
189  * A snapshot of the enablement state of the interrupts for UART.
190  *
191  * This is an opaque type, to be used with the `dif_uart_irq_disable_all()` and
192  * `dif_uart_irq_restore_all()` functions.
193  */
194 typedef uint32_t dif_uart_irq_snapshot_t;
195 
196 /**
197  * A UART FIFO watermark depth configuration.
198  */
199 typedef enum dif_uart_watermark {
200  /**
201  * Indicates a one-byte watermark.
202  */
204  /**
205  * Indicates a four-byte watermark.
206  */
208  /**
209  * Indicates an eight-byte watermark.
210  */
212  /**
213  * Indicates a sixteen-byte watermark.
214  */
216  /**
217  * Indicates a thirty-byte watermark.
218  */
221 
222 /**
223  * A UART FIFO reset selection.
224  */
225 typedef enum dif_uart_fifo_reset {
226  /**
227  * Indicates that the RX FIFO should be reset.
228  */
230  /**
231  * Indicates that the TX FIFO should be reset.
232  */
234  /**
235  * Indicates that both FIFOs should be reset.
236  */
239 
240 /**
241  * A UART system/line loopback configuration.
242  */
243 typedef enum dif_uart_loopback {
244  /**
245  * Indicates that outgoing TX bits should be recieved through RX.
246  */
248  /**
249  * Indicates that incoming RX bits should be forwarded to TX.
250  */
253 
254 /**
255  * The size of the UART TX and RX FIFOs, in bytes.
256  */
257 extern const uint32_t kDifUartFifoSizeBytes;
258 
259 /**
260  * Creates a new handle for UART.
261  *
262  * This function does not actuate the hardware.
263  *
264  * @param params Hardware instantiation parameters.
265  * @param uart Out param for the initialized handle.
266  * @return The result of the operation.
267  */
270 
271 /**
272  * Configures UART with runtime information.
273  *
274  * This function should need to be called once for the lifetime of `handle`.
275  *
276  * @param uart A UART handle.
277  * @param config Runtime configuration parameters.
278  * @return The result of the operation.
279  */
281 dif_uart_config_result_t dif_uart_configure(const dif_uart_t *uart,
282  dif_uart_config_t config);
283 
284 /**
285  * Returns whether a particular interrupt is currently pending.
286  *
287  * @param uart A UART handle.
288  * @param irq An interrupt type.
289  * @param is_pending Out-param for whether the interrupt is pending.
290  * @return The result of the operation.
291  */
294  dif_uart_irq_t irq, bool *is_pending);
295 
296 /**
297  * Acknowledges a particular interrupt, indicating to the hardware that it has
298  * been successfully serviced.
299  *
300  * @param uart A UART handle.
301  * @param irq An interrupt type.
302  * @return The result of the operation.
303  */
306  dif_uart_irq_t irq);
307 
308 /**
309  * Checks whether a particular interrupt is currently enabled or disabled.
310  *
311  * @param uart A UART handle.
312  * @param irq An interrupt type.
313  * @param state Out-param toggle state of the interrupt.
314  * @return The result of the operation.
315  */
318  dif_uart_irq_t irq,
319  dif_uart_toggle_t *state);
320 
321 /**
322  * Sets whether a particular interrupt is currently enabled or disabled.
323  *
324  * @param uart A UART handle.
325  * @param irq An interrupt type.
326  * @param state The new toggle state for the interrupt.
327  * @return The result of the operation.
328  */
331  dif_uart_irq_t irq,
332  dif_uart_toggle_t state);
333 
334 /**
335  * Forces a particular interrupt, causing it to be serviced as if hardware had
336  * asserted it.
337  *
338  * @param uart A UART handle.
339  * @param irq An interrupt type.
340  * @return The result of the operation.
341  */
344  dif_uart_irq_t irq);
345 
346 /**
347  * Disables all interrupts, optionally snapshotting all toggle state for later
348  * restoration.
349  *
350  * @param uart A UART handle.
351  * @param snapshot Out-param for the snapshot; may be `NULL`.
352  * @return The result of the operation.
353  */
356  dif_uart_irq_snapshot_t *snapshot);
357 
358 /**
359  * Restores interrupts from the given snapshot.
360  *
361  * This function can be used with `dif_uart_irq_disable_all()` to temporary
362  * interrupt save-and-restore.
363  *
364  * @param uart A UART handle.
365  * @param snapshot A snapshot to restore from.
366  * @return The result of the operation.
367  */
370  const dif_uart_t *uart, const dif_uart_irq_snapshot_t *snapshot);
371 
372 /**
373  * Sets the RX FIFO watermark.
374  *
375  * This function is only useful when the corresponding interrupt is enabled.
376  * When the queued RX FIFO number of bytes rises to or above this
377  * level, the RX watermark interrupt is raised.
378  *
379  * @param uart A UART handle.
380  * @param watermark RX FIFO watermark.
381  * @return The result of the operation.
382  */
385  dif_uart_watermark_t watermark);
386 
387 /**
388  * Sets the TX FIFO watermark.
389  *
390  * This function is only useful when the corresponding interrupt is enabled.
391  * When the queued RX FIFO number of bytes rises to or above this
392  * level, the RX watermark interrupt is raised.
393  *
394  * @param uart A UART handle.
395  * @param watermark TX FIFO watermark.
396  * @return The result of the operation.
397  */
400  dif_uart_watermark_t watermark);
401 
402 /**
403  * Sends bytes over UART.
404  *
405  * Can be used from inside an UART ISR.
406  *
407  * This function attempts to write `bytes_requested` number of bytes to the
408  * UART TX FIFO from `bytes_requested`, and passes `bytes_written` back to
409  * the caller. `bytes_written` is optional, NULL should be passed in if the
410  * value is not needed.
411  *
412  * @param uart A UART handle.
413  * @param data Data to be written.
414  * @param bytes_requested Number of bytes requested to be written by the caller.
415  * @param[out] bytes_written Number of bytes written (optional).
416  * @return The result of the operation.
417  */
420  const uint8_t *data,
421  size_t bytes_requested,
422  size_t *bytes_written);
423 
424 /**
425  * Recieves bytes over UART.
426  *
427  * Can be used from inside an UART ISR.
428  *
429  * This function attempts to read `bytes_requested` number of bytes from the
430  * UART RX FIFO into `data`, and passes `bytes_read` back to the caller.
431  * `bytes_read` is optional, NULL should be passed in if the value is not
432  * needed.
433  *
434  * @param uart A UART handle.
435  * @param bytes_requested Number of bytes requested to be read by the caller.
436  * @param[out] data Buffer for up to `bytes_requested` bytes of read data.
437  * @param[out] bytes_read Number of bytes read (optional).
438  * @return The result of the operation.
439  */
442  size_t bytes_requested, uint8_t *data,
443  size_t *bytes_read);
444 
445 /**
446  * Transmits a single UART byte (polled).
447  *
448  * This operation is polled, and will busy wait until a byte has been sent.
449  *
450  * Must not be used inside an ISR.
451  *
452  * @param uart A UART handle.
453  * @param byte Byte to be transmitted.
454  * @return The result of the operation.
455  */
458  uint8_t byte);
459 
460 /**
461  * Receives a single UART byte (polled).
462  *
463  * This operation is polled, and will busy wait until a byte has been read.
464  *
465  * Must not be used inside an ISR.
466  *
467  * @param uart A UART handle.
468  * @param[out] byte Received byte.
469  * @return The result of the operation.
470  */
473  uint8_t *byte);
474 
475 /**
476  * Gets the number of bytes available to be read from the UART RX FIFO.
477  *
478  * This function can be used to check FIFO full and empty conditions.
479  *
480  * @param uart A UART handle.
481  * @param[out] num_bytes Number of bytes available to be read.
482  * @return The result of the operation.
483  */
486  size_t *num_bytes);
487 
488 /**
489  * Gets the number of bytes available to be written from the UART TX FIFO.
490  *
491  * This function can be used to check FIFO full and empty conditions.
492  *
493  * @param uart A UART handle.
494  * @param[out] num_bytes Number of bytes available to be written.
495  * @return The result of the operation.
496  */
499  size_t *num_bytes);
500 /**
501  * UART TX reset RX/TX FIFO.
502  *
503  * Reset both FIFOs, or the requested one.
504  *
505  * @param uart A UART handle.
506  * @param reset FIFO to reset (RX or TX).
507  * @return The result of the operation.
508  */
510  dif_uart_fifo_reset_t reset);
511 
512 /**
513  * Enables or disables a transmit/receive loopback.
514  *
515  * This API can be used for testing, such as to validate transmit and receive
516  * routines.
517  *
518  * Loopback should only be enabled when device is in the IDLE state to prevent
519  * data loss/coruption. Behaviour depends on the `loopback` parameter:
520  * - `kDifUartLoopbackSystem`:
521  * Receives the data that is being transmitted. No external data can be
522  * received (from the RX line). When enabled the TX line goes high.
523  * - `kDifUartLoopbackLine`:
524  * Transmits the data that is being received. No internal data can be
525  * sent out (from the TX FIFO). When enabled the RX line goes high.
526  *
527  * @param uart A UART handle.
528  * @param loopback Loopback type (transmit/receive).
529  * @param enable Enable/disable control flag.
530  * @return The result of the operation.
531  */
533  dif_uart_loopback_t loopback,
534  dif_uart_toggle_t enable);
535 
536 #ifdef __cplusplus
537 } // extern "C"
538 #endif // __cplusplus
539 
540 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_UART_H_