diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 0000000..df99c69 --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1 @@ +max_width = 80 diff --git a/.travis.yml b/.travis.yml index c0c85bf..1d9ab5e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,11 +20,13 @@ branches: before_script: - rustup target add thumbv7em-none-eabihf - # - rustup component add clippy + - rustup component add clippy + - rustup component add rustfmt script: - # - cargo clippy - "cargo build --target thumbv7em-none-eabihf --features \"$FEATURES\" $ARGS" + - cargo clippy + - cargo fmt --all -- --check notifications: email: false diff --git a/src/board.rs b/src/board.rs index 86eea26..993ebe7 100644 --- a/src/board.rs +++ b/src/board.rs @@ -1,43 +1,40 @@ -use super::pac; -use super::i2c; use super::eth; +use super::i2c; +use super::pac; fn pwr_setup(pwr: &pac::PWR) { // go to VOS1 voltage scale for high perf - pwr.cr3.write(|w| - w.scuen().set_bit() - .ldoen().set_bit() - .bypass().clear_bit() - ); + pwr.cr3 + .write(|w| w.scuen().set_bit().ldoen().set_bit().bypass().clear_bit()); while pwr.csr1.read().actvosrdy().bit_is_clear() {} - pwr.d3cr.write(|w| unsafe { w.vos().bits(0b11) }); // vos1 + pwr.d3cr.write(|w| unsafe { w.vos().bits(0b11) }); // vos1 while pwr.d3cr.read().vosrdy().bit_is_clear() {} } fn rcc_reset(rcc: &pac::RCC) { // Reset all peripherals rcc.ahb1rstr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); - rcc.ahb1rstr.write(|w| unsafe { w.bits(0)}); + rcc.ahb1rstr.write(|w| unsafe { w.bits(0) }); rcc.apb1lrstr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); - rcc.apb1lrstr.write(|w| unsafe { w.bits(0)}); + rcc.apb1lrstr.write(|w| unsafe { w.bits(0) }); rcc.apb1hrstr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); - rcc.apb1hrstr.write(|w| unsafe { w.bits(0)}); + rcc.apb1hrstr.write(|w| unsafe { w.bits(0) }); rcc.ahb2rstr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); - rcc.ahb2rstr.write(|w| unsafe { w.bits(0)}); + rcc.ahb2rstr.write(|w| unsafe { w.bits(0) }); rcc.apb2rstr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); - rcc.apb2rstr.write(|w| unsafe { w.bits(0)}); + rcc.apb2rstr.write(|w| unsafe { w.bits(0) }); // do not reset the cpu rcc.ahb3rstr.write(|w| unsafe { w.bits(0x7FFF_FFFF) }); - rcc.ahb3rstr.write(|w| unsafe { w.bits(0)}); + rcc.ahb3rstr.write(|w| unsafe { w.bits(0) }); rcc.apb3rstr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); - rcc.apb3rstr.write(|w| unsafe { w.bits(0)}); + rcc.apb3rstr.write(|w| unsafe { w.bits(0) }); rcc.ahb4rstr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); - rcc.ahb4rstr.write(|w| unsafe { w.bits(0)}); + rcc.ahb4rstr.write(|w| unsafe { w.bits(0) }); rcc.apb4rstr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); - rcc.apb4rstr.write(|w| unsafe { w.bits(0)}); + rcc.apb4rstr.write(|w| unsafe { w.bits(0) }); } fn rcc_pll_setup(rcc: &pac::RCC, flash: &pac::FLASH) { @@ -50,64 +47,89 @@ fn rcc_pll_setup(rcc: &pac::RCC, flash: &pac::FLASH) { rcc.cfgr.reset(); // Ensure HSE is on and stable - rcc.cr.modify(|_, w| - w.hseon().on() - .hsebyp().not_bypassed()); + rcc.cr.modify(|_, w| w.hseon().on().hsebyp().not_bypassed()); while !rcc.cr.read().hserdy().is_ready() {} - rcc.pllckselr.modify(|_, w| - w.pllsrc().hse() - .divm1().bits(1) // ref prescaler - .divm2().bits(1) // ref prescaler + rcc.pllckselr.modify( + |_, w| { + w.pllsrc() + .hse() + .divm1() + .bits(1) // ref prescaler + .divm2() + .bits(1) + }, // ref prescaler ); // Configure PLL1: 8MHz /1 *100 /2 = 400 MHz - rcc.pllcfgr.modify(|_, w| - w.pll1vcosel().wide_vco() // 192-836 MHz VCO - .pll1rge().range8() // 8-16 MHz PFD - .pll1fracen().reset() - .divp1en().enabled() - .pll2vcosel().medium_vco() // 150-420 MHz VCO - .pll2rge().range8() // 8-16 MHz PFD - .pll2fracen().reset() - .divp2en().enabled() - .divq2en().enabled() - ); + rcc.pllcfgr.modify(|_, w| { + w.pll1vcosel() + .wide_vco() // 192-836 MHz VCO + .pll1rge() + .range8() // 8-16 MHz PFD + .pll1fracen() + .reset() + .divp1en() + .enabled() + .pll2vcosel() + .medium_vco() // 150-420 MHz VCO + .pll2rge() + .range8() // 8-16 MHz PFD + .pll2fracen() + .reset() + .divp2en() + .enabled() + .divq2en() + .enabled() + }); rcc.pll1divr.write(|w| unsafe { - w.divn1().bits(100 - 1) // feebdack divider - .divp1().div2() // p output divider + w.divn1() + .bits(100 - 1) // feebdack divider + .divp1() + .div2() // p output divider }); rcc.cr.modify(|_, w| w.pll1on().on()); while !rcc.cr.read().pll1rdy().is_ready() {} // Configure PLL2: 8MHz /1 *25 / 2 = 100 MHz rcc.pll2divr.write(|w| unsafe { - w.divn2().bits(25 - 1) // feebdack divider - .divp2().bits(2 - 1) // p output divider - .divq2().bits(2 - 1) // q output divider + w.divn2() + .bits(25 - 1) // feebdack divider + .divp2() + .bits(2 - 1) // p output divider + .divq2() + .bits(2 - 1) // q output divider }); rcc.cr.modify(|_, w| w.pll2on().on()); while !rcc.cr.read().pll2rdy().is_ready() {} // hclk 200 MHz, pclk 100 MHz - rcc.d1cfgr.write(|w| - w.d1cpre().div1() // sys_ck not divided - .hpre().div2() // rcc_hclk3 = sys_d1cpre_ck / 2 - .d1ppre().div2() // rcc_pclk3 = rcc_hclk3 / 2 + rcc.d1cfgr.write( + |w| { + w.d1cpre() + .div1() // sys_ck not divided + .hpre() + .div2() // rcc_hclk3 = sys_d1cpre_ck / 2 + .d1ppre() + .div2() + }, // rcc_pclk3 = rcc_hclk3 / 2 ); - rcc.d2cfgr.write(|w| - w.d2ppre1().div2() // rcc_pclk1 = rcc_hclk3 / 2 - .d2ppre2().div2() // rcc_pclk2 = rcc_hclk3 / 2 + rcc.d2cfgr.write( + |w| { + w.d2ppre1() + .div2() // rcc_pclk1 = rcc_hclk3 / 2 + .d2ppre2() + .div2() + }, // rcc_pclk2 = rcc_hclk3 / 2 ); - rcc.d3cfgr.write(|w| - w.d3ppre().div2() // rcc_pclk4 = rcc_hclk3 / 2 + rcc.d3cfgr.write( + |w| w.d3ppre().div2(), // rcc_pclk4 = rcc_hclk3 / 2 ); // 2 wait states, 0b10 programming delay // 185-210 MHz - flash.acr.write(|w| unsafe { - w.wrhighfreq().bits(2) - .latency().bits(2) - }); + flash + .acr + .write(|w| unsafe { w.wrhighfreq().bits(2).latency().bits(2) }); while flash.acr.read().latency().bits() != 2 {} // CSI for I/O compensationc ell @@ -119,24 +141,26 @@ fn rcc_pll_setup(rcc: &pac::RCC, flash: &pac::FLASH) { while !rcc.cfgr.read().sws().is_pll1() {} rcc.d1ccipr.write(|w| w.ckpersel().hse()); - rcc.d2ccip1r.modify(|_, w| - w.spi123sel().pll2_p() - .spi45sel().pll2_q() - ); + rcc.d2ccip1r + .modify(|_, w| w.spi123sel().pll2_p().spi45sel().pll2_q()); rcc.d3ccipr.modify(|_, w| w.spi6sel().pll2_q()); } fn io_compensation_setup(syscfg: &pac::SYSCFG) { - syscfg.cccsr.modify(|_, w| - w.en().set_bit() - .cs().clear_bit() - .hslv().clear_bit() - ); + syscfg + .cccsr + .modify(|_, w| w.en().set_bit().cs().clear_bit().hslv().clear_bit()); while syscfg.cccsr.read().ready().bit_is_clear() {} } -fn gpio_setup(gpioa: &pac::GPIOA, gpiob: &pac::GPIOB, gpiod: &pac::GPIOD, - gpioe: &pac::GPIOE, gpiof: &pac::GPIOF, gpiog: &pac::GPIOG) { +fn gpio_setup( + gpioa: &pac::GPIOA, + gpiob: &pac::GPIOB, + gpiod: &pac::GPIOD, + gpioe: &pac::GPIOE, + gpiof: &pac::GPIOF, + gpiog: &pac::GPIOG, +) { // FP_LED0 gpiod.otyper.modify(|_, w| w.ot5().push_pull()); gpiod.moder.modify(|_, w| w.moder5().output()); @@ -158,18 +182,13 @@ fn gpio_setup(gpioa: &pac::GPIOA, gpiob: &pac::GPIOB, gpiod: &pac::GPIOD, gpiod.odr.modify(|_, w| w.odr12().low()); // AFE0_A0,1: PG2,PG3 - gpiog.otyper.modify(|_, w| - w.ot2().push_pull() - .ot3().push_pull() - ); - gpiog.moder.modify(|_, w| - w.moder2().output() - .moder3().output() - ); - gpiog.odr.modify(|_, w| - w.odr2().low() - .odr3().low() - ); + gpiog + .otyper + .modify(|_, w| w.ot2().push_pull().ot3().push_pull()); + gpiog + .moder + .modify(|_, w| w.moder2().output().moder3().output()); + gpiog.odr.modify(|_, w| w.odr2().low().odr3().low()); // ADC0 // SCK: PG11 @@ -216,32 +235,22 @@ fn gpio_setup(gpioa: &pac::GPIOA, gpiob: &pac::GPIOB, gpiod: &pac::GPIOD, gpioe.odr.modify(|_, w| w.odr12().high()); // AFE1_A0,1: PD14,PD15 - gpiod.otyper.modify(|_, w| - w.ot14().push_pull() - .ot15().push_pull() - ); - gpiod.moder.modify(|_, w| - w.moder14().output() - .moder15().output() - ); - gpiod.odr.modify(|_, w| - w.odr14().low() - .odr15().low() - ); + gpiod + .otyper + .modify(|_, w| w.ot14().push_pull().ot15().push_pull()); + gpiod + .moder + .modify(|_, w| w.moder14().output().moder15().output()); + gpiod.odr.modify(|_, w| w.odr14().low().odr15().low()); // I2C2: SDA,SCL: PF0,PF1 - gpiof.moder.modify(|_, w| - w.moder0().alternate() - .moder1().alternate() - ); - gpiof.afrl.modify(|_, w| - w.afr0().af4() - .afr1().af4() - ); - gpiof.otyper.modify(|_, w| - w.ot0().open_drain() - .ot1().open_drain() - ); + gpiof + .moder + .modify(|_, w| w.moder0().alternate().moder1().alternate()); + gpiof.afrl.modify(|_, w| w.afr0().af4().afr1().af4()); + gpiof + .otyper + .modify(|_, w| w.ot0().open_drain().ot1().open_drain()); // ADC1 // SCK: PF6 @@ -285,81 +294,114 @@ fn gpio_setup(gpioa: &pac::GPIOA, gpiob: &pac::GPIOB, gpiod: &pac::GPIOD, // ADC0 fn spi1_setup(spi1: &pac::SPI1) { - spi1.cfg1.modify(|_, w| - w.mbr().div4() - .dsize().bits(16 - 1) - .fthlv().one_frame() - ); - spi1.cfg2.modify(|_, w| - w.afcntr().controlled() - .ssom().not_asserted() - .ssoe().enabled() - .ssiop().active_low() - .ssm().disabled() - .cpol().idle_high() - .cpha().second_edge() - .lsbfrst().msbfirst() - .master().master() - .sp().motorola() - .comm().receiver() - .ioswp().disabled() - .midi().bits(0) - .mssi().bits(6) - ); + spi1.cfg1 + .modify(|_, w| w.mbr().div4().dsize().bits(16 - 1).fthlv().one_frame()); + spi1.cfg2.modify(|_, w| { + w.afcntr() + .controlled() + .ssom() + .not_asserted() + .ssoe() + .enabled() + .ssiop() + .active_low() + .ssm() + .disabled() + .cpol() + .idle_high() + .cpha() + .second_edge() + .lsbfrst() + .msbfirst() + .master() + .master() + .sp() + .motorola() + .comm() + .receiver() + .ioswp() + .disabled() + .midi() + .bits(0) + .mssi() + .bits(6) + }); spi1.cr2.modify(|_, w| w.tsize().bits(1)); spi1.cr1.write(|w| w.spe().enabled()); } // ADC1 fn spi5_setup(spi5: &pac::SPI5) { - spi5.cfg1.modify(|_, w| - w.mbr().div4() - .dsize().bits(16 - 1) - .fthlv().one_frame() - ); - spi5.cfg2.modify(|_, w| - w.afcntr().controlled() - .ssom().not_asserted() - .ssoe().enabled() - .ssiop().active_low() - .ssm().disabled() - .cpol().idle_high() - .cpha().second_edge() - .lsbfrst().msbfirst() - .master().master() - .sp().motorola() - .comm().receiver() - .ioswp().disabled() - .midi().bits(0) - .mssi().bits(6) - ); + spi5.cfg1 + .modify(|_, w| w.mbr().div4().dsize().bits(16 - 1).fthlv().one_frame()); + spi5.cfg2.modify(|_, w| { + w.afcntr() + .controlled() + .ssom() + .not_asserted() + .ssoe() + .enabled() + .ssiop() + .active_low() + .ssm() + .disabled() + .cpol() + .idle_high() + .cpha() + .second_edge() + .lsbfrst() + .msbfirst() + .master() + .master() + .sp() + .motorola() + .comm() + .receiver() + .ioswp() + .disabled() + .midi() + .bits(0) + .mssi() + .bits(6) + }); spi5.cr2.modify(|_, w| w.tsize().bits(1)); spi5.cr1.write(|w| w.spe().enabled()); } // DAC0 fn spi2_setup(spi2: &pac::SPI2) { - spi2.cfg1.modify(|_, w| - w.mbr().div2() - .dsize().bits(16 - 1) - .fthlv().one_frame() - ); - spi2.cfg2.modify(|_, w| - w.afcntr().controlled() - .ssom().not_asserted() - .ssoe().enabled() - .ssiop().active_low() - .ssm().disabled() - .cpol().idle_low() - .cpha().first_edge() - .lsbfrst().msbfirst() - .master().master() - .sp().motorola() - .comm().transmitter() - .ioswp().disabled() - .midi().bits(0) - .mssi().bits(0) - ); + spi2.cfg1 + .modify(|_, w| w.mbr().div2().dsize().bits(16 - 1).fthlv().one_frame()); + spi2.cfg2.modify(|_, w| { + w.afcntr() + .controlled() + .ssom() + .not_asserted() + .ssoe() + .enabled() + .ssiop() + .active_low() + .ssm() + .disabled() + .cpol() + .idle_low() + .cpha() + .first_edge() + .lsbfrst() + .msbfirst() + .master() + .master() + .sp() + .motorola() + .comm() + .transmitter() + .ioswp() + .disabled() + .midi() + .bits(0) + .mssi() + .bits(0) + }); spi2.cr2.modify(|_, w| w.tsize().bits(0)); spi2.cr1.write(|w| w.spe().enabled()); spi2.cr1.modify(|_, w| w.cstart().started()); @@ -367,42 +409,58 @@ fn spi2_setup(spi2: &pac::SPI2) { // DAC1 fn spi4_setup(spi4: &pac::SPI4) { - spi4.cfg1.modify(|_, w| - w.mbr().div2() - .dsize().bits(16 - 1) - .fthlv().one_frame() - ); - spi4.cfg2.modify(|_, w| - w.afcntr().controlled() - .ssom().not_asserted() - .ssoe().enabled() - .ssiop().active_low() - .ssm().disabled() - .cpol().idle_low() - .cpha().first_edge() - .lsbfrst().msbfirst() - .master().master() - .sp().motorola() - .comm().transmitter() - .ioswp().disabled() - .midi().bits(0) - .mssi().bits(0) - ); + spi4.cfg1 + .modify(|_, w| w.mbr().div2().dsize().bits(16 - 1).fthlv().one_frame()); + spi4.cfg2.modify(|_, w| { + w.afcntr() + .controlled() + .ssom() + .not_asserted() + .ssoe() + .enabled() + .ssiop() + .active_low() + .ssm() + .disabled() + .cpol() + .idle_low() + .cpha() + .first_edge() + .lsbfrst() + .msbfirst() + .master() + .master() + .sp() + .motorola() + .comm() + .transmitter() + .ioswp() + .disabled() + .midi() + .bits(0) + .mssi() + .bits(0) + }); spi4.cr2.modify(|_, w| w.tsize().bits(0)); spi4.cr1.write(|w| w.spe().enabled()); spi4.cr1.modify(|_, w| w.cstart().started()); } fn tim2_setup(tim2: &pac::TIM2) { - tim2.psc.write(|w| w.psc().bits(200 - 1)); // from 200 MHz - tim2.arr.write(|w| unsafe { w.bits(2 - 1) }); // ‘s + tim2.psc.write(|w| w.psc().bits(200 - 1)); // from 200 MHz + tim2.arr.write(|w| unsafe { w.bits(2 - 1) }); // 2 µs tim2.dier.write(|w| w.ude().set_bit()); tim2.egr.write(|w| w.ug().set_bit()); - tim2.cr1.modify(|_, w| - w.dir().clear_bit()); // up + tim2.cr1.modify(|_, w| w.dir().clear_bit()); // up } -fn dma1_setup(dma1: &pac::DMA1, dmamux1: &pac::DMAMUX1, ma: usize, pa0: usize, pa1: usize) { +fn dma1_setup( + dma1: &pac::DMA1, + dmamux1: &pac::DMAMUX1, + ma: usize, + pa0: usize, + pa1: usize, +) { dma1.st[0].cr.modify(|_, w| w.en().clear_bit()); while dma1.st[0].cr.read().en().bit_is_set() {} @@ -411,17 +469,28 @@ fn dma1_setup(dma1: &pac::DMA1, dmamux1: &pac::DMAMUX1, ma: usize, pa0: usize, p dma1.st[0].ndtr.write(|w| unsafe { w.ndt().bits(1) }); dmamux1.ccr[0].modify(|_, w| w.dmareq_id().tim2_up()); dma1.st[0].cr.modify(|_, w| unsafe { - w.pl().bits(0b01) // medium - .circ().set_bit() // reload ndtr - .msize().bits(0b10) // 32 - .minc().clear_bit() - .mburst().bits(0b00) - .psize().bits(0b10) // 32 - .pinc().clear_bit() - .pburst().bits(0b00) - .dbm().clear_bit() - .dir().bits(0b01) // memory_to_peripheral - .pfctrl().clear_bit() // dma is FC + w.pl() + .bits(0b01) // medium + .circ() + .set_bit() // reload ndtr + .msize() + .bits(0b10) // 32 + .minc() + .clear_bit() + .mburst() + .bits(0b00) + .psize() + .bits(0b10) // 32 + .pinc() + .clear_bit() + .pburst() + .bits(0b00) + .dbm() + .clear_bit() + .dir() + .bits(0b01) // memory_to_peripheral + .pfctrl() + .clear_bit() // dma is FC }); dma1.st[0].fcr.modify(|_, w| w.dmdis().clear_bit()); dma1.st[0].cr.modify(|_, w| w.en().set_bit()); @@ -434,28 +503,39 @@ fn dma1_setup(dma1: &pac::DMA1, dmamux1: &pac::DMAMUX1, ma: usize, pa0: usize, p dma1.st[1].ndtr.write(|w| unsafe { w.ndt().bits(1) }); dmamux1.ccr[1].modify(|_, w| w.dmareq_id().tim2_up()); dma1.st[1].cr.modify(|_, w| unsafe { - w.pl().bits(0b01) // medium - .circ().set_bit() // reload ndtr - .msize().bits(0b10) // 32 - .minc().clear_bit() - .mburst().bits(0b00) - .psize().bits(0b10) // 32 - .pinc().clear_bit() - .pburst().bits(0b00) - .dbm().clear_bit() - .dir().bits(0b01) // memory_to_peripheral - .pfctrl().clear_bit() // dma is FC + w.pl() + .bits(0b01) // medium + .circ() + .set_bit() // reload ndtr + .msize() + .bits(0b10) // 32 + .minc() + .clear_bit() + .mburst() + .bits(0b00) + .psize() + .bits(0b10) // 32 + .pinc() + .clear_bit() + .pburst() + .bits(0b00) + .dbm() + .clear_bit() + .dir() + .bits(0b01) // memory_to_peripheral + .pfctrl() + .clear_bit() // dma is FC }); dma1.st[1].fcr.modify(|_, w| w.dmdis().clear_bit()); dma1.st[1].cr.modify(|_, w| w.en().set_bit()); } #[link_section = ".sram1.datspi"] -static mut DAT: u32 = 0x201; // EN | CSTART +static mut DAT: u32 = 0x201; // EN | CSTART pub fn init() { - let mut cp = unsafe{ cortex_m::Peripherals::steal() }; - let dp = unsafe{ pac::Peripherals::steal()}; + let mut cp = unsafe { cortex_m::Peripherals::steal() }; + let dp = unsafe { pac::Peripherals::steal() }; let rcc = dp.RCC; rcc_reset(&rcc); @@ -467,18 +547,27 @@ pub fn init() { cp.SCB.enable_icache(); // TODO: ETH DMA coherence issues // cp.SCB.enable_dcache(&mut cp.CPUID); - cp.DWT.enable_cycle_counter(); // japaric/cortex-m-rtfm#184 + cp.DWT.enable_cycle_counter(); // japaric/cortex-m-rtfm#184 - rcc.ahb4enr.modify(|_, w| - w.gpioaen().set_bit() - .gpioben().set_bit() - .gpiocen().set_bit() - .gpioden().set_bit() - .gpioeen().set_bit() - .gpiofen().set_bit() - .gpiogen().set_bit() + rcc.ahb4enr.modify(|_, w| { + w.gpioaen() + .set_bit() + .gpioben() + .set_bit() + .gpiocen() + .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.GPIOF, &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; @@ -498,22 +587,28 @@ pub fn init() { spi5_setup(&spi5); // spi5.ier.write(|w| w.eotie().set_bit()); - rcc.ahb2enr.modify(|_, w| - w - .sram1en().set_bit() - .sram2en().set_bit() - .sram3en().set_bit() - ); + rcc.ahb2enr.modify(|_, w| { + w.sram1en() + .set_bit() + .sram2en() + .set_bit() + .sram3en() + .set_bit() + }); rcc.ahb1enr.modify(|_, w| w.dma1en().set_bit()); // init SRAM1 rodata can't load with sram1 disabled - unsafe { DAT = 0x201 }; // EN | CSTART + unsafe { DAT = 0x201 }; // EN | CSTART cortex_m::asm::dsb(); let dat_addr = unsafe { &DAT as *const _ } as usize; cp.SCB.clean_dcache_by_address(dat_addr, 4); - dma1_setup(&dp.DMA1, &dp.DMAMUX1, dat_addr, - &spi1.cr1 as *const _ as usize, - &spi5.cr1 as *const _ as usize); + dma1_setup( + &dp.DMA1, + &dp.DMAMUX1, + dat_addr, + &spi1.cr1 as *const _ as usize, + &spi5.cr1 as *const _ as usize, + ); rcc.apb1lenr.modify(|_, w| w.tim2en().set_bit()); @@ -523,16 +618,21 @@ pub fn init() { tim2_setup(&dp.TIM2); - rcc.apb1lenr.modify(|_,w| w.i2c2en().set_bit()); + rcc.apb1lenr.modify(|_, w| w.i2c2en().set_bit()); i2c::setup(&dp.I2C2); rcc.apb4enr.modify(|_, w| w.syscfgen().set_bit()); rcc.ahb1enr.modify(|_, w| { - w.eth1macen().set_bit() - .eth1txen().set_bit() - .eth1rxen().set_bit() + w.eth1macen() + .set_bit() + .eth1txen() + .set_bit() + .eth1rxen() + .set_bit() }); - dp.SYSCFG.pmcr.modify(|_, w| unsafe { w.epis().bits(0b100) }); // RMII + dp.SYSCFG + .pmcr + .modify(|_, w| unsafe { w.epis().bits(0b100) }); // RMII eth::setup_pins(&dp.GPIOA, &dp.GPIOB, &dp.GPIOC, &dp.GPIOG); // enable TIM2 this must be late to be able to handle the first ADC SPI diff --git a/src/eeprom.rs b/src/eeprom.rs index ce2efc4..fe30680 100644 --- a/src/eeprom.rs +++ b/src/eeprom.rs @@ -1,5 +1,5 @@ -use stm32h7::stm32h743 as pac; use super::i2c; +use stm32h7::stm32h743 as pac; const I2C_ADDR: u8 = 0xa0; diff --git a/src/eth.rs b/src/eth.rs index 7f3d3de..9cd1c9c 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -1,9 +1,9 @@ -use core::{slice, cmp}; -use stm32h7::stm32h743 as pac; -use smoltcp::Result; +use core::{cmp, slice}; +use smoltcp::phy; use smoltcp::time::Instant; use smoltcp::wire::EthernetAddress; -use smoltcp::phy; +use smoltcp::Result; +use stm32h7::stm32h743 as pac; #[allow(dead_code)] mod phy_consts { @@ -16,7 +16,7 @@ mod phy_consts { pub const PHY_REG_ANEXP: u8 = 0x06; pub const PHY_REG_ANNPTX: u8 = 0x07; pub const PHY_REG_ANNPRX: u8 = 0x08; - pub const PHY_REG_SSR: u8 = 0x1F; // Special Status Register + pub const PHY_REG_SSR: u8 = 0x1F; // Special Status Register pub const PHY_REG_CTL: u8 = 0x0D; // Ethernet PHY Register Control pub const PHY_REG_ADDAR: u8 = 0x0E; // Ethernet PHY Address or Data @@ -85,8 +85,12 @@ use self::cr_consts::*; // 200 MHz AHB clock = eth_hclk const CLOCK_RANGE: u8 = ETH_MACMIIAR_CR_HCLK_DIV_102; -pub fn setup_pins(gpioa: &pac::GPIOA, gpiob: &pac::GPIOB, - gpioc: &pac::GPIOC, gpiog: &pac::GPIOG) { +pub fn setup_pins( + gpioa: &pac::GPIOA, + gpiob: &pac::GPIOB, + gpioc: &pac::GPIOC, + gpiog: &pac::GPIOG, +) { // PA1 RMII_REF_CLK gpioa.moder.modify(|_, w| w.moder1().alternate()); gpioa.afrl.modify(|_, w| w.afr1().af11()); @@ -130,12 +134,16 @@ const PHY_ADDR: u8 = 0; fn phy_read(reg_addr: u8, mac: &pac::ETHERNET_MAC) -> u16 { while mac.macmdioar.read().mb().bit_is_set() {} mac.macmdioar.modify(|_, w| unsafe { - w - .pa().bits(PHY_ADDR) - .rda().bits(reg_addr) - .goc().bits(0b11) // read - .cr().bits(CLOCK_RANGE) - .mb().set_bit() + w.pa() + .bits(PHY_ADDR) + .rda() + .bits(reg_addr) + .goc() + .bits(0b11) // read + .cr() + .bits(CLOCK_RANGE) + .mb() + .set_bit() }); while mac.macmdioar.read().mb().bit_is_set() {} mac.macmdiodr.read().md().bits() @@ -145,12 +153,16 @@ fn phy_write(reg_addr: u8, reg_data: u16, mac: &pac::ETHERNET_MAC) { while mac.macmdioar.read().mb().bit_is_set() {} mac.macmdiodr.write(|w| unsafe { w.md().bits(reg_data) }); mac.macmdioar.modify(|_, w| unsafe { - w - .pa().bits(PHY_ADDR) - .rda().bits(reg_addr) - .goc().bits(0b01) // write - .cr().bits(CLOCK_RANGE) - .mb().set_bit() + w.pa() + .bits(PHY_ADDR) + .rda() + .bits(reg_addr) + .goc() + .bits(0b01) // write + .cr() + .bits(CLOCK_RANGE) + .mb() + .set_bit() }); while mac.macmdioar.read().mb().bit_is_set() {} } @@ -195,7 +207,8 @@ impl RxRing { let addr = &self.desc_buf as *const _ as u32; assert_eq!(addr & 0x3, 0); dma.dmacrx_dlar.write(|w| w.bits(addr)); - dma.dmacrx_rlr.write(|w| w.rdrl().bits(self.desc_buf.len() as u16 - 1)); + dma.dmacrx_rlr + .write(|w| w.rdrl().bits(self.desc_buf.len() as u16 - 1)); self.cur_desc = 0; for _ in 0..self.desc_buf.len() { @@ -213,9 +226,9 @@ impl RxRing { } fn buf_valid(&self) -> bool { - self.desc_buf[self.cur_desc][3] & - (EMAC_DES3_FD | EMAC_DES3_LD | EMAC_DES3_ES | EMAC_DES3_CTXT) == - (EMAC_DES3_FD | EMAC_DES3_LD) + self.desc_buf[self.cur_desc][3] + & (EMAC_DES3_FD | EMAC_DES3_LD | EMAC_DES3_ES | EMAC_DES3_CTXT) + == (EMAC_DES3_FD | EMAC_DES3_LD) } unsafe fn buf_as_slice_mut<'a>(&self) -> &'a mut [u8] { @@ -228,7 +241,8 @@ impl RxRing { fn buf_release(&mut self) { let addr = &self.pkt_buf[self.cur_desc] as *const _; self.desc_buf[self.cur_desc][0] = addr as u32 & EMAC_DES0_BUF1AP; - self.desc_buf[self.cur_desc][3] = EMAC_RDES3_BUF1V | EMAC_RDES3_IOC | EMAC_DES3_OWN; + self.desc_buf[self.cur_desc][3] = + EMAC_RDES3_BUF1V | EMAC_RDES3_IOC | EMAC_DES3_OWN; let addr = &self.desc_buf[self.cur_desc] as *const _ as u32; assert_eq!(addr & 0x3, 0); @@ -278,7 +292,8 @@ impl TxRing { let addr = &self.desc_buf as *const _ as u32; assert_eq!(addr & 0x3, 0); dma.dmactx_dlar.write(|w| w.bits(addr)); - dma.dmactx_rlr.write(|w| w.tdrl().bits(self.desc_buf.len() as u16 - 1)); + dma.dmactx_rlr + .write(|w| w.tdrl().bits(self.desc_buf.len() as u16 - 1)); let addr = &self.desc_buf[0] as *const _ as u32; assert_eq!(addr & 0x3, 0); dma.dmactx_dtpr.write(|w| w.bits(addr)); @@ -295,14 +310,16 @@ impl TxRing { unsafe fn buf_as_slice_mut<'a>(&mut self, len: usize) -> &'a mut [u8] { let len = cmp::min(len, ETH_BUFFER_SIZE); - self.desc_buf[self.cur_desc][2] = EMAC_TDES2_IOC | (len as u32 & EMAC_TDES2_B1L); + self.desc_buf[self.cur_desc][2] = + EMAC_TDES2_IOC | (len as u32 & EMAC_TDES2_B1L); let addr = &self.pkt_buf[self.cur_desc] as *const _ as *mut u8; self.desc_buf[self.cur_desc][0] = addr as u32 & EMAC_DES0_BUF1AP; slice::from_raw_parts_mut(addr, len) } fn buf_release(&mut self) { - self.desc_buf[self.cur_desc][3] = EMAC_DES3_OWN | EMAC_DES3_FD | EMAC_DES3_LD; + self.desc_buf[self.cur_desc][3] = + EMAC_DES3_OWN | EMAC_DES3_FD | EMAC_DES3_LD; self.cur_desc = self.next_desc(); let addr = &self.desc_buf[self.cur_desc] as *const _ as u32; @@ -325,7 +342,10 @@ pub struct Device { impl Device { pub const fn new() -> Self { - Self{ rx: RxRing::new(), tx: TxRing::new() } + Self { + rx: RxRing::new(), + tx: TxRing::new(), + } } // Initialize the ethernet peripherals @@ -337,75 +357,108 @@ impl Device { // are correct. // // After `init` is called, `Device` shall not be moved. - pub unsafe fn init(&mut self, mac: EthernetAddress, - eth_mac: &pac::ETHERNET_MAC, - eth_dma: &pac::ETHERNET_DMA, - eth_mtl: &pac::ETHERNET_MTL, - ) { + pub unsafe fn init( + &mut self, + mac: EthernetAddress, + eth_mac: &pac::ETHERNET_MAC, + eth_dma: &pac::ETHERNET_DMA, + eth_mtl: &pac::ETHERNET_MTL, + ) { eth_dma.dmamr.modify(|_, w| w.swr().set_bit()); while eth_dma.dmamr.read().swr().bit_is_set() {} // 200 MHz - eth_mac.mac1ustcr.modify(|_, w| w.tic_1us_cntr().bits(200 - 1)); + eth_mac + .mac1ustcr + .modify(|_, w| w.tic_1us_cntr().bits(200 - 1)); // Configuration Register eth_mac.maccr.modify(|_, w| { - w - .arpen().clear_bit() - .ipc().set_bit() - .ipg().bits(0b000) // 96 bit - .ecrsfd().clear_bit() - .dcrs().clear_bit() - .bl().bits(0b00) // 19 - .prelen().bits(0b00) // 7 + w.arpen() + .clear_bit() + .ipc() + .set_bit() + .ipg() + .bits(0b000) // 96 bit + .ecrsfd() + .clear_bit() + .dcrs() + .clear_bit() + .bl() + .bits(0b00) // 19 + .prelen() + .bits(0b00) // 7 // CRC stripping for Type frames - .cst().set_bit() + .cst() + .set_bit() // Fast Ethernet speed - .fes().set_bit() + .fes() + .set_bit() // Duplex mode - .dm().set_bit() + .dm() + .set_bit() // Automatic pad/CRC stripping - .acs().set_bit() + .acs() + .set_bit() // Retry disable in half-duplex mode - .dr().set_bit() + .dr() + .set_bit() }); eth_mac.macecr.modify(|_, w| { - w - .eipgen().clear_bit() - .usp().clear_bit() - .spen().clear_bit() - .dcrcc().clear_bit() + w.eipgen() + .clear_bit() + .usp() + .clear_bit() + .spen() + .clear_bit() + .dcrcc() + .clear_bit() }); // Set the MAC address - eth_mac.maca0lr.write(|w| - w.addrlo().bits( u32::from(mac.0[0]) | - (u32::from(mac.0[1]) << 8) | - (u32::from(mac.0[2]) << 16) | - (u32::from(mac.0[3]) << 24)) - ); - eth_mac.maca0hr.write(|w| - w.addrhi().bits( u16::from(mac.0[4]) | - (u16::from(mac.0[5]) << 8)) - ); + eth_mac.maca0lr.write(|w| { + w.addrlo().bits( + u32::from(mac.0[0]) + | (u32::from(mac.0[1]) << 8) + | (u32::from(mac.0[2]) << 16) + | (u32::from(mac.0[3]) << 24), + ) + }); + eth_mac.maca0hr.write(|w| { + w.addrhi() + .bits(u16::from(mac.0[4]) | (u16::from(mac.0[5]) << 8)) + }); // frame filter register eth_mac.macpfr.modify(|_, w| { - w - .dntu().clear_bit() - .ipfe().clear_bit() - .vtfe().clear_bit() - .hpf().clear_bit() - .saf().clear_bit() - .saif().clear_bit() - .pcf().bits(0b00) - .dbf().clear_bit() - .pm().clear_bit() - .daif().clear_bit() - .hmc().clear_bit() - .huc().clear_bit() + w.dntu() + .clear_bit() + .ipfe() + .clear_bit() + .vtfe() + .clear_bit() + .hpf() + .clear_bit() + .saf() + .clear_bit() + .saif() + .clear_bit() + .pcf() + .bits(0b00) + .dbf() + .clear_bit() + .pm() + .clear_bit() + .daif() + .clear_bit() + .hmc() + .clear_bit() + .huc() + .clear_bit() // Receive All - .ra().clear_bit() + .ra() + .clear_bit() // Promiscuous mode - .pr().clear_bit() + .pr() + .clear_bit() }); eth_mac.macwtr.write(|w| w.pwe().clear_bit()); // Flow Control Register @@ -414,31 +467,44 @@ impl Device { w.pt().bits(0x100) }); eth_mac.macrx_fcr.modify(|_, w| w); - eth_mtl.mtlrx_qomr.modify(|_, w| + eth_mtl.mtlrx_qomr.modify(|_, w| { w // Receive store and forward - .rsf().set_bit() + .rsf() + .set_bit() // Dropping of TCP/IP checksum error frames disable - .dis_tcp_ef().clear_bit() + .dis_tcp_ef() + .clear_bit() // Forward error frames - .fep().clear_bit() + .fep() + .clear_bit() // Forward undersized good packets - .fup().clear_bit() - ); + .fup() + .clear_bit() + }); eth_mtl.mtltx_qomr.modify(|_, w| { w // Transmit store and forward - .tsf().set_bit() + .tsf() + .set_bit() }); - if (phy_read(PHY_REG_ID1, eth_mac) != 0x0007) | (phy_read(PHY_REG_ID2, eth_mac) != 0xC131) { + if (phy_read(PHY_REG_ID1, eth_mac) != 0x0007) + | (phy_read(PHY_REG_ID2, eth_mac) != 0xC131) + { error!("PHY ID error!"); } phy_write(PHY_REG_BCR, PHY_REG_BCR_RESET, eth_mac); - while phy_read(PHY_REG_BCR, eth_mac) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {}; + while phy_read(PHY_REG_BCR, eth_mac) & PHY_REG_BCR_RESET + == PHY_REG_BCR_RESET + {} phy_write_ext(PHY_REG_WUCSR, 0, eth_mac); - phy_write(PHY_REG_BCR, PHY_REG_BCR_AN | PHY_REG_BCR_ANRST | PHY_REG_BCR_100M, eth_mac); + phy_write( + PHY_REG_BCR, + PHY_REG_BCR_AN | PHY_REG_BCR_ANRST | PHY_REG_BCR_100M, + eth_mac, + ); /* while phy_read(PHY_REG_BSR) & PHY_REG_BSR_UP == 0 {}; while phy_read(PHY_REG_BSR) & PHY_REG_BSR_ANDONE == 0 {}; @@ -448,43 +514,51 @@ impl Device { // operation mode register eth_dma.dmamr.modify(|_, w| { - w - .intm().bits(0b00) + w.intm() + .bits(0b00) // Rx Tx priority ratio 1:1 - .pr().bits(0b000) - .txpr().clear_bit() - .da().clear_bit() + .pr() + .bits(0b000) + .txpr() + .clear_bit() + .da() + .clear_bit() }); // bus mode register eth_dma.dmasbmr.modify(|_, w| { // Address-aligned beats - w.aal().set_bit() + w.aal() + .set_bit() // Fixed burst - .fb().set_bit() - }); - eth_dma.dmaccr.modify(|_, w| { - w - .dsl().bits(0) - .pblx8().clear_bit() - .mss().bits(536) + .fb() + .set_bit() }); + eth_dma + .dmaccr + .modify(|_, w| w.dsl().bits(0).pblx8().clear_bit().mss().bits(536)); eth_dma.dmactx_cr.modify(|_, w| { w // Tx DMA PBL - .txpbl().bits(32) - .tse().clear_bit() + .txpbl() + .bits(32) + .tse() + .clear_bit() // Operate on second frame - .osf().clear_bit() + .osf() + .clear_bit() }); eth_dma.dmacrx_cr.modify(|_, w| { w // receive buffer size - .rbsz().bits(ETH_BUFFER_SIZE as u16) + .rbsz() + .bits(ETH_BUFFER_SIZE as u16) // Rx DMA PBL - .rxpbl().bits(32) + .rxpbl() + .bits(32) // Disable flushing of received frames - .rpf().clear_bit() + .rpf() + .clear_bit() }); self.rx.init(eth_dma); @@ -492,8 +566,10 @@ impl Device { // Manage MAC transmission and reception eth_mac.maccr.modify(|_, w| { - w.re().bit(true) // Receiver Enable - .te().bit(true) // Transmiter Enable + w.re() + .bit(true) // Receiver Enable + .te() + .bit(true) // Transmiter Enable }); eth_mtl.mtltx_qomr.modify(|_, w| w.ftq().set_bit()); @@ -505,10 +581,9 @@ impl Device { eth_dma.dmactx_cr.modify(|_, w| w.st().set_bit()); eth_dma.dmacrx_cr.modify(|_, w| w.sr().set_bit()); - eth_dma.dmacsr.modify(|_, w| - w.tps().set_bit() - .rps().set_bit() - ); + eth_dma + .dmacsr + .modify(|_, w| w.tps().set_bit().rps().set_bit()); } } @@ -532,7 +607,7 @@ impl<'a, 'b> phy::Device<'a> for &'b mut Device { } if !(self.rx.buf_owned() && self.tx.buf_owned()) { - return None + return None; } Some((RxToken(&mut self.rx), TxToken(&mut self.tx))) @@ -540,7 +615,7 @@ impl<'a, 'b> phy::Device<'a> for &'b mut Device { fn transmit(&mut self) -> Option { if !self.tx.buf_owned() { - return None + return None; } Some(TxToken(&mut self.tx)) @@ -551,7 +626,9 @@ pub struct RxToken<'a>(&'a mut RxRing); impl<'a> phy::RxToken for RxToken<'a> { fn consume(self, _timestamp: Instant, f: F) -> Result - where F: FnOnce(&mut [u8]) -> Result { + where + F: FnOnce(&mut [u8]) -> Result, + { let result = f(unsafe { self.0.buf_as_slice_mut() }); self.0.buf_release(); result @@ -562,7 +639,9 @@ pub struct TxToken<'a>(&'a mut TxRing); impl<'a> phy::TxToken for TxToken<'a> { fn consume(self, _timestamp: Instant, len: usize, f: F) -> Result - where F: FnOnce(&mut [u8]) -> Result { + where + F: FnOnce(&mut [u8]) -> Result, + { let result = f(unsafe { self.0.buf_as_slice_mut(len) }); self.0.buf_release(); result diff --git a/src/i2c.rs b/src/i2c.rs index 5b3a17b..9c431ca 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -12,7 +12,7 @@ pub enum Error { // Address not ACKd within a reasonable time (no device present?) Timeout, // Unexpected NACK during transfer - NAck + NAck, } // Maximum number of times to retry NACKed address phase before timing out @@ -20,25 +20,28 @@ pub enum Error { // EEPROMs during write) const N_RETRY: usize = 100; // ~ 10ms @ 100 kHz bus clock - pub fn setup(i2c: &pac::I2C2) { // Disable the peripheral before setting timings i2c.cr1.modify(|_, w| w.pe().clear_bit()); // Values from STM32MXCube for 100 kHz I2C clock with 100 MHz peripheral clock - i2c.timingr.modify( |_,w| - w.presc().bits(1) - .scldel().bits(0x12) - .sdadel().bits(0) - .sclh().bits(0xec) - .scll().bits(0xff) - ); + i2c.timingr.modify(|_, w| { + w.presc() + .bits(1) + .scldel() + .bits(0x12) + .sdadel() + .bits(0) + .sclh() + .bits(0xec) + .scll() + .bits(0xff) + }); // Enable the peripheral i2c.cr1.write(|w| w.pe().set_bit()); } - // Busy-wait for a flag to be asserted, erroring out on unrecoverable problems macro_rules! busy_wait_errors { ($i2c:expr, $flag:ident) => { @@ -58,25 +61,29 @@ macro_rules! busy_wait_errors { }; } - fn poll_for_start_ack( i2c: &pac::I2C2, addr: u8, r_wn: bool, data_len: usize, autoend: bool, - start: bool -) -> Result<(), Error> -{ + start: bool, +) -> Result<(), Error> { for _i in 0..N_RETRY { // START and prepare to send `data_len` i2c.cr2.write(|w| { - w.start().bit(start) - .sadd().bits(addr as u16) - .add10().clear_bit() - .rd_wrn().bit(r_wn) - .nbytes().bits( data_len as u8 ) - .autoend().bit(autoend) + w.start() + .bit(start) + .sadd() + .bits(addr as u16) + .add10() + .clear_bit() + .rd_wrn() + .bit(r_wn) + .nbytes() + .bits(data_len as u8) + .autoend() + .bit(autoend) }); loop { @@ -87,7 +94,7 @@ fn poll_for_start_ack( } else if isr.arlo().bit_is_set() { return Err(Error::Arbitration); } else if isr.nackf().bit_is_set() { - i2c.icr.write(|w| { w.nackcf().set_bit() }); + i2c.icr.write(|w| w.nackcf().set_bit()); // Wait to finish handling NACK-STOP loop { if i2c.isr.read().busy().bit_is_clear() { @@ -96,7 +103,7 @@ fn poll_for_start_ack( } break; } else if isr.txis().bit_is_set() || isr.rxne().bit_is_set() { - return Ok(()) + return Ok(()); } } } @@ -104,7 +111,6 @@ fn poll_for_start_ack( Err(Error::Timeout) } - pub fn write_read( i2c: &pac::I2C2, addr: u8, @@ -126,7 +132,7 @@ pub fn write_read( // Wait until the last transmission is finished busy_wait_errors!(i2c, tc); - poll_for_start_ack(i2c, addr|1, true, buffer.len(), true, true)?; + poll_for_start_ack(i2c, addr | 1, true, buffer.len(), true, true)?; for byte in buffer { // Wait until we have received something diff --git a/src/iir.rs b/src/iir.rs index 85c3787..0c34306 100644 --- a/src/iir.rs +++ b/src/iir.rs @@ -1,11 +1,11 @@ use core::ops::{Add, Mul}; -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use core::f32; pub type IIRState = [f32; 5]; -#[derive(Copy,Clone,Deserialize,Serialize)] +#[derive(Copy, Clone, Deserialize, Serialize)] pub struct IIR { pub ba: IIRState, pub y_offset: f32, @@ -14,7 +14,11 @@ pub struct IIR { } fn abs(x: f32) -> f32 { - if x >= 0. { x } else { -x } + if x >= 0. { + x + } else { + -x + } } fn copysign(x: f32, y: f32) -> f32 { @@ -26,37 +30,51 @@ fn copysign(x: f32, y: f32) -> f32 { } fn max(x: f32, y: f32) -> f32 { - if x > y { x } else { y } + if x > y { + x + } else { + y + } } fn min(x: f32, y: f32) -> f32 { - if x < y { x } else { y } + if x < y { + x + } else { + y + } } fn macc(y0: T, x: &[T], a: &[T]) -> T - where T: Add + Mul + Copy +where + T: Add + Mul + Copy, { - x.iter().zip(a.iter()).map(|(&i, &j)| i * j).fold(y0, |y, xa| y + xa) + x.iter() + .zip(a.iter()) + .map(|(&i, &j)| i * j) + .fold(y0, |y, xa| y + xa) } impl IIR { pub fn set_pi(&mut self, kp: f32, ki: f32, g: f32) -> Result<(), &str> { let ki = copysign(ki, kp); let g = copysign(g, kp); - let (a1, b0, b1) = - if abs(ki) < f32::EPSILON { - (0., kp, 0.) + let (a1, b0, b1) = if abs(ki) < f32::EPSILON { + (0., kp, 0.) + } else { + let c = if abs(g) < f32::EPSILON { + 1. } else { - let c = if abs(g) < f32::EPSILON { 1. } - else { 1./(1. + ki/g) }; - let a1 = 2.*c - 1.; - let b0 = ki*c + kp; - let b1 = ki*c - a1*kp; - if abs(b0 + b1) < f32::EPSILON { - return Err("low integrator gain and/or gain limit") - } - (a1, b0, b1) + 1. / (1. + ki / g) }; + let a1 = 2. * c - 1.; + let b0 = ki * c + kp; + let b1 = ki * c - a1 * kp; + if abs(b0 + b1) < f32::EPSILON { + return Err("low integrator gain and/or gain limit"); + } + (a1, b0, b1) + }; self.ba[0] = b0; self.ba[1] = b1; self.ba[2] = 0.; @@ -70,13 +88,13 @@ impl IIR { if abs(b) < f32::EPSILON { Err("b is zero") } else { - Ok(self.y_offset/b) + Ok(self.y_offset / b) } } pub fn set_x_offset(&mut self, xo: f32) { let b: f32 = self.ba[..3].iter().sum(); - self.y_offset = xo*b; + self.y_offset = xo * b; } pub fn update(&self, xy: &mut IIRState, x0: f32) -> f32 { @@ -84,7 +102,7 @@ impl IIR { xy[0] = x0; let y0 = macc(self.y_offset, xy, &self.ba); let y0 = max(self.y_min, min(self.y_max, y0)); - xy[xy.len()/2] = y0; + xy[xy.len() / 2] = y0; y0 } } diff --git a/src/main.rs b/src/main.rs index 78ef457..f7e9f94 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,5 @@ #![deny(warnings)] #![allow(clippy::missing_safety_doc)] - #![no_std] #![no_main] #![cfg_attr(feature = "nightly", feature(asm))] @@ -13,8 +12,10 @@ #[cfg(all(feature = "nightly", not(feature = "semihosting")))] fn panic(_info: &core::panic::PanicInfo) -> ! { let gpiod = unsafe { &*pac::GPIOD::ptr() }; - gpiod.odr.modify(|_, w| w.odr6().high().odr12().high()); // FP_LED_1, FP_LED_3 - unsafe { core::intrinsics::abort(); } + gpiod.odr.modify(|_, w| w.odr6().high().odr12().high()); // FP_LED_1, FP_LED_3 + unsafe { + core::intrinsics::abort(); + } } #[cfg(feature = "semihosting")] @@ -30,40 +31,38 @@ use core::ptr; // use core::sync::atomic::{AtomicU32, AtomicBool, Ordering}; use core::fmt::Write; use cortex_m_rt::exception; -use stm32h7::stm32h743 as pac; -use heapless::{String, Vec, consts::*}; +use heapless::{consts::*, String, Vec}; use rtfm::cyccnt::{Instant, U32Ext as _}; +use stm32h7::stm32h743 as pac; use smoltcp as net; -use serde::{Serialize, Deserialize, de::DeserializeOwned}; -use serde_json_core::{ser::to_string, de::from_slice}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use serde_json_core::{de::from_slice, ser::to_string}; mod eth; mod iir; use iir::*; -mod i2c; -mod eeprom; mod board; +mod eeprom; +mod i2c; #[cfg(not(feature = "semihosting"))] fn init_log() {} #[cfg(feature = "semihosting")] fn init_log() { + use cortex_m_log::log::{init as init_log, Logger}; + use cortex_m_log::printer::semihosting::{hio::HStdout, InterruptOk}; use log::LevelFilter; - use cortex_m_log::log::{Logger, init as init_log}; - use cortex_m_log::printer::semihosting::{InterruptOk, hio::HStdout}; static mut LOGGER: Option>> = None; let logger = Logger { inner: InterruptOk::<_>::stdout().unwrap(), level: LevelFilter::Info, }; - let logger = unsafe { - LOGGER.get_or_insert(logger) - }; + let logger = unsafe { LOGGER.get_or_insert(logger) }; init_log(logger).unwrap(); } @@ -74,7 +73,6 @@ mod build_info { // include!(concat!(env!("OUT_DIR"), "/built.rs")); } - const SCALE: f32 = ((1 << 15) - 1) as f32; // static ETHERNET_PENDING: AtomicBool = AtomicBool::new(true); @@ -83,14 +81,17 @@ const TCP_RX_BUFFER_SIZE: usize = 8192; const TCP_TX_BUFFER_SIZE: usize = 8192; macro_rules! create_socket { - ($set:ident, $rx_storage:ident, $tx_storage:ident, $target:ident) => ( + ($set:ident, $rx_storage:ident, $tx_storage:ident, $target:ident) => { let mut $rx_storage = [0; TCP_RX_BUFFER_SIZE]; let mut $tx_storage = [0; TCP_TX_BUFFER_SIZE]; - let tcp_rx_buffer = net::socket::TcpSocketBuffer::new(&mut $rx_storage[..]); - let tcp_tx_buffer = net::socket::TcpSocketBuffer::new(&mut $tx_storage[..]); - let tcp_socket = net::socket::TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer); + let tcp_rx_buffer = + net::socket::TcpSocketBuffer::new(&mut $rx_storage[..]); + let tcp_tx_buffer = + net::socket::TcpSocketBuffer::new(&mut $tx_storage[..]); + let tcp_socket = + net::socket::TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer); let $target = $set.add(tcp_socket); - ) + }; } #[rtfm::app(device = stm32h7::stm32h743, peripherals = true, monotonic = rtfm::cyccnt::CYCCNT)] @@ -98,7 +99,8 @@ const APP: () = { struct Resources { spi: (pac::SPI1, pac::SPI2, pac::SPI4, pac::SPI5), i2c: pac::I2C2, - ethernet_periph: (pac::ETHERNET_MAC, pac::ETHERNET_DMA, pac::ETHERNET_MTL), + ethernet_periph: + (pac::ETHERNET_MAC, pac::ETHERNET_DMA, pac::ETHERNET_MTL), #[init([[0.; 5]; 2])] iir_state: [IIRState; 2], #[init([IIR { ba: [1., 0., 0., 0., 0.], y_offset: 0., y_min: -SCALE - 1., y_max: SCALE }; 2])] @@ -123,7 +125,11 @@ const APP: () = { init::LateResources { spi: (dp.SPI1, dp.SPI2, dp.SPI4, dp.SPI5), i2c: dp.I2C2, - ethernet_periph: (dp.ETHERNET_MAC, dp.ETHERNET_DMA, dp.ETHERNET_MTL), + ethernet_periph: ( + dp.ETHERNET_MAC, + dp.ETHERNET_DMA, + dp.ETHERNET_MTL, + ), } } @@ -135,23 +141,26 @@ const APP: () = { Err(_) => { info!("Could not read EEPROM, using default MAC address"); net::wire::EthernetAddress([0x10, 0xE2, 0xD5, 0x00, 0x03, 0x00]) - }, - Ok(raw_mac) => net::wire::EthernetAddress(raw_mac) + } + Ok(raw_mac) => net::wire::EthernetAddress(raw_mac), }; info!("MAC: {}", hardware_addr); unsafe { c.resources.ethernet.init(hardware_addr, MAC, DMA, MTL) }; let mut neighbor_cache_storage = [None; 8]; - let neighbor_cache = net::iface::NeighborCache::new(&mut neighbor_cache_storage[..]); + let neighbor_cache = + net::iface::NeighborCache::new(&mut neighbor_cache_storage[..]); let local_addr = net::wire::IpAddress::v4(10, 0, 16, 99); let mut ip_addrs = [net::wire::IpCidr::new(local_addr, 24)]; - let mut iface = net::iface::EthernetInterfaceBuilder::new(c.resources.ethernet) - .ethernet_addr(hardware_addr) - .neighbor_cache(neighbor_cache) - .ip_addrs(&mut ip_addrs[..]) - .finalize(); + let mut iface = + net::iface::EthernetInterfaceBuilder::new(c.resources.ethernet) + .ethernet_addr(hardware_addr) + .neighbor_cache(neighbor_cache) + .ip_addrs(&mut ip_addrs[..]) + .finalize(); let mut socket_set_entries: [_; 8] = Default::default(); - let mut sockets = net::socket::SocketSet::new(&mut socket_set_entries[..]); + let mut sockets = + net::socket::SocketSet::new(&mut socket_set_entries[..]); create_socket!(sockets, tcp_rx_storage0, tcp_tx_storage0, tcp_handle0); create_socket!(sockets, tcp_rx_storage0, tcp_tx_storage0, tcp_handle1); @@ -170,41 +179,55 @@ const APP: () = { time += 1; } { - let socket = &mut *sockets.get::(tcp_handle0); + let socket = + &mut *sockets.get::(tcp_handle0); if socket.state() == net::socket::TcpState::CloseWait { socket.close(); } else if !(socket.is_open() || socket.is_listening()) { - socket.listen(1234).unwrap_or_else(|e| warn!("TCP listen error: {:?}", e)); + socket + .listen(1234) + .unwrap_or_else(|e| warn!("TCP listen error: {:?}", e)); } else if tick && socket.can_send() { let s = iir_state.lock(|iir_state| Status { t: time, x0: iir_state[0][0], y0: iir_state[0][2], x1: iir_state[1][0], - y1: iir_state[1][2] + y1: iir_state[1][2], }); json_reply(socket, &s); } } { - let socket = &mut *sockets.get::(tcp_handle1); + let socket = + &mut *sockets.get::(tcp_handle1); if socket.state() == net::socket::TcpState::CloseWait { socket.close(); } else if !(socket.is_open() || socket.is_listening()) { - socket.listen(1235).unwrap_or_else(|e| warn!("TCP listen error: {:?}", e)); + socket + .listen(1235) + .unwrap_or_else(|e| warn!("TCP listen error: {:?}", e)); } else { server.poll(socket, |req: &Request| { if req.channel < 2 { - iir_ch.lock(|iir_ch| iir_ch[req.channel as usize] = req.iir); + iir_ch.lock(|iir_ch| { + iir_ch[req.channel as usize] = req.iir + }); } }); } } - if !match iface.poll(&mut sockets, net::time::Instant::from_millis(time as i64)) { + if !match iface.poll( + &mut sockets, + net::time::Instant::from_millis(time as i64), + ) { Ok(changed) => changed, Err(net::Error::Unrecognized) => true, - Err(e) => { info!("iface poll error: {:?}", e); true } + Err(e) => { + info!("iface poll error: {:?}", e); + true + } } { // cortex_m::asm::wfi(); } @@ -278,7 +301,7 @@ const APP: () = { } }; -#[derive(Deserialize,Serialize)] +#[derive(Deserialize, Serialize)] struct Request { channel: u8, iir: IIR, @@ -296,7 +319,7 @@ struct Status { x0: f32, y0: f32, x1: f32, - y1: f32 + y1: f32, } fn json_reply(socket: &mut net::socket::TcpSocket, msg: &T) { @@ -312,32 +335,48 @@ struct Server { impl Server { fn new() -> Self { - Self { data: Vec::new(), discard: false } + Self { + data: Vec::new(), + discard: false, + } } - fn poll(&mut self, socket: &mut net::socket::TcpSocket, f: F) -> Option - where - T: DeserializeOwned, - F: FnOnce(&T) -> R, + fn poll( + &mut self, + socket: &mut net::socket::TcpSocket, + f: F, + ) -> Option + where + T: DeserializeOwned, + F: FnOnce(&T) -> R, { while socket.can_recv() { - let found = socket.recv(|buf| { - let (len, found) = match buf.iter().position(|&c| c as char == '\n') { - Some(end) => (end + 1, true), - None => (buf.len(), false), - }; - if self.data.len() + len >= self.data.capacity() { - self.discard = true; - self.data.clear(); - } else if !self.discard && len > 0 { - self.data.extend_from_slice(&buf[..len]).unwrap(); - } - (len, found) - }).unwrap(); + let found = socket + .recv(|buf| { + let (len, found) = + match buf.iter().position(|&c| c as char == '\n') { + Some(end) => (end + 1, true), + None => (buf.len(), false), + }; + if self.data.len() + len >= self.data.capacity() { + self.discard = true; + self.data.clear(); + } else if !self.discard && len > 0 { + self.data.extend_from_slice(&buf[..len]).unwrap(); + } + (len, found) + }) + .unwrap(); if found { if self.discard { self.discard = false; - json_reply(socket, &Response { code: 520, message: "command buffer overflow" }); + json_reply( + socket, + &Response { + code: 520, + message: "command buffer overflow", + }, + ); self.data.clear(); } else { let r = from_slice::(&self.data[..self.data.len() - 1]); @@ -345,13 +384,25 @@ impl Server { match r { Ok(res) => { let r = f(&res); - json_reply(socket, &Response { code: 200, message: "ok" }); + json_reply( + socket, + &Response { + code: 200, + message: "ok", + }, + ); return Some(r); - }, + } Err(err) => { warn!("parse error {:?}", err); - json_reply(socket, &Response { code: 550, message: "parse error" }); - }, + json_reply( + socket, + &Response { + code: 550, + message: "parse error", + }, + ); + } } } }