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 = if raw_cc > 2047 {
563 2047
564 } else if raw_cc < 80 {
565 80
566 } else {
567 raw_cc
568 };
569
570 self.registers
571 .samplerate
572 .write(SAMPLERATE::MODE::Timers + SAMPLERATE::CC.val(cc));
573 }
574}
575
576impl<'a> hil::adc::Adc<'a> for Adc<'a> {
578 type Channel = AdcChannelSetup;
579
580 fn sample(&self, channel: &Self::Channel) -> Result<(), ErrorCode> {
581 self.setup_channel(channel);
582 self.setup_resolution();
583
584 self.registers
586 .result_maxcnt
587 .write(RESULT_MAXCNT::MAXCNT.val(1));
588 self.registers.result_ptr.set(addr_of!(SAMPLE) as *const _);
590
591 self.registers.samplerate.write(SAMPLERATE::MODE::Task);
593
594 self.registers.enable.write(ENABLE::ENABLE::SET);
596
597 self.registers
599 .inten
600 .write(INTEN::STARTED::SET + INTEN::END::SET + INTEN::STOPPED::SET);
601
602 self.mode.set(AdcMode::Single);
603
604 self.registers.tasks_start.write(TASK::TASK::SET);
606
607 Ok(())
608 }
609
610 fn sample_continuous(
611 &self,
612 _channel: &Self::Channel,
613 _frequency: u32,
614 ) -> Result<(), ErrorCode> {
615 Err(ErrorCode::FAIL)
616 }
617
618 fn stop_sampling(&self) -> Result<(), ErrorCode> {
619 self.registers.tasks_stop.write(TASK::TASK::SET);
620 Ok(())
621 }
622
623 fn get_resolution_bits(&self) -> usize {
624 12
625 }
626
627 fn get_voltage_reference_mv(&self) -> Option<usize> {
628 Some(self.reference.get())
629 }
630
631 fn set_client(&self, client: &'a dyn hil::adc::Client) {
632 self.client.set(client);
633 }
634}
635
636impl<'a> hil::adc::AdcHighSpeed<'a> for Adc<'a> {
637 fn sample_highspeed(
638 &self,
639 channel: &Self::Channel,
640 frequency: u32,
641 buffer1: &'static mut [u16],
642 length1: usize,
643 buffer2: &'static mut [u16],
644 length2: usize,
645 ) -> Result<(), (ErrorCode, &'static mut [u16], &'static mut [u16])> {
646 if length1 == 0 {
647 Err((ErrorCode::INVAL, buffer1, buffer2))
649 } else {
650 self.next_buffer.replace(buffer2);
652 self.next_length.set(length2);
653
654 self.setup_channel(channel);
655 self.setup_resolution();
656
657 self.registers.result_ptr.set(buffer1.as_ptr());
659
660 self.buffer.replace(buffer1);
662 self.length.set(length1);
663
664 self.setup_sample_count(length1);
666
667 self.setup_frequency(frequency);
669
670 self.registers.enable.write(ENABLE::ENABLE::SET);
672
673 self.registers
675 .inten
676 .write(INTEN::STARTED::SET + INTEN::END::SET + INTEN::STOPPED::SET);
677
678 self.mode.set(AdcMode::HighSpeed);
679
680 self.registers.tasks_start.write(TASK::TASK::SET);
682
683 Ok(())
684 }
685 }
686
687 fn provide_buffer(
688 &self,
689 buf: &'static mut [u16],
690 length: usize,
691 ) -> Result<(), (ErrorCode, &'static mut [u16])> {
692 if self.next_buffer.is_some() {
693 Err((ErrorCode::BUSY, buf))
695 } else {
696 self.next_buffer.replace(buf);
698 self.next_length.set(length);
699
700 Ok(())
701 }
702 }
703
704 fn retrieve_buffers(
705 &self,
706 ) -> Result<(Option<&'static mut [u16]>, Option<&'static mut [u16]>), ErrorCode> {
707 Ok((self.buffer.take(), self.next_buffer.take()))
708 }
709
710 fn set_highspeed_client(&self, client: &'a dyn hil::adc::HighSpeedClient) {
711 self.highspeed_client.set(client);
712 }
713}