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