forked from lowRISC/opentitan
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dif_pinmux.h
509 lines (475 loc) · 17.3 KB
/
dif_pinmux.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
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
// 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_PINMUX_H_
#define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_PINMUX_H_
/**
* @file
* @brief <a href="/hw/ip/pinmux/doc/">Pin Multiplexer</a> Device Interface
* Functions
*/
/**
* Pin Multiplexer connects peripheral input/output signals to the Padring MIO
* pad input/output signals.
*
* Every peripheral input signal is fed into a multiplexer, where selects
* determine which Padring MIO pad input or constants should be connected to it.
*
* Every Padring MIO pad output signal is fed into a multiplexer, where selects
* determine which peripheral output or constants should be connected to it.
*/
#include <stdbool.h>
#include <stdint.h>
#include "sw/device/lib/base/macros.h"
#include "sw/device/lib/base/mmio.h"
#include "sw/device/lib/dif/dif_base.h"
#include "sw/device/lib/dif/autogen/dif_pinmux_autogen.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
/**
* Pin Multiplexer Padring pad kinds.
*
* A pad can be a Multiplexed (MIO) or Dedicated (DIO).
*/
typedef enum dif_pinmux_pad_kind {
/**
* Multiplexed Input/Output pad. Connected to a peripheral input or output
* via a multiplexer matrix inside the a Pin Multiplexer.
*/
kDifPinmuxPadKindMio = 0,
/**
* Dedicated Input/Output pad. Connected directly to a peripheral input
* or output, bypassing the multiplexer matrix.
*/
kDifPinmuxPadKindDio,
kDifPinmuxPadKindCount,
} dif_pinmux_pad_kind_t;
/**
* Pin Multiplexer functionality locking.
*
* Represents a target functionality to be locked for a given
* pad/peripheral input.
*/
typedef enum dif_pinmux_lock_target {
/**
* Lock MIO pad input select for a given peripheral input. This means that
* the peripheral input connection can no longer be changed.
*/
kDifPinmuxLockTargetInsel = 0,
/**
* Lock peripheral output select for a given MIO pad output. This means
* that the MIO pad output connection can no longer be changed.
*/
kDifPinmuxLockTargetOutsel,
/**
* Lock the sleep mode configuration for a given MIO pad.
*/
kDifPinmuxLockTargetMioSleep,
/**
* Lock the sleep mode configuration for a given DIO pad.
*/
kDifPinmuxLockTargetDioSleep,
/**
* Lock physical characteristics configuration for a given MIO pad.
*/
kDifPinmuxLockTargetMioPadAttr,
/**
* Lock physical characteristics configuration for a given DIO pad.
*/
kDifPinmuxLockTargetDioPadAttr,
/**
* Lock wake-up detector configuration for a given detector.
*/
kDifPinmuxLockTargetWakeupDetector,
} dif_pinmux_lock_target_t;
/**
* Pin Multiplexer generic index.
*
* The meaning of this index changes between APIs, and must be documented in
* the corresponding function description.
*/
typedef uint32_t dif_pinmux_index_t;
/**
* Pad slew rate value.
*
* This selects between available slew rate values, where the largest number
* produces the fastest slew rate. See the device's data sheet for the
* particular mapping.
*/
typedef uint8_t dif_pinmux_pad_slew_rate_t;
/**
* Pad drive strength value.
*
* This selects between available drive strength values, where the largest
* number produces the highest drive strength. See the device's data sheet for
* the particular mapping.
*/
typedef uint8_t dif_pinmux_pad_drive_strength_t;
/**
* Pad attribute flag values
*
* This `enum` is a bitfield, meaning that it is allowed to pass combined value
* of multiple individual attributes.
*
* Some attributes have defined meanings, others are implementation defined. Not
* all pads will support all attributes, or attribute combinations. The Pin
* Multiplexer DIF checks for conflicting or unsupported attributes provided by
* the Write-Any Read-Legal (WARL) semantics of the underlying hardware. If the
* combination of attributes is not supported - some/all of these attributes
* will still be disabled (relevant bit unset in the attribute field).
*
* IMPORTANT:
* - Functions are used to toggle these attributes, must signal an error if at
* least one of the attributes in the bitfield could not be toggled.
*/
typedef enum dif_pinmux_pad_attr_flags {
kDifPinmuxPadAttrInvertLevel = 1 << 0,
kDifPinmuxPadAttrVirtualOpenDrain = 1 << 1,
kDifPinmuxPadAttrPullResistorEnable = 1 << 2,
kDifPinmuxPadAttrPullResistorUp = 1 << 3,
kDifPinmuxPadAttrKeeper = 1 << 4,
kDifPinmuxPadAttrSchmittTrigger = 1 << 5,
kDifPinmuxPadAttrOpenDrain = 1 << 6,
} dif_pinmux_pad_attr_flags_t;
/**
* Pin multiplexer padring pad attributes.
*/
typedef struct dif_pinmux_pad_attr {
/**
* Slew rate attribute. A greater number produces a faster slew rate.
*/
dif_pinmux_pad_slew_rate_t slew_rate;
/**
* Drive strength pad attribute. A greater number produces a stronger drive.
*/
dif_pinmux_pad_drive_strength_t drive_strength;
/**
* A bit map of single-bit attribute flags. See dif_pinmux_pad_attr_flags_t
* for the mapping and definitions.
*/
dif_pinmux_pad_attr_flags_t flags;
} dif_pinmux_pad_attr_t;
/**
* A sleep mode for a Padring DIO/MIO pad.
*
* This determines the behaviour of a pad in deep sleep state.
*
* NOTE:
* After the chip has come back from deep sleep, the mode of the pad
* persists until it is explicitly cleared by `dif_pinmux_sleep_clear_state`.
* Calling `dif_pinmux_sleep_enable` will configure the pad mode for
* the next deep sleep, however it will not change the current mode.
*/
typedef enum dif_pinmux_sleep_mode {
/**
* The pad is driven actively to zero.
*/
kDifPinmuxSleepModeLow = 0,
/**
* The pad is driven actively to one.
*/
kDifPinmuxSleepModeHigh,
/**
* The pad is left undriven. Note that the actual driving behaviour will
* depend on the pull-up/-down configuration.
*/
kDifPinmuxSleepModeHighZ,
/**
* Keep last driven value (including high-Z).
*/
kDifPinmuxSleepModeKeep,
kDifPinmuxSleepModeCount,
} dif_pinmux_sleep_mode_t;
/**
* A Pin Multiplexer wake-up detection mode (edge triggered).
*/
typedef enum dif_pinmux_wakeup_mode {
/**
* Trigger a wakeup request when observing a positive edge.
*/
kDifPinmuxWakeupModePositiveEdge = 0,
/**
* Trigger a wakeup request when observing a negative edge.
*/
kDifPinmuxWakeupModeNegativeEdge,
/**
* Trigger a wakeup request when observing an edge in any direction.
*/
kDifPinmuxWakeupModeAnyEdge,
/**
* Trigger a wakeup request when pin is driven HIGH for a certain amount of
* always-on clock cycles as configured in
* `dif_pinmux_wakeup_timed_config_t`, `counter_threshold` field.
*/
kDifPinmuxWakeupModeTimedHigh,
/**
* Trigger a wakeup request when pin is driven LOW for a certain amount of
* always-on clock cycles as configured in
* `dif_pinmux_wakeup_timed_config_t`, `counter_threshold` field.
*/
kDifPinmuxWakeupModeTimedLow,
kDifPinmuxWakeupModeCount,
} dif_pinmux_wakeup_mode_t;
/**
* A Pin Multiplexer common wake-up configuration between different modes.
*/
typedef struct dif_pinmux_wakeup_config {
/**
* Signal filter - signal must be stable for 4 always-on clock cycles
* before the value is being forwarded. Can be used for debouncing.
*/
dif_toggle_t signal_filter;
/**
* Pad type (MIO or DIO) to enable the wake-up detection for.
*/
dif_pinmux_pad_kind_t pad_type;
/**
* Selects a specific pad. In the case of MIO, the pad select index is the
* same as used for `dif_pinmux_input_select`, meaning that index 0 and 1 just
* select constant 0, and the MIO pads live at indices >= 2. In the case of
* DIO pads, the pad select index corresponds 1:1 to the DIO pad to be
* selected.
*/
dif_pinmux_index_t pad_select;
/**
* Wake-up detection mode.
*/
dif_pinmux_wakeup_mode_t mode;
/**
* Counter threshold for `kDifPinmuxWakeupModeTimedLow` and
* `kDifPinmuxWakeupModeTimedHigh` wake-up detector modes. The threshold is in
* terms of always-on clock cycles.
*/
uint8_t counter_threshold;
} dif_pinmux_wakeup_config_t;
/**
* Locks out Pin Multiplexer functionality based on the `target` and `index`.
*
* This function allows for a fine grained locking of the Pin Multiplexer
* parts. `index` changes meaning dependent on the `target`. For example, when
* `target` is `kDifPinmuxLockTargetInsel`, `index` represents a peripheral
* input for which the MIO input select functionality should be locked.
*
* NOTE:
* Locking an already locked register will succeed with the `kDifOk`
* return code.
*
* @param pinmux A Pin Multiplexer handle.
* @param index Exact meaning is determined by the `target`, however, it
* represents one of the following: peripheral input index,
* MIO pad index, DIO pad index or a wakeup detector index.
* @param target Target functionality to be locked.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_pinmux_lock(const dif_pinmux_t *pinmux,
dif_pinmux_index_t index,
dif_pinmux_lock_target_t target);
/**
* Obtains the Pin Multiplexer Pad lock status based on `target` and `index`.
*
* @param pinmux A Pin Multiplexer handle.
* @param index Exact meaning is determined by the `target`, however, it
* represents one of the following: peripheral input index,
* MIO pad index, DIO pad index or a wakeup detector index.
* @param target Target functionality to be locked.
* @param[out] is_locked Out-param for the locked state.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_pinmux_is_locked(const dif_pinmux_t *pinmux,
dif_pinmux_index_t index,
dif_pinmux_lock_target_t target,
bool *is_locked);
/**
* Sets a connection between a peripheral input and a MIO pad input.
*
* A peripheral input can be connected to any available MIO pad input.
*
* @param pinmux A Pin Multiplexer handle.
* @param peripheral_input A Peripheral input index.
* @param insel Input connection select - a MIO pad input to be connected to
* a peripheral input.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_pinmux_input_select(const dif_pinmux_t *pinmux,
dif_pinmux_index_t peripheral_input,
dif_pinmux_index_t insel);
/**
* Sets a connection between a MIO pad output and peripheral output.
*
* A MIO pad output can be connected to any available peripheral output.
*
* @param pinmux A Pin Multiplexer handle.
* @param mio_pad_output Padring MIO output index.
* @param outsel Peripheral output connection select - a Peripheral output to be
* connected to a MIO pad output.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_pinmux_output_select(const dif_pinmux_t *pinmux,
dif_pinmux_index_t mio_pad_output,
dif_pinmux_index_t outsel);
/**
* Writes attributes for a pad.
*
* This function completely overwrites the existing configuration of a pad, and
* has both enable and disable semantics.
*
* Not all pads implement all attributes and some combinations cannot be
* enabled together. This function returns a `kDifBadArg` error in case of
* invalid `attrs_in`.
* Conflicting attributes will be discarded by the hardware, and can be
* identified by comparing `attrs_in` to `attrs_out`.
*
* IMPORTANT:
* See `dif_pinmux_pad_attr` for information on which attributes are compulsory
* and which invariants are mutually exclusive.
*
* @param pinmux A Pin Multiplexer handle.
* @param pad Pad index to write the attributes for.
* @param type Pad type (MIO or DIO).
* @param attrs_in Attribute values to write.
* @param attrs_out[out] The actual attributes written and accepted by the
* hardware.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_pinmux_pad_write_attrs(const dif_pinmux_t *pinmux,
dif_pinmux_index_t pad,
dif_pinmux_pad_kind_t type,
dif_pinmux_pad_attr_t attrs_in,
dif_pinmux_pad_attr_t *attrs_out);
/**
* Get attributes for a pad.
*
* @param pinmux A Pin Multiplexer handle.
* @param pad Pad index to obtain the attributes for.
* @param type Pad type (MIO or DIO).
* @param attrs[out] Obtained attributes.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_pinmux_pad_get_attrs(const dif_pinmux_t *pinmux,
dif_pinmux_index_t pad,
dif_pinmux_pad_kind_t type,
dif_pinmux_pad_attr_t *attrs);
/**
* Enables deep sleep mode of a particular pad.
*
* NOTE:
* After the chip has come back from deep sleep, the mode of a pad persists
* until is explicitly cleared by `dif_pinmux_pad_sleep_clear_state`. Calling
* `dif_pinmux_pad_sleep_enable` will configure a pad mode for the next deep
* sleep, however it will not change the current mode.
*
* @param pinmux A Pin Multiplexer handle.
* @param pad Pad index.
* @param type Pad type (MIO or DIO).
* @param mode Pad deep sleep mode.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_pinmux_pad_sleep_enable(const dif_pinmux_t *pinmux,
dif_pinmux_index_t pad,
dif_pinmux_pad_kind_t type,
dif_pinmux_sleep_mode_t mode);
/**
* Disables deep sleep mode of a particular pad.
*
* NOTE:
* After the chip has come back from deep sleep, the mode of a pad persists
* until is explicitly cleared by `dif_pinmux_pad_sleep_clear_state`. Calling
* `dif_pinmux_pad_sleep_enable` will configure a pad mode for the next deep
* sleep, however it will not change the current mode.
*
* @param pinmux A Pin Multiplexer handle.
* @param pad Pad index.
* @param type Pad type (MIO or DIO).
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_pinmux_pad_sleep_disable(const dif_pinmux_t *pinmux,
dif_pinmux_index_t pad,
dif_pinmux_pad_kind_t type);
/**
* Returns the state of a particular pad.
*
* When the pad is in deep sleep mode, the mode persists until is explicitly
* cleared via `dif_pinmux_pad_sleep_clear_state`.
*
* @param padmux A Pin Multiplexer handle.
* @param pad Pad index.
* @param type Padring pad type (MIO or DIO).
* @param[out] in_sleep_mode Pad state, `true` when in deep sleep mode.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_pinmux_pad_sleep_get_state(const dif_pinmux_t *pinmux,
dif_pinmux_index_t pad,
dif_pinmux_pad_kind_t type,
bool *in_sleep_mode);
/**
* Clears deep sleep mode for a particular pad.
*
* When deep sleep mode is enabled for a pad, and the device has entered deep
* sleep mode; upon wake-up, the deep sleep status of this pad can only be
* cleared by calling this function. Re-configuring this pad will only take
* effect during the next deep sleep.
*
* @param pinmux A Pin Multiplexer handle.
* @param pad Pad index.
* @param type Padring pad type (MIO or DIO).
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_pinmux_pad_sleep_clear_state(const dif_pinmux_t *pinmux,
dif_pinmux_index_t pad,
dif_pinmux_pad_kind_t type);
/**
* Enables wake-up mode detection for a particular detector.
*
* @param pinmux A Pin Multiplexer handle.
* @param detector A detector index.
* @param config A wake-up detector configuration.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_pinmux_wakeup_detector_enable(
const dif_pinmux_t *pinmux, dif_pinmux_index_t detector,
dif_pinmux_wakeup_config_t config);
/**
* Disables wake-up detection for a particular detector.
*
* @param pinmux A Pin Multiplexer handle.
* @param detector A detector index.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_pinmux_wakeup_detector_disable(const dif_pinmux_t *pinmux,
dif_pinmux_index_t detector);
/**
* Clears the wake-up cause information.
*
* @param pinmux A Pin Multiplexer handle.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_pinmux_wakeup_cause_clear(const dif_pinmux_t *pinmux);
/**
* Retrieves the detectors that have detected wake-up patterns.
*
* @param pinmux A Pin Multiplexer handle.
* @param detector_map[out] A bit map representing detectors that have detected
* wake-up patterns.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_pinmux_wakeup_cause_get(const dif_pinmux_t *pinmux,
uint32_t *detector_map);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_PINMUX_H_