From a11e3146f8f5c00c770c6ef913bca676bbc9a685 Mon Sep 17 00:00:00 2001
From: Torin Cooper-Bennun <tcbennun@maxiluxsystems.com>
Date: Thu, 22 Feb 2024 16:55:00 +0000
Subject: [PATCH 1/4] stm32: time_driver: allow use of TIM1 for driver

---
 embassy-stm32/Cargo.toml         | 2 ++
 embassy-stm32/src/time_driver.rs | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index d585d2cd6..0defde033 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -130,6 +130,8 @@ _time-driver = ["dep:embassy-time-driver", "time"]
 
 ## Use any time driver
 time-driver-any = ["_time-driver"]
+## Use TIM1 as time driver
+time-driver-tim1 = ["_time-driver"]
 ## Use TIM2 as time driver
 time-driver-tim2 = ["_time-driver"]
 ## Use TIM3 as time driver
diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs
index a1f54307d..4129e4f30 100644
--- a/embassy-stm32/src/time_driver.rs
+++ b/embassy-stm32/src/time_driver.rs
@@ -38,7 +38,7 @@ cfg_if::cfg_if! {
     }
 }
 
-#[cfg(time_drvier_tim1)]
+#[cfg(time_driver_tim1)]
 type T = peripherals::TIM1;
 #[cfg(time_driver_tim2)]
 type T = peripherals::TIM2;

From 44534abf32f556533c1183640e87bc2d45161d54 Mon Sep 17 00:00:00 2001
From: Torin Cooper-Bennun <tcbennun@maxiluxsystems.com>
Date: Thu, 22 Feb 2024 17:26:44 +0000
Subject: [PATCH 2/4] stm32: sync available TIMs in Cargo.toml, build.rs

---
 embassy-stm32/Cargo.toml | 8 ++++++++
 embassy-stm32/build.rs   | 1 +
 2 files changed, 9 insertions(+)

diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 0defde033..c4b3ece1a 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -140,6 +140,8 @@ time-driver-tim3 = ["_time-driver"]
 time-driver-tim4 = ["_time-driver"]
 ## Use TIM5 as time driver
 time-driver-tim5 = ["_time-driver"]
+## Use TIM8 as time driver
+time-driver-tim8 = ["_time-driver"]
 ## Use TIM9 as time driver
 time-driver-tim9 = ["_time-driver"]
 ## Use TIM11 as time driver
@@ -148,10 +150,16 @@ time-driver-tim11 = ["_time-driver"]
 time-driver-tim12 = ["_time-driver"]
 ## Use TIM15 as time driver
 time-driver-tim15 = ["_time-driver"]
+## Use TIM20 as time driver
+time-driver-tim20 = ["_time-driver"]
 ## Use TIM21 as time driver
 time-driver-tim21 = ["_time-driver"]
 ## Use TIM22 as time driver
 time-driver-tim22 = ["_time-driver"]
