Skip to content

Commit 7bbfc17

Browse files
committed
Add magnetometer example
Uses LSM303AGR driver from eldruin mentioned here #27 (comment) This example works on the micro:bit V1.5 and V2. The micro:bit V1.3 uses a different magnetometer.
1 parent 15f2e3e commit 7bbfc17

File tree

7 files changed

+235
-19
lines changed

7 files changed

+235
-19
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1919
- Add BLE Beacon demo.
2020
- Add a simple speaker demo for micro:bit V2.
2121
- Add Board struct following the pattern used in other nrf board support crates.
22+
- Add magnetometer example.
2223

2324
## [0.10.1] - 2021-05-25
2425

examples/magnetometer/Cargo.toml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
[package]
2+
name = "magnetometer"
3+
version = "0.1.0"
4+
edition = "2018"
5+
6+
[dependencies]
7+
cortex-m-rt = "0.6.12"
8+
panic-halt = "0.2.0"
9+
defmt-rtt = "0.2.0"
10+
defmt = "0.2.0"
11+
lsm303agr = "0.2.0"
12+
13+
[dependencies.microbit]
14+
path = "../../microbit"
15+
optional = true
16+
17+
[dependencies.microbit-v2]
18+
path = "../../microbit-v2"
19+
optional = true
20+
21+
[features]
22+
v1 = ["microbit"]
23+
v2 = ["microbit-v2"]
24+
25+
default = [
26+
"defmt-default",
27+
]
28+
29+
# do NOT modify these features
30+
defmt-default = []
31+
defmt-trace = []
32+
defmt-debug = []
33+
defmt-info = []
34+
defmt-warn = []
35+
defmt-error = []

examples/magnetometer/src/main.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#![no_std]
2+
#![no_main]
3+
4+
use defmt_rtt as _;
5+
use panic_halt as _;
6+
7+
use cortex_m_rt::entry;
8+
9+
use microbit::hal::{prelude::*, Timer};
10+
11+
#[cfg(feature = "v1")]
12+
use microbit::{
13+
hal::twi,
14+
pac::{twi0::frequency::FREQUENCY_A, TWI0},
15+
};
16+
#[cfg(feature = "v2")]
17+
use microbit::{
18+
hal::twim,
19+
pac::{twim0::frequency::FREQUENCY_A, TWIM0},
20+
};
21+
22+
use lsm303agr::{
23+
interface::I2cInterface, mode::MagOneShot, AccelMode, AccelOutputDataRate, Lsm303agr,
24+
};
25+
26+
#[entry]
27+
fn main() -> ! {
28+
let board = microbit::Board::take().unwrap();
29+
let mut timer = Timer::new(board.TIMER0);
30+
31+
#[cfg(feature = "v1")]
32+
let i2c = { twi::Twi::new(board.TWI0, board.i2c.into(), FREQUENCY_A::K100) };
33+
34+
#[cfg(feature = "v2")]
35+
let i2c = { twim::Twim::new(board.TWIM0, board.i2c_internal.into(), FREQUENCY_A::K100) };
36+
37+
let mut sensor = Lsm303agr::new_with_i2c(i2c);
38+
match sensor.accelerometer_id() {
39+
Ok(0x33u8) => {}
40+
_ => defmt::panic!("accelerometer not found"),
41+
}
42+
sensor.init().unwrap();
43+
sensor.set_accel_odr(AccelOutputDataRate::Hz50).unwrap();
44+
45+
defmt::info!("normal mode");
46+
sensor.set_accel_mode(AccelMode::Normal).unwrap();
47+
timer.delay_ms(1000_u32);
48+
get_data(&mut sensor);
49+
50+
defmt::info!("low power mode");
51+
sensor.set_accel_mode(AccelMode::LowPower).unwrap();
52+
timer.delay_ms(1000_u32);
53+
get_data(&mut sensor);
54+
55+
defmt::info!("high resolution mode");
56+
sensor.set_accel_mode(AccelMode::HighResolution).unwrap();
57+
timer.delay_ms(1000_u32);
58+
get_data(&mut sensor);
59+
60+
loop {
61+
timer.delay_ms(100_u32);
62+
get_data(&mut sensor);
63+
}
64+
}
65+
66+
#[cfg(feature = "v1")]
67+
type Sensor = Lsm303agr<I2cInterface<twi::Twi<TWI0>>, MagOneShot>;
68+
69+
#[cfg(feature = "v2")]
70+
type Sensor = Lsm303agr<I2cInterface<twim::Twim<TWIM0>>, MagOneShot>;
71+
72+
fn get_data(sensor: &mut Sensor) {
73+
loop {
74+
if sensor.accel_status().unwrap().xyz_new_data {
75+
let data = sensor.accel_data().unwrap();
76+
defmt::info!("x {} y {} z {}", data.x, data.y, data.z);
77+
return;
78+
}
79+
}
80+
}

