diff --git a/firmware/.gitignore b/firmware/.gitignore new file mode 100644 index 0000000..dd41f89 --- /dev/null +++ b/firmware/.gitignore @@ -0,0 +1,2 @@ +target/ +firmware.bin diff --git a/firmware/faderboard/.cargo/config b/firmware/faderboard/.cargo/config new file mode 100644 index 0000000..09114c0 --- /dev/null +++ b/firmware/faderboard/.cargo/config @@ -0,0 +1,8 @@ +[build] +target = "thumbv6m-none-eabi" + +[target.thumbv6m-none-eabi] +runner = "./flash.sh" +rustflags = [ + "-C", "link-arg=-Tlink.x", +] diff --git a/firmware/faderboard/Cargo.lock b/firmware/faderboard/Cargo.lock new file mode 100644 index 0000000..9736021 --- /dev/null +++ b/firmware/faderboard/Cargo.lock @@ -0,0 +1,395 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version 0.2.3", +] + +[[package]] +name = "bare-metal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" + +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bxcan" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b13b4b2ea9ab2ba924063ebb86ad895cb79f4a79bf90f27949eb20c335b30f9" +dependencies = [ + "bitflags", + "nb 1.1.0", + "vcell", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cast" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" +dependencies = [ + "rustc_version 0.4.0", +] + +[[package]] +name = "cortex-m" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" +dependencies = [ + "bare-metal 0.2.5", + "bitfield", + "embedded-hal", + "volatile-register", +] + +[[package]] +name = "cortex-m-rt" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee84e813d593101b1723e13ec38b6ab6abbdbaaa4546553f5395ed274079ddb1" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "faderboard" +version = "0.1.0" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "panic-halt", + "stm32f0xx-hal", + "usb-device 0.3.2", + "usbd-hid", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32", + "stable_deref_trait", +] + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "nb" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" + +[[package]] +name = "panic-halt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812" + +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.23", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "ssmarshal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3e6ad23b128192ed337dfa4f1b8099ced0c2bf30d61e551b65fda5916dbb850" +dependencies = [ + "encode_unicode", + "serde", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "stm32-usbd" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6c94998f166d66b210a164648a0b7866428d8f1e0740bf8a4c5edd89d4750c1" +dependencies = [ + "cortex-m", + "usb-device 0.2.9", + "vcell", +] + +[[package]] +name = "stm32f0" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad6efffc472f66098c4ec84d5907b4d001c550db86a7dfa607adf1ba94adbf82" +dependencies = [ + "bare-metal 1.0.0", + "cortex-m", + "cortex-m-rt", + "vcell", +] + +[[package]] +name = "stm32f0xx-hal" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79544d457fe9a119c6fd02f0a16b8c20f39472b03199aac0a307d871a7015ad8" +dependencies = [ + "bare-metal 1.0.0", + "bxcan", + "cast", + "cortex-m", + "embedded-hal", + "nb 1.1.0", + "stm32-usbd", + "stm32f0", + "void", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "usb-device" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f6cc3adc849b5292b4075fc0d5fdcf2f24866e88e336dd27a8943090a520508" + +[[package]] +name = "usb-device" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98816b1accafbb09085168b90f27e93d790b4bfa19d883466b5e53315b5f06a6" +dependencies = [ + "heapless", + "portable-atomic", +] + +[[package]] +name = "usbd-hid" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a2d4546ca3e6a5c6a85584e5caf29feabf3ec35d6cd6b772eb35bd3cff7256" +dependencies = [ + "serde", + "ssmarshal", + "usb-device 0.3.2", + "usbd-hid-macros", +] + +[[package]] +name = "usbd-hid-descriptors" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbee8c6735e90894fba04770bc41e11fd3c5256018856e15dc4dd1e6c8a3dd1" +dependencies = [ + "bitfield", +] + +[[package]] +name = "usbd-hid-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "261079a9ada015fa1acac7cc73c98559f3a92585e15f508034beccf6a2ab75a2" +dependencies = [ + "byteorder", + "proc-macro2", + "quote", + "serde", + "syn 1.0.109", + "usbd-hid-descriptors", +] + +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" +dependencies = [ + "vcell", +] diff --git a/firmware/faderboard/Cargo.toml b/firmware/faderboard/Cargo.toml new file mode 100644 index 0000000..99ffa58 --- /dev/null +++ b/firmware/faderboard/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "faderboard" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +cortex-m = "0.7.7" +cortex-m-rt = "0.7.3" +panic-halt = "0.2.0" +stm32f0xx-hal = { version = "0.18.0", features = ["rt", "stm32f072", "stm32-usbd"] } +usb-device = "0.3.2" +usbd-hid = "0.7.0" diff --git a/firmware/faderboard/build.rs b/firmware/faderboard/build.rs new file mode 100644 index 0000000..d2a1cfe --- /dev/null +++ b/firmware/faderboard/build.rs @@ -0,0 +1,16 @@ +use std::env; +use std::fs; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); + + fs::File::create(out_dir.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + + println!("cargo:rustc-link-search={}", out_dir.display()); + println!("cargo:rerun-if-changed=memory.x"); +} diff --git a/firmware/faderboard/flash.sh b/firmware/faderboard/flash.sh new file mode 100755 index 0000000..3c9227f --- /dev/null +++ b/firmware/faderboard/flash.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +if [ -z "$1" ] +then + echo "usage: $0 " >&1 + exit 1 +fi + +set -eux + +arm-none-eabi-objcopy -O binary "$1" firmware.bin +dfu-util -a 0 -s 0x08000000:leave -D firmware.bin diff --git a/firmware/faderboard/memory.x b/firmware/faderboard/memory.x new file mode 100644 index 0000000..1c307d0 --- /dev/null +++ b/firmware/faderboard/memory.x @@ -0,0 +1,6 @@ +/* STM32F072CxT6 */ +MEMORY +{ + FLASH : ORIGIN = 0x08000000, LENGTH = 128K /* STM32F072C8T6 = 64K, STM32F072CBT6 = 128K */ + RAM : ORIGIN = 0x20000000, LENGTH = 16K +} diff --git a/firmware/faderboard/src/main.rs b/firmware/faderboard/src/main.rs new file mode 100644 index 0000000..bcf3ea1 --- /dev/null +++ b/firmware/faderboard/src/main.rs @@ -0,0 +1,124 @@ +#![no_std] +#![no_main] + +mod touch; + +use cortex_m_rt::entry; + +use panic_halt as _; + +use stm32f0xx_hal as hal; + +use hal::adc::Adc; +use hal::pac::Peripherals; +use hal::prelude::*; + +use touch::Touch; + +#[entry] +fn main() -> ! { + let mut p = Peripherals::take().unwrap(); + + let touch = Touch::new(p.SYSCFG, p.EXTI, &mut p.RCC); + + let mut rcc = p + .RCC + .configure() + .hsi48() + .enable_crs(p.CRS) + .sysclk(48.mhz()) + .pclk(24.mhz()) + .freeze(&mut p.FLASH); + + let gpioa = p.GPIOA.split(&mut rcc); + let gpiob = p.GPIOB.split(&mut rcc); + let gpioc = p.GPIOC.split(&mut rcc); + let gpiof = p.GPIOF.split(&mut rcc); + + #[allow(unused)] + let ( + mut adc3, // ADC_IN0 + mut adc2, // ADC_IN1 + mut adc1, // ADC_IN2 + mut adc8, // ADC_IN3 + mut adc7, // ADC_IN4 + mut adc6, // ADC_IN5 + mut adc5, // ADC_IN6 + mut adc4, // ADC_IN7 + pwm6, // TIM1_CH1 + tx, // USART1_TX + rx, // USART1_RX + usb_dm, // USB_DM + usb_dp, // USB_DP + mut dir5, // PA13 + mut dir4, // PA14 + mut dir3, // PA15 + mut touch4, // PB0 + mut touch5, // PB1 + mut touch6, // PB2 + pwm5, // TIM2_CH2 + pwm4, // TIM3_CH1 + pwm3, // TIM3_CH2 + mut dir2, // PB6 + mut dir1, // PB7 + pwm1, // TIM16_CH1 + pwm2, // TIM17_CH1 + mut touch7, // PB10 + mut touch8, // PB11 + mut dir8, // PB12 + mut dir7, // PB13 + pwm8, // TIM15_CH1 + pwm7, // TIM15_CH2 + mut touch1, // PC13 + mut touch2, // PC14 + mut touch3, // PC15 + mut nsleep, // PF0 + mut dir6, // PF1 + ) = cortex_m::interrupt::free(|cs| { + ( + gpioa.pa0.into_analog(cs), + gpioa.pa1.into_analog(cs), + gpioa.pa2.into_analog(cs), + gpioa.pa3.into_analog(cs), + gpioa.pa4.into_analog(cs), + gpioa.pa5.into_analog(cs), + gpioa.pa6.into_analog(cs), + gpioa.pa7.into_analog(cs), + gpioa.pa8.into_alternate_af2(cs), + gpioa.pa9.into_alternate_af1(cs), + gpioa.pa10.into_alternate_af1(cs), + gpioa.pa11, + gpioa.pa12, + gpioa.pa13.into_push_pull_output(cs), + gpioa.pa14.into_push_pull_output(cs), + gpioa.pa15.into_push_pull_output(cs), + gpiob.pb0.into_open_drain_output(cs), + gpiob.pb1.into_open_drain_output(cs), + gpiob.pb2.into_open_drain_output(cs), + gpiob.pb3.into_alternate_af2(cs), + gpiob.pb4.into_alternate_af1(cs), + gpiob.pb5.into_alternate_af1(cs), + gpiob.pb6.into_push_pull_output(cs), + gpiob.pb7.into_push_pull_output(cs), + gpiob.pb8.into_alternate_af2(cs), + gpiob.pb9.into_alternate_af2(cs), + gpiob.pb10.into_open_drain_output(cs), + gpiob.pb11.into_open_drain_output(cs), + gpiob.pb12.into_push_pull_output(cs), + gpiob.pb13.into_push_pull_output(cs), + gpiob.pb14.into_alternate_af1(cs), + gpiob.pb15.into_alternate_af1(cs), + gpioc.pc13.into_open_drain_output(cs), + gpioc.pc14.into_open_drain_output(cs), + gpioc.pc15.into_open_drain_output(cs), + gpiof.pf0.into_push_pull_output(cs), + gpiof.pf1.into_push_pull_output(cs), + ) + }); + + let mut _adc = Adc::new(p.ADC, &mut rcc); + + touch.setup(); + + loop {} +} diff --git a/firmware/faderboard/src/touch.rs b/firmware/faderboard/src/touch.rs new file mode 100644 index 0000000..0ba875a --- /dev/null +++ b/firmware/faderboard/src/touch.rs @@ -0,0 +1,79 @@ +use stm32f0xx_hal::pac::{interrupt, Interrupt, EXTI, RCC, SYSCFG}; + +pub struct Touch { + exti: EXTI, + syscfg: SYSCFG, +} + +impl Touch { + pub fn new(syscfg: SYSCFG, exti: EXTI, rcc: &mut RCC) -> Self { + cortex_m::interrupt::free(|_| rcc.apb2enr.modify(|_, w| w.syscfgen().set_bit())); + + Self { exti, syscfg } + } + + pub fn setup(&self) { + cortex_m::interrupt::free(|_| { + self.syscfg.exticr1.modify(|_, w| { + w.exti0().pb0(); + w.exti1().pb1(); + w.exti2().pb2(); + w + }); + self.syscfg.exticr3.modify(|_, w| { + w.exti10().pb10(); + w.exti11().pb11(); + w + }); + self.syscfg.exticr4.modify(|_, w| { + w.exti13().pc13(); + w.exti14().pc14(); + w.exti15().pc15(); + w + }); + + self.exti.imr.modify(|_, w| { + w.mr0().unmasked(); + w.mr1().unmasked(); + w.mr2().unmasked(); + w.mr10().unmasked(); + w.mr11().unmasked(); + w.mr13().unmasked(); + w.mr14().unmasked(); + w.mr15().unmasked(); + w + }); + + self.exti.rtsr.modify(|_, w| { + w.tr0().enabled(); + w.tr1().enabled(); + w.tr2().enabled(); + w.tr10().enabled(); + w.tr11().enabled(); + w.tr13().enabled(); + w.tr14().enabled(); + w.tr15().enabled(); + w + }); + + unsafe { + cortex_m::peripheral::NVIC::unmask(Interrupt::EXTI0_1); + cortex_m::peripheral::NVIC::unmask(Interrupt::EXTI2_3); + cortex_m::peripheral::NVIC::unmask(Interrupt::EXTI4_15); + } + + cortex_m::peripheral::NVIC::unpend(Interrupt::EXTI0_1); + cortex_m::peripheral::NVIC::unpend(Interrupt::EXTI2_3); + cortex_m::peripheral::NVIC::unpend(Interrupt::EXTI4_15); + }); + } +} + +#[interrupt] +fn EXTI0_1() {} + +#[interrupt] +fn EXTI2_3() {} + +#[interrupt] +fn EXTI4_15() {}