Skip to content

Commit e2cc3c7

Browse files
committed
Enables PWM for the nRF9160
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.
1 parent dbd46e4 commit e2cc3c7

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)