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
This commit is contained in:
Robin Müller 2021-11-09 19:10:05 +01:00
parent 3b3c7da3ed
commit d2369767b7
15 changed files with 427 additions and 26 deletions

View File

@ -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 = [

2
.github/bors.toml vendored Normal file
View File

@ -0,0 +1,2 @@
status = ["ci"]
delete_merged_branches = true

69
.github/workflows/ci.yml vendored Normal file
View File

@ -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

22
.vscode/launch.json vendored Normal file
View File

@ -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,
},
]
}

19
.vscode/tasks.json vendored Normal file
View File

@ -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
}
},
]
}

View File

@ -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 <robin.mueller.m@gmail.com>"]
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"]

View File

@ -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

View File

@ -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() {}

113
examples/blinky-leds.rs Normal file
View File

@ -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);
}
}
}
}
}

View File

@ -1,10 +0,0 @@
#![no_main]
#![no_std]
use cortex_m_rt::entry;
use va108xx;
#[entry]
fn main() -> ! {
let mut dp = va108xx::Peripherals::take();
}

10
jlink.gdb Normal file
View File

@ -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

View File

@ -1,6 +1,6 @@
MEMORY
{
ROM : ORIGIN = 0x00000000, LENGTH = 0x20000 /* 128K */
FLASH : ORIGIN = 0x00000000, LENGTH = 0x20000 /* 128K */
RAM : ORIGIN = 0x10000000, LENGTH = 0x08000 /* 32K */
}

92
src/leds.rs Normal file
View File

@ -0,0 +1,92 @@
use va108xx_hal::{
gpio::{
porta::{Parts, PA10, PA6, PA7},
Output, Pin, PushPull,
},
pac::{IOCONFIG, PORTA},
prelude::*,
};
pub type LD2 = PA10<Output<PushPull>>;
pub type LD3 = PA7<Output<PushPull>>;
pub type LD4 = PA6<Output<PushPull>>;
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<usize> for Leds {
type Output = Led;
fn index(&self, i: usize) -> &Led {
&self.leds[i]
}
}
impl core::ops::IndexMut<usize> for Leds {
fn index_mut(&mut self, i: usize) -> &mut Led {
&mut self.leds[i]
}
}
pub struct Led {
pin: Pin<Output<PushPull>>,
}
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();
}
}

View File

@ -0,0 +1,3 @@
#![no_std]
pub mod leds;

View File

@ -1,3 +0,0 @@
fn main() {
println!("Hello, world!");
}