Add serial examples
This commit is contained in:
@@ -33,7 +33,7 @@
|
|||||||
- [Delays](microbit/02.00.DELAY.md)
|
- [Delays](microbit/02.00.DELAY.md)
|
||||||
- [Display](microbit/03.00.DISPLAY.md)
|
- [Display](microbit/03.00.DISPLAY.md)
|
||||||
|
|
||||||
- [WIP - Serial UART](serial/00.00.README.md)
|
- [Serial UART - Blocking](serial/00.00.README.md)
|
||||||
- [Echo Server](serial/01.00.ECHO.md)
|
- [Echo Server](serial/01.00.ECHO.md)
|
||||||
- [Theory](serial/01.01.THEORY.md)
|
- [Theory](serial/01.01.THEORY.md)
|
||||||
- [Solution](serial/01.02.ECHO.md)
|
- [Solution](serial/01.02.ECHO.md)
|
||||||
@@ -42,8 +42,6 @@
|
|||||||
- [Solution](serial/02.01.SOLUTION.md)
|
- [Solution](serial/02.01.SOLUTION.md)
|
||||||
- [Countdown](serial/02.02.md)
|
- [Countdown](serial/02.02.md)
|
||||||
- [Solution](serial/02.02.SOLUTION.md)
|
- [Solution](serial/02.02.SOLUTION.md)
|
||||||
- [Display echo](serial/02.03.md)
|
|
||||||
- [Solution](serial/02.03.SOLUTION.md)
|
|
||||||
- [Quiz](serial/02.04.md)
|
- [Quiz](serial/02.04.md)
|
||||||
- [Solution](serial/02.04.SOLUTION.md)
|
- [Solution](serial/02.04.SOLUTION.md)
|
||||||
|
|
||||||
@@ -58,6 +56,8 @@
|
|||||||
- [Multiplexing](display/03.02.MULT.md)
|
- [Multiplexing](display/03.02.MULT.md)
|
||||||
- [Full Solution](display/03.03.FULL.md)
|
- [Full Solution](display/03.03.FULL.md)
|
||||||
|
|
||||||
|
- [WIP - Non-blocking](nb/00.00.README.md)
|
||||||
|
|
||||||
- [WIP - Sensors and I²C](sensors/00.00.README.md)
|
- [WIP - Sensors and I²C](sensors/00.00.README.md)
|
||||||
|
|
||||||
- [WIP - Real time](rtfm/00.00.README.md)
|
- [WIP - Real time](rtfm/00.00.README.md)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ fn main() -> ! {
|
|||||||
let mut gpio = p.GPIO.split();
|
let mut gpio = p.GPIO.split();
|
||||||
let mut delay = Delay::new(p.TIMER0);
|
let mut delay = Delay::new(p.TIMER0);
|
||||||
|
|
||||||
// Display
|
// Configure display pins
|
||||||
let row1 = gpio.pin13.into_push_pull_output().downgrade();
|
let row1 = gpio.pin13.into_push_pull_output().downgrade();
|
||||||
let row2 = gpio.pin14.into_push_pull_output().downgrade();
|
let row2 = gpio.pin14.into_push_pull_output().downgrade();
|
||||||
let row3 = gpio.pin15.into_push_pull_output().downgrade();
|
let row3 = gpio.pin15.into_push_pull_output().downgrade();
|
||||||
|
|||||||
@@ -7,6 +7,6 @@ monitor arm semihosting enable
|
|||||||
# Load your program, breaks at entry
|
# Load your program, breaks at entry
|
||||||
load
|
load
|
||||||
# (optional) Add breakpoint at function
|
# (optional) Add breakpoint at function
|
||||||
break serial::main
|
#break serial::main
|
||||||
# Continue with execution
|
# Continue with execution
|
||||||
continue
|
#continue
|
||||||
6
src/serial/02.00.md
Normal file
6
src/serial/02.00.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Exercises
|
||||||
|
|
||||||
|
- Reverse echo a line of input
|
||||||
|
- Numerical countdown
|
||||||
|
- Display echo
|
||||||
|
- Quiz game
|
||||||
8
src/serial/02.01.SOLUTION.md
Normal file
8
src/serial/02.01.SOLUTION.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Solution
|
||||||
|
|
||||||
|
``` rust
|
||||||
|
{{#include examples/reverse.rs}}
|
||||||
|
```
|
||||||
|
|
||||||
|
I have used an implementation of a vector on the stack, provided by the heapless crate.
|
||||||
|
After 32 characters (a char is a u8 byte) the heapless vector is full, and an error is shown.
|
||||||
19
src/serial/02.01.md
Normal file
19
src/serial/02.01.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Reverse Echo
|
||||||
|
|
||||||
|
The micro:bit should buffer characters it receives until `\n` or `\r` is received
|
||||||
|
(the enter key is pressed on the host computer).
|
||||||
|
The characters should then be printed back in reverse order to the host computer.
|
||||||
|
The characters may also be echoed like earlier to see what is being typed.
|
||||||
|
|
||||||
|
## Flow
|
||||||
|
|
||||||
|
1. Letter `a` is typed and transmitted to the micro:bit
|
||||||
|
2. (optional) The micro:bit retransmits the letter `a` (echo)
|
||||||
|
3. Letter `b` is typed and transmitted to the micro:bit
|
||||||
|
4. (optional) The micro:bit retransmits the letter `b` (echo)
|
||||||
|
5. Enter key is pressed and `\r` is transmitted to the micro:bit
|
||||||
|
6. Letters `ba` are transmitted from the micro:bit
|
||||||
|
|
||||||
|
## Useful crates
|
||||||
|
|
||||||
|
+ [Heapless](https://docs.rs/heapless)
|
||||||
5
src/serial/02.02.SOLUTION.md
Normal file
5
src/serial/02.02.SOLUTION.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Solution
|
||||||
|
|
||||||
|
``` rust
|
||||||
|
{{#include examples/countdown.rs}}
|
||||||
|
```
|
||||||
18
src/serial/02.02.md
Normal file
18
src/serial/02.02.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Countdown
|
||||||
|
|
||||||
|
You should be able to type a number greater than 0, press enter,
|
||||||
|
and the micro:bit will return a countdown.
|
||||||
|
|
||||||
|
```
|
||||||
|
5
|
||||||
|
4
|
||||||
|
3
|
||||||
|
2
|
||||||
|
1
|
||||||
|
```
|
||||||
|
|
||||||
|
Feel free to add your own surprise at the end of the countdown
|
||||||
|
|
||||||
|
## Useful crates
|
||||||
|
|
||||||
|
+ [Heapless](https://docs.rs/heapless)
|
||||||
5
src/serial/02.03.SOLUTION.md
Normal file
5
src/serial/02.03.SOLUTION.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Solution
|
||||||
|
|
||||||
|
``` rust
|
||||||
|
{{#include examples/quiz.rs}}
|
||||||
|
```
|
||||||
23
src/serial/02.03.md
Normal file
23
src/serial/02.03.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Quiz
|
||||||
|
|
||||||
|
Let us create a simple quiz system.
|
||||||
|
The quiz will have a quizmaster and 2 contestants;
|
||||||
|
the quizmaster will operate the host computer,
|
||||||
|
and the micro:bit's user buttons will be used as buzzers for the 2 contestants.
|
||||||
|
We have only learnt about blocking operations so far,
|
||||||
|
so the following cannot be done at the same time:
|
||||||
|
|
||||||
|
+ Scan the buttons for presses
|
||||||
|
+ Operate the LED display
|
||||||
|
+ Operate the serial UART
|
||||||
|
|
||||||
|
For the sake of consistency, let us say that the quiz should have 11 questions.
|
||||||
|
|
||||||
|
## Flow
|
||||||
|
|
||||||
|
1. Display question number and score.
|
||||||
|
2. Wait for a contestant to press a button.
|
||||||
|
3. Print the constestant who buzzed in to the quizmaster's computer.
|
||||||
|
4. (optional) Display the contestant who buzzed in to the contestants on the micro:bit for 1-2 seconds.
|
||||||
|
5. Prompt the quizmaster for whether the contestant answered correctly.
|
||||||
|
6. Record the updated score and repeat from 1, unless someone has won.
|
||||||
@@ -3,6 +3,7 @@ name = "serial"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
heapless="~0.3"
|
||||||
cortex-m-rt="~0.5"
|
cortex-m-rt="~0.5"
|
||||||
cortex-m-semihosting=""
|
cortex-m-semihosting=""
|
||||||
panic-semihosting = "~0.3"
|
panic-semihosting = "~0.3"
|
||||||
|
|||||||
86
src/serial/examples/countdown.rs
Normal file
86
src/serial/examples/countdown.rs
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
extern crate panic_semihosting;
|
||||||
|
extern crate cortex_m_rt as rt;
|
||||||
|
extern crate cortex_m_semihosting as sh;
|
||||||
|
extern crate heapless;
|
||||||
|
|
||||||
|
#[macro_use(entry, exception, block)]
|
||||||
|
extern crate microbit;
|
||||||
|
|
||||||
|
use core::fmt::Write;
|
||||||
|
use rt::ExceptionFrame;
|
||||||
|
use sh::hio;
|
||||||
|
use heapless::{consts, Vec, String};
|
||||||
|
|
||||||
|
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() -> ! {
|
||||||
|
let mut stdout = hio::hstdout().unwrap();
|
||||||
|
writeln!(stdout, "Start").unwrap();
|
||||||
|
if let Some(p) = microbit::Peripherals::take() {
|
||||||
|
// Split GPIO
|
||||||
|
let mut gpio = p.GPIO.split();
|
||||||
|
// Create delay provider
|
||||||
|
let mut delay = Delay::new(p.TIMER0);
|
||||||
|
// 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, mut rx) = serial::Serial::uart0(p.UART0, tx, rx, BAUD115200).split();
|
||||||
|
writeln!(tx, "Start");
|
||||||
|
loop {
|
||||||
|
// A buffer with 32 bytes of capacity
|
||||||
|
let mut buffer: Vec<u8, consts::U32> = Vec::new();
|
||||||
|
loop {
|
||||||
|
// Read
|
||||||
|
let byte = block!(rx.read()).unwrap();
|
||||||
|
// Echo
|
||||||
|
block!(tx.write(byte));
|
||||||
|
// Carriage return
|
||||||
|
if byte == b'\r' {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Push to buffer
|
||||||
|
if buffer.push(byte).is_err() {
|
||||||
|
// Buffer full
|
||||||
|
writeln!(tx, "\r\nWarning: buffer full, dumping buffer");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Buffer to string
|
||||||
|
let buf_str = String::from_utf8(buffer).unwrap();
|
||||||
|
writeln!(tx, "");
|
||||||
|
match buf_str.parse() {
|
||||||
|
// Transmit countdown
|
||||||
|
Ok(buf_int) => {
|
||||||
|
for i in (1..buf_int).rev() {
|
||||||
|
delay.delay_ms(1000_u32);
|
||||||
|
writeln!(tx, "{}", i);
|
||||||
|
}
|
||||||
|
// Add post countdown effects here
|
||||||
|
},
|
||||||
|
// Transmit parse error
|
||||||
|
Err(e) => writeln!(tx, "{:?}", e).unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("End");
|
||||||
|
}
|
||||||
69
src/serial/examples/display_echo.rs.disabled
Normal file
69
src/serial/examples/display_echo.rs.disabled
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
extern crate panic_semihosting;
|
||||||
|
extern crate cortex_m_rt as rt;
|
||||||
|
extern crate cortex_m_semihosting as sh;
|
||||||
|
extern crate heapless;
|
||||||
|
|
||||||
|
#[macro_use(entry, exception, block)]
|
||||||
|
extern crate microbit;
|
||||||
|
|
||||||
|
use core::fmt::Write;
|
||||||
|
use rt::ExceptionFrame;
|
||||||
|
use sh::hio;
|
||||||
|
use heapless::{consts, Vec, String};
|
||||||
|
|
||||||
|
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() -> ! {
|
||||||
|
let mut stdout = hio::hstdout().unwrap();
|
||||||
|
writeln!(stdout, "Start").unwrap();
|
||||||
|
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, mut rx) = serial::Serial::uart0(p.UART0, tx, rx, BAUD115200).split();
|
||||||
|
// Configure display pins
|
||||||
|
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 display
|
||||||
|
let mut leds = led::Display::new(
|
||||||
|
row1, row2, row3, col1, col2, col3, col4, col5, col6, col7, col8, col9,
|
||||||
|
);
|
||||||
|
writeln!(tx, "Start");
|
||||||
|
loop {
|
||||||
|
let val = block!(rx.read()).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("End");
|
||||||
|
}
|
||||||
146
src/serial/examples/quiz.rs
Normal file
146
src/serial/examples/quiz.rs
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
extern crate panic_semihosting;
|
||||||
|
extern crate cortex_m_rt as rt;
|
||||||
|
extern crate cortex_m_semihosting as sh;
|
||||||
|
|
||||||
|
#[macro_use(entry, exception, block)]
|
||||||
|
extern crate microbit;
|
||||||
|
|
||||||
|
use core::fmt::Write;
|
||||||
|
use rt::ExceptionFrame;
|
||||||
|
use sh::hio;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
const WINNING_SCORE: u8 = 6;
|
||||||
|
const QUESTION_COUNT: u8 = 2*WINNING_SCORE - 1;
|
||||||
|
|
||||||
|
const LETTER_A: [[u8; 5]; 5] = [
|
||||||
|
[0, 0, 1, 0, 0],
|
||||||
|
[0, 1, 0, 1, 0],
|
||||||
|
[0, 1, 1, 1, 0],
|
||||||
|
[0, 1, 0, 1, 0],
|
||||||
|
[0, 1, 0, 1, 0],
|
||||||
|
];
|
||||||
|
|
||||||
|
const LETTER_B: [[u8; 5]; 5] = [
|
||||||
|
[0, 1, 1, 0, 0],
|
||||||
|
[0, 1, 0, 1, 0],
|
||||||
|
[0, 1, 1, 0, 0],
|
||||||
|
[0, 1, 0, 1, 0],
|
||||||
|
[0, 1, 1, 0, 0],
|
||||||
|
];
|
||||||
|
|
||||||
|
entry!(main);
|
||||||
|
fn main() -> ! {
|
||||||
|
let mut stdout = hio::hstdout().unwrap();
|
||||||
|
writeln!(stdout, "Start").unwrap();
|
||||||
|
if let Some(p) = microbit::Peripherals::take() {
|
||||||
|
// Split GPIO
|
||||||
|
let mut gpio = p.GPIO.split();
|
||||||
|
// Configure delay
|
||||||
|
let mut delay = Delay::new(p.TIMER0);
|
||||||
|
// 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, mut rx) = serial::Serial::uart0(p.UART0, tx, rx, BAUD115200).split();
|
||||||
|
// Configure display pins
|
||||||
|
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 display
|
||||||
|
let mut leds = led::Display::new(
|
||||||
|
row1, row2, row3, col1, col2, col3, col4, col5, col6, col7, col8, col9,
|
||||||
|
);
|
||||||
|
// Configure button GPIOs as inputs
|
||||||
|
let button_a = gpio.pin17.into_floating_input();
|
||||||
|
let button_b = gpio.pin26.into_floating_input();
|
||||||
|
writeln!(tx, "Start");
|
||||||
|
loop {
|
||||||
|
let mut score_a: u8 = 0;
|
||||||
|
let mut score_b: u8 = 0;
|
||||||
|
for n in 0..QUESTION_COUNT {
|
||||||
|
writeln!(tx, "Question {} - Score {}:{}", n, score_a, score_b);
|
||||||
|
let mut button_a_low;
|
||||||
|
let mut button_b_low;
|
||||||
|
loop {
|
||||||
|
// Get button states
|
||||||
|
button_a_low = button_a.is_low();
|
||||||
|
button_b_low = button_b.is_low();
|
||||||
|
if button_a_low || button_b_low {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let letter = match (button_a_low, button_b_low) {
|
||||||
|
(true, false) => {
|
||||||
|
writeln!(tx, "A");
|
||||||
|
LETTER_A
|
||||||
|
},
|
||||||
|
(false, true) => {
|
||||||
|
writeln!(tx, "B");
|
||||||
|
LETTER_B
|
||||||
|
},
|
||||||
|
(true, true) => {
|
||||||
|
writeln!(tx, "Tie! Next question.");
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
leds.display(&mut delay, letter, 1000);
|
||||||
|
loop {
|
||||||
|
// Keep asking until y or n is received
|
||||||
|
write!(tx, "Answer correct? [y/n] ");
|
||||||
|
let byte = block!(rx.read()).unwrap();
|
||||||
|
block!(tx.write(byte));
|
||||||
|
writeln!(tx);
|
||||||
|
match byte {
|
||||||
|
b'y' => {
|
||||||
|
if button_a_low {
|
||||||
|
score_a += 1;
|
||||||
|
}
|
||||||
|
if button_b_low {
|
||||||
|
score_b += 1;
|
||||||
|
}
|
||||||
|
break
|
||||||
|
},
|
||||||
|
b'n' => break,
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if score_a >= WINNING_SCORE || score_b >= WINNING_SCORE {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeln!(tx, "Final Score {}:{}", score_a, score_b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("End");
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
extern crate panic_semihosting;
|
extern crate panic_semihosting;
|
||||||
extern crate cortex_m_rt as rt;
|
extern crate cortex_m_rt as rt;
|
||||||
extern crate cortex_m_semihosting as sh;
|
extern crate cortex_m_semihosting as sh;
|
||||||
|
extern crate heapless;
|
||||||
|
|
||||||
#[macro_use(entry, exception, block)]
|
#[macro_use(entry, exception, block)]
|
||||||
extern crate microbit;
|
extern crate microbit;
|
||||||
@@ -11,6 +12,7 @@ extern crate microbit;
|
|||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
use rt::ExceptionFrame;
|
use rt::ExceptionFrame;
|
||||||
use sh::hio;
|
use sh::hio;
|
||||||
|
use heapless::{consts, Vec};
|
||||||
|
|
||||||
use microbit::hal::prelude::*;
|
use microbit::hal::prelude::*;
|
||||||
use microbit::hal::delay::Delay;
|
use microbit::hal::delay::Delay;
|
||||||
@@ -43,10 +45,34 @@ fn main() -> ! {
|
|||||||
let rx = gpio.pin25.into_floating_input().downgrade();
|
let rx = gpio.pin25.into_floating_input().downgrade();
|
||||||
// Configure serial communication
|
// Configure serial communication
|
||||||
let (mut tx, mut rx) = serial::Serial::uart0(p.UART0, tx, rx, BAUD115200).split();
|
let (mut tx, mut rx) = serial::Serial::uart0(p.UART0, tx, rx, BAUD115200).split();
|
||||||
write!(tx, "Start\r\n");
|
// A buffer with 32 bytes of capacity
|
||||||
|
let mut buffer: Vec<u8, consts::U32> = Vec::new();
|
||||||
|
writeln!(tx, "Start");
|
||||||
loop {
|
loop {
|
||||||
let val = block!(rx.read()).unwrap();
|
loop {
|
||||||
block!(tx.write(val));
|
// Read
|
||||||
|
let byte = block!(rx.read()).unwrap();
|
||||||
|
// Echo
|
||||||
|
block!(tx.write(byte));
|
||||||
|
// Carriage return
|
||||||
|
if byte == b'\r' {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Push to buffer
|
||||||
|
if buffer.push(byte).is_err() {
|
||||||
|
// Buffer full
|
||||||
|
writeln!(tx, "\r\nWarning: buffer full, dumping buffer");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Uncomment to not overwrite input string
|
||||||
|
//writeln!(tx, "");
|
||||||
|
// Respond
|
||||||
|
for b in buffer.iter().rev() {
|
||||||
|
block!(tx.write(*b));
|
||||||
|
}
|
||||||
|
writeln!(tx, "");
|
||||||
|
buffer.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panic!("End");
|
panic!("End");
|
||||||
Reference in New Issue
Block a user