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