diff --git a/src/iir.rs b/src/iir.rs index 3b15885..8acb288 100644 --- a/src/iir.rs +++ b/src/iir.rs @@ -48,7 +48,7 @@ impl IIR { pub fn update(&self, xy: &mut IIRState, x0: f32) -> f32 { xy.rotate_right(1); - xy[0] = x0 - self.x_offset; + xy[0] = x0 + self.x_offset; let y0 = macc(self.y_offset, xy, &self.ba) .min(self.scale).max(-self.scale); xy[xy.len()/2] = y0; diff --git a/src/main.rs b/src/main.rs index 8cebee0..b1342ca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -197,7 +197,7 @@ fn io_compensation_setup(syscfg: &stm32::SYSCFG) { } fn gpio_setup(gpioa: &stm32::GPIOA, gpiob: &stm32::GPIOB, gpiod: &stm32::GPIOD, - gpioe: &stm32::GPIOE, gpiog: &stm32::GPIOG) { + gpioe: &stm32::GPIOE, gpiof: &stm32::GPIOF, gpiog: &stm32::GPIOG) { // FP_LED0 gpiod.otyper.modify(|_, w| w.ot5().push_pull()); gpiod.moder.modify(|_, w| w.moder5().output()); @@ -232,6 +232,7 @@ fn gpio_setup(gpioa: &stm32::GPIOA, gpiob: &stm32::GPIOB, gpiod: &stm32::GPIOD, .odr3().clear_bit() ); + // ADC0 // SCK: PG11 gpiog.moder.modify(|_, w| w.moder11().alternate()); gpiog.otyper.modify(|_, w| w.ot11().push_pull()); @@ -247,6 +248,7 @@ fn gpio_setup(gpioa: &stm32::GPIOA, gpiob: &stm32::GPIOB, gpiod: &stm32::GPIOD, gpiog.ospeedr.modify(|_, w| w.ospeedr10().very_high_speed()); gpiog.afrh.modify(|_, w| w.afr10().af5()); + // DAC0 // SCK: PB10 gpiob.moder.modify(|_, w| w.moder10().alternate()); gpiob.otyper.modify(|_, w| w.ot10().push_pull()); @@ -268,12 +270,53 @@ fn gpio_setup(gpioa: &stm32::GPIOA, gpiob: &stm32::GPIOB, gpiod: &stm32::GPIOD, gpioe.moder.modify(|_, w| w.moder11().output()); gpioe.otyper.modify(|_, w| w.ot11().push_pull()); gpioe.odr.modify(|_, w| w.odr11().clear_bit()); + // DAC_CLR: PE12 gpioe.moder.modify(|_, w| w.moder12().output()); gpioe.otyper.modify(|_, w| w.ot12().push_pull()); gpioe.odr.modify(|_, w| w.odr12().set_bit()); + + // ADC1 + // SCK: PF6 + gpiof.moder.modify(|_, w| w.moder7().alternate()); + gpiof.otyper.modify(|_, w| w.ot7().push_pull()); + gpiof.ospeedr.modify(|_, w| w.ospeedr7().very_high_speed()); + gpiof.afrl.modify(|_, w| w.afr7().af5()); + // MOSI: PF9 + // MISO: PF7 + gpiof.moder.modify(|_, w| w.moder8().alternate()); + gpiof.afrh.modify(|_, w| w.afr8().af5()); + // NSS: PF8 + gpiof.moder.modify(|_, w| w.moder6().alternate()); + gpiof.otyper.modify(|_, w| w.ot6().push_pull()); + gpiof.ospeedr.modify(|_, w| w.ospeedr6().very_high_speed()); + gpiof.afrl.modify(|_, w| w.afr6().af5()); + + // DAC1 + // SCK: PE2 + gpioe.moder.modify(|_, w| w.moder2().alternate()); + gpioe.otyper.modify(|_, w| w.ot2().push_pull()); + gpioe.ospeedr.modify(|_, w| w.ospeedr2().very_high_speed()); + gpioe.afrl.modify(|_, w| w.afr2().af5()); + // MOSI: PE6 + gpioe.moder.modify(|_, w| w.moder6().alternate()); + gpioe.otyper.modify(|_, w| w.ot6().push_pull()); + gpioe.ospeedr.modify(|_, w| w.ospeedr6().very_high_speed()); + gpioe.afrl.modify(|_, w| w.afr6().af5()); + // MISO: PE5 + // NSS: PE4 + gpioe.moder.modify(|_, w| w.moder4().alternate()); + gpioe.otyper.modify(|_, w| w.ot4().push_pull()); + gpioe.ospeedr.modify(|_, w| w.ospeedr4().very_high_speed()); + gpioe.afrl.modify(|_, w| w.afr4().af5()); + + // DAC1_LDAC: PE15 + gpioe.moder.modify(|_, w| w.moder15().output()); + gpioe.otyper.modify(|_, w| w.ot15().push_pull()); + gpioe.odr.modify(|_, w| w.odr15().clear_bit()); } +// ADC0 fn spi1_setup(spi1: &stm32::SPI1) { spi1.cfg1.modify(|_, w| unsafe { w.mbr().bits(1) // clk/4 @@ -302,6 +345,36 @@ fn spi1_setup(spi1: &stm32::SPI1) { spi1.cr1.write(|w| w.spe().set_bit()); } +// ADC1 +fn spi5_setup(spi5: &stm32::SPI5) { + spi5.cfg1.modify(|_, w| unsafe { + w.mbr().bits(1) // clk/4 + .dsize().bits(16 - 1) + .fthvl().bits(1 - 1) // one data + }); + spi5.cfg2.modify(|_, w| unsafe { + w.afcntr().set_bit() + .ssom().set_bit() // ss deassert between frames during midi + .ssoe().set_bit() // ss output enable + .ssiop().clear_bit() // ss active low + .ssm().clear_bit() // PAD counts + .cpol().set_bit() + .cpha().set_bit() + .lsbfrst().clear_bit() + .master().set_bit() + .sp().bits(0) // motorola + .comm().bits(0b10) // simplex receiver + .ioswp().clear_bit() + .midi().bits(0) // master inter data idle + .mssi().bits(6) // master SS idle + }); + spi5.cr2.modify(|_, w| unsafe { + w.tsize().bits(1) + }); + spi5.cr1.write(|w| w.spe().set_bit()); +} + +// DAC0 fn spi2_setup(spi2: &stm32::SPI2) { spi2.cfg1.modify(|_, w| unsafe { w.mbr().bits(0) // clk/2 @@ -328,6 +401,37 @@ fn spi2_setup(spi2: &stm32::SPI2) { w.tsize().bits(0) }); spi2.cr1.write(|w| w.spe().set_bit()); + spi2.cr1.modify(|r, w| unsafe { w.bits(r.bits() | (1 << 9)) }); +} + +// DAC1 +fn spi4_setup(spi4: &stm32::SPI4) { + spi4.cfg1.modify(|_, w| unsafe { + w.mbr().bits(0) // clk/2 + .dsize().bits(16 - 1) + .fthvl().bits(1 - 1) // one data + }); + spi4.cfg2.modify(|_, w| unsafe { + w.afcntr().set_bit() + .ssom().set_bit() // ss deassert between frames during midi + .ssoe().set_bit() // ss output enable + .ssiop().clear_bit() // ss active low + .ssm().clear_bit() // PAD counts + .cpol().clear_bit() + .cpha().clear_bit() + .lsbfrst().clear_bit() + .master().set_bit() + .sp().bits(0) // motorola + .comm().bits(0b01) // simplex transmitter + .ioswp().clear_bit() + .midi().bits(0) // master inter data idle + .mssi().bits(0) // master SS idle + }); + spi4.cr2.modify(|_, w| unsafe { + w.tsize().bits(0) + }); + spi4.cr1.write(|w| w.spe().set_bit()); + spi4.cr1.modify(|r, w| unsafe { w.bits(r.bits() | (1 << 9)) }); } fn tim2_setup(tim2: &stm32::TIM2) { @@ -367,9 +471,8 @@ fn dma1_setup(dma1: &stm32::DMA1, dmamux1: &stm32::DMAMUX1, ma: usize, pa: usize dma1.s0cr.modify(|_, w| w.en().set_bit()); } -static SPI1P: Mutex>> = - Mutex::new(RefCell::new(None)); -static SPI2P: Mutex>> = +static SPIP: Mutex>> = Mutex::new(RefCell::new(None)); #[link_section = ".sram1"] @@ -402,19 +505,28 @@ fn main() -> ! { .gpioben().set_bit() .gpioden().set_bit() .gpioeen().set_bit() + .gpiofen().set_bit() .gpiogen().set_bit() ); - gpio_setup(&dp.GPIOA, &dp.GPIOB, &dp.GPIOD, &dp.GPIOE, &dp.GPIOG); + gpio_setup(&dp.GPIOA, &dp.GPIOB, &dp.GPIOD, &dp.GPIOE, &dp.GPIOF, &dp.GPIOG); rcc.apb1lenr.modify(|_, w| w.spi2en().set_bit()); let spi2 = dp.SPI2; spi2_setup(&spi2); - spi2.cr1.modify(|r, w| unsafe { w.bits(r.bits() | (1 << 9)) }); + + rcc.apb2enr.modify(|_, w| w.spi4en().set_bit()); + let spi4 = dp.SPI4; + spi4_setup(&spi4); rcc.apb2enr.modify(|_, w| w.spi1en().set_bit()); let spi1 = dp.SPI1; spi1_setup(&spi1); - spi1.ier.write(|w| w.rxpie().set_bit()); + spi1.ier.write(|w| w.eotie().set_bit()); + + rcc.apb2enr.modify(|_, w| w.spi5en().set_bit()); + let spi5 = dp.SPI5; + spi5_setup(&spi5); + // spi5.ier.write(|w| w.eotie().set_bit()); rcc.ahb2enr.modify(|_, w| w.sram1en().set_bit()); rcc.ahb1enr.modify(|_, w| w.dma1en().set_bit()); @@ -423,25 +535,27 @@ fn main() -> ! { let dat_addr = unsafe { &DAT as *const _ } as usize; cp.SCB.clean_dcache_by_address(dat_addr, 4); + // TODO: also SPI4/ADC0 dma1_setup(&dp.DMA1, &dp.DMAMUX1, dat_addr, &spi1.cr1 as *const _ as usize); rcc.apb1lenr.modify(|_, w| w.tim2en().set_bit()); tim2_setup(&dp.TIM2); - unsafe { IIR_CH[0].pi(-0.01, 10.*2e-6/2., 0.).expect("bad coefficients"); } + unsafe { IIR_CH[0].pi(-0.1, 10.*2e-6/2., 0.).expect("bad coefficients"); } + unsafe { IIR_CH[1].pi(0.1, 10.*2e-6/2., 0.).expect("bad coefficients"); } cortex_m::interrupt::free(|cs| { cp.NVIC.enable(stm32::Interrupt::SPI1); cp.NVIC.enable(stm32::Interrupt::TIM2); // FIXME - SPI1P.borrow(cs).replace(Some(spi1)); - SPI2P.borrow(cs).replace(Some(spi2)); + SPIP.borrow(cs).replace(Some((spi1, spi2, spi4, spi5))); }); loop { for _ in 0..1000000 { cortex_m::asm::wfi(); } - let (x0, y0) = unsafe { (IIR_STATE[0][0], IIR_STATE[0][2]) }; - info!("x0={} y0={}", x0, y0); + let (x0, y0, x1, y1) = unsafe { + (IIR_STATE[0][0], IIR_STATE[0][2], IIR_STATE[1][0], IIR_STATE[1][2]) }; + info!("x0={} y0={} x1={} y1={}", x0, y0, x1, y1); } } @@ -449,7 +563,8 @@ fn main() -> ! { fn TIM2() { // FIXME let dp = unsafe { Peripherals::steal() }; dp.TIM2.sr.write(|w| w.uif().clear_bit()); // rc_w0 - dp.SPI1.cr1.write(|w| unsafe { w.bits(0x201) }); + dp.SPI1.cr1.write(|w| unsafe { w.bits(0x201) }); // ADC0 + dp.SPI5.cr1.write(|w| unsafe { w.bits(0x201) }); // ADC1 } const SCALE: f32 = ((1 << 15) - 1) as f32; @@ -463,26 +578,38 @@ fn SPI1() { #[cfg(feature = "bkpt")] cortex_m::asm::bkpt(); cortex_m::interrupt::free(|cs| { - let spi1p = SPI1P.borrow(cs).borrow(); - let spi1 = spi1p.as_ref().unwrap(); + let spip = SPIP.borrow(cs).borrow(); + let (spi1, spi2, spi4, spi5) = spip.as_ref().unwrap(); let sr = spi1.sr.read(); + if sr.eot().bit_is_set() { spi1.ifcr.write(|w| w.eotc().set_bit()); } if sr.rxp().bit_is_set() { - // needs to be a half word read let rxdr1 = &spi1.rxdr as *const _ as *const u16; let a = unsafe { ptr::read_volatile(rxdr1) }; let x0 = a as i16 as f32; let y0 = unsafe { IIR_CH[0].update(&mut IIR_STATE[0], x0) }; let d = y0 as i16 as u16 ^ 0x8000; - let spi2p = SPI2P.borrow(cs).borrow(); - let spi2 = spi2p.as_ref().unwrap(); - // needs to be a half word write let txdr2 = &spi2.txdr as *const _ as *mut u16; unsafe { ptr::write_volatile(txdr2, d) }; } + + let sr = spi5.sr.read(); + if sr.eot().bit_is_set() { + spi5.ifcr.write(|w| w.eotc().set_bit()); + } + if sr.rxp().bit_is_set() { + let rxdr1 = &spi5.rxdr as *const _ as *const u16; + let a = unsafe { ptr::read_volatile(rxdr1) }; + let x0 = a as i16 as f32; + let y0 = unsafe { IIR_CH[1].update(&mut IIR_STATE[1], x0) }; + let d = y0 as i16 as u16 ^ 0x8000; + + let txdr2 = &spi4.txdr as *const _ as *mut u16; + unsafe { ptr::write_volatile(txdr2, d) }; + } }); #[cfg(feature = "bkpt")] cortex_m::asm::bkpt();