use crate::include::{ProgError, ADC_MAP};
use crate::gpio::{Pin, Analog};
use rtt_target::rprintln;
#[doc(hidden)]
pub fn enable_channel(pin: (char, u8)) -> Result<(u8, u8), ProgError> {
let peripheral_ptr;
unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
let rcc = &peripheral_ptr.RCC;
let adcc = &peripheral_ptr.ADC_COMMON;
let (core, channel) = match return_channel(pin) {
Ok(values) => values,
Err(error) => {
rprintln!("P{}{} is not available for analog functions! | enable_channel()", pin.0.to_uppercase(), pin.1);
return Err(error);
}
};
match core {
1 => {
let adc1 = &peripheral_ptr.ADC1;
if rcc.apb2enr.read().adc1en().is_disabled() {
rcc.apb2enr.modify(|_, w| w.adc1en().enabled());
adcc.ccr.modify(|_, w| w.adcpre().div2());
adc1.smpr2.modify(|_, w| w.smp0().cycles144());
adc1.cr1.modify(|_, w| w.res().ten_bit());
adc1.cr2.modify(|_, w| w.adon().enabled());
}
},
2 => {
let adc2 = &peripheral_ptr.ADC2;
if rcc.apb2enr.read().adc2en().is_disabled() {
rcc.apb2enr.modify(|_, w| w.adc2en().enabled());
adcc.ccr.modify(|_, w| w.adcpre().div2());
adc2.smpr2.modify(|_, w| w.smp0().cycles144());
adc2.cr1.modify(|_, w| w.res().ten_bit());
adc2.cr2.modify(|_, w| w.adon().enabled());
}
},
3 => {
let adc3 = &peripheral_ptr.ADC3;
if rcc.apb2enr.read().adc3en().is_disabled() {
rcc.apb2enr.modify(|_, w| w.adc3en().enabled());
adcc.ccr.modify(|_, w| w.adcpre().div2());
adc3.smpr2.modify(|_, w| w.smp0().cycles144());
adc3.cr1.modify(|_, w| w.res().ten_bit());
adc3.cr2.modify(|_, w| w.adon().enabled());
}
},
_ => unreachable!()
};
return Ok((core, channel));
}
pub fn adc_resolution(res: u8) -> Result<(), ProgError> {
let peripheral_ptr;
unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
let rcc = &peripheral_ptr.RCC;
let adc1 = &peripheral_ptr.ADC1;
let adc2 = &peripheral_ptr.ADC2;
let adc3 = &peripheral_ptr.ADC3;
let enc_res = match res {
6 => 3,
8 => 2,
10 => 1,
12 => 0,
_ => {
rprintln!("{} is not a available ADC resolution! | adc_resolution()", res);
return Err(ProgError::InvalidConfiguration);
}
};
if rcc.apb2enr.read().adc1en().is_enabled() {adc1.cr1.modify(|_, w| w.res().bits(enc_res));}
if rcc.apb2enr.read().adc2en().is_enabled() {adc2.cr1.modify(|_, w| w.res().bits(enc_res));}
if rcc.apb2enr.read().adc3en().is_enabled() {adc3.cr1.modify(|_, w| w.res().bits(enc_res));}
return Ok(());
}
pub fn analog_read(pin: &Pin<Analog>) -> u16 {
let peripheral_ptr;
unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
let buffer = match pin.inner.core {
1 => {
let adc1 = &peripheral_ptr.ADC1;
adc1.sqr3.modify(|_, w| unsafe {w.sq1().bits(pin.number)});
adc1.cr2.write(|w| w.swstart().start());
while adc1.sr.read().eoc().is_not_complete() {}
adc1.dr.read().data().bits()
},
2 => {
let adc2 = &peripheral_ptr.ADC2;
adc2.sqr3.modify(|_, w| unsafe {w.sq1().bits(pin.number)});
adc2.cr2.write(|w| w.swstart().start());
while adc2.sr.read().eoc().is_not_complete() {}
adc2.dr.read().data().bits()
},
3 => {
let adc3 = &peripheral_ptr.ADC3;
adc3.sqr3.modify(|_, w| unsafe {w.sq1().bits(pin.number)});
adc3.cr2.write(|w| w.swstart().start());
while adc3.sr.read().eoc().is_not_complete() {}
adc3.dr.read().data().bits()
},
_ => unreachable!()
};
return buffer;
}
fn return_channel(pin: (char, u8)) -> Result<(u8, u8), ProgError> {
if !ADC_MAP.pins.contains(&pin) {return Err(ProgError::InvalidConfiguration);}
else {
let core = ADC_MAP.adcs[ADC_MAP.pins.iter().position(|&i| i == pin).unwrap()];
let channel = ADC_MAP.channels[ADC_MAP.pins.iter().position(|&i| i == pin).unwrap()];
return Ok((core, channel));
}
}