Add microbit chapter
This commit is contained in:
10
src/microbit/.gdbinit
Normal file
10
src/microbit/.gdbinit
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Connects GDB to OpenOCD server port
|
||||||
|
target remote :3333
|
||||||
|
# (optional) Unmangle function names when debugging
|
||||||
|
set print asm-demangle on
|
||||||
|
# Enable semihosting
|
||||||
|
monitor arm semihosting enable
|
||||||
|
# Load your program, breaks at entry
|
||||||
|
load
|
||||||
|
# Continue with execution
|
||||||
|
continue
|
||||||
10
src/microbit/00.00.README.md
Normal file
10
src/microbit/00.00.README.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# micro:bit HAL
|
||||||
|
|
||||||
|
This chapter will demosntrate the common uses of the micro:bit crate,
|
||||||
|
and its specific hardware abstraction layer (HAL) features.
|
||||||
|
The content in this chapter should be deduceable from the HAL crate,
|
||||||
|
but are given here as a reference.
|
||||||
|
|
||||||
|
More examples can be found in the [micro:bit crate's examples][eg].
|
||||||
|
|
||||||
|
[eg]: https://github.com/therealprof/microbit/tree/master/examples
|
||||||
9
src/microbit/01.00.BUTTONS.md
Normal file
9
src/microbit/01.00.BUTTONS.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Buttons
|
||||||
|
|
||||||
|
The micro:bit as 3 hardware buttons, 2 user buttons and the reset button.
|
||||||
|
|
||||||
|
## User Buttons
|
||||||
|
|
||||||
|
The user buttons are wired up to be high when unpressed and low when pressed.
|
||||||
|
|
||||||
|
{{#include examples/buttons.rs}}
|
||||||
10
src/microbit/02.00.DELAY.md
Normal file
10
src/microbit/02.00.DELAY.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Delays
|
||||||
|
|
||||||
|
The microbit has 3 timers, the micro:bit crate currently only supports using TIMER0.
|
||||||
|
|
||||||
|
``` rust
|
||||||
|
if let Some(p) = microbit::Peripherals::take() {
|
||||||
|
let mut delay = Delay::new(p.TIMER0);
|
||||||
|
delay.delay_ms(1000_u32);
|
||||||
|
}
|
||||||
|
```
|
||||||
11
src/microbit/03.00.DISPLAY.md
Normal file
11
src/microbit/03.00.DISPLAY.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Display
|
||||||
|
|
||||||
|
The micro:bit display is not trivial to control, so a driver is needed;
|
||||||
|
see [the display chapter](display/00.00.README.html) for more details.
|
||||||
|
|
||||||
|
Display calls for now are only blocking, and can either be for binary images (0 for off, 1 for on),
|
||||||
|
or for monochrome images with differing brightness levels
|
||||||
|
|
||||||
|
## Blocking binary image display
|
||||||
|
|
||||||
|
{{#include examples/display_blocking.rs}}
|
||||||
10
src/microbit/Cargo.toml
Normal file
10
src/microbit/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "microbit"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
cortex-m-rt="~0.5"
|
||||||
|
cortex-m-semihosting=""
|
||||||
|
panic-abort = "~0.2"
|
||||||
|
panic-semihosting = "~0.3"
|
||||||
|
microbit="~0.5"
|
||||||
69
src/microbit/examples/buttons.rs
Normal file
69
src/microbit/examples/buttons.rs
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
extern crate panic_abort;
|
||||||
|
extern crate cortex_m_rt as rt;
|
||||||
|
|
||||||
|
#[macro_use(entry, exception)]
|
||||||
|
extern crate microbit;
|
||||||
|
|
||||||
|
use core::fmt::Write;
|
||||||
|
use rt::ExceptionFrame;
|
||||||
|
|
||||||
|
use microbit::hal::prelude::*;
|
||||||
|
use microbit::hal::serial;
|
||||||
|
use microbit::hal::serial::BAUD115200;
|
||||||
|
|
||||||
|
exception!(HardFault, hard_fault);
|
||||||
|
|
||||||
|
fn hard_fault(ef: &ExceptionFrame) -> ! {
|
||||||
|
panic!("{:#?}", ef);
|
||||||
|
}
|
||||||
|
|
||||||
|
exception!(*, default_handler);
|
||||||
|
|
||||||
|
fn default_handler(irqn: i16) {
|
||||||
|
panic!("Unhandled exception (IRQn = {})", irqn);
|
||||||
|
}
|
||||||
|
|
||||||
|
entry!(main);
|
||||||
|
fn main() -> ! {
|
||||||
|
if let Some(p) = microbit::Peripherals::take() {
|
||||||
|
// Split GPIO
|
||||||
|
let mut gpio = p.GPIO.split();
|
||||||
|
// Configure RX and TX pins accordingly
|
||||||
|
let tx = gpio.pin24.into_push_pull_output().downgrade();
|
||||||
|
let rx = gpio.pin25.into_floating_input().downgrade();
|
||||||
|
// Configure serial communication
|
||||||
|
let (mut tx, _) = serial::Serial::uart0(p.UART0, tx, rx, BAUD115200).split();
|
||||||
|
// Configure button GPIOs as inputs
|
||||||
|
let button_a = gpio.pin17.into_floating_input();
|
||||||
|
let button_b = gpio.pin26.into_floating_input();
|
||||||
|
// loop variables
|
||||||
|
let mut state_a_low = false;
|
||||||
|
let mut state_b_low = false;
|
||||||
|
loop {
|
||||||
|
// Get button states
|
||||||
|
let button_a_low = button_a.is_low();
|
||||||
|
let button_b_low = button_b.is_low();
|
||||||
|
if button_a_low && !state_a_low {
|
||||||
|
writeln!(tx, "Button A down").unwrap();
|
||||||
|
}
|
||||||
|
if button_b_low && !state_b_low {
|
||||||
|
writeln!(tx, "Button B down").unwrap();
|
||||||
|
}
|
||||||
|
if !button_a_low && state_a_low {
|
||||||
|
writeln!(tx, "Button A up").unwrap();
|
||||||
|
}
|
||||||
|
if !button_b_low && state_b_low {
|
||||||
|
writeln!(tx, "Button B up").unwrap();
|
||||||
|
}
|
||||||
|
// Store buttons states
|
||||||
|
// This should not read the GPIO pins again, as the state
|
||||||
|
// may have changed and the change will not be recorded
|
||||||
|
state_a_low = button_a_low;
|
||||||
|
state_b_low = button_b_low;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("End");
|
||||||
|
}
|
||||||
57
src/microbit/examples/buttons_poll.rs
Normal file
57
src/microbit/examples/buttons_poll.rs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
extern crate panic_abort;
|
||||||
|
extern crate cortex_m_rt as rt;
|
||||||
|
|
||||||
|
#[macro_use(entry, exception)]
|
||||||
|
extern crate microbit;
|
||||||
|
|
||||||
|
use core::fmt::Write;
|
||||||
|
use rt::ExceptionFrame;
|
||||||
|
|
||||||
|
use microbit::hal::prelude::*;
|
||||||
|
use microbit::hal::delay::Delay;
|
||||||
|
use microbit::hal::serial;
|
||||||
|
use microbit::hal::serial::BAUD115200;
|
||||||
|
|
||||||
|
exception!(HardFault, hard_fault);
|
||||||
|
|
||||||
|
fn hard_fault(ef: &ExceptionFrame) -> ! {
|
||||||
|
panic!("{:#?}", ef);
|
||||||
|
}
|
||||||
|
|
||||||
|
exception!(*, default_handler);
|
||||||
|
|
||||||
|
fn default_handler(irqn: i16) {
|
||||||
|
panic!("Unhandled exception (IRQn = {})", irqn);
|
||||||
|
}
|
||||||
|
|
||||||
|
entry!(main);
|
||||||
|
fn main() -> ! {
|
||||||
|
if let Some(p) = microbit::Peripherals::take() {
|
||||||
|
// Split GPIO
|
||||||
|
let mut gpio = p.GPIO.split();
|
||||||
|
// Configure RX and TX pins accordingly
|
||||||
|
let tx = gpio.pin24.into_push_pull_output().downgrade();
|
||||||
|
let rx = gpio.pin25.into_floating_input().downgrade();
|
||||||
|
// Configure serial communication
|
||||||
|
let (mut tx, _) = serial::Serial::uart0(p.UART0, tx, rx, BAUD115200).split();
|
||||||
|
// Configure button GPIOs as inputs
|
||||||
|
let button_a = gpio.pin17.into_floating_input();
|
||||||
|
let button_b = gpio.pin26.into_floating_input();
|
||||||
|
// delay
|
||||||
|
let mut delay = Delay::new(p.TIMER0);
|
||||||
|
loop {
|
||||||
|
writeln!(
|
||||||
|
tx, "Button A(down:{}, up:{}) B(down:{}, up:{})",
|
||||||
|
button_a.is_low(),
|
||||||
|
button_a.is_high(),
|
||||||
|
button_b.is_low(),
|
||||||
|
button_b.is_high(),
|
||||||
|
).unwrap();
|
||||||
|
delay.delay_ms(100_u8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("End");
|
||||||
|
}
|
||||||
101
src/microbit/examples/display_blocking.rs
Normal file
101
src/microbit/examples/display_blocking.rs
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
#[macro_use(entry, exception)]
|
||||||
|
extern crate microbit;
|
||||||
|
extern crate cortex_m_rt as rt;
|
||||||
|
extern crate cortex_m_semihosting as sh;
|
||||||
|
extern crate panic_abort;
|
||||||
|
|
||||||
|
use core::fmt::Write;
|
||||||
|
|
||||||
|
use rt::ExceptionFrame;
|
||||||
|
|
||||||
|
use microbit::hal::delay::Delay;
|
||||||
|
use microbit::hal::prelude::*;
|
||||||
|
use microbit::hal::serial;
|
||||||
|
use microbit::hal::serial::BAUD115200;
|
||||||
|
|
||||||
|
use microbit::led;
|
||||||
|
|
||||||
|
exception!(HardFault, hard_fault);
|
||||||
|
|
||||||
|
fn hard_fault(ef: &ExceptionFrame) -> ! {
|
||||||
|
panic!("{:#?}", ef);
|
||||||
|
}
|
||||||
|
|
||||||
|
exception!(*, default_handler);
|
||||||
|
|
||||||
|
fn default_handler(irqn: i16) {
|
||||||
|
panic!("Unhandled exception (IRQn = {})", irqn);
|
||||||
|
}
|
||||||
|
|
||||||
|
entry!(main);
|
||||||
|
fn main() -> ! {
|
||||||
|
if let Some(p) = microbit::Peripherals::take() {
|
||||||
|
let mut gpio = p.GPIO.split();
|
||||||
|
let mut delay = Delay::new(p.TIMER0);
|
||||||
|
|
||||||
|
// Display
|
||||||
|
let row1 = gpio.pin13.into_push_pull_output().downgrade();
|
||||||
|
let row2 = gpio.pin14.into_push_pull_output().downgrade();
|
||||||
|
let row3 = gpio.pin15.into_push_pull_output().downgrade();
|
||||||
|
let col1 = gpio.pin4.into_push_pull_output().downgrade();
|
||||||
|
let col2 = gpio.pin5.into_push_pull_output().downgrade();
|
||||||
|
let col3 = gpio.pin6.into_push_pull_output().downgrade();
|
||||||
|
let col4 = gpio.pin7.into_push_pull_output().downgrade();
|
||||||
|
let col5 = gpio.pin8.into_push_pull_output().downgrade();
|
||||||
|
let col6 = gpio.pin9.into_push_pull_output().downgrade();
|
||||||
|
let col7 = gpio.pin10.into_push_pull_output().downgrade();
|
||||||
|
let col8 = gpio.pin11.into_push_pull_output().downgrade();
|
||||||
|
let col9 = gpio.pin12.into_push_pull_output().downgrade();
|
||||||
|
|
||||||
|
// Configure RX and TX pins accordingly
|
||||||
|
let tx = gpio.pin24.into_push_pull_output().downgrade();
|
||||||
|
let rx = gpio.pin25.into_floating_input().downgrade();
|
||||||
|
|
||||||
|
let mut leds = led::Display::new(
|
||||||
|
row1, row2, row3, col1, col2, col3, col4, col5, col6, col7, col8, col9,
|
||||||
|
);
|
||||||
|
|
||||||
|
let (mut tx, _) = serial::Serial::uart0(p.UART0, tx, rx, BAUD115200).split();
|
||||||
|
|
||||||
|
let _ = write!(tx, "\n\rStarting!\n\r");
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
let letter_I = [
|
||||||
|
[0, 1, 1, 1, 0],
|
||||||
|
[0, 0, 1, 0, 0],
|
||||||
|
[0, 0, 1, 0, 0],
|
||||||
|
[0, 0, 1, 0, 0],
|
||||||
|
[0, 1, 1, 1, 0],
|
||||||
|
];
|
||||||
|
|
||||||
|
let heart = [
|
||||||
|
[0, 1, 0, 1, 0],
|
||||||
|
[1, 0, 1, 0, 1],
|
||||||
|
[1, 0, 0, 0, 1],
|
||||||
|
[0, 1, 0, 1, 0],
|
||||||
|
[0, 0, 1, 0, 0],
|
||||||
|
];
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
let letter_U = [
|
||||||
|
[0, 1, 0, 1, 0],
|
||||||
|
[0, 1, 0, 1, 0],
|
||||||
|
[0, 1, 0, 1, 0],
|
||||||
|
[0, 1, 0, 1, 0],
|
||||||
|
[0, 1, 1, 1, 0],
|
||||||
|
];
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let _ = write!(tx, "I <3 Rust!\n\r");
|
||||||
|
leds.display(&mut delay, letter_I, 1000);
|
||||||
|
leds.display(&mut delay, heart, 1000);
|
||||||
|
leds.display(&mut delay, letter_U, 1000);
|
||||||
|
leds.clear();
|
||||||
|
delay.delay_ms(250_u32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("End");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user