From d780798de9346af206495ff82d8ac9363741336a Mon Sep 17 00:00:00 2001
From: Stephen D <webmaster@scd31.com>
Date: Fri, 7 Jul 2023 16:09:52 -0300
Subject: [PATCH] move to interrupt-based rf4463 lib. overruns sometimes. need
 to move to SPI

---
 Cargo.lock  | 19 ++++++++++++----
 Cargo.toml  |  8 +++----
 src/main.rs | 63 ++++++++++++++++++++++++++++++++++++++++-------------
 3 files changed, 67 insertions(+), 23 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index f925f26..bc8866c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -111,6 +111,15 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "cortex-m-semihosting"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c23234600452033cc77e4b761e740e02d2c4168e11dbf36ab14a0f58973592b0"
+dependencies = [
+ "cortex-m",
+]
+
 [[package]]
 name = "critical-section"
 version = "1.1.1"
@@ -240,12 +249,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
 
 [[package]]
-name = "panic-reset"
-version = "0.1.1"
+name = "panic-semihosting"
+version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6cf1ff2a5b1a478dd94572aa43476b6630e72071cbd016985003ad3903a3a4f5"
+checksum = "ee8a3e1233d9073d76a870223512ce4eeea43c067a94a445c13bd6d792d7b1ab"
 dependencies = [
  "cortex-m",
+ "cortex-m-semihosting",
 ]
 
 [[package]]
