diff --git a/.vscode/launch.json b/.vscode/launch.json index 19c3088ec87671ea1b8e7480b93c2fa9351a4aea..f6d7a6f0ec37caf6f926ac5b5f1fbb77402482de 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,38 +8,177 @@ "type": "cortex-debug", "request": "launch", "servertype": "openocd", - "name": "hello 16Mhz (debug)", + "name": "hello (debug)", "preLaunchTask": "cargo build --example hello", "executable": "./target/thumbv7em-none-eabihf/debug/examples/hello", "configFiles": [ - "interface/stlink.cfg", - "target/stm32f4x.cfg" + "./openocd_jlink.cfg", + ], + "postLaunchCommands": [ + "monitor arm semihosting enable", + ], + "cwd": "${workspaceRoot}" + }, + { + "type": "cortex-debug", + "request": "launch", + "servertype": "jlink", + "name": "hello (debug) jlink", + "preLaunchTask": "cargo build --example hello", + "executable": "./target/thumbv7em-none-eabihf/debug/examples/hello", + "device": "nrf52", + "interface": "swd", + "postLaunchCommands": [ + "monitor semihosting enable" + ], + "cwd": "${workspaceRoot}" + }, + { + "type": "cortex-debug", + "request": "launch", + "servertype": "jlink", + "name": "itm (debug) jlink", + "preLaunchTask": "cargo build --example itm", + "executable": "./target/thumbv7em-none-eabihf/debug/examples/itm", + "device": "nrf52", + "interface": "swd", + "swoConfig": { + "enabled": true, + "cpuFrequency": 64000000, + "swoFrequency": 250000, + "source": "probe", + "decoders": [ + { + "type": "console", + "label": "ITM", + "port": 0 + } + ] + }, + "cwd": "${workspaceRoot}" + }, + { + "type": "cortex-debug", + "request": "launch", + "servertype": "openocd", + "name": "app (debug)", + "preLaunchTask": "cargo build --example app", + "executable": "./target/thumbv7em-none-eabihf/debug/examples/app", + "configFiles": [ + "./openocd_jlink.cfg", ], "postLaunchCommands": [ "monitor arm semihosting enable" ], + "swoConfig": { + "enabled": true, + "cpuFrequency": 64000000, + "swoFrequency": 250000, + "source": "probe", + "decoders": [ + { + "type": "console", + "label": "ITM", + "port": 0 + } + ] + }, "cwd": "${workspaceRoot}" }, { "type": "cortex-debug", "request": "launch", "servertype": "openocd", - "name": "itm 16Mhz (debug)", + "name": "app1 (debug)", + "preLaunchTask": "cargo build --example app1", + "executable": "./target/thumbv7em-none-eabihf/debug/examples/app1", + "configFiles": [ + "./openocd_jlink.cfg", + ], + "postLaunchCommands": [ + "monitor arm semihosting enable" + ], + "cwd": "${workspaceRoot}" + }, + { + "type": "cortex-debug", + "request": "launch", + "servertype": "openocd", + "name": "app2 (debug)", + "preLaunchTask": "cargo build --example app2", + "executable": "./target/thumbv7em-none-eabihf/debug/examples/app2", + "configFiles": [ + "./openocd_jlink.cfg", + ], + "postLaunchCommands": [ + "monitor arm semihosting enable" + ], + "cwd": "${workspaceRoot}" + }, + { + "type": "cortex-debug", + "request": "launch", + "servertype": "openocd", + "name": "app3 (debug)", + "preLaunchTask": "cargo build --example app3", + "executable": "./target/thumbv7em-none-eabihf/debug/examples/app3", + "configFiles": [ + "./openocd_jlink.cfg", + ], + "postLaunchCommands": [ + "monitor arm semihosting enable" + ], + "cwd": "${workspaceRoot}" + }, + { + "type": "cortex-debug", + "request": "launch", + "servertype": "openocd", + "name": "app4 (debug)", + "preLaunchTask": "cargo build --example app4", + "executable": "./target/thumbv7em-none-eabihf/debug/examples/app4", + "configFiles": [ + "./openocd_jlink.cfg", + ], + "postLaunchCommands": [ + "monitor arm semihosting enable" + ], + "cwd": "${workspaceRoot}" + }, + { + "type": "cortex-debug", + "request": "launch", + "servertype": "openocd", + "name": "app5 (debug)", + "preLaunchTask": "cargo build --example app5", + "executable": "./target/thumbv7em-none-eabihf/debug/examples/app5", + "configFiles": [ + "./openocd_jlink.cfg", + ], + "postLaunchCommands": [ + "monitor arm semihosting enable" + ], + "cwd": "${workspaceRoot}" + }, + { + "type": "cortex-debug", + "request": "launch", + "servertype": "openocd", + "name": "itm (debug)", "preLaunchTask": "cargo build --example itm", "executable": "./target/thumbv7em-none-eabihf/debug/examples/itm", // uses local config files "configFiles": [ - "./stlink.cfg", - "./stm32f4x.cfg" - ], - "postLaunchCommands": [ - // here the MCU remains in 16MHz, since we use our local .cfg files - "monitor reset init" + "./openocd_jlink.cfg", ], + // "postLaunchCommands": [ + // // here the MCU remains in 16MHz, since we use our local .cfg files + // "monitor reset init" + // ], "swoConfig": { "enabled": true, - "cpuFrequency": 16000000, - "swoFrequency": 2000000, + "cpuFrequency": 64000000, + "swoFrequency": 250000, "source": "probe", "decoders": [ { @@ -51,6 +190,7 @@ }, "cwd": "${workspaceRoot}" }, + // ITMLOG 0 > "debug.log" { "type": "cortex-debug", "request": "launch", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index db1e20156d78c951c233e3b80949689fa3b148f3..fd89034a8a515faca68392e77a4e8fd9df45e841 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -51,6 +51,78 @@ "isDefault": true } }, + { + "type": "shell", + "label": "cargo build --example app", + "command": "cargo build --example app", + "problemMatcher": [ + "$rustc" + ], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "type": "shell", + "label": "cargo build --example app1", + "command": "cargo build --example app1", + "problemMatcher": [ + "$rustc" + ], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "type": "shell", + "label": "cargo build --example app2", + "command": "cargo build --example app2", + "problemMatcher": [ + "$rustc" + ], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "type": "shell", + "label": "cargo build --example app3", + "command": "cargo build --example app3", + "problemMatcher": [ + "$rustc" + ], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "type": "shell", + "label": "cargo build --example app4", + "command": "cargo build --example app4", + "problemMatcher": [ + "$rustc" + ], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "type": "shell", + "label": "cargo build --example app5", + "command": "cargo build --example app5", + "problemMatcher": [ + "$rustc" + ], + "group": { + "kind": "build", + "isDefault": true + } + }, { "type": "shell", "label": "cargo build --example panic", diff --git a/Cargo.toml b/Cargo.toml index 3089f34742470f03ec9cda4ed1a5aa5db3bef303..77c34e60231e497ea563c6389f5147e196655253 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ version = "0.1.0" # stm32fxx-hal = {git = "https://github.com/stm32-rs/stm32f4xx-hal.git" } [dependencies] -cortex-m-rt = "0.6.7" +cortex-m-rt = "0.6.8" cortex-m-semihosting = "0.3.2" # panic-abort = "0.3.1" # requires nightly toolchain @@ -21,34 +21,43 @@ panic-itm = "0.4.0" bare-metal = "0.2.4" nb = "0.1.1" heapless = "0.4.1" +nrf52-hal-common = "0.7.0" +embedded-hal = "0.2.2" + +[dependencies.nrf52832-hal] +version = "0.7.0" + + [dependencies.cortex-m-rtfm] -version = "0.4.0" -optional = true +version = "0.4.1" +# optional = true [dependencies.cortex-m] -version = "0.5.8" +version = "0.6.0" +#version = "0.5.8" + # features = ["inline-asm"] # <- currently requires nightly compiler # Uncomment for the allocator example. # alloc-cortex-m = "0.3.5" -[dependencies.stm32f4] -version = "0.5.0" -features = ["stm32f413", "rt"] -optional = true - -[dependencies.stm32f4xx-hal] -git = "https://github.com/stm32-rs/stm32f4xx-hal.git" -version = "0.2.8" -features = ["stm32f413", "rt"] -optional = true - -[features] -pac = ["stm32f4"] -hal = ["stm32f4xx-hal"] -rtfm = ["cortex-m-rtfm"] -rtfm-tq = ["cortex-m-rtfm/timer-queue"] +# [dependencies.stm32f4] +# version = "0.5.0" +# features = ["stm32f413", "rt"] +# optional = true + +# [dependencies.stm32f4xx-hal] +# git = "https://github.com/stm32-rs/stm32f4xx-hal.git" +# version = "0.2.8" +# features = ["stm32f413", "rt"] +# optional = true + +# [features] +# pac = ["stm32f4"] +# hal = ["stm32f4xx-hal"] +# rtfm = ["cortex-m-rtfm"] +# rtfm-tq = ["cortex-m-rtfm/timer-queue"] # this lets you use `cargo fix`! [[bin]] diff --git a/examples/app.rs b/examples/app.rs new file mode 100644 index 0000000000000000000000000000000000000000..2d3364abcbaa1509e48364032ec788c2dc56a243 --- /dev/null +++ b/examples/app.rs @@ -0,0 +1,47 @@ +#![no_main] +#![no_std] +use cortex_m_semihosting::hprintln; +use hal::nrf52832_pac as pac; +use nrf52832_hal as hal; +#[allow(unused_imports)] +use panic_semihosting; +use rtfm::app; + +use embedded_hal::digital::OutputPin; +use hal::gpio; +use hal::gpio::p0::*; +use hal::gpio::Level; +use hal::gpio::*; +use hal::prelude::GpioExt; + +#[app(device = crate::hal::target)] +const APP: () = { + #[init] + fn init() { + static mut X: u32 = 0; + + // Safe access to local `static mut` variable + let _x: &'static mut u32 = X; + + // Cortex-M peripherals + let _core: rtfm::Peripherals = core; + + // Device specific peripherals + let p: pac::Peripherals = device; + let port0 = p.P0.split(); + + let mut led: P0_14<gpio::Output<PushPull>> = port0.p0_14.into_push_pull_output(Level::High); + + loop { + led.set_low(); + led.set_high(); + } + + hprintln!("init").unwrap(); + } + #[idle] + fn idle() -> ! { + hprintln!("idle").unwrap(); + loop {} + } +}; diff --git a/examples/app1.rs b/examples/app1.rs new file mode 100644 index 0000000000000000000000000000000000000000..ac9c161b20c71a34b8b1ff589956c0455c25376e --- /dev/null +++ b/examples/app1.rs @@ -0,0 +1,31 @@ +#![no_main] +#![no_std] +use cortex_m_semihosting::hprintln; +use hal::nrf52832_pac as pac; +use nrf52832_hal as hal; +use pac::interrupt; +#[allow(unused_imports)] +use panic_semihosting; +use rtfm::app; + +#[app(device = crate::hal::target)] +const APP: () = { + #[init] + fn init() { + hprintln!("init").unwrap(); + rtfm::pend(interrupt::SWI0_EGU0); + } + #[idle] + fn idle() -> ! { + hprintln!("idle").unwrap(); + rtfm::pend(interrupt::SWI0_EGU0); + loop {} + } + + #[interrupt] + fn SWI0_EGU0() { + static mut TIMES: u32 = 0; + *TIMES += 1; + hprintln!("SWIO_EGU0 {}", TIMES).unwrap(); + } +}; diff --git a/examples/app2.rs b/examples/app2.rs new file mode 100644 index 0000000000000000000000000000000000000000..44f18c6a3159ab535b0ea5d7729d3b7f71bfb64f --- /dev/null +++ b/examples/app2.rs @@ -0,0 +1,48 @@ +#![no_main] +#![no_std] +use cortex_m_semihosting::hprintln; +use hal::nrf52832_pac as pac; +use nrf52832_hal as hal; +use pac::interrupt; +#[allow(unused_imports)] +use panic_semihosting; +use rtfm::app; + +#[app(device = crate::hal::target)] +const APP: () = { + // A resource named SHARED + static mut SHARED: u64 = 0; + + #[init] + fn init() { + hprintln!("init").unwrap(); + rtfm::pend(interrupt::SWI0_EGU0); + rtfm::pend(interrupt::SWI1_EGU1); + } + + #[idle] + fn idle() -> ! { + hprintln!("idle").unwrap(); + + loop { + // hprintln!(".").unwrap(); + } + } + + // defaults to priority = 1 + #[interrupt(resources = [SHARED])] + fn SWI0_EGU0() { + hprintln!("SWI0_EGU0 start").unwrap(); + resources.SHARED.lock(|shared| { + *shared += 1; + }); + hprintln!("SWI0_EGU0 end").unwrap(); + } + + #[interrupt(priority = 2, + resources = [SHARED])] + fn SWI1_EGU1() { + hprintln!("SWI1_EGU1").unwrap(); + *resources.SHARED += 1; + } +}; diff --git a/examples/app3.rs b/examples/app3.rs new file mode 100644 index 0000000000000000000000000000000000000000..cbe229a92f2a39a060e818d153e00985e7a24383 --- /dev/null +++ b/examples/app3.rs @@ -0,0 +1,38 @@ +#![no_main] +#![no_std] +use cortex_m_semihosting::hprintln; +use nrf52832_hal as hal; +#[allow(unused_imports)] +use panic_semihosting; +use rtfm::app; + +#[app(device = crate::hal::target)] +const APP: () = { + #[init(spawn = [foo])] + fn init() { + hprintln!("init").unwrap(); + spawn.foo().unwrap(); + } + + #[task(spawn = [bar, baz])] + fn foo() { + hprintln!("foo").unwrap(); + spawn.bar().unwrap(); + spawn.baz().unwrap(); + } + + #[task] + fn bar() { + hprintln!("bar").unwrap(); + } + + #[task(priority = 2)] + fn baz() { + hprintln!("baz").unwrap(); + } + + extern "C" { + fn SWI0_EGU0(); + fn SWI1_EGU1(); + } +}; diff --git a/examples/app4.rs b/examples/app4.rs new file mode 100644 index 0000000000000000000000000000000000000000..398d1627c5b7764e4c15fc72bc8f05e56a6f7031 --- /dev/null +++ b/examples/app4.rs @@ -0,0 +1,55 @@ +#![no_main] +#![no_std] +use cortex_m_semihosting::hprintln; +use hal::nrf52832_pac as pac; +use nrf52832_hal as hal; +use pac::interrupt; +#[allow(unused_imports)] +use panic_semihosting; +use rtfm::app; + +use heapless::{ + consts::*, + spsc::{Consumer, Producer, Queue}, +}; + +#[app(device = crate::hal::target)] +const APP: () = { + // Late resources + static mut P: Producer<'static, u32, U4> = (); + static mut C: Consumer<'static, u32, U4> = (); + + #[init] + fn init() -> init::LateResources { + // NOTE: we use `Option` here to work around the lack of + // a stable `const` constructor + static mut Q: Option<Queue<u32, U4>> = None; + + *Q = Some(Queue::new()); + let (p, c) = Q.as_mut().unwrap().split(); + + // Initialization of late resources + init::LateResources { P: p, C: c } + } + + #[idle(resources = [C])] + fn idle() -> ! { + loop { + if let Some(data) = resources.C.dequeue() { + hprintln!("received message: {}", data).unwrap(); + + + } else { + rtfm::pend(interrupt::SWI0_EGU0); + } + } + } + + #[interrupt(resources = [P])] + fn SWI0_EGU0() { + static mut NUMBER : u32 = 0; + hprintln!("SWI0_EGU0: {}", NUMBER).unwrap(); + resources.P.enqueue(*NUMBER).unwrap(); + *NUMBER += 1; + } +}; diff --git a/examples/app5.rs b/examples/app5.rs new file mode 100644 index 0000000000000000000000000000000000000000..0a5ba5a177ff4d427c016b600c43c30fed1537af --- /dev/null +++ b/examples/app5.rs @@ -0,0 +1,42 @@ +#![no_main] +#![no_std] +use cortex_m_semihosting::hprintln; +use hal::nrf52832_pac as pac; +use nrf52832_hal as hal; +use pac::interrupt; +#[allow(unused_imports)] +use panic_semihosting; +use rtfm::app; + +use embedded_hal::digital::OutputPin; +use hal::gpio; +use hal::gpio::p0::*; +use hal::gpio::Level; +use hal::gpio::*; +use hal::prelude::GpioExt; + +#[app(device = crate::hal::target)] +const APP: () = { + // Late resources + static mut LED: P0_14<gpio::Output<PushPull>> = (); + + #[init] + fn init() -> init::LateResources { + hprintln!("init").unwrap(); + let port0 = device.P0.split(); + let led = port0.p0_14.into_push_pull_output(Level::High); + init::LateResources { LED : led } + } + + #[idle(resources = [LED])] + fn idle() -> ! { + + let led = resources.LED; + loop { + hprintln!("low").unwrap(); + led.set_low(); + hprintln!("high").unwrap(); + led.set_high(); + } + } +}; diff --git a/examples/hello.rs b/examples/hello.rs index f36bdb3edeb66447ed3290aef1408356f3e64eea..8c8d32c418585bbb576437043df440526f00d00e 100644 --- a/examples/hello.rs +++ b/examples/hello.rs @@ -10,6 +10,9 @@ use cortex_m_semihosting::hprintln; #[entry] fn main() -> ! { - hprintln!("Hello, world!").unwrap(); + let a = 10; + let b = a * 20; + let c = a + b; + hprintln!("Hello Oxidize! {}", c).unwrap(); loop {} } diff --git a/memory.x b/memory.x index ae97600f49820c1c5027dba4ba8be2d97bb7352e..bb151f69715d0526a58ff0a6d16e2c83563a0849 100644 --- a/memory.x +++ b/memory.x @@ -1,9 +1,6 @@ + MEMORY { - /* NOTE 1 K = 1 KiBi = 1024 bytes */ - /* These values correspond to the stm32f401re/stm32f411re */ - - FLASH : ORIGIN = 0x08000000, LENGTH = 512K - RAM : ORIGIN = 0x20000000, LENGTH = 96K -} - + FLASH : ORIGIN = 0x00000000, LENGTH = 512K + RAM : ORIGIN = 0x20000000, LENGTH = 64K +} \ No newline at end of file diff --git a/openocd.cfg b/openocd.cfg index f6a81487a5e9553eaae35d02e0e275e26a1a38b5..fd42d1b97b0c5c72ffcfcdedbfc0ca81df91329d 100644 --- a/openocd.cfg +++ b/openocd.cfg @@ -1,8 +1,23 @@ -# Sample OpenOCD configuration for the STM32F3DISCOVERY development board +source [find interface/jlink.cfg] +transport select swd +source [find target/nrf52.cfg] -# Depending on the hardware revision you got you'll have to pick ONE of these -# interfaces. At any time only one interface should be commented out. +# Configure a flash bank +# +# I'm not sure what exactly that does, or why it's required, but flashing +# doesn't work without it, so here we go. +# +# That "nrf51" bit in there looks wrong, but it isn't. It's the name of the +# flash driver, and for some reason, the nRF52832 is covered by the nrf51 +# driver. As far as I can tell, there isn't even an nrf52 driver. +# +# As of 2018-08-13, the documentation I found on openocd.org[1] states that the +# driver's name should be "nrf5", which makes more sense. That seems to apply to +# the in-development version, however, not the currently released one (0.10.0). +# +# [1] http://openocd.org/doc/html/Flash-Commands.html#index-nrf5 +flash bank $_CHIPNAME.flash nrf51 0x00000000 0 0 0 $_TARGETNAME -source [find interface/stlink.cfg] - -source [find target/stm32f4x.cfg] +init +arm semihosting enable +reset \ No newline at end of file diff --git a/openocd.gdb b/openocd.gdb index 46b34b908e55412d05de8e077e8fe1ac55fe4712..a470e0728b40f405793b9a5966792b1bfc81dea3 100644 --- a/openocd.gdb +++ b/openocd.gdb @@ -16,7 +16,7 @@ monitor arm semihosting enable # send captured ITM to the file (fifo) /tmp/itm.log # (the microcontroller SWO pin must be connected to the programmer SWO pin) # 16000000 must match the core clock frequency -monitor tpiu config internal /tmp/itm.log uart off 16000000 +monitor tpiu config internal /tmp/itm.log uart off 64000000 2000000 # OR: make the microcontroller SWO pin output compatible with UART (8N1) # 8000000 must match the core clock frequency diff --git a/openocd_jlink.cfg b/openocd_jlink.cfg new file mode 100644 index 0000000000000000000000000000000000000000..88bd4f0bff50af0abd6a57b73f645b880f5d46ee --- /dev/null +++ b/openocd_jlink.cfg @@ -0,0 +1,29 @@ +source [find interface/jlink.cfg] +transport select swd +source [find target/nrf52.cfg] + +# Configure a flash bank +# +# I'm not sure what exactly that does, or why it's required, but flashing +# doesn't work without it, so here we go. +# +# That "nrf51" bit in there looks wrong, but it isn't. It's the name of the +# flash driver, and for some reason, the nRF52832 is covered by the nrf51 +# driver. As far as I can tell, there isn't even an nrf52 driver. +# +# As of 2018-08-13, the documentation I found on openocd.org[1] states that the +# driver's name should be "nrf5", which makes more sense. That seems to apply to +# the in-development version, however, not the currently released one (0.10.0). +# +# [1] http://openocd.org/doc/html/Flash-Commands.html#index-nrf5 +#flash bank $_CHIPNAME.flash nrf51 0x00000000 0 0 0 $_TARGETNAME + +# init +# arm semihosting enable + +# # 64000000 must match the core clock frequency +# tpiu config internal /tmp/itm.log uart off 64000000 +# # enable ITM port 0 +# itm port 0 on + +# reset \ No newline at end of file