kernel/hil/
adc.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Interfaces for analog to digital converter peripherals.
6
7use crate::ErrorCode;
8
9// *** Interfaces for low-speed, single-sample ADCs ***
10
11/// Simple interface for reading an ADC sample on any channel.
12pub trait Adc<'a> {
13    /// The chip-dependent type of an ADC channel.
14    type Channel: PartialEq;
15
16    /// Request a single ADC sample on a particular channel.
17    /// Used for individual samples that have no timing requirements.
18    /// All ADC samples will be the raw ADC value left-justified in the u16.
19    fn sample(&self, channel: &Self::Channel) -> Result<(), ErrorCode>;
20
21    /// Request repeated ADC samples on a particular channel.
22    /// Callbacks will occur at the given frequency with low jitter and can be
23    /// set to any frequency supported by the chip implementation. However
24    /// callbacks may be limited based on how quickly the system can service
25    /// individual samples, leading to missed samples at high frequencies.
26    /// All ADC samples will be the raw ADC value left-justified in the u16.
27    fn sample_continuous(&self, channel: &Self::Channel, frequency: u32) -> Result<(), ErrorCode>;
28
29    /// Stop a sampling operation.
30    /// Can be used to stop any simple or high-speed sampling operation. No
31    /// further callbacks will occur.
32    fn stop_sampling(&self) -> Result<(), ErrorCode>;
33
34    /// Function to ask the ADC how many bits of resolution are in the samples
35    /// it is returning.
36    fn get_resolution_bits(&self) -> usize;
37
38    /// Function to ask the ADC what reference voltage it used when taking the
39    /// samples. This allows the user of this interface to calculate an actual
40    /// voltage from the ADC reading.
41    ///
42    /// The returned reference voltage is in millivolts, or `None` if unknown.
43    fn get_voltage_reference_mv(&self) -> Option<usize>;
44
45    fn set_client(&self, client: &'a dyn Client);
46}
47
48/// Trait for handling callbacks from simple ADC calls.
49pub trait Client {
50    /// Called when a sample is ready.
51    fn sample_ready(&self, sample: u16);
52}
53
54// *** Interfaces for high-speed, buffered ADC sampling ***
55
56/// Interface for continuously sampling at a given frequency on a channel.
57/// Requires the AdcSimple interface to have been implemented as well.
58pub trait AdcHighSpeed<'a>: Adc<'a> {
59    /// Start sampling continuously into buffers.
60    /// Samples are double-buffered, going first into `buffer1` and then into
61    /// `buffer2`. A callback is performed to the client whenever either buffer
62    /// is full, which expects either a second buffer to be sent via the
63    /// `provide_buffer` call. Length fields correspond to the number of
64    /// samples that should be collected in each buffer. If an error occurs,
65    /// the buffers will be returned.
66    ///
67    /// All ADC samples will be the raw ADC value left-justified in the u16.
68    fn sample_highspeed(
69        &self,
70        channel: &Self::Channel,
71        frequency: u32,
72        buffer1: &'static mut [u16],
73        length1: usize,
74        buffer2: &'static mut [u16],
75        length2: usize,
76    ) -> Result<(), (ErrorCode, &'static mut [u16], &'static mut [u16])>;
77
78    /// Provide a new buffer to fill with the ongoing `sample_continuous`
79    /// configuration.
80    /// Expected to be called in a `buffer_ready` callback. Note that if this
81    /// is not called before the second buffer is filled, samples will be
82    /// missed. Length field corresponds to the number of samples that should
83    /// be collected in the buffer. If an error occurs, the buffer will be
84    /// returned.
85    ///
86    /// All ADC samples will be the raw ADC value left-justified in the u16.
87    fn provide_buffer(
88        &self,
89        buf: &'static mut [u16],
90        length: usize,
91    ) -> Result<(), (ErrorCode, &'static mut [u16])>;
92
93    /// Reclaim ownership of buffers.
94    /// Can only be called when the ADC is inactive, which occurs after a
95    /// successful `stop_sampling`. Used to reclaim buffers after a sampling
96    /// operation is complete. Returns Ok() if the ADC was inactive, but
97    /// there may still be no buffers that are `some` if the driver had already
98    /// returned all buffers.
99    ///
100    /// All ADC samples will be the raw ADC value left-justified in the u16.
101    fn retrieve_buffers(
102        &self,
103    ) -> Result<(Option<&'static mut [u16]>, Option<&'static mut [u16]>), ErrorCode>;
104
105    fn set_highspeed_client(&self, client: &'a dyn HighSpeedClient);
106}
107
108/// Trait for handling callbacks from high-speed ADC calls.
109pub trait HighSpeedClient {
110    /// Called when a buffer is full.
111    /// The length provided will always be less than or equal to the length of
112    /// the buffer. Expects an additional call to either provide another buffer
113    /// or stop sampling
114    fn samples_ready(&self, buf: &'static mut [u16], length: usize);
115}
116
117pub trait AdcChannel<'a> {
118    /// Request a single ADC sample on a particular channel.
119    /// Used for individual samples that have no timing requirements.
120    /// All ADC samples will be the raw ADC value left-justified in the u16.
121    fn sample(&self) -> Result<(), ErrorCode>;
122
123    /// Request repeated ADC samples on a particular channel.
124    /// Callbacks will occur at the given frequency with low jitter and can be
125    /// set to any frequency supported by the chip implementation. However
126    /// callbacks may be limited based on how quickly the system can service
127    /// individual samples, leading to missed samples at high frequencies.
128    /// All ADC samples will be the raw ADC value left-justified in the u16.
129    fn sample_continuous(&self) -> Result<(), ErrorCode>;
130
131    /// Stop a sampling operation.
132    /// Can be used to stop any simple or high-speed sampling operation. No
133    /// further callbacks will occur.
134    fn stop_sampling(&self) -> Result<(), ErrorCode>;
135
136    /// Function to ask the ADC how many bits of resolution are in the samples
137    /// it is returning.
138    fn get_resolution_bits(&self) -> usize;
139
140    /// Function to ask the ADC what reference voltage it used when taking the
141    /// samples. This allows the user of this interface to calculate an actual
142    /// voltage from the ADC reading.
143    ///
144    /// The returned reference voltage is in millivolts, or `None` if unknown.
145    fn get_voltage_reference_mv(&self) -> Option<usize>;
146
147    fn set_client(&self, client: &'a dyn Client);
148}