From d2369767b71033061e121cbfe22ea8315b475d0e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 9 Nov 2021 19:10:05 +0100 Subject: [PATCH] BSP update - Add basic LED BSP - Moved generic examples to the HAL - Updated rust edition to 2021 - Updated README to provide full instructions for flashing and building - Added jlink.gdb file to command line flashing --- .cargo/config.toml | 4 +- .github/bors.toml | 2 + .github/workflows/ci.yml | 69 +++++++++++++++++++++ .vscode/launch.json | 22 +++++++ .vscode/tasks.json | 19 ++++++ Cargo.toml | 21 ++++--- README.md | 63 ++++++++++++++++++- examples/blinky-button-irq.rs | 18 ++++++ examples/blinky-leds.rs | 113 ++++++++++++++++++++++++++++++++++ examples/minimal-blinky.rs | 10 --- jlink.gdb | 10 +++ memory.x | 4 +- src/leds.rs | 92 +++++++++++++++++++++++++++ src/lib.rs | 3 + src/main.rs | 3 - 15 files changed, 427 insertions(+), 26 deletions(-) create mode 100644 .github/bors.toml create mode 100644 .github/workflows/ci.yml create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json create mode 100644 examples/blinky-button-irq.rs create mode 100644 examples/blinky-leds.rs delete mode 100644 examples/minimal-blinky.rs create mode 100644 jlink.gdb create mode 100644 src/leds.rs delete mode 100644 src/main.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index c9d858b..dd54ddd 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,8 +1,8 @@ [target.'cfg(all(target_arch = "arm", target_os = "none"))'] # uncomment ONE of these three option to make `cargo run` start a GDB session # which option to pick depends on your system -# runner = "arm-none-eabi-gdb -q -x openocd.gdb" -# runner = "gdb-multiarch -q -x openocd.gdb" +# runner = "arm-none-eabi-gdb -q -x jlink.gdb" +# runner = "gdb-multiarch -q -x jlink.gdb" # runner = "gdb -q -x openocd.gdb" rustflags = [ diff --git a/.github/bors.toml b/.github/bors.toml new file mode 100644 index 0000000..1779788 --- /dev/null +++ b/.github/bors.toml @@ -0,0 +1,2 @@ +status = ["ci"] +delete_merged_branches = true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..cb0b87d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,69 @@ +on: [push] + +name: ci + +jobs: + check: + name: Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + target: thumbv6m-none-eabi + override: true + - uses: actions-rs/cargo@v1 + with: + use-cross: true + command: check + args: --target thumbv6m-none-eabi + - uses: actions-rs/cargo@v1 + with: + use-cross: true + command: check + args: --examples --target thumbv6m-none-eabi + + fmt: + name: Rustfmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + - run: rustup component add rustfmt + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + + clippy: + name: Clippy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + target: thumbv6m-none-eabi + override: true + - run: rustup component add clippy + - uses: actions-rs/cargo@v1 + with: + use-cross: true + command: clippy + args: --target thumbv6m-none-eabi -- -D warnings + + ci: + if: ${{ success() }} + # all new jobs must be added to this list + needs: [check, fmt, clippy] + runs-on: ubuntu-latest + steps: + - name: CI succeeded + run: exit 0 \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..9ca710e --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,22 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "cortex-debug", + "request": "launch", + "name": "Debug Blinky", + "servertype": "jlink", + "gdbPath": "/usr/bin/gdb-multiarch", + "cwd": "${workspaceRoot}", + "device": "VA10820", + "svdFile": "../va108xx-rs/va108xx.svd", + "preLaunchTask": "rust: cargo build minimal blinky", + "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/blinky-leds", + "interface": "jtag", + "runToMain": true, + }, + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..008890f --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,19 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "rust: cargo build blinky", + "type": "shell", + "command": "~/.cargo/bin/cargo", // note: full path to the cargo + "args": [ + "build", "--example", "blinky-leds", + ], + "group": { + "kind": "build", + "isDefault": true + } + }, + ] +} \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index d9a9b2c..63c9962 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,17 +1,24 @@ [package] name = "vorago-reb1" -description = "BSP crate for the Vorago REB1 development Board" version = "0.1.0" -edition = "2018" +authors = ["Robin Mueller "] +edition = "2021" +description = "Board Support Crate for the Vorago REB1 development board" +homepage = "https://github.com/robamu/vorago-reb1-rs" +repository = "https://github.com/robamu/vorago-reb1-rs" license = "MIT OR Apache-2.0" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +keywords = ["no-std", "reb1", "cortex-m", "vorago", "va108xx"] +categories = ["embedded", "no-std", "hardware-support"] [dependencies] +cortex-m = "0.7.3" cortex-m-rt = "0.7.0" +panic-halt = "0.2" +embedded-hal = "0.2.6" +panic-rtt-target = { version = "0.1", features = ["cortex-m"] } +rtt-target = { version = "0.3", features = ["cortex-m"] } -[dependencies.va108xx] -path = "../va108xx-rs" -version = "0.1.0" +[dependencies.va108xx-hal] +version = "0.1" features = ["rt"] diff --git a/README.md b/README.md index 509883c..45f01c1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,61 @@ -# vorago-reb1-rs -Test repository for running Rust code on the REB1 board +# Rust BSP for the Vorago REB1 development board + +This is the Rust **B**oard **S**upport **P**ackage crate for the Vorago REB1 development board. +Its aim is to provide drivers for the board features of the REB1 board + +The BSP builds on top of the [HAL crate for VA108xx devices](https://github.com/robamu-org/va108xx-hal-rs). + +## Building + +Building an application requires the `thumbv6m-none-eabi` cross-compiler toolchain. +If you have not installed it yet, you can do so with + +```sh +rustup target add thumbv6m-none-eabi +``` + +This repository provides some example applications to show how the BSP is used. For example +you can build the blinky example with + +```sh +cargo build --example blinky-leds +``` + +## Flashing from the command line + +A `jlink.gdb` file is provided to allow flashing of the board from the command line. + + +1. Ensure that you have a suitable GDB application like `arm-none-eabi-gdb` or `gdb-multiarch` + installed first. On Windows, you can use [xPacks](https://xpack.github.io/arm-none-eabi-gcc/). + On Linux, you can install `gdb-multiarch` from the package manager. + +2. Install the [JLink Tools](https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPack). + +3. Start the JLink GDB server with the GUI or from the command line. The device should be recognized + automatically + +4. Make sure to select an appropriate runner in the `.cargo/config.toml` file depending on which + GDB application you are using + +5. Use + + ```sh + cargo run --example blinky-leds + ``` + + to flash the board. The debugger should stop at the start of the main. + +## Debugging with VS Code + +The REB1 board features an on-board JTAG, so all that is required to flash the board is a +Micro-USB cable and an +You can debug applications on the REB1 board with a graphical user interface using VS Code with +the [`Cortex-Debug` plugin](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug). + +Some sample configuration files for VS code were provided as well. You can simply use `Run and Debug` +to automatically rebuild and flash your application. + +## Flashing the non-volatile memory + +Coming Soon diff --git a/examples/blinky-button-irq.rs b/examples/blinky-button-irq.rs new file mode 100644 index 0000000..bf01274 --- /dev/null +++ b/examples/blinky-button-irq.rs @@ -0,0 +1,18 @@ +//! Minimal blinky for the REB1 board using only PAC features +#![no_main] +#![no_std] + +use cortex_m_rt::entry; +use panic_halt as _; +use rtt_target::{rprintln, rtt_init_print}; +use va108xx_hal::pac::interrupt; + +#[entry] +fn main() -> ! { + rtt_init_print!(); + rprintln!("-- Vorago Button Blinky --"); + loop {} +} + +#[interrupt] +fn OC15() {} diff --git a/examples/blinky-leds.rs b/examples/blinky-leds.rs new file mode 100644 index 0000000..dfb40be --- /dev/null +++ b/examples/blinky-leds.rs @@ -0,0 +1,113 @@ +//! Blinky examples using the PAC directly, the HAL, or the BSP +//! +//! Additional note on LEDs: +//! Be not afraid: Pulling the GPIOs low makes the LEDs blink. See REB1 +//! schematic for more details. +#![no_main] +#![no_std] + +use cortex_m_rt::entry; +use embedded_hal::digital::v2::ToggleableOutputPin; +use panic_halt as _; +use va108xx_hal::{pac, prelude::*}; +use vorago_reb1::leds::Leds; + +// REB LED pin definitions. All on port A +const LED_D2: u32 = 1 << 10; +const LED_D3: u32 = 1 << 7; +const LED_D4: u32 = 1 << 6; + +#[allow(dead_code)] +enum LibType { + Pac, + Hal, + Bsp, +} + +#[entry] +fn main() -> ! { + let mut dp = pac::Peripherals::take().unwrap(); + let porta = dp.PORTA.split(&mut dp.SYSCONFIG).unwrap(); + let lib_type = LibType::Bsp; + + match lib_type { + LibType::Pac => { + // Enable all peripheral clocks + dp.SYSCONFIG + .peripheral_clk_enable + .modify(|_, w| unsafe { w.bits(0xffffffff) }); + dp.PORTA + .dir() + .modify(|_, w| unsafe { w.bits(LED_D2 | LED_D3 | LED_D4) }); + dp.PORTA + .datamask() + .modify(|_, w| unsafe { w.bits(LED_D2 | LED_D3 | LED_D4) }); + for _ in 0..10 { + dp.PORTA + .clrout() + .write(|w| unsafe { w.bits(LED_D2 | LED_D3 | LED_D4) }); + cortex_m::asm::delay(5_000_000); + dp.PORTA + .setout() + .write(|w| unsafe { w.bits(LED_D2 | LED_D3 | LED_D4) }); + cortex_m::asm::delay(5_000_000); + } + loop { + dp.PORTA + .togout() + .write(|w| unsafe { w.bits(LED_D2 | LED_D3 | LED_D4) }); + cortex_m::asm::delay(25_000_000); + } + } + LibType::Hal => { + let mut led1 = porta + .pa10 + .into_push_pull_output(&mut dp.IOCONFIG, &mut dp.PORTA); + let mut led2 = porta + .pa7 + .into_push_pull_output(&mut dp.IOCONFIG, &mut dp.PORTA); + let mut led3 = porta + .pa6 + .into_push_pull_output(&mut dp.IOCONFIG, &mut dp.PORTA); + for _ in 0..10 { + led1.set_low().ok(); + led2.set_low().ok(); + led3.set_low().ok(); + cortex_m::asm::delay(5_000_000); + led1.set_high().ok(); + led2.set_high().ok(); + led3.set_high().ok(); + cortex_m::asm::delay(5_000_000); + } + loop { + led1.toggle().ok(); + cortex_m::asm::delay(5_000_000); + led2.toggle().ok(); + cortex_m::asm::delay(5_000_000); + led3.toggle().ok(); + cortex_m::asm::delay(5_000_000); + } + } + LibType::Bsp => { + let mut leds = Leds::new(porta, &mut dp.IOCONFIG, &mut dp.PORTA); + loop { + for _ in 0..10 { + // Blink all LEDs quickly + for led in leds.iter_mut() { + led.toggle(); + } + cortex_m::asm::delay(5_000_000); + } + // Now use a wave pattern + loop { + leds[0].toggle(); + cortex_m::asm::delay(5_000_000); + leds[1].toggle(); + cortex_m::asm::delay(5_000_000); + leds[2].toggle(); + cortex_m::asm::delay(5_000_000); + } + } + } + } +} diff --git a/examples/minimal-blinky.rs b/examples/minimal-blinky.rs deleted file mode 100644 index 21c5a8f..0000000 --- a/examples/minimal-blinky.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![no_main] -#![no_std] - -use cortex_m_rt::entry; -use va108xx; - -#[entry] -fn main() -> ! { - let mut dp = va108xx::Peripherals::take(); -} diff --git a/jlink.gdb b/jlink.gdb new file mode 100644 index 0000000..20ff2d5 --- /dev/null +++ b/jlink.gdb @@ -0,0 +1,10 @@ +target remote localhost:2331 + +monitor reset + +# *try* to stop at the user entry point (it might be gone due to inlining) +break main + +load + +continue diff --git a/memory.x b/memory.x index c82d080..1ca0e97 100644 --- a/memory.x +++ b/memory.x @@ -1,7 +1,7 @@ MEMORY { - ROM : ORIGIN = 0x00000000, LENGTH = 0x20000 /* 128K */ - RAM: ORIGIN = 0x10000000, LENGTH = 0x08000 /* 32K */ + FLASH : ORIGIN = 0x00000000, LENGTH = 0x20000 /* 128K */ + RAM : ORIGIN = 0x10000000, LENGTH = 0x08000 /* 32K */ } /* This is where the call stack will be allocated. */ diff --git a/src/leds.rs b/src/leds.rs new file mode 100644 index 0000000..75be733 --- /dev/null +++ b/src/leds.rs @@ -0,0 +1,92 @@ +use va108xx_hal::{ + gpio::{ + porta::{Parts, PA10, PA6, PA7}, + Output, Pin, PushPull, + }, + pac::{IOCONFIG, PORTA}, + prelude::*, +}; + +pub type LD2 = PA10>; +pub type LD3 = PA7>; +pub type LD4 = PA6>; + +pub struct Leds { + leds: [Led; 3], +} + +impl Leds { + pub fn new(led_parts: Parts, iocfg: &mut IOCONFIG, porta: &mut PORTA) -> Self { + let led2 = led_parts.pa10.into_push_pull_output(iocfg, porta); + let led3 = led_parts.pa7.into_push_pull_output(iocfg, porta); + let led4 = led_parts.pa6.into_push_pull_output(iocfg, porta); + Leds { + leds: [led2.into(), led3.into(), led4.into()], + } + } +} + +impl core::ops::Deref for Leds { + type Target = [Led]; + + fn deref(&self) -> &[Led] { + &self.leds + } +} + +impl core::ops::DerefMut for Leds { + fn deref_mut(&mut self) -> &mut [Led] { + &mut self.leds + } +} + +impl core::ops::Index for Leds { + type Output = Led; + + fn index(&self, i: usize) -> &Led { + &self.leds[i] + } +} + +impl core::ops::IndexMut for Leds { + fn index_mut(&mut self, i: usize) -> &mut Led { + &mut self.leds[i] + } +} + +pub struct Led { + pin: Pin>, +} + +macro_rules! ctor { + ($($ldx:ident),+) => { + $( + impl From<$ldx> for Led { + fn from(led: $ldx) -> Self { + Led { + pin: led.downgrade(), + } + } + } + )+ + } +} + +ctor!(LD2, LD3, LD4); + +impl Led { + /// Turns the LED off + pub fn off(&mut self) { + self.pin.set_low().ok(); + } + + /// Turns the LED on + pub fn on(&mut self) { + self.pin.set_high().ok(); + } + + /// Toggles the LED + pub fn toggle(&mut self) { + self.pin.toggle().ok(); + } +} diff --git a/src/lib.rs b/src/lib.rs index e69de29..8ec1ae9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -0,0 +1,3 @@ +#![no_std] + +pub mod leds; diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -}