dual channel
This commit is contained in:
parent
7f378a3f3d
commit
dc2e0f8b07
@ -48,7 +48,7 @@ impl IIR {
|
|||||||
|
|
||||||
pub fn update(&self, xy: &mut IIRState, x0: f32) -> f32 {
|
pub fn update(&self, xy: &mut IIRState, x0: f32) -> f32 {
|
||||||
xy.rotate_right(1);
|
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)
|
let y0 = macc(self.y_offset, xy, &self.ba)
|
||||||
.min(self.scale).max(-self.scale);
|
.min(self.scale).max(-self.scale);
|
||||||
xy[xy.len()/2] = y0;
|
xy[xy.len()/2] = y0;
|
||||||
|
165
src/main.rs
165
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,
|
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
|
// FP_LED0
|
||||||
gpiod.otyper.modify(|_, w| w.ot5().push_pull());
|
gpiod.otyper.modify(|_, w| w.ot5().push_pull());
|
||||||
gpiod.moder.modify(|_, w| w.moder5().output());
|
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()
|
.odr3().clear_bit()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ADC0
|
||||||
// SCK: PG11
|
// SCK: PG11
|
||||||
gpiog.moder.modify(|_, w| w.moder11().alternate());
|
gpiog.moder.modify(|_, w| w.moder11().alternate());
|
||||||
gpiog.otyper.modify(|_, w| w.ot11().push_pull());
|
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.ospeedr.modify(|_, w| w.ospeedr10().very_high_speed());
|
||||||
gpiog.afrh.modify(|_, w| w.afr10().af5());
|
gpiog.afrh.modify(|_, w| w.afr10().af5());
|
||||||
|
|
||||||
|
// DAC0
|
||||||
// SCK: PB10
|
// SCK: PB10
|
||||||
gpiob.moder.modify(|_, w| w.moder10().alternate());
|
gpiob.moder.modify(|_, w| w.moder10().alternate());
|
||||||
gpiob.otyper.modify(|_, w| w.ot10().push_pull());
|
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.moder.modify(|_, w| w.moder11().output());
|
||||||
gpioe.otyper.modify(|_, w| w.ot11().push_pull());
|
gpioe.otyper.modify(|_, w| w.ot11().push_pull());
|
||||||
gpioe.odr.modify(|_, w| w.odr11().clear_bit());
|
gpioe.odr.modify(|_, w| w.odr11().clear_bit());
|
||||||
|
|
||||||
// DAC_CLR: PE12
|
// DAC_CLR: PE12
|
||||||
gpioe.moder.modify(|_, w| w.moder12().output());
|
gpioe.moder.modify(|_, w| w.moder12().output());
|
||||||
gpioe.otyper.modify(|_, w| w.ot12().push_pull());
|
gpioe.otyper.modify(|_, w| w.ot12().push_pull());
|
||||||
gpioe.odr.modify(|_, w| w.odr12().set_bit());
|
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) {
|
fn spi1_setup(spi1: &stm32::SPI1) {
|
||||||
spi1.cfg1.modify(|_, w| unsafe {
|
spi1.cfg1.modify(|_, w| unsafe {
|
||||||
w.mbr().bits(1) // clk/4
|
w.mbr().bits(1) // clk/4
|
||||||
@ -302,6 +345,36 @@ fn spi1_setup(spi1: &stm32::SPI1) {
|
|||||||
spi1.cr1.write(|w| w.spe().set_bit());
|
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) {
|
fn spi2_setup(spi2: &stm32::SPI2) {
|
||||||
spi2.cfg1.modify(|_, w| unsafe {
|
spi2.cfg1.modify(|_, w| unsafe {
|
||||||
w.mbr().bits(0) // clk/2
|
w.mbr().bits(0) // clk/2
|
||||||
@ -328,6 +401,37 @@ fn spi2_setup(spi2: &stm32::SPI2) {
|
|||||||
w.tsize().bits(0)
|
w.tsize().bits(0)
|
||||||
});
|
});
|
||||||
spi2.cr1.write(|w| w.spe().set_bit());
|
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) {
|
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());
|
dma1.s0cr.modify(|_, w| w.en().set_bit());
|
||||||
}
|
}
|
||||||
|
|
||||||
static SPI1P: Mutex<RefCell<Option<stm32::SPI1>>> =
|
static SPIP: Mutex<RefCell<Option<(
|
||||||
Mutex::new(RefCell::new(None));
|
stm32::SPI1, stm32::SPI2, stm32::SPI4, stm32::SPI5)>>> =
|
||||||
static SPI2P: Mutex<RefCell<Option<stm32::SPI2>>> =
|
|
||||||
Mutex::new(RefCell::new(None));
|
Mutex::new(RefCell::new(None));
|
||||||
|
|
||||||
#[link_section = ".sram1"]
|
#[link_section = ".sram1"]
|
||||||
@ -402,19 +505,28 @@ fn main() -> ! {
|
|||||||
.gpioben().set_bit()
|
.gpioben().set_bit()
|
||||||
.gpioden().set_bit()
|
.gpioden().set_bit()
|
||||||
.gpioeen().set_bit()
|
.gpioeen().set_bit()
|
||||||
|
.gpiofen().set_bit()
|
||||||
.gpiogen().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());
|
rcc.apb1lenr.modify(|_, w| w.spi2en().set_bit());
|
||||||
let spi2 = dp.SPI2;
|
let spi2 = dp.SPI2;
|
||||||
spi2_setup(&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());
|
rcc.apb2enr.modify(|_, w| w.spi1en().set_bit());
|
||||||
let spi1 = dp.SPI1;
|
let spi1 = dp.SPI1;
|
||||||
spi1_setup(&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.ahb2enr.modify(|_, w| w.sram1en().set_bit());
|
||||||
rcc.ahb1enr.modify(|_, w| w.dma1en().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;
|
let dat_addr = unsafe { &DAT as *const _ } as usize;
|
||||||
cp.SCB.clean_dcache_by_address(dat_addr, 4);
|
cp.SCB.clean_dcache_by_address(dat_addr, 4);
|
||||||
|
|
||||||
|
// TODO: also SPI4/ADC0
|
||||||
dma1_setup(&dp.DMA1, &dp.DMAMUX1, dat_addr,
|
dma1_setup(&dp.DMA1, &dp.DMAMUX1, dat_addr,
|
||||||
&spi1.cr1 as *const _ as usize);
|
&spi1.cr1 as *const _ as usize);
|
||||||
|
|
||||||
rcc.apb1lenr.modify(|_, w| w.tim2en().set_bit());
|
rcc.apb1lenr.modify(|_, w| w.tim2en().set_bit());
|
||||||
tim2_setup(&dp.TIM2);
|
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| {
|
cortex_m::interrupt::free(|cs| {
|
||||||
cp.NVIC.enable(stm32::Interrupt::SPI1);
|
cp.NVIC.enable(stm32::Interrupt::SPI1);
|
||||||
cp.NVIC.enable(stm32::Interrupt::TIM2); // FIXME
|
cp.NVIC.enable(stm32::Interrupt::TIM2); // FIXME
|
||||||
SPI1P.borrow(cs).replace(Some(spi1));
|
SPIP.borrow(cs).replace(Some((spi1, spi2, spi4, spi5)));
|
||||||
SPI2P.borrow(cs).replace(Some(spi2));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
for _ in 0..1000000 { cortex_m::asm::wfi(); }
|
for _ in 0..1000000 { cortex_m::asm::wfi(); }
|
||||||
let (x0, y0) = unsafe { (IIR_STATE[0][0], IIR_STATE[0][2]) };
|
let (x0, y0, x1, y1) = unsafe {
|
||||||
info!("x0={} y0={}", x0, y0);
|
(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
|
fn TIM2() { // FIXME
|
||||||
let dp = unsafe { Peripherals::steal() };
|
let dp = unsafe { Peripherals::steal() };
|
||||||
dp.TIM2.sr.write(|w| w.uif().clear_bit()); // rc_w0
|
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;
|
const SCALE: f32 = ((1 << 15) - 1) as f32;
|
||||||
@ -463,26 +578,38 @@ fn SPI1() {
|
|||||||
#[cfg(feature = "bkpt")]
|
#[cfg(feature = "bkpt")]
|
||||||
cortex_m::asm::bkpt();
|
cortex_m::asm::bkpt();
|
||||||
cortex_m::interrupt::free(|cs| {
|
cortex_m::interrupt::free(|cs| {
|
||||||
let spi1p = SPI1P.borrow(cs).borrow();
|
let spip = SPIP.borrow(cs).borrow();
|
||||||
let spi1 = spi1p.as_ref().unwrap();
|
let (spi1, spi2, spi4, spi5) = spip.as_ref().unwrap();
|
||||||
let sr = spi1.sr.read();
|
let sr = spi1.sr.read();
|
||||||
|
|
||||||
if sr.eot().bit_is_set() {
|
if sr.eot().bit_is_set() {
|
||||||
spi1.ifcr.write(|w| w.eotc().set_bit());
|
spi1.ifcr.write(|w| w.eotc().set_bit());
|
||||||
}
|
}
|
||||||
if sr.rxp().bit_is_set() {
|
if sr.rxp().bit_is_set() {
|
||||||
// needs to be a half word read
|
|
||||||
let rxdr1 = &spi1.rxdr as *const _ as *const u16;
|
let rxdr1 = &spi1.rxdr as *const _ as *const u16;
|
||||||
let a = unsafe { ptr::read_volatile(rxdr1) };
|
let a = unsafe { ptr::read_volatile(rxdr1) };
|
||||||
let x0 = a as i16 as f32;
|
let x0 = a as i16 as f32;
|
||||||
let y0 = unsafe { IIR_CH[0].update(&mut IIR_STATE[0], x0) };
|
let y0 = unsafe { IIR_CH[0].update(&mut IIR_STATE[0], x0) };
|
||||||
let d = y0 as i16 as u16 ^ 0x8000;
|
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;
|
let txdr2 = &spi2.txdr as *const _ as *mut u16;
|
||||||
unsafe { ptr::write_volatile(txdr2, d) };
|
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")]
|
#[cfg(feature = "bkpt")]
|
||||||
cortex_m::asm::bkpt();
|
cortex_m::asm::bkpt();
|
||||||
|
Loading…
Reference in New Issue
Block a user