From 40d717e27a84e6bef02f3195047c6ea44164d2ae Mon Sep 17 00:00:00 2001 From: Serge Bazanski Date: Wed, 17 Apr 2019 21:41:22 +0200 Subject: [PATCH] it works lol --- Cargo.lock | 244 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 19 ++++ default.nix | 12 +++ flash.sh | 7 ++ memory.x | 6 ++ src/main.rs | 171 ++++++++++++++++++++++++++++++++++++ 6 files changed, 459 insertions(+) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 default.nix create mode 100644 flash.sh create mode 100644 memory.x create mode 100644 src/main.rs diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..06966cb --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,244 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "aligned" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bare-metal" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "byteorder" +version = "1.3.1" +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 = "controller" +version = "0.1.0" +dependencies = [ + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cortex-m 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cortex-m-rt 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cortex-m-semihosting 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "nb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "panic-halt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "stm32f1xx-hal 0.2.1 (git+https://github.com/stm32-rs/stm32f1xx-hal?rev=9f95056273525110949923ff83c12e793eac5b5c)", +] + +[[package]] +name = "cortex-m" +version = "0.5.8" +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.4 (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.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cortex-m-rt-macros 0.1.5 (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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.31 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cortex-m-semihosting" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cortex-m 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "embedded-hal" +version = "0.2.2" +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-halt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "proc-macro2" +version = "0.4.27" +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.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.27 (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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "stm32f1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cortex-m 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cortex-m-rt 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "stm32f1xx-hal" +version = "0.2.1" +source = "git+https://github.com/stm32-rs/stm32f1xx-hal?rev=9f95056273525110949923ff83c12e793eac5b5c#9f95056273525110949923ff83c12e793eac5b5c" +dependencies = [ + "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cortex-m 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cortex-m-rt 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "embedded-hal 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "nb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "stm32f1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "0.15.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (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.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a3caf393d93b2d453e80638d0674597020cef3382ada454faacd43d1a55a735a" +"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" +"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" +"checksum cortex-m 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dab2164a0fc216781a47fc343347365112ae6917421d3fa4bac6faf0fbaaaec7" +"checksum cortex-m-rt 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7e1ccc9052352415ec4e3f762f4541098d012016f9354a1a5b2dede39b67f426" +"checksum cortex-m-rt-macros 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d7ae692573e0acccb1579fef1abf5a5bf1d2f3f0149a22b16870ec9309aee25f" +"checksum cortex-m-semihosting 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d1dc2abec1a772e8bb697cad17d5710f180043caf8939820f0f6ba4b7ae2a4b5" +"checksum embedded-hal 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9880e55238830314d41d88f1ac7a819d495799c3cc3bc392cc172bab26428c33" +"checksum nb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "69f380b5fe9fab8c0d7a6a99cda23e2cc0463bedb2cbc3aada0813b98496ecdc" +"checksum panic-halt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812" +"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" +"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" +"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f" +"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +"checksum stm32f1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5c9a197094ef680c79c5018701f0c03f0dc673cbf4a0df944371d3f83c71161d" +"checksum stm32f1xx-hal 0.2.1 (git+https://github.com/stm32-rs/stm32f1xx-hal?rev=9f95056273525110949923ff83c12e793eac5b5c)" = "" +"checksum syn 0.15.31 (registry+https://github.com/rust-lang/crates.io-index)" = "d2b4cfac95805274c6afdb12d8f770fa2d27c045953e7b630a81801953699a9a" +"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/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..fe60af9 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "controller" +version = "0.1.0" +authors = ["Serge Bazanski "] +edition = "2018" + +[profile.release] +opt-level = 's' +lto = true +debug = true + +[dependencies] +stm32f1xx-hal = {git = "https://github.com/stm32-rs/stm32f1xx-hal", rev = "9f95056273525110949923ff83c12e793eac5b5c", features = ["stm32f103", "rt"]} +panic-halt = "0.2.0" +nb = "0.1.1" +cortex-m = "0.5.8" +cortex-m-rt = "0.6.8" +cortex-m-semihosting = "0.3.2" +byteorder = { version = "1.3.1", default-features = false } diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..c5144b6 --- /dev/null +++ b/default.nix @@ -0,0 +1,12 @@ +with import {}; + + +stdenv.mkDerivation rec { + name = "venv"; + env = buildEnv { name = name; paths = buildInputs; }; + buildInputs = [ + gcc-arm-embedded + rustup + openocd + ]; +} diff --git a/flash.sh b/flash.sh new file mode 100644 index 0000000..6029384 --- /dev/null +++ b/flash.sh @@ -0,0 +1,7 @@ +#!/bin/sh +set -e + +cargo build --release +arm-none-eabi-objcopy -O binary target/thumbv7m-none-eabi/release/controller controller.bin +sudo openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c "program controller.bin 0x08000000" -c "arm semihosting enable" -c "reset run" + diff --git a/memory.x b/memory.x new file mode 100644 index 0000000..71f245d --- /dev/null +++ b/memory.x @@ -0,0 +1,6 @@ +/* Linker script for the STM32F103C8T6 */ +MEMORY +{ + FLASH : ORIGIN = 0x08000000, LENGTH = 64K + RAM : ORIGIN = 0x20000000, LENGTH = 20K +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..5727151 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,171 @@ +//! Blinks an LED +//! +//! This assumes that a LED is connected to pc13 as is the case on the blue pill board. +//! +//! Note: Without additional hardware, PC13 should not be used to drive an LED, see page 5.1.2 of +//! the reference manaual for an explanation. This is not an issue on the blue pill. + +#![deny(unsafe_code)] +#![deny(warnings)] +#![no_std] +#![no_main] + +extern crate panic_halt; +extern crate cortex_m_semihosting; + +use nb::block; + +use stm32f1xx_hal::{ + prelude::*, + pac, + timer::Timer, + serial::Serial, +}; +use cortex_m_rt::entry; +//use cortex_m_semihosting::hprintln; +use stm32f1xx_hal::adc; + +extern crate byteorder; +use byteorder::{ByteOrder, LittleEndian}; + +struct RangeConverter { + // Input specifics + left: u16, + center: u16, + right: u16, + deadzone: u16, + + // Output range + min: i16, + max: i16, +} + +impl RangeConverter { + fn convert(&self, value: u16) -> i16 { + if value <= self.left { + return self.min + } + if value >= self.right { + return self.max + } + + let cd: u16 = if value > self.center { + value - self.center + } else { + self.center - value + }; + + if cd <= self.deadzone { + return 0; + } + + // Value outside of deadzone. + let cv: i16 = (cd - self.deadzone) as i16; + if value > self.center { + let md: i32 = ((self.right - self.center) - self.deadzone) as i32; + let val: i32 = (self.max as i32) * (cv as i32) / md; + return val as i16; + } else { + let md: i32 = ((self.center - self.left) - self.deadzone) as i32; + let val: i32 = (self.min as i32) * (cv as i32) / md; + return val as i16; + } + } +} + +#[entry] +fn main() -> ! { + // Get access to the core peripherals from the cortex-m crate + let cp = cortex_m::Peripherals::take().unwrap(); + // Get access to the device specific peripherals from the peripheral access crate + let dp = pac::Peripherals::take().unwrap(); + + // Take ownership over the raw flash and rcc devices and convert them into the corresponding + // HAL structs + let mut flash = dp.FLASH.constrain(); + let mut rcc = dp.RCC.constrain(); + let mut afio = dp.AFIO.constrain(&mut rcc.apb2); + + // Freeze the configuration of all the clocks in the system and store the frozen frequencies in + // `clocks` + let clocks = rcc.cfgr.adcclk(2.mhz()).freeze(&mut flash.acr); + //hprintln!("adc freq: {}", clocks.adcclk().0).unwrap(); + + // Acquire the GPIOC peripheral + let mut gpioa = dp.GPIOA.split(&mut rcc.apb2); + let mut gpiob = dp.GPIOB.split(&mut rcc.apb2); + let mut gpioc = dp.GPIOC.split(&mut rcc.apb2); + + // Configure gpio C pin 13 as a push-pull output. The `crh` register is passed to the function + // in order to configure the port. For pins 0-7, crl should be passed instead. + let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh); + // Configure the syst timer to trigger an update every second + let mut timer = Timer::syst(cp.SYST, 30.hz(), clocks); + + let mut adc1 = adc::Adc::adc1(dp.ADC1, &mut rcc.apb2); + + let mut ch0 = gpiob.pb0.into_analog(&mut gpiob.crl); + let mut ch1 = gpiob.pb1.into_analog(&mut gpiob.crl); + let mut ch2 = gpioa.pa0.into_analog(&mut gpioa.crl); + + let fire = gpioc.pc14.into_pull_up_input(&mut gpioc.crh); + let tx = gpioa.pa2.into_alternate_push_pull(&mut gpioa.crl); + let rx = gpioa.pa3; + let serial = Serial::usart2( + dp.USART2, + (tx, rx), + &mut afio.mapr, + 19_200.bps(), + clocks, + &mut rcc.apb1, + ); + let (mut tx, mut _rx) = serial.split(); + + let rcx = RangeConverter{ + left: 2064, + center: 3026, + right: 4096, + deadzone: 300, + + min: -1000, + max: 1000, + }; + let rcy = RangeConverter{ + left: 2250, + center: 3000, + right: 4096, + deadzone: 100, + + min: -1000, + max: 1000, + }; + + // Wait for the timer to trigger an update and change the state of the LED + loop { + block!(timer.wait()).unwrap(); + led.set_high(); + block!(timer.wait()).unwrap(); + led.set_low(); + + let data0: u16 = adc1.read(&mut ch0).unwrap(); + let data1: u16 = adc1.read(&mut ch1).unwrap(); + let _data2: u16 = adc1.read(&mut ch2).unwrap(); + + let x: i16 = -rcx.convert(data0); + let y: i16 = rcy.convert(data1); + + let mut bufx = [0, 0]; + let mut bufy = [0, 0]; + if fire.is_low() { + LittleEndian::write_i16(&mut bufx, x); + LittleEndian::write_i16(&mut bufy, y); + } else { + LittleEndian::write_i16(&mut bufx, 0); + LittleEndian::write_i16(&mut bufy, 0); + }; + block!(tx.write(bufx[0])).ok(); + block!(tx.write(bufx[1])).ok(); + block!(tx.write(bufy[0])).ok(); + block!(tx.write(bufy[1])).ok(); + } +}