Prechádzať zdrojové kódy

Support for stm32f105xx and stm32f107xx devices

Those are known as “Connectivity line" and have a peripheral configuration similar
to the stm32f103 high-density devices but feature a USB OTG FS peripheral.
stm32f107xx devices additionally have an ethernet controller.

The connectivity line devices support less PLL multiplier values.
A second PLL can be cascaded to achieve greater flexibility.
This patch just does not add support for the second PLL but makes sure
the values for PLL1 stay in the allowed range.
A user should check if the requested clock rate could be configured by looking
at the return value of `freeze()`
Timo Kröger 4 rokov pred
rodič
commit
5beed6af6c
12 zmenil súbory, kde vykonal 100 pridanie a 46 odobranie
  1. 2 0
      .github/workflows/ci.yml
  2. 1 0
      CHANGELOG.md
  3. 4 0
      Cargo.toml
  4. 5 1
      README.md
  5. 2 2
      src/backup_domain.rs
  6. 21 1
      src/lib.rs
  7. 3 3
      src/pwm.rs
  8. 3 3
      src/pwm_input.rs
  9. 3 3
      src/qei.rs
  10. 39 12
      src/rcc.rs
  11. 5 3
      src/spi.rs
  12. 12 18
      src/timer.rs

+ 2 - 0
.github/workflows/ci.yml

@@ -11,6 +11,8 @@ jobs:
           - stm32f100
           - stm32f101
           - stm32f103
+          - stm32f105
+          - stm32f107
         rust:
           - stable
         include:

+ 1 - 0
CHANGELOG.md

@@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 
 ### Changed
 
+- Support for connectivity line devices: `stm32f105xx` and `stm32f107xx`
 - Consistently use PAC as `pac` and mark `device` and `stm32` informally as deprecated
 - Replace default blocking spi Write implementation with an optimized one
 - Use `Deref` for SPI generic implementations instead of macros

+ 4 - 0
Cargo.toml

@@ -86,6 +86,8 @@ rt = ["stm32f1/rt"]
 stm32f100 = ["stm32f1/stm32f100", "device-selected"]
 stm32f101 = ["stm32f1/stm32f101", "device-selected"]
 stm32f103 = ["stm32f1/stm32f103", "device-selected"]
+stm32f105 = ["stm32f1/stm32f107", "device-selected", "connectivity"]
+stm32f107 = ["stm32f1/stm32f107", "device-selected", "connectivity"]
 
 # Devices with 64 or 128 Kb ROM
 medium = []
@@ -93,6 +95,8 @@ medium = []
 high = ["medium"]
 # Devices with 768 Kb ROM or more
 xl = ["high"]
+# Connectivity line devices (`stm32f105xx` and `stm32f107xx`)
+connectivity = ["medium"]
 
 [profile.dev]
 incremental = false

+ 5 - 1
README.md

@@ -137,12 +137,16 @@ device) but check the datasheet or CubeMX to be sure.
 * C, D, E => `high` feature
 * F, G => `xl` feature
 
+For microcontrollers of the `connectivity line` (`stm32f105` and `stm32f107`) no
+density feature must be specified.
+
 ### Supported Microcontrollers
 
 * `stm32f100`
 * `stm32f101`
 * `stm32f103`
-
+* `stm32f105`
+* `stm32f107`
 
 ## Trying out the examples
 

+ 2 - 2
src/backup_domain.rs

@@ -49,7 +49,7 @@ impl BackupDomain {
     /// DRx registers: 0 is DR11, up to 31 for DR42. Providing a number above 31
     /// will panic.
     /// NOTE: not available on medium- and low-density devices!
-    #[cfg(feature = "high")]
+    #[cfg(any(feature = "high", feature = "connectivity"))]
     pub fn read_data_register_high(&self, register: usize) -> u16 {
         read_drx!(self, bkp_dr, register)
     }
@@ -67,7 +67,7 @@ impl BackupDomain {
     /// DRx registers: 0 is DR11, up to 31 for DR42. Providing a number above 31
     /// will panic.
     /// NOTE: not available on medium- and low-density devices!
-    #[cfg(feature = "high")]
+    #[cfg(any(feature = "high", feature = "connectivity"))]
     pub fn write_data_register_high(&self, register: usize, data: u16) {
         write_drx!(self, bkp_dr, register, data)
     }

+ 21 - 1
src/lib.rs

@@ -16,6 +16,8 @@
 //! - stm32f103
 //! - stm32f101
 //! - stm32f100
+//! - stm32f105
+//! - stm32f107
 //!
 //! ## Usage
 //!
@@ -30,6 +32,8 @@
 //! - `stm32f100`
 //! - `stm32f101`
 //! - `stm32f103`
+//! - `stm32f105`
+//! - `stm32f107`
 //!
 //! You may also need to specify the density of the device with `medium`, `high` or `xl`
 //! to enable certain peripherals. Generally the density can be determined by the 2nd character
@@ -66,14 +70,27 @@
 #![deny(intra_doc_link_resolution_failure)]
 
 // If no target specified, print error message.
-#[cfg(not(any(feature = "stm32f100", feature = "stm32f101", feature = "stm32f103")))]
+#[cfg(not(any(
+    feature = "stm32f100",
+    feature = "stm32f101",
+    feature = "stm32f103",
+    feature = "stm32f105",
+    feature = "stm32f107",
+)))]
 compile_error!("Target not found. A `--features <target-name>` is required.");
 
 // If any two or more targets are specified, print error message.
 #[cfg(any(
     all(feature = "stm32f100", feature = "stm32f101"),
     all(feature = "stm32f100", feature = "stm32f103"),