+## Use TIM23 as time driver
+time-driver-tim23 = ["_time-driver"]
+## Use TIM24 as time driver
+time-driver-tim24 = ["_time-driver"]
 
 
 #! ## Analog Switch Pins (Pxy_C) on STM32H7 series
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 068a74733..75a2055eb 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -189,6 +189,7 @@ fn main() {
         Some("tim5") => "TIM5",
         Some("tim8") => "TIM8",
         Some("tim9") => "TIM9",
+        Some("tim11") => "TIM11",
         Some("tim12") => "TIM12",
         Some("tim15") => "TIM15",
         Some("tim20") => "TIM20",

From 86ccf0bc3e0a9908402405aebde6755df0e1b4f6 Mon Sep 17 00:00:00 2001
From: Torin Cooper-Bennun <tcbennun@maxiluxsystems.com>
Date: Thu, 22 Feb 2024 17:42:08 +0000
Subject: [PATCH 3/4] stm32: remove TIM11 as time driver candidate (only 1 CC
 channel)

---
 embassy-stm32/Cargo.toml         | 2 --
 embassy-stm32/build.rs           | 1 -
 embassy-stm32/src/time_driver.rs | 2 --
 3 files changed, 5 deletions(-)

diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index c4b3ece1a..abcc8ac4e 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -144,8 +144,6 @@ time-driver-tim5 = ["_time-driver"]
 time-driver-tim8 = ["_time-driver"]
 ## Use TIM9 as time driver
 time-driver-tim9 = ["_time-driver"]
-## Use TIM11 as time driver
-time-driver-tim11 = ["_time-driver"]
 ## Use TIM12 as time driver
 time-driver-tim12 = ["_time-driver"]
 ## Use TIM15 as time driver
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 75a2055eb..068a74733 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -189,7 +189,6 @@ fn main() {
         Some("tim5") => "TIM5",
         Some("tim8") => "TIM8",
         Some("tim9") => "TIM9",
-        Some("tim11") => "TIM11",
         Some("tim12") => "TIM12",
         Some("tim15") => "TIM15",
         Some("tim20") => "TIM20",
diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs
index 4129e4f30..8e4e606a4 100644
--- a/embassy-stm32/src/time_driver.rs
+++ b/embassy-stm32/src/time_driver.rs
@@ -52,8 +52,6 @@ type T = peripherals::TIM5;
 type T = peripherals::TIM8;
 #[cfg(time_driver_tim9)]
 type T = peripherals::TIM9;
-#[cfg(time_driver_tim11)]
-type T = peripherals::TIM11;
 #[cfg(time_driver_tim12)]
 type T = peripherals::TIM12;
 #[cfg(time_driver_tim15)]

From 5c45723777dbd7d9d23188f5b5a2adc417e29292 Mon Sep 17 00:00:00 2001
From: Torin Cooper-Bennun <tcbennun@maxiluxsystems.com>
Date: Fri, 23 Feb 2024 14:33:25 +0000
Subject: [PATCH 4/4] stm32: timers: use TIMx_CC interrupt source for advanced
 timers

fixes (hopefully) time driver when using TIM1/8/20
---
 embassy-stm32/src/time_driver.rs | 34 ++++++++++++++++++++++++++++++++
 embassy-stm32/src/timer/mod.rs   | 19 ++++++++++++++----
 2 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs
index 8e4e606a4..37b2e7526 100644
--- a/embassy-stm32/src/time_driver.rs
+++ b/embassy-stm32/src/time_driver.rs
@@ -16,6 +16,8 @@ use crate::pac::timer::vals;
 use crate::rcc::sealed::RccPeripheral;
 #[cfg(feature = "low-power")]
 use crate::rtc::Rtc;
+#[cfg(any(time_driver_tim1, time_driver_tim8, time_driver_tim20))]
+use crate::timer::sealed::AdvancedControlInstance;
 use crate::timer::sealed::{CoreInstance, GeneralPurpose16bitInstance as Instance};
 use crate::{interrupt, peripherals};
 
@@ -76,6 +78,14 @@ foreach_interrupt! {
             DRIVER.on_interrupt()
         }
     };
+    (TIM1, timer, $block:ident, CC, $irq:ident) => {
+        #[cfg(time_driver_tim1)]
+        #[cfg(feature = "rt")]
+        #[interrupt]
+        fn $irq() {
+            DRIVER.on_interrupt()
+        }
+    };
     (TIM2, timer, $block:ident, UP, $irq:ident) => {
         #[cfg(time_driver_tim2)]
         #[cfg(feature = "rt")]
@@ -116,6 +126,14 @@ foreach_interrupt! {
             DRIVER.on_interrupt()
         }
     };
+    (TIM8, timer, $block:ident, CC, $irq:ident) => {
+        #[cfg(time_driver_tim8)]
+        #[cfg(feature = "rt")]
+        #[interrupt]
+        fn $irq() {
+            DRIVER.on_interrupt()
+        }
+    };
     (TIM9, timer, $block:ident, UP, $irq:ident) => {
         #[cfg(time_driver_tim9)]
         #[cfg(feature = "rt")]
@@ -148,6 +166,14 @@ foreach_interrupt! {
             DRIVER.on_interrupt()
         }
     };
+    (TIM20, timer, $block:ident, CC, $irq:ident) => {
+        #[cfg(time_driver_tim20)]
+        #[cfg(feature = "rt")]
+        #[interrupt]
+        fn $irq() {
+            DRIVER.on_interrupt()
+        }
+    };
     (TIM21, timer, $block:ident, UP, $irq:ident) => {
         #[cfg(time_driver_tim21)]
         #[cfg(feature = "rt")]
@@ -281,6 +307,14 @@ impl RtcDriver {
         <T as CoreInstance>::Interrupt::unpend();
         unsafe { <T as CoreInstance>::Interrupt::enable() };
 
+        #[cfg(any(time_driver_tim1, time_driver_tim8, time_driver_tim20))]
+        {
+            <T as AdvancedControlInstance>::CaptureCompareInterrupt::unpend();
+            unsafe {
+                <T as AdvancedControlInstance>::CaptureCompareInterrupt::enable();
+            }
+        }
+
         r.cr1().modify(|w| w.set_cen(true));
     }
 
diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs
index 9397da2a1..c8f580101 100644
--- a/embassy-stm32/src/timer/mod.rs
+++ b/embassy-stm32/src/timer/mod.rs
@@ -464,6 +464,9 @@ pub(crate) mod sealed {
     pub trait AdvancedControlInstance:
         GeneralPurpose2ChannelComplementaryInstance + GeneralPurpose16bitInstance
     {
+        /// Capture compare interrupt for this timer.
+        type CaptureCompareInterrupt: interrupt::typelevel::Interrupt;
+
         /// Get access to the advanced timer registers.
         fn regs_advanced() -> crate::pac::timer::TimAdv;
 
@@ -831,8 +834,10 @@ macro_rules! impl_2ch_cmp_timer {
 
 #[allow(unused)]
 macro_rules! impl_adv_timer {
-    ($inst:ident) => {
+    ($inst:ident, $irq:ident) => {
         impl sealed::AdvancedControlInstance for crate::peripherals::$inst {
+            type CaptureCompareInterrupt = crate::interrupt::typelevel::$irq;
+
             fn regs_advanced() -> crate::pac::timer::TimAdv {
                 unsafe { crate::pac::timer::TimAdv::from_ptr(crate::pac::$inst.as_ptr()) }
             }
@@ -905,11 +910,13 @@ foreach_interrupt! {
         impl_gp16_timer!($inst);
         impl_1ch_cmp_timer!($inst);
         impl_2ch_cmp_timer!($inst);
-        impl_adv_timer!($inst);
         impl BasicInstance for crate::peripherals::$inst {}
         impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
         impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {}
     };
+    ($inst:ident, timer, TIM_1CH_CMP, CC, $irq:ident) => {
+        impl_adv_timer!($inst, $irq);
+    };
 
 
     ($inst:ident, timer, TIM_2CH_CMP, UP, $irq:ident) => {
@@ -921,11 +928,13 @@ foreach_interrupt! {
         impl_gp16_timer!($inst);
         impl_1ch_cmp_timer!($inst);
         impl_2ch_cmp_timer!($inst);
-        impl_adv_timer!($inst);
         impl BasicInstance for crate::peripherals::$inst {}
         impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
         impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {}
     };
+    ($inst:ident, timer, TIM_2CH_CMP, CC, $irq:ident) => {
+        impl_adv_timer!($inst, $irq);
+    };
 
 
     ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => {
@@ -937,11 +946,13 @@ foreach_interrupt! {
         impl_gp16_timer!($inst);
         impl_1ch_cmp_timer!($inst);
         impl_2ch_cmp_timer!($inst);
-        impl_adv_timer!($inst);
         impl BasicInstance for crate::peripherals::$inst {}
         impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
         impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {}
     };
+    ($inst:ident, timer, TIM_ADV, CC, $irq:ident) => {
+        impl_adv_timer!($inst, $irq);
+    };
 }
 
 // Update Event trigger DMA for every timer