From 643d2870b59541366da84b0e9d2d2a48dfcf347f Mon Sep 17 00:00:00 2001 From: Tim Docker <tim@dockerz.net> Date: Mon, 8 Oct 2018 10:21:06 +1100 Subject: [PATCH] sport protocol demonstration --- sport-demo/.cargo/config | 10 ++ sport-demo/.gdbinit | 21 ++++ sport-demo/Cargo.lock | 205 +++++++++++++++++++++++++++++++++++++++ sport-demo/Cargo.toml | 49 ++++++++++ sport-demo/README.md | 11 +++ sport-demo/build.rs | 18 ++++ sport-demo/memory.x | 22 +++++ sport-demo/src/main.rs | 87 +++++++++++++++++ sport-demo/src/sbus.rs | 51 ++++++++++ 9 files changed, 474 insertions(+) create mode 100644 sport-demo/.cargo/config create mode 100644 sport-demo/.gdbinit create mode 100644 sport-demo/Cargo.lock create mode 100644 sport-demo/Cargo.toml create mode 100644 sport-demo/README.md create mode 100644 sport-demo/build.rs create mode 100644 sport-demo/memory.x create mode 100644 sport-demo/src/main.rs create mode 100644 sport-demo/src/sbus.rs diff --git a/sport-demo/.cargo/config b/sport-demo/.cargo/config new file mode 100644 index 0000000..d62cf99 --- /dev/null +++ b/sport-demo/.cargo/config @@ -0,0 +1,10 @@ +[target.thumbv7em-none-eabi] +runner = 'arm-none-eabi-gdb' +rustflags = [ +# "-C", "linker=arm-none-eabi-gcc", +# "-C", "link-arg=-Wl,-Tlink.x", +# "-C", "link-arg=-nostartfiles" + "-C", "link-arg=-Tlink.x" +] +[build] +target = "thumbv7em-none-eabi" diff --git a/sport-demo/.gdbinit b/sport-demo/.gdbinit new file mode 100644 index 0000000..0c4f8c8 --- /dev/null +++ b/sport-demo/.gdbinit @@ -0,0 +1,21 @@ +target remote :3333 + +# print demangled symbols by default +set print asm-demangle on + +#monitor arm semihosting enable + +# # send captured ITM to the file itm.fifo +# # (the microcontroller SWO pin must be connected to the programmer SWO pin) +# # 8000000 must match the core clock frequency +monitor tpiu config internal itm.fifo uart off 168000000 + +# # OR: make the microcontroller SWO pin output compatible with UART (8N1) +# # 2000000 is the frequency of the SWO pin +# monitor tpiu config external uart off 8000000 2000000 + +# # enable ITM port 0 +monitor itm port 0 on + +load +step diff --git a/sport-demo/Cargo.lock b/sport-demo/Cargo.lock new file mode 100644 index 0000000..c66acfa --- /dev/null +++ b/sport-demo/Cargo.lock @@ -0,0 +1,205 @@ +[[package]] +name = "aligned" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bare-metal" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cast" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cortex-m" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aligned 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bare-metal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cortex-m-rt" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cortex-m-rt-macros 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "embedded-hal" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nb" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "panic-itm" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cortex-m 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro2" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "r0" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "sport-demo" +version = "0.0.1" +dependencies = [ + "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cortex-m 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cortex-m-rt 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "embedded-hal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "nb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "panic-itm 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "stm32f407g-disc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "stm32f4xx-hal 0.1.0", +] + +[[package]] +name = "stm32f4" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bare-metal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cortex-m 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cortex-m-rt 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "stm32f407g-disc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cortex-m 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cortex-m-rt 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "embedded-hal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "stm32f4xx-hal 0.1.0", +] + +[[package]] +name = "stm32f4xx-hal" +version = "0.1.0" +dependencies = [ + "bare-metal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cortex-m 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cortex-m-rt 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "embedded-hal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "nb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "stm32f4 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "vcell" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "volatile-register" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[metadata] +"checksum aligned 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d39da9b88ae1a81c03c9c082b8db83f1d0e93914126041962af61034ab44c4a5" +"checksum bare-metal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1bdcf9294ed648c7cd29b11db06ea244005aeef50ae8f605b1a3af2940bf8f92" +"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" +"checksum cortex-m 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)" = "4573199c5b1e9b0eeae418b46f7c0af5fdf11b3057f83880810dfef68dd1dcb5" +"checksum cortex-m-rt 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d86cfa89fa220d3cb7a41133693e2d302d18e9a632298ffb3738f175c8c12325" +"checksum cortex-m-rt-macros 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3139fdadccaa0db6fa96637678ced9b0b97e4f10047c9ab603d125048e107d1a" +"checksum embedded-hal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "26944677e4934eb5fb4025501dc0d6cdbcf6bfabd6200fcfee2e7e8eef8c0362" +"checksum nb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "69f380b5fe9fab8c0d7a6a99cda23e2cc0463bedb2cbc3aada0813b98496ecdc" +"checksum panic-itm 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2f8558d6f59b9d74b4c34588604b7d9382060218abd5ec3fc01157c97838666" +"checksum proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "ffe022fb8c8bd254524b0b3305906c1921fa37a84a644e29079a9e62200c3901" +"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" +"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f" +"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" +"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" +"checksum stm32f4 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9dd897c48dc34c0483a190715a0d4e0e805308fbefabcf941e4e2948d6f622" +"checksum stm32f407g-disc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57197f804593fc9fd73af204996b347d5279946d9e3d555ff19f0b0090a680cc" +"checksum syn 0.15.8 (registry+https://github.com/rust-lang/crates.io-index)" = "356d1c5043597c40489e9af2d2498c7fefc33e99b7d75b43be336c8a59b3e45e" +"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45c297f0afb6928cd08ab1ff9d95e99392595ea25ae1b5ecf822ff8764e57a0d" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286" diff --git a/sport-demo/Cargo.toml b/sport-demo/Cargo.toml new file mode 100644 index 0000000..d744fd0 --- /dev/null +++ b/sport-demo/Cargo.toml @@ -0,0 +1,49 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "sport-demo" +version = "0.0.1" +authors = ["Tim Docker<tim@dockerz.net>"] +description = "A flashing light" +keywords = ["arm", "cortex-m"] +categories = ["embedded", "no-std"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/timbod7/..." + +[dependencies.cast] +version = "0.2.2" +default-features = false + +[dependencies.stm32f407g-disc] +version = "0.1.0" + +[dependencies.embedded-hal] +version = "0.2.1" + +[dependencies.cortex-m] +version = "0.5.7" + +[dependencies.cortex-m-rt] +version = "0.6.4" + +[dependencies.panic-itm] +version = "0.4.0" + +[dependencies.nb] +version = "0.1.1" + +[dependencies.stm32f4xx-hal] +version = "0.1.0" + +[patch.crates-io] +stm32f4xx-hal = { path = "../../repos-3rd-party/stm32f4xx-hal" } \ No newline at end of file diff --git a/sport-demo/README.md b/sport-demo/README.md new file mode 100644 index 0000000..abd47ca --- /dev/null +++ b/sport-demo/README.md @@ -0,0 +1,11 @@ +Run the binary on the stm32f407 discovery board as per normal. With +the gdb configuration as in this directory, an itm.fifo file will be +written. + +Run this command: + +``` +itmdump -F -f itm.fifo +``` + +to follow it. diff --git a/sport-demo/build.rs b/sport-demo/build.rs new file mode 100644 index 0000000..98f603e --- /dev/null +++ b/sport-demo/build.rs @@ -0,0 +1,18 @@ +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + // Put the linker script somewhere the linker can find it + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + // Only re-run the build script when memory.x is changed, + // instead of when any part of the source code changes. + println!("cargo:rerun-if-changed=memory.x"); +} diff --git a/sport-demo/memory.x b/sport-demo/memory.x new file mode 100644 index 0000000..f4df782 --- /dev/null +++ b/sport-demo/memory.x @@ -0,0 +1,22 @@ +MEMORY +{ + /* NOTE K = KiBi = 1024 bytes */ + FLASH : ORIGIN = 0x08000000, LENGTH = 256K + RAM : ORIGIN = 0x20000000, LENGTH = 40K +} + +/* This is where the call stack will be allocated. */ +/* The stack is of the full descending type. */ +/* You may want to use this variable to locate the call stack and static + variables in different memory regions. Below is shown the default value */ +/* _stack_start = ORIGIN(RAM) + LENGTH(RAM); */ + +/* You can use this symbol to customize the location of the .text section */ +/* If omitted the .text section will be placed right after the .vector_table + section */ +/* This is required only on microcontrollers that store some configuration right + after the vector table */ +/* _stext = ORIGIN(FLASH) + 0x400; */ + +/* Size of the heap (in bytes) */ +/* _heap_size = 1024; */ diff --git a/sport-demo/src/main.rs b/sport-demo/src/main.rs new file mode 100644 index 0000000..2d924ac --- /dev/null +++ b/sport-demo/src/main.rs @@ -0,0 +1,87 @@ +#![no_main] +#![no_std] + +extern crate cortex_m; +extern crate cortex_m_rt; +extern crate panic_itm; + +extern crate stm32f407g_disc as board; +extern crate embedded_hal as hal; + +use cortex_m_rt::entry; + +use board::hal::delay::Delay; +use board::hal::prelude::*; +use board::hal::stm32; +use board::gpio; +use board::gpio::gpiod::{PD12, PD13, PD14, PD15}; +use board::hal::serial; +use board::hal::serial::{Serial}; + +#[macro_use(block)] +extern crate nb; +mod sbus; + +use hal::digital::OutputPin; + +use cortex_m::iprintln; +use cortex_m::peripheral::Peripherals; + +struct Leds { + green: PD12<gpio::Output<gpio::PushPull>>, + orange: PD13<gpio::Output<gpio::PushPull>>, + red: PD14<gpio::Output<gpio::PushPull>>, + blue: PD15<gpio::Output<gpio::PushPull>>, +} + +#[entry] +fn main() -> ! { + if let (Some(p), Some(cp)) = (stm32::Peripherals::take(), Peripherals::take()) { + let gpiod = p.GPIOD.split(); + let mut itm = cp.ITM; + + // Constrain clock registers + let mut rcc = p.RCC.constrain(); + + // Configure clock to 168 MHz (i.e. the maximum) and freeze it + let clocks = rcc.cfgr.sysclk(168.mhz()).freeze(); + + // USART2 at PD5 (TX) and PD6(RX) + let txpin = gpiod.pd5.into_alternate_af7(); + let rxpin = gpiod.pd6.into_alternate_af7(); + let config = serial::config::Config::default() + .baudrate(100_000.bps()) + .parity_even() + .wordlength_9() + .stopbits(serial::config::StopBits::STOP2); + let serial = Serial::usart2(p.USART2, (txpin, rxpin), config, clocks).unwrap(); + + let (mut tx, mut rx) = serial.split(); + + // Get delay provider + let mut delay = Delay::new(cp.SYST, clocks); + + iprintln!(&mut itm.stim[0], "start" ); + + let mut state = sbus::SbusReadState::default(); + + loop { + let received = block!(rx.read()); + match received { + Ok(c) => { + let complete = sbus::process_char(&mut state, c); + if complete { + iprintln!(&mut itm.stim[0], "{} {}", state.frame.channels[0], state.frame.channels[1] ); + } + }, + Err(e) => { + iprintln!(&mut itm.stim[0], "err" ); + + }, + } + + } + } + + loop {} +} \ No newline at end of file diff --git a/sport-demo/src/sbus.rs b/sport-demo/src/sbus.rs new file mode 100644 index 0000000..d9c0876 --- /dev/null +++ b/sport-demo/src/sbus.rs @@ -0,0 +1,51 @@ +#[derive(Default)] +pub struct SbusFrame { + pub channels: [u16; 16], + pub channel17: bool, + pub channel18: bool, + pub frame_lost: bool, + pub failsafe: bool +} + +#[derive(Default)] +pub struct SbusReadState { + pub bytei: u16, + pub frame: SbusFrame, +} + +pub fn process_idle(state: &mut SbusReadState) { + *state = SbusReadState::default(); +} + +pub fn process_char(state: &mut SbusReadState, c: u8) -> bool { + if state.bytei == 0 { + if c == 0x0f { + state.bytei = state.bytei + 1; + state.frame = SbusFrame::default(); + } + false + } else if state.bytei < 23 { + let c16: u16 = c.into(); + let biti = (state.bytei - 1) * 8; + let x = c16 << (biti % 11); + let y = x >> 11; + let ci: usize = (biti / 11).into(); + state.frame.channels[ci] = (state.frame.channels[ci] | x) & 0b11111111111; + if y != 0 { + state.frame.channels[ci+1] |= y; + } + state.bytei = state.bytei + 1; + false + } else if state.bytei == 23 { + state.frame.channel17 = c & 1 != 0; + state.frame.channel18 = c & 2 != 0; + state.frame.frame_lost = c & 4 != 0; + state.frame.failsafe = c & 8 != 0; + state.bytei = state.bytei + 1; + false + } else { + state.bytei = 0; + // success if the last byte was 0 + c == 0 + } +} \ No newline at end of file -- GitLab