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 let sample: *const [u16; 1] = addr_of!(SAMPLE);
403 let sample: *const u16 = sample.cast();
404 self.registers.result_ptr.set(sample);
405
406 self.registers.samplerate.write(SAMPLERATE::MODE::Task);
408
409 self.registers.enable.write(ENABLE::ENABLE::SET);
411
412 self.registers
414 .inten
415 .write(INTEN::STARTED::SET + INTEN::END::SET + INTEN::STOPPED::SET);
416
417 self.registers.tasks_start.write(TASK::TASK::SET);
418
419 } else if self.registers.events_started.is_set(EVENT::EVENT) {
421 self.registers.events_started.write(EVENT::EVENT::CLEAR);
422 self.registers.tasks_sample.write(TASK::TASK::SET);
424 } else if self.registers.events_end.is_set(EVENT::EVENT) {
425 self.registers.events_end.write(EVENT::EVENT::CLEAR);
426 self.registers.tasks_stop.write(TASK::TASK::SET);
428 } else if self.registers.events_stopped.is_set(EVENT::EVENT) {
429 self.registers.events_stopped.write(EVENT::EVENT::CLEAR);
430 self.registers.enable.write(ENABLE::ENABLE::CLEAR);
432
433 let reading = unsafe { SAMPLE[0] as i16 } as usize;
434
435 let val = (reading * 3600) / (1 << 12);
440
441 if val > 1000 && val < 5100 {
444 self.reference.set(val);
445 }
446 }
447 }
448
449 AdcMode::Single => {
450 if self.registers.events_calibratedone.is_set(EVENT::EVENT) {
452 self.registers
453 .events_calibratedone
454 .write(EVENT::EVENT::CLEAR);
455 self.registers.enable.write(ENABLE::ENABLE::CLEAR);
456 } else if self.registers.events_started.is_set(EVENT::EVENT) {
457 self.registers.events_started.write(EVENT::EVENT::CLEAR);
458 self.registers.tasks_sample.write(TASK::TASK::SET);
460 } else if self.registers.events_end.is_set(EVENT::EVENT) {
461 self.registers.events_end.write(EVENT::EVENT::CLEAR);
462 self.registers.tasks_stop.write(TASK::TASK::SET);
464 } else if self.registers.events_stopped.is_set(EVENT::EVENT) {
465 self.registers.events_stopped.write(EVENT::EVENT::CLEAR);
466 self.registers.enable.write(ENABLE::ENABLE::CLEAR);
468
469 let val = unsafe { SAMPLE[0] as i16 };
470 self.client.map(|client| {
471 client.sample_ready(if val < 0 { 0 } else { val << 4 } as u16);
473 });
474 }
475 }
476
477 AdcMode::HighSpeed => {
478 if self.registers.events_started.is_set(EVENT::EVENT) {
479 self.registers.events_started.write(EVENT::EVENT::CLEAR);
480
481 self.next_buffer.map(|buf| {
484 let dma_len = cmp::min(buf.len(), self.next_length.get());
486 if dma_len > 0 {
487 self.registers.result_ptr.set(buf.as_ptr());
488 }
489 });
490
491 self.registers.tasks_sample.write(TASK::TASK::SET);
493 } else if self.registers.events_end.is_set(EVENT::EVENT) {
494 self.registers.events_end.write(EVENT::EVENT::CLEAR);
495
496 let ret_buf = self.buffer.take().unwrap();
497
498 let length = self.length.get();
502 for i in 0..length {
503 ret_buf[i] <<= 4;
504 }
505
506 self.highspeed_client.map(|client| {
507 client.samples_ready(ret_buf, length);
508 });
509
510 let length2 = self.next_length.get();
513 if length2 > 0 {
514 self.length.set(length2);
515 self.buffer.put(self.next_buffer.take());
516 self.registers
517 .result_maxcnt
518 .write(RESULT_MAXCNT::MAXCNT.val(length2 as u32));
519 kernel::debug!("len2 {}", length2);
520
521 self.registers.tasks_start.write(TASK::TASK::SET);
523 }
524 } else if self.registers.events_stopped.is_set(EVENT::EVENT) {
525 self.registers.events_stopped.write(EVENT::EVENT::CLEAR);
526 }
527 }
528
529 AdcMode::Idle => {}
530 }
531 }
532
533 fn setup_channel(&self, channel: &AdcChannelSetup) {
534 self.registers.ch[0]
536 .pselp
537 .write(PSEL::PSEL.val(channel.channel as u32));
538 self.registers.ch[0].pseln.write(PSEL::PSEL::NotConnected);
539
540 self.registers.ch[0].config.write(
542 CONFIG::GAIN.val(channel.gain as u32)
543 + CONFIG::REFSEL::VDD1_4
544 + CONFIG::TACQ.val(channel.sampling_time as u32)
545 + CONFIG::RESP.val(channel.resp as u32)
546 + CONFIG::RESN.val(channel.resn as u32)
547 + CONFIG::MODE::SE,
548 );
549 }
550
551 fn setup_resolution(&self) {
552 self.registers.resolution.write(RESOLUTION::VAL::bit12);
554 }
555
556 fn setup_sample_count(&self, count: usize) {
557 self.registers
558 .result_maxcnt
559 .write(RESULT_MAXCNT::MAXCNT.val(count as u32));
560 }
561
562 fn setup_frequency(&self, frequency: u32) {
563 let raw_cc = 16000000 / frequency;
564 let cc = raw_cc.clamp(80, 2047);
565
566 self.registers
567 .samplerate
568 .write(SAMPLERATE::MODE::Timers + SAMPLERATE::CC.val(cc));
569 }
570}
571
572impl<'a> hil::adc::Adc<'a> for Adc<'a> {
574 type Channel = AdcChannelSetup;
575
576 fn sample(&self, channel: &Self::Channel) -> Result<(), ErrorCode> {
577 self.setup_channel(channel);
578 self.setup_resolution();
579
580 self.registers
582 .result_maxcnt
583 .write(RESULT_MAXCNT::MAXCNT.val(1));
584 let sample: *const [u16; 1] = addr_of!(SAMPLE);
586 let sample: *const u16 = sample.cast();
587 self.registers.result_ptr.set(sample);
588
589 self.registers.samplerate.write(SAMPLERATE::MODE::Task);
591
592 self.registers.enable.write(ENABLE::ENABLE::SET);
594
595 self.registers
597 .inten
598 .write(INTEN::STARTED::SET + INTEN::END::SET + INTEN::STOPPED::SET);
599
600 self.mode.set(AdcMode::Single);
601
602 self.registers.tasks_start.write(TASK::TASK::SET);
604
605 Ok(())
606 }
607
608 fn sample_continuous(
609 &self,
610 _channel: &Self::Channel,
611 _frequency: u32,
612 ) -> Result<(), ErrorCode> {
613 Err(ErrorCode::FAIL)
614 }
615
616 fn stop_sampling(&self) -> Result<(), ErrorCode> {
617 self.registers.tasks_stop.write(TASK::TASK::SET);
618 Ok(())
619 }
620
621 fn get_resolution_bits(&self) -> usize {
622 12
623 }
624
625 fn get_voltage_reference_mv(&self) -> Option<usize> {
626 Some(self.reference.get())
627 }
628
629 fn set_client(&self, client: &'a dyn hil::adc::Client) {
630 self.client.set(client);
631 }
632}
633
634impl<'a> hil::adc::AdcHighSpeed<'a> for Adc<'a> {
635 fn sample_highspeed(
636 &self,
637 channel: &Self::Channel,
638 frequency: u32,
639 buffer1: &'static mut [u16],
640 length1: usize,
641 buffer2: &'static mut [u16],
642 length2: usize,
643 ) -> Result<(), (ErrorCode, &'static mut [u16], &'static mut [u16])> {
644 if length1 == 0 {
645 Err((ErrorCode::INVAL, buffer1, buffer2))
647 } else {
648 self.next_buffer.replace(buffer2);
650 self.next_length.set(length2);
651
652 self.setup_channel(channel);
653 self.setup_resolution();
654
655 self.registers.result_ptr.set(buffer1.as_ptr());
657
658 self.buffer.replace(buffer1);
660 self.length.set(length1);
661
662 self.setup_sample_count(length1);
664
665 self.setup_frequency(frequency);
667
668 self.registers.enable.write(ENABLE::ENABLE::SET);
670
671 self.registers
673 .inten
674 .write(INTEN::STARTED::SET + INTEN::END::SET + INTEN::STOPPED::SET);
675
676 self.mode.set(AdcMode::HighSpeed);
677
678 self.registers.tasks_start.write(TASK::TASK::SET);
680
681 Ok(())
682 }
683 }
684
685 fn provide_buffer(
686 &self,
687 buf: &'static mut [u16],
688 length: usize,
689 ) -> Result<(), (ErrorCode, &'static mut [u16])> {
690 if self.next_buffer.is_some() {
691 Err((ErrorCode::BUSY, buf))
693 } else {
694 self.next_buffer.replace(buf);
696 self.next_length.set(length);
697
698 Ok(())
699 }
700 }
701
702 fn retrieve_buffers(
703 &self,
704 ) -> Result<(Option<&'static mut [u16]>, Option<&'static mut [u16]>), ErrorCode> {
705 Ok((self.buffer.take(), self.next_buffer.take()))
706 }
707
708 fn set_highspeed_client(&self, client: &'a dyn hil::adc::HighSpeedClient) {
709 self.highspeed_client.set(client);
710 }
711}