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}