Skip to content

Commit ed5d87d

Browse files
bors[bot]huntc
andauthored
Merge #311
311: Enables PWM for the nRF9160 r=jonathanpallant a=huntc Without it, we can't have blinky on the Thingy:91 as its RGB LEDs require PWM! This PR assumes just unsecured peripheral access for now. I've also included a new `pwm-blinky-demo` and ensure that this and the original `pwm-demo` are included with the `xtask` tests. Additionally, the `pwm-blinky-demo` is tested for the nRF9160 target. Tested on an nRF9160-dk via the probe-rs/embed tool. The result from `cargo embed`: ![image](https://user-images.githubusercontent.com/694893/117934382-f9ccdc80-b345-11eb-9e86-f77e57c81f08.png) cc @kalkyl Co-authored-by: huntc <[email protected]>
2 parents dbd46e4 + e2cc3c7 commit ed5d87d

File tree

10 files changed

+318
-15
lines changed

10 files changed

+318
-15
lines changed

.vscode/settings.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"rust-analyzer.cargo.features": [
3+
"52840"
4+
]
5+
}

examples/pwm-blinky-demo/Cargo.toml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
[package]
2+
name = "pwm-blinky-demo"
3+
version = "0.1.0"
4+
authors = ["Christopher Hunt <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
cortex-m = "0.6.2"
11+
cortex-m-rt = "0.6.12"
12+
rtt-target = {version = "0.2.0", features = ["cortex-m"] }
13+
nb = "1.0.0"
14+
15+
[dependencies.embedded-hal]
16+
version = "0.2.3"
17+
features = ["unproven"]
18+
19+
[dependencies.nrf9160-hal]
20+
features = ["rt"]
21+
path = "../../nrf9160-hal"
22+
optional = true
23+
24+
[dependencies.nrf52840-hal]
25+
features = ["rt"]
26+
path = "../../nrf52840-hal"
27+
optional = true
28+
29+
[features]
30+
9160 = ["nrf9160-hal"]
31+
52840 = ["nrf52840-hal"]

examples/pwm-blinky-demo/Embed.toml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
[default.probe]
2+
# USB vendor ID
3+
# usb_vid = "1337"
4+
# USB product ID
5+
# usb_pid = "1337"
6+
# Serial number
7+
# serial = "12345678"
8+
# The protocol to be used for communicating with the target.
9+
protocol = "Swd"
10+
# The speed in kHz of the data link to the target.
11+
# speed = 1337
12+
13+
[default.flashing]
14+
# Whether or not the target should be flashed.
15+
enabled = true
16+
# Whether or not the target should be halted after reset.
17+
# DEPRECATED, moved to reset section
18+
halt_afterwards = false
19+
# Whether or not bytes erased but not rewritten with data from the ELF
20+
# should be restored with their contents before erasing.
21+
restore_unwritten_bytes = false
22+
# The path where an SVG of the assembled flash layout should be written to.
23+
# flash_layout_output_path = "out.svg"
24+
25+
[default.reset]
26+
# Whether or not the target should be reset.
27+
# When flashing is enabled as well, the target will be reset after flashing.
28+
enabled = true
29+
# Whether or not the target should be halted after reset.
30+
halt_afterwards = false
31+
32+
[default.general]
33+
# The chip name of the chip to be debugged.
34+
chip = "nRF52840_xxAA"
35+
# A list of chip descriptions to be loaded during runtime.
36+
chip_descriptions = []
37+
# The default log level to be used. Possible values are one of:
38+
# "OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"
39+
log_level = "WARN"
40+
41+
[default.rtt]
42+
# Whether or not an RTTUI should be opened after flashing.
43+
# This is exclusive and cannot be used with GDB at the moment.
44+
enabled = true
45+
# A list of channel associations to be displayed. If left empty, all channels are displayed.
46+
channels = [
47+
# { up = 0, down = 0, name = "name", format = "String" }
48+
]
49+
# The duration in ms for which the logger should retry to attach to RTT.
50+
timeout = 3000
51+
# Whether timestamps in the RTTUI are enabled
52+
show_timestamps = true
53+
# Whether to save rtt history buffer on exit.
54+
log_enabled = false
55+
# Where to save rtt history buffer relative to manifest path.
56+
log_path = "./logs"
57+
58+
[default.gdb]
59+
# Whether or not a GDB server should be opened after flashing.
60+
# This is exclusive and cannot be used with RTT at the moment.
61+
enabled = false
62+
# The connection string in host:port format wher the GDB server will open a socket.
63+
# gdb_connection_string

examples/pwm-blinky-demo/build.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//! This build script copies the `memory.x` file from the crate root into
2+
//! a directory where the linker can always find it at build time.
3+
//! For many projects this is optional, as the linker always searches the
4+
//! project root directory -- wherever `Cargo.toml` is. However, if you
5+
//! are using a workspace or have a more complicated build setup, this
6+
//! build script becomes required. Additionally, by requesting that
7+
//! Cargo re-run the build script whenever `memory.x` is changed,
8+
//! updating `memory.x` ensures a rebuild of the application with the
9+
//! new memory settings.
10+
11+
fn main() {
12+
// We only need the memory.x file for the nRF9160 as our program
13+
// must then reside in a location where unsecure programs need to be.
14+
#[cfg(feature = "9160")]
15+
{
16+
use std::env;
17+
use std::fs::File;
18+
use std::io::Write;
19+
use std::path::PathBuf;
20+
21+
// Put `memory.x` in our output directory and ensure it's
22+
// on the linker search path.
23+
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
24+
File::create(out.join("memory.x"))
25+
.unwrap()
26+
.write_all(include_bytes!("memory.x"))
27+
.unwrap();
28+
println!("cargo:rustc-link-search={}", out.display());
29+
30+
// By default, Cargo will re-run a build script whenever
31+
// any file in the project changes. By specifying `memory.x`
32+
// here, we ensure the build script is only re-run when
33+
// `memory.x` is changed.
34+
println!("cargo:rerun-if-changed=memory.x");
35+
}
36+
}

examples/pwm-blinky-demo/memory.x

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
MEMORY
2+
{
3+
/* NOTE 1 K = 1 KiBi = 1024 bytes */
4+
FLASH : ORIGIN = 0x00050000, LENGTH = 768K
5+
RAM : ORIGIN = 0x20020000, LENGTH = 128K
6+
}
7+
8+
/* This is where the call stack will be allocated. */
9+
/* The stack is of the full descending type. */
10+
/* You may want to use this variable to locate the call stack and static
11+
variables in different memory regions. Below is shown the default value */
12+
/* _stack_start = ORIGIN(RAM) + LENGTH(RAM); */
13+
14+
/* You can use this symbol to customize the location of the .text section */
15+
/* If omitted the .text section will be placed right after the .vector_table
16+
section */
17+
/* This is required only on microcontrollers that store some configuration right
18+
after the vector table */
19+
/* _stext = ORIGIN(FLASH) + 0x400; */
20+
21+
/* Example of putting non-initialized variables into custom RAM locations. */
22+
/* This assumes you have defined a region RAM2 above, and in the Rust
23+
sources added the attribute `#[link_section = ".ram2bss"]` to the data
24+
you want to place there. */
25+
/* Note that the section will not be zero-initialized by the runtime! */
26+
/* SECTIONS {
27+
.ram2bss (NOLOAD) : ALIGN(4) {
28+
*(.ram2bss);
29+
. = ALIGN(4);
30+
} > RAM2
31+
} INSERT AFTER .bss;
32+
*/

examples/pwm-blinky-demo/src/main.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#![no_main]
2+
#![no_std]
3+
4+
use hal::{gpio, prelude::*, pwm, pwm::Pwm, timer, timer::Timer};
5+
use nb::block;
6+
#[cfg(feature = "52840")]
7+
use nrf52840_hal as hal;
8+
#[cfg(feature = "9160")]
9+
use nrf9160_hal as hal;
10+
use rtt_target::{rprintln, rtt_init_print};
11+
12+
#[panic_handler] // panicking behavior
13+
fn panic(_: &core::panic::PanicInfo) -> ! {
14+
loop {
15+
cortex_m::asm::bkpt();
16+
}
17+
}
18+
19+
#[cortex_m_rt::entry]
20+
fn main() -> ! {
21+
rtt_init_print!();
22+
23+
let p = hal::pac::Peripherals::take().unwrap();
24+
25+
let (pwm, mut timer) = init_device(p);
26+
27+
pwm.set_period(500u32.hz());
28+
29+
rprintln!("PWM Blinky demo starting");
30+
loop {
31+
pwm.set_duty_on_common(pwm.get_max_duty());
32+
delay(&mut timer, 250_000); // 250ms
33+
pwm.set_duty_on_common(0);
34+
delay(&mut timer, 1_000_000); // 1s
35+
}
36+
}
37+
38+
#[cfg(feature = "9160")]
39+
fn init_device(p: hal::pac::Peripherals) -> (Pwm<hal::pac::PWM0_NS>, Timer<hal::pac::TIMER0_NS>) {
40+
let p0 = gpio::p0::Parts::new(p.P0_NS);
41+
42+
let pwm = Pwm::new(p.PWM0_NS);
43+
pwm.set_output_pin(
44+
pwm::Channel::C0,
45+
&p0.p0_02.into_push_pull_output(gpio::Level::High).degrade(),
46+
);
47+
48+
let timer = Timer::new(p.TIMER0_NS);
49+
50+
(pwm, timer)
51+
}
52+
53+
#[cfg(feature = "52840")]
54+
fn init_device(p: hal::pac::Peripherals) -> (Pwm<hal::pac::PWM0>, Timer<hal::pac::TIMER0>) {
55+
let p0 = gpio::p0::Parts::new(p.P0);
56+
57+
let pwm = Pwm::new(p.PWM0);
58+
pwm.set_output_pin(
59+
pwm::Channel::C0,
60+
&p0.p0_13.into_push_pull_output(gpio::Level::High).degrade(),
61+
);
62+
63+
let timer = Timer::new(p.TIMER0);
64+
65+
(pwm, timer)
66+
}
67+
68+
fn delay<T>(timer: &mut Timer<T>, cycles: u32)
69+
where
70+
T: timer::Instance,
71+
{
72+
timer.start(cycles);
73+
let _ = block!(timer.wait());
74+
}

examples/pwm-demo/Cargo.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,15 @@ edition = "2018"
1010
cortex-m = "0.6.2"
1111
cortex-m-rtic = "0.5.3"
1212
rtt-target = {version = "0.2.0", features = ["cortex-m"] }
13-
nrf52840-hal = { features = ["rt"], path = "../../nrf52840-hal" }
1413

1514
[dependencies.embedded-hal]
1615
version = "0.2.3"
1716
features = ["unproven"]
17+
18+
[dependencies.nrf52840-hal]
19+
features = ["rt"]
20+
path = "../../nrf52840-hal"
21+
optional = true
22+
23+
[features]
24+
52840 = ["nrf52840-hal"]

nrf-hal-common/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub mod ieee802154;
4949
pub mod lpcomp;
5050
#[cfg(not(feature = "9160"))]
5151
pub mod ppi;
52-
#[cfg(not(any(feature = "51", feature = "52832", feature = "9160")))]
52+
#[cfg(not(any(feature = "51", feature = "52832")))]
5353
pub mod pwm;
5454
#[cfg(not(any(feature = "51", feature = "9160")))]
5555
pub mod qdec;

0 commit comments

Comments
 (0)