From d61139b56e1093209391b954b0389c2dbd8aadf4 Mon Sep 17 00:00:00 2001
From: sheepwall <a.sve@live.se>
Date: Mon, 18 Mar 2019 18:03:31 +0100
Subject: [PATCH] ..

---
 examples/bare10.rs | 150 ++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 129 insertions(+), 21 deletions(-)

diff --git a/examples/bare10.rs b/examples/bare10.rs
index 4ad60ca..88532d5 100644
--- a/examples/bare10.rs
+++ b/examples/bare10.rs
@@ -16,8 +16,10 @@ use crate::hal::prelude::*;
 use crate::hal::serial::{config::Config, Event, Rx, Serial, Tx};
 use hal::stm32::ITM;
 
+use crate::hal::gpio::{gpioa::PA5, Output, PushPull};
+
 use nb::block;
-use rtfm::app;
+use rtfm::{app, Instant};
 
 // Our error type
 #[derive(Debug)]
@@ -27,12 +29,66 @@ pub enum Error {
     UsartReceiveOverflow,
 }
 
+enum CmdType {
+    Off,
+    On,
+    Set,
+}
+
+pub struct Cmd {
+    cmd_type: CmdType,
+    half_period: u32,
+}
+
+impl Cmd {
+    fn parse(&mut self, cmd_byte: [u8; 10], cmd_length: usize) {
+        if cmd_byte.starts_with(&[b'o', b'n', b' ']) {
+            self.cmd_type = CmdType::On;
+            self.half_period = freq_to_half_period(1);
+        } else if cmd_byte.starts_with(&[b's', b'e', b't', b' ']) {
+            let mut tmp = 0;
+            for c in &cmd_byte[4..cmd_length] {
+                if c.is_ascii_digit() {
+                    tmp = 10 * tmp + (c - b'0') as u32;
+                } else {
+                    return;
+                }
+            }
+            self.cmd_type = CmdType::Set;
+            self.half_period = freq_to_half_period(tmp);
+        } else {
+            self.cmd_type = CmdType::Off;
+            self.half_period = freq_to_half_period(1);
+        }
+    }
+
+    fn freq_to_half_period(freq: u32) -> u32 {
+        if freq == 0 {
+            return 1;
+        } else {
+            return SYSTEM_CLOCK_FREQ / (2 * freq);
+        }
+    }
+}
+
+const ASCII_CR: u8 = 13;
+const ASCII_LF: u8 = 10;
+
+const CMD_BUFFER_LENGTH: usize = 10;
+
+const SYSTEM_CLOCK_FREQ: u32 = 16000000;
+
 #[app(device = hal::stm32)]
 const APP: () = {
     // Late resources
     static mut TX: Tx<hal::stm32::USART2> = ();
     static mut RX: Rx<hal::stm32::USART2> = ();
     static mut ITM: ITM = ();
+    static mut IS_LED_ON: bool = ();
+    static mut LED: PA5<Output<PushPull>> = ();
+    static mut B: [u8; CMD_BUFFER_LENGTH] = ();
+    static mut B_INDEX: usize = ();
+    static mut CURRENT_CMD: Cmd = ();
 
     // init runs in an interrupt free section>
     #[init]
@@ -50,6 +106,9 @@ const APP: () = {
         let tx = gpioa.pa2.into_alternate_af7();
         let rx = gpioa.pa3.into_alternate_af7(); // try comment out
 
+        let mut led = gpioa.pa5.into_push_pull_output();
+        led.set_low();
+
         let mut serial = Serial::usart2(
             device.USART2,
             (tx, rx),
@@ -67,6 +126,17 @@ const APP: () = {
         TX = tx;
         RX = rx;
 
+        // LED
+        LED = led;
+        IS_LED_ON = false;
+        CURRENT_CMD = Cmd {
+            cmd_type: CmdType::Off,
+            frequency: 1,
+        };
+        // CMD Interpretor
+        B = [0u8; 10];
+        B_INDEX = 0;
+
         // For debugging
         ITM = core.ITM;
     }
@@ -79,24 +149,65 @@ const APP: () = {
         }
     }
 
-    #[task(priority = 1, capacity = 4, resources = [ITM])]
-    fn trace_data(byte: u8) {
-        // let stim = &mut resources.ITM.stim[0];
-        // iprintln!(stim, "data {}", byte);
-        // for _ in 0..10000 {
-        //     asm::nop();
-        // }
-    }
-
-    #[task(priority = 1, spawn = [echo, trace_error])]
+    #[task(priority = 1, capacity = 10, resources = [IS_LED_ON, B, B_INDEX, CURRENT_CMD, ITM], spawn = [echo, on, off])]
     fn cmd_interpretor(byte: u8) {
-        
-        let send: u8 = match byte as char {
-            'a' => byte + 1,
-            _ => byte,
+        let is_led_on = *resources.IS_LED_ON;
+        let mut b = *resources.B;
+        let mut b_i = *resources.B_INDEX;
+        let mut cmd = resources.CURRENT_CMD;
+
+        if b_i >= CMD_BUFFER_LENGTH {
+            b = [0u8; 10];
+            b_i = 0;
+        }
+
+        match byte {
+            ASCII_CR => {
+                cmd.parse(b, b_i);
+                b = [0u8; 10];
+                b_i = 0;
+            },
+            ASCII_LF => {
+                cmd.parse(b, b_i);
+                b = [0u8; 10];
+                b_i = 0;
+            },
+            _ => {
+                b[b_i] = byte;
+                b_i += 1;
+            },
         };
 
-        let _ = spawn.echo(send);
+        let stim = &mut resources.ITM.stim[0];
+        iprintln!(stim, "byte: {:?}", byte);
+        iprintln!(stim, "B: {:?}", b);
+        iprintln!(stim, "B INDEX: {:?}", b_i);
+        iprintln!(stim, "IS_LED_ON: {:?}", is_led_on);
+
+        match cmd.cmd_type {
+            CmdType::Off => iprintln!(stim, "CURRENT_CMD: off, {:?}", cmd.frequency),
+            CmdType::On => iprintln!(stim, "CURRENT_CMD: on, {:?}", cmd.frequency),
+            CmdType::Set => iprintln!(stim, "CURRENT_CMD: set, {:?}", cmd.frequency),
+        }
+        
+        let _ = spawn.on();
+
+        *resources.B = b;
+        *resources.B_INDEX = b_i;
+    }
+
+    #[task(priority = 1, schedule = [off], resources = [LED, IS_LED_ON])]
+    fn on() {
+        if 
+        schedule.off(Instant::now + )
+        resources.LED.set_high();
+        *resources.IS_LED_ON = true;
+    }
+
+    #[task(priority = 1, resources = [LED, IS_LED_ON])]
+    fn off() {
+        resources.LED.set_low();
+        *resources.IS_LED_ON = false;
     }
 
     #[task(priority = 1, resources = [ITM])]
@@ -112,17 +223,15 @@ const APP: () = {
         if block!(tx.write(byte)).is_err() {
             let _ = spawn.trace_error(Error::UsartSendOverflow);
         }
-
     }
 
-    #[interrupt(priority = 3, resources = [RX], spawn = [trace_data, trace_error, cmd_interpretor])]
+    #[interrupt(priority = 3, resources = [RX], spawn = [trace_error, cmd_interpretor])]
     fn USART2() {
         let rx = resources.RX;
 
         match rx.read() {
             Ok(byte) => {
-                let _ = spawn.cmd_interpretor(byte);
-                if spawn.trace_data(byte).is_err() {
+                if spawn.cmd_interpretor(byte).is_err() {
                     let _ = spawn.trace_error(Error::RingBufferOverflow);
                 }
             }
@@ -137,7 +246,6 @@ const APP: () = {
     extern "C" {
         fn EXTI0();
         fn EXTI1();
-        fn EXTI2();
     }
 };
 
-- 
GitLab