From 038317f54b1bb1b02f1649ca4e50c9a5db741a93 Mon Sep 17 00:00:00 2001
From: Stephen D <webmaster@scd31.com>
Date: Sun, 28 May 2023 11:01:47 -0300
Subject: [PATCH] works, in theory

---
 src/main.rs | 152 ++++++++++++++++++++++++++--------------------------
 1 file changed, 77 insertions(+), 75 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 250df8d..7d99950 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,30 +2,41 @@
 #![no_std]
 
 extern crate cortex_m;
-#[macro_use(entry, exception)]
 extern crate cortex_m_rt as rt;
 extern crate panic_semihosting;
 
 extern crate stm32f4xx_hal as hal;
-// #[macro_use(block)]
-// extern crate nb;
 
 #[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::gpio;
+    use hal::pac::{SPI1, TIM5, USART1};
     use hal::serial::{Config, Event, Serial};
     use hal::spi::{Mode, Phase, Polarity, Spi};
+    use hal::timer::Delay;
     use rf4463::config::RADIO_CONFIG_500_2;
     use rf4463::Rf4463;
-    use ringbuf::{Consumer, Producer, Rb, StaticRb};
+    use ringbuf::{Rb, StaticRb};
 
     use crate::hal::{interrupt, prelude::*};
 
+    const PACKET_LEN: usize = 256 + 2 + 65;
+    const BUFFER_LEN: usize = 16_384;
+
+    const MODE: Mode = Mode {
+        polarity: Polarity::IdleLow,
+        phase: Phase::CaptureOnFirstTransition,
+    };
+
+    type Radio = Rf4463<
+        Spi<SPI1>,
+        gpio::Pin<'B', 1, gpio::Output>,
+        gpio::Pin<'B', 0, gpio::Output>,
+        Delay<TIM5, 1000000>,
+    >;
+
     enum SlaveCmd {
         BufferStatus,
         SendPacket,
@@ -41,37 +52,25 @@ mod app {
         }
     }
 
-    enum SlaveState {
+    pub enum SlaveState {
         Idle,
         RecvPacket(usize),
     }
 
     #[shared]
-    struct Shared {}
+    struct Shared {
+        tx_buf: StaticRb<u8, BUFFER_LEN>,
+    }
 
     #[local]
     struct Local {
+        radio: Radio,
         usart: Serial<USART1>,
         state: SlaveState,
-        producer: Producer<u8, StaticRb<u8, 16384>>,
-        consumer: Consumer<u8, StaticRb<u8, 16384>>,
     }
 
-    static USART: Mutex<RefCell<Option<Serial<USART1, u8>>>> = Mutex::new(RefCell::new(None));
-
-    static SLAVE_STATE: Mutex<RefCell<SlaveState>> = Mutex::new(RefCell::new(SlaveState::Idle));
-
-    static BUF: Mutex<RefCell<Option<StaticRb<u8, 16384>>>> = Mutex::new(RefCell::new(None));
-
-    const MODE: Mode = Mode {
-        polarity: Polarity::IdleLow,
-        phase: Phase::CaptureOnFirstTransition,
-    };
-
-    const PACKET_LEN: usize = 256 + 2 + 65;
-
     #[init]
-    fn init(mut ctx: init::Context) -> (Shared, Local, init::Monotonics) {
+    fn init(ctx: init::Context) -> (Shared, Local, init::Monotonics) {
         let rcc = ctx.device.RCC.constrain();
 
         let gpioa = ctx.device.GPIOA.split();
@@ -92,13 +91,13 @@ mod app {
         let spi = Spi::new(ctx.device.SPI1, (sclk, miso, mosi), MODE, 10.MHz(), &clocks);
 
         let delay = ctx.device.TIM5.delay_us(&clocks);
-        let mut radio = Rf4463::new(spi, sdn, cs, delay, &mut RADIO_CONFIG_500_2.clone()).unwrap();
+        let radio = Rf4463::new(spi, sdn, cs, delay, &mut RADIO_CONFIG_500_2.clone()).unwrap();
 
         // setup Pi UART
         let tx = gpioa.pa9;
         let rx = gpioa.pa10;
 
-        let mut serial = Serial::new(
+        let mut usart = Serial::new(
             ctx.device.USART1,
             (tx, rx),
             Config::default().baudrate(921_600.bps()),
@@ -106,27 +105,39 @@ mod app {
         )
         .unwrap();
 
-        serial.listen(Event::Rxne);
+        usart.listen(Event::Rxne);
 
         // enable usart interrupt
         unsafe {
             NVIC::unmask(interrupt::USART1);
         }
 
+        (
+            Shared {
+                tx_buf: StaticRb::default(),
+            },
+            Local {
+                radio,
+                usart,
+                state: SlaveState::Idle,
+            },
+            init::Monotonics(),
+        )
+    }
+
+    #[idle(local = [radio], shared=[tx_buf])]
+    fn idle(mut ctx: idle::Context) -> ! {
         let mut data = [0; PACKET_LEN];
         let mut i = 0;
 
         loop {
             if i == PACKET_LEN {
-                radio.tx(&mut data).unwrap();
+                ctx.local.radio.tx(&mut data).unwrap();
                 i = 0;
                 continue;
             }
 
-            free(|cs| {
-                let mut buf = BUF.borrow(cs).borrow_mut();
-                let buf = buf.as_mut().unwrap();
-
+            ctx.shared.tx_buf.lock(|buf| {
                 if let Some(b) = buf.pop() {
                     data[i] = b;
 
@@ -140,53 +151,44 @@ mod app {
         }
     }
 
-    /*#[exception]
-    unsafe fn HardFault(ef: &ExceptionFrame) -> ! {
-        panic!("{:#?}", ef);
-    }*/
-
-    #[interrupt]
-    fn USART1() {
-        free(|cs| {
-            let mut state = SLAVE_STATE.borrow(cs).borrow_mut();
-
-            let mut usart = USART.borrow(cs).borrow_mut();
-            let usart = usart.as_mut().unwrap();
-
-            let mut buf = BUF.borrow(cs).borrow_mut();
-            let buf = buf.as_mut().unwrap();
-
-            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
-                                }
-                            }
+    #[task(binds = USART1, local = [state, usart], shared = [tx_buf])]
+    fn usart1(ctx: usart1::Context) {
+        let state = ctx.local.state;
 
-                            SlaveCmd::SendPacket => {
-                                *state = SlaveState::RecvPacket(PACKET_LEN - 1);
+        let usart = ctx.local.usart;
+
+        let mut buf = ctx.shared.tx_buf;
+
+        let x = block!(usart.read()).unwrap();
+
+        match *state {
+            SlaveState::Idle => {
+                if let Some(cmd) = SlaveCmd::from_u8(x) {
+                    match cmd {
+                        SlaveCmd::BufferStatus => {
+                            if buf.lock(|b| b.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);
+                        }
                     }
                 }
+            }
 
-                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).unwrap();
-                }
-            };
-        });
+                buf.lock(|b| b.push(x).unwrap());
+            }
+        };
     }
 }
-- 
GitLab