From 13b415d7ea1a8db0df875a95374f9a0e590dc254 Mon Sep 17 00:00:00 2001
From: Stephen <webmaster@scd31.com>
Date: Sat, 20 May 2023 14:10:13 -0300
Subject: [PATCH] wip

---
 Cargo.lock  | 200 ++++++++++++++++++++++++++++++++++++-
 Cargo.toml  |  11 +-
 src/main.rs | 282 +++++++++++++++++++++++++---------------------------
 3 files changed, 343 insertions(+), 150 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 364d4f0..505eca1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,13 +2,28 @@
 # It is not intended for manual editing.
 version = 3
 
+[[package]]
+name = "atomic-polyfill"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28"
+dependencies = [
+ "critical-section",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
 [[package]]
 name = "bare-metal"
 version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
 dependencies = [
- "rustc_version",
+ "rustc_version 0.2.3",
 ]
 
 [[package]]
@@ -29,6 +44,12 @@ version = "2.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "24a6904aef64d73cf10ab17ebace7befb918b82164785cb89907993be7f83813"
 
+[[package]]
+name = "byteorder"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+
 [[package]]
 name = "cfg-if"
 version = "1.0.0"
@@ -77,6 +98,34 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "cortex-m-rtic"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d696ae7390bdb9f7978f71ca7144256a2c4616240a6df9002da3c451f9fc8f02"
+dependencies = [
+ "bare-metal 1.0.0",
+ "cortex-m",
+ "cortex-m-rtic-macros",
+ "heapless",
+ "rtic-core",
+ "rtic-monotonic",
+ "version_check",
+]
+
+[[package]]
+name = "cortex-m-rtic-macros"
+version = "1.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eefb40b1ca901c759d29526e5c8a0a1b246c20caaa5b4cc5d0f0b94debecd4c7"
+dependencies = [
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "rtic-syntax",
+ "syn",
+]
+
 [[package]]
 name = "cortex-m-semihosting"
 version = "0.5.0"
@@ -160,6 +209,54 @@ version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a4b1b088ad0a967aa29540456b82fc8903f854775d33f71e9709c4efb3dfbfd2"
 
+[[package]]
+name = "hash32"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "heapless"
+version = "0.7.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743"
+dependencies = [
+ "atomic-polyfill",
+ "hash32",
+ "rustc_version 0.4.0",
+ "spin",
+ "stable_deref_trait",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
+[[package]]
+name = "lock_api"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
 [[package]]
 name = "memchr"
 version = "2.5.0"
@@ -198,12 +295,38 @@ dependencies = [
  "core2",
  "cortex-m",
  "cortex-m-rt",
+ "cortex-m-rtic",
+ "cortex-m-semihosting",
  "panic-semihosting",
  "rf4463",
  "ringbuf",
  "stm32f4xx-hal",
 ]
 
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
 [[package]]
 name = "proc-macro2"
 version = "1.0.47"
@@ -244,15 +367,54 @@ dependencies = [
  "crossbeam-utils",
 ]
 
+[[package]]
+name = "rtic-core"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9369355b04d06a3780ec0f51ea2d225624db777acbc60abd8ca4832da5c1a42"
+
+[[package]]
+name = "rtic-monotonic"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb8b0b822d1a366470b9cea83a1d4e788392db763539dc4ba022bcc787fece82"
+
+[[package]]
+name = "rtic-syntax"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f5e215601dc467752c2bddc6284a622c6f3d2bab569d992adcd5ab7e4cb9478"
+dependencies = [
+ "indexmap",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "rustc_version"
 version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
 dependencies = [
- "semver",
+ "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.17",
+]
+
+[[package]]
+name = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
 [[package]]
 name = "semver"
 version = "0.9.0"
@@ -262,12 +424,27 @@ dependencies = [
  "semver-parser",
 ]
 
+[[package]]
+name = "semver"
+version = "1.0.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
+
 [[package]]
 name = "semver-parser"
 version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 
+[[package]]
+name = "spin"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
+dependencies = [
+ "lock_api",
+]
+
 [[package]]
 name = "stable_deref_trait"
 version = "1.2.0"
@@ -304,7 +481,9 @@ dependencies = [
  "fugit-timer",
  "nb 1.1.0",
  "rand_core",
+ "rtic-monotonic",
  "stm32f4",
+ "systick-monotonic",
  "time",
  "void",
 ]
@@ -320,6 +499,17 @@ dependencies = [
  "unicode-ident",
 ]
 
+[[package]]
+name = "systick-monotonic"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67fb822d5c615a0ae3a4795ee5b1d06381c7faf488d861c0a4fa8e6a88d5ff84"
+dependencies = [
+ "cortex-m",
+ "fugit",
+ "rtic-monotonic",
+]
+
 [[package]]
 name = "time"
 version = "0.3.17"
@@ -347,6 +537,12 @@ version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
 
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
 [[package]]
 name = "void"
 version = "1.0.2"
diff --git a/Cargo.toml b/Cargo.toml
index ecf56b3..00acfd1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,14 +5,21 @@ authors = ["Stephen D <webmaster@scd31.com>"]
 edition = "2021"
 readme = "README.md"
 
+[profile.release]
+codegen-units = 1
+debug = 0
+lto = true
+opt-level = "z"
+
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-stm32f4xx-hal = { version = "0.16", features = ["stm32f411"]}
+stm32f4xx-hal = { version = "0.16", features = ["stm32f411", "rtic"]}
 cortex-m = "0.7"
 cortex-m-rt = "0.7"
-# cortex-m-semihosting = "0.5"
+cortex-m-semihosting = "0.5"
 panic-semihosting = "0.6"
 core2 = { version = "0.3", default_features = false }
 rf4463 = { path = "../rf4463" }
 ringbuf = { version = "0.3", default_features = false }
+cortex-m-rtic = { version = "1.1.4" }
\ No newline at end of file
diff --git a/src/main.rs b/src/main.rs
index f86ce79..250df8d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -10,193 +10,183 @@ extern crate stm32f4xx_hal as hal;
 // #[macro_use(block)]
 // extern crate nb;
 
-use core::cell::RefCell;
-
-use cortex_m::interrupt::{free, Mutex};
-use cortex_m::peripheral::NVIC;
-use hal::gpio::Pull;
-use hal::pac::{self, SPI2};
-use hal::spi::{Event, Mode, Phase, Polarity, Spi, SpiSlave};
-use rf4463::config::RADIO_CONFIG_500_2;
-use rf4463::Rf4463;
-use ringbuf::{Rb, StaticRb};
-
-use crate::hal::{interrupt, prelude::*};
-use crate::rt::ExceptionFrame;
-
-enum SlaveCmd {
-    BufferStatus,
-    SendPacket,
-}
+#[rtic::app(device = stm32f4xx_hal::pac, peripherals = true)]
+mod app {
+    use core::cell::RefCell;
+
+    use cortex_m::interrupt::{free, Mutex};
+    use cortex_m::peripheral::NVIC;
+    use hal::block;
+    use hal::pac::{self, USART1};
+    use hal::serial::{Config, Event, Serial};
+    use hal::spi::{Mode, Phase, Polarity, Spi};
+    use rf4463::config::RADIO_CONFIG_500_2;
+    use rf4463::Rf4463;
+    use ringbuf::{Consumer, Producer, Rb, StaticRb};
+
+    use crate::hal::{interrupt, prelude::*};
+
+    enum SlaveCmd {
+        BufferStatus,
+        SendPacket,
+    }
 
-impl SlaveCmd {
-    pub fn from_u8(i: u8) -> Option<Self> {
-        match i {
-            0 => Some(Self::BufferStatus),
-            1 => Some(Self::SendPacket),
-            _ => None,
+    impl SlaveCmd {
+        pub fn from_u8(i: u8) -> Option<Self> {
+            match i {
+                0 => Some(Self::BufferStatus),
+                1 => Some(Self::SendPacket),
+                _ => None,
+            }
         }
     }
-}
-
-enum SlaveState {
-    Idle,
-    BufferStatus,
-    RecvPacket(usize),
-}
 
-static SPI_SLAVE: Mutex<RefCell<Option<SpiSlave<SPI2, false, u8>>>> =
-    Mutex::new(RefCell::new(None));
+    enum SlaveState {
+        Idle,
+        RecvPacket(usize),
+    }
 
-static SLAVE_STATE: Mutex<RefCell<SlaveState>> = Mutex::new(RefCell::new(SlaveState::Idle));
+    #[shared]
+    struct Shared {}
 
-static BUF: Mutex<RefCell<Option<StaticRb<u8, 16384>>>> = Mutex::new(RefCell::new(None));
+    #[local]
+    struct Local {
+        usart: Serial<USART1>,
+        state: SlaveState,
+        producer: Producer<u8, StaticRb<u8, 16384>>,
+        consumer: Consumer<u8, StaticRb<u8, 16384>>,
+    }
 
-const MODE: Mode = Mode {
-    polarity: Polarity::IdleLow,
-    phase: Phase::CaptureOnFirstTransition,
-};
+    static USART: Mutex<RefCell<Option<Serial<USART1, u8>>>> = Mutex::new(RefCell::new(None));
 
-const PACKET_LEN: usize = 256 + 2 + 65;
+    static SLAVE_STATE: Mutex<RefCell<SlaveState>> = Mutex::new(RefCell::new(SlaveState::Idle));
 
-#[entry]
-fn main() -> ! {
-    let cp = cortex_m::Peripherals::take().unwrap();
-    let dp = pac::Peripherals::take().unwrap();
+    static BUF: Mutex<RefCell<Option<StaticRb<u8, 16384>>>> = Mutex::new(RefCell::new(None));
 
-    let rcc = dp.RCC.constrain();
+    const MODE: Mode = Mode {
+        polarity: Polarity::IdleLow,
+        phase: Phase::CaptureOnFirstTransition,
+    };
 
-    let gpioa = dp.GPIOA.split();
-    let gpiob = dp.GPIOB.split();
+    const PACKET_LEN: usize = 256 + 2 + 65;
 
-    // setup clocks
-    let clocks = rcc.cfgr.use_hse(25.MHz()).sysclk(48.MHz()).freeze();
+    #[init]
+    fn init(mut ctx: init::Context) -> (Shared, Local, init::Monotonics) {
+        let rcc = ctx.device.RCC.constrain();
 
-    // setup 4463 spi
-    let mosi = gpioa.pa7.into_alternate();
-    let miso = gpioa.pa6.into_alternate();
-    let sclk = gpioa.pa5.into_alternate();
+        let gpioa = ctx.device.GPIOA.split();
+        let gpiob = ctx.device.GPIOB.split();
 
-    let sdn = gpioa.pa1.into_push_pull_output();
+        // setup clocks
+        let clocks = rcc.cfgr.use_hse(25.MHz()).sysclk(48.MHz()).freeze();
 
-    let cs = gpioa.pa4.into_push_pull_output();
+        // setup 4463 spi
+        let mosi = gpioa.pa7.into_alternate();
+        let miso = gpioa.pa6.into_alternate();
+        let sclk = gpioa.pa5.into_alternate();
 
-    let spi = Spi::new(dp.SPI1, (sclk, miso, mosi), MODE, 10.MHz(), &clocks);
+        let sdn = gpiob.pb1.into_push_pull_output();
 
-    let delay = dp.TIM2.delay_ms(&clocks);
-    let mut radio = Rf4463::new(spi, sdn, cs, delay, &RADIO_CONFIG_500_2).unwrap();
+        let cs = gpiob.pb0.into_push_pull_output();
 
-    // setup Pi SPI (we're the slave)
-    let sck2 = gpiob.pb13.internal_resistor(Pull::Up);
-    let miso2 = gpiob.pb14.internal_resistor(Pull::Down);
-    let mosi2 = gpiob.pb15.internal_resistor(Pull::Down);
-    let nss = gpiob.pb12.internal_resistor(Pull::Up).into(); // TODO
+        let spi = Spi::new(ctx.device.SPI1, (sclk, miso, mosi), MODE, 10.MHz(), &clocks);
 
-    let mut spi2 = dp.SPI2.spi_slave((sck2, miso2, mosi2, Some(nss)), MODE);
+        let delay = ctx.device.TIM5.delay_us(&clocks);
+        let mut radio = Rf4463::new(spi, sdn, cs, delay, &mut RADIO_CONFIG_500_2.clone()).unwrap();
 
-    // need something in the outgoing buffer for when the master toggles the clock
-    spi2.write(&[0x00]).unwrap();
+        // setup Pi UART
+        let tx = gpioa.pa9;
+        let rx = gpioa.pa10;
 
-    spi2.listen(Event::Rxne);
+        let mut serial = Serial::new(
+            ctx.device.USART1,
+            (tx, rx),
+            Config::default().baudrate(921_600.bps()),
+            &clocks,
+        )
+        .unwrap();
 
-    free(|cs| {
-        BUF.borrow(cs).replace(Some(StaticRb::default()));
-        SPI_SLAVE.borrow(cs).replace(Some(spi2));
-    });
+        serial.listen(Event::Rxne);
 
-    // enable spi2 interrupt
-    unsafe {
-        NVIC::unmask(interrupt::SPI2);
-    }
+        // enable usart interrupt
+        unsafe {
+            NVIC::unmask(interrupt::USART1);
+        }
 
-    let mut data = [0; PACKET_LEN];
-    let mut i = 0;
+        let mut data = [0; PACKET_LEN];
+        let mut i = 0;
 
-    loop {
-        if i == PACKET_LEN {
-            radio.tx(&data).unwrap();
-            i = 0;
-            continue;
-        }
+        loop {
+            if i == PACKET_LEN {
+                radio.tx(&mut data).unwrap();
+                i = 0;
+                continue;
+            }
 
-        free(|cs| {
-            let mut buf = BUF.borrow(cs).borrow_mut();
-            let buf = buf.as_mut().unwrap();
+            free(|cs| {
+                let mut buf = BUF.borrow(cs).borrow_mut();
+                let buf = buf.as_mut().unwrap();
 
-            if let Some(b) = buf.pop() {
-                data[i] = b;
+                if let Some(b) = buf.pop() {
+                    data[i] = b;
 
-                i += 1;
+                    i += 1;
 
-                if buf.free_len() == 16000 {
-                    //block!(USART.borrow(cs).borrow_mut().as_mut().unwrap().write(b'E')).unwrap();
+                    if buf.free_len() == 16000 {
+                        //block!(USART.borrow(cs).borrow_mut().as_mut().unwrap().write(b'E')).unwrap();
+                    }
                 }
-            }
-        });
+            });
+        }
     }
-}
-
-#[exception]
-unsafe fn HardFault(ef: &ExceptionFrame) -> ! {
-    panic!("{:#?}", ef);
-}
 
-#[interrupt]
-fn SPI2() {
-    free(|cs| {
-        let mut state = SLAVE_STATE.borrow(cs).borrow_mut();
+    /*#[exception]
+    unsafe fn HardFault(ef: &ExceptionFrame) -> ! {
+        panic!("{:#?}", ef);
+    }*/
 
-        let mut spi = SPI_SLAVE.borrow(cs).borrow_mut();
-        let spi = spi.as_mut().unwrap();
-
-        let mut buf = BUF.borrow(cs).borrow_mut();
-        let buf = buf.as_mut().unwrap();
+    #[interrupt]
+    fn USART1() {
+        free(|cs| {
+            let mut state = SLAVE_STATE.borrow(cs).borrow_mut();
 
-        let mut x = [0];
-        spi.read(&mut x).unwrap();
+            let mut usart = USART.borrow(cs).borrow_mut();
+            let usart = usart.as_mut().unwrap();
 
-        let out = match *state {
-            SlaveState::Idle => {
-                if let Some(cmd) = SlaveCmd::from_u8(x[0]) {
-                    match cmd {
-                        SlaveCmd::BufferStatus => {
-                            *state = SlaveState::BufferStatus;
+            let mut buf = BUF.borrow(cs).borrow_mut();
+            let buf = buf.as_mut().unwrap();
 
-                            if buf.free_len() < PACKET_LEN {
-                                0x01 // not enough space for a new packet
-                            } else {
-                                0x02 // safe to send a packet
+            let x = block!(usart.read()).unwrap();
+
+            match *state {
+                SlaveState::Idle => {
+                    if let Some(cmd) = SlaveCmd::from_u8(x) {
+                        match cmd {
+                            SlaveCmd::BufferStatus => {
+                                if buf.free_len() < PACKET_LEN {
+                                    block!(usart.write(0x01)).unwrap(); // not enough space for a new packet
+                                } else {
+                                    block!(usart.write(0x02)).unwrap(); // safe to send a packet
+                                }
                             }
-                        }
-
-                        SlaveCmd::SendPacket => {
-                            *state = SlaveState::RecvPacket(PACKET_LEN - 1);
 
-                            0x00
+                            SlaveCmd::SendPacket => {
+                                *state = SlaveState::RecvPacket(PACKET_LEN - 1);
+                            }
                         }
                     }
-                } else {
-                    0x00
                 }
-            }
-            SlaveState::BufferStatus => {
-                *state = SlaveState::Idle;
 
-                0x00
-            }
-            SlaveState::RecvPacket(i) => {
-                *state = if i == 0 {
-                    SlaveState::Idle
-                } else {
-                    SlaveState::RecvPacket(i - 1)
-                };
+                SlaveState::RecvPacket(i) => {
+                    *state = if i == 0 {
+                        SlaveState::Idle
+                    } else {
+                        SlaveState::RecvPacket(i - 1)
+                    };
 
-                buf.push(x[0]).unwrap();
-
-                0x00
-            }
-        };
-
-        spi.write(&[out]).unwrap();
-    });
+                    buf.push(x).unwrap();
+                }
+            };
+        });
+    }
 }
-- 
GitLab