diff --git a/.vscode/launch.json b/.vscode/launch.json index 56464e766e2e4931a50f363d770cbd759d4d23f7..09516bde169f299a9bf8dff4dcbeea85cadb641e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -382,6 +382,7 @@ "request": "launch", "servertype": "openocd", "name": "bare6 (debug) 64Mhz", + "preLaunchTask": "cargo build --example bare6 --features stm32f4", "executable": "./target/thumbv7em-none-eabihf/debug/examples/bare6", "configFiles": [ "interface/stlink.cfg", @@ -410,6 +411,7 @@ "request": "launch", "servertype": "openocd", "name": "bare6 (debug) 84Mhz", + "preLaunchTask": "cargo build --example bare6 --features stm32f4", "executable": "./target/thumbv7em-none-eabihf/debug/examples/bare6", "configFiles": [ "interface/stlink.cfg", diff --git a/examples/bare6.rs b/examples/bare6.rs index f2d6f75158d117e519b7b7bc7de2c910da17065d..32eab268ca1d6c0114d910da5c73bee8844c11f0 100644 --- a/examples/bare6.rs +++ b/examples/bare6.rs @@ -27,40 +27,36 @@ extern crate panic_halt; use cortex_m::{iprint, iprintln, peripheral::itm::Stim, peripheral::syst::SystClkSource}; -use cortex_m_rt::entry; +use cortex_m_rt::{entry, exception}; -// use cortex_m_semihosting::hprintln; use stm32f4::stm32f411; -use stm32f411::{DWT, GPIOA, NVIC, /* interrupt, Peripherals, Interrupt, ITM, */ RCC}; +use stm32f411::{interrupt, Interrupt, DWT, GPIOA, GPIOC, ITM, NVIC, RCC, SYST}; + #[entry] fn main() -> ! { let p = stm32f411::Peripherals::take().unwrap(); let mut c = stm32f411::CorePeripherals::take().unwrap(); - //p.GPIOA.odr.write(|w| w.bits(1)); - - //let stim = &mut p. - let stim = &mut c.ITM.stim[0]; iprintln!(stim, "Hello, bare6!"); - // // let dwt = unsafe { &mut *DWT.get() }; // get the reference to DWD in memory - // // let rcc = unsafe { &mut *RCC.get() }; // get the reference to RCC in memory - // // let gpioa = unsafe { &mut *GPIOA.get() }; // get the reference to GPIOA in memory - // // let gpioc = unsafe { &mut *GPIOC.get() }; // get the reference to GPIOC in memory - // // let flash = unsafe { &mut *FLASH.get() }; // get the reference to FLASH in memory + c.DWT.enable_cycle_counter(); + unsafe { + c.DWT.cyccnt.write(0); + } + let t = DWT::get_cycle_count(); + iprintln!(stim, "{}", t); - // p.DWT.enable_cycle_counter(); - // // clock_out(rcc, gpioc); - // // //clock::set_84_mhz(rcc, flash); - idle(stim, c.DWT, p.RCC, p.GPIOA); + clock_out(&p.RCC, &p.GPIOC); + // clock::set_84_mhz(rcc, flash); + idle(stim, p.RCC, p.GPIOA); loop {} } // // user application -fn idle(stim: &mut Stim, dwt: DWT, rcc: RCC, gpioa: GPIOA) { +fn idle(stim: &mut Stim, rcc: RCC, gpioa: GPIOA) { iprintln!(stim, "idle"); // power on GPIOA, RM0368 6.3.11 @@ -69,156 +65,170 @@ fn idle(stim: &mut Stim, dwt: DWT, rcc: RCC, gpioa: GPIOA) { // configure PA5 as output, RM0368 8.4.1 gpioa.moder.modify(|_, w| w.moder5().bits(1)); - // at 16 Mhz, 8000_0000 cycles = period 0.5s - // at 64 Mhz, 8000_0000 cycles = period 0.125s - let cycles = 8000_0000; + // at 16 Mhz, 8_000_000 cycles = period 0.5s + // at 64 Mhz, 4*8_000_000 cycles = period 0.55s + // let cycles = 8_000_000; + let cycles = 4*8_000_000; + loop { - // ipln!("led on"); + iprintln!(stim, "on {}", DWT::get_cycle_count()); // set PA5 high, RM0368 8.4.7 gpioa.bsrr.write(|w| w.bs5().set_bit()); - wait_cycles(&dwt, cycles); + wait_cycles(cycles); - // ipln!("led off"); + + iprintln!(stim, "off {}", DWT::get_cycle_count()); // set PA5 low, RM0368 8.4.7 gpioa.bsrr.write(|w| w.br5().set_bit()); - wait_cycles(&dwt, cycles); + wait_cycles(cycles); } } // uses the DWT.CYCNT // doc: ARM trm_100166_0001_00_en.pdf, chapter 9.2 // we use the `cortex-m` abstraction, as re-exported by the stm32f40x -fn wait_cycles(dwt: &DWT, nr_cycles: u32) { - let t = dwt.cyccnt.read().wrapping_add(nr_cycles); - while (dwt.cyccnt.read().wrapping_sub(t) as i32) < 0 {} +fn wait_cycles(nr_cycles: u32) { + let t = DWT::get_cycle_count().wrapping_add(nr_cycles); + while (DWT::get_cycle_count().wrapping_sub(t) as i32) < 0 {} } // see the Reference Manual RM0368 (www.st.com/resource/en/reference_manual/dm00096844.pdf) // rcc, chapter 6 // gpio, chapter 8 -// fn clock_out(rcc: &mut RCC, gpioc: &mut GPIOC) { -// // output MCO2 to pin PC9 +fn clock_out(rcc: &RCC, gpioc: &GPIOC) { + // output MCO2 to pin PC9 -// // mco2 : SYSCLK = 0b00 -// // mcopre : divide by 4 = 0b110 -// rcc.cfgr -// .modify(|_, w| unsafe { w.mco2().bits(0b00).mco2pre().bits(0b110) }); + // mco2 : SYSCLK = 0b00 + // mcopre : divide by 4 = 0b110 + rcc.cfgr + .modify(|_, w| unsafe { w.mco2().bits(0b00).mco2pre().bits(0b110) }); -// // power on GPIOC, RM0368 6.3.11 -// rcc.ahb1enr.modify(|_, w| w.gpiocen().set_bit()); + // power on GPIOC, RM0368 6.3.11 + rcc.ahb1enr.modify(|_, w| w.gpiocen().set_bit()); -// // MCO_2 alternate function AF0, STM32F401xD STM32F401xE data sheet -// // table 9 -// // AF0, gpioc reset value = AF0 + // MCO_2 alternate function AF0, STM32F401xD STM32F401xE data sheet + // table 9 + // AF0, gpioc reset value = AF0 -// // configure PC9 as alternate function 0b10, RM0368 6.2.10 -// gpioc.moder.modify(|_, w| unsafe { w.moder9().bits(0b10) }); + // configure PC9 as alternate function 0b10, RM0368 6.2.10 + gpioc.moder.modify(|_, w| w.moder9().bits(0b10) ); -// // otyper reset state push/pull, in reset state (don't need to change) + // otyper reset state push/pull, in reset state (don't need to change) -// // ospeedr 0b11 = high speed -// gpioc -// .ospeedr -// .modify(|_, w| unsafe { w.ospeedr9().bits(0b11) }); -// } + // ospeedr 0b11 = high speed + gpioc + .ospeedr + .modify(|_, w| w.ospeedr9().bits(0b11) ); +} // 1. Compile and run the example, in 16Mhz // The processor SYSCLK defaults to HCI 16Mhz // (this is what you get after a `monitor reset halt`). // -// confirm that your ITM dump traces the init, idle and led on/off -// make sure your TPIU is set to a system clock at 16Mhz +// Confirm that your ITM dump traces the init, idle and led on/off. +// Make sure your TPIU is set to a system clock at 16Mhz +// +// What is the frequency of blinking? +// +// ** your answer here ** +// +// commit your answers (bare6_1) +// +// 2. Now connect an oscilloscope to PC9, which is set to +// output the MCO2. +// +// What is the frequency of MCO2 read by the oscilloscope? +// +// ** your answer here ** +// +// Compute the value of SYSCLK based on the oscilloscope reading +// +// ** your answer here ** +// +// What is the peak to peak reading of the signal? +// +// ** your answer here ** +// +// Make a folder called "pictures" in your git project. +// Make a screen dump or photo of the oscilloscope output. +// Save the the picture as "bare_6_16mhz_high_speed". +// +// commit your answaaasers (bare6_2) +// +// 3. Now run the example in 64Mz +// You can do that by issuing a `monitor reset init` +// which reprograms SYSCLK to 4*HCI. +// // -// you may use either ITM tracing using ITM dump or internally in -// vscode using the new "cortex debug" plugin +// Confirm that your ITM dump traces the init, idle and led on/off +// (make sure your TPIU is set to a system clock at 64Mhz) // -// what is the frequency of blinking -// ** your answer here ** +// Uncommnet: `let cycles = 4 * 8_000_000; +//` +// What is the frequency of blinking? // -// commit your answers (bare6_1) +// ** your answer here ** // -// 2. now connect an oscilloscope to PC9, which is set to -// output the MCO2 +// commit your answers (bare6_3) // -// what is the frequency of MCO2 read by the oscilloscope -// ** your answer here ** +// 4. Repeat experiment 2 // -// compute the value of SYSCLK based on the oscilloscope reading -// ** your answer here ** +// What is the frequency of MCO2 read by the oscilloscope? // -// what is the peak to peak reading of the signal -// ** your answer here ** +// ** your answer here ** // -// make a folder called "pictures" in your git project -// make a screen dump or photo of the oscilloscope output -// save the the picture as "bare_6_16mhz_high_speed" +// Compute the value of SYSCLK based on the oscilloscope reading. // -// commit your answaaasers (bare6_2) +// ** your answer here ** // -// 3. now run the example in 64Mz -// you can do that by issuing a `monitor reset init` -// which reprograms SYSCLK to 4*HCI -// (make sure you have the latest openocd v 0.10) +// What is the peak to peak reading of the signal? // -// confirm that your ITM dump traces the init, idle and led on/off -// (make sure your TPIU is set to a system clock at 64Mhz) +// ** your answer here ** // -// what is the frequency of blinking -// ** your answer here ** +// Make a screen dump or photo of the oscilloscope output. +// Save the the picture as "bare_6_64mhz_high_speed". // -// commit your answers (bare6_3) +// commit your answers (bare6_4) // -// 4. repeat the experiment 2 -// what is the frequency of MCO2 read by the oscilloscope -// ** your answer here ** +// 5. Now we will put the MCU in 84MHz using the function +// clock::set_84_mhz(rcc, flash); // -// compute the value of SYSCLK based on the oscilloscope reading -// ** your answer here ** -// what is the peak to peak reading of the signal +// This function is part of the `f4` support crate (by Johonnes Sjölund) +// besides `rcc` (for clocking) it takes `flash` as a parameter to set +// up correct latency (wait states) for the flash memory (where our +// program typically resides). This is required since the flash cannot +// operate at the full 84MHz, so the MCU has to wait for the memory. // -// ** your answer here ** +// Repeat the experiment 2. // -// make a screen dump or photo of the oscilloscope output -// save the the picture as "bare_6_64mhz_high_speed" +// What is the frequency of MCO2 read by the oscilloscope. // -// commit your answers (bare6_4) +// ** your answer here ** // -// 5. now we will put the MCU in 84MHz using the function -// clock::set_84_mhz(rcc, flash); +// Compute the value of SYSCLK based on the oscilloscope reading. // -// this function is part of the `f4` support crate (by Johonnes Sjölund) -// besides `rcc` (for clocking) it takes `flash` as a parameter to set -// up correct latency (wait states) for the flash memory (where our -// program typically resides). This is required since the flash cannot -// operate at the full 84MHz, so the MCU has to wait for the memory. +// ** your answer here ** // -// repeat the experiment 2. -// what is the frequency of MCO2 read by the oscilloscope -// ** your answer here ** +// What is the peak to peak reading of the signal. // -// compute the value of SYSCLK based on the oscilloscope reading -// ** your answer here ** -// what is the peak to peak reading of the signal +// ** your answer here ** // -// ** your answer here ** +// Make a screen dump or photo of the oscilloscope output. +// Save the the picture as "bare_6_84mhz_high_speed" // -// make a screen dump or photo of the oscilloscope output -// save the the picture as "bare_6_84mhz_high_speed" +// commit your answers (bare6_5) // -// commit your answers (bare6_5) +// 6. Now reprogram the PC9 to be "Low Speed", and re-run at 84Mz. // -// 6. now reprogram the PC9 to be "Low Speed", and re-run at 84Mz +// Did the frequency change in comparison to assignment 5? // -// did the frequency change in comparison to assignment 5. -// ** your answer here ** +// ** your answer here ** // -// what is the peak to peak reading of the signal -// ** your answer here ** +// What is the peak to peak reading of the signal (and why did it change)? // -// why does it differ? -// ** your answer here ** +// ** your answer here ** // -// make a screen dump or photo of the oscilloscope output -// save the the picture as "bare_6_84mhz_low_speed" +// Make a screen dump or photo of the oscilloscope output. +// Save the the picture as "bare_6_84mhz_low_speed". // -// commit your answers (bare6_6) +// commit your answers (bare6_6)