1use core::cell::Cell;
8use core::cmp;
9use core::ptr::addr_of;
10use kernel::hil;
11use kernel::utilities::cells::{OptionalCell, TakeCell, VolatileCell};
12use kernel::utilities::registers::interfaces::{Readable, Writeable};
13use kernel::utilities::registers::{register_bitfields, ReadOnly, ReadWrite, WriteOnly};
14use kernel::utilities::StaticRef;
15use kernel::ErrorCode;
16
17#[repr(C)]
18struct AdcRegisters {
19    tasks_start: WriteOnly<u32, TASK::Register>,
21    tasks_sample: WriteOnly<u32, TASK::Register>,
23    tasks_stop: WriteOnly<u32, TASK::Register>,
25    tasks_calibrateoffset: WriteOnly<u32, TASK::Register>,
27    _reserved0: [u8; 240],
28    events_started: ReadWrite<u32, EVENT::Register>,
30    events_end: ReadWrite<u32, EVENT::Register>,
32    events_done: ReadWrite<u32, EVENT::Register>,
34    events_resultdone: ReadWrite<u32, EVENT::Register>,
36    events_calibratedone: ReadWrite<u32, EVENT::Register>,
38    events_stopped: ReadWrite<u32, EVENT::Register>,
40    events_ch: [AdcEventChRegisters; 8],
42    _reserved1: [u8; 424],
43    inten: ReadWrite<u32, INTEN::Register>,
45    intenset: ReadWrite<u32, INTEN::Register>,
47    intenclr: ReadWrite<u32, INTEN::Register>,
49    _reserved2: [u8; 244],
50    status: ReadOnly<u32>,
52    _reserved3: [u8; 252],
53    enable: ReadWrite<u32, ENABLE::Register>,
55    _reserved4: [u8; 12],
56    ch: [AdcChRegisters; 8],
57    _reserved5: [u8; 96],
58    resolution: ReadWrite<u32, RESOLUTION::Register>,
60    oversample: ReadWrite<u32>,
62    samplerate: ReadWrite<u32, SAMPLERATE::Register>,
64    _reserved6: [u8; 48],
65    result_ptr: VolatileCell<*const u16>,
67    result_maxcnt: ReadWrite<u32, RESULT_MAXCNT::Register>,
69    result_amount: ReadWrite<u32, RESULT_AMOUNT::Register>,
71}
72
73#[repr(C)]
74struct AdcEventChRegisters {
75    limith: ReadWrite<u32, EVENT::Register>,
76    limitl: ReadWrite<u32, EVENT::Register>,
77}
78
79#[repr(C)]
80struct AdcChRegisters {
81    pselp: ReadWrite<u32, PSEL::Register>,
82    pseln: ReadWrite<u32, PSEL::Register>,
83    config: ReadWrite<u32, CONFIG::Register>,
84    limit: ReadWrite<u32, LIMIT::Register>,
85}
86
87register_bitfields![u32,
88    INTEN [
89        STARTED 0,
91        END 1,
93        DONE 2,
95        RESULTDONE 3,
97        CALIBRATEDONE 4,
99        STOPPED 5,
101        CH0LIMITH 6,
103        CH0LIMITL 7,
105        CH1LIMITH 8,
107        CH1LIMITL 9,
109        CH2LIMITH 10,
111        CH2LIMITL 11,
113        CH3LIMITH 12,
115        CH3LIMITL 13,
117        CH4LIMITH 14,
119        CH4LIMITL 15,
121        CH5LIMITH 16,
123        CH5LIMITL 17,
125        CH6LIMITH 18,
127        CH6LIMITL 19,
129        CH7LIMITH 20,
131        CH7LIMITL 21
133    ],
134    ENABLE [
135        ENABLE 0
136    ],
137    SAMPLERATE [
138        CC OFFSET(0) NUMBITS(11) [],
140        MODE OFFSET(12) NUMBITS(1) [
142            Task = 0,
144            Timers = 1
146        ]
147    ],
148    EVENT [
149        EVENT 0
150    ],
151    TASK [
152        TASK 0
153    ],
154    PSEL [
155        PSEL OFFSET(0) NUMBITS(5) [
156            NotConnected = 0,
157            AnalogInput0 = 1,
158            AnalogInput1 = 2,
159            AnalogInput2 = 3,
160            AnalogInput3 = 4,
161            AnalogInput4 = 5,
162            AnalogInput5 = 6,
163            AnalogInput6 = 7,
164            AnalogInput7 = 8,
165            VDD = 9,
166            VDDHDIV5 = 0xD
167        ]
168    ],
169    CONFIG [
170        RESP OFFSET(0) NUMBITS(2) [
171            Bypass = 0,
172            Pulldown = 1,
173            Pullup = 2,
174            VDD1_2 = 3
175        ],
176        RESN OFFSET(4) NUMBITS(2) [
177            Bypass = 0,
178            Pulldown = 1,
179            Pullup = 2,
180            VDD1_2 = 3
181        ],
182        GAIN OFFSET(8) NUMBITS(3) [
183            Gain1_6 = 0,
184            Gain1_5 = 1,
185            Gain1_4 = 2,
186            Gain1_3 = 3,
187            Gain1_2 = 4,
188            Gain1 = 5,
189            Gain2 = 6,
190            Gain4 = 7
191        ],
192        REFSEL OFFSET(12) NUMBITS(1) [
193            Internal = 0,
194            VDD1_4 = 1
195        ],
196        TACQ OFFSET(16) NUMBITS(3) [
197            us3 = 0,
198            us5 = 1,
199            us10 = 2,
200            us15 = 3,
201            us20 = 4,
202            us40 = 5
203        ],
204        MODE OFFSET(20) NUMBITS(1) [
205            SE = 0,
206            Diff = 1
207        ],
208        BURST OFFSET(24) NUMBITS(1) [
209            Disable = 0,
210            Enable = 1
211        ]
212    ],
213    LIMIT [
214        LOW OFFSET(0) NUMBITS(16) [],
215        HIGH OFFSET(16) NUMBITS(16) []
216    ],
217    RESOLUTION [
218        VAL OFFSET(0) NUMBITS(3) [
219            bit8 = 0,
220            bit10 = 1,
221            bit12 = 2,
222            bit14 = 3
223        ]
224    ],
225    RESULT_MAXCNT [
226        MAXCNT OFFSET(0) NUMBITS(16) []
227    ],
228    RESULT_AMOUNT [
229        AMOUNT OFFSET(0) NUMBITS(16) []
230    ]
231];
232
233#[derive(Copy, Clone, Debug, PartialEq)]
234pub enum AdcChannel {
235    AnalogInput0 = 1,
236    AnalogInput1 = 2,
237    AnalogInput2 = 3,
238    AnalogInput3 = 4,
239    AnalogInput4 = 5,
240    AnalogInput5 = 6,
241    AnalogInput6 = 7,
242    AnalogInput7 = 8,
243    VDD = 9,
244    VDDHDIV5 = 0xD,
245}
246
247const SAADC_BASE: StaticRef<AdcRegisters> =
248    unsafe { StaticRef::new(0x40007000 as *const AdcRegisters) };
249
250static mut SAMPLE: [u16; 1] = [0; 1];
252
253#[repr(u8)]
254#[derive(Copy, Clone, Debug)]
255pub enum AdcChannelGain {
256    Gain1_6 = 0,
257    Gain1_5 = 1,
258    Gain1_4 = 2,
259    Gain1_3 = 3,
260    Gain1_2 = 4,
261    Gain1 = 5,
262    Gain2 = 6,
263    Gain4 = 7,
264}
265
266#[repr(u8)]
267#[derive(Copy, Clone, Debug)]
268pub enum AdcChannelResistor {
269    Bypass = 0,
270    Pulldown = 1,
271    Pullup = 2,
272    VDD1_2 = 3,
273}
274
275#[allow(non_camel_case_types)]
276#[repr(u8)]
277#[derive(Clone, Copy, Debug)]
278pub enum AdcChannelSamplingTime {
279    us3 = 0,
280    us5 = 1,
281    us10 = 2,
282    us15 = 3,
283    us20 = 4,
284    us40 = 5,
285}
286
287#[derive(Copy, Clone, Debug)]
288pub struct AdcChannelSetup {
289    channel: AdcChannel,
290    gain: AdcChannelGain,
291    resp: AdcChannelResistor,
292    resn: AdcChannelResistor,
293    sampling_time: AdcChannelSamplingTime,
294}
295
296impl PartialEq for AdcChannelSetup {
297    fn eq(&self, other: &Self) -> bool {
298        self.channel == other.channel
299    }
300}
301
302impl AdcChannelSetup {
303    pub fn new(channel: AdcChannel) -> AdcChannelSetup {
304        AdcChannelSetup {
305            channel,
306            gain: AdcChannelGain::Gain1_4,
307            resp: AdcChannelResistor::Bypass,
308            resn: AdcChannelResistor::Pulldown,
309            sampling_time: AdcChannelSamplingTime::us10,
310        }
311    }
312
313    pub fn setup(
314        channel: AdcChannel,
315        gain: AdcChannelGain,
316        resp: AdcChannelResistor,
317        resn: AdcChannelResistor,
318        sampling_time: AdcChannelSamplingTime,
319    ) -> AdcChannelSetup {
320        AdcChannelSetup {
321            channel,
322            gain,
323            resp,
324            resn,
325            sampling_time,
326        }
327    }
328}
329
330#[derive(Clone, Copy)]
331enum AdcMode {
332    Idle,
333    Calibrate,
334    Single,
335    HighSpeed,
336}
337
338pub struct Adc<'a> {
339    registers: StaticRef<AdcRegisters>,
340    reference: Cell<usize>,
341    mode: Cell<AdcMode>,
342    client: OptionalCell<&'a dyn hil::adc::Client>,
343    highspeed_client: OptionalCell<&'a dyn hil::adc::HighSpeedClient>,
344
345    buffer: TakeCell<'static, [u16]>,
346    length: Cell<usize>,
347    next_buffer: TakeCell<'static, [u16]>,
348    next_length: Cell<usize>,
349}
350
351impl Adc<'_> {
352    pub const fn new(voltage_reference_in_mv: usize) -> Self {
353        Self {
354            registers: SAADC_BASE,
355            reference: Cell::new(voltage_reference_in_mv),
356            mode: Cell::new(AdcMode::Idle),
357            client: OptionalCell::empty(),
358            highspeed_client: OptionalCell::empty(),
359            buffer: TakeCell::empty(),
360            length: Cell::new(0),
361            next_buffer: TakeCell::empty(),
362            next_length: Cell::new(0),
363        }
364    }
365
366    pub fn calibrate(&self) {
368        self.mode.set(AdcMode::Calibrate);
369
370        self.registers.enable.write(ENABLE::ENABLE::SET);
372        self.registers.inten.write(INTEN::CALIBRATEDONE::SET);
373        self.registers.tasks_calibrateoffset.write(TASK::TASK::SET);
374    }
375
376    pub fn handle_interrupt(&self) {
377        match self.mode.get() {
378            AdcMode::Calibrate => {
379                if self.registers.events_calibratedone.is_set(EVENT::EVENT) {
380                    self.registers
381                        .events_calibratedone
382                        .write(EVENT::EVENT::CLEAR);
383
384                    self.registers.ch[0].pselp.write(PSEL::PSEL::VDD);
386                    self.registers.ch[0].pseln.write(PSEL::PSEL::NotConnected);
387
388                    self.registers.ch[0].config.write(
390                        CONFIG::GAIN::Gain1_6
391                            + CONFIG::REFSEL::Internal
392                            + CONFIG::TACQ::us10
393                            + CONFIG::RESP::Bypass
394                            + CONFIG::RESN::Bypass
395                            + CONFIG::MODE::SE,
396                    );
397
398                    self.setup_resolution();
399                    self.setup_sample_count(1);
400
401                    self.registers.result_ptr.set(addr_of!(SAMPLE) as *const _);
403
404                    self.registers.samplerate.write(SAMPLERATE::MODE::Task);
406
407                    self.registers.enable.write(ENABLE::ENABLE::SET);
409
410                    self.registers
412                        .inten
413                        .write(INTEN::STARTED::SET + INTEN::END::SET + INTEN::STOPPED::SET);
414
415                    self.registers.tasks_start.write(TASK::TASK::SET);
416
417                    } else if self.registers.events_started.is_set(EVENT::EVENT) {
419                    self.registers.events_started.write(EVENT::EVENT::CLEAR);
420                    self.registers.tasks_sample.write(TASK::TASK::SET);
422                } else if self.registers.events_end.is_set(EVENT::EVENT) {
423                    self.registers.events_end.write(EVENT::EVENT::CLEAR);
424                    self.registers.tasks_stop.write(TASK::TASK::SET);
426                } else if self.registers.events_stopped.is_set(EVENT::EVENT) {
427                    self.registers.events_stopped.write(EVENT::EVENT::CLEAR);
428                    self.registers.enable.write(ENABLE::ENABLE::CLEAR);
430
431                    let reading = unsafe { SAMPLE[0] as i16 } as usize;
432
433                    let val = (reading * 3600) / (1 << 12);
438
439                    if val > 1000 && val < 5100 {
442                        self.reference.set(val);
443                    }
444                }
445            }
446
447            AdcMode::Single => {
448                if self.registers.events_calibratedone.is_set(EVENT::EVENT) {
450                    self.registers
451                        .events_calibratedone
452                        .write(EVENT::EVENT::CLEAR);
453                    self.registers.enable.write(ENABLE::ENABLE::CLEAR);
454                } else if self.registers.events_started.is_set(EVENT::EVENT) {
455                    self.registers.events_started.write(EVENT::EVENT::CLEAR);
456                    self.registers.tasks_sample.write(TASK::TASK::SET);
458                } else if self.registers.events_end.is_set(EVENT::EVENT) {
459                    self.registers.events_end.write(EVENT::EVENT::CLEAR);
460                    self.registers.tasks_stop.write(TASK::TASK::SET);
462                } else if self.registers.events_stopped.is_set(EVENT::EVENT) {
463                    self.registers.events_stopped.write(EVENT::EVENT::CLEAR);
464                    self.registers.enable.write(ENABLE::ENABLE::CLEAR);
466
467                    let val = unsafe { SAMPLE[0] as i16 };
468                    self.client.map(|client| {
469                        client.sample_ready(if val < 0 { 0 } else { val << 4 } as u16);
471                    });
472                }
473            }
474
475            AdcMode::HighSpeed => {
476                if self.registers.events_started.is_set(EVENT::EVENT) {
477                    self.registers.events_started.write(EVENT::EVENT::CLEAR);
478
479                    self.next_buffer.map(|buf| {
482                        let dma_len = cmp::min(buf.len(), self.next_length.get());
484                        if dma_len > 0 {
485                            self.registers.result_ptr.set(buf.as_ptr());
486                        }
487                    });
488
489                    self.registers.tasks_sample.write(TASK::TASK::SET);
491                } else if self.registers.events_end.is_set(EVENT::EVENT) {
492                    self.registers.events_end.write(EVENT::EVENT::CLEAR);
493
494                    let ret_buf = self.buffer.take().unwrap();
495
496                    let length = self.length.get();
500                    for i in 0..length {
501                        ret_buf[i] <<= 4;
502                    }
503
504                    self.highspeed_client.map(|client| {
505                        client.samples_ready(ret_buf, length);
506                    });
507
508                    let length2 = self.next_length.get();
511                    if length2 > 0 {
512                        self.length.set(length2);
513                        self.buffer.put(self.next_buffer.take());
514                        self.registers
515                            .result_maxcnt
516                            .write(RESULT_MAXCNT::MAXCNT.val(length2 as u32));
517                        kernel::debug!("len2 {}", length2);
518
519                        self.registers.tasks_start.write(TASK::TASK::SET);
521                    }
522                } else if self.registers.events_stopped.is_set(EVENT::EVENT) {
523                    self.registers.events_stopped.write(EVENT::EVENT::CLEAR);
524                }
525            }
526
527            AdcMode::Idle => {}
528        }
529    }
530
531    fn setup_channel(&self, channel: &AdcChannelSetup) {
532        self.registers.ch[0]
534            .pselp
535            .write(PSEL::PSEL.val(channel.channel as u32));
536        self.registers.ch[0].pseln.write(PSEL::PSEL::NotConnected);
537
538        self.registers.ch[0].config.write(
540            CONFIG::GAIN.val(channel.gain as u32)
541                + CONFIG::REFSEL::VDD1_4
542                + CONFIG::TACQ.val(channel.sampling_time as u32)
543                + CONFIG::RESP.val(channel.resp as u32)
544                + CONFIG::RESN.val(channel.resn as u32)
545                + CONFIG::MODE::SE,
546        );
547    }
548
549    fn setup_resolution(&self) {
550        self.registers.resolution.write(RESOLUTION::VAL::bit12);
552    }
553
554    fn setup_sample_count(&self, count: usize) {
555        self.registers
556            .result_maxcnt
557            .write(RESULT_MAXCNT::MAXCNT.val(count as u32));
558    }
559
560    fn setup_frequency(&self, frequency: u32) {
561        let raw_cc = 16000000 / frequency;
562        let cc = raw_cc.clamp(80, 2047);
563
564        self.registers
565            .samplerate
566            .write(SAMPLERATE::MODE::Timers + SAMPLERATE::CC.val(cc));
567    }
568}
569
570impl<'a> hil::adc::Adc<'a> for Adc<'a> {
572    type Channel = AdcChannelSetup;
573
574    fn sample(&self, channel: &Self::Channel) -> Result<(), ErrorCode> {
575        self.setup_channel(channel);
576        self.setup_resolution();
577
578        self.registers
580            .result_maxcnt
581            .write(RESULT_MAXCNT::MAXCNT.val(1));
582        self.registers.result_ptr.set(addr_of!(SAMPLE) as *const _);
584
585        self.registers.samplerate.write(SAMPLERATE::MODE::Task);
587
588        self.registers.enable.write(ENABLE::ENABLE::SET);
590
591        self.registers
593            .inten
594            .write(INTEN::STARTED::SET + INTEN::END::SET + INTEN::STOPPED::SET);
595
596        self.mode.set(AdcMode::Single);
597
598        self.registers.tasks_start.write(TASK::TASK::SET);
600
601        Ok(())
602    }
603
604    fn sample_continuous(
605        &self,
606        _channel: &Self::Channel,
607        _frequency: u32,
608    ) -> Result<(), ErrorCode> {
609        Err(ErrorCode::FAIL)
610    }
611
612    fn stop_sampling(&self) -> Result<(), ErrorCode> {
613        self.registers.tasks_stop.write(TASK::TASK::SET);
614        Ok(())
615    }
616
617    fn get_resolution_bits(&self) -> usize {
618        12
619    }
620
621    fn get_voltage_reference_mv(&self) -> Option<usize> {
622        Some(self.reference.get())
623    }
624
625    fn set_client(&self, client: &'a dyn hil::adc::Client) {
626        self.client.set(client);
627    }
628}
629
630impl<'a> hil::adc::AdcHighSpeed<'a> for Adc<'a> {
631    fn sample_highspeed(
632        &self,
633        channel: &Self::Channel,
634        frequency: u32,
635        buffer1: &'static mut [u16],
636        length1: usize,
637        buffer2: &'static mut [u16],
638        length2: usize,
639    ) -> Result<(), (ErrorCode, &'static mut [u16], &'static mut [u16])> {
640        if length1 == 0 {
641            Err((ErrorCode::INVAL, buffer1, buffer2))
643        } else {
644            self.next_buffer.replace(buffer2);
646            self.next_length.set(length2);
647
648            self.setup_channel(channel);
649            self.setup_resolution();
650
651            self.registers.result_ptr.set(buffer1.as_ptr());
653
654            self.buffer.replace(buffer1);
656            self.length.set(length1);
657
658            self.setup_sample_count(length1);
660
661            self.setup_frequency(frequency);
663
664            self.registers.enable.write(ENABLE::ENABLE::SET);
666
667            self.registers
669                .inten
670                .write(INTEN::STARTED::SET + INTEN::END::SET + INTEN::STOPPED::SET);
671
672            self.mode.set(AdcMode::HighSpeed);
673
674            self.registers.tasks_start.write(TASK::TASK::SET);
676
677            Ok(())
678        }
679    }
680
681    fn provide_buffer(
682        &self,
683        buf: &'static mut [u16],
684        length: usize,
685    ) -> Result<(), (ErrorCode, &'static mut [u16])> {
686        if self.next_buffer.is_some() {
687            Err((ErrorCode::BUSY, buf))
689        } else {
690            self.next_buffer.replace(buf);
692            self.next_length.set(length);
693
694            Ok(())
695        }
696    }
697
698    fn retrieve_buffers(
699        &self,
700    ) -> Result<(Option<&'static mut [u16]>, Option<&'static mut [u16]>), ErrorCode> {
701        Ok((self.buffer.take(), self.next_buffer.take()))
702    }
703
704    fn set_highspeed_client(&self, client: &'a dyn hil::adc::HighSpeedClient) {
705        self.highspeed_client.set(client);
706    }
707}