embedded_c_sdk_bind_hal/
adc.rs1use crate::common::atomic_ring_buffer::RingBuffer;
2use crate::ll_api::{ll_cmd::*, AdcCtrl};
3#[cfg(feature = "_adc-buffered")]
4use paste::paste;
5
6pub use crate::ll_api::AdcChannel;
7
8#[cfg(not(feature = "adc-data-type-u8"))]
9pub type AdcDataType = u16;
10
11#[cfg(feature = "adc-data-type-u8")]
12pub type AdcDataType = u8;
13
14#[derive(Clone, Debug)]
15pub struct Adc {
16 ch: AdcChannel,
17}
18
19impl Adc {
20 pub fn new(ch: AdcChannel, flags: Option<u32>) -> Self {
29 if let Some(val) = flags {
30 ll_invoke_inner!(INVOKE_ID_ADC_INIT, ch, val);
31 } else {
32 ll_invoke_inner!(INVOKE_ID_ADC_INIT, ch);
33 }
34
35 Adc { ch }
36 }
37
38 pub fn single_convert(&self) -> AdcDataType {
43 let mut buf = [0; 1];
44 let result = ll_invoke_inner!(
45 INVOKE_ID_ADC_CTRL,
46 self.ch,
47 AdcCtrl::Convert,
48 buf.as_mut_ptr(),
49 1
50 );
51 if result < 0 {
52 return 0;
53 }
54
55 buf[0]
56 }
57
58 pub fn multiple_convert(&self, buf: &mut [AdcDataType]) -> bool {
66 let result = ll_invoke_inner!(
67 INVOKE_ID_ADC_CTRL,
68 self.ch,
69 AdcCtrl::Convert,
70 buf.as_mut_ptr(),
71 buf.len()
72 );
73 result >= 0
74 }
75}
76
77impl Drop for Adc {
78 fn drop(&mut self) {
79 ll_invoke_inner!(INVOKE_ID_ADC_DEINIT, self.ch);
80 }
81}
82
83pub struct AdcChData(RingBuffer<AdcDataType>);
84
85pub struct AdcBuffered<'a> {
86 ch: AdcChannel,
87 data: &'a AdcChData,
88}
89
90impl<'a> AdcBuffered<'a> {
100 pub fn new(ch: AdcChannel, data: &'a AdcChData, flags: Option<u32>) -> Self {
101 if let Some(val) = flags {
102 ll_invoke_inner!(INVOKE_ID_ADC_INIT, ch, val);
103 } else {
104 ll_invoke_inner!(INVOKE_ID_ADC_INIT, ch);
105 }
106
107 AdcBuffered { ch, data }
108 }
109
110 pub fn set_buf(&self, buffer: &mut [u16]) {
115 let len = buffer.len();
116 unsafe { self.data.0.init(buffer.as_mut_ptr(), len) };
117 }
118
119 pub fn start(&self) {
121 ll_invoke_inner!(INVOKE_ID_ADC_CTRL, self.ch, AdcCtrl::Start);
122 }
123
124 pub fn stop(&self) {
126 ll_invoke_inner!(INVOKE_ID_ADC_CTRL, self.ch, AdcCtrl::Stop);
127 }
128
129 pub fn read(&self) -> Option<AdcDataType> {
134 let mut result = None;
135 critical_section::with(|_| result = unsafe { self.data.0.reader().pop_one() });
136 return result;
137 }
138
139 pub fn read_multiple(&self, buf: &mut [AdcDataType]) -> usize {
147 let mut result = 0;
148 critical_section::with(|_| {
149 let mut reader = unsafe { self.data.0.reader() };
150 for b in buf {
151 if let Some(data) = reader.pop_one() {
152 *b = data;
153 result += 1;
154 }
155 }
156 });
157
158 return result;
159 }
160}
161
162impl<'a> Drop for AdcBuffered<'a> {
163 fn drop(&mut self) {
164 ll_invoke_inner!(INVOKE_ID_ADC_DEINIT, self.ch);
165 }
166}
167
168#[cfg(feature = "_adc-buffered")]
169macro_rules! impl_adc_ch_data {
170 ($adc_ch:expr) => {
171 paste! {
172 pub static [<ADC_CH $adc_ch _DATA>]: AdcChData = AdcChData ( RingBuffer::new() );
173 }
174
175 paste! {
176 #[allow(non_snake_case)]
177 #[no_mangle]
178 #[inline]
179 unsafe extern "C" fn [<ADC_CH $adc_ch _EOC_hook_rs>] (val: AdcDataType) {paste! {
181 let ch_data = &[<ADC_CH $adc_ch _DATA>].0;
182 if ch_data.is_full() {
183 ch_data.reader().pop_one();
184 }
185 ch_data.writer().push_one(val);
186 }
187 }
188 }
189 };
190}
191
192#[cfg(feature = "adc-buffered-ch0")]
193impl_adc_ch_data!(0);
194
195#[cfg(feature = "adc-buffered-ch1")]
196impl_adc_ch_data!(1);
197
198#[cfg(feature = "adc-buffered-ch2")]
199impl_adc_ch_data!(2);
200
201#[cfg(feature = "adc-buffered-ch3")]
202impl_adc_ch_data!(3);
203
204#[cfg(feature = "adc-buffered-ch4")]
205impl_adc_ch_data!(4);
206
207#[cfg(feature = "adc-buffered-ch5")]
208impl_adc_ch_data!(5);
209
210#[cfg(feature = "adc-buffered-ch6")]
211impl_adc_ch_data!(6);
212
213#[cfg(feature = "adc-buffered-ch7")]
214impl_adc_ch_data!(7);