microbit-common/src/v1/board.rs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
use super::gpio::{DisplayPins, BTN_A, BTN_B};
1+
use super::gpio::{DisplayPins, BTN_A, BTN_B, SCL, SDA};
22
use crate::{
3-
hal::gpio::{p0, Disconnected, Level},
3+
hal::{
4+
gpio::{p0, Disconnected, Level},
5+
twi,
6+
},
47
pac,
58
};
69

@@ -16,6 +19,9 @@ pub struct Board {
1619
/// buttons
1720
pub buttons: Buttons,
1821

22+
/// I2C shared internal and external bus pins
23+
pub i2c: I2CPins,
24+
1925
/// Core peripheral: Cache and branch predictor maintenance operations
2026
pub CBP: pac::CBP,
2127

@@ -75,6 +81,9 @@ pub struct Board {
7581

7682
/// nRF51 peripheral: TIMER2
7783
pub TIMER2: pac::TIMER2,
84+
85+
/// nRF51 peripheral: TWI0
86+
pub TWI0: pac::TWI0,
7887
}
7988

8089
impl Board {
@@ -93,7 +102,6 @@ impl Board {
93102
let p0parts = p0::Parts::new(p.GPIO);
94103
Self {
95104
pins: Pins {
96-
p0_00: p0parts.p0_00,
97105
p0_01: p0parts.p0_01,
98106
p0_02: p0parts.p0_02,
99107
p0_03: p0parts.p0_03,
@@ -109,7 +117,6 @@ impl Board {
109117
p0_27: p0parts.p0_27,
110118
p0_28: p0parts.p0_28,
111119
p0_29: p0parts.p0_29,
112-
p0_30: p0parts.p0_30,
113120
},
114121
display_pins: DisplayPins {
115122
row1: p0parts.p0_13.into_push_pull_output(Level::High),
@@ -129,6 +136,10 @@ impl Board {
129136
button_a: p0parts.p0_17.into_floating_input(),
130137
button_b: p0parts.p0_26.into_floating_input(),
131138
},
139+
i2c: I2CPins {
140+
scl: p0parts.p0_00.into_floating_input(),
141+
sda: p0parts.p0_30.into_floating_input(),
142+
},
132143

133144
// Core peripherals
134145
CBP: cp.CBP,
@@ -153,14 +164,15 @@ impl Board {
153164
TIMER0: p.TIMER0,
154165
TIMER1: p.TIMER1,
155166
TIMER2: p.TIMER2,
167+
TWI0: p.TWI0,
156168
}
157169
}
158170
}
159171

160172
/// Unused GPIO pins
161173
#[allow(missing_docs)]
162174
pub struct Pins {
163-
pub p0_00: p0::P0_00<Disconnected>,
175+
// pub p0_00: p0::P0_00<Disconnected>, // SCL
164176
pub p0_01: p0::P0_01<Disconnected>,
165177
pub p0_02: p0::P0_02<Disconnected>,
166178
pub p0_03: p0::P0_03<Disconnected>,
@@ -190,7 +202,7 @@ pub struct Pins {
190202
pub p0_27: p0::P0_27<Disconnected>,
191203
pub p0_28: p0::P0_28<Disconnected>,
192204
pub p0_29: p0::P0_29<Disconnected>,
193-
pub p0_30: p0::P0_30<Disconnected>,
205+
// pub p0_30: p0::P0_30<Disconnected>, // SDA
194206
}
195207

196208
/// Board buttons
@@ -200,3 +212,18 @@ pub struct Buttons {
200212
/// Right hand side button
201213
pub button_b: BTN_B,
202214
}
215+
216+
/// I2C shared internal and external bus pins
217+
pub struct I2CPins {
218+
scl: SCL,
219+
sda: SDA,
220+
}
221+
222+
impl Into<twi::Pins> for I2CPins {
223+
fn into(self) -> twi::Pins {
224+
twi::Pins {
225+
scl: self.scl.degrade(),
226+
sda: self.sda.degrade(),
227+
}
228+
}
229+
}

microbit-common/src/v1/gpio.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ pub type MOSI<MODE> = p0::P0_21<MODE>;
127127
pub type MISO<MODE> = p0::P0_22<MODE>;
128128
pub type SCK<MODE> = p0::P0_23<MODE>;
129129

130-
/* i2c */
130+
/* i2c - shared external and internal */
131131
pub type SCL = p0::P0_00<Input<Floating>>;
132132
pub type SDA = p0::P0_30<Input<Floating>>;
133133

0 commit comments

Comments
 (0)