+    all(feature = "stm32f100", feature = "stm32f105"),
+    all(feature = "stm32f100", feature = "stm32f107"),
     all(feature = "stm32f101", feature = "stm32f103"),
+    all(feature = "stm32f101", feature = "stm32f105"),
+    all(feature = "stm32f101", feature = "stm32f107"),
+    all(feature = "stm32f103", feature = "stm32f105"),
+    all(feature = "stm32f103", feature = "stm32f107"),
+    all(feature = "stm32f105", feature = "stm32f107"),
 ))]
 compile_error!(
     "Multiple targets specified. Only a single `--features <target-name>` can be specified."
@@ -91,6 +108,9 @@ pub use stm32f1::stm32f101 as pac;
 #[cfg(feature = "stm32f103")]
 pub use stm32f1::stm32f103 as pac;
 
+#[cfg(any(feature = "stm32f105", feature = "stm32f107"))]
+pub use stm32f1::stm32f107 as pac;
+
 #[cfg(feature = "device-selected")]
 #[deprecated(since = "0.6.0", note = "please use `pac` instead")]
 pub use crate::pac as device;

+ 3 - 3
src/pwm.rs

@@ -58,7 +58,7 @@ use core::marker::PhantomData;
 use core::mem;
 
 use crate::hal;
-#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "stm32f105",))]
+#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
 use crate::pac::TIM1;
 #[cfg(feature = "medium")]
 use crate::pac::TIM4;
@@ -135,7 +135,7 @@ pins_impl!(
     (P4), (Ch4), (C4);
 );
 
-#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "stm32f105",))]
+#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
 impl Timer<TIM1> {
     pub fn pwm<REMAP, P, PINS, T>(
         self,
@@ -490,7 +490,7 @@ macro_rules! hal {
     }
 }
 
-#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "stm32f105",))]
+#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
 hal! {
     TIM1: (tim1),
 }

+ 3 - 3
src/pwm_input.rs

@@ -5,7 +5,7 @@ use core::marker::PhantomData;
 use core::mem;
 
 use crate::pac::DBGMCU as DBG;
-#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "stm32f105",))]
+#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
 use crate::pac::TIM1;
 #[cfg(feature = "medium")]
 use crate::pac::TIM4;
@@ -82,7 +82,7 @@ where
     RawValues { arr: u16, presc: u16 },
 }
 
-#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "stm32f105",))]
+#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
 impl Timer<TIM1> {
     pub fn pwm_input<REMAP, PINS, T>(
         mut self,
@@ -305,7 +305,7 @@ macro_rules! hal {
     }
 }
 
-#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "stm32f105",))]
+#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
 hal! {
     TIM1: (tim1),
 }

+ 3 - 3
src/qei.rs

@@ -9,7 +9,7 @@ use core::u16;
 use core::marker::PhantomData;
 
 use crate::hal::{self, Direction};
-#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "stm32f105",))]
+#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
 use crate::pac::TIM1;
 #[cfg(feature = "medium")]
 use crate::pac::TIM4;
@@ -71,7 +71,7 @@ pub struct Qei<TIM, REMAP, PINS> {
     _remap: PhantomData<REMAP>,
 }
 
-#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "stm32f105",))]
+#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
 impl Timer<TIM1> {
     pub fn qei<REMAP, PINS>(
         self,
@@ -199,7 +199,7 @@ macro_rules! hal {
     }
 }
 
-#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "stm32f105",))]
+#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
 hal! {
     TIM1: (_tim1, tim1en, tim1rst),
 }

+ 39 - 12
src/rcc.rs

@@ -173,11 +173,16 @@ impl CFGR {
         let pllsrcclk = self.hse.unwrap_or(HSI / 2);
 
         let pllmul = self.sysclk.unwrap_or(pllsrcclk) / pllsrcclk;
-        let pllmul = cmp::min(cmp::max(pllmul, 1), 16);
 
         let (pllmul_bits, sysclk) = if pllmul == 1 {
             (None, self.hse.unwrap_or(HSI))
         } else {
+            #[cfg(not(feature = "connectivity"))]
+            let pllmul = cmp::min(cmp::max(pllmul, 1), 16);
+
+            #[cfg(feature = "connectivity")]
+            let pllmul = cmp::min(cmp::max(pllmul, 4), 9);
+
             (Some(pllmul as u8 - 2), pllsrcclk * pllmul)
         };
 
@@ -242,7 +247,7 @@ impl CFGR {
         assert!(pclk2 <= 72_000_000);
 
         // adjust flash wait states
-        #[cfg(feature = "stm32f103")]
+        #[cfg(any(feature = "stm32f103", feature = "connectivity"))]
         unsafe {
             acr.acr().write(|w| {
                 w.latency().bits(if sysclk <= 24_000_000 {
@@ -292,7 +297,8 @@ impl CFGR {
         if let Some(pllmul_bits) = pllmul_bits {
             // enable PLL and wait for it to be ready
 
-            rcc.cfgr.modify(|_, w| {
+            #[allow(unused_unsafe)]
+            rcc.cfgr.modify(|_, w| unsafe {
                 w.pllmul()
                     .bits(pllmul_bits)
                     .pllsrc()
@@ -305,6 +311,30 @@ impl CFGR {
         }
 
         // set prescalers and clock source
+        #[cfg(feature = "connectivity")]
+        rcc.cfgr.modify(|_, w| unsafe {
+            w.adcpre().bits(apre_bits);
+            w.ppre2()
+                .bits(ppre2_bits)
+                .ppre1()
+                .bits(ppre1_bits)
+                .hpre()
+                .bits(hpre_bits)
+                .otgfspre()
+                .bit(usbpre)
+                .sw()
+                .bits(if pllmul_bits.is_some() {
+                    // PLL
+                    0b10
+                } else if self.hse.is_some() {
+                    // HSE
+                    0b1
+                } else {
+                    // HSI
+                    0b0
+                })
+        });
+
         #[cfg(feature = "stm32f103")]
         rcc.cfgr.modify(|_, w| unsafe {
             w.adcpre().bits(apre_bits);
@@ -574,7 +604,7 @@ bus! {
     WWDG => (APB1, wwdgen, wwdgrst),
 }
 
-#[cfg(feature = "high")]
+#[cfg(any(feature = "high", feature = "connectivity"))]
 bus! {
     SPI3 => (APB1, spi3en, spi3rst),
 }
@@ -595,22 +625,19 @@ bus! {
     TIM3 => (APB1, tim3en, tim3rst),
 }
 
-#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "stm32f105",))]
+#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))]
 bus! {
     TIM1 => (APB2, tim1en, tim1rst),
 }
 
-#[cfg(any(feature = "stm32f100", feature = "stm32f105", feature = "high",))]
+#[cfg(any(feature = "stm32f100", feature = "high", feature = "connectivity"))]
 bus! {
     TIM6 => (APB1, tim6en, tim6rst),
 }
 
 #[cfg(any(
-    all(
-        feature = "high",
-        any(feature = "stm32f101", feature = "stm32f103", feature = "stm32f107",)
-    ),
-    any(feature = "stm32f100", feature = "stm32f105",)
+    all(feature = "high", any(feature = "stm32f101", feature = "stm32f103")),
+    any(feature = "stm32f100", feature = "connectivity")
 ))]
 bus! {
     TIM7 => (APB1, tim7en, tim7rst),
@@ -628,7 +655,7 @@ bus! {
     TIM4 => (APB1, tim4en, tim4rst),
 }
 
-#[cfg(feature = "high")]
+#[cfg(any(feature = "high", feature = "connectivity"))]
 bus! {
     TIM5 => (APB1, tim5en, tim5rst),
 }

+ 5 - 3
src/spi.rs

@@ -34,7 +34,7 @@ use core::ops::Deref;
 use core::ptr;
 
 pub use crate::hal::spi::{FullDuplex, Mode, Phase, Polarity};
-#[cfg(feature = "high")]
+#[cfg(any(feature = "high", feature = "connectivity"))]
 use crate::pac::SPI3;
 use crate::pac::{SPI1, SPI2};
 
@@ -43,6 +43,8 @@ use crate::dma::dma1::{C3, C5};
 use crate::dma::{Static, Transfer, TransferPayload, Transmit, TxDma, R};
 use crate::gpio::gpioa::{PA5, PA6, PA7};
 use crate::gpio::gpiob::{PB13, PB14, PB15, PB3, PB4, PB5};
+#[cfg(feature = "connectivity")]
+use crate::gpio::gpioc::{PC10, PC11, PC12};
 use crate::gpio::{Alternate, Floating, Input, PushPull};
 use crate::rcc::{sealed::RccBus, Clocks, Enable, GetBusFreq, Reset};
 use crate::time::Hertz;
@@ -141,7 +143,7 @@ remap!(Spi1Remap, SPI1, true, PB3, PB4, PB5);
 remap!(Spi2NoRemap, SPI2, false, PB13, PB14, PB15);
 #[cfg(feature = "high")]
 remap!(Spi3NoRemap, SPI3, false, PB3, PB4, PB5);
-#[cfg(feature = "stm32f105")]
+#[cfg(feature = "connectivity")]
 remap!(Spi3Remap, SPI3, true, PC10, PC11, PC12);
 
 impl<REMAP, PINS> Spi<SPI1, REMAP, PINS> {
@@ -182,7 +184,7 @@ impl<REMAP, PINS> Spi<SPI2, REMAP, PINS> {
     }
 }
 
-#[cfg(feature = "high")]
+#[cfg(any(feature = "high", feature = "connectivity"))]
 impl<REMAP, PINS> Spi<SPI3, REMAP, PINS> {
     pub fn spi3<F, POS>(
         spi: SPI3,

+ 12 - 18
src/timer.rs

@@ -48,20 +48,17 @@
 */
 
 use crate::hal::timer::{CountDown, Periodic};
-#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "stm32f105",))]
+#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
 use crate::pac::TIM1;
 #[cfg(feature = "medium")]
 use crate::pac::TIM4;
-#[cfg(feature = "high")]
+#[cfg(any(feature = "high", feature = "connectivity"))]
 use crate::pac::TIM5;
-#[cfg(any(feature = "stm32f100", feature = "stm32f105", feature = "high",))]
+#[cfg(any(feature = "stm32f100", feature = "high", feature = "connectivity",))]
 use crate::pac::TIM6;
 #[cfg(any(
-    all(
-        feature = "high",
-        any(feature = "stm32f101", feature = "stm32f103", feature = "stm32f107",),
-    ),
-    any(feature = "stm32f100", feature = "stm32f105",)
+    all(feature = "high", any(feature = "stm32f101", feature = "stm32f103",),),
+    any(feature = "stm32f100", feature = "connectivity",)
 ))]
 use crate::pac::TIM7;
 #[cfg(all(feature = "stm32f103", feature = "high",))]
@@ -125,12 +122,12 @@ use crate::gpio::gpioa::{PA0, PA1, PA15, PA2, PA3, PA6, PA7};
 use crate::gpio::gpiob::{PB0, PB1, PB10, PB11, PB3, PB4, PB5};
 use crate::gpio::gpioc::{PC6, PC7, PC8, PC9};
 
-#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "stm32f105",))]
+#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
 use crate::gpio::{
     gpioa::{PA10, PA11, PA8, PA9},
     gpioe::{PE11, PE13, PE14, PE9},
 };
-#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "stm32f105",))]
+#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
 remap!(
     Tim1NoRemap: (TIM1, 0b00, PA8, PA9, PA10, PA11),
     //Tim1PartialRemap: (TIM1, 0b01, PA8, PA9, PA10, PA11),
@@ -426,22 +423,19 @@ hal! {
     TIM3: (tim3, dbg_tim3_stop, tim2),
 }
 
-#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "stm32f105",))]
+#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
 hal! {
     TIM1: (tim1, dbg_tim1_stop, tim1),
 }
 
-#[cfg(any(feature = "stm32f100", feature = "stm32f105", feature = "high",))]
+#[cfg(any(feature = "stm32f100", feature = "high", feature = "connectivity",))]
 hal! {
     TIM6: (tim6, dbg_tim6_stop, tim6),
 }
 
 #[cfg(any(
-    all(
-        feature = "high",
-        any(feature = "stm32f101", feature = "stm32f103", feature = "stm32f107",),
-    ),
-    any(feature = "stm32f100", feature = "stm32f105",)
+    all(feature = "high", any(feature = "stm32f101", feature = "stm32f103",),),
+    any(feature = "stm32f100", feature = "connectivity",)
 ))]
 hal! {
     TIM7: (tim7, dbg_tim7_stop, tim6),
@@ -459,7 +453,7 @@ hal! {
     TIM4: (tim4, dbg_tim4_stop, tim2),
 }
 
-#[cfg(feature = "high")]
+#[cfg(any(feature = "high", feature = "connectivity"))]
 hal! {
     TIM5: (tim5, dbg_tim5_stop, tim2),
 }