Skip to content

Support for the STM32L0x0 subfamily #146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 19 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ disable-linker-script = []

# STM32L0 subfamilies
# (Warning: Some peripherals, e.g. GPIO, don't follow this subfamily grouping.)
stm32l0x0 = ["stm32l0/stm32l0x0"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that enough, or do we need to add more features flags (thinking about the ones @dbrgn auto-generated from CubeMX).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably yes. I only have a l0x0RBT to test against, which is a class 5. I keep finding more things to fix; basically it's similar to the features of L020 class 5 with a lot of stuff cut out.

stm32l0x1 = ["stm32l0/stm32l0x1"]
stm32l0x2 = ["stm32l0/stm32l0x2"]
stm32l0x3 = ["stm32l0/stm32l0x3"]
Expand Down
11 changes: 9 additions & 2 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ fn main() {

let mut feature_count = 0;

if cfg!(feature = "stm32l0x0") {
feature_count += 1;
}

if cfg!(feature = "stm32l0x1") {
feature_count += 1;
}
Expand All @@ -22,11 +26,13 @@ fn main() {
}

if feature_count != 1 {
panic!("\n\nMust select exactly one package for linker script generation!\nChoices: 'stm32l0x1' or 'stm32l0x2' or 'stm32l0x3'\nAlternatively, pick the mcu-feature that matches your MCU, for example 'mcu-STM32L071KBTx'\n\n");
panic!("\n\nMust select exactly one package for linker script generation!\nChoices: 'stm32l0x0' or 'stm32l0x1' or 'stm32l0x2' or 'stm32l0x3'\nAlternatively, pick the mcu-feature that matches your MCU, for example 'mcu-STM32L071KBTx'\n\n");
}

if !cfg!(feature = "disable-linker-script") {
let linker = if cfg!(feature = "stm32l0x1") {
let linker = if cfg!(feature = "stm32l0x0") {
include_bytes!("memory_l0x0.x").as_ref()
} else if cfg!(feature = "stm32l0x1") {
include_bytes!("memory_l0x1.x").as_ref()
} else if cfg!(feature = "stm32l0x2") {
include_bytes!("memory_l0x2.x").as_ref()
Expand All @@ -42,6 +48,7 @@ fn main() {
.unwrap();
println!("cargo:rustc-link-search={}", out.display());

println!("cargo:rerun-if-changed=memory_l0x0.x");
println!("cargo:rerun-if-changed=memory_l0x1.x");
println!("cargo:rerun-if-changed=memory_l0x2.x");
println!("cargo:rerun-if-changed=memory_l0x3.x");
Expand Down
2 changes: 1 addition & 1 deletion examples/pwm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fn main() -> ! {
// Initialize TIM2 for PWM
let pwm = pwm::Timer::new(dp.TIM2, 10.khz(), &mut rcc);

#[cfg(feature = "stm32l0x1")]
#[cfg(any(feature = "stm32l0x0", feature = "stm32l0x1"))]
let mut pwm = pwm.channel2.assign(gpioa.pa1);

// This is LD2 on ST's B-L072Z-LRWAN1 development board.
Expand Down
5 changes: 5 additions & 0 deletions memory_l0x0.x
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 128K
RAM : ORIGIN = 0x20000000, LENGTH = 20K
}
17 changes: 12 additions & 5 deletions src/dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use crate::{
rcc::Rcc,
};

#[cfg(any(feature = "io-STM32L051", feature = "io-STM32L071"))]
#[cfg(all(not(feature = "stm32l0x0"), any(feature = "io-STM32L051", feature = "io-STM32L071")))]
use crate::pac::USART1;

#[cfg(any(
Expand All @@ -37,9 +37,16 @@ use crate::pac::USART1;
))]
use crate::{
i2c,
pac::{I2C1, I2C2, I2C3, USART2},
pac::{I2C1, USART2},
serial,
};
#[cfg(not(feature = "stm32l0x0"))]
use crate::{
pac::{
I2C2,
I2C3
},
};

#[cfg(feature = "stm32l082")]
use crate::aes;
Expand Down Expand Up @@ -324,14 +331,14 @@ macro_rules! impl_channel {
handle: &mut Handle,
address: u32,
) {
handle.dma.$chfield.par.write(|w| w.pa().bits(address));
unsafe { handle.dma.$chfield.par.write(|w| w.pa().bits(address)); }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This confuses me. Wouldn't the bits method be unsafe for all targets? Why did it work in the first place?

}

fn set_memory_address(&self,
handle: &mut Handle,
address: u32,
) {
handle.dma.$chfield.mar.write(|w| w.ma().bits(address));
unsafe { handle.dma.$chfield.mar.write(|w| w.ma().bits(address)); }
}

fn set_transfer_len(&self, handle: &mut Handle, len: u16) {
Expand Down Expand Up @@ -504,7 +511,7 @@ impl_target!(
adc::DmaToken, Channel2, 0;
);

#[cfg(any(feature = "io-STM32L051", feature = "io-STM32L071"))]
#[cfg(all(not(feature = "stm32l0x0"), any(feature = "io-STM32L051", feature = "io-STM32L071")))]
impl_target!(
// USART1
serial::Tx<USART1>, Channel2, 3;
Expand Down
17 changes: 17 additions & 0 deletions src/exti.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,11 +308,14 @@ impl ExtiLine for GpioLine {
/// both.
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum ConfigurableLine {
#[cfg(not(feature = "stm32l0x0"))]
Pvd = 16,
RtcAlarm = 17,
RtcTamper_CssLse = 19,
RtcWakeup = 20,
#[cfg(not(feature = "stm32l0x0"))]
Comp1 = 21,
#[cfg(not(feature = "stm32l0x0"))]
Comp2 = 22,
}

Expand All @@ -321,12 +324,15 @@ impl ExtiLine for ConfigurableLine {
use ConfigurableLine::*;

Some(match line {
#[cfg(not(feature = "stm32l0x0"))]
16 => Pvd,
17 => RtcAlarm,
// 18 = USB (or reserved)
19 => RtcTamper_CssLse,
20 => RtcWakeup,
#[cfg(not(feature = "stm32l0x0"))]
21 => Comp1,
#[cfg(not(feature = "stm32l0x0"))]
22 => Comp2,
_ => return None,
})
Expand All @@ -341,8 +347,10 @@ impl ExtiLine for ConfigurableLine {
use ConfigurableLine::*;

match self {
#[cfg(not(feature = "stm32l0x0"))]
Pvd => Interrupt::PVD,
RtcAlarm | RtcTamper_CssLse | RtcWakeup => Interrupt::RTC,
#[cfg(not(feature = "stm32l0x0"))]
Comp1 | Comp2 => Interrupt::ADC_COMP,
}
}
Expand All @@ -354,7 +362,9 @@ pub enum DirectLine {
#[cfg(any(feature = "stm32l0x2", feature = "stm32l0x3"))]
Usb = 18,
I2C1 = 23,
#[cfg(not(feature = "stm32l0x0"))]
I2C3 = 24,
#[cfg(not(feature = "stm32l0x0"))]
Usart1 = 25,
Usart2 = 26,
// 27 = reserved
Expand All @@ -370,7 +380,9 @@ impl ExtiLine for DirectLine {
#[cfg(any(feature = "stm32l0x2", feature = "stm32l0x3"))]
18 => Usb,
23 => I2C1,
#[cfg(not(feature = "stm32l0x0"))]
24 => I2C3,
#[cfg(not(feature = "stm32l0x0"))]
25 => Usart1,
26 => Usart2,
// 27 = reserved
Expand All @@ -392,9 +404,14 @@ impl ExtiLine for DirectLine {
#[cfg(any(feature = "stm32l0x2", feature = "stm32l0x3"))]
Usb => Interrupt::USB,
I2C1 => Interrupt::I2C1,
#[cfg(not(feature = "stm32l0x0"))]
I2C3 => Interrupt::I2C3,
#[cfg(not(feature = "stm32l0x0"))]
Usart1 => Interrupt::USART1,
Usart2 => Interrupt::USART2,
#[cfg(feature = "stm32l0x0")]
Lpuart1 => Interrupt::LPUART1,
#[cfg(not(feature = "stm32l0x0"))]
Lpuart1 => Interrupt::AES_RNG_LPUART1,
Lptim1 => Interrupt::LPTIM1,
}
Expand Down
2 changes: 1 addition & 1 deletion src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ macro_rules! gpio {
}

#[allow(dead_code)]
pub(crate) fn set_alt_mode(&self, mode: AltMode) {
pub fn set_alt_mode(&self, mode: AltMode) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there any reason not to make this public? I looked at other hal crates, they made this a private function, but referenced all the pin modes as function

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a reason, but I'm not very familiar with that code. I also don't know why the #[allow(dead_code)] is here and on AltMode itself. Seems all very weird.

let mode = mode as u32;
let offset = 2 * $i;
let offset2 = 4 * $i;
Expand Down
47 changes: 32 additions & 15 deletions src/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,21 @@ use crate::hal::blocking::i2c::{Read, Write, WriteRead};

// I/O Imports
use crate::gpio::{AltMode, OpenDrain, Output};
#[cfg(feature = "io-STM32L051")]
#[cfg(feature = "stm32l0x0")]
use crate::{
gpio::gpioa::{PA9, PA10},
gpio::gpiob::{PB10, PB13, PB7, PB9},
pac::I2C1,
};

#[cfg(all(feature = "io-STM32L051", not(feature = "stm32l0x0")))]
use crate::{
gpio::gpiob::{PB10, PB11, PB13, PB14, PB6, PB7, PB8, PB9},
pac::{I2C1, I2C2},
pac::I2C1,
};
#[cfg(all(feature = "io-STM32L051", not(feature = "stm32l0x0")))]
use create::pac::I2C2;

#[cfg(feature = "io-STM32L021")]
use crate::{
gpio::{
Expand Down Expand Up @@ -538,58 +548,65 @@ macro_rules! i2c {
};
}

#[cfg(feature = "io-STM32L021")]
#[cfg(feature= "stm32l0x0")]
i2c!(
I2C1, i2c1en, i2c1rst,
sda: [
(PA10<Output<OpenDrain>>, AltMode::AF1),
(PA13<Output<OpenDrain>>, AltMode::AF3),
(PA10<Output<OpenDrain>>, AltMode::AF6),
(PB7<Output<OpenDrain>>, AltMode::AF1),
],
(PB9<Output<OpenDrain>>, AltMode::AF4),
],
scl: [
(PA4<Output<OpenDrain>>, AltMode::AF3),
(PA9<Output<OpenDrain>>, AltMode::AF1),
(PB6<Output<OpenDrain>>, AltMode::AF1),
(PB8<Output<OpenDrain>>, AltMode::AF4),
],
(PA9<Output<OpenDrain>>, AltMode::AF6),
(PB10<Output<OpenDrain>>, AltMode::AF6),
(PB13<Output<OpenDrain>>, AltMode::AF5),
],
);

#[cfg(feature = "io-STM32L031")]

#[cfg(feature = "io-STM32L021")]
i2c!(
I2C1, i2c1en, i2c1rst,
sda: [
(PA10<Output<OpenDrain>>, AltMode::AF1),
(PA13<Output<OpenDrain>>, AltMode::AF3),
(PB7<Output<OpenDrain>>, AltMode::AF1),
(PB9<Output<OpenDrain>>, AltMode::AF4),
],
scl: [
(PA4<Output<OpenDrain>>, AltMode::AF3),
(PA9<Output<OpenDrain>>, AltMode::AF1),
(PB6<Output<OpenDrain>>, AltMode::AF1),
(PB8<Output<OpenDrain>>, AltMode::AF4),
],
);

#[cfg(feature = "io-STM32L051")]
#[cfg(feature = "io-STM32L031")]
i2c!(
I2C1, i2c1en, i2c1rst,
sda: [
(PA10<Output<OpenDrain>>, AltMode::AF1),
(PB7<Output<OpenDrain>>, AltMode::AF1),
(PB9<Output<OpenDrain>>, AltMode::AF4),
],
scl: [
(PA9<Output<OpenDrain>>, AltMode::AF1),
(PB6<Output<OpenDrain>>, AltMode::AF1),
(PB8<Output<OpenDrain>>, AltMode::AF4),
],
);

#[cfg(feature = "io-STM32L051")]
#[cfg(all(feature = "io-STM32L051", not(feature = "stm32l0x0")))]
i2c!(
I2C2, i2c2en, i2c2rst,
sda: [
(PB7<Output<OpenDrain>>, AltMode::AF1),
(PB9<Output<OpenDrain>>, AltMode::AF4),
(PB11<Output<OpenDrain>>, AltMode::AF6),
(PB14<Output<OpenDrain>>, AltMode::AF5),
],
scl: [
(PB6<Output<OpenDrain>>, AltMode::AF1),
(PB8<Output<OpenDrain>>, AltMode::AF4),
(PB10<Output<OpenDrain>>, AltMode::AF6),
(PB13<Output<OpenDrain>>, AltMode::AF5),
],
Expand Down
7 changes: 5 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#![cfg_attr(not(test), no_std)]
#![allow(non_camel_case_types)]

#[cfg(not(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3")))]
#[cfg(not(any(feature = "stm32l0x0", feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3")))]
compile_error!(
"This crate requires one of the following features enabled: stm32l0x1, stm32l0x2, stm32l0x3"
"This crate requires one of the following features enabled: stm32l0x0, stm32l0x1, stm32l0x2, stm32l0x3"
);

use embedded_hal as hal;

#[cfg(feature = "stm32l0x0")]
pub use stm32l0::stm32l0x0 as pac;
#[cfg(feature = "stm32l0x1")]
pub use stm32l0::stm32l0x1 as pac;
#[cfg(feature = "stm32l0x2")]
Expand All @@ -16,6 +18,7 @@ pub use stm32l0::stm32l0x2 as pac;
pub use stm32l0::stm32l0x3 as pac;

pub mod adc;
#[cfg(not(feature = "stm32l0x0"))]
pub mod aes;
pub mod calibration;
pub mod delay;
Expand Down
5 changes: 4 additions & 1 deletion src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ pub use crate::{
))]
pub use crate::i2c::I2cExt as _;

#[cfg(any(feature = "io-STM32L051", feature = "io-STM32L071",))]
#[cfg(all(not(feature = "stm32l0x0"), any(feature = "io-STM32L051", feature = "io-STM32L071")))]
pub use crate::serial::{Serial1Ext as _, Serial1LpExt as _};
#[cfg(feature = "stm32l0x0")]
pub use crate::serial::{Serial1LpExt as _};

#[cfg(any(
feature = "io-STM32L021",
feature = "io-STM32L031",
Expand Down
9 changes: 8 additions & 1 deletion src/pwm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use cortex_m::interrupt;
use crate::gpio::gpioa::{PA0, PA1, PA2, PA3};
use crate::gpio::{AltMode, PinMode};
use crate::hal;
use crate::pac::{tim2, TIM2, TIM3};

use crate::pac::{tim2, TIM2};
#[cfg(not(feature = "stm32l0x0"))]
use crate::pac::TIM3;
use crate::rcc::Rcc;
use crate::time::Hertz;
use cast::{u16, u32};
Expand Down Expand Up @@ -132,6 +135,10 @@ macro_rules! impl_instance {

impl_instance!(
TIM2, apb1enr, apb1rstr, tim2en, tim2rst, apb1_clk;
);

#[cfg(not(feature = "stm32l0x0"))]
impl_instance!(
TIM3, apb1enr, apb1rstr, tim3en, tim3rst, apb1_clk;
);

Expand Down
Loading