commit
248e0a21ec
@ -1,8 +1,8 @@
|
|||||||
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
||||||
# uncomment ONE of these three option to make `cargo run` start a GDB session
|
# uncomment ONE of these three option to make `cargo run` start a GDB session
|
||||||
# which option to pick depends on your system
|
# which option to pick depends on your system
|
||||||
# runner = "arm-none-eabi-gdb -q -x openocd.gdb"
|
# runner = "arm-none-eabi-gdb -q -x jlink.gdb"
|
||||||
# runner = "gdb-multiarch -q -x openocd.gdb"
|
# runner = "gdb-multiarch -q -x jlink.gdb"
|
||||||
# runner = "gdb -q -x openocd.gdb"
|
# runner = "gdb -q -x openocd.gdb"
|
||||||
|
|
||||||
rustflags = [
|
rustflags = [
|
||||||
|
2
.github/bors.toml
vendored
Normal file
2
.github/bors.toml
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
status = ["ci"]
|
||||||
|
delete_merged_branches = true
|
69
.github/workflows/ci.yml
vendored
Normal file
69
.github/workflows/ci.yml
vendored
Normal 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
22
.vscode/launch.json
vendored
Normal 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
19
.vscode/tasks.json
vendored
Normal 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
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
21
Cargo.toml
21
Cargo.toml
@ -1,17 +1,24 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "vorago-reb1"
|
name = "vorago-reb1"
|
||||||
description = "BSP crate for the Vorago REB1 development Board"
|
|
||||||
version = "0.1.0"
|
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"
|
license = "MIT OR Apache-2.0"
|
||||||
|
keywords = ["no-std", "reb1", "cortex-m", "vorago", "va108xx"]
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
categories = ["embedded", "no-std", "hardware-support"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
||||||
|
cortex-m = "0.7.3"
|
||||||
cortex-m-rt = "0.7.0"
|
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]
|
[dependencies.va108xx-hal]
|
||||||
path = "../va108xx-rs"
|
version = "0.1"
|
||||||
version = "0.1.0"
|
|
||||||
features = ["rt"]
|
features = ["rt"]
|
||||||
|
63
README.md
63
README.md
@ -1,2 +1,61 @@
|
|||||||
# vorago-reb1-rs
|
# Rust BSP for the Vorago REB1 development board
|
||||||
Test repository for running Rust code on the REB1 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
|
||||||
|
18
examples/blinky-button-irq.rs
Normal file
18
examples/blinky-button-irq.rs
Normal 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
113
examples/blinky-leds.rs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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
10
jlink.gdb
Normal 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
|
4
memory.x
4
memory.x
@ -1,7 +1,7 @@
|
|||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
ROM : ORIGIN = 0x00000000, LENGTH = 0x20000 /* 128K */
|
FLASH : ORIGIN = 0x00000000, LENGTH = 0x20000 /* 128K */
|
||||||
RAM: ORIGIN = 0x10000000, LENGTH = 0x08000 /* 32K */
|
RAM : ORIGIN = 0x10000000, LENGTH = 0x08000 /* 32K */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is where the call stack will be allocated. */
|
/* This is where the call stack will be allocated. */
|
||||||
|
92
src/leds.rs
Normal file
92
src/leds.rs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
#![no_std]
|
||||||
|
|
||||||
|
pub mod leds;
|
@ -1,3 +0,0 @@
|
|||||||
fn main() {
|
|
||||||
println!("Hello, world!");
|
|
||||||
}
|
|
Reference in New Issue
Block a user