diff --git a/README.md b/README.md index 8a7e2e66b28033171121c3b63b599f8aacc6fc86..322b2ffbc4256c155a568ec0bddb178aacf0a526 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,36 @@ The set of examples covers. - `ITM` tracing truogh the file `/tmp/itm.log`. - Access to `arm-none-eabi-gdb`. +# ITMDump + +Install via + +``` +cargo install itm +``` + +Note + Version 0.1.1 of ITM has a different syntax, the latest, version 0.2.0, see below. + +Before running openocd run: + +If this is the first time or if no /tmp/itm.log exists: +``` +> mkfifo /tmp/itm.log +``` + +When the FIFO-file exists, do the following: + +``` +> itmdump -Ff /tmp/itm.log +``` + +ITM Version 0.1.1: + +``` +>itmdump /tmp/itm.log +``` + # Openocd Start `openocd` in a terminal window. (Status and semihosting output is visible here.) diff --git a/examples/clk_out_itm.rs b/examples/clk_out_itm.rs new file mode 100644 index 0000000000000000000000000000000000000000..6098a40ac9af39bdfad7174a7962b5095e64c585 --- /dev/null +++ b/examples/clk_out_itm.rs @@ -0,0 +1,96 @@ +//! Simple access to gpio +//#![deny(unsafe_code)] +#![feature(proc_macro)] +#![no_std] + +extern crate cortex_m; +extern crate cortex_m_rtfm as rtfm; +extern crate stm32f40x; + +#[macro_use] +extern crate cortex_m_debug; +use rtfm::app; + +app! { + device: stm32f40x, +} + +fn wait(i: u32) { + for _ in 0..i { + cortex_m::asm::nop(); // no operation (cannot be optimized out) + } +} + +// see the Reference Manual RM0368 (www.st.com/resource/en/reference_manual/dm00096844.pdf) +// rcc, chapter 6 +// gpio, chapter 8 + +fn init(p: init::Peripherals) { + ipln!("OUTPUT MCO2 on PC9/CN10-1)"); + sprintln!("OUTPUT MCO2 on PC9/CN10-1)"); + // output MCO2 to pin PC9 + // + + // mco2 : SYSCLK = 0b00 + // mcopre : divide by 4 = 0b110 + p.RCC + .cfgr + .modify(|_, w| unsafe { w.mco2().bits(0b00).mco2pre().bits(0b110) }); + + // power on GPIOC, RM0368 6.3.11 + p.RCC.ahb1enr.modify(|_, w| w.gpiocen().set_bit()); + + // 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 + p.GPIOC + .moder + .modify(|_, w| unsafe { w.moder9().bits(0b10) }); + + // otyper reset state push/pull + + // ospeedr 0b11 = high speed + p.GPIOC + .ospeedr + .modify(|_, w| unsafe { w.ospeedr9().bits(0b11) }); + + // power on GPIOA, RM0368 6.3.11 + p.RCC.ahb1enr.modify(|_, w| w.gpioaen().set_bit()); + + // configure PA5 as output, RM0368 8.4.1 + p.GPIOA.moder.modify(|_, w| w.moder5().bits(1)); + + // loop { + // // set PA5 high, RM0368 8.4.6 + // p.GPIOA.odr.modify(|_, w| w.odr5().bit(true)); + // wait(10_000); + + // // set PA5 low, RM0368 8.4.6 + // p.GPIOA.odr.modify(|_, w| w.odr5().bit(false)); + // wait(10_000); + // } + + // rewrite the above code to have the GPIO as output + // and alter the data output through the BSRR register + // this is more efficient as the read register (in modify) + // is not needed. + + loop { + // set PA5 high, RM0368 8.4.7 + p.GPIOA.bsrr.write(|w| w.bs5().set_bit()); + wait(10_000); + + // set PA5 low, RM0368 8.4.7 + p.GPIOA.bsrr.write(|w| w.br5().set_bit()); + wait(10_000); + } +} + +#[inline(never)] +fn idle() -> ! { + loop { + rtfm::wfi(); + } +}