From d391a7538126a5a05de518d82de9568a07300102 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andreas=20Holmstr=C3=B6m?= <holmstrom.andreas95@gmail.com>
Date: Tue, 19 Mar 2024 16:11:08 +0100
Subject: [PATCH] Working on PWM. Problems understanding what set period does.
 It does not seem to change how often the led blinks

---
 zoo/examples/pwm_led_example.rs | 158 ++++++++++++++++++++++++++++++++
 1 file changed, 158 insertions(+)
 create mode 100644 zoo/examples/pwm_led_example.rs

diff --git a/zoo/examples/pwm_led_example.rs b/zoo/examples/pwm_led_example.rs
new file mode 100644
index 0000000..7b2d89e
--- /dev/null
+++ b/zoo/examples/pwm_led_example.rs
@@ -0,0 +1,158 @@
+#![no_main]
+#![no_std]
+// #![deny(unsafe_code)]
+// #![deny(warnings)]
+
+use {
+    cortex_m::asm,
+    embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin},
+    fugit::{MillisDurationU64, TimerInstantU64},
+    hal::{
+        pwm::*,
+        gpio::{Level, Output, Pin, PullDown, PushPull, Input},
+        gpiote::*,
+        // ppi::{self, ConfigurablePpi, Ppi},
+        prelude::*,
+        saadc::*,
+        clocks::*,
+        pac::interrupt,
+        rtc::{Rtc, RtcCompareReg, RtcInterrupt}, 
+    },
+    nrf52833_hal as hal, panic_rtt_target as _,
+    rtt_target::{rprintln, rtt_init_print},
+    systick_monotonic::*,
+};
+
+const TIMER_HZ: u32 = 4; // 4 Hz (250 ms granularity)
+const TIME_0: Instant = TimerInstantU64::from_ticks(0); // Constant for time zero
+
+type SeqBuffer = &'static mut [u16; 48];
+type Led = Pin<Output<PushPull>>;
+type Instant = TimerInstantU64<TIMER_HZ>;
+type Duration = MillisDurationU64;
+
+#[rtic::app(device = nrf52833_hal::pac, dispatchers= [TIMER0])]
+mod app {
+    use core::borrow::Borrow;
+
+    use hal::{comp::CompInputPin, gpio::{self, p0::P0_31, Disconnected, Floating}, pac::{PWM0, RTC0}, pwm::PwmSeq};
+
+    use super::*;
+    //#[monotonic(binds = RTC0, default = true)]
+    //type Mono = hal::monotonic::MonotonicTimer<hal::pac::RTC0, 32_768u32>;
+    #[monotonic(binds = SysTick, default = true)]
+    type MyMono = Systick<TIMER_HZ>;
+
+    #[shared]
+    struct Shared {
+        pwm0: Pwm<PWM0>,
+    }
+
+    #[local]
+    struct Local {
+    }
+
+    #[init(local = [
+        BUF0: [u16; 48] = [0u16; 48],
+        BUF1: [u16; 48] = [0u16; 48],
+    ])]
+    fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
+        rtt_init_print!();
+        rprintln!("\n---init---\n");
+        
+        /************************** SECTION: Ports and time *************************/
+        let port1 = hal::gpio::p1::Parts::new(cx.device.P1);
+        let mut mono = Systick::new(cx.core.SYST, 64_000_000);
+        let port0 = hal::gpio::p0::Parts::new(cx.device.P0);
+        /****************************************************************************/
+
+        /******************** SECTION: Buttons, buzzer and led setup ***************/
+        let buzzer = port1.p1_09.into_push_pull_output(Level::Low).degrade();
+        let led1 = port0.p0_11.into_push_pull_output(Level::Low).degrade();
+        /****************************************************************************/
+
+        /************************** SECTION: PWM Led ********************************/
+        let mut pwm0 = Pwm::new(cx.device.PWM0);
+        pwm0.set_period(1.hz())
+            .set_output_pin(Channel::C0, led1)
+            .set_prescaler(Prescaler::Div128)
+            .enable_interrupt(PwmEvent::Stopped)
+            .enable_interrupt(PwmEvent::PwmPeriodEnd)
+            .enable();
+        let max_duty = pwm0.max_duty();
+        rprintln!("pmw0 max duty {}", max_duty);
+        let dutybefore = pwm0.get_duty(Channel::C0); 
+        rprintln!("before {}", dutybefore);
+        pwm0.set_duty(Channel::C0, max_duty/2);
+        let dutyafter = pwm0.get_duty(Channel::C0);
+        rprintln!("after {}", dutyafter);
+        
+        
+        /****************************************************************************/
+        let buf0 = cx.local.BUF0;
+        let buf1 = cx.local.BUF1;
+
+        pwm0.task_start_seq0();
+
+        
+
+        //stop::spawn_after(2.secs()).unwrap();
+
+
+        (Shared { pwm0 }, Local { }, init::Monotonics(mono))
+    }
+
+    #[task(shared = [pwm0])]
+    fn pwm_stop(mut cx: pwm_stop::Context) {
+        cx.shared.pwm0.lock(|pwm| {
+            pwm.stop();
+        });
+    }
+    
+/*     #[task(binds = PWM0, shared = [pwm0])]
+    fn on_pwm(mut cx: on_pwm::Context) {
+        cx.shared.pwm0.lock(|pwm| {
+            if pwm.is_event_triggered(PwmEvent::PwmPeriodEnd) {
+                toggle_led::spawn_after(1000.millis()).ok();
+            }
+        });
+    } */
+
+    #[task(binds = PWM0, shared = [pwm0])]
+    fn toggle_led(mut cx: toggle_led::Context) {
+        cx.shared.pwm0.lock(|pwm| {
+            if pwm.is_event_triggered(PwmEvent::PwmPeriodEnd) {
+                let mut led = pwm.clear_output_pin(Channel::C0).unwrap();
+                if led.is_set_high().unwrap() {
+                    rprintln!("toggling low");
+                    match led.set_low() {
+                        Ok(res) => res,
+                        Err(_) => rprintln!("Error with led.set_low() in toggle_led task")
+                    }
+                } else {
+                    rprintln!("toggling high");
+                    match led.set_high() {
+                        Ok(res) => res,
+                        Err(_) => rprintln!("Error with led.set_high() in toggle_led task")
+                    }
+                }
+                pwm.set_output_pin(Channel::C0, led);
+            } else {
+                rprintln!("Other event triggered")
+            }
+        });
+    }
+
+
+
+    #[idle]
+    fn idle(_cx: idle::Context) -> ! {
+        rprintln!("idle");
+        loop{
+            //rprintln!("LOOPIN");
+            asm::wfi();
+        }
+    }
+
+
+}
-- 
GitLab