Work fully on both axies, reduce use of redundant code

Signed-off-by: fly <merspieler@alwaysdata.com>
This commit is contained in:
fly 2024-05-14 10:19:18 +02:00
parent 24ed8207bf
commit 42eca6a0ef

View file

@ -18,7 +18,7 @@ use stm32f1xx_hal::{
pac, pac,
prelude::*, prelude::*,
timer::{Channel, Tim2NoRemap}, timer::{Channel, Tim2NoRemap},
flash::{FlashWriter, FLASH_START, FlashSize, SectorSize}, flash::{FlashWriter, FlashSize, SectorSize},
usb::{Peripheral, UsbBus}, usb::{Peripheral, UsbBus},
}; };
@ -49,10 +49,6 @@ struct CalibrationData {
impl CalibrationData { impl CalibrationData {
const ADC_MAX: u16 = 4095; const ADC_MAX: u16 = 4095;
const _dummy: () = {
let size = core::mem::size_of::<CalibrationData>();
assert!(size <= 1021, "CalibrationData too big for flash size!");
};
fn new (min: u16, max: u16) -> CalibrationData { fn new (min: u16, max: u16) -> CalibrationData {
return CalibrationData {min, max, factor: calculate_factor(min, max)}; return CalibrationData {min, max, factor: calculate_factor(min, max)};
} }
@ -64,15 +60,17 @@ impl CalibrationData {
#[derive(Clone)] #[derive(Clone)]
#[derive(Zeroable)] #[derive(Zeroable)]
struct Calibration { struct Calibration {
integ_lt: CalibrationData, data: [CalibrationData; 2],
// flood_lt: CalibrationData,
} }
impl Calibration { impl Calibration {
const _dummy: () = {
let size = core::mem::size_of::<Calibration>();
assert!(size <= 1021, "Calibration too big for flash size!");
};
fn new () -> Calibration { fn new () -> Calibration {
return Calibration { return Calibration {
integ_lt: CalibrationData::new(0, CalibrationData::ADC_MAX), data: [CalibrationData::new(0, CalibrationData::ADC_MAX); 2],
// flood_lt: CalibrationData::new(0, CalibrationData::ADC_MAX),
}; };
} }
} }
@ -82,7 +80,6 @@ impl Calibration {
fn main() -> ! { fn main() -> ! {
// ====================== general setup ================= // ====================== general setup =================
// Acquire peripherals // Acquire peripherals
// let cp = cortex_m::Peripherals::take().unwrap();
let p = pac::Peripherals::take().unwrap(); let p = pac::Peripherals::take().unwrap();
let mut flash = p.FLASH.constrain(); let mut flash = p.FLASH.constrain();
let rcc = p.RCC.constrain(); let rcc = p.RCC.constrain();
@ -163,6 +160,7 @@ fn main() -> ! {
} }
} }
// TODO figure out why we only land here after we've sent a report
if usb_dev.poll(&mut [&mut consumer]) { if usb_dev.poll(&mut [&mut consumer]) {
match consumer.device().read_report() { match consumer.device().read_report() {
Err(UsbHidError::WouldBlock) => {} Err(UsbHidError::WouldBlock) => {}
@ -182,20 +180,30 @@ fn main() -> ! {
if output.generic & 0x1 == 0x1 { if output.generic & 0x1 == 0x1 {
calibration_active = true; calibration_active = true;
if !calibration_min_done && output.generic & 0x2 == 0x2 { if !calibration_min_done && output.generic & 0x2 == 0x2 {
cal.integ_lt.min = adc1.read(&mut input_pins.pa1).unwrap(); cal.data[0].min = adc1.read(&mut input_pins.pa1).unwrap();
cal.data[1].min = adc1.read(&mut input_pins.pa2).unwrap();
calibration_min_done = true; calibration_min_done = true;
} }
} }
else { else {
if calibration_active { if calibration_active {
let max = adc1.read(&mut input_pins.pa1).unwrap(); let mut values: [u16; 2] = [0; 2];
if max > cal.integ_lt.min { values[0] = adc1.read(&mut input_pins.pa1).unwrap();
cal.integ_lt.max = max; values[1] = adc1.read(&mut input_pins.pa2).unwrap();
let mut i = 0;
loop {
if values[i] > cal.data[i].min {
cal.data[i].max = values[i];
} }
else { else {
cal.integ_lt.max = CalibrationData::ADC_MAX; cal.data[i].max = CalibrationData::ADC_MAX;
}
cal.data[i].factor = calculate_factor(cal.data[i].min, cal.data[i].max);
i += 1;
if i == values.len() {
break;
}
} }
cal.integ_lt.factor = calculate_factor(cal.integ_lt.min, cal.integ_lt.max);
let save_success = save_calibration(&mut flash_writer, &cal); let save_success = save_calibration(&mut flash_writer, &cal);
if save_success { if save_success {
pwm.set_duty(Channel::C1, pwm_max); pwm.set_duty(Channel::C1, pwm_max);
@ -221,24 +229,32 @@ fn calculate_factor(min: u16, max: u16) -> f32 {
// Returns a CustomInputReport from the inputs given // Returns a CustomInputReport from the inputs given
fn get_report(pins: &mut MyPins, adc1: &mut adc::Adc<pac::ADC1>, cal: &Calibration) -> CustomInputReport { fn get_report(pins: &mut MyPins, adc1: &mut adc::Adc<pac::ADC1>, cal: &Calibration) -> CustomInputReport {
let integ_lt: u16 = adc1.read(&mut pins.pa1).unwrap(); let mut values: [u16; 2] = [0; 2];
let flood_lt: u16 = adc1.read(&mut pins.pa2).unwrap(); values[0] = adc1.read(&mut pins.pa1).unwrap();
values[1] = adc1.read(&mut pins.pa2).unwrap();
let buttons: u16 = 0; let buttons: u16 = 0;
let integ_lt_norm: u16; let mut values_norm: [u16; 2] = [0; 2];
if integ_lt < cal.integ_lt.min { let mut i = 0;
integ_lt_norm = 0; loop {
if values[i] < cal.data[i].min {
values_norm[i] = 0;
} }
else if integ_lt > cal.integ_lt.max { else if values[i] > cal.data[i].max {
integ_lt_norm = CalibrationData::ADC_MAX; values_norm[i] = CalibrationData::ADC_MAX;
} }
else { else {
integ_lt_norm = ((integ_lt - cal.integ_lt.min) as f32 * cal.integ_lt.factor) as u16; values_norm[i] = ((values[i] - cal.data[i].min) as f32 * cal.data[i].factor) as u16;
}
i += 1;
if i == values_norm.len() {
break;
}
} }
CustomInputReport { CustomInputReport {
x: integ_lt_norm, x: values_norm[0],
y: flood_lt, y: values_norm[1],
buttons, buttons,
} }
} }
@ -288,7 +304,7 @@ fn load_calibration(flash: &mut FlashWriter) -> Calibration {
// Load calibration data // Load calibration data
let dummy = bytes_of(&cal); let dummy = bytes_of(&cal);
let dummy2 = &data[3..][..dummy.len()]; let dummy2 = &data[3..][..dummy.len()];
let mut dummy3 = bytes_of_mut(&mut cal); let dummy3 = bytes_of_mut(&mut cal);
dummy3.copy_from_slice(&dummy2); dummy3.copy_from_slice(&dummy2);
return cal; return cal;
}, },