### Manual ARM Toolchain Installation Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/03-setup/linux.md Manually installs the ARM GNU toolchain by downloading a pre-built binary and extracting it. This method is for distributions without readily available packages, requiring manual PATH configuration. ```console mkdir -p ~/local && cd ~/local tar xjf /path/to/downloaded/file/gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2 ``` ```shell PATH=$PATH:$HOME/local/gcc-arm-none-eabi-9-2020-q2-update/bin ``` -------------------------------- ### Install PuTTY on Windows Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/03-setup/windows.md Instructions to download and install PuTTY, a free SSH and Telnet client for Windows. After downloading `putty.exe`, place it in a directory included in your system's PATH environment variable for easy access. ```console Download the latest `putty.exe` from [this site] and place it somewhere in your `%PATH%`. ``` -------------------------------- ### Start Minicom in Setup Mode (Shell) Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/06-serial-communication/minicom-on-macos.md This command initiates Minicom in its setup mode, allowing users to configure various settings including keyboard options. No external dependencies are required beyond Minicom itself. ```shell # start minicom in setup mode minicom -s ``` -------------------------------- ### Rust Embedded: Setup and Verification Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/SUMMARY.md This snippet demonstrates the basic setup and verification steps for an embedded Rust development environment. It typically involves installing the necessary toolchains and running a simple check to ensure the environment is correctly configured for embedded development. ```rust cargo install --git https://github.com/rust-embedded/cross # Example verification command (actual command may vary based on target) # cross build --target thumbv7m-none-eabi ``` -------------------------------- ### Install Debugging Tools on Fedora Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/03-setup/linux.md Installs gdb and minicom on Fedora 32+ systems. These packages provide the necessary debugging capabilities for ARM Cortex-M development and serial terminal access. ```console sudo dnf install \ gdb \ minicom ``` -------------------------------- ### Verify ARM GCC Installation on Windows Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/03-setup/windows.md This command verifies the installation of the ARM GCC toolchain by displaying its version. Ensure the `arm-none-eabi-gcc` executable is in your system's PATH environment variable. ```console $ arm-none-eabi-gcc -v (..) gcc version 5.4.1 20160919 (release) (..) ``` -------------------------------- ### Project Setup with Cargo.toml Source: https://context7.com/rust-embedded/discovery/llms.txt Defines project metadata, dependencies, and features for a micro:bit embedded Rust project. It specifies the microbit BSP, core embedded crates like cortex-m-rt, and panic handlers. ```toml [package] name = "led-roulette" version = "0.1.0" edition = "2018" [dependencies.microbit-v2] version = "0.12.0" optional = true [dependencies.microbit] version = "0.12.0" optional = true [dependencies] cortex-m = "0.7.3" cortex-m-rt = "0.7.0" panic-halt = "0.2.0" rtt-target = { version = "0.3.1", features = ["cortex-m"] } panic-rtt-target = { version = "0.1.2", features = ["cortex-m"] } [features] v2 = ["microbit-v2"] v1 = ["microbit"] ``` -------------------------------- ### Install and Verify cargo-binutils Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/03-setup/README.md Installs the `cargo-binutils` component, which provides utilities for working with binary files generated by Rust. It requires the `llvm-tools` component to be installed first. ```console $ rustup component add llvm-tools $ cargo install cargo-binutils --vers 0.3.3 $ cargo size --version cargo-size 0.3.3 ``` -------------------------------- ### Install Debugging Tools on Ubuntu/Debian Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/03-setup/linux.md Installs gdb-multiarch and minicom on Ubuntu 20.04+ or Debian 10+ systems. These tools are essential for debugging ARM Cortex-M programs and serial communication, respectively. ```console sudo apt-get install \ gdb-multiarch \ minicom ``` -------------------------------- ### Micro:bit Serial Communication Setup and Echo (Rust) Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/07-uart/my-solution.md Initializes serial communication (UART for v1, UARTE for v2) on a micro:bit and enters a loop to read bytes, store them in a buffer, and echo them back. Handles buffer overflow and line termination. Requires the `cortex-m-rt`, `heapless`, `rtt-target`, and `panic-rtt-target` crates, along with the `microbit` HAL. ```rust #![no_main] #![no_std] use cortex_m_rt::entry; use core::fmt::Write; use heapless::Vec; use rtt_target::rtt_init_print; use panic_rtt_target as _; #[cfg(feature = "v1")] use microbit::{ hal::prelude::*, hal::uart, hal::uart::{Baudrate, Parity}, }; #[cfg(feature = "v2")] use microbit::{ hal::prelude::*, hal::uarte, hal::uarte::{Baudrate, Parity}, }; #[cfg(feature = "v2")] mod serial_setup; #[cfg(feature = "v2")] use serial_setup::UartePort; #[entry] fn main() -> ! { rtt_init_print!(); let board = microbit::Board::take().unwrap(); #[cfg(feature = "v1")] let mut serial = { uart::Uart::new( board.UART0, board.uart.into(), Parity::EXCLUDED, Baudrate::BAUD115200, ) }; #[cfg(feature = "v2")] let mut serial = { let serial = uarte::Uarte::new( board.UARTE0, board.uart.into(), Parity::EXCLUDED, Baudrate::BAUD115200, ); UartePort::new(serial) }; // A buffer with 32 bytes of capacity let mut buffer: Vec = Vec::new(); loop { buffer.clear(); loop { // We assume that the receiving cannot fail let byte = nb::block!(serial.read()).unwrap(); if buffer.push(byte).is_err() { write!(serial, "error: buffer full\r\n").unwrap(); break; } if byte == 13 { for byte in buffer.iter().rev().chain(&[b'\n', b'\r']) { nb::block!(serial.write(*byte)).unwrap(); } break; } } nb::block!(serial.flush()).unwrap() } } ``` -------------------------------- ### Install Debugging Tools on Arch Linux Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/03-setup/linux.md Installs arm-none-eabi-gdb and minicom on Arch Linux. This command ensures you have the specific GDB version for ARM embedded targets and a serial communication tool. ```console sudo pacman -S \ arm-none-eabi-gdb \ minicom ``` -------------------------------- ### Install and Verify cargo-embed Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/03-setup/README.md Installs `cargo-embed`, a tool for flashing and debugging embedded applications. It depends on `probe-rs` tools and requires specific versioning. The installation might require following the latest instructions from the probe.rs website. ```console $ cargo install --locked probe-rs-tools --vers '^0.24' $ cargo embed --version cargo-embed 0.24.0 (git commit: crates.io) ``` -------------------------------- ### Install ARM GCC Debugger, Minicom, and lsusb on macOS using Homebrew Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/03-setup/macos.md This snippet demonstrates the Homebrew commands to install the ARM GCC debugger, Minicom for serial communication, and lsusb for listing USB devices. These tools are essential for embedded development workflows on macOS. ```console # ARM GCC debugger brew install arm-none-eabi-gdb # Minicom brew install minicom # lsusb (list connected USB devices) brew install lsusb ``` -------------------------------- ### Configure udev Rules for USB Devices Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/03-setup/linux.md Creates a udev rule file to allow access to USB devices like the micro:bit without root privileges. This involves defining vendor and product IDs and reloading udev rules. ```console cat /etc/udev/rules.d/69-microbit.rules ``` ```text # CMSIS-DAP for microbit ACTION!="add|change", GOTO="microbit_rules_end" SUBSYSTEM=="usb", ATTR{idVendor}=="0d28", ATTR{idProduct}=="0204", TAG+="uaccess" LABEL="microbit_rules_end" ``` ```console sudo udevadm control --reload ``` ```console sudo udevadm trigger ``` -------------------------------- ### Main Function Setup with Non-blocking Display Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/11-snake-game/nonblocking-display.md Sets up the main application loop, initializing the non-blocking display and integrating it with the game logic. It initializes buttons, the non-blocking display, and then enters a loop where it continuously displays the game state and updates it based on user input and game progress. ```rust #![no_main] #![no_std] mod game; mod control; mod display; use cortex_m_rt::entry; use microbit::{ Board, hal::{prelude::*, Rng, Timer}, display::nonblocking::{BitImage, GreyscaleImage} }; use rtt_target::rtt_init_print; use panic_rtt_target as _; use crate::control::{get_turn, init_buttons}; use crate::display::{clear_display, display_image, init_display}; use crate::game::{Game, GameStatus}; #[entry] fn main() -> ! { rtt_init_print!(); let mut board = Board::take().unwrap(); let mut timer = Timer::new(board.TIMER0).into_periodic(); let mut rng = Rng::new(board.RNG); let mut game = Game::new(rng.random_u32()); init_buttons(board.GPIOTE, board.buttons); init_display(board.TIMER1, board.display_pins); loop { loop { // Game loop let image = GreyscaleImage::new(&game.game_matrix(6, 3, 9)); display_image(&image); timer.delay_ms(game.step_len_ms()); match game.status { GameStatus::Ongoing => game.step(get_turn(true)), _ => { for _ in 0..3 { clear_display(); timer.delay_ms(200u32); ``` -------------------------------- ### Verify Rust Compiler Version Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/03-setup/README.md This command verifies the installed version of the Rust compiler (`rustc`). Ensure your version is 1.57.0 or newer for compatibility with the project. ```console $ rustc -V rustc 1.53.0 (53cb7b09b 2021-06-17) ``` -------------------------------- ### Initialize Buttons and GPIOTE Interrupts (Rust) Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/11-snake-game/controls.md Initializes the GPIOTE peripheral and configures two channels to detect falling edge events on button A and button B. It enables interrupts for these channels, stores the GPIOTE peripheral reference in the global `GPIO` Mutex, and unmasks the GPIOTE interrupt in the NVIC. This setup allows the system to react to button presses. ```rust use cortex_m::interrupt::free; use microbit::{ board::Buttons, pac::{self, GPIOTE} }; // ... /// Initialise the buttons and enable interrupts. pub(crate) fn init_buttons(board_gpiote: GPIOTE, board_buttons: Buttons) { let gpiote = Gpiote::new(board_gpiote); let channel0 = gpiote.channel0(); channel0 .input_pin(&board_buttons.button_a.degrade()) .hi_to_lo() .enable_interrupt(); channel0.reset_events(); let channel1 = gpiote.channel1(); channel1 .input_pin(&board_buttons.button_b.degrade()) .hi_to_lo() .enable_interrupt(); channel1.reset_events(); free(move |cs| { *GPIO.borrow(cs).borrow_mut() = Some(gpiote); unsafe { pac::NVIC::unmask(pac::Interrupt::GPIOTE); } pac::NVIC::unpend(pac::Interrupt::GPIOTE); }); } ``` -------------------------------- ### GPIO Control for LED with Rust Source: https://context7.com/rust-embedded/discovery/llms.txt Demonstrates controlling an LED using GPIO pins on the micro:bit with Rust. It utilizes the embedded-hal OutputPin trait to set pin states, requiring the Board peripheral and a loop. ```rust #![deny(unsafe_code)] #![no_main] #![no_std] use cortex_m_rt::entry; use panic_halt as _; use microbit::board::Board; use microbit::hal::prelude::*; #[entry] fn main() -> ! { // Take ownership of all board peripherals let mut board = Board::take().unwrap(); // The LED matrix requires setting column low and row high // to light up the LED at the intersection board.display_pins.col1.set_low().unwrap(); board.display_pins.row1.set_high().unwrap(); loop {} } ``` -------------------------------- ### List Connected Debug Probes with probe-rs Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/03-setup/verify.md This command uses the `probe-rs` tool to list all connected debug probes. It's a primary method to verify if `probe-rs` can detect the micro:bit and other supported debug hardware. The output shows the probe's identification details. ```bash $ probe-rs list The following debug probes were found: [0]: BBC micro:bit CMSIS-DAP -- 0d28:0204:990636020005282030f57fa14252d446000000006e052820 (CMSIS-DAP) ``` -------------------------------- ### Configure and Embed Rust Program on micro:bit Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/03-setup/verify.md This section details the process of configuring `cargo-embed` for different micro:bit versions (v1 and v2) by uncommenting the appropriate chip variant in `Embed.toml`. It then shows how to add the necessary Rust target architecture and finally run `cargo embed` to compile, flash, and run a Rust program on the micro:bit. ```toml [default.general] # chip = "nrf52833_xxAA" # uncomment this line for micro:bit V2 # chip = "nrf51822_xxAA" # uncomment this line for micro:bit V1 ``` ```bash # If you are working with micro:bit v2 $ rustup target add thumbv7em-none-eabihf $ cargo embed --target thumbv7em-none-eabihf # If you are working with micro:bit v1 $ rustup target add thumbv6m-none-eabi $ cargo embed --target thumbv6m-none-eabi ``` -------------------------------- ### Initialize Micro:bit Buttons Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/11-snake-game/controls.md Initializes the buttons on the micro:bit for game control. This function takes the GPIOTE and buttons peripherals as input and sets up the necessary configurations for button event handling. ```rust #![no_main] #![no_std] mod game; mod control; use cortex_m_rt::entry; use microbit::{ Board, hal::{prelude::*, Rng, Timer}, display::blocking::Display }; use rtt_target::rtt_init_print; use panic_rtt_target as _; use crate::game::{Game, GameStatus}; use crate::control::{init_buttons, get_turn}; #[entry] fn main() -> ! { rtt_init_print!(); let mut board = Board::take().unwrap(); let mut timer = Timer::new(board.TIMER0); let mut rng = Rng::new(board.RNG); let mut game = Game::new(rng.random_u32()); let mut display = Display::new(board.display_pins); init_buttons(board.GPIOTE, board.buttons); loop { // Main loop loop { // Game loop let image = game.game_matrix(9, 9, 9); // The brightness values are meaningless at the moment as we haven't yet // implemented a display capable of displaying different brightnesses display.show(&mut timer, image, game.step_len_ms()); match game.status { GameStatus::Ongoing => game.step(get_turn(true)), _ => { for _ in 0..3 { display.clear(); timer.delay_ms(200u32); display.show(&mut timer, image, 200); } display.clear(); display.show(&mut timer, game.score_matrix(), 1000); break } } } game.reset(); } } ``` -------------------------------- ### UART Serial Communication Setup for micro:bit v2 in Rust Source: https://context7.com/rust-embedded/discovery/llms.txt Configures the UARTE peripheral for serial communication on the micro:bit v2, supporting DMA. It sets up baud rate and parity, then demonstrates writing a single byte using a non-blocking API. ```rust #![no_main] #![no_std] use cortex_m_rt::entry; use panic_rtt_target as _; use rtt_target::rtt_init_print; use microbit::{ hal::prelude::*, hal::uarte, hal::uarte::{Baudrate, Parity}, }; use embedded_hal_nb::serial::Write; mod serial_setup; use serial_setup::UartePort; #[entry] fn main() -> ! { rtt_init_print!(); let board = microbit::Board::take().unwrap(); // Configure UARTE with 115200 baud, no parity let serial = uarte::Uarte::new( board.UARTE0, board.uart.into(), Parity::EXCLUDED, Baudrate::BAUD115200, ); let mut serial = UartePort::new(serial); // Write a single byte using non-blocking API with nb::block! nb::block!(serial.write(b'X')).unwrap(); nb::block!(serial.flush()).unwrap(); loop {} } ``` -------------------------------- ### Initialize Micro:bit Peripherals and Game Loop in Rust Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/11-snake-game/game-logic.md This snippet initializes the Micro:bit board, timer, random number generator, game state, and display. It then enters a main loop that contains a game loop. The game loop repeatedly generates and displays the game matrix, updates the game state, and handles game over conditions. ```rust #![no_main] #![no_std] mod game; use cortex_m_rt::entry; use microbit::{ Board, hal::{prelude::*, Rng, Timer}, display::blocking::Display }; use rtt_target::rtt_init_print; use panic_rtt_target as _; use crate::game::{Game, GameStatus, Turn}; #[entry] fn main() -> ! { rtt_init_print!(); let mut board = Board::take().unwrap(); let mut timer = Timer::new(board.TIMER0); let mut rng = Rng::new(board.RNG); let mut game = Game::new(rng.random_u32()); let mut display = Display::new(board.display_pins); loop { loop { // Game loop let image = game.game_matrix(9, 9, 9); // The brightness values are meaningless at the moment as we haven't yet // implemented a display capable of displaying different brightnesses display.show(&mut timer, image, game.step_len_ms()); match game.status { GameStatus::Ongoing => game.step(Turn::None), // Placeholder as we // haven't implemented // controls yet _ => { for _ in 0..3 { display.clear(); timer.delay_ms(200u32); display.show(&mut timer, image, 200); } display.clear(); display.show(&mut timer, game.score_matrix(), 1000); break } } } game.reset(); } } ``` -------------------------------- ### Get Detailed Debug Information with probe-rs Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/03-setup/verify.md This command retrieves detailed information about the connected debug probe and the target microcontroller. It attempts to probe using JTAG and SWD protocols, providing insights into the CPU core, memory map, and debug components. This is useful for diagnosing complex connection issues. ```bash $ probe-rs info Probing target via JTAG Error identifying target using protocol JTAG: The probe does not support the JTAG protocol. Probing target via SWD ARM Chip with debug port Default: Debug Port: DPv1, DP Designer: ARM Ltd ├── 0 MemoryAP │ └── ROM Table (Class 1), Designer: Nordic VLSI ASA │ ├── Cortex-M4 SCS (Generic IP component) │ │ └── CPUID │ │ ├── IMPLEMENTER: ARM Ltd │ │ ├── VARIANT: 0 │ │ ├── PARTNO: Cortex-M4 │ │ └── REVISION: 1 │ ├── Cortex-M3 DWT (Generic IP component) │ ├── Cortex-M3 FBP (Generic IP component) │ ├── Cortex-M3 ITM (Generic IP component) │ ├── Cortex-M4 TPIU (Coresight Component) │ └── Cortex-M4 ETM (Coresight Component) └── 1 Unknown AP (Designer: Nordic VLSI ASA, Class: Undefined, Type: 0x0, Variant: 0x0, Revision: 0x0) Debugging RISC-V targets over SWD is not supported. For these targets, JTAG is the only supported protocol. RISC-V specific information cannot be printed. Debugging Xtensa targets over SWD is not supported. For these targets, JTAG is the only supported protocol. Xtensa specific information cannot be printed. ``` -------------------------------- ### Initialize and Control micro:bit Display with Rust Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/05-led-roulette/the-challenge.md Initializes the micro:bit board, timer, and display. It then enters a loop to display a full 5x5 LED matrix for 1000ms, clears the display, and waits for another 1000ms. This demonstrates basic display control using the provided BSP API. ```rust #![deny(unsafe_code)] #![no_main] #![no_std] use cortex_m_rt::entry; use rtt_target::rtt_init_print; use panic_rtt_target as _; use microbit:: board::Board, display::blocking::Display, hal::{prelude::*, Timer}, ; #[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 light_it_all = [ [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], ]; loop { // Show light_it_all for 1000ms display.show(&mut timer, light_it_all, 1000); // clear the display again display.clear(); timer.delay_ms(1000_u32); } } ``` -------------------------------- ### Rust Microcontroller Entry Point and Configuration Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/05-led-roulette/README.md This snippet demonstrates the basic structure of a Rust program for microcontrollers, utilizing `#![no_std]` and `#![no_main]` attributes. It defines a custom entry point using the `cortex-m-rt` crate, which is essential for bare-metal execution. The configuration files (`.cargo/config` and `Embed.toml`) are crucial for tailoring the build process to specific hardware, including memory layout, flashing behavior, and debugging options. ```rust #![no_std] #![no_main] use cortex_m_rt::entry; #[entry] fn main() -> ! { // Application logic goes here loop { // Infinite loop to keep the program running } } ``` ```toml # .cargo/config [target.thumbv7em-none-eabihf] linker = "rust-lld" runner = "arm-none-eabi-gdb" # Embed.toml [ உற்பத்தியாளர் ] chip = "nrf52833" # or "nrf51822" [ flash ] halt_after_reset = true [ debug ] rt_enabled = false gdb_enabled = true ``` -------------------------------- ### Implement Wraparound for Coordinates in Rust Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/11-snake-game/game-logic.md Handles out-of-bounds coordinates by wrapping them around the grid. For example, a coordinate off the left edge appears on the right edge. Assumes out-of-bounds in only one dimension at a time. ```rust fn wraparound(&self, coords: Coords) -> Coords { if coords.row < 0 { Coords { row: 4, ..coords } } else if coords.row >= 5 { Coords { row: 0, ..coords } } else if coords.col < 0 { Coords { col: 4, ..coords } } else { Coords { col: 0, ..coords } } } ``` -------------------------------- ### Micro:bit Sensor and Display with Rust Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/09-led-compass/solution-1.md Initializes the micro:bit board, sets up I2C communication for the LSM303AGR sensor, configures sensor parameters, performs magnetic calibration, and enters a loop to continuously read sensor data, calculate direction, and display it on the LED matrix. It handles both micro:bit v1 and v2 hardware differences for I2C. ```rust #![deny(unsafe_code)] #![no_main] #![no_std] use cortex_m_rt::entry; use panic_rtt_target as _; use rtt_target::{rprintln, rtt_init_print}; mod calibration; use crate::calibration::calc_calibration; use crate::calibration::calibrated_measurement; mod led; use crate::led::Direction; use crate::led::direction_to_led; use microbit::{display::blocking::Display, hal::Timer}; #[cfg(feature = "v1")] use microbit::{hal::twi, pac::twi0::frequency::FREQUENCY_A}; #[cfg(feature = "v2")] use microbit::{hal::twim, pac::twim0::frequency::FREQUENCY_A}; use lsm303agr::{AccelOutputDataRate, Lsm303agr, MagOutputDataRate}; #[entry] fn main() -> ! { rtt_init_print!(); let board = microbit::Board::take().unwrap(); #[cfg(feature = "v1")] let i2c = { twi::Twi::new(board.TWI0, board.i2c.into(), FREQUENCY_A::K100) }; #[cfg(feature = "v2")] let i2c = { twim::Twim::new(board.TWIM0, board.i2c_internal.into(), FREQUENCY_A::K100) }; let mut timer = Timer::new(board.TIMER0); let mut display = Display::new(board.display_pins); let mut sensor = Lsm303agr::new_with_i2c(i2c); sensor.init().unwrap(); sensor.set_mag_odr(MagOutputDataRate::Hz10).unwrap(); sensor.set_accel_odr(AccelOutputDataRate::Hz10).unwrap(); let mut sensor = sensor.into_mag_continuous().ok().unwrap(); let calibration = calc_calibration(&mut sensor, &mut display, &mut timer); rprintln!("Calibration: {:?}", calibration); rprintln!("Calibration done, entering busy loop"); loop { while !sensor.mag_status().unwrap().xyz_new_data {} let mut data = sensor.mag_data().unwrap(); data = calibrated_measurement(data, &calibration); let dir = match (data.x > 0, data.y > 0) { // Quadrant I (true, true) => Direction::NorthEast, // Quadrant II (false, true) => Direction::NorthWest, // Quadrant III (false, false) => Direction::SouthWest, // Quadrant IV (true, false) => Direction::SouthEast, }; // use the led module to turn the direction into an LED arrow // and the led display functions from chapter 5 to display the // arrow display.show(&mut timer, direction_to_led(dir), 100); } } ``` -------------------------------- ### Get Current Turn from Micro:bit Buttons Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/11-snake-game/controls.md Retrieves the current turn status from the micro:bit's buttons. It takes a boolean `reset` argument; if true, it resets the internal turn state to `Turn::None` before returning the current value. ```rust /// Returns the current value of the `TURN` Mutex. /// /// If `reset` is `true`, the value of `TURN` is reset, i.e., set to `Turn::None`. pub fn get_turn(reset: bool) -> Turn { // Placeholder for actual implementation // In a real scenario, this would interact with button press detection // and potentially a shared mutable state (like a Mutex). if reset { Turn::None } else { Turn::None // Replace with actual logic to read turn state } } // Assuming Turn enum is defined elsewhere, e.g.: // #[derive(Clone, Copy, PartialEq)] // pub enum Turn { Player1, Player2, None } ``` -------------------------------- ### Reset Game State in Rust Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/11-snake-game/nonblocking-display.md Resets the game to its initial state. This is typically called at the end of a game round or when a new game is to be started. It ensures all game variables and logic are prepared for a fresh playthrough. ```rust game.reset(); ``` -------------------------------- ### Control micro:bit LED with Rust and embedded-hal Source: https://github.com/rust-embedded/discovery/blob/master/microbit/src/05-led-roulette/light-it-up.md This code snippet demonstrates how to initialize the micro:bit board and control a specific LED on the matrix. It utilizes the `embedded-hal` crate's `OutputPin` trait to set pin states. Dependencies include `cortex-m-rt`, `panic-halt`, and the `microbit` board support package. ```rust #![deny(unsafe_code)] #![no_main] #![no_std] use cortex_m_rt::entry; use panic_halt as _; use microbit::board::Board; use microbit::hal::prelude::*; #[entry] fn main() -> ! { let mut board = Board::take().unwrap(); board.display_pins.col1.set_low().unwrap(); board.display_pins.row1.set_high().unwrap(); loop {} } ``` -------------------------------- ### LED Matrix Display Animation with Timer in Rust Source: https://context7.com/rust-embedded/discovery/llms.txt Implements a roulette animation on the micro:bit's 5x5 LED matrix using a blocking display driver and timer. It defines pixel patterns and cycles through them with specified timing. ```rust #![deny(unsafe_code)] #![no_main] #![no_std] use cortex_m_rt::entry; use rtt_target::rtt_init_print; use panic_rtt_target as _; use microbit::{ board::Board, display::blocking::Display, hal::Timer, }; // Define LED positions for a roulette animation around the edge const PIXELS: [(usize, usize); 16] = [ (0,0), (0,1), (0,2), (0,3), (0,4), (1,4), (2,4), (3,4), (4,4), (4,3), (4,2), (4,1), (4,0), (3,0), (2,0), (1,0) ]; #[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); // 5x5 LED matrix brightness values (0 = off, 1 = on) let mut leds = [ [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], ]; let mut last_led = (0,0); loop { for current_led in PIXELS.iter() { leds[last_led.0][last_led.1] = 0; // Turn off previous LED leds[current_led.0][current_led.1] = 1; // Turn on current LED display.show(&mut timer, leds, 30); // Display for 30ms last_led = *current_led; } } } ``` -------------------------------- ### Minimal Embedded Rust Application Template Source: https://context7.com/rust-embedded/discovery/llms.txt A basic no_std Rust application structure for embedded systems using cortex-m-rt. It sets up the entry point and includes necessary crates for minimal functionality, ensuring the program never returns. ```rust #![deny(unsafe_code)] #![no_main] #![no_std] use cortex_m_rt::entry; use panic_halt as _; use microbit as _; #[entry] fn main() -> ! { let _y; let x = 42; _y = x; // Embedded programs must never return - use infinite loop loop {} } ```