Add some code

This commit is contained in:
Marco Thomas
2021-09-16 21:54:32 +02:00
parent 5e2ab32981
commit 6fef749d7b
2 changed files with 233 additions and 0 deletions

187
src/main.rs Normal file
View File

@@ -0,0 +1,187 @@
#![no_main]
#![no_std]
use cortex_m_rt::entry;
use microbit::{
board::Board,
display::blocking::Display,
hal::{
timer::Timer,
pac::twim0::frequency::FREQUENCY_A,
prelude::*,
twim::Twim,
uarte,
uarte::{Baudrate, Parity},
},
};
use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
use core::fmt::Write;
use heapless::{Vec};
mod serial_setup;
use serial_setup::UartePort;
const SCREEN_SIZE: usize = 5;
const CLEAN_DISPLAY: [[u8; 5]; 5] = [
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
];
/// Direction, clockwise
#[derive(Debug, Clone, Copy)]
enum Direction {
UP,
RIGHT,
DOWN,
LEFT,
}
impl Direction {
fn right(&self) -> Self {
match self {
Self::UP => Self::RIGHT,
Self::RIGHT => Self::DOWN,
Self::DOWN => Self::LEFT,
Self::LEFT => Self::UP,
}
}
fn left(&self) -> Self {
match self {
Self::UP => Self::LEFT,
Self::RIGHT => Self::UP,
Self::DOWN => Self::RIGHT,
Self::LEFT => Self::DOWN,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
struct Position {
x: usize,
y: usize,
}
struct Food {
position: Position
}
impl Food {
fn regenerate(&mut self) {
// TODO rand this
self.position = Position { x: 3, y: 3 };
}
}
#[derive(Debug, Clone)]
struct Snake {
body: Vec<Position, 32>,
direction: Direction,
}
impl Snake {
fn new(start: Position, direction: Direction) -> Self {
let mut body: Vec<Position, 32> = Vec::new();
body.push(start).unwrap();
Self { body, direction }
}
fn update(&mut self, button_a: bool, button_b: bool, food: &mut Food) {
// update direction
if button_a {
self.direction = self.direction.left();
}
if button_b {
self.direction = self.direction.right();
}
// update snake
let mut new_head = self.body[0].clone();
match self.direction {
// some bound checking
Direction::DOWN => new_head.y = (self.body[0].y + 1) % SCREEN_SIZE,
Direction::RIGHT => new_head.x = (self.body[0].x + 1) % SCREEN_SIZE,
Direction::UP => {
let next = (self.body[0].x, (self.body[0].y as isize) - 1);
if next.1 < 0 {
new_head.y = 4;
} else {
new_head.y -= 1;
}
}
Direction::LEFT => {
let next = ((self.body[0].x as isize) - 1, self.body[0].y);
if next.0 < 0 {
new_head.x = 4;
} else {
new_head.x -= 1;
}
}
};
// add new_head
let mut new_body: Vec<Position, 32> = Vec::new();
new_body.push(new_head);
self.body
.clone()
.into_iter()
.map(|body_part| new_body.push(body_part));
self.body = new_body;
// remove tail element
if self.body[0] != food.position {
self.body.pop();
food.regenerate();
}
}
}
#[entry]
fn main() -> ! {
rtt_init_print!();
let board = Board::take().unwrap();
let mut timer = Timer::new(board.TIMER0);
let mut display = Display::new(board.display_pins);
let _i2c = { Twim::new(board.TWIM0, board.i2c_internal.into(), FREQUENCY_A::K100) };
let mut uart = {
let serial = uarte::Uarte::new(
board.UARTE0,
board.uart.into(),
Parity::EXCLUDED,
Baudrate::BAUD115200,
);
UartePort::new(serial)
};
let button_a = board.buttons.button_a;
let button_b = board.buttons.button_b;
let mut snake = Snake::new(Position { x: 1, y: 1 }, Direction::RIGHT);
let mut food = Food { position: Position { x: 2, y: 2 }};
loop {
// update snake
let is_a_pressed = button_a.is_low().unwrap();
let is_b_pressed = button_b.is_low().unwrap();
snake.update(is_a_pressed, is_b_pressed, &mut food);
// print some debug to uart
writeln!(uart, "Direction: {:?}\r", snake.direction);
// update screen
let mut display_matrix = CLEAN_DISPLAY;
for element in snake.body.iter() {
writeln!(uart, "Element: {:?}\r", element);
display_matrix[element.y][element.x] = 1;
}
display_matrix[food.position.y][food.position.x] = 1;
display.show(&mut timer, display_matrix, 200);
}
}

46
src/serial_setup.rs Normal file
View File

@@ -0,0 +1,46 @@
use core::fmt;
use embedded_hal::blocking::serial as bserial;
use embedded_hal::serial;
use microbit::hal::uarte::{Error, Instance, Uarte, UarteRx, UarteTx};
static mut TX_BUF: [u8; 1] = [0; 1];
static mut RX_BUF: [u8; 1] = [0; 1];
pub struct UartePort<T: Instance>(UarteTx<T>, UarteRx<T>);
impl<T: Instance> UartePort<T> {
pub fn new(serial: Uarte<T>) -> UartePort<T> {
let (tx, rx) = serial
.split(unsafe { &mut TX_BUF }, unsafe { &mut RX_BUF })
.unwrap();
UartePort(tx, rx)
}
}
impl<T: Instance> fmt::Write for UartePort<T> {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.0.write_str(s)
}
}
impl<T: Instance> serial::Write<u8> for UartePort<T> {
type Error = Error;
fn write(&mut self, b: u8) -> nb::Result<(), Self::Error> {
self.0.write(b)
}
fn flush(&mut self) -> nb::Result<(), Self::Error> {
self.0.flush()
}
}
impl<T: Instance> bserial::write::Default<u8> for UartePort<T> {}
impl<T: Instance> serial::Read<u8> for UartePort<T> {
type Error = Error;
fn read(&mut self) -> nb::Result<u8, Self::Error> {
self.1.read()
}
}