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 #ifdef __cplusplus
19 extern "C" {
20 #endif // __cplusplus
21 
22 /**
23  * A toggle state: enabled, or disabled.
24  *
25  * This enum may be used instead of a `bool` when describing an enabled/disabled
26  * state.
27  */
28 typedef enum dif_uart_toggle {
29  /**
30  * The "enabled" state.
31  */
33  /**
34  * The "disabled" state.
35  */
38 
39 /**
40  * A parity state: odd, or even.
41  */
42 typedef enum dif_uart_parity {
43  /**
44  * Indicates the "odd" parity.
45  */
47  /**
48  * Indicates the "even" parity.
49  */
52 
53 /**
54  * Hardware instantiation parameters for UART.
55  *
56  * This struct describes information about the underlying hardware that is
57  * not determined until the hardware design is used as part of a top-level
58  * design.
59  */
60 typedef struct dif_uart_params {
61  /**
62  * The base address for the UART hardware registers.
63  */
66 
67 /**
68  * Runtime configuration for UART.
69  *
70  * This struct describes runtime information for one-time configuration of the
71  * hardware.
72  */
73 typedef struct dif_uart_config {
74  /**
75  * The UART baudrate.
76  */
77  uint32_t baudrate;
78  /**
79  * The frequency of the clock driving the UART.
80  */
81  uint32_t clk_freq_hz;
82  /**
83  * Whether to enable parity checking.
84  */
85  dif_uart_toggle_t parity_enable;
86  /**
87  * The parity to set.
88  */
89  dif_uart_parity_t parity;
91 
92 /**
93  * A handle to UART.
94  *
95  * This type should be treated as opaque by users.
96  */
97 typedef struct dif_uart { dif_uart_params_t params; } dif_uart_t;
98 
99 /**
100  * The result of a UART operation.
101  */
102 typedef enum dif_uart_result {
103  /**
104  * Indicates that the operation succeeded.
105  */
107  /**
108  * Indicates some unspecified failure.
109  */
111  /**
112  * Indicates that some parameter passed into a function failed a
113  * precondition.
114  *
115  * When this value is returned, no hardware operations occurred.
116  */
119 
120 /**
121  * The result of a UART operation.
122  */
124  /**
125  * Indicates that the operation succeeded.
126  */
128  /**
129  * Indicates some unspecified failure.
130  */
132  /**
133  * Indicates that some parameter passed into a function failed a
134  * precondition.
135  *
136  * When this value is returned, no hardware operations occurred.
137  */
139  /**
140  * Indicates that the given configuration parameters are not valid.
141  */
143  /**
144  * Indicates that the calculated NCO value was not valid.
145  */
148 
149 /**
150  * A UART interrupt request type.
151  */
152 typedef enum dif_uart_irq {
153  /**
154  * Fired when the TX FIFO dips below its watermark.
155  */
157  /**
158  * Fired when the RX FIFO goes over its watermark.
159  */
161  /**
162  * Fired when the TX FIFO is empty.
163  */
165  /**
166  * Fired when the RX FIFO overflows.
167  */
169  /**
170  * Fired when an RX framing error occurs.
171  */
173  /**
174  * Fired to indicate an RX break condition.
175  */
177  /**
178  * Fired when the RX FIFO timeout expires before it is emptied.
179  */
181  /**
182  * Fired when an RX parity error is detected.
183  */
186 
187 /**
188  * A snapshot of the enablement state of the interrupts for UART.
189  *
190  * This is an opaque type, to be used with the `dif_uart_irq_disable_all()` and
191  * `dif_uart_irq_restore_all()` functions.
192  */
193 typedef uint32_t dif_uart_irq_snapshot_t;
194 
195 /**
196  * A UART FIFO watermark depth configuration.
197  */
198 typedef enum dif_uart_watermark {
199  /**
200  * Indicates a one-byte watermark.
201  */
203  /**
204  * Indicates a four-byte watermark.
205  */
207  /**
208  * Indicates an eight-byte watermark.
209  */
211  /**
212  * Indicates a sixteen-byte watermark.
213  */
215  /**
216  * Indicates a thirty-byte watermark.
217  */
220 
221 /**
222  * A UART FIFO reset selection.
223  */
224 typedef enum dif_uart_fifo_reset {
225  /**
226  * Indicates that the RX FIFO should be reset.
227  */
229  /**
230  * Indicates that the TX FIFO should be reset.
231  */
233  /**
234  * Indicates that both FIFOs should be reset.
235  */
238 
239 /**
240  * A UART system/line loopback configuration.
241  */
242 typedef enum dif_uart_loopback {
243  /**
244  * Indicates that outgoing TX bits should be recieved through RX.
245  */
247  /**
248  * Indicates that incoming RX bits should be forwarded to TX.
249  */
252 
253 /**
254  * The size of the UART TX and RX FIFOs, in bytes.
255  */
256 extern const uint32_t kDifUartFifoSizeBytes;
257 
258 /**
259  * Creates a new handle for UART.
260  *
261  * This function does not actuate the hardware.
262  *
263  * @param params Hardware instantiation parameters.
264  * @param uart Out param for the initialized handle.
265  * @return The result of the operation.
266  */
269 
270 /**
271  * Configures UART with runtime information.
272  *
273  * This function should need to be called once for the lifetime of `handle`.
274  *
275  * @param uart A UART handle.
276  * @param config Runtime configuration parameters.
277  * @return The result of the operation.
278  */
280 dif_uart_config_result_t dif_uart_configure(const dif_uart_t *uart,
281  dif_uart_config_t config);
282 
283 /**
284  * Returns whether a particular interrupt is currently pending.
285  *
286  * @param uart A UART handle.
287  * @param irq An interrupt type.
288  * @param is_pending Out-param for whether the interrupt is pending.
289  * @return The result of the operation.
290  */
293  dif_uart_irq_t irq, bool *is_pending);
294 
295 /**
296  * Acknowledges a particular interrupt, indicating to the hardware that it has
297  * been successfully serviced.
298  *
299  * @param uart A UART handle.
300  * @param irq An interrupt type.
301  * @return The result of the operation.
302  */
305  dif_uart_irq_t irq);
306 
307 /**
308  * Checks whether a particular interrupt is currently enabled or disabled.
309  *
310  * @param uart A UART handle.
311  * @param irq An interrupt type.
312  * @param state Out-param toggle state of the interrupt.
313  * @return The result of the operation.
314  */
317  dif_uart_irq_t irq,
318  dif_uart_toggle_t *state);
319 
320 /**
321  * Sets whether a particular interrupt is currently enabled or disabled.
322  *
323  * @param uart A UART handle.
324  * @param irq An interrupt type.
325  * @param state The new toggle state for the interrupt.
326  * @return The result of the operation.
327  */
330  dif_uart_irq_t irq,
331  dif_uart_toggle_t state);
332 
333 /**
334  * Forces a particular interrupt, causing it to be serviced as if hardware had
335  * asserted it.
336  *
337  * @param uart A UART handle.
338  * @param irq An interrupt type.
339  * @return The result of the operation.
340  */
343  dif_uart_irq_t irq);
344 
345 /**
346  * Disables all interrupts, optionally snapshotting all toggle state for later
347  * restoration.
348  *
349  * @param uart A UART handle.
350  * @param snapshot Out-param for the snapshot; may be `NULL`.
351  * @return The result of the operation.
352  */
355  dif_uart_irq_snapshot_t *snapshot);
356 
357 /**
358  * Restores interrupts from the given snapshot.
359  *
360  * This function can be used with `dif_uart_irq_disable_all()` to temporary
361  * interrupt save-and-restore.
362  *
363  * @param uart A UART handle.
364  * @param snapshot A snapshot to restore from.
365  * @return The result of the operation.
366  */
369  const dif_uart_t *uart, const dif_uart_irq_snapshot_t *snapshot);
370 
371 /**
372  * Sets the RX FIFO watermark.
373  *
374  * This function is only useful when the corresponding interrupt is enabled.
375  * When the queued RX FIFO number of bytes rises to or above this
376  * level, the RX watermark interrupt is raised.
377  *
378  * @param uart A UART handle.
379  * @param watermark RX FIFO watermark.
380  * @return The result of the operation.
381  */
384  dif_uart_watermark_t watermark);
385 
386 /**
387  * Sets the TX FIFO watermark.
388  *
389  * This function is only useful when the corresponding interrupt is enabled.
390  * When the queued RX FIFO number of bytes rises to or above this
391  * level, the RX watermark interrupt is raised.
392  *
393  * @param uart A UART handle.
394  * @param watermark TX FIFO watermark.
395  * @return The result of the operation.
396  */
399  dif_uart_watermark_t watermark);
400 
401 /**
402  * Sends bytes over UART.
403  *
404  * Can be used from inside an UART ISR.
405  *
406  * This function attempts to write `bytes_requested` number of bytes to the
407  * UART TX FIFO from `bytes_requested`, and passes `bytes_written` back to
408  * the caller. `bytes_written` is optional, NULL should be passed in if the
409  * value is not needed.
410  *
411  * @param uart A UART handle.
412  * @param data Data to be written.
413  * @param bytes_requested Number of bytes requested to be written by the caller.
414  * @param[out] bytes_written Number of bytes written (optional).
415  * @return The result of the operation.
416  */
419  const uint8_t *data,
420  size_t bytes_requested,
421  size_t *bytes_written);
422 
423 /**
424  * Recieves bytes over UART.
425  *
426  * Can be used from inside an UART ISR.
427  *
428  * This function attempts to read `bytes_requested` number of bytes from the
429  * UART RX FIFO into `data`, and passes `bytes_read` back to the caller.
430  * `bytes_read` is optional, NULL should be passed in if the value is not
431  * needed.
432  *
433  * @param uart A UART handle.
434  * @param bytes_requested Number of bytes requested to be read by the caller.
435  * @param[out] data Buffer for up to `bytes_requested` bytes of read data.
436  * @param[out] bytes_read Number of bytes read (optional).
437  * @return The result of the operation.
438  */
441  size_t bytes_requested, uint8_t *data,
442  size_t *bytes_read);
443 
444 /**
445  * Transmits a single UART byte (polled).
446  *
447  * This operation is polled, and will busy wait until a byte has been sent.
448  *
449  * Must not be used inside an ISR.
450  *
451  * @param uart A UART handle.
452  * @param byte Byte to be transmitted.
453  * @return The result of the operation.
454  */
457  uint8_t byte);
458 
459 /**
460  * Receives a single UART byte (polled).
461  *
462  * This operation is polled, and will busy wait until a byte has been read.
463  *
464  * Must not be used inside an ISR.
465  *
466  * @param uart A UART handle.
467  * @param[out] byte Received byte.
468  * @return The result of the operation.
469  */
472  uint8_t *byte);
473 
474 /**
475  * Gets the number of bytes available to be read from the UART RX FIFO.
476  *
477  * This function can be used to check FIFO full and empty conditions.
478  *
479  * @param uart A UART handle.
480  * @param[out] num_bytes Number of bytes available to be read.
481  * @return The result of the operation.
482  */
485  size_t *num_bytes);
486 
487 /**
488  * Gets the number of bytes available to be written from the UART TX FIFO.
489  *
490  * This function can be used to check FIFO full and empty conditions.
491  *
492  * @param uart A UART handle.
493  * @param[out] num_bytes Number of bytes available to be written.
494  * @return The result of the operation.
495  */
498  size_t *num_bytes);
499 /**
500  * UART TX reset RX/TX FIFO.
501  *
502  * Resets one or both FIFOs. If the byte is in transit, this function will
503  * not abort the operation.
504  *
505  * @param uart A UART handle.
506  * @param reset FIFO to reset (RX, TX or both).
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 /**
537  * Enables the RX timeout with the given duration.
538  *
539  * @param uart A UART handle.
540  * @param duration_ticks RX timeout value in UART bit times (using the baud rate
541  * clock as reference) in the range [0,0xffffff].
542  * @return The result of the operation.
543  */
546  uint32_t duration_ticks);
547 
548 /**
549  * Disables the RX timeout.
550  *
551  * In addition to disabling the RX timeout the timeout duration is reset to 0
552  * ticks.
553  *
554  * @param uart A UART handle.
555  * @return The result of the operation.
556  */
559 
560 /**
561  * Gets the current status of the RX timeout control.
562  *
563  * @param uart A UART handle.
564  * @param[out] status The status of the RX timeout control (enabled or
565  * disabled).
566  * @param[out] duration_ticks RX timeout value in UART bit times (using the baud
567  * rate clock as reference) in the range [0,0xffffff] (optional).
568  * @return The result of the operation.
569  */
572  dif_uart_toggle_t *status,
573  uint32_t *duration_ticks);
574 
575 #ifdef __cplusplus
576 } // extern "C"
577 #endif // __cplusplus
578 
579 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_UART_H_