@@ -255,7 +265,8 @@ dependencies = [
  "cortex-m",
  "cortex-m-rt",
  "cortex-m-rtic",
- "panic-reset",
+ "cortex-m-semihosting",
+ "panic-semihosting",
  "rf4463",
  "ringbuffer",
  "stm32f4xx-hal",
diff --git a/Cargo.toml b/Cargo.toml
index 381e794..91a85a6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,7 +7,7 @@ readme = "README.md"
 
 [profile.release]
 codegen-units = 1
-debug = 0
+debug = true
 lto = true
 opt-level = "z"
 
@@ -17,9 +17,9 @@ opt-level = "z"
 stm32f4xx-hal = { version = "0.16", features = ["stm32f411", "rtic"]}
 cortex-m = "0.7"
 cortex-m-rt = "0.7"
-#cortex-m-semihosting = "0.5"
-#panic-semihosting = "0.6"
+cortex-m-semihosting = "0.5"
+panic-semihosting = "0.6"
 rf4463 = { path = "../rf4463" }
 cortex-m-rtic = { version = "1.1.4" }
 ringbuffer = { version = "0.13.0", default_features = false }
-panic-reset = "0.1.1"
+#panic-reset = "0.1.1"
diff --git a/src/main.rs b/src/main.rs
index 89b5dd5..9354caf 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,7 +3,8 @@
 
 extern crate cortex_m;
 extern crate cortex_m_rt as rt;
-extern crate panic_reset;
+//extern crate panic_reset;
+extern crate panic_semihosting;
 extern crate stm32f4xx_hal as hal;
 
 mod packet;
@@ -11,7 +12,7 @@ mod packet;
 #[rtic::app(device = stm32f4xx_hal::pac, peripherals = true)]
 mod app {
     use hal::block;
-    use hal::gpio;
+    use hal::gpio::{self, Speed};
     use hal::pac::{SPI1, TIM5, USART1};
     use hal::prelude::*;
     use hal::serial::{Config, Event, Serial};
@@ -33,6 +34,7 @@ mod app {
     };
 
     type Radio = Rf4463<
+        PACKET_LEN,
         Spi<SPI1>,
         gpio::Pin<'B', 1, gpio::Output>,
         gpio::Pin<'B', 0, gpio::Output>,
@@ -67,19 +69,20 @@ mod app {
 
     #[shared]
     struct Shared {
+        radio: Radio,
         radio_temp: f32,
         tx_buf: ConstGenericRingBuffer<Packet, BUFFER_LEN>,
     }
 
     #[local]
     struct Local {
-        radio: Radio,
+        radio_irq: gpio::Pin<'B', 2, gpio::Input>,
         usart: Serial<USART1>,
         state: SlaveState,
     }
 
     #[init]
-    fn init(ctx: init::Context) -> (Shared, Local, init::Monotonics) {
+    fn init(mut ctx: init::Context) -> (Shared, Local, init::Monotonics) {
         let rcc = ctx.device.RCC.constrain();
 
         let gpioa = ctx.device.GPIOA.split();
@@ -93,21 +96,26 @@ mod app {
             .pclk1(48.MHz())
             .pclk2(48.MHz())
             .freeze();
+        let mut sys_cfg = ctx.device.SYSCFG.constrain();
 
         // setup 4463 spi
-        let mosi = gpioa.pa7.into_alternate();
-        let miso = gpioa.pa6.into_alternate();
-        let sclk = gpioa.pa5.into_alternate();
+        let mosi = gpioa.pa7.into_alternate().speed(Speed::VeryHigh);
+        let miso = gpioa.pa6.into_alternate().speed(Speed::VeryHigh);
+        let sclk = gpioa.pa5.into_alternate().speed(Speed::VeryHigh);
 
         let sdn = gpiob.pb1.into_push_pull_output();
-
         let cs = gpiob.pb0.into_push_pull_output();
+        let mut radio_irq = gpiob.pb2.into_pull_up_input();
 
         let spi = Spi::new(ctx.device.SPI1, (sclk, miso, mosi), MODE, 10.MHz(), &clocks);
 
         let delay = ctx.device.TIM5.delay_us(&clocks);
         let radio = Rf4463::new(spi, sdn, cs, delay, &mut RADIO_CONFIG_500_2.clone()).unwrap();
 
+        radio_irq.make_interrupt_source(&mut sys_cfg);
+        radio_irq.enable_interrupt(&mut ctx.device.EXTI);
+        radio_irq.trigger_on_edge(&mut ctx.device.EXTI, gpio::Edge::Falling);
+
         // setup Pi UART
         let tx = gpioa.pa9;
         let rx = gpioa.pa10;
@@ -124,11 +132,12 @@ mod app {
 
         (
             Shared {
+                radio,
                 radio_temp: 0.0,
                 tx_buf: ConstGenericRingBuffer::new(),
             },
             Local {
-                radio,
+                radio_irq,
                 usart,
                 state: SlaveState::Idle,
             },
@@ -136,22 +145,36 @@ mod app {
         )
     }
 
-    #[idle(local=[radio], shared=[tx_buf, radio_temp])]
+    #[idle(shared=[radio, tx_buf, radio_temp])]
     fn idle(mut ctx: idle::Context) -> ! {
         let mut i = 0;
         let mut iterations_since_last_packet = 0;
         loop {
-            if let Some(mut pkt) = ctx.shared.tx_buf.lock(|buf| buf.dequeue()) {
+            if let Some(pkt) = ctx.shared.tx_buf.lock(|buf| buf.dequeue()) {
                 if iterations_since_last_packet >= 1000 {
                     // if we haven't transmitted in a while, the receiver's AGC is going to be messed up
                     // send 5 packets just so it can calibrate before we actually send it
                     for _ in 0..5 {
                         const GARBAGE: [u8; PACKET_LEN] = [0x00; PACKET_LEN];
-                        ctx.local.radio.tx(&mut GARBAGE.clone()).unwrap();
+                        ctx.shared.radio.lock(|r| r.start_tx(GARBAGE).unwrap());
+
+                        // wait for radio to be idle again
+                        loop {
+                            if ctx.shared.radio.lock(|r| r.is_idle()) {
+                                break;
+                            }
+                        }
                     }
                 }
 
-                ctx.local.radio.tx(&mut pkt.data).unwrap();
+                ctx.shared.radio.lock(|r| r.start_tx(pkt.data).unwrap());
+
+                // wait for radio to be idle again
+                loop {
+                    if ctx.shared.radio.lock(|r| r.is_idle()) {
+                        break;
+                    }
+                }
 
                 iterations_since_last_packet = 0;
             } else {
@@ -164,14 +187,14 @@ mod app {
             if i >= 500 {
                 i = 0;
 
-                if let Ok(new_temp) = ctx.local.radio.get_temp() {
+                if let Ok(new_temp) = ctx.shared.radio.lock(|r| r.get_temp()) {
                     ctx.shared.radio_temp.lock(|cur_temp| *cur_temp = new_temp);
                 }
             }
         }
     }
 
-    #[task(binds = USART1, priority=1, local = [state, usart], shared = [tx_buf, radio_temp])]
+    #[task(binds = USART1, priority = 2, local = [state, usart], shared = [tx_buf, radio_temp])]
     fn usart1(mut ctx: usart1::Context) {
         let state = ctx.local.state;
         let usart = ctx.local.usart;
@@ -223,4 +246,14 @@ mod app {
             }
         };
     }
+
+    #[task(binds = EXTI2, shared = [radio], local = [radio_irq])]
+    fn radio_irq(mut ctx: radio_irq::Context) {
+        ctx.shared.radio.lock(|r| r.interrupt()).unwrap();
+
+        let irq = ctx.local.radio_irq;
+        if irq.is_high() {
+            irq.clear_interrupt_pending_bit();
+        }
+    }
 }
-- 
GitLab