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
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 {
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 {
77 
78  kDifAdcCtrlTrans,
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 {
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  */
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  */
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  */
162 typedef 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  */
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  */
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  */
263  dif_adc_ctrl_channel_t channel,
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  */
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  */
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  */
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  */
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  */
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 #ifdef __cplusplus
476 } // extern "C"
477 #endif // __cplusplus
478 
479 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_ADC_CTRL_H_