use crate::clock::{AdcClock, Enabled};
use crate::gpio::*;
use crate::hal::adc::{Channel, OneShot};
use crate::pac::ADC;
use crate::pdc::*;
use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering};
use cortex_m::singleton;
use embedded_dma::WriteBuffer;
use fugit::RateExtU32;
#[derive(PartialEq, Eq, Copy, Clone, Debug, defmt::Format)]
pub enum Powersaving {
Normal,
FastWakeup,
Sleep,
}
#[derive(PartialEq, Eq, Copy, Clone, Debug, defmt::Format)]
pub enum SingleEndedGain {
Gain1x = 1,
Gain2x = 2,
Gain4x = 3,
}
#[derive(PartialEq, Eq, Copy, Clone, Debug, defmt::Format)]
pub enum StartupTime {
Sut0,
Sut8,
Sut16,
Sut24,
Sut64,
Sut80,
Sut96,
Sut112,
Sut512,
Sut576,
Sut640,
Sut704,
Sut768,
Sut832,
Sut896,
Sut960,
}
#[derive(PartialEq, Eq, Copy, Clone, Debug, defmt::Format)]
pub enum SettlingTime {
Ast3,
Ast5,
Ast9,
Ast17,
}
#[derive(PartialEq, Eq, Copy, Clone, Debug, defmt::Format)]
pub enum TrackingTime {
Tt1 = 0,
Tt2 = 1,
Tt3 = 2,
Tt4 = 3,
Tt5 = 4,
Tt6 = 5,
Tt7 = 6,
Tt8 = 7,
Tt9 = 8,
Tt10 = 9,
Tt11 = 10,
Tt12 = 11,
Tt13 = 12,
Tt14 = 13,
Tt15 = 14,
Tt16 = 15,
}
#[derive(PartialEq, Eq, Copy, Clone, Debug, defmt::Format)]
pub enum TransferTime {
Tt3 = 0,
Tt5 = 1,
Tt7 = 2,
Tt11 = 3,
}
pub struct InterruptAdc<C>
where
C: ConversionMode,
{
adc: Adc,
m: core::marker::PhantomData<C>,
}
pub struct Adc {
adc: ADC,
clock: PhantomData<AdcClock<Enabled>>,
}
pub struct SingleConversion;
pub struct FreeRunning;
pub trait ConversionMode {
fn on_start(adc: &mut Adc);
fn on_complete<PIN: Channel<ADC, ID = u8>>(adc: &mut Adc, pin: &mut PIN);
fn on_stop<PIN: Channel<ADC, ID = u8>>(adc: &mut Adc, pin: &mut PIN);
}
impl Adc {
pub fn new(adc: ADC, clock: AdcClock<Enabled>) -> Self {
adc.wpmr
.modify(|_, w| w.wpkey().passwd().wpen().clear_bit());
unsafe {
adc.cr.write_with_zero(|w| w.swrst().set_bit());
adc.mr.write_with_zero(|w| w);
adc.ptcr
.write_with_zero(|w| w.rxtdis().set_bit().txtdis().set_bit());
}
let prescaler = (clock.frequency() / (2 * 20_u32.MHz::<1, 1>()) - 1) as u8;
adc.mr
.modify(|_, w| unsafe { w.prescal().bits(prescaler).startup().sut512() });
let tracking_time = 10;
let transfer_period = 2;
adc.mr.modify(|_, w| unsafe {
w.transfer()
.bits(transfer_period)
.tracktim()
.bits(tracking_time)
.settling()
.ast17()
});
adc.acr.modify(|_, w| w.tson().set_bit());
adc.mr.modify(|_, w| w.anach().allowed());
Self {
adc,
clock: PhantomData,
}
}
pub fn startup_time(&mut self, sut: StartupTime) {
self.adc.mr.modify(|_, w| match sut {
StartupTime::Sut0 => w.startup().sut0(),
StartupTime::Sut8 => w.startup().sut8(),
StartupTime::Sut16 => w.startup().sut16(),
StartupTime::Sut24 => w.startup().sut24(),
StartupTime::Sut64 => w.startup().sut64(),
StartupTime::Sut80 => w.startup().sut80(),
StartupTime::Sut96 => w.startup().sut96(),
StartupTime::Sut112 => w.startup().sut112(),
StartupTime::Sut512 => w.startup().sut512(),
StartupTime::Sut576 => w.startup().sut576(),
StartupTime::Sut640 => w.startup().sut640(),
StartupTime::Sut704 => w.startup().sut704(),
StartupTime::Sut768 => w.startup().sut768(),
StartupTime::Sut832 => w.startup().sut832(),
StartupTime::Sut896 => w.startup().sut896(),
StartupTime::Sut960 => w.startup().sut960(),
});
}
pub fn tracking_time(&mut self, tracking_time: TrackingTime) {
self.adc
.mr
.modify(|_, w| unsafe { w.tracktim().bits(tracking_time as u8) });
}
pub fn transfer_time(&mut self, transfer_time: TransferTime) {
self.adc
.mr
.modify(|_, w| unsafe { w.transfer().bits(transfer_time as u8) });
}
pub fn settling_time(&mut self, ast: SettlingTime) {
self.adc.mr.modify(|_, w| match ast {
SettlingTime::Ast3 => w.settling().ast3(),
SettlingTime::Ast5 => w.settling().ast5(),
SettlingTime::Ast9 => w.settling().ast9(),
SettlingTime::Ast17 => w.settling().ast17(),
});
}
pub fn prescaler(&mut self, prescaler: u8) {
self.adc
.mr
.modify(|_, w| unsafe { w.prescal().bits(prescaler) });
}
pub fn enable_tags(&mut self) {
self.adc.emr.modify(|_, w| w.tag().set_bit());
}
pub fn disable_tags(&mut self) {
self.adc.emr.modify(|_, w| w.tag().clear_bit());
}
pub fn temp_sensor(&mut self) -> &'static mut TempSensor {
singleton!(: TempSensor = TempSensor {}).unwrap()
}
pub fn sequence(&mut self, channels: &[u8]) {
for (pos, ch) in channels.iter().enumerate() {
defmt::trace!("Setting channel {} to {}", pos, *ch);
match pos {
0 => self.adc.seqr1.modify(|_, w| unsafe { w.usch1().bits(*ch) }),
1 => self.adc.seqr1.modify(|_, w| unsafe { w.usch2().bits(*ch) }),
2 => self.adc.seqr1.modify(|_, w| unsafe { w.usch3().bits(*ch) }),
3 => self.adc.seqr1.modify(|_, w| unsafe { w.usch4().bits(*ch) }),
4 => self.adc.seqr1.modify(|_, w| unsafe { w.usch5().bits(*ch) }),
5 => self.adc.seqr1.modify(|_, w| unsafe { w.usch6().bits(*ch) }),
6 => self.adc.seqr1.modify(|_, w| unsafe { w.usch7().bits(*ch) }),
7 => self.adc.seqr1.modify(|_, w| unsafe { w.usch8().bits(*ch) }),
8 => self.adc.seqr2.modify(|_, w| unsafe { w.usch9().bits(*ch) }),
9 => self
.adc
.seqr2
.modify(|_, w| unsafe { w.usch10().bits(*ch) }),
10 => self
.adc
.seqr2
.modify(|_, w| unsafe { w.usch11().bits(*ch) }),
11 => self
.adc
.seqr2
.modify(|_, w| unsafe { w.usch12().bits(*ch) }),
12 => self
.adc
.seqr2
.modify(|_, w| unsafe { w.usch13().bits(*ch) }),
13 => self
.adc
.seqr2
.modify(|_, w| unsafe { w.usch14().bits(*ch) }),
14 => self
.adc
.seqr2
.modify(|_, w| unsafe { w.usch15().bits(*ch) }),
_ => {
panic!("Invalid sequence position: {}", pos);
}
}
}
}
pub fn enable_sequencing(&mut self) {
self.adc.mr.modify(|_, w| w.useq().set_bit());
}
pub fn disable_sequencing(&mut self) {
self.adc.mr.modify(|_, w| w.useq().clear_bit());
}
pub fn powersaving(&mut self, ps: Powersaving) {
match ps {
Powersaving::Normal => self.adc.mr.modify(|_, w| w.sleep().normal()),
Powersaving::FastWakeup => self.adc.mr.modify(|_, w| w.sleep().sleep().fwup().on()),
Powersaving::Sleep => self.adc.mr.modify(|_, w| w.sleep().sleep().fwup().off()),
}
}
pub fn gain<PIN: Channel<ADC, ID = u8>>(&mut self, _pin: &mut PIN, gain: SingleEndedGain) {
match PIN::channel() {
0 => self
.adc
.cgr
.modify(|_, w| unsafe { w.gain0().bits(gain as u8) }),
1 => self
.adc
.cgr
.modify(|_, w| unsafe { w.gain1().bits(gain as u8) }),
2 => self
.adc
.cgr
.modify(|_, w| unsafe { w.gain2().bits(gain as u8) }),
3 => self
.adc
.cgr
.modify(|_, w| unsafe { w.gain3().bits(gain as u8) }),
4 => self
.adc
.cgr
.modify(|_, w| unsafe { w.gain4().bits(gain as u8) }),
5 => self
.adc
.cgr
.modify(|_, w| unsafe { w.gain5().bits(gain as u8) }),
6 => self
.adc
.cgr
.modify(|_, w| unsafe { w.gain6().bits(gain as u8) }),
7 => self
.adc
.cgr
.modify(|_, w| unsafe { w.gain7().bits(gain as u8) }),
8 => self
.adc
.cgr
.modify(|_, w| unsafe { w.gain8().bits(gain as u8) }),
9 => self
.adc
.cgr
.modify(|_, w| unsafe { w.gain9().bits(gain as u8) }),
10 => self
.adc
.cgr
.modify(|_, w| unsafe { w.gain10().bits(gain as u8) }),
11 => self
.adc
.cgr
.modify(|_, w| unsafe { w.gain11().bits(gain as u8) }),
12 => self
.adc
.cgr
.modify(|_, w| unsafe { w.gain12().bits(gain as u8) }),
13 => self
.adc
.cgr
.modify(|_, w| unsafe { w.gain13().bits(gain as u8) }),
14 => self
.adc
.cgr
.modify(|_, w| unsafe { w.gain14().bits(gain as u8) }),
15 => self
.adc
.cgr
.modify(|_, w| unsafe { w.gain15().bits(gain as u8) }),
_ => {
panic!("Invalid channel: {}", PIN::channel());
}
}
}
pub fn offset<PIN: Channel<ADC, ID = u8>>(&mut self, _pin: &mut PIN, offset: bool) {
match PIN::channel() {
0 => self.adc.cor.modify(|_, w| w.off0().bit(offset)),
1 => self.adc.cor.modify(|_, w| w.off1().bit(offset)),
2 => self.adc.cor.modify(|_, w| w.off2().bit(offset)),
3 => self.adc.cor.modify(|_, w| w.off3().bit(offset)),
4 => self.adc.cor.modify(|_, w| w.off4().bit(offset)),
5 => self.adc.cor.modify(|_, w| w.off5().bit(offset)),
6 => self.adc.cor.modify(|_, w| w.off6().bit(offset)),
7 => self.adc.cor.modify(|_, w| w.off7().bit(offset)),
8 => self.adc.cor.modify(|_, w| w.off8().bit(offset)),
9 => self.adc.cor.modify(|_, w| w.off9().bit(offset)),
10 => self.adc.cor.modify(|_, w| w.off10().bit(offset)),
11 => self.adc.cor.modify(|_, w| w.off11().bit(offset)),
12 => self.adc.cor.modify(|_, w| w.off12().bit(offset)),
13 => self.adc.cor.modify(|_, w| w.off13().bit(offset)),
14 => self.adc.cor.modify(|_, w| w.off14().bit(offset)),
15 => self.adc.cor.modify(|_, w| w.off15().bit(offset)),
_ => {
panic!("Invalid channel: {}", PIN::channel());
}
}
}
pub fn autocalibration(&mut self, wait: bool) {
unsafe { self.adc.cr.write_with_zero(|w| w.autocal().set_bit()) };
if wait {
while !self.calibration_ready() {}
defmt::trace!("Calibration complete");
}
}
pub fn calibration_ready(&self) -> bool {
self.adc.isr.read().eocal().bit()
}
fn enable_freerunning(&mut self) {
self.adc.mr.modify(|_, w| w.freerun().on());
}
fn disable_freerunning(&mut self) {
self.adc.mr.modify(|_, w| w.freerun().off());
}
fn synchronous_convert<PIN: Channel<ADC, ID = u8>>(&mut self, _pin: &mut PIN) -> u16 {
self.start_conversion();
while !match PIN::channel() {
0 => self.adc.isr.read().eoc0().bit(),
1 => self.adc.isr.read().eoc1().bit(),
2 => self.adc.isr.read().eoc2().bit(),
3 => self.adc.isr.read().eoc3().bit(),
4 => self.adc.isr.read().eoc4().bit(),
5 => self.adc.isr.read().eoc5().bit(),
6 => self.adc.isr.read().eoc6().bit(),
7 => self.adc.isr.read().eoc7().bit(),
8 => self.adc.isr.read().eoc8().bit(),
9 => self.adc.isr.read().eoc9().bit(),
10 => self.adc.isr.read().eoc10().bit(),
11 => self.adc.isr.read().eoc11().bit(),
12 => self.adc.isr.read().eoc12().bit(),
13 => self.adc.isr.read().eoc13().bit(),
14 => self.adc.isr.read().eoc14().bit(),
15 => self.adc.isr.read().eoc15().bit(),
_ => {
panic!("Invalid channel: {}", PIN::channel());
}
} {}
self.adc.cdr[PIN::channel() as usize].read().data().bits()
}
fn start_conversion(&mut self) {
unsafe { self.adc.cr.write_with_zero(|w| w.start().set_bit()) };
}
pub fn enable_channel<PIN: Channel<ADC, ID = u8>>(&mut self, _pin: &mut PIN) {
self.enable_channel_id(PIN::channel());
}
pub fn enable_channel_id(&mut self, channel: u8) {
unsafe {
match channel {
0 => self.adc.cher.write_with_zero(|w| w.ch0().set_bit()),
1 => self.adc.cher.write_with_zero(|w| w.ch1().set_bit()),
2 => self.adc.cher.write_with_zero(|w| w.ch2().set_bit()),
3 => self.adc.cher.write_with_zero(|w| w.ch3().set_bit()),
4 => self.adc.cher.write_with_zero(|w| w.ch4().set_bit()),
5 => self.adc.cher.write_with_zero(|w| w.ch5().set_bit()),
6 => self.adc.cher.write_with_zero(|w| w.ch6().set_bit()),
7 => self.adc.cher.write_with_zero(|w| w.ch7().set_bit()),
8 => self.adc.cher.write_with_zero(|w| w.ch8().set_bit()),
9 => self.adc.cher.write_with_zero(|w| w.ch9().set_bit()),
10 => self.adc.cher.write_with_zero(|w| w.ch10().set_bit()),
11 => self.adc.cher.write_with_zero(|w| w.ch11().set_bit()),
12 => self.adc.cher.write_with_zero(|w| w.ch12().set_bit()),
13 => self.adc.cher.write_with_zero(|w| w.ch13().set_bit()),
14 => self.adc.cher.write_with_zero(|w| w.ch14().set_bit()),
15 => self.adc.cher.write_with_zero(|w| w.ch15().set_bit()),
_ => {
panic!("Invalid channel: {}", channel);
}
}
}
}
pub fn disable_channel<PIN: Channel<ADC, ID = u8>>(&mut self, _pin: &mut PIN) {
self.disable_channel_id(PIN::channel());
}
pub fn disable_channel_id(&mut self, channel: u8) {
unsafe {
match channel {
0 => self.adc.chdr.write_with_zero(|w| w.ch0().set_bit()),
1 => self.adc.chdr.write_with_zero(|w| w.ch1().set_bit()),
2 => self.adc.chdr.write_with_zero(|w| w.ch2().set_bit()),
3 => self.adc.chdr.write_with_zero(|w| w.ch3().set_bit()),
4 => self.adc.chdr.write_with_zero(|w| w.ch4().set_bit()),
5 => self.adc.chdr.write_with_zero(|w| w.ch5().set_bit()),
6 => self.adc.chdr.write_with_zero(|w| w.ch6().set_bit()),
7 => self.adc.chdr.write_with_zero(|w| w.ch7().set_bit()),
8 => self.adc.chdr.write_with_zero(|w| w.ch8().set_bit()),
9 => self.adc.chdr.write_with_zero(|w| w.ch9().set_bit()),
10 => self.adc.chdr.write_with_zero(|w| w.ch10().set_bit()),
11 => self.adc.chdr.write_with_zero(|w| w.ch11().set_bit()),
12 => self.adc.chdr.write_with_zero(|w| w.ch12().set_bit()),
13 => self.adc.chdr.write_with_zero(|w| w.ch13().set_bit()),
14 => self.adc.chdr.write_with_zero(|w| w.ch14().set_bit()),
15 => self.adc.chdr.write_with_zero(|w| w.ch15().set_bit()),
_ => {
panic!("Invalid channel: {}", channel);
}
}
}
}
fn enable_interrupts<PIN: Channel<ADC, ID = u8>>(&mut self, _pin: &mut PIN) {
unsafe {
match PIN::channel() {
0 => self.adc.ier.write_with_zero(|w| w.eoc0().set_bit()),
1 => self.adc.ier.write_with_zero(|w| w.eoc1().set_bit()),
2 => self.adc.ier.write_with_zero(|w| w.eoc2().set_bit()),
3 => self.adc.ier.write_with_zero(|w| w.eoc3().set_bit()),
4 => self.adc.ier.write_with_zero(|w| w.eoc4().set_bit()),
5 => self.adc.ier.write_with_zero(|w| w.eoc5().set_bit()),
6 => self.adc.ier.write_with_zero(|w| w.eoc6().set_bit()),
7 => self.adc.ier.write_with_zero(|w| w.eoc7().set_bit()),
8 => self.adc.ier.write_with_zero(|w| w.eoc8().set_bit()),
9 => self.adc.ier.write_with_zero(|w| w.eoc9().set_bit()),
10 => self.adc.ier.write_with_zero(|w| w.eoc10().set_bit()),
11 => self.adc.ier.write_with_zero(|w| w.eoc11().set_bit()),
12 => self.adc.ier.write_with_zero(|w| w.eoc12().set_bit()),
13 => self.adc.ier.write_with_zero(|w| w.eoc13().set_bit()),
14 => self.adc.ier.write_with_zero(|w| w.eoc14().set_bit()),
15 => self.adc.ier.write_with_zero(|w| w.eoc15().set_bit()),
_ => {
panic!("Invalid channel: {}", PIN::channel());
}
}
}
}
fn disable_interrupts<PIN: Channel<ADC, ID = u8>>(&mut self, _pin: &mut PIN) {
unsafe {
match PIN::channel() {
0 => self.adc.idr.write_with_zero(|w| w.eoc0().set_bit()),
1 => self.adc.idr.write_with_zero(|w| w.eoc1().set_bit()),
2 => self.adc.idr.write_with_zero(|w| w.eoc2().set_bit()),
3 => self.adc.idr.write_with_zero(|w| w.eoc3().set_bit()),
4 => self.adc.idr.write_with_zero(|w| w.eoc4().set_bit()),
5 => self.adc.idr.write_with_zero(|w| w.eoc5().set_bit()),
6 => self.adc.idr.write_with_zero(|w| w.eoc6().set_bit()),
7 => self.adc.idr.write_with_zero(|w| w.eoc7().set_bit()),
8 => self.adc.idr.write_with_zero(|w| w.eoc8().set_bit()),
9 => self.adc.idr.write_with_zero(|w| w.eoc9().set_bit()),
10 => self.adc.idr.write_with_zero(|w| w.eoc10().set_bit()),
11 => self.adc.idr.write_with_zero(|w| w.eoc11().set_bit()),
12 => self.adc.idr.write_with_zero(|w| w.eoc12().set_bit()),
13 => self.adc.idr.write_with_zero(|w| w.eoc13().set_bit()),
14 => self.adc.idr.write_with_zero(|w| w.eoc14().set_bit()),
15 => self.adc.idr.write_with_zero(|w| w.eoc15().set_bit()),
_ => {
panic!("Invalid channel: {}", PIN::channel());
}
}
}
}
fn service_interrupt_ready<PIN: Channel<ADC, ID = u8>>(
&mut self,
_pin: &mut PIN,
) -> Option<u16> {
if !match PIN::channel() {
0 => self.adc.imr.read().eoc0().bit(),
1 => self.adc.imr.read().eoc1().bit(),
2 => self.adc.imr.read().eoc2().bit(),
3 => self.adc.imr.read().eoc3().bit(),
4 => self.adc.imr.read().eoc4().bit(),
5 => self.adc.imr.read().eoc5().bit(),
6 => self.adc.imr.read().eoc6().bit(),
7 => self.adc.imr.read().eoc7().bit(),
8 => self.adc.imr.read().eoc8().bit(),
9 => self.adc.imr.read().eoc9().bit(),
10 => self.adc.imr.read().eoc10().bit(),
11 => self.adc.imr.read().eoc11().bit(),
12 => self.adc.imr.read().eoc12().bit(),
13 => self.adc.imr.read().eoc13().bit(),
14 => self.adc.imr.read().eoc14().bit(),
15 => self.adc.imr.read().eoc15().bit(),
_ => {
panic!("Invalid channel: {}", PIN::channel());
}
} {
return None;
}
if match PIN::channel() {
0 => self.adc.isr.read().eoc0().bit(),
1 => self.adc.isr.read().eoc1().bit(),
2 => self.adc.isr.read().eoc2().bit(),
3 => self.adc.isr.read().eoc3().bit(),
4 => self.adc.isr.read().eoc4().bit(),
5 => self.adc.isr.read().eoc5().bit(),
6 => self.adc.isr.read().eoc6().bit(),
7 => self.adc.isr.read().eoc7().bit(),
8 => self.adc.isr.read().eoc8().bit(),
9 => self.adc.isr.read().eoc9().bit(),
10 => self.adc.isr.read().eoc10().bit(),
11 => self.adc.isr.read().eoc11().bit(),
12 => self.adc.isr.read().eoc12().bit(),
13 => self.adc.isr.read().eoc13().bit(),
14 => self.adc.isr.read().eoc14().bit(),
15 => self.adc.isr.read().eoc15().bit(),
_ => {
panic!("Invalid channel: {}", PIN::channel());
}
} {
Some(self.adc.cdr[PIN::channel() as usize].read().data().bits())
} else {
None
}
}
}
impl ConversionMode for SingleConversion {
fn on_start(_adc: &mut Adc) {}
fn on_complete<PIN: Channel<ADC, ID = u8>>(adc: &mut Adc, pin: &mut PIN) {
adc.disable_interrupts(pin);
}
fn on_stop<PIN: Channel<ADC, ID = u8>>(_adc: &mut Adc, _pin: &mut PIN) {}
}
impl ConversionMode for FreeRunning {
fn on_start(adc: &mut Adc) {
adc.enable_freerunning();
}
fn on_complete<PIN: Channel<ADC, ID = u8>>(_adc: &mut Adc, _pin: &mut PIN) {}
fn on_stop<PIN: Channel<ADC, ID = u8>>(adc: &mut Adc, pin: &mut PIN) {
adc.disable_interrupts(pin);
adc.disable_freerunning();
}
}
impl<C> InterruptAdc<C>
where
C: ConversionMode,
{
pub fn service_interrupt_ready<PIN: Channel<ADC, ID = u8>>(
&mut self,
pin: &mut PIN,
) -> Option<u16> {
if let Some(res) = self.adc.service_interrupt_ready(pin) {
C::on_complete(&mut self.adc, pin);
Some(res)
} else {
None
}
}
pub fn start_conversion<PIN: Channel<ADC, ID = u8>>(&mut self, pin: &mut PIN) {
C::on_start(&mut self.adc);
self.adc.enable_interrupts(pin);
self.adc.start_conversion();
}
pub fn stop_conversion<PIN: Channel<ADC, ID = u8>>(&mut self, pin: &mut PIN) {
C::on_stop(&mut self.adc, pin);
}
pub fn revert(self) -> Adc {
self.adc
}
}
impl<C> From<Adc> for InterruptAdc<C>
where
C: ConversionMode,
{
fn from(adc: Adc) -> Self {
Self {
adc,
m: PhantomData {},
}
}
}
impl<WORD, PIN> OneShot<ADC, WORD, PIN> for Adc
where
WORD: From<u16>,
PIN: Channel<ADC, ID = u8>,
{
type Error = ();
fn read(&mut self, pin: &mut PIN) -> nb::Result<WORD, Self::Error> {
let result = self.synchronous_convert(pin);
Ok(result.into())
}
}
macro_rules! adc_pins {
(
$(
$PinId:ident: ($CHAN:literal),
)+
) => {
$(
impl Channel<ADC> for $PinId<ExFn> {
type ID = u8;
fn channel() -> Self::ID { $CHAN }
}
)+
}
}
pub fn ch<PIN: Channel<ADC, ID = u8>>(_pin: &PIN) -> u8 {
PIN::channel()
}
#[cfg(feature = "atsam4s")]
adc_pins! {
Pa17: (0),
Pa18: (1),
Pa19: (2),
Pa20: (3),
Pb0: (4),
Pb1: (5),
Pb2: (6),
Pb3: (7),
}
#[cfg(any(feature = "atsam4s_b", feature = "atsam4s_c"))]
adc_pins! {
Pa21: (8),
Pa22: (9),
}
#[cfg(feature = "atsam4s_c")]
adc_pins! {
Pc13: (10),
Pc15: (11),
Pc12: (12),
Pc29: (13),
Pc30: (14),
}
#[cfg(feature = "atsam4s")]
pub struct TempSensor {}
#[cfg(feature = "atsam4s")]
impl Channel<ADC> for TempSensor {
type ID = u8;
fn channel() -> u8 {
15
}
}
pdc_rx! { Adc: adc, isr }
impl Adc {
pub fn with_pdc(self) -> AdcDma<SingleSequence> {
let payload = AdcPayload {
adc: self,
_mode: PhantomData,
};
RxDma { payload }
}
pub fn with_continuous_pdc(self) -> AdcDma<Continuous> {
let payload = AdcPayload {
adc: self,
_mode: PhantomData,
};
RxDma { payload }
}
}
pub struct Continuous;
pub struct SingleSequence;
pub struct AdcPayload<MODE> {
adc: Adc,
_mode: PhantomData<MODE>,
}
pub type AdcDma<MODE> = RxDma<AdcPayload<MODE>>;
impl<MODE> AdcDma<MODE>
where
Self: TransferPayload,
{
pub fn revert(mut self) -> Adc {
self.payload.adc.stop_rx_pdc();
self.payload.adc
}
}
impl<MODE> Receive for AdcDma<MODE> {
type TransmittedWord = u16;
}
impl<B, MODE> ReadDma<B, u16> for AdcDma<MODE>
where
Self: TransferPayload,
B: WriteBuffer<Word = u16>,
{
fn read(mut self, mut buffer: B) -> Transfer<W, B, Self> {
let (ptr, len) = unsafe { buffer.write_buffer() };
self.payload.adc.set_receive_address(ptr as u32);
self.payload.adc.set_receive_counter(len as u16);
compiler_fence(Ordering::Release);
self.start();
Transfer::w(buffer, self)
}
}
impl<B, MODE> ReadDmaPaused<B, u16> for AdcDma<MODE>
where
Self: TransferPayload,
B: WriteBuffer<Word = u16>,
{
fn read_paused(mut self, mut buffer: B) -> Transfer<W, B, Self> {
let (ptr, len) = unsafe { buffer.write_buffer() };
self.payload.adc.set_receive_address(ptr as u32);
self.payload.adc.set_receive_counter(len as u16);
compiler_fence(Ordering::Release);
Transfer::w(buffer, self)
}
}
impl TransferPayload for AdcDma<SingleSequence> {
fn start(&mut self) {
self.payload.adc.start_rx_pdc();
self.payload.adc.start_conversion(); }
fn stop(&mut self) {
self.payload.adc.stop_rx_pdc();
}
fn in_progress(&self) -> bool {
self.payload.adc.rx_in_progress()
}
}
impl TransferPayload for AdcDma<Continuous> {
fn start(&mut self) {
self.payload.adc.start_rx_pdc();
self.payload.adc.enable_freerunning();
self.payload.adc.start_conversion(); }
fn stop(&mut self) {
self.payload.adc.disable_freerunning();
self.payload.adc.stop_rx_pdc();
}
fn in_progress(&self) -> bool {
self.payload.adc.rx_in_progress()
}
}