From 4b49f29b17b84f7185d4427e87075009f8b2aa1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Tue, 19 Mar 2019 15:27:22 +0000 Subject: [PATCH] dac --- .cargo/config | 8 +-- Cargo.toml | 4 +- .gdbinit => openocd.gdb | 6 ++ src/main.rs | 129 +++++++++++++++++++++++++++++++++------- 4 files changed, 119 insertions(+), 28 deletions(-) rename .gdbinit => openocd.gdb (80%) diff --git a/.cargo/config b/.cargo/config index f907e49..56c81fd 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,8 +1,6 @@ -[target.thumbv7em-none-eabihf] -runner = "arm-none-eabi-gdb" -rustflags = [ - "-C", "link-arg=-Tlink.x", -] +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +runner = "arm-none-eabi-gdb -x openocd.gdb" +rustflags = ["-C", "link-arg=-Tlink.x"] [build] target = "thumbv7em-none-eabihf" diff --git a/Cargo.toml b/Cargo.toml index 550a37c..69e23c8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ name = "stabilizer" version = "0.1.0" authors = ["Robert Jördens "] categories = ["embedded", "no-std"] -license = "Apache-2.0" +license = "GPL-3" keywords = ["ethernet", "eth", "stm32", "adc", "dac", "tcp"] repository = "https://github.com/quartiq/stabilizer" #documentation = "https://docs.rs/stabilizer/" @@ -43,4 +43,4 @@ debug = true lto = true codegen-units = 1 incremental = false -opt-level = "s" +opt-level = 2 diff --git a/.gdbinit b/openocd.gdb similarity index 80% rename from .gdbinit rename to openocd.gdb index fc0aadd..7aac921 100644 --- a/.gdbinit +++ b/openocd.gdb @@ -6,6 +6,12 @@ monitor arm semihosting enable # or uart # monitor tpiu config external uart off 168000000 2000000 # monitor itm port 0 on + +# detect unhandled exceptions, hard faults and panics +break DefaultHandler +break HardFault +break rust_begin_unwind + load # tbreak cortex_m_rt::reset_handler # monitor reset halt diff --git a/src/main.rs b/src/main.rs index 1aacbe7..e5ca972 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,7 @@ extern crate stm32h7; #[macro_use] extern crate log; +use core::ptr; use cortex_m_rt::{entry, exception}; // use core::fmt::Write; use stm32h7::{stm32h7x3 as stm32}; @@ -102,13 +103,15 @@ fn main() -> ! { rcc.cfgr.reset(); // Ensure HSE is on and stable - rcc.cr.modify(|_, w| w.hseon().set_bit()); + rcc.cr.modify(|_, w| + w.hseon().set_bit() + .hsebyp().clear_bit()); while rcc.cr.read().hserdy().bit_is_clear() {} rcc.pllckselr.modify(|_, w| unsafe { w.pllsrc().bits(0b10) // hse .divm1().bits(1) // ref prescaler - .divm2().bits(4) // ref prescaler + .divm2().bits(1) // ref prescaler }); // Configure PLL1: 8MHz /1 *100 /2 = 400 MHz rcc.pllcfgr.modify(|_, w| unsafe { @@ -117,7 +120,7 @@ fn main() -> ! { .pll1fracen().clear_bit() .divp1en().set_bit() .pll2vcosel().set_bit() // 150-420 MHz VCO - .pll2rge().bits(0b01) // 2-4 MHz PFD + .pll2rge().bits(0b11) // 8-16 MHz PFD .pll2fracen().clear_bit() .divp2en().set_bit() .divq2en().set_bit() @@ -129,9 +132,9 @@ fn main() -> ! { rcc.cr.modify(|_, w| w.pll1on().set_bit()); while rcc.cr.read().pll1rdy().bit_is_clear() {} - // Configure PLL2: 8MHz /4 * 125 = 250 MHz + // Configure PLL2: 8MHz /1 *25 / 2 = 100 MHz rcc.pll2divr.write(|w| unsafe { - w.divn1().bits(125 - 1) // feebdack divider + w.divn1().bits(25 - 1) // feebdack divider .divp1().bits(2 - 1) // p output divider .divq1().bits(2 - 1) // q output divider }); @@ -139,17 +142,19 @@ fn main() -> ! { while rcc.cr.read().pll2rdy().bit_is_clear() {} // hclk 200 MHz, pclk 100 MHz + let dapb = 0b100; rcc.d1cfgr.write(|w| unsafe { w.d1cpre().bits(0) // sys_ck not divided - .d1ppre().bits(0b100) // rcc_pclk3 = rcc_hclk3 / 2 .hpre().bits(0b1000) // rcc_hclk3 = sys_d1cpre_ck / 2 + .d1ppre().bits(dapb) // rcc_pclk3 = rcc_hclk3 / 2 }); rcc.d2cfgr.write(|w| unsafe { - w.d2ppre1().bits(0b100) // rcc_pclk1 = rcc_hclk3 / 2 - .d2ppre2().bits(0b100) // rcc_pclk2 = rcc_hclk3 / 2 + w.d2ppre1().bits(dapb) // rcc_pclk1 = rcc_hclk3 / 2 + .d2ppre2().bits(dapb) // rcc_pclk2 = rcc_hclk3 / 2 + }); rcc.d3cfgr.write(|w| unsafe { - w.d3ppre().bits(0b100) // rcc_pclk4 = rcc_hclk3 / 2 + w.d3ppre().bits(dapb) // rcc_pclk4 = rcc_hclk3 / 2 }); let flash = dp.FLASH; @@ -161,7 +166,7 @@ fn main() -> ! { }); while flash.acr.read().latency().bits() != 2 {} - // Set system clock to HSI + // Set system clock to pll1_p rcc.cfgr.modify(|_, w| unsafe { w.sw().bits(0b011) }); // pll1p while rcc.cfgr.read().sws().bits() != 0b011 {} @@ -171,7 +176,7 @@ fn main() -> ! { init_log(); // info!("Version {} {}", build_info::PKG_VERSION, build_info::GIT_VERSION.unwrap()); - info!("Built on {}", build_info::BUILT_TIME_UTC); + // info!("Built on {}", build_info::BUILT_TIME_UTC); // info!("{} {}", build_info::RUSTC_VERSION, build_info::TARGET); // FP_LED0 @@ -198,10 +203,14 @@ fn main() -> ! { gpiod.moder.modify(|_, w| w.moder12().output()); gpiod.odr.modify(|_, w| w.odr12().set_bit()); + rcc.d1ccipr.write(|w| unsafe { + w.ckpersrc().bits(1) // hse_ck + }); rcc.d2ccip1r.modify(|_, w| unsafe { w.spi123src().bits(1) // pll2_p .spi45src().bits(1) // pll2_q }); + rcc.d3ccipr.modify(|_, w| unsafe { w.spi6src().bits(1) // pll2_q }); @@ -244,6 +253,7 @@ fn main() -> ! { // SCK: PG11 gpiog.moder.modify(|_, w| w.moder11().alternate()); gpiog.otyper.modify(|_, w| w.ot11().push_pull()); + gpiog.ospeedr.modify(|_, w| w.ospeedr11().very_high_speed()); gpiog.afrh.modify(|_, w| w.afr11().af5()); // MOSI: PD7 // MISO: PA6 @@ -252,6 +262,7 @@ fn main() -> ! { // NSS: PG10 gpiog.moder.modify(|_, w| w.moder10().alternate()); gpiog.otyper.modify(|_, w| w.ot10().push_pull()); + gpiog.ospeedr.modify(|_, w| w.ospeedr10().very_high_speed()); gpiog.afrh.modify(|_, w| w.afr10().af5()); let spi1 = dp.SPI1; @@ -262,7 +273,69 @@ fn main() -> ! { .fthvl().bits(1 - 1) // one data }); spi1.cfg2.modify(|_, w| unsafe { - w.ssom().set_bit() // ss deassert between frames during midi + 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(2) // master inter data idle + .mssi().bits(11) // master SS idle + }); + spi1.cr2.modify(|_, w| unsafe { + w.tsize().bits(1) + }); + spi1.cr1.write(|w| w.spe().set_bit()); + + let gpiob = dp.GPIOB; + rcc.ahb4enr.modify(|_, w| w.gpioben().set_bit()); + // SCK: PB10 + gpiob.moder.modify(|_, w| w.moder10().alternate()); + gpiob.otyper.modify(|_, w| w.ot10().push_pull()); + gpiob.ospeedr.modify(|_, w| w.ospeedr10().very_high_speed()); + gpiob.afrh.modify(|_, w| w.afr10().af5()); + // MOSI: PB15 + gpiob.moder.modify(|_, w| w.moder15().alternate()); + gpiob.otyper.modify(|_, w| w.ot15().push_pull()); + gpiob.ospeedr.modify(|_, w| w.ospeedr15().very_high_speed()); + gpiob.afrh.modify(|_, w| w.afr15().af5()); + // MISO: PB14 + // NSS: PB9 + gpiob.moder.modify(|_, w| w.moder9().alternate()); + gpiob.otyper.modify(|_, w| w.ot9().push_pull()); + gpiob.ospeedr.modify(|_, w| w.ospeedr9().very_high_speed()); + gpiob.afrh.modify(|_, w| w.afr9().af5()); + + let gpioe = dp.GPIOE; + rcc.ahb4enr.modify(|_, w| w.gpioeen().set_bit()); + // DAC0_LDAC: PE11 + 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()); + + let spi2 = dp.SPI2; + rcc.apb1lrstr.write(|w| w.spi2rst().set_bit()); + rcc.apb1lrstr.write(|w| w.spi2rst().clear_bit()); + rcc.apb1lenr.modify(|_, w| w.spi2en().set_bit()); + + spi2.cfg1.modify(|_, w| unsafe { + w.mbr().bits(0) // clk/2 + .dsize().bits(16 - 1) + .fthvl().bits(1 - 1) // one data + }); + spi2.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 @@ -271,25 +344,39 @@ fn main() -> ! { .lsbfrst().clear_bit() .master().set_bit() .sp().bits(0) // motorola - .comm().bits(0b10) // simplex receiver + .comm().bits(0b01) // simplex transmitter .ioswp().clear_bit() - .midi().bits(2) // master inter data idle - .mssi().bits(15) // master SS idle + .midi().bits(1) // master inter data idle + .mssi().bits(0) // master SS idle }); - spi1.cr2.modify(|_, w| unsafe { - w.tsize().bits(1) + spi2.cr2.modify(|_, w| unsafe { + w.tsize().bits(0) }); - spi1.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)) }); - // cortex_m::interrupt::free(|_cs| { }); loop { + // cortex_m::interrupt::free(|_cs| { }); // spi1.cr1.write(|w| w.cstart().set_bit()); spi1.cr1.modify(|r, w| unsafe { w.bits(r.bits() | (1 << 9)) }); while spi1.sr.read().eot().bit_is_clear() {} spi1.ifcr.write(|w| w.eotc().set_bit()); while spi1.sr.read().rxp().bit_is_set() { - let a = spi1.rxdr.read().rxdr().bits() as i16; - info!("adc {}", a); + let a = spi1.rxdr.read().rxdr().bits() as i16; + let d = (a as u16) ^ 0x8000; + + // while spi2.sr.read().txp().bit_is_clear() {} + // spi2.txdr.write(|w| unsafe { w.bits(d as u32) }); + unsafe { ptr::write_volatile(&spi2.txdr as *const _ as *mut u16, d) }; + // write(|w| unsafe { w.bits(d as u32) }); + // while spi2.sr.read().txc().bit_is_clear() {} + // while spi2.sr.read().eot().bit_is_clear() {} + // spi2.ifcr.write(|w| w.eotc().set_bit()); + info!("dac adc {:#x} cr1 {:#x} sr {:#x} cfg1 {:#x} cr2 {:#x}", + a, + spi2.cr1.read().bits(), spi2.sr.read().bits(), + spi2.cfg1.read().bits(), spi2.cr2.read().bits(), + ); } // cortex_m::asm::wfi(); }