Software APIs
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.
16
17#ifdef __cplusplus
18extern "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 */
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 */
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 */
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 */
116 (1U << (ADC_CTRL_ADC_INTR_STATUS_ONESHOT_BIT + 1)) - 1,
118
119#undef DIF_ADC_CTRL_IRQ_CAUSE_ENUM_INIT_
120
121/**
122 * Operation mode of the ADC Controller.
123 */
124typedef 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 */
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 */
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 */
158
159/**
160 * Runtime configuration for an ADC Controller.
161 */
162typedef struct dif_adc_ctrl_config {
163 /**
164 * The sampling mode to configure the ADC Controller in.
165 */
167 /**
168 * The time to allow the ADC to power up.
169 *
170 * Units: always-on clock cycles
171 */
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 */
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 */
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 */
195
196/**
197 * Runtime configuration for an ADC Controller filter.
198 */
200 /**
201 * The ADC Controller filter this configuration applies to.
202 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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_