From ff70b395f44d97db70c75f5c07e89a06d28dcf72 Mon Sep 17 00:00:00 2001 From: "Ivan Radeljak (irii)" Date: Mon, 15 Jan 2024 01:50:34 +0100 Subject: [PATCH 1/5] Update to embedded-hal-1.0.0 --- CHANGELOG.md | 2 + Cargo.toml | 10 ++--- examples/graphics.rs | 2 +- examples/pixelsquare.rs | 2 +- examples/rtic_brightness.rs | 6 +-- examples/rtic_dvd.rs | 6 +-- src/i2c_interface.rs | 6 +-- src/lib.rs | 6 +-- src/prelude.rs | 2 +- src/test_helpers.rs | 77 +++++++++++++++++++++++++++---------- 10 files changed, 79 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8e02d41..bf704ee0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ SSD1306 monochrome OLED display. ## [Unreleased] - ReleaseDate +- Changed dependencies for embbedded-hal-1.0.0 + ### Added - [#203](https://github.com/jamwaffles/ssd1306/pull/203) Added `Ssd1306::release(self)` to release the contained i2c interface. diff --git a/Cargo.toml b/Cargo.toml index 4ad80b4c..45f421f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,16 +11,16 @@ repository = "https://github.com/rust-embedded-community/ssd1306" version = "0.8.4" edition = "2018" exclude = [ "build.rs", "build.sh", "memory.x", "doc", "*.jpg", "*.png", "*.bmp" ] -rust-version = "1.61" +rust-version = "1.75.0" [package.metadata.docs.rs] targets = [ "thumbv7m-none-eabi", "thumbv7em-none-eabihf" ] [dependencies] -embedded-hal = "0.2.5" -display-interface = "0.4.1" -display-interface-i2c = "0.4.0" -display-interface-spi = "0.4.1" +embedded-hal = "1.0.0" +display-interface = "0.5.0" +display-interface-i2c = "0.5.0" +display-interface-spi = "0.5.0" embedded-graphics-core = { version = "0.4.0", optional = true } [dev-dependencies] diff --git a/examples/graphics.rs b/examples/graphics.rs index 33bab8c4..de8f8492 100644 --- a/examples/graphics.rs +++ b/examples/graphics.rs @@ -72,7 +72,7 @@ fn main() -> ! { clocks, ); - let interface = display_interface_spi::SPIInterfaceNoCS::new(spi, dc); + let interface = display_interface_spi::SPIInterface::new(spi, dc); let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0) .into_buffered_graphics_mode(); diff --git a/examples/pixelsquare.rs b/examples/pixelsquare.rs index fd3c676b..1aa47ad8 100644 --- a/examples/pixelsquare.rs +++ b/examples/pixelsquare.rs @@ -68,7 +68,7 @@ fn main() -> ! { clocks, ); - let interface = display_interface_spi::SPIInterfaceNoCS::new(spi, dc); + let interface = display_interface_spi::SPIInterface::new(spi, dc); let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0) .into_buffered_graphics_mode(); diff --git a/examples/rtic_brightness.rs b/examples/rtic_brightness.rs index 6162df0c..49513eca 100644 --- a/examples/rtic_brightness.rs +++ b/examples/rtic_brightness.rs @@ -8,7 +8,7 @@ #[rtic::app(device = stm32f1xx_hal::pac, peripherals = true, dispatchers = [EXTI0])] mod app { - use display_interface_spi::SPIInterfaceNoCS; + use display_interface_spi::SPIInterface; use embedded_graphics::{ geometry::Point, image::Image, @@ -28,7 +28,7 @@ mod app { use tinybmp::Bmp; type Display = Ssd1306< - SPIInterfaceNoCS< + SPIInterface< spi::Spi< SPI1, spi::Spi1NoRemap, @@ -100,7 +100,7 @@ mod app { clocks, ); - let interface = display_interface_spi::SPIInterfaceNoCS::new(spi, dc); + let interface = display_interface_spi::SPIInterface::new(spi, dc); let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate180) .into_buffered_graphics_mode(); diff --git a/examples/rtic_dvd.rs b/examples/rtic_dvd.rs index 1d8ccb84..c119d5be 100644 --- a/examples/rtic_dvd.rs +++ b/examples/rtic_dvd.rs @@ -9,7 +9,7 @@ #[rtic::app(device = stm32f1xx_hal::pac, peripherals = true, dispatchers = [EXTI0])] mod app { - use display_interface_spi::SPIInterfaceNoCS; + use display_interface_spi::SPIInterface; use embedded_graphics::{ geometry::Point, image::Image, @@ -29,7 +29,7 @@ mod app { use tinybmp::Bmp; type Display = Ssd1306< - SPIInterfaceNoCS< + SPIInterface< spi::Spi< SPI1, spi::Spi1NoRemap, @@ -100,7 +100,7 @@ mod app { clocks, ); - let interface = display_interface_spi::SPIInterfaceNoCS::new(spi, dc); + let interface = display_interface_spi::SPIInterface::new(spi, dc); let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate180) .into_buffered_graphics_mode(); diff --git a/src/i2c_interface.rs b/src/i2c_interface.rs index 84a8015a..d76a8773 100644 --- a/src/i2c_interface.rs +++ b/src/i2c_interface.rs @@ -12,7 +12,7 @@ impl I2CDisplayInterface { // pub fn with_i2c(i2c: I) -> I2CInterface // alternative, but breaking change pub fn new(i2c: I) -> I2CInterface where - I: embedded_hal::blocking::i2c::Write, + I: embedded_hal::i2c::I2c, { Self::new_custom_address(i2c, 0x3C) } @@ -20,7 +20,7 @@ impl I2CDisplayInterface { /// Create a new I2C interface with the alternate address 0x3D as specified in the datasheet. pub fn new_alternate_address(i2c: I) -> I2CInterface where - I: embedded_hal::blocking::i2c::Write, + I: embedded_hal::i2c::I2c, { Self::new_custom_address(i2c, 0x3D) } @@ -28,7 +28,7 @@ impl I2CDisplayInterface { /// Create a new I2C interface with a custom address. pub fn new_custom_address(i2c: I, address: u8) -> I2CInterface where - I: embedded_hal::blocking::i2c::Write, + I: embedded_hal::i2c::I2c, { I2CInterface::new(i2c, address, 0x40) } diff --git a/src/lib.rs b/src/lib.rs index cc43eb46..7cedc54a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -126,7 +126,7 @@ use crate::mode::BasicMode; use brightness::Brightness; use command::{AddrMode, Command, VcomhLevel}; use display_interface::{DataFormat::U8, DisplayError, WriteOnlyDataCommand}; -use embedded_hal::{blocking::delay::DelayMs, digital::v2::OutputPin}; +use embedded_hal::{delay::DelayNs, digital::OutputPin}; use error::Error; use mode::{BufferedGraphicsMode, TerminalMode}; use rotation::DisplayRotation; @@ -430,12 +430,12 @@ impl Ssd1306 { ) -> Result<(), Error> where RST: OutputPin, - DELAY: DelayMs, + DELAY: DelayNs, { fn inner_reset(rst: &mut RST, delay: &mut DELAY) -> Result<(), RST::Error> where RST: OutputPin, - DELAY: DelayMs, + DELAY: DelayNs, { rst.set_high()?; delay.delay_ms(1); diff --git a/src/prelude.rs b/src/prelude.rs index 86f9d87c..20616030 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -2,7 +2,7 @@ pub use display_interface::WriteOnlyDataCommand; pub use display_interface_i2c::I2CInterface; -pub use display_interface_spi::{SPIInterface, SPIInterfaceNoCS}; +pub use display_interface_spi::SPIInterface; pub use super::{ brightness::Brightness, diff --git a/src/test_helpers.rs b/src/test_helpers.rs index fc5f4709..0082c410 100644 --- a/src/test_helpers.rs +++ b/src/test_helpers.rs @@ -2,30 +2,59 @@ use display_interface::{DisplayError, WriteOnlyDataCommand}; use embedded_hal::{ - blocking::{ - i2c, - spi::{self, Transfer}, - }, - digital::v2::OutputPin, + digital::{ErrorType, OutputPin}, + i2c, + spi::{self, SpiBus}, }; +#[derive(PartialEq, Eq, Clone, Debug, Copy)] +pub struct Error {} + +impl embedded_hal::digital::Error for Error { + fn kind(&self) -> embedded_hal::digital::ErrorKind { + embedded_hal::digital::ErrorKind::Other + } +} + +impl i2c::Error for Error { + fn kind(&self) -> i2c::ErrorKind { + i2c::ErrorKind::Other + } +} + +impl spi::Error for Error { + fn kind(&self) -> spi::ErrorKind { + spi::ErrorKind::Other + } +} + #[allow(dead_code)] #[derive(Debug, Clone, Copy)] pub struct SpiStub; -impl spi::Write for SpiStub { - type Error = (); +impl spi::ErrorType for SpiStub { + type Error = Error; +} - fn write(&mut self, _buf: &[u8]) -> Result<(), ()> { +impl SpiBus for SpiStub { + fn read(&mut self, _words: &mut [u8]) -> Result<(), Self::Error> { + todo!() + } + + fn write(&mut self, _words: &[u8]) -> Result<(), Self::Error> { + Ok(()) + } + + fn transfer(&mut self, _read: &mut [u8], _write: &[u8]) -> Result<(), Self::Error> { Ok(()) } -} -impl Transfer for SpiStub { - type Error = (); + fn transfer_in_place(&mut self, _words: &mut [u8]) -> Result<(), Self::Error> { + todo!() + } - fn transfer<'a>(&mut self, buf: &'a mut [u8]) -> Result<&'a [u8], ()> { - Ok(buf) + fn flush(&mut self) -> Result<(), Self::Error> { + todo!() } } @@ -33,10 +62,16 @@ impl Transfer for SpiStub { #[derive(Debug, Clone, Copy)] pub struct I2cStub; -impl i2c::Write for I2cStub { - type Error = (); +impl i2c::ErrorType for I2cStub { + type Error = Error; +} - fn write(&mut self, _addr: u8, _buf: &[u8]) -> Result<(), ()> { +impl i2c::I2c for I2cStub { + fn transaction( + &mut self, + _address: u8, + _operations: &mut [i2c::Operation<'_>], + ) -> Result<(), Self::Error> { Ok(()) } } @@ -45,14 +80,16 @@ impl i2c::Write for I2cStub { #[derive(Debug, Clone, Copy)] pub struct PinStub; -impl OutputPin for PinStub { - type Error = (); +impl ErrorType for PinStub { + type Error = Error; +} - fn set_high(&mut self) -> Result<(), ()> { +impl OutputPin for PinStub { + fn set_low(&mut self) -> Result<(), Self::Error> { Ok(()) } - fn set_low(&mut self) -> Result<(), ()> { + fn set_high(&mut self) -> Result<(), Self::Error> { Ok(()) } } From d23a42ab9e0c94b8b423fce7a088676042e38541 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Sat, 22 Jun 2024 23:40:20 +0200 Subject: [PATCH 2/5] ci: Bump msrv rust version to 1.75 The examples might require newer rust version based on the pac crate used; So for the MRSV test only build the actual library and documentation --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 144260fb..12a33907 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,15 +29,15 @@ jobs: - run: cargo test --doc --target x86_64-unknown-linux-gnu test-msrv: - name: test with MSRV + name: build with MSRV runs-on: "ubuntu-latest" steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: - toolchain: 1.61 - - run: cargo test --lib --target x86_64-unknown-linux-gnu - - run: cargo test --doc --target x86_64-unknown-linux-gnu + toolchain: 1.75 + - run: cargo build --lib --target x86_64-unknown-linux-gnu + - run: cargo doc --target x86_64-unknown-linux-gnu build: strategy: From 7c7637919ad8e50dbdd379274042a21101b3bd4a Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Sat, 22 Jun 2024 23:36:05 +0200 Subject: [PATCH 3/5] examples: Switch to embassy-stm32 as a pac provider stmf32f1xx doesn't yet support embedded-hal 1.0. Switch to embassy-stm32 as a pac provider, which can be used in both a sync and async setups. Unfortunately for blocking i2c support embassy git has to be used rather then a releaed version. Also for i2c move the expected configuration from PB8/PB9 to PB6/PB7 to avoid the needed for pin remapping, which embassy doesn't yet support on stm32f1xx chips --- .cargo/config.toml | 2 + Cargo.toml | 12 ++- build.rs | 14 ---- examples/bmp_i2c.rs | 60 +++++---------- examples/graphics.rs | 76 +++++++------------ examples/graphics_i2c.rs | 59 +++++---------- examples/graphics_i2c_128x32.rs | 59 +++++---------- examples/graphics_i2c_72x40.rs | 59 +++++---------- examples/image_i2c.rs | 59 +++++---------- examples/noise_i2c.rs | 54 ++++---------- examples/pixelsquare.rs | 76 +++++++------------ examples/rotation_i2c.rs | 59 +++++---------- examples/rtic_brightness.rs | 122 ++++++++++++++----------------- examples/rtic_dvd.rs | 125 +++++++++++++++----------------- examples/terminal_i2c.rs | 54 ++++---------- examples/text_i2c.rs | 60 +++++---------- memory.x | 6 -- 17 files changed, 322 insertions(+), 634 deletions(-) delete mode 100644 build.rs delete mode 100644 memory.x diff --git a/.cargo/config.toml b/.cargo/config.toml index 6b42f2aa..b5044baa 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -2,6 +2,8 @@ runner = [ "probe-rs", "run", "--chip", "STM32F103C8" ] rustflags = [ "-C", "link-arg=-Tlink.x", + "-C", "link-arg=--nmagic", + "-C", "link-arg=-Tdefmt.x", ] [build] diff --git a/Cargo.toml b/Cargo.toml index 45f421f0..b18c4229 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,23 +24,27 @@ display-interface-spi = "0.5.0" embedded-graphics-core = { version = "0.4.0", optional = true } [dev-dependencies] -cortex-m = "0.7.2" +cortex-m = { version = "0.7.2", features = ["critical-section-single-core"] } cortex-m-rt = "0.7.3" cortex-m-rtic = "1.1.4" -panic-halt = "0.2.0" -cast = { version = "0.2.6", default-features = false } +defmt = "0.3.6" +defmt-rtt = "0.4.0" +panic-probe = { version = "0.3.1", features = ["print-defmt"] } # Used to load BMP images in various examples tinybmp = "0.5.0" embedded-graphics = "0.8.0" # Used by the noise_i2c examples rand = { version = "0.8.4", default-features = false, features = [ "small_rng" ] } -stm32f1xx-hal = { version = "0.10.0", features = [ "rt", "stm32f103" ] } +embassy-stm32 = { version = "0.1.0", git = "https://github.com/embassy-rs/embassy", features = [ "stm32f103c8", "memory-x", "defmt", "exti", "time-driver-tim3" , "unstable-pac"] } +embassy-time = { version = "0.3.1", git = "https://github.com/embassy-rs/embassy" } +embedded-hal-bus = "0.2.0" [features] default = ["graphics"] graphics = ["embedded-graphics-core"] [profile.dev] +opt-level="s" codegen-units = 1 incremental = false diff --git a/build.rs b/build.rs deleted file mode 100644 index 364f9a09..00000000 --- a/build.rs +++ /dev/null @@ -1,14 +0,0 @@ -use std::{env, fs::File, io::Write, path::PathBuf}; - -pub fn main() { - // Put the linker script somewhere the linker can find it - let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); - File::create(out.join("memory.x")) - .unwrap() - .write_all(include_bytes!("memory.x")) - .unwrap(); - println!("cargo:rustc-link-search={}", out.display()); - - println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-changed=memory.x"); -} diff --git a/examples/bmp_i2c.rs b/examples/bmp_i2c.rs index f89eea78..c042cfa7 100644 --- a/examples/bmp_i2c.rs +++ b/examples/bmp_i2c.rs @@ -12,8 +12,8 @@ //! Display -> Blue Pill //! (black) GND -> GND //! (red) +5V -> VCC -//! (yellow) SDA -> PB9 -//! (green) SCL -> PB8 +//! (yellow) SDA -> PB7 +//! (green) SCL -> PB6 //! ``` //! //! Run on a Blue Pill with `cargo run --example image_i2c`. @@ -21,46 +21,25 @@ #![no_std] #![no_main] -use cortex_m_rt::{entry, exception, ExceptionFrame}; +use cortex_m::asm::nop; +use cortex_m_rt::entry; +use defmt_rtt as _; +use embassy_stm32::time::Hertz; use embedded_graphics::{image::Image, pixelcolor::Rgb565, prelude::*}; -use panic_halt as _; +use panic_probe as _; use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; -use stm32f1xx_hal::{ - i2c::{BlockingI2c, DutyCycle, Mode}, - prelude::*, - stm32, -}; + use tinybmp::Bmp; #[entry] fn main() -> ! { - let dp = stm32::Peripherals::take().unwrap(); - - let mut flash = dp.FLASH.constrain(); - let rcc = dp.RCC.constrain(); - - let clocks = rcc.cfgr.freeze(&mut flash.acr); - - let mut afio = dp.AFIO.constrain(); - - let mut gpiob = dp.GPIOB.split(); - - let scl = gpiob.pb8.into_alternate_open_drain(&mut gpiob.crh); - let sda = gpiob.pb9.into_alternate_open_drain(&mut gpiob.crh); - - let i2c = BlockingI2c::i2c1( - dp.I2C1, - (scl, sda), - &mut afio.mapr, - Mode::Fast { - frequency: 400_000.Hz(), - duty_cycle: DutyCycle::Ratio2to1, - }, - clocks, - 1000, - 10, - 1000, - 1000, + let p = embassy_stm32::init(Default::default()); + let i2c = embassy_stm32::i2c::I2c::new_blocking( + p.I2C1, + p.PB6, + p.PB7, + Hertz::khz(400), + Default::default(), ); let interface = I2CDisplayInterface::new(i2c); @@ -80,10 +59,7 @@ fn main() -> ! { display.flush().unwrap(); - loop {} -} - -#[exception] -unsafe fn HardFault(ef: &ExceptionFrame) -> ! { - panic!("{:#?}", ef); + loop { + nop() + } } diff --git a/examples/graphics.rs b/examples/graphics.rs index de8f8492..8d160865 100644 --- a/examples/graphics.rs +++ b/examples/graphics.rs @@ -9,10 +9,11 @@ //! ``` //! GND -> GND //! 3V3 -> VCC -//! PA5 -> SCL -//! PA7 -> SDA +//! PA5 -> SCL (D0) +//! PA7 -> SDA (D1) //! PB0 -> RST //! PB1 -> D/C +//! PB10 -> CS //! ``` //! //! Run on a Blue Pill with `cargo run --example graphics`. @@ -20,63 +21,41 @@ #![no_std] #![no_main] -use cortex_m_rt::{entry, exception, ExceptionFrame}; +use cortex_m::asm::nop; +use cortex_m_rt::entry; +use defmt_rtt as _; +use embassy_stm32::{ + gpio, + spi::{self, Spi}, + time::Hertz, +}; use embedded_graphics::{ pixelcolor::BinaryColor, prelude::*, primitives::{Circle, PrimitiveStyleBuilder, Rectangle, Triangle}, }; -use panic_halt as _; +use panic_probe as _; use ssd1306::{prelude::*, Ssd1306}; -use stm32f1xx_hal::{ - prelude::*, - spi::{Mode, Phase, Polarity, Spi}, - stm32, - timer::Timer, -}; #[entry] fn main() -> ! { - let cp = cortex_m::Peripherals::take().unwrap(); - let dp = stm32::Peripherals::take().unwrap(); - - let mut flash = dp.FLASH.constrain(); - let rcc = dp.RCC.constrain(); - - let clocks = rcc.cfgr.freeze(&mut flash.acr); - - let mut afio = dp.AFIO.constrain(); - - let mut gpioa = dp.GPIOA.split(); - let mut gpiob = dp.GPIOB.split(); + let p = embassy_stm32::init(Default::default()); + let mut config = spi::Config::default(); + config.frequency = Hertz::mhz(8); + let spi = Spi::new_blocking_txonly(p.SPI1, p.PA5, p.PA7, config); - // SPI1 - let sck = gpioa.pa5.into_alternate_push_pull(&mut gpioa.crl); - let miso = gpioa.pa6; - let mosi = gpioa.pa7.into_alternate_push_pull(&mut gpioa.crl); - - let mut delay = Timer::syst(cp.SYST, &clocks).delay(); - - let mut rst = gpiob.pb0.into_push_pull_output(&mut gpiob.crl); - let dc = gpiob.pb1.into_push_pull_output(&mut gpiob.crl); - - let spi = Spi::spi1( - dp.SPI1, - (sck, miso, mosi), - &mut afio.mapr, - Mode { - polarity: Polarity::IdleLow, - phase: Phase::CaptureOnFirstTransition, - }, - 8.MHz(), - clocks, - ); + let mut rst = gpio::Output::new(p.PB0, gpio::Level::Low, gpio::Speed::Low); + let dc = gpio::Output::new(p.PB1, gpio::Level::Low, gpio::Speed::Low); + let cs = gpio::Output::new(p.PB10, gpio::Level::Low, gpio::Speed::Low); + let spi = embedded_hal_bus::spi::ExclusiveDevice::new_no_delay(spi, cs).unwrap(); let interface = display_interface_spi::SPIInterface::new(spi, dc); let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0) .into_buffered_graphics_mode(); - display.reset(&mut rst, &mut delay).unwrap(); + display + .reset(&mut rst, &mut embassy_time::Delay {}) + .unwrap(); display.init().unwrap(); let yoffset = 20; @@ -118,10 +97,7 @@ fn main() -> ! { display.flush().unwrap(); - loop {} -} - -#[exception] -unsafe fn HardFault(ef: &ExceptionFrame) -> ! { - panic!("{:#?}", ef); + loop { + nop() + } } diff --git a/examples/graphics_i2c.rs b/examples/graphics_i2c.rs index cd105a75..d8c06124 100644 --- a/examples/graphics_i2c.rs +++ b/examples/graphics_i2c.rs @@ -8,8 +8,8 @@ //! Display -> Blue Pill //! (black) GND -> GND //! (red) +5V -> VCC -//! (yellow) SDA -> PB9 -//! (green) SCL -> PB8 +//! (yellow) SDA -> PB7 +//! (green) SCL -> PB6 //! ``` //! //! Run on a Blue Pill with `cargo run --example graphics_i2c`. @@ -17,49 +17,27 @@ #![no_std] #![no_main] -use cortex_m_rt::{entry, exception, ExceptionFrame}; +use cortex_m::asm::nop; +use cortex_m_rt::entry; +use defmt_rtt as _; +use embassy_stm32::time::Hertz; use embedded_graphics::{ pixelcolor::BinaryColor, prelude::*, primitives::{Circle, PrimitiveStyleBuilder, Rectangle, Triangle}, }; -use panic_halt as _; +use panic_probe as _; use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; -use stm32f1xx_hal::{ - i2c::{BlockingI2c, DutyCycle, Mode}, - prelude::*, - stm32, -}; #[entry] fn main() -> ! { - let dp = stm32::Peripherals::take().unwrap(); - - let mut flash = dp.FLASH.constrain(); - let rcc = dp.RCC.constrain(); - - let clocks = rcc.cfgr.freeze(&mut flash.acr); - - let mut afio = dp.AFIO.constrain(); - - let mut gpiob = dp.GPIOB.split(); - - let scl = gpiob.pb8.into_alternate_open_drain(&mut gpiob.crh); - let sda = gpiob.pb9.into_alternate_open_drain(&mut gpiob.crh); - - let i2c = BlockingI2c::i2c1( - dp.I2C1, - (scl, sda), - &mut afio.mapr, - Mode::Fast { - frequency: 400_000.Hz(), - duty_cycle: DutyCycle::Ratio2to1, - }, - clocks, - 1000, - 10, - 1000, - 1000, + let p = embassy_stm32::init(Default::default()); + let i2c = embassy_stm32::i2c::I2c::new_blocking( + p.I2C1, + p.PB6, + p.PB7, + Hertz::khz(400), + Default::default(), ); let interface = I2CDisplayInterface::new(i2c); @@ -106,10 +84,7 @@ fn main() -> ! { display.flush().unwrap(); - loop {} -} - -#[exception] -unsafe fn HardFault(ef: &ExceptionFrame) -> ! { - panic!("{:#?}", ef); + loop { + nop() + } } diff --git a/examples/graphics_i2c_128x32.rs b/examples/graphics_i2c_128x32.rs index f092f98e..9620b933 100644 --- a/examples/graphics_i2c_128x32.rs +++ b/examples/graphics_i2c_128x32.rs @@ -8,8 +8,8 @@ //! Display -> Blue Pill //! (black) GND -> GND //! (red) +5V -> VCC -//! (yellow) SDA -> PB9 -//! (green) SCL -> PB8 +//! (yellow) SDA -> PB7 +//! (green) SCL -> PB6 //! ``` //! //! Run on a Blue Pill with `cargo run --example graphics_i2c_128x32`. @@ -17,49 +17,27 @@ #![no_std] #![no_main] -use cortex_m_rt::{entry, exception, ExceptionFrame}; +use cortex_m::asm::nop; +use cortex_m_rt::entry; +use defmt_rtt as _; +use embassy_stm32::time::Hertz; use embedded_graphics::{ pixelcolor::BinaryColor, prelude::*, primitives::{Circle, PrimitiveStyleBuilder, Rectangle, Triangle}, }; -use panic_halt as _; +use panic_probe as _; use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; -use stm32f1xx_hal::{ - i2c::{BlockingI2c, DutyCycle, Mode}, - prelude::*, - stm32, -}; #[entry] fn main() -> ! { - let dp = stm32::Peripherals::take().unwrap(); - - let mut flash = dp.FLASH.constrain(); - let rcc = dp.RCC.constrain(); - - let clocks = rcc.cfgr.freeze(&mut flash.acr); - - let mut afio = dp.AFIO.constrain(); - - let mut gpiob = dp.GPIOB.split(); - - let scl = gpiob.pb8.into_alternate_open_drain(&mut gpiob.crh); - let sda = gpiob.pb9.into_alternate_open_drain(&mut gpiob.crh); - - let i2c = BlockingI2c::i2c1( - dp.I2C1, - (scl, sda), - &mut afio.mapr, - Mode::Fast { - frequency: 400_000.Hz(), - duty_cycle: DutyCycle::Ratio2to1, - }, - clocks, - 1000, - 10, - 1000, - 1000, + let p = embassy_stm32::init(Default::default()); + let i2c = embassy_stm32::i2c::I2c::new_blocking( + p.I2C1, + p.PB6, + p.PB7, + Hertz::khz(400), + Default::default(), ); let interface = I2CDisplayInterface::new(i2c); @@ -106,10 +84,7 @@ fn main() -> ! { display.flush().unwrap(); - loop {} -} - -#[exception] -unsafe fn HardFault(ef: &ExceptionFrame) -> ! { - panic!("{:#?}", ef); + loop { + nop() + } } diff --git a/examples/graphics_i2c_72x40.rs b/examples/graphics_i2c_72x40.rs index b8eed608..e45a4eed 100644 --- a/examples/graphics_i2c_72x40.rs +++ b/examples/graphics_i2c_72x40.rs @@ -8,8 +8,8 @@ //! Display -> Blue Pill //! (black) GND -> GND //! (red) +5V -> VCC -//! (yellow) SDA -> PB9 -//! (green) SCL -> PB8 +//! (yellow) SDA -> PB7 +//! (green) SCL -> PB6 //! ``` //! //! Run on a Blue Pill with `cargo run --example graphics_i2c`. @@ -17,49 +17,27 @@ #![no_std] #![no_main] -use cortex_m_rt::{entry, exception, ExceptionFrame}; +use cortex_m::asm::nop; +use cortex_m_rt::entry; +use defmt_rtt as _; +use embassy_stm32::time::Hertz; use embedded_graphics::{ pixelcolor::BinaryColor, prelude::*, primitives::{Circle, PrimitiveStyleBuilder, Rectangle, Triangle}, }; -use panic_halt as _; +use panic_probe as _; use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; -use stm32f1xx_hal::{ - i2c::{BlockingI2c, DutyCycle, Mode}, - prelude::*, - stm32, -}; #[entry] fn main() -> ! { - let dp = stm32::Peripherals::take().unwrap(); - - let mut flash = dp.FLASH.constrain(); - let rcc = dp.RCC.constrain(); - - let clocks = rcc.cfgr.freeze(&mut flash.acr); - - let mut afio = dp.AFIO.constrain(); - - let mut gpiob = dp.GPIOB.split(); - - let scl = gpiob.pb8.into_alternate_open_drain(&mut gpiob.crh); - let sda = gpiob.pb9.into_alternate_open_drain(&mut gpiob.crh); - - let i2c = BlockingI2c::i2c1( - dp.I2C1, - (scl, sda), - &mut afio.mapr, - Mode::Fast { - frequency: 400_000.Hz(), - duty_cycle: DutyCycle::Ratio2to1, - }, - clocks, - 1000, - 10, - 1000, - 1000, + let p = embassy_stm32::init(Default::default()); + let i2c = embassy_stm32::i2c::I2c::new_blocking( + p.I2C1, + p.PB6, + p.PB7, + Hertz::khz(400), + Default::default(), ); let interface = I2CDisplayInterface::new(i2c); @@ -117,10 +95,7 @@ fn main() -> ! { display.flush().unwrap(); - loop {} -} - -#[exception] -unsafe fn HardFault(ef: &ExceptionFrame) -> ! { - panic!("{:#?}", ef); + loop { + nop() + } } diff --git a/examples/image_i2c.rs b/examples/image_i2c.rs index 309d320b..772cc8ae 100644 --- a/examples/image_i2c.rs +++ b/examples/image_i2c.rs @@ -14,8 +14,8 @@ //! Display -> Blue Pill //! (black) GND -> GND //! (red) +5V -> VCC -//! (yellow) SDA -> PB9 -//! (green) SCL -> PB8 +//! (yellow) SDA -> PB7 +//! (green) SCL -> PB6 //! ``` //! //! Run on a Blue Pill with `cargo run --example image_i2c`. @@ -23,49 +23,27 @@ #![no_std] #![no_main] -use cortex_m_rt::{entry, exception, ExceptionFrame}; +use cortex_m::asm::nop; +use cortex_m_rt::entry; +use defmt_rtt as _; +use embassy_stm32::time::Hertz; use embedded_graphics::{ image::{Image, ImageRaw}, pixelcolor::BinaryColor, prelude::*, }; -use panic_halt as _; +use panic_probe as _; use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; -use stm32f1xx_hal::{ - i2c::{BlockingI2c, DutyCycle, Mode}, - prelude::*, - stm32, -}; #[entry] fn main() -> ! { - let dp = stm32::Peripherals::take().unwrap(); - - let mut flash = dp.FLASH.constrain(); - let rcc = dp.RCC.constrain(); - - let clocks = rcc.cfgr.freeze(&mut flash.acr); - - let mut afio = dp.AFIO.constrain(); - - let mut gpiob = dp.GPIOB.split(); - - let scl = gpiob.pb8.into_alternate_open_drain(&mut gpiob.crh); - let sda = gpiob.pb9.into_alternate_open_drain(&mut gpiob.crh); - - let i2c = BlockingI2c::i2c1( - dp.I2C1, - (scl, sda), - &mut afio.mapr, - Mode::Fast { - frequency: 400_000.Hz(), - duty_cycle: DutyCycle::Ratio2to1, - }, - clocks, - 1000, - 10, - 1000, - 1000, + let p = embassy_stm32::init(Default::default()); + let i2c = embassy_stm32::i2c::I2c::new_blocking( + p.I2C1, + p.PB6, + p.PB7, + Hertz::khz(400), + Default::default(), ); let interface = I2CDisplayInterface::new(i2c); @@ -81,10 +59,7 @@ fn main() -> ! { display.flush().unwrap(); - loop {} -} - -#[exception] -unsafe fn HardFault(ef: &ExceptionFrame) -> ! { - panic!("{:#?}", ef); + loop { + nop() + } } diff --git a/examples/noise_i2c.rs b/examples/noise_i2c.rs index 19f15de1..c51ca290 100644 --- a/examples/noise_i2c.rs +++ b/examples/noise_i2c.rs @@ -10,8 +10,8 @@ //! Display -> Blue Pill //! (black) GND -> GND //! (red) +5V -> VCC -//! (yellow) SDA -> PB9 -//! (green) SCL -> PB8 +//! (yellow) SDA -> PB7 +//! (green) SCL -> PB6 //! ``` //! //! Run on a Blue Pill with `cargo run --example noise_i2c`. Best results when using `--release`. @@ -19,45 +19,22 @@ #![no_std] #![no_main] -use cortex_m_rt::{entry, exception, ExceptionFrame}; -use panic_halt as _; +use cortex_m_rt::entry; +use defmt_rtt as _; +use embassy_stm32::time::Hertz; +use panic_probe as _; use rand::prelude::*; use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; -use stm32f1xx_hal::{ - i2c::{BlockingI2c, DutyCycle, Mode}, - prelude::*, - stm32, -}; #[entry] fn main() -> ! { - let dp = stm32::Peripherals::take().unwrap(); - - let mut flash = dp.FLASH.constrain(); - let rcc = dp.RCC.constrain(); - - let clocks = rcc.cfgr.freeze(&mut flash.acr); - - let mut afio = dp.AFIO.constrain(); - - let mut gpiob = dp.GPIOB.split(); - - let scl = gpiob.pb8.into_alternate_open_drain(&mut gpiob.crh); - let sda = gpiob.pb9.into_alternate_open_drain(&mut gpiob.crh); - - let i2c = BlockingI2c::i2c1( - dp.I2C1, - (scl, sda), - &mut afio.mapr, - Mode::Fast { - frequency: 400_000.Hz(), - duty_cycle: DutyCycle::Ratio2to1, - }, - clocks, - 1000, - 10, - 1000, - 1000, + let p = embassy_stm32::init(Default::default()); + let i2c = embassy_stm32::i2c::I2c::new_blocking( + p.I2C1, + p.PB6, + p.PB7, + Hertz::khz(400), + Default::default(), ); let interface = I2CDisplayInterface::new(i2c); @@ -74,8 +51,3 @@ fn main() -> ! { display.draw(&buf).unwrap(); } } - -#[exception] -unsafe fn HardFault(ef: &ExceptionFrame) -> ! { - panic!("{:#?}", ef); -} diff --git a/examples/pixelsquare.rs b/examples/pixelsquare.rs index 1aa47ad8..af8e1845 100644 --- a/examples/pixelsquare.rs +++ b/examples/pixelsquare.rs @@ -10,10 +10,11 @@ //! ``` //! GND -> GND //! 3V3 -> VCC -//! PA5 -> SCL -//! PA7 -> SDA +//! PA5 -> SCL (D0) +//! PA7 -> SDA (D1) //! PB0 -> RST //! PB1 -> D/C +//! PB10 -> CS //! ``` //! //! Run on a Blue Pill with `cargo run --example pixelsquare`. @@ -21,58 +22,36 @@ #![no_std] #![no_main] -use cortex_m_rt::{entry, exception, ExceptionFrame}; -use panic_halt as _; -use ssd1306::{prelude::*, Ssd1306}; -use stm32f1xx_hal::{ - prelude::*, - spi::{Mode, Phase, Polarity, Spi}, - stm32, - timer::Timer, +use cortex_m::asm::nop; +use cortex_m_rt::entry; +use defmt_rtt as _; +use embassy_stm32::{ + gpio, + spi::{self, Spi}, + time::Hertz, }; +use panic_probe as _; +use ssd1306::{prelude::*, Ssd1306}; #[entry] fn main() -> ! { - let cp = cortex_m::Peripherals::take().unwrap(); - let dp = stm32::Peripherals::take().unwrap(); - - let mut flash = dp.FLASH.constrain(); - let rcc = dp.RCC.constrain(); - - let clocks = rcc.cfgr.freeze(&mut flash.acr); - - let mut afio = dp.AFIO.constrain(); - - let mut gpioa = dp.GPIOA.split(); - let mut gpiob = dp.GPIOB.split(); + let p = embassy_stm32::init(Default::default()); + let mut config = spi::Config::default(); + config.frequency = Hertz::mhz(8); + let spi = Spi::new_blocking_txonly(p.SPI1, p.PA5, p.PA7, config); - // SPI1 - let sck = gpioa.pa5.into_alternate_push_pull(&mut gpioa.crl); - let miso = gpioa.pa6; - let mosi = gpioa.pa7.into_alternate_push_pull(&mut gpioa.crl); - - let mut delay = Timer::syst(cp.SYST, &clocks).delay(); - - let mut rst = gpiob.pb0.into_push_pull_output(&mut gpiob.crl); - let dc = gpiob.pb1.into_push_pull_output(&mut gpiob.crl); - - let spi = Spi::spi1( - dp.SPI1, - (sck, miso, mosi), - &mut afio.mapr, - Mode { - polarity: Polarity::IdleLow, - phase: Phase::CaptureOnFirstTransition, - }, - 8.MHz(), - clocks, - ); + let mut rst = gpio::Output::new(p.PB0, gpio::Level::Low, gpio::Speed::Low); + let dc = gpio::Output::new(p.PB1, gpio::Level::Low, gpio::Speed::Low); + let cs = gpio::Output::new(p.PB10, gpio::Level::Low, gpio::Speed::Low); + let spi = embedded_hal_bus::spi::ExclusiveDevice::new_no_delay(spi, cs).unwrap(); let interface = display_interface_spi::SPIInterface::new(spi, dc); let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0) .into_buffered_graphics_mode(); - display.reset(&mut rst, &mut delay).unwrap(); + display + .reset(&mut rst, &mut embassy_time::Delay {}) + .unwrap(); display.init().unwrap(); // Top side @@ -101,10 +80,7 @@ fn main() -> ! { display.flush().unwrap(); - loop {} -} - -#[exception] -unsafe fn HardFault(ef: &ExceptionFrame) -> ! { - panic!("{:#?}", ef); + loop { + nop() + } } diff --git a/examples/rotation_i2c.rs b/examples/rotation_i2c.rs index 51c0c3b6..67535559 100644 --- a/examples/rotation_i2c.rs +++ b/examples/rotation_i2c.rs @@ -14,8 +14,8 @@ //! Display -> Blue Pill //! (black) GND -> GND //! (red) +5V -> VCC -//! (yellow) SDA -> PB9 -//! (green) SCL -> PB8 +//! (yellow) SDA -> PB7 +//! (green) SCL -> PB6 //! ``` //! //! Run on a Blue Pill with `cargo run --example rotation_i2c`. @@ -23,49 +23,27 @@ #![no_std] #![no_main] -use cortex_m_rt::{entry, exception, ExceptionFrame}; +use cortex_m::asm::nop; +use cortex_m_rt::entry; +use defmt_rtt as _; +use embassy_stm32::time::Hertz; use embedded_graphics::{ image::{Image, ImageRaw}, pixelcolor::BinaryColor, prelude::*, }; -use panic_halt as _; +use panic_probe as _; use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; -use stm32f1xx_hal::{ - i2c::{BlockingI2c, DutyCycle, Mode}, - prelude::*, - stm32, -}; #[entry] fn main() -> ! { - let dp = stm32::Peripherals::take().unwrap(); - - let mut flash = dp.FLASH.constrain(); - let rcc = dp.RCC.constrain(); - - let clocks = rcc.cfgr.freeze(&mut flash.acr); - - let mut afio = dp.AFIO.constrain(); - - let mut gpiob = dp.GPIOB.split(); - - let scl = gpiob.pb8.into_alternate_open_drain(&mut gpiob.crh); - let sda = gpiob.pb9.into_alternate_open_drain(&mut gpiob.crh); - - let i2c = BlockingI2c::i2c1( - dp.I2C1, - (scl, sda), - &mut afio.mapr, - Mode::Fast { - frequency: 400_000.Hz(), - duty_cycle: DutyCycle::Ratio2to1, - }, - clocks, - 1000, - 10, - 1000, - 1000, + let p = embassy_stm32::init(Default::default()); + let i2c = embassy_stm32::i2c::I2c::new_blocking( + p.I2C1, + p.PB6, + p.PB7, + Hertz::khz(400), + Default::default(), ); let interface = I2CDisplayInterface::new(i2c); @@ -90,10 +68,7 @@ fn main() -> ! { display.flush().unwrap(); - loop {} -} - -#[exception] -unsafe fn HardFault(ef: &ExceptionFrame) -> ! { - panic!("{:#?}", ef); + loop { + nop() + } } diff --git a/examples/rtic_brightness.rs b/examples/rtic_brightness.rs index 49513eca..1e159b5f 100644 --- a/examples/rtic_brightness.rs +++ b/examples/rtic_brightness.rs @@ -6,9 +6,23 @@ #![no_std] #![no_main] -#[rtic::app(device = stm32f1xx_hal::pac, peripherals = true, dispatchers = [EXTI0])] +pub mod pac { + pub use embassy_stm32::pac::Interrupt as interrupt; + pub use embassy_stm32::pac::*; +} + +#[rtic::app(device = crate::pac, peripherals= false, dispatchers = [EXTI0])] mod app { + use defmt_rtt as _; use display_interface_spi::SPIInterface; + use embassy_stm32::{ + gpio, + mode::Blocking, + spi::{self, Spi}, + time::Hertz, + timer::low_level::Timer, + Config, + }; use embedded_graphics::{ geometry::Point, image::Image, @@ -16,30 +30,18 @@ mod app { prelude::*, primitives::{PrimitiveStyle, Rectangle}, }; - use panic_halt as _; + use panic_probe as _; use ssd1306::{mode::BufferedGraphicsMode, prelude::*, Ssd1306}; - use stm32f1xx_hal::{ - gpio, - pac::{self, SPI1}, - prelude::*, - spi::{self, Mode, Phase, Polarity, Spi}, - timer::{CounterMs, Event, Timer}, - }; use tinybmp::Bmp; type Display = Ssd1306< SPIInterface< - spi::Spi< - SPI1, - spi::Spi1NoRemap, - ( - gpio::gpioa::PA5>, - gpio::gpioa::PA6>, - gpio::gpioa::PA7>, - ), - u8, + embedded_hal_bus::spi::ExclusiveDevice< + Spi<'static, Blocking>, + gpio::Output<'static>, + embedded_hal_bus::spi::NoDelay, >, - gpio::gpiob::PB1>, + gpio::Output<'static>, >, DisplaySize128x64, BufferedGraphicsMode, @@ -51,7 +53,7 @@ mod app { #[local] struct Resources { display: Display, - timer: CounterMs, + timer: Timer<'static, embassy_stm32::peripherals::TIM1>, top_left: Point, velocity: Point, bmp: Bmp, @@ -59,59 +61,47 @@ mod app { } #[init] - fn init(cx: init::Context) -> (SharedResources, Resources, init::Monotonics) { - let dp = cx.device; - let core = cx.core; - - let mut flash = dp.FLASH.constrain(); - let rcc = dp.RCC.constrain(); - - let clocks = rcc - .cfgr - .use_hse(8.MHz()) - .sysclk(72.MHz()) - .pclk1(36.MHz()) - .freeze(&mut flash.acr); - - let mut afio = dp.AFIO.constrain(); - - let mut gpiob = dp.GPIOB.split(); - let mut gpioa = dp.GPIOA.split(); - - // SPI1 - let sck = gpioa.pa5.into_alternate_push_pull(&mut gpioa.crl); - let miso = gpioa.pa6; - let mosi = gpioa.pa7.into_alternate_push_pull(&mut gpioa.crl); - - let mut delay = Timer::syst(core.SYST, &clocks).delay(); - - let mut rst = gpiob.pb0.into_push_pull_output(&mut gpiob.crl); - let dc = gpiob.pb1.into_push_pull_output(&mut gpiob.crl); - - let spi = Spi::spi1( - dp.SPI1, - (sck, miso, mosi), - &mut afio.mapr, - Mode { - polarity: Polarity::IdleLow, - phase: Phase::CaptureOnFirstTransition, - }, - 8.MHz(), - clocks, - ); + fn init(_cx: init::Context) -> (SharedResources, Resources, init::Monotonics) { + let mut config: Config = Default::default(); + config.rcc.hse = Some(embassy_stm32::rcc::Hse { + freq: Hertz::mhz(8), + mode: embassy_stm32::rcc::HseMode::Oscillator, + }); + config.rcc.sys = embassy_stm32::rcc::Sysclk::PLL1_P; + config.rcc.pll = Some(embassy_stm32::rcc::Pll { + src: embassy_stm32::rcc::PllSource::HSE, + prediv: embassy_stm32::rcc::PllPreDiv::DIV1, + mul: embassy_stm32::rcc::PllMul::MUL9, // 8 * 9 = 72Mhz + }); + // Scale down to 36Mhz (maximum allowed) + config.rcc.apb1_pre = embassy_stm32::rcc::APBPrescaler::DIV2; + + let p = embassy_stm32::init(config); + let mut config = spi::Config::default(); + config.frequency = Hertz::mhz(8); + let spi = Spi::new_blocking_txonly(p.SPI1, p.PA5, p.PA7, config); + + let mut rst = gpio::Output::new(p.PB0, gpio::Level::Low, gpio::Speed::Low); + let dc = gpio::Output::new(p.PB1, gpio::Level::Low, gpio::Speed::Low); + let cs = gpio::Output::new(p.PB10, gpio::Level::Low, gpio::Speed::Low); + let spi = embedded_hal_bus::spi::ExclusiveDevice::new_no_delay(spi, cs).unwrap(); let interface = display_interface_spi::SPIInterface::new(spi, dc); let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate180) .into_buffered_graphics_mode(); - display.reset(&mut rst, &mut delay).unwrap(); + display + .reset(&mut rst, &mut embassy_time::Delay {}) + .unwrap(); display.init().unwrap(); + // Forget the RST pin to keep the display out of reset + core::mem::forget(rst); // Update framerate - let mut timer = dp.TIM1.counter_ms(&clocks); - timer.start(50.millis()).unwrap(); // 20 FPS - - timer.listen(Event::Update); + let timer = Timer::new(p.TIM1); + timer.set_frequency(Hertz(20)); // 20 FPS + timer.enable_update_interrupt(true); + timer.start(); let bmp = Bmp::from_slice(include_bytes!("dvd.bmp")).unwrap(); @@ -191,6 +181,6 @@ mod app { display.flush().unwrap(); // Clears the update flag - timer.clear_interrupt(Event::Update); + timer.clear_update_interrupt(); } } diff --git a/examples/rtic_dvd.rs b/examples/rtic_dvd.rs index c119d5be..c4cafe1f 100644 --- a/examples/rtic_dvd.rs +++ b/examples/rtic_dvd.rs @@ -7,9 +7,23 @@ #![no_std] #![no_main] -#[rtic::app(device = stm32f1xx_hal::pac, peripherals = true, dispatchers = [EXTI0])] +pub mod pac { + pub use embassy_stm32::pac::Interrupt as interrupt; + pub use embassy_stm32::pac::*; +} + +#[rtic::app(device = crate::pac, peripherals= false, dispatchers = [EXTI0])] mod app { + use defmt_rtt as _; use display_interface_spi::SPIInterface; + use embassy_stm32::{ + gpio, + mode::Blocking, + spi::{self, Spi}, + time::Hertz, + timer::low_level::Timer, + Config, + }; use embedded_graphics::{ geometry::Point, image::Image, @@ -17,30 +31,18 @@ mod app { prelude::*, primitives::{PrimitiveStyle, Rectangle}, }; - use panic_halt as _; + use panic_probe as _; use ssd1306::{mode::BufferedGraphicsMode, prelude::*, Ssd1306}; - use stm32f1xx_hal::{ - gpio, - pac::{self, SPI1}, - prelude::*, - spi::{self, Mode, Phase, Polarity, Spi}, - timer::{CounterMs, Event, Timer}, - }; use tinybmp::Bmp; type Display = Ssd1306< SPIInterface< - spi::Spi< - SPI1, - spi::Spi1NoRemap, - ( - gpio::gpioa::PA5>, - gpio::gpioa::PA6>, - gpio::gpioa::PA7>, - ), - u8, + embedded_hal_bus::spi::ExclusiveDevice< + Spi<'static, Blocking>, + gpio::Output<'static>, + embedded_hal_bus::spi::NoDelay, >, - gpio::gpiob::PB1>, + gpio::Output<'static>, >, DisplaySize128x64, BufferedGraphicsMode, @@ -52,66 +54,55 @@ mod app { #[local] struct Resources { display: Display, - timer: CounterMs, + timer: Timer<'static, embassy_stm32::peripherals::TIM1>, top_left: Point, velocity: Point, bmp: Bmp, } #[init] - fn init(cx: init::Context) -> (SharedResources, Resources, init::Monotonics) { - let dp = cx.device; - let core = cx.core; - - let mut flash = dp.FLASH.constrain(); - let rcc = dp.RCC.constrain(); - - let clocks = rcc - .cfgr - .use_hse(8.MHz()) - .sysclk(72.MHz()) - .pclk1(36.MHz()) - .freeze(&mut flash.acr); - - let mut afio = dp.AFIO.constrain(); - - let mut gpiob = dp.GPIOB.split(); - let mut gpioa = dp.GPIOA.split(); - - // SPI1 - let sck = gpioa.pa5.into_alternate_push_pull(&mut gpioa.crl); - let miso = gpioa.pa6; - let mosi = gpioa.pa7.into_alternate_push_pull(&mut gpioa.crl); - - let mut delay = Timer::syst(core.SYST, &clocks).delay(); - - let mut rst = gpiob.pb0.into_push_pull_output(&mut gpiob.crl); - let dc = gpiob.pb1.into_push_pull_output(&mut gpiob.crl); - - let spi = Spi::spi1( - dp.SPI1, - (sck, miso, mosi), - &mut afio.mapr, - Mode { - polarity: Polarity::IdleLow, - phase: Phase::CaptureOnFirstTransition, - }, - 8.MHz(), - clocks, - ); + fn init(_cx: init::Context) -> (SharedResources, Resources, init::Monotonics) { + let mut config: Config = Default::default(); + config.rcc.hse = Some(embassy_stm32::rcc::Hse { + freq: Hertz::mhz(8), + mode: embassy_stm32::rcc::HseMode::Oscillator, + }); + config.rcc.sys = embassy_stm32::rcc::Sysclk::PLL1_P; + config.rcc.pll = Some(embassy_stm32::rcc::Pll { + src: embassy_stm32::rcc::PllSource::HSE, + prediv: embassy_stm32::rcc::PllPreDiv::DIV1, + mul: embassy_stm32::rcc::PllMul::MUL9, // 8 * 9 = 72Mhz + }); + // Scale down to 36Mhz (maximum allowed) + config.rcc.apb1_pre = embassy_stm32::rcc::APBPrescaler::DIV2; + + let p = embassy_stm32::init(config); + let mut config = spi::Config::default(); + config.frequency = Hertz::mhz(8); + let spi = Spi::new_blocking_txonly(p.SPI1, p.PA5, p.PA7, config); + + let mut rst = gpio::Output::new(p.PB0, gpio::Level::Low, gpio::Speed::Low); + let dc = gpio::Output::new(p.PB1, gpio::Level::Low, gpio::Speed::Low); + let cs = gpio::Output::new(p.PB10, gpio::Level::Low, gpio::Speed::Low); + let spi = embedded_hal_bus::spi::ExclusiveDevice::new_no_delay(spi, cs).unwrap(); let interface = display_interface_spi::SPIInterface::new(spi, dc); let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate180) .into_buffered_graphics_mode(); - display.reset(&mut rst, &mut delay).unwrap(); + display + .reset(&mut rst, &mut embassy_time::Delay {}) + .unwrap(); display.init().unwrap(); - // Update framerate - let mut timer = dp.TIM1.counter_ms(&clocks); - timer.start(50.millis()).unwrap(); // 20 FPS + // Forget the RST pin to keep the display out of reset + core::mem::forget(rst); - timer.listen(Event::Update); + // Update framerate + let timer = Timer::new(p.TIM1); + timer.set_frequency(Hertz(20)); // 20 FPS + timer.enable_update_interrupt(true); + timer.start(); let bmp = Bmp::from_slice(include_bytes!("dvd.bmp")).unwrap(); @@ -129,7 +120,7 @@ mod app { ) } - #[task(binds = TIM1_UP, local = [display, top_left, velocity, timer, bmp])] + #[task(binds = TIM1_UP, local = [display, top_left, velocity, timer, bmp ])] fn update(cx: update::Context) { let update::LocalResources { display, @@ -171,6 +162,6 @@ mod app { display.flush().unwrap(); // Clears the update flag - timer.clear_interrupt(Event::Update); + timer.clear_update_interrupt(); } } diff --git a/examples/terminal_i2c.rs b/examples/terminal_i2c.rs index 9a52dc66..f1fb86bb 100644 --- a/examples/terminal_i2c.rs +++ b/examples/terminal_i2c.rs @@ -8,8 +8,8 @@ //! Display -> Blue Pill //! (black) GND -> GND //! (red) +5V -> VCC -//! (yellow) SDA -> PB9 -//! (green) SCL -> PB8 +//! (yellow) SDA -> PB7 +//! (green) SCL -> PB6 //! ``` //! //! Run on a Blue Pill with `cargo run --example terminal_i2c`. @@ -18,44 +18,21 @@ #![no_main] use core::fmt::Write; -use cortex_m_rt::{entry, exception, ExceptionFrame}; -use panic_halt as _; +use cortex_m_rt::entry; +use defmt_rtt as _; +use embassy_stm32::time::Hertz; +use panic_probe as _; use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; -use stm32f1xx_hal::{ - i2c::{BlockingI2c, DutyCycle, Mode}, - prelude::*, - stm32, -}; #[entry] fn main() -> ! { - let dp = stm32::Peripherals::take().unwrap(); - - let mut flash = dp.FLASH.constrain(); - let rcc = dp.RCC.constrain(); - - let clocks = rcc.cfgr.freeze(&mut flash.acr); - - let mut afio = dp.AFIO.constrain(); - - let mut gpiob = dp.GPIOB.split(); - - let scl = gpiob.pb8.into_alternate_open_drain(&mut gpiob.crh); - let sda = gpiob.pb9.into_alternate_open_drain(&mut gpiob.crh); - - let i2c = BlockingI2c::i2c1( - dp.I2C1, - (scl, sda), - &mut afio.mapr, - Mode::Fast { - frequency: 400_000.Hz(), - duty_cycle: DutyCycle::Ratio2to1, - }, - clocks, - 1000, - 10, - 1000, - 1000, + let p = embassy_stm32::init(Default::default()); + let i2c = embassy_stm32::i2c::I2c::new_blocking( + p.I2C1, + p.PB6, + p.PB7, + Hertz::khz(400), + Default::default(), ); let interface = I2CDisplayInterface::new(i2c); @@ -74,8 +51,3 @@ fn main() -> ! { } } } - -#[exception] -unsafe fn HardFault(ef: &ExceptionFrame) -> ! { - panic!("{:#?}", ef); -} diff --git a/examples/text_i2c.rs b/examples/text_i2c.rs index d1f21a1c..b5e95158 100644 --- a/examples/text_i2c.rs +++ b/examples/text_i2c.rs @@ -9,8 +9,8 @@ //! Display -> Blue Pill //! (black) GND -> GND //! (red) +5V -> VCC -//! (yellow) SDA -> PB9 -//! (green) SCL -> PB8 +//! (yellow) SDA -> PB7 +//! (green) SCL -> PB6 //! ``` //! //! Run on a Blue Pill with `cargo run --example text_i2c`. @@ -18,50 +18,28 @@ #![no_std] #![no_main] -use cortex_m_rt::{entry, exception, ExceptionFrame}; +use cortex_m::asm::nop; +use cortex_m_rt::entry; +use defmt_rtt as _; +use embassy_stm32::time::Hertz; use embedded_graphics::{ mono_font::{ascii::FONT_6X10, MonoTextStyleBuilder}, pixelcolor::BinaryColor, prelude::*, text::{Baseline, Text}, }; -use panic_halt as _; +use panic_probe as _; use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; -use stm32f1xx_hal::{ - i2c::{BlockingI2c, DutyCycle, Mode}, - prelude::*, - stm32, -}; #[entry] fn main() -> ! { - let dp = stm32::Peripherals::take().unwrap(); - - let mut flash = dp.FLASH.constrain(); - let rcc = dp.RCC.constrain(); - - let clocks = rcc.cfgr.freeze(&mut flash.acr); - - let mut afio = dp.AFIO.constrain(); - - let mut gpiob = dp.GPIOB.split(); - - let scl = gpiob.pb8.into_alternate_open_drain(&mut gpiob.crh); - let sda = gpiob.pb9.into_alternate_open_drain(&mut gpiob.crh); - - let i2c = BlockingI2c::i2c1( - dp.I2C1, - (scl, sda), - &mut afio.mapr, - Mode::Fast { - frequency: 400_000.Hz(), - duty_cycle: DutyCycle::Ratio2to1, - }, - clocks, - 1000, - 10, - 1000, - 1000, + let p = embassy_stm32::init(Default::default()); + let i2c = embassy_stm32::i2c::I2c::new_blocking( + p.I2C1, + p.PB6, + p.PB7, + Hertz::khz(400), + Default::default(), ); let interface = I2CDisplayInterface::new(i2c); @@ -83,11 +61,7 @@ fn main() -> ! { .unwrap(); display.flush().unwrap(); - - loop {} -} - -#[exception] -unsafe fn HardFault(ef: &ExceptionFrame) -> ! { - panic!("{:#?}", ef); + loop { + nop() + } } diff --git a/memory.x b/memory.x deleted file mode 100644 index 71f245d1..00000000 --- a/memory.x +++ /dev/null @@ -1,6 +0,0 @@ -/* Linker script for the STM32F103C8T6 */ -MEMORY -{ - FLASH : ORIGIN = 0x08000000, LENGTH = 64K - RAM : ORIGIN = 0x20000000, LENGTH = 20K -} From b8be87a8fce316d86bc4f273348e94bfa21ca377 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Sun, 23 Jun 2024 14:34:58 +0200 Subject: [PATCH 4/5] cargo: Bump to edition 2021 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index b18c4229..8b7dda67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ name = "ssd1306" readme = "README.md" repository = "https://github.com/rust-embedded-community/ssd1306" version = "0.8.4" -edition = "2018" +edition = "2021" exclude = [ "build.rs", "build.sh", "memory.x", "doc", "*.jpg", "*.png", "*.bmp" ] rust-version = "1.75.0" From bad421a066723cf40e36b2257ff1aaf2956cba63 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Mon, 24 Jun 2024 22:15:11 +0200 Subject: [PATCH 5/5] Update changelog --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf704ee0..d6a004b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,9 @@ SSD1306 monochrome OLED display. ## [Unreleased] - ReleaseDate -- Changed dependencies for embbedded-hal-1.0.0 +- Updated dependencies for `embedded-hal` 1.0.0. +- Switch examples to embassy STM32 PAC which implements `embedded-hal` 1.0.0 traits. +- **(breaking)** Increased MSRV to 1.75.0 ### Added