Skip to content

Commit

Permalink
Enables PWM for the nRF9160
Browse files Browse the repository at this point in the history
Without it, we can't have blinky as its RGB LEDs require PWM!

This PR assumes unsecured peripheral access. I'm thinking that in future we might introduce a "Secured" feature perhaps.
  • Loading branch information
huntc committed May 10, 2021
1 parent 053dc54 commit 411e000
Show file tree
Hide file tree
Showing 10 changed files with 309 additions and 15 deletions.
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rust-analyzer.cargo.features": [
"52840"
]
}
31 changes: 31 additions & 0 deletions examples/pwm-blinky-demo/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "pwm-blinky-demo"
version = "0.1.0"
authors = ["Christopher Hunt <[email protected]>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
cortex-m = "0.6.2"
cortex-m-rt = "0.6.12"
rtt-target = {version = "0.2.0", features = ["cortex-m"] }
nb = "1.0.0"

[dependencies.embedded-hal]
version = "0.2.3"
features = ["unproven"]

[dependencies.nrf9160-hal]
features = ["rt"]
path = "../../nrf9160-hal"
optional = true

[dependencies.nrf52840-hal]
features = ["rt"]
path = "../../nrf52840-hal"
optional = true

[features]
9160 = ["nrf9160-hal"]
52840 = ["nrf52840-hal"]
63 changes: 63 additions & 0 deletions examples/pwm-blinky-demo/Embed.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
[default.probe]
# USB vendor ID
# usb_vid = "1337"
# USB product ID
# usb_pid = "1337"
# Serial number
# serial = "12345678"
# The protocol to be used for communicating with the target.
protocol = "Swd"
# The speed in kHz of the data link to the target.
# speed = 1337

[default.flashing]
# Whether or not the target should be flashed.
enabled = true
# Whether or not the target should be halted after reset.
# DEPRECATED, moved to reset section
halt_afterwards = false
# Whether or not bytes erased but not rewritten with data from the ELF
# should be restored with their contents before erasing.
restore_unwritten_bytes = false
# The path where an SVG of the assembled flash layout should be written to.
# flash_layout_output_path = "out.svg"

[default.reset]
# Whether or not the target should be reset.
# When flashing is enabled as well, the target will be reset after flashing.
enabled = true
# Whether or not the target should be halted after reset.
halt_afterwards = false

[default.general]
# The chip name of the chip to be debugged.
chip = "nRF52840_xxAA"
# A list of chip descriptions to be loaded during runtime.
chip_descriptions = []
# The default log level to be used. Possible values are one of:
# "OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"
log_level = "WARN"

[default.rtt]
# Whether or not an RTTUI should be opened after flashing.
# This is exclusive and cannot be used with GDB at the moment.
enabled = true
# A list of channel associations to be displayed. If left empty, all channels are displayed.
channels = [
# { up = 0, down = 0, name = "name", format = "String" }
]
# The duration in ms for which the logger should retry to attach to RTT.
timeout = 3000
# Whether timestamps in the RTTUI are enabled
show_timestamps = true
# Whether to save rtt history buffer on exit.
log_enabled = false
# Where to save rtt history buffer relative to manifest path.
log_path = "./logs"

[default.gdb]
# Whether or not a GDB server should be opened after flashing.
# This is exclusive and cannot be used with RTT at the moment.
enabled = false
# The connection string in host:port format wher the GDB server will open a socket.
# gdb_connection_string
36 changes: 36 additions & 0 deletions examples/pwm-blinky-demo/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//! 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.
fn main() {
// We only need the memory.x file for the nRF9160 as our program
// must then reside in a location where unsecure programs need to be.
#[cfg(feature = "9160")]
{
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;

// 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");
}
}
32 changes: 32 additions & 0 deletions examples/pwm-blinky-demo/memory.x
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
MEMORY
{
/* NOTE 1 K = 1 KiBi = 1024 bytes */
FLASH : ORIGIN = 0x00050000, LENGTH = 768K
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;
*/
65 changes: 65 additions & 0 deletions examples/pwm-blinky-demo/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#![no_main]
#![no_std]

use nb::block;
#[cfg(feature = "9160")]
use nrf9160_hal as hal;
#[cfg(feature = "52840")]
use nrf52840_hal as hal;
use hal::{gpio, prelude::*, pwm, pwm::Pwm, timer, timer::Timer};
use rtt_target::{rprintln, rtt_init_print};

#[panic_handler] // panicking behavior
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {
cortex_m::asm::bkpt();
}
}

#[cortex_m_rt::entry]
fn main() -> ! {
rtt_init_print!();
let p = hal::pac::Peripherals::take().unwrap();
#[cfg(feature = "9160")]
let p0 = gpio::p0::Parts::new(p.P0_NS);
#[cfg(feature = "52840")]
let p0 = gpio::p0::Parts::new(p.P0);

#[cfg(feature = "9160")]
let pwm = Pwm::new(p.PWM0_NS);
#[cfg(feature = "52840")]
let pwm = Pwm::new(p.PWM0);
#[cfg(feature = "9160")]
pwm.set_output_pin(
pwm::Channel::C0,
&p0.p0_02.into_push_pull_output(gpio::Level::High).degrade(),
);
#[cfg(feature = "52840")]
pwm.set_output_pin(
pwm::Channel::C0,
&p0.p0_13.into_push_pull_output(gpio::Level::High).degrade(),
);

pwm.set_period(500u32.hz());

#[cfg(feature = "9160")]
let mut timer = Timer::new(p.TIMER0_NS);
#[cfg(feature = "52840")]
let mut timer = Timer::new(p.TIMER0);

rprintln!("PWM Blinky demo starting");
loop {
pwm.set_duty_on_common(pwm.get_max_duty());
delay(&mut timer, 250_000); // 250ms
pwm.set_duty_on_common(0);
delay(&mut timer, 1_000_000); // 1s
}
}

fn delay<T>(timer: &mut Timer<T>, cycles: u32)
where
T: timer::Instance,
{
timer.start(cycles);
let _ = block!(timer.wait());
}
9 changes: 8 additions & 1 deletion examples/pwm-demo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,15 @@ edition = "2018"
cortex-m = "0.6.2"
cortex-m-rtic = "0.5.3"
rtt-target = {version = "0.2.0", features = ["cortex-m"] }
nrf52840-hal = { features = ["rt"], path = "../../nrf52840-hal" }

[dependencies.embedded-hal]
version = "0.2.3"
features = ["unproven"]

[dependencies.nrf52840-hal]
features = ["rt"]
path = "../../nrf52840-hal"
optional = true

[features]
52840 = ["nrf52840-hal"]
2 changes: 1 addition & 1 deletion nrf-hal-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub mod ieee802154;
pub mod lpcomp;
#[cfg(not(feature = "9160"))]
pub mod ppi;
#[cfg(not(any(feature = "51", feature = "52832", feature = "9160")))]
#[cfg(not(any(feature = "51", feature = "52832")))]
pub mod pwm;
#[cfg(not(any(feature = "51", feature = "9160")))]
pub mod qdec;
Expand Down
Loading

0 comments on commit 411e000

Please sign in to comment.