Software APIs
sw
device
lib
dif
dif_adc_ctrl.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_ADC_CTRL_H_
6
#define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_ADC_CTRL_H_
7
8
/**
9
* @file
10
* @brief <a href="/hw/ip/adc_ctrl/doc/">ADC Controller</a> Device Interface
11
* Functions
12
*/
13
14
#include "adc_ctrl_regs.h"
// Generated.
15
#include "
sw/device/lib/dif/autogen/dif_adc_ctrl_autogen.h
"
16
17
#ifdef __cplusplus
18
extern
"C"
{
19
#endif // __cplusplus
20
21
/**
22
* Helper X macro for defining enums and case statements related to ADC
23
* Controller channels. If an additional channel is ever added to the hardware,
24
* this list can be updated.
25
*/
26
#define DIF_ADC_CTRL_CHANNEL_LIST(X) \
27
X(0) \
28
X(1)
29
30
/**
31
* Helper X macro for defining enums and case statements related to ADC
32
* Controller filters. If an additional filter is ever added to the hardware,
33
* this list can be updated.
34
*/
35
#define DIF_ADC_CTRL_FILTER_LIST(X) \
36
X(0) \
37
X(1) \
38
X(2) \
39
X(3) \
40
X(4) \
41
X(5) \
42
X(6) \
43
X(7)
44
45
/**
46
* Helper macro for defining a `dif_adc_ctrl_channel_t` enumeration constant.
47
* @channel_ ADC Controller channel of the enumeration constant.
48
*/
49
#define DIF_ADC_CTRL_CHANNEL_ENUM_INIT_(channel_) \
50
kDifAdcCtrlChannel##channel_ = channel_,
51
52
/**
53
* An ADC Controller Channel.
54
*/
55
typedef
enum
dif_adc_ctrl_channel
{
56
DIF_ADC_CTRL_CHANNEL_LIST
(
DIF_ADC_CTRL_CHANNEL_ENUM_INIT_
)
57
}
dif_adc_ctrl_channel_t
;
58
59
#undef DIF_ADC_CTRL_CHANNEL_ENUM_INIT_
60
61
/**
62
* Helper macro for defining a `dif_adc_ctrl_filter_t` enumeration constant.
63
* @filter_ ADC Controller filter of the enumeration constant.
64
*/
65
#define DIF_ADC_CTRL_FILTER_ENUM_INIT_(filter_) \
66
kDifAdcCtrlFilter##filter_ = filter_,
67
68
/**
69
* An ADC Controller filter.
70
*
71
* Each channel has a separate instance of each filter. For example, if there
72
* are two channels and eight filters, there would be a total of 16 filter
73
* instances that may be configured.
74
*/
75
typedef
enum
dif_adc_ctrl_filter
{
76
DIF_ADC_CTRL_FILTER_LIST
(
DIF_ADC_CTRL_FILTER_ENUM_INIT_
)
77
78
kDifAdcCtrlTrans,
79
}
dif_adc_ctrl_filter_t
;
80
81
#undef DIF_ADC_CTRL_FILTER_ENUM_INIT_
82
83
/**
84
* Helper macro for defining a `dif_adc_ctrl_irq_cause_t` enumeration constant.
85
* @filter_cause_ ADC Controller IRQ filter cause of the enumeration constant.
86
*/
87
#define DIF_ADC_CTRL_IRQ_CAUSE_ENUM_INIT_(filter_cause_) \
88
kDifAdcCtrlIrqCauseFilter##filter_cause_ = 1U << filter_cause_,
89
90
/**
91
* An ADC Controller IRQ cause.
92
*
93
* The ADC Controller can only generate a single interrupt (the `debug_cable`
94
* interrupt). However, depending on how the ADC Controller is configured, there
95
* are several causes that could trigger this interrupt. These include filter
96
* matches (when in Normal Power Scan mode), or sample completion (when in
97
* Oneshot mode).
98
*/
99
typedef
enum
dif_adc_ctrl_irq_cause
{
100
DIF_ADC_CTRL_FILTER_LIST
(
DIF_ADC_CTRL_IRQ_CAUSE_ENUM_INIT_
)
101
/**
102
* Sample ready cause in Oneshot mode.
103
*/
104
kDifAdcCtrlIrqCauseTrans
= 1U << ADC_CTRL_ADC_INTR_STATUS_TRANS_BIT,
105
/**
106
* Sample ready cause in Oneshot mode.
107
*/
108
kDifAdcCtrlIrqCauseOneshot
= 1U << ADC_CTRL_ADC_INTR_STATUS_ONESHOT_BIT,
109
/**
110
* All IRQ causes ORed together.
111
*
112
* This is useful when clearing all IRQ causes at once, to initialize the ADC
113
* Controller.
114
*/
115
kDifAdcCtrlIrqCauseAll
=
116
(1U << (ADC_CTRL_ADC_INTR_STATUS_ONESHOT_BIT + 1)) - 1,
117
}
dif_adc_ctrl_irq_cause_t
;
118
119
#undef DIF_ADC_CTRL_IRQ_CAUSE_ENUM_INIT_
120
121
/**
122
* Operation mode of the ADC Controller.
123
*/
124
typedef
enum
dif_adc_ctrl_mode
{
125
/**
126
* Low Power (Continuous) Scan mode.
127
*
128
* In Low Power Scan mode, the ADC periodically samples enabled channels, and
129
* upon matching a set of enabled filters, a set number of times, will
130
* transition to Normal Power Scan mode. If no filters are enabled, then the
131
* ADC controller will never transition to Normal Power Scan mode.
132
*/
133
kDifAdcCtrlLowPowerScanMode
= 0,
134
/**
135
* Normal Power (Continuous) Scan mode.
136
*
137
* In Normal Power Scan mode, the ADC samples enabled channels as fast as
138
* possible, and upon matching a set of enabled filters, a set number of
139
* consecutive times, may trigger a system wakeup and/or IRQ. Similar to Low
140
* Power Scan mode, if no filters are enabled, then a system wakeup and/or IRQ
141
* will never be triggered.
142
*/
143
kDifAdcCtrlNormalPowerScanMode
= 1,
144
/**
145
* Oneshot mode.
146
*
147
* In Oneshot mode, an ADC channel is triggered to take a single sample, upon
148
* being enabled, and optionally, raises an interrupt upon completion. Unlike
149
* the Scan modes, in Oneshot mode, the ADC Controller does not attempt to
150
* filter samples. Rather, an IRQ may be raised immediately upon the sample
151
* being ready, regardless of what the sample is. After the sample is
152
* completed the ADC is powered down, until another sample is triggered,
153
* either by toggling the channel's enable bit on and off, or by resetting the
154
* sampling FSM.
155
*/
156
kDifAdcCtrlOneshotMode
= 2,
157
}
dif_adc_ctrl_mode_t
;
158
159
/**
160
* Runtime configuration for an ADC Controller.
161
*/
162
typedef
struct
dif_adc_ctrl_config
{
163
/**
164
* The sampling mode to configure the ADC Controller in.
165
*/
166
dif_adc_ctrl_mode_t
mode
;
167
/**
168
* The time to allow the ADC to power up.
169
*
170
* Units: always-on clock cycles
171
*/
172
uint8_t
power_up_time_aon_cycles
;
173
/**
174
* The sampling period when in Low Power Scan mode, i.e., how often the ADC
175
* Controller wakes up the ADC to take a sample.
176
*
177
* Units: always-on clock cycles
178
*
179
* Only relevant in Low Power Scan mode.
180
*/
181
uint32_t
wake_up_time_aon_cycles
;
182
/**
183
* The number of filter-matching samples to count in Low Power Scan mode
184
* before switching to Normal Power Scan mode.
185
*
186
* Only relevant in Low Power Scan mode.
187
*/
188
uint8_t
num_low_power_samples
;
189
/**
190
* The number of filter-matching samples to count in Normal Power Scan mode
191
* before triggering a system wakeup and/or interrupt.
192
*/
193
uint16_t
num_normal_power_samples
;
194
}
dif_adc_ctrl_config_t
;
195
196
/**
197
* Runtime configuration for an ADC Controller filter.
198
*/
199
typedef
struct
dif_adc_ctrl_filter_config
{
200
/**
201
* The ADC Controller filter this configuration applies to.
202
*/
203
dif_adc_ctrl_filter_t
filter
;
204
/**
205
* The minimum voltage (inclusive) of the range defined by this filter.
206
*
207
* Valid range: [0, 1024)
208
* Units: 2.148 mV (i.e., range / 2 ^ 10)
209
*/
210
uint16_t
min_voltage
;
211
/**
212
* The maximum voltage (inclusive) of the range defined by this filter.
213
*
214
* Valid range: [0, 1024)
215
* Units: 2.148 mV (i.e., range / 2 ^ 10)
216
*/
217
uint16_t
max_voltage
;
218
/**
219
* Where a filter hit is classfied as an (inclusive) in-range hit, or
220
* (exclusive) out-of-range hit.
221
*/
222
bool
in_range
;
223
/**
224
* Whether to generate a system wakeup on a filter match after saturating the
225
* `num_normal_power_samples` threshold in Normal Power Scan mode.
226
*/
227
bool
generate_wakeup_on_match
;
228
/**
229
* Whether to generate a `debug_cable` interrupt on a filter match after
230
* saturating the `num_normal_power_samples` threshold in Normal Power Scan
231
* mode.
232
*/
233
bool
generate_irq_on_match
;
234
}
dif_adc_ctrl_filter_config_t
;
235
236
/**
237
* Configures an ADC Controller.
238
*
239
* @param adc_ctrl An adc_ctrl handle.
240
* @param config Runtime configuration parameters.
241
* @return The result of the operation.
242
*/
243
OT_WARN_UNUSED_RESULT
244
dif_result_t
dif_adc_ctrl_configure
(
const
dif_adc_ctrl_t
*adc_ctrl,
245
dif_adc_ctrl_config_t
config);
246
247
/**
248
* Configures a channel filter.
249
*
250
* This should be invoked for each desired filter _before_ the sampling sequence
251
* is enabled via `dif_adc_ctrl_set_enabled()`.
252
*
253
* This only applies in Low / Normal Power Scan sampling modes.
254
*
255
* @param adc_ctrl An adc_ctrl handle.
256
* @param channel The channel of the filter to configure.
257
* @param config Runtime configuration parameters for the filter.
258
* @param enabled The enablement state to configure the filter in.
259
* @return The result of the operation.
260
*/
261
OT_WARN_UNUSED_RESULT
262
dif_result_t
dif_adc_ctrl_configure_filter
(
const
dif_adc_ctrl_t
*adc_ctrl,
263
dif_adc_ctrl_channel_t
channel,
264
dif_adc_ctrl_filter_config_t
config,
265
dif_toggle_t
enabled);
266
267
/**
268
* Sets the enablement state of the ADC Controller.
269
*
270
* Enabling the ADC Controller powers it up, while disabling the ADC Controller
271
* powers it down and resets the sampling FSM. After powering up, sampling
272
* begins, regardless of the operation mode.
273
*
274
* @param adc_ctrl An adc_ctrl handle.
275
* @param enabled The enablement state to configure the ADC Controller in.
276
* @return The result of the operation.
277
*/
278
OT_WARN_UNUSED_RESULT
279
dif_result_t
dif_adc_ctrl_set_enabled
(
const
dif_adc_ctrl_t
*adc_ctrl,
280
dif_toggle_t
enabled);
281
282
/**
283
* Gets the enablement state of the ADC Controller.
284
*
285
* If the ADC Controller is enabled, it is powered up, or being powered up.
286
*
287
* @param adc_ctrl An adc_ctrl handle.
288
* @param[out] is_enabled The enablement state of the ADC Controller.
289
* @return The result of the operation.
290
*/
291
OT_WARN_UNUSED_RESULT
292
dif_result_t
dif_adc_ctrl_get_enabled
(
const
dif_adc_ctrl_t
*adc_ctrl,
293
dif_toggle_t
*is_enabled);
294
295
/**
296
* Sets the enablement state of the specified filter for the specified channel.
297
*
298
* @param adc_ctrl An adc_ctrl handle.
299
* @param channel The channel the filter resides in.
300
* @param filter The filter to set the enablement state of.
301
* @param enabled The enablement state to configure the filter in.
302
* @return The result of the operation.
303
*/
304
OT_WARN_UNUSED_RESULT
305
dif_result_t
dif_adc_ctrl_filter_set_enabled
(
const
dif_adc_ctrl_t
*adc_ctrl,
306
dif_adc_ctrl_channel_t
channel,
307
dif_adc_ctrl_filter_t
filter,
308
dif_toggle_t
enabled);
309
310
/**
311
* Gets the enablement state of the specified filter for the specified channel.
312
*
313
* @param adc_ctrl An adc_ctrl handle.
314
* @param channel The channel the filter resides in.
315
* @param filter The filter to get the enablement state of.
316
* @param[out] is_enabled The enablement state of the filter.
317
* @return The result of the operation.
318
*/
319
OT_WARN_UNUSED_RESULT
320
dif_result_t
dif_adc_ctrl_filter_get_enabled
(
const
dif_adc_ctrl_t
*adc_ctrl,
321
dif_adc_ctrl_channel_t
channel,
322
dif_adc_ctrl_filter_t
filter,
323
dif_toggle_t
*enabled);
324
325
/**
326
* Get the sampled value from the specified channel that triggered the IRQ.
327
*
328
* Values are 10-bits in the range from 0V to 2.2V. Based on this, the
329
* resolution (and units) of the sample are in increments of 2.148mV.
330
*
331
* @param adc_ctrl An adc_ctrl handle.
332
* @param channel The channel to read the sample from.
333
* @param[out] value The value of the sample.
334
* @return The result of the operation.
335
*/
336
OT_WARN_UNUSED_RESULT
337
dif_result_t
dif_adc_ctrl_get_triggered_value
(
const
dif_adc_ctrl_t
*adc_ctrl,
338
dif_adc_ctrl_channel_t
channel,
339
uint16_t *value);
340
341
/**
342
* Get the latest sampled value from the specified channel.
343
*
344
* Since in Normal Power Scan mode, sampling continues even after an IRQ has
345
* been raised, the value returned by this function may be different than the
346
* value returned by `dif_adc_ctrl_get_irq_value()`.
347
*
348
* Values are 10-bits in the range from 0V to 2.2V. Based on this, the
349
* resolution (and units) of the sample are in increments of 2.148mV.
350
*
351
* @param adc_ctrl An adc_ctrl handle.
352
* @param channel The channel to read the sample from.
353
* @param[out] value The value of the sample.
354
* @return The result of the operation.
355
*/
356
OT_WARN_UNUSED_RESULT
357
dif_result_t
dif_adc_ctrl_get_latest_value
(
const
dif_adc_ctrl_t
*adc_ctrl,
358
dif_adc_ctrl_channel_t
channel,
359
uint16_t *value);
360
361
/**
362
* Reset all ADC Controller FSMs and counters, and if enabled, begin sampling
363
* sequence.
364
*
365
* @param adc_ctrl An adc_ctrl handle.
366
* @return The result of the operation.
367
*/
368
OT_WARN_UNUSED_RESULT
369
dif_result_t
dif_adc_ctrl_reset
(
const
dif_adc_ctrl_t
*adc_ctrl);
370
371
/**
372
* Gets the cause(s) of a `debug_cable` IRQ.
373
*
374
* IRQs can be triggered by filter matches in Normal Power Scan mode (after
375
* saturating the `num_normal_power_samples` threshold), or after a single
376
* sample capture in Oneshot mode.
377
*
378
* @param adc_ctrl An adc_ctrl handle.
379
* @param[out] causes The causes of the IRQ (one or more
380
* `dif_adc_ctrl_irq_cause_t`s ORed together).
381
* @return The result of the operation.
382
*/
383
OT_WARN_UNUSED_RESULT
384
dif_result_t
dif_adc_ctrl_irq_get_causes
(
const
dif_adc_ctrl_t
*adc_ctrl,
385
uint32_t *causes);
386
387
/**
388
* Gets the filter status.
389
*
390
* @param adc_ctrl An adc_ctrl handle.
391
* @param[out] status The current filter status.
392
* @return The result of the operation.
393
*/
394
OT_WARN_UNUSED_RESULT
395
dif_result_t
dif_adc_ctrl_get_filter_status
(
const
dif_adc_ctrl_t
*adc_ctrl,
396
uint32_t *
status
);
397
398
/**
399
* Clears the cause(s) of a `debug_cable` IRQ.
400
*
401
* TODO(lowRISC/opentitan:#11354): future releases of the HW should hide the
402
* filter and interrupt status registers behind the standardized IRQ registers.
403
* For now, the autogenerated `dif_adc_ctrl_irq_acknowledge[_all]()` DIF may be
404
* used to clear the main IRQ status register, while this DIF may be used to
405
* clear the local cause / filter status registers.
406
*
407
* @param adc_ctrl An adc_ctrl handle.
408
* @param causes The causes of the IRQ (one or more `dif_adc_ctrl_irq_cause_t`s
409
* ORed together).
410
* @return The result of the operation.
411
*/
412
OT_WARN_UNUSED_RESULT
413
dif_result_t
dif_adc_ctrl_irq_clear_causes
(
const
dif_adc_ctrl_t
*adc_ctrl,
414
uint32_t causes);
415
416
/**
417
* Sets the enablement of generating system wakeups on a filter match.
418
*
419
* Only relevant in Normal Power Scan mode (and Low Power Scan mode, which can
420
* transition to Normal Power Scan mode).
421
*
422
* @param adc_ctrl An adc_ctrl handle.
423
* @param filter A filter to enable wakeup triggering for.
424
* @param enabled The enablement state to set.
425
* @return The result of the operation.
426
*/
427
OT_WARN_UNUSED_RESULT
428
dif_result_t
dif_adc_ctrl_filter_match_wakeup_set_enabled
(
429
const
dif_adc_ctrl_t
*adc_ctrl,
dif_adc_ctrl_filter_t
filter,
430
dif_toggle_t
enabled);
431
432
/**
433
* Gets the enablement of generating system wakeups on a filter match.
434
*
435
* @param adc_ctrl An adc_ctrl handle.
436
* @param filter A filter to enable wakeup triggering for.
437
* @param[out] is_enabled The enablement state retrieved.
438
* @return The result of the operation.
439
*/
440
OT_WARN_UNUSED_RESULT
441
dif_result_t
dif_adc_ctrl_filter_match_wakeup_get_enabled
(
442
const
dif_adc_ctrl_t
*adc_ctrl,
dif_adc_ctrl_filter_t
filter,
443
dif_toggle_t
*is_enabled);
444
445
/**
446
* Sets the enablement of generating a `debug_cable` IRQ for given cause(s).
447
*
448
* Causes can be filter matches (in Normal Power Scan mode), or when a sample is
449
* complete (in Oneshot mode).
450
*
451
* @param adc_ctrl An adc_ctrl handle.
452
* @param causes Causes (one or more `dif_adc_ctrl_irq_cause_t`s ORed together)
453
* to generate the `debug_cable` IRQ for.
454
* @param enabled The enablement state to set.
455
* @return The result of the operation.
456
*/
457
OT_WARN_UNUSED_RESULT
458
dif_result_t
dif_adc_ctrl_irq_cause_set_enabled
(
const
dif_adc_ctrl_t
*adc_ctrl,
459
uint32_t causes,
460
dif_toggle_t
enabled);
461
462
/**
463
* Gets the causes that will generate a `debug_cable` IRQ.
464
*
465
* @param adc_ctrl An adc_ctrl handle.
466
* @param[out] enabled_causes Causes (one or more `dif_adc_ctrl_irq_cause_t`s
467
* ORed together) that will generate the
468
* `debug_cable` IRQ.
469
* @return The result of the operation.
470
*/
471
OT_WARN_UNUSED_RESULT
472
dif_result_t
dif_adc_ctrl_irq_cause_get_enabled
(
const
dif_adc_ctrl_t
*adc_ctrl,
473
uint32_t *enabled_causes);
474
475
/**
476
* Wait enough time for CDC synchronization between block and CSRs.
477
*
478
* Wait long enough for any CDC synchronization between the AON part
479
* of the block and the CSRs to be complete. This is particularly important
480
* for the FILTER_STATUS register: this register can be updated by the HW
481
* and any update may take a while to become visible by the SW.
482
*
483
* @param adc_ctrl An adc_ctrl handle.
484
* @param aon_freq_hz Frequency of the AON clock in Hz.
485
* @return The result of the operation.
486
*/
487
dif_result_t
dif_adc_ctrl_wait_cdc_sync
(
const
dif_adc_ctrl_t
*adc_ctrl,
488
uint32_t aon_freq_hz);
489
490
#ifdef __cplusplus
491
}
// extern "C"
492
#endif // __cplusplus
493
494
#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_ADC_CTRL_H_
Return to
OpenTitan Documentation