Skip to content

Commit

Permalink
Merge pull request #192 from wbuck/feature/embedded-time
Browse files Browse the repository at this point in the history
Feature/embedded time
  • Loading branch information
Sh3Rm4n authored Mar 11, 2021
2 parents dbadc66 + 5be98c1 commit 3c4dcd4
Show file tree
Hide file tree
Showing 19 changed files with 217 additions and 298 deletions.
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

## [v0.7.0] - 2021-03-10

### Added

- Replace custom time based units with types defined in the [embedded-time][] crate ([#192])

### Breaking changes

- The `rcc` public API now expects time based units in `Megahertz`.
If the supplied frequency cannot be converted to `Hertz` the code
will `panic`. This will occur if the supplied `Megahertz` frequency
cannot fit into `u32::MAX` when converting to `Hertz`

```rust
// The supplied frequencies must be in `MHz`.
let clocks = rcc
.cfgr
.use_hse(8u32.MHz())
.hclk(48u32.MHz())
.sysclk(48u32.MHz())
.pclk1(12u32.MHz())
.pclk2(12u32.MHz())
```

[embedded-time]: https://github.com/FluenTech/embedded-time/
### Changed

- Added support for more CAN bit rates and modes. ([#186])
Expand Down Expand Up @@ -273,6 +298,7 @@ let clocks = rcc

[#208]: https://github.com/stm32-rs/stm32f3xx-hal/pull/208
[#203]: https://github.com/stm32-rs/stm32f3xx-hal/issues/203
[#192]: https://github.com/stm32-rs/stm32f3xx-hal/pull/192
[#186]: https://github.com/stm32-rs/stm32f3xx-hal/pull/186
[#184]: https://github.com/stm32-rs/stm32f3xx-hal/pull/184
[#172]: https://github.com/stm32-rs/stm32f3xx-hal/pull/172
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ nb = "0.1"
paste = "1"
rtcc = "0.2"
stm32f3 = "0.12"
embedded-time = "0.10"

[dependencies.embedded-hal-can]
version = "0.1.0"
Expand Down
11 changes: 6 additions & 5 deletions examples/can.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use cortex_m_rt::entry;

use hal::prelude::*;
use hal::stm32;
use hal::time::{duration::*, rate::*};
use hal::watchdog::IndependentWatchDog;

use hal::can::{Can, CanFilter, CanFrame, CanId, Filter, Frame, Receiver, Transmitter};
Expand All @@ -31,10 +32,10 @@ fn main() -> ! {

let _clocks = rcc
.cfgr
.use_hse(32.mhz())
.sysclk(32.mhz())
.pclk1(16.mhz())
.pclk2(16.mhz())
.use_hse(32u32.MHz())
.sysclk(32u32.MHz())
.pclk1(16u32.MHz())
.pclk2(16u32.MHz())
.freeze(&mut flash.acr);

// Configure CAN RX and TX pins (AF9)
Expand All @@ -60,7 +61,7 @@ fn main() -> ! {
// Watchdog makes sure this gets restarted periodically if nothing happens
let mut iwdg = IndependentWatchDog::new(dp.IWDG);
iwdg.stop_on_debug(&dp.DBGMCU, true);
iwdg.start(100.ms());
iwdg.start(100u32.milliseconds());

// Send an initial message!
asm::delay(100_000);
Expand Down
12 changes: 10 additions & 2 deletions examples/i2c_scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
#![no_std]
#![no_main]

use core::ops::Range;
use core::{convert::TryInto, ops::Range};

use panic_semihosting as _;

use cortex_m::asm;
use cortex_m_rt::entry;
use cortex_m_semihosting::{hprint, hprintln};

use hal::time::rate::*;
use stm32f3xx_hal::{self as hal, pac, prelude::*};

const VALID_ADDR_RANGE: Range<u8> = 0x08..0x78;
Expand All @@ -33,7 +34,14 @@ fn main() -> ! {
gpiob.pb6.into_af4(&mut gpiob.moder, &mut gpiob.afrl), // SCL
gpiob.pb7.into_af4(&mut gpiob.moder, &mut gpiob.afrl), // SDA
);
let mut i2c = hal::i2c::I2c::new(dp.I2C1, pins, 100.khz(), clocks, &mut rcc.apb1);

let mut i2c = hal::i2c::I2c::new(
dp.I2C1,
pins,
100u32.kHz().try_into().unwrap(),
clocks,
&mut rcc.apb1,
);

hprintln!("Start i2c scanning...").expect("Error using hprintln.");
hprintln!().unwrap();
Expand Down
28 changes: 14 additions & 14 deletions examples/pwm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use hal::gpio::GpioExt;
use hal::pac;
use hal::pwm::{tim16, tim2, tim3, tim8};
use hal::rcc::RccExt;
use hal::time::U32Ext;
use hal::time::rate::*;

#[entry]
fn main() -> ! {
Expand All @@ -28,7 +28,7 @@ fn main() -> ! {
// Configure our clocks
let mut flash = dp.FLASH.constrain();
let mut rcc = dp.RCC.constrain();
let clocks = rcc.cfgr.sysclk(16.mhz()).freeze(&mut flash.acr);
let clocks = rcc.cfgr.sysclk(16u32.MHz()).freeze(&mut flash.acr);

// Prep the pins we need in their correct alternate function
let mut gpioa = dp.GPIOA.split(&mut rcc.ahb);
Expand All @@ -52,9 +52,9 @@ fn main() -> ! {
// A four channel general purpose timer that's broadly available
let tim3_channels = tim3(
dp.TIM3,
1280, // resolution of duty cycle
50.hz(), // frequency of period
&clocks, // To get the timer's clock speed
1280, // resolution of duty cycle
50u32.Hz(), // frequency of period
&clocks, // To get the timer's clock speed
);

// Channels without pins cannot be enabled, so we can't forget to
Expand Down Expand Up @@ -101,9 +101,9 @@ fn main() -> ! {
// A 32-bit timer, so we can set a larger resolution
let tim2_channels = tim2(
dp.TIM2,
160000, // resolution of duty cycle
50.hz(), // frequency of period
&clocks, // To get the timer's clock speed
160000, // resolution of duty cycle
50u32.Hz(), // frequency of period
&clocks, // To get the timer's clock speed
);

let mut tim2_ch3 = tim2_channels.2.output_to_pb10(pb10);
Expand All @@ -116,9 +116,9 @@ fn main() -> ! {
// just use it directly
let mut tim16_ch1 = tim16(
dp.TIM16,
1280, // resolution of duty cycle
50.hz(), // frequency of period
&clocks, // To get the timer's clock speed
1280, // resolution of duty cycle
50u32.Hz(), // frequency of period
&clocks, // To get the timer's clock speed
)
.output_to_pb8(pb8);
tim16_ch1.set_duty(tim16_ch1.get_max_duty() / 20); // 5% duty cyle
Expand All @@ -130,9 +130,9 @@ fn main() -> ! {
// to complementary pins (works just like standard pins)
let tim8_channels = tim8(
dp.TIM8,
1280, // resolution of duty cycle
50.hz(), // frequency of period
&clocks, // To get the timer's clock speed
1280, // resolution of duty cycle
50u32.Hz(), // frequency of period
&clocks, // To get the timer's clock speed
);

let mut tim8_ch1 = tim8_channels.0.output_to_pc10(pc10);
Expand Down
4 changes: 2 additions & 2 deletions examples/serial_dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use panic_semihosting as _;

use cortex_m::{asm, singleton};
use cortex_m_rt::entry;
use stm32f3xx_hal::{pac, prelude::*, serial::Serial};
use stm32f3xx_hal::{pac, prelude::*, serial::Serial, time::rate::*};

#[entry]
fn main() -> ! {
Expand All @@ -25,7 +25,7 @@ fn main() -> ! {
gpioa.pa9.into_af7(&mut gpioa.moder, &mut gpioa.afrh),
gpioa.pa10.into_af7(&mut gpioa.moder, &mut gpioa.afrh),
);
let serial = Serial::usart1(dp.USART1, pins, 9600.bps(), clocks, &mut rcc.apb2);
let serial = Serial::usart1(dp.USART1, pins, 9600.Bd(), clocks, &mut rcc.apb2);
let (tx, rx) = serial.split();

let dma1 = dp.DMA1.split(&mut rcc.ahb);
Expand Down
11 changes: 7 additions & 4 deletions examples/spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#![no_std]
#![no_main]

use core::convert::TryInto;

use panic_semihosting as _;

use stm32f3xx_hal as hal;
Expand All @@ -13,6 +15,7 @@ use cortex_m_rt::entry;
use hal::pac;
use hal::prelude::*;
use hal::spi::{Mode, Phase, Polarity, Spi};
use hal::time::rate::*;

#[entry]
fn main() -> ! {
Expand All @@ -24,9 +27,9 @@ fn main() -> ! {

let clocks = rcc
.cfgr
.use_hse(8.mhz())
.sysclk(48.mhz())
.pclk1(24.mhz())
.use_hse(8u32.MHz())
.sysclk(48u32.MHz())
.pclk1(24u32.MHz())
.freeze(&mut flash.acr);

// Configure pins for SPI
Expand All @@ -43,7 +46,7 @@ fn main() -> ! {
dp.SPI1,
(sck, miso, mosi),
spi_mode,
3.mhz(),
3u32.MHz().try_into().unwrap(),
clocks,
&mut rcc.apb2,
);
Expand Down
9 changes: 5 additions & 4 deletions examples/usb_serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use cortex_m_rt::entry;

use hal::pac;
use hal::prelude::*;
use hal::time::rate::*;
use hal::usb::{Peripheral, UsbBus};

use usb_device::prelude::*;
Expand All @@ -26,10 +27,10 @@ fn main() -> ! {

let clocks = rcc
.cfgr
.use_hse(8.mhz())
.sysclk(48.mhz())
.pclk1(24.mhz())
.pclk2(24.mhz())
.use_hse(8u32.MHz())
.sysclk(48u32.MHz())
.pclk1(24u32.MHz())
.pclk2(24u32.MHz())
.freeze(&mut flash.acr);

assert!(clocks.usbclk_valid());
Expand Down
17 changes: 7 additions & 10 deletions src/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{
hal::blocking::i2c::{Read, Write, WriteRead},
pac::{i2c1::RegisterBlock, rcc::cfgr3::I2C1SW_A, I2C1, RCC},
rcc::{Clocks, APB1},
time::{Hertz, U32Ext},
time::rate::*,
};

#[cfg(not(feature = "gpio-f333"))]
Expand Down Expand Up @@ -111,16 +111,13 @@ macro_rules! busy_wait {

impl<I2C, SCL, SDA> I2c<I2C, (SCL, SDA)> {
/// Configures the I2C peripheral to work in master mode
pub fn new<F>(i2c: I2C, pins: (SCL, SDA), freq: F, clocks: Clocks, apb1: &mut APB1) -> Self
pub fn new(i2c: I2C, pins: (SCL, SDA), freq: Hertz, clocks: Clocks, apb1: &mut APB1) -> Self
where
I2C: Instance,
SCL: SclPin<I2C>,
SDA: SdaPin<I2C>,
F: Into<Hertz>,
{
let freq = freq.into().0;

crate::assert!(freq <= 1_000_000);
crate::assert!(*freq.integer() <= 1_000_000);

I2C::enable_clock(apb1);

Expand All @@ -133,16 +130,16 @@ impl<I2C, SCL, SDA> I2c<I2C, (SCL, SDA)> {
// t_SYNC1 + t_SYNC2 > 4 * t_I2CCLK
// t_SCL ~= t_SYNC1 + t_SYNC2 + t_SCLL + t_SCLH
let i2cclk = I2C::clock(&clocks).0;
let ratio = i2cclk / freq - 4;
let (presc, scll, sclh, sdadel, scldel) = if freq >= 100_000 {
let ratio = i2cclk / *freq.integer() - 4;
let (presc, scll, sclh, sdadel, scldel) = if *freq.integer() >= 100_000 {
// fast-mode or fast-mode plus
// here we pick SCLL + 1 = 2 * (SCLH + 1)
let presc = ratio / 387;

let sclh = ((ratio / (presc + 1)) - 3) / 3;
let scll = 2 * (sclh + 1) - 1;

let (sdadel, scldel) = if freq > 400_000 {
let (sdadel, scldel) = if *freq.integer() > 400_000 {
// fast-mode plus
let sdadel = 0;
let scldel = i2cclk / 4_000_000 / (presc + 1) - 1;
Expand Down Expand Up @@ -451,7 +448,7 @@ macro_rules! i2c {
fn clock(clocks: &Clocks) -> Hertz {
// NOTE(unsafe) atomic read with no side effects
match unsafe { (*RCC::ptr()).cfgr3.read().$i2cXsw().variant() } {
I2C1SW_A::HSI => 8.mhz().into(),
I2C1SW_A::HSI => Hertz(8_000_000),
I2C1SW_A::SYSCLK => clocks.sysclk(),
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ pub use embedded_hal as hal;
pub use nb;
pub use nb::block;

pub use embedded_time as time;

#[cfg(feature = "defmt")]
pub(crate) use defmt::{assert, panic, unreachable, unwrap};
#[cfg(feature = "defmt")]
Expand Down Expand Up @@ -188,7 +190,6 @@ cfg_if::cfg_if! {
pub mod rtc;
pub mod serial;
pub mod spi;
pub mod time;
pub mod timer;
}
}
Expand Down
1 change: 0 additions & 1 deletion src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ pub use crate::flash::FlashExt as _stm32f3xx_hal_flash_FlashExt;
pub use crate::gpio::GpioExt as _stm32f3xx_hal_gpio_GpioExt;
pub use crate::hal::prelude::*;
pub use crate::rcc::RccExt as _stm32f3xx_hal_rcc_RccExt;
pub use crate::time::U32Ext as _stm32f3xx_hal_time_U32Ext;
#[cfg(feature = "unproven")]
pub use crate::{
hal::digital::v2::InputPin as _embedded_hal_digital_InputPin,
Expand Down
Loading

0 comments on commit 3c4dcd4

Please sign in to comment.