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);
}