summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorDario Nieuwenhuis <dirbaio@dirbaio.net>2020-09-05 01:18:00 +0200
committerDario Nieuwenhuis <dirbaio@dirbaio.net>2020-09-05 01:18:00 +0200
commit840e130a80b36eb53029ca7f0c115ea4aa7d19e3 (patch)
tree1708cb7a314f284c938d9314f8f517ac56fc132e /examples
parentace5776dcf6561ac8bbb25cc0a2ed6b373d581c5 (diff)
downloadnrf-softdevice-840e130a80b36eb53029ca7f0c115ea4aa7d19e3.zip
Add new nrf-softdevice crate, with just interrupts+flash for now.
Diffstat (limited to 'examples')
-rw-r--r--examples/flash/.cargo/config27
-rw-r--r--examples/flash/Cargo.toml32
-rw-r--r--examples/flash/build.rs31
-rw-r--r--examples/flash/memory.x34
-rw-r--r--examples/flash/src/main.rs69
5 files changed, 193 insertions, 0 deletions
diff --git a/examples/flash/.cargo/config b/examples/flash/.cargo/config
new file mode 100644
index 0000000..3f319ae
--- /dev/null
+++ b/examples/flash/.cargo/config
@@ -0,0 +1,27 @@
+[target.'cfg(all(target_arch = "arm", target_os = "none"))']
+runner = "probe-run --chip nRF52840_xxAA --defmt"
+
+rustflags = [
+ # LLD (shipped with the Rust toolchain) is used as the default linker
+ "-C", "link-arg=--nmagic",
+ "-C", "link-arg=-Tlink.x",
+ "-C", "link-arg=-Tdefmt.x",
+
+ # if you run into problems with LLD switch to the GNU linker by commenting out
+ # this line
+ # "-C", "linker=arm-none-eabi-ld",
+
+ # if you need to link to pre-compiled C libraries provided by a C toolchain
+ # use GCC as the linker by commenting out both lines above and then
+ # uncommenting the three lines below
+ # "-C", "linker=arm-none-eabi-gcc",
+ # "-C", "link-arg=-Wl,-Tlink.x",
+ # "-C", "link-arg=-nostartfiles",
+]
+
+[build]
+# Pick ONE of these compilation targets
+# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
+# target = "thumbv7m-none-eabi" # Cortex-M3
+# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU)
+target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
diff --git a/examples/flash/Cargo.toml b/examples/flash/Cargo.toml
new file mode 100644
index 0000000..f5c7568
--- /dev/null
+++ b/examples/flash/Cargo.toml
@@ -0,0 +1,32 @@
+[package]
+authors = ["Dario Nieuwenhuis <dirbaio@dirbaio.net>"]
+edition = "2018"
+readme = "README.md"
+name = "softdevice-test"
+version = "0.1.0"
+
+[features]
+default = [ "defmt-default" ]
+defmt-default = []
+defmt-trace = []
+defmt-debug = []
+defmt-info = []
+defmt-warn = []
+defmt-error = []
+
+[dependencies]
+async-flash = { version = "0.1.0", path = "../../async-flash" }
+cortex-m = { version = "0.6.3", features = [ "inline-asm" ] }
+cortex-m-rt = "0.6.12"
+defmt = "0.1.0"
+defmt-rtt = "0.1.0"
+panic-probe = "0.1.0"
+nrf52840-hal = { version = "0.11.0" }
+nrf-softdevice = { version = "0.1.0", path = "../../nrf-softdevice" }
+static-executor = { version = "0.1.0" }
+static-executor-cortex-m = { version = "0.1.0" }
+
+[[bin]]
+name = "softdevice-test"
+test = false
+bench = false
diff --git a/examples/flash/build.rs b/examples/flash/build.rs
new file mode 100644
index 0000000..d534cc3
--- /dev/null
+++ b/examples/flash/build.rs
@@ -0,0 +1,31 @@
+//! This build script copies the `memory.x` file from the crate root into
+//! a directory where the linker can always find it at build time.
+//! For many projects this is optional, as the linker always searches the
+//! project root directory -- wherever `Cargo.toml` is. However, if you
+//! are using a workspace or have a more complicated build setup, this
+//! build script becomes required. Additionally, by requesting that
+//! Cargo re-run the build script whenever `memory.x` is changed,
+//! updating `memory.x` ensures a rebuild of the application with the
+//! new memory settings.
+
+use std::env;
+use std::fs::File;
+use std::io::Write;
+use std::path::PathBuf;
+
+fn main() {
+ // Put `memory.x` in our output directory and ensure it's
+ // on the linker search path.
+ let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
+ File::create(out.join("memory.x"))
+ .unwrap()
+ .write_all(include_bytes!("memory.x"))
+ .unwrap();
+ println!("cargo:rustc-link-search={}", out.display());
+
+ // By default, Cargo will re-run a build script whenever
+ // any file in the project changes. By specifying `memory.x`
+ // here, we ensure the build script is only re-run when
+ // `memory.x` is changed.
+ println!("cargo:rerun-if-changed=memory.x");
+}
diff --git a/examples/flash/memory.x b/examples/flash/memory.x
new file mode 100644
index 0000000..f98ee4a
--- /dev/null
+++ b/examples/flash/memory.x
@@ -0,0 +1,34 @@
+MEMORY
+{
+ /* NOTE 1 K = 1 KiBi = 1024 bytes */
+ /* TODO Adjust these memory regions to match your device memory layout */
+ /* These values correspond to the LM3S6965, one of the few devices QEMU can emulate */
+ FLASH : ORIGIN = 0x00027000, LENGTH = 256K
+ RAM : ORIGIN = 0x20020000, LENGTH = 128K
+}
+
+/* This is where the call stack will be allocated. */
+/* The stack is of the full descending type. */
+/* You may want to use this variable to locate the call stack and static
+ variables in different memory regions. Below is shown the default value */
+/* _stack_start = ORIGIN(RAM) + LENGTH(RAM); */
+
+/* You can use this symbol to customize the location of the .text section */
+/* If omitted the .text section will be placed right after the .vector_table
+ section */
+/* This is required only on microcontrollers that store some configuration right
+ after the vector table */
+/* _stext = ORIGIN(FLASH) + 0x400; */
+
+/* Example of putting non-initialized variables into custom RAM locations. */
+/* This assumes you have defined a region RAM2 above, and in the Rust
+ sources added the attribute `#[link_section = ".ram2bss"]` to the data
+ you want to place there. */
+/* Note that the section will not be zero-initialized by the runtime! */
+/* SECTIONS {
+ .ram2bss (NOLOAD) : ALIGN(4) {
+ *(.ram2bss);
+ . = ALIGN(4);
+ } > RAM2
+ } INSERT AFTER .bss;
+*/
diff --git a/examples/flash/src/main.rs b/examples/flash/src/main.rs
new file mode 100644
index 0000000..6b33ded
--- /dev/null
+++ b/examples/flash/src/main.rs
@@ -0,0 +1,69 @@
+#![no_std]
+#![no_main]
+#![feature(type_alias_impl_trait)]
+
+use defmt_rtt as _; // global logger
+use nrf52840_hal as _;
+use panic_probe as _;
+use static_executor_cortex_m as _;
+
+use async_flash::Flash;
+use core::sync::atomic::{AtomicUsize, Ordering};
+use cortex_m_rt::entry;
+use defmt::info;
+use nrf_softdevice as sd;
+
+#[defmt::timestamp]
+fn timestamp() -> u64 {
+ static COUNT: AtomicUsize = AtomicUsize::new(0);
+ // NOTE(no-CAS) `timestamps` runs with interrupts disabled
+ let n = COUNT.load(Ordering::Relaxed);
+ COUNT.store(n + 1, Ordering::Relaxed);
+ n as u64
+}
+
+macro_rules! depanic {
+ ($( $i:expr ),*) => {
+ {
+ defmt::error!($( $i ),*);
+ panic!();
+ }
+ }
+}
+
+#[static_executor::task]
+async fn softdevice_task() {
+ sd::run().await;
+}
+
+#[static_executor::task]
+async fn flash_task() {
+ let mut f = unsafe { sd::Flash::new() };
+ info!("starting erase");
+ match f.erase(0x80000).await {
+ Ok(()) => info!("erased!"),
+ Err(e) => depanic!("erase failed: {:?}", e),
+ }
+
+ info!("starting write");
+ match f.write(0x80000, &[1, 2, 3, 4]).await {
+ Ok(()) => info!("write done!"),
+ Err(e) => depanic!("write failed: {:?}", e),
+ }
+}
+
+#[entry]
+fn main() -> ! {
+ info!("Hello World!");
+
+ info!("enabling softdevice");
+ unsafe { sd::enable() }
+ info!("softdevice enabled");
+
+ unsafe {
+ softdevice_task.spawn().unwrap();
+ flash_task.spawn().unwrap();
+
+ static_executor::run();
+ }
+}