Skip to content

Commit 1ceb222

Browse files
committed
Upgrade nrf51-hal to 0.12.1
This is a large change down to the nrf51-hal API changing significantly between 0.7 and 0.10. Below I cover the big changes from the perspective of what has changed in the nrf51-hal API first as that is where I started. The library =========== `nrf51_hal::timer` ------------------ This is the biggest change. The new timer interface is significantly stripped back so all of the interrupt and compare config in `microbit::display::timer` now have to be done directly on the PAC. A gotcha I hit here was that on the nrf51 all but the first timer seem to only be 16 bit. While the implementation has changed significantly here the public interface has not changed. `nrf51_hal::gpio` ----------------- How the pins are accessed and how they are named has changed however at the end of the day, they're still GPIO pins so it's not too difficult. `nrf51_hal::twi` ---------------- The name has changed, arguments are slightly different and you have to pass the frequency explicitly now. Other than that it seems the same. `nrf51_hal::uart` ----------------- The name has changed, arguments are slightly different and you have to pass whether the parity bit is included explicitly now. There doesn't seem to be a way to split it into separate read and write parts but for the examples that didn't seem to be a problem. The examples ============ I have updated all examples to compile and tried to run them however not all of them work. Fully working ------------- - `gpio_direct_blinky.rs` - `gpio_hal_blinky.rs` - `gpio_hal_ledbutton.rs` - `gpio_hal_printbuttons.rs` - `led_blocking.rs` - `led_nonblocking.rs` (it's a bit flickery but it was before, I'll look at that separately - `led_rtfm.rs` - `rng_direct_printrngserial.rs` - `serial_direct_echo.rs` - `serial_direct_helloworld.rs` - `serial_hal_blocking_echo.rs` Not working ----------- None of these work for me on this branch or on master. I would appreciate someone who has them working on master testing them for me. - `rng_hal_printrandserial.rs`: crashes on line 84 at `rng.next_u32()`. - `gpio_hal_receivedcf77.rs`: just get a zero timestamp. I believe all these are failing because I have v1.5 see #9 - `i2c_direct_printmagserial.rs` - `i2c_hal_printmagserial.rs` - `i2c_haldriver_printmagserial.rs`
1 parent db5eed0 commit 1ceb222

22 files changed

+369
-324
lines changed

Cargo.toml

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,42 @@ version = "0.8.0"
2323
cortex-m = "0.6.1"
2424
cortex-m-rt = "0.6.10"
2525
nb = "0.1.2"
26-
nrf51-hal = "0.7.0"
26+
nrf51-hal = "0.12.1"
2727
tiny-led-matrix = "1.0.1"
28+
embedded-hal = "0.2.4"
29+
30+
defmt = "0.1.3"
2831

2932
[dev-dependencies]
30-
cortex-m-semihosting = "0.3.5"
3133
numtoa = "0.2.3"
3234
dcf77 = "0.1.0"
3335
mag3110 = "0.1.4"
3436
panic-halt = "0.2.0"
35-
cortex-m-rtfm = "0.5"
37+
cortex-m-rtic = "0.5"
38+
defmt-rtt = "0.1.0"
39+
panic-probe = { version = "0.1.0", features = ["print-defmt"] }
40+
41+
[features]
42+
# set logging levels here
43+
default = [
44+
"defmt-default",
45+
# "dependency-a/defmt-trace",
46+
]
47+
48+
# do NOT modify these features
49+
defmt-default = []
50+
defmt-trace = []
51+
defmt-debug = []
52+
defmt-info = []
53+
defmt-warn = []
54+
defmt-error = []
3655

3756
[dev-dependencies.rand]
3857
default-features = false
39-
version = "0.7.2"
58+
version = "0.8.3"
4059

4160
[dev-dependencies.rand_chacha]
42-
version = "0.2.1"
61+
version = "0.3.0"
4362
default-features = false
4463

4564
[profile.dev]

examples/gpio_direct_blinky.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn main() -> ! {
2323
p.GPIO.out.write(|w| unsafe { w.bits(0) });
2424
}
2525

26-
for _ in 0..1_000_000 {
26+
for _ in 0..50_000 {
2727
cortex_m::asm::nop();
2828
}
2929
}

examples/gpio_hal_blinky.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,28 @@
33

44
use panic_halt as _;
55

6-
use microbit::hal::delay::Delay;
7-
use microbit::hal::prelude::*;
8-
96
use cortex_m_rt::entry;
7+
use embedded_hal::{blocking::delay::DelayMs, digital::v2::OutputPin};
8+
use microbit::hal::{
9+
gpio::{p0, Level},
10+
timer::Timer,
11+
};
1012

1113
#[entry]
1214
fn main() -> ! {
1315
if let Some(p) = microbit::Peripherals::take() {
14-
let gpio = p.GPIO.split();
15-
let mut delay = Delay::new(p.TIMER0);
16-
let mut led = gpio.pin13.into_push_pull_output();
17-
let _ = gpio.pin4.into_push_pull_output();
16+
/* Split GPIO pins */
17+
let gpio = p0::Parts::new(p.GPIO);
18+
19+
let mut timer = Timer::new(p.TIMER0);
20+
let mut led = gpio.p0_13.into_push_pull_output(Level::Low);
21+
let _ = gpio.p0_04.into_push_pull_output(Level::Low);
1822

1923
loop {
2024
let _ = led.set_low();
21-
delay.delay_ms(1_000_u16);
25+
timer.delay_ms(1_000_u16);
2226
let _ = led.set_high();
23-
delay.delay_ms(1_000_u16);
27+
timer.delay_ms(1_000_u16);
2428
}
2529
}
2630

examples/gpio_hal_ledbutton.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,24 @@
44
use panic_halt as _;
55

66
use cortex_m_rt::entry;
7-
use microbit::hal::prelude::*;
7+
use microbit::hal::{self, gpio::Level, prelude::*};
88

99
#[entry]
1010
fn main() -> ! {
1111
if let Some(p) = microbit::Peripherals::take() {
1212
// Split GPIO pins
13-
let gpio = p.GPIO.split();
13+
let gpio = hal::gpio::p0::Parts::new(p.GPIO);
1414

1515
// Set row of LED matrix to permanent high
16-
let _ = gpio.pin13.into_push_pull_output().set_high();
16+
let _ = gpio.p0_13.into_push_pull_output(Level::Low).set_high();
1717

1818
// Set 2 columns to output to control LED states
19-
let mut led1 = gpio.pin4.into_push_pull_output();
20-
let mut led2 = gpio.pin6.into_push_pull_output();
19+
let mut led1 = gpio.p0_04.into_push_pull_output(Level::Low);
20+
let mut led2 = gpio.p0_06.into_push_pull_output(Level::Low);
2121

2222
// Configure button GPIOs as inputs
23-
let button_a = gpio.pin17.into_floating_input();
24-
let button_b = gpio.pin26.into_floating_input();
23+
let button_a = gpio.p0_17.into_floating_input();
24+
let button_b = gpio.p0_26.into_floating_input();
2525

2626
loop {
2727
if let Ok(true) = button_a.is_high() {

examples/gpio_hal_printbuttons.rs

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,39 @@
33

44
use panic_halt as _;
55

6-
use microbit::hal::nrf51::{interrupt, GPIOTE, UART0};
7-
use microbit::hal::prelude::*;
8-
use microbit::hal::serial;
9-
use microbit::hal::serial::BAUD115200;
10-
use microbit::NVIC;
6+
use core::{cell::RefCell, fmt::Write, ops::DerefMut};
117

128
use cortex_m::interrupt::Mutex;
139
use cortex_m_rt::entry;
10+
use microbit::{
11+
hal::{
12+
self,
13+
uart::{Baudrate, Uart},
14+
},
15+
pac::{self, interrupt},
16+
};
1417

15-
use core::cell::RefCell;
16-
use core::fmt::Write;
17-
use core::ops::DerefMut;
18-
19-
static GPIO: Mutex<RefCell<Option<GPIOTE>>> = Mutex::new(RefCell::new(None));
20-
static TX: Mutex<RefCell<Option<serial::Tx<UART0>>>> = Mutex::new(RefCell::new(None));
18+
static GPIO: Mutex<RefCell<Option<pac::GPIOTE>>> = Mutex::new(RefCell::new(None));
19+
static TX: Mutex<RefCell<Option<Uart<pac::UART0>>>> = Mutex::new(RefCell::new(None));
2120

2221
#[entry]
2322
fn main() -> ! {
2423
if let Some(p) = microbit::Peripherals::take() {
2524
cortex_m::interrupt::free(move |cs| {
2625
/* Enable external GPIO interrupts */
2726
unsafe {
28-
NVIC::unmask(microbit::Interrupt::GPIOTE);
27+
pac::NVIC::unmask(pac::Interrupt::GPIOTE);
2928
}
30-
microbit::NVIC::unpend(microbit::Interrupt::GPIOTE);
29+
pac::NVIC::unpend(pac::Interrupt::GPIOTE);
3130

3231
/* Split GPIO pins */
33-
let gpio = p.GPIO.split();
32+
let gpio = hal::gpio::p0::Parts::new(p.GPIO);
3433

3534
/* Configure button GPIOs as inputs */
36-
let _ = gpio.pin26.into_floating_input();
37-
let _ = gpio.pin17.into_floating_input();
35+
let _ = gpio.p0_26.into_floating_input();
36+
let _ = gpio.p0_17.into_floating_input();
3837

38+
// TODO: check for safe wrappers
3939
/* Set up GPIO 17 (button A) to generate an interrupt when pulled down */
4040
p.GPIOTE.config[0]
4141
.write(|w| unsafe { w.mode().event().psel().bits(17).polarity().hi_to_lo() });
@@ -50,18 +50,14 @@ fn main() -> ! {
5050

5151
*GPIO.borrow(cs).borrow_mut() = Some(p.GPIOTE);
5252

53-
/* Configure RX and TX pins accordingly */
54-
let tx = gpio.pin24.into_push_pull_output().into();
55-
let rx = gpio.pin25.into_floating_input().into();
56-
57-
/* Set up serial port using the prepared pins */
58-
let (mut tx, _) = serial::Serial::uart0(p.UART0, tx, rx, BAUD115200).split();
53+
/* Initialise serial port on the micro:bit */
54+
let mut serial = microbit::serial_port!(gpio, p.UART0, Baudrate::BAUD115200);
5955

6056
let _ = write!(
61-
tx,
57+
serial,
6258
"\n\rWelcome to the buttons demo. Press buttons A and/or B for some action.\n\r",
6359
);
64-
*TX.borrow(cs).borrow_mut() = Some(tx);
60+
*TX.borrow(cs).borrow_mut() = Some(serial);
6561
});
6662
}
6763

examples/gpio_hal_receivedcf77.rs

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,31 @@
33

44
use panic_halt as _;
55

6-
use dcf77::{DCF77Time, SimpleDCF77Decoder};
7-
8-
use microbit::hal::gpio::gpio::PIN16;
9-
use microbit::hal::gpio::{Floating, Input};
10-
use microbit::hal::nrf51::{interrupt, RTC0, UART0};
11-
use microbit::hal::prelude::*;
12-
use microbit::hal::serial;
13-
use microbit::hal::serial::BAUD115200;
14-
use microbit::NVIC;
6+
use core::{cell::RefCell, fmt::Write, ops::DerefMut};
157

168
use cortex_m::interrupt::Mutex;
17-
189
use cortex_m_rt::entry;
19-
20-
use core::cell::RefCell;
21-
use core::fmt::Write;
22-
use core::ops::DerefMut;
10+
use dcf77::{DCF77Time, SimpleDCF77Decoder};
11+
use microbit::{
12+
hal::{
13+
self,
14+
gpio::{p0::P0_16, Floating, Input},
15+
prelude::*,
16+
uart::{Baudrate, Uart},
17+
},
18+
pac::{self, interrupt},
19+
};
2320

2421
static DCF: Mutex<RefCell<Option<SimpleDCF77Decoder>>> = Mutex::new(RefCell::new(None));
25-
static DCFPIN: Mutex<RefCell<Option<PIN16<Input<Floating>>>>> = Mutex::new(RefCell::new(None));
26-
static RTC: Mutex<RefCell<Option<RTC0>>> = Mutex::new(RefCell::new(None));
27-
static TX: Mutex<RefCell<Option<serial::Tx<UART0>>>> = Mutex::new(RefCell::new(None));
22+
static DCFPIN: Mutex<RefCell<Option<P0_16<Input<Floating>>>>> = Mutex::new(RefCell::new(None));
23+
static RTC: Mutex<RefCell<Option<pac::RTC0>>> = Mutex::new(RefCell::new(None));
24+
static TX: Mutex<RefCell<Option<Uart<pac::UART0>>>> = Mutex::new(RefCell::new(None));
2825

2926
#[entry]
3027
fn main() -> ! {
3128
if let Some(p) = microbit::Peripherals::take() {
3229
cortex_m::interrupt::free(move |cs| {
30+
// TODO: check if there are safe wrappers now
3331
p.CLOCK.tasks_lfclkstart.write(|w| unsafe { w.bits(1) });
3432

3533
while p.CLOCK.events_lfclkstarted.read().bits() == 0 {}
@@ -38,36 +36,34 @@ fn main() -> ! {
3836
p.CLOCK.events_lfclkstarted.write(|w| unsafe { w.bits(0) });
3937

4038
/* Split GPIO pins */
41-
let gpio = p.GPIO.split();
39+
let gpio = hal::gpio::p0::Parts::new(p.GPIO);
4240

4341
/* Configure DCF77 receiver GPIO as input */
44-
let pin = gpio.pin16.into_floating_input();
45-
46-
/* Configure RX and TX pins accordingly */
47-
let tx = gpio.pin24.into_push_pull_output().into();
48-
let rx = gpio.pin25.into_floating_input().into();
42+
let pin = gpio.p0_16.into_floating_input();
4943

50-
/* Set up serial port using the prepared pins */
51-
let (mut tx, _) = serial::Serial::uart0(p.UART0, tx, rx, BAUD115200).split();
44+
/* Initialise serial port on the micro:bit */
45+
let mut serial = microbit::serial_port!(gpio, p.UART0, Baudrate::BAUD115200);
5246

53-
let _ = tx.write_str("\n\rWelcome to the DCF77 decoder demo.\n\r");
54-
let _ = tx.write_str("If you are within reach of a DCF77 radio clock signal and have a DCF77 receiver connected\n\r");
55-
let _ = tx.write_str("you should see a stream of 59 bits appear in a line, followed by thd decoded date and time.\n\r");
56-
let _ = tx.write_str("If not, please check your hardware, location and reception.\n\r");
47+
let _ = serial.write_str("\n\rWelcome to the DCF77 decoder demo.\n\r");
48+
let _ = serial.write_str("If you are within reach of a DCF77 radio clock signal and have a DCF77 receiver connected\n\r");
49+
let _ = serial.write_str("you should see a stream of 59 bits appear in a line, followed by thd decoded date and time.\n\r");
50+
let _ =
51+
serial.write_str("If not, please check your hardware, location and reception.\n\r");
52+
// TODO: check for safe wrappers
5753
p.RTC0.prescaler.write(|w| unsafe { w.bits(327) });
5854
p.RTC0.evtenset.write(|w| w.tick().set_bit());
5955
p.RTC0.intenset.write(|w| w.tick().set_bit());
6056
p.RTC0.tasks_start.write(|w| unsafe { w.bits(1) });
6157

6258
*RTC.borrow(cs).borrow_mut() = Some(p.RTC0);
63-
*TX.borrow(cs).borrow_mut() = Some(tx);
59+
*TX.borrow(cs).borrow_mut() = Some(serial);
6460
*DCFPIN.borrow(cs).borrow_mut() = Some(pin);
6561
*DCF.borrow(cs).borrow_mut() = Some(SimpleDCF77Decoder::new());
6662

6763
unsafe {
68-
NVIC::unmask(microbit::Interrupt::RTC0);
64+
pac::NVIC::unmask(pac::Interrupt::RTC0);
6965
}
70-
microbit::NVIC::unpend(microbit::Interrupt::RTC0);
66+
pac::NVIC::unpend(pac::Interrupt::RTC0);
7167
});
7268
}
7369

examples/i2c_direct_printmagserial.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,15 @@
33

44
use panic_halt as _;
55

6-
use microbit::hal::nrf51::*;
7-
use microbit::hal::nrf51::{interrupt, UART0};
8-
use microbit::NVIC;
6+
use core::{cell::RefCell, fmt::Write};
97

108
use cortex_m::interrupt::Mutex;
11-
12-
use core::cell::RefCell;
13-
use core::fmt::Write;
149
use cortex_m_rt::entry;
10+
use microbit::pac::{self, interrupt};
1511

16-
static RTC: Mutex<RefCell<Option<RTC0>>> = Mutex::new(RefCell::new(None));
17-
static UART: Mutex<RefCell<Option<UART0>>> = Mutex::new(RefCell::new(None));
18-
static TWI: Mutex<RefCell<Option<TWI1>>> = Mutex::new(RefCell::new(None));
12+
static RTC: Mutex<RefCell<Option<pac::RTC0>>> = Mutex::new(RefCell::new(None));
13+
static UART: Mutex<RefCell<Option<pac::UART0>>> = Mutex::new(RefCell::new(None));
14+
static TWI: Mutex<RefCell<Option<pac::TWI1>>> = Mutex::new(RefCell::new(None));
1915

2016
#[entry]
2117
fn main() -> ! {
@@ -93,9 +89,9 @@ fn main() -> ! {
9389
});
9490

9591
unsafe {
96-
NVIC::unmask(microbit::Interrupt::RTC0);
92+
pac::NVIC::unmask(pac::Interrupt::RTC0);
9793
}
98-
microbit::NVIC::unpend(microbit::Interrupt::RTC0);
94+
pac::NVIC::unpend(pac::Interrupt::RTC0);
9995
}
10096

10197
loop {
@@ -166,7 +162,7 @@ fn RTC0() {
166162
}
167163
}
168164

169-
pub struct UART0Buffer<'a>(pub &'a UART0);
165+
pub struct UART0Buffer<'a>(pub &'a pac::UART0);
170166

171167
impl<'a> core::fmt::Write for UART0Buffer<'a> {
172168
fn write_str(&mut self, s: &str) -> core::fmt::Result {

0 commit comments

Comments
 (0)