diff --git a/README.md b/README.md index 6faebbe..3401486 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ If no microcontroller is specified, the crate will not compile. * `stm32f722` * `stm32f723` * `stm32f730` +* `stm32f730-lpc` ("low pin count" variant) * `stm32f732` * `stm32f733` * `stm32f745` diff --git a/build.rs b/build.rs index fdabffc..4546dca 100644 --- a/build.rs +++ b/build.rs @@ -88,7 +88,7 @@ impl SubFamily { SubFamily::Stm32f722 } else if cfg!(feature = "stm32f723") { SubFamily::Stm32f723 - } else if cfg!(feature = "stm32f730") { + } else if cfg!(feature = "stm32f730") || cfg!(feature = "stm32f730-lpc") { SubFamily::Stm32f730 } else if cfg!(feature = "stm32f732") { SubFamily::Stm32f732 diff --git a/src/flash.rs b/src/flash.rs index 1437665..ab739fc 100644 --- a/src/flash.rs +++ b/src/flash.rs @@ -202,7 +202,7 @@ impl<'a> EraseSequence<'a> { flash.check_locked_or_busy()?; flash.clear_errors(); - flash.registers.cr.modify(|_, w| unsafe { + flash.registers.cr.modify(|_, w| { #[cfg(any( feature = "stm32f765", feature = "stm32f767", diff --git a/src/lib.rs b/src/lib.rs index 8655025..71b622f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,6 +9,7 @@ compile_error!( stm32f722 stm32f723 stm32f730 + stm32f730-lpc stm32f732 stm32f733 stm32f745 @@ -31,7 +32,7 @@ pub use stm32f7::stm32f7x2 as pac; #[cfg(feature = "stm32f723")] pub use stm32f7::stm32f7x3 as pac; -#[cfg(feature = "stm32f730")] +#[cfg(any(feature = "stm32f730", feature = "stm32f730-lpc"))] pub use stm32f7::stm32f730 as pac; #[cfg(feature = "stm32f732")] @@ -95,6 +96,7 @@ pub mod dac; feature = "stm32f722", feature = "stm32f723", feature = "stm32f730", + feature = "stm32f730-lpc", feature = "stm32f732", feature = "stm32f733", feature = "stm32f746", @@ -109,6 +111,7 @@ pub mod otg_fs; feature = "stm32f722", feature = "stm32f723", feature = "stm32f730", + feature = "stm32f730-lpc", feature = "stm32f732", feature = "stm32f733", feature = "stm32f746", diff --git a/src/serial.rs b/src/serial.rs index 991c6ba..4724d9f 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -17,7 +17,7 @@ use crate::rcc::{BusClock, Enable, Reset}; use crate::state; use nb::block; -use crate::pac::{RCC, UART4, UART5, UART7, USART1, USART2, USART3, USART6}; +use crate::pac::{RCC, UART4, UART5, UART7, UART8, USART1, USART2, USART3, USART6}; use crate::gpio::{self, Alternate}; @@ -38,14 +38,14 @@ pub enum Error { Parity, } -pub trait Pins {} -pub trait PinTx {} -pub trait PinRx {} +pub trait Pins {} +pub trait PinTx {} +pub trait PinRx {} -impl Pins for (TX, RX) +impl Pins for (TX, RX) where - TX: PinTx, - RX: PinRx, + TX: PinTx, + RX: PinRx, { } @@ -84,63 +84,85 @@ mod f7xx_pins { impl PinRx for gpio::PB3> {} } +// USART1 impl PinTx for gpio::PA9> {} impl PinTx for gpio::PB6> {} + +impl PinRx for gpio::PA10> {} +impl PinRx for gpio::PB7> {} + +// USART2 impl PinTx for gpio::PA2> {} impl PinTx for gpio::PD5> {} + +impl PinRx for gpio::PA3> {} +impl PinRx for gpio::PD6> {} + +// USART3 impl PinTx for gpio::PB10> {} impl PinTx for gpio::PC10> {} impl PinTx for gpio::PD8> {} -impl PinTx for gpio::PA0> {} -impl PinTx for gpio::PC10> {} -impl PinTx for gpio::PC12> {} -impl PinTx for gpio::PC6> {} -impl PinTx for gpio::PG14> {} -impl PinTx for gpio::PE8> {} -impl PinTx for gpio::PF7> {} -impl PinRx for gpio::PA10> {} -impl PinRx for gpio::PB7> {} -impl PinRx for gpio::PA3> {} -impl PinRx for gpio::PD6> {} impl PinRx for gpio::PB11> {} impl PinRx for gpio::PC11> {} impl PinRx for gpio::PD9> {} + +// USART6 +impl PinTx for gpio::PC6> {} +impl PinTx for gpio::PG14> {} + +impl PinRx for gpio::PC7> {} +impl PinRx for gpio::PG9> {} + +// UART4 +impl PinTx for gpio::PA0> {} +impl PinTx for gpio::PC10> {} + impl PinRx for gpio::PA1> {} impl PinRx for gpio::PC11> {} + +// UART5 +impl PinTx for gpio::PC12> {} impl PinRx for gpio::PD2> {} -impl PinRx for gpio::PC7> {} -impl PinRx for gpio::PG9> {} + +// UART7 +impl PinTx for gpio::PE8> {} +impl PinTx for gpio::PF7> {} + impl PinRx for gpio::PE7> {} impl PinRx for gpio::PF6> {} +// UART8 +impl PinTx for gpio::PE1> {} +impl PinRx for gpio::PE0> {} + /// Serial abstraction -pub struct Serial { - usart: USART, +pub struct Serial { + usart: U, pins: PINS, } -impl Serial +impl Serial where - PINS: Pins, - USART: Instance, + PINS: Pins, + U: Instance, { - pub fn new(usart: USART, pins: PINS, clocks: &Clocks, config: Config) -> Self { + pub fn new(usart: U, pins: PINS, clocks: &Clocks, config: Config) -> Self { // NOTE(unsafe) This executes only during initialisation let rcc = unsafe { &(*RCC::ptr()) }; // TODO: The unsafe calls below should be replaced with accessing // the correct registers directly. - USART::select_sysclock(rcc, config.sysclock); + U::select_sysclock(rcc, config.sysclock); unsafe { - USART::enable_unchecked(); + U::enable_unchecked(); } let clk = if config.sysclock { clocks.sysclk() } else { - USART::clock(clocks) + U::clock(clocks) }; // Calculate correct baudrate divisor on the fly @@ -191,14 +213,11 @@ where match config.parity { Parity::ParityEven => w.ps().even().pce().enabled(), - Parity::ParityOdd => w.ps().odd().pce().enabled(), + Parity::ParityOdd => w.ps().odd().pce().enabled(), Parity::ParityNone => w.pce().disabled(), }; - w - .te().enabled() - .re().enabled() - .ue().enabled() + w.te().enabled().re().enabled().ue().enabled(); }); // Enable DMA @@ -227,7 +246,7 @@ where } } - pub fn split(self) -> (Tx, Rx) { + pub fn split(self) -> (Tx, Rx) { ( Tx { _usart: PhantomData, @@ -238,40 +257,40 @@ where ) } - pub fn release(self) -> (USART, PINS) { + pub fn release(self) -> (U, PINS) { (self.usart, self.pins) } } -impl serial::Read for Serial +impl serial::Read for Serial where - USART: Instance, + U: Instance, { type Error = Error; fn read(&mut self) -> nb::Result { - let mut rx: Rx = Rx { + let mut rx: Rx = Rx { _usart: PhantomData, }; rx.read() } } -impl serial::Write for Serial +impl serial::Write for Serial where - USART: Instance, + U: Instance, { type Error = Error; fn flush(&mut self) -> nb::Result<(), Self::Error> { - let mut tx: Tx = Tx { + let mut tx: Tx = Tx { _usart: PhantomData, }; tx.flush() } fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> { - let mut tx: Tx = Tx { + let mut tx: Tx = Tx { _usart: PhantomData, }; tx.write(byte) @@ -279,13 +298,13 @@ where } /// Serial receiver -pub struct Rx { - _usart: PhantomData, +pub struct Rx { + _usart: PhantomData, } -impl Rx +impl Rx where - USART: Instance, + U: Instance, Self: dma::Target, { /// Reads data using DMA until `buffer` is full @@ -304,7 +323,7 @@ where { // This is safe, as we're only using the USART instance to access the // address of one register. - let address = &unsafe { &*USART::ptr() }.rdr as *const _ as _; + let address = &unsafe { &*U::ptr() }.rdr as *const _ as _; // Safe, because the trait bounds on this method guarantee that `buffer` // can be written to safely. @@ -321,18 +340,18 @@ where } } -impl serial::Read for Rx +impl serial::Read for Rx where - USART: Instance, + U: Instance, { type Error = Error; fn read(&mut self) -> nb::Result { // NOTE(unsafe) atomic read with no side effects - let isr = unsafe { (*USART::ptr()).isr.read() }; + let isr = unsafe { (*U::ptr()).isr.read() }; // NOTE(unsafe): Only used for atomic writes, to clear error flags. - let icr = unsafe { &(*USART::ptr()).icr }; + let icr = unsafe { &(*U::ptr()).icr }; if isr.pe().bit_is_set() { icr.write(|w| w.pecf().clear()); @@ -356,7 +375,7 @@ where return Ok(unsafe { // Casting to `u8` should be fine, as we've configured the USART // to use 8 data bits. - (*USART::ptr()).rdr.read().rdr().bits() as u8 + (*U::ptr()).rdr.read().rdr().bits() as u8 }); } @@ -365,14 +384,14 @@ where } /// Serial transmitter -pub struct Tx { - _usart: PhantomData, +pub struct Tx { + _usart: PhantomData, } -impl Tx +impl Tx where Self: dma::Target, - USART: Instance, + U: Instance, { /// Writes data using DMA /// @@ -392,7 +411,7 @@ where // STM32F74xxx, section 31.5.15. // // This is safe, as we're doing just one atomic write. - let usart = unsafe { &*USART::ptr() }; + let usart = unsafe { &*U::ptr() }; usart.icr.write(|w| w.tccf().clear()); // Safe, because the trait bounds on this method guarantee that `buffer` @@ -410,15 +429,15 @@ where } } -impl serial::Write for Tx +impl serial::Write for Tx where - USART: Instance, + U: Instance, { type Error = Error; fn flush(&mut self) -> nb::Result<(), Self::Error> { // NOTE(unsafe) atomic read with no side effects - let isr = unsafe { (*USART::ptr()).isr.read() }; + let isr = unsafe { (*U::ptr()).isr.read() }; if isr.tc().bit_is_set() { Ok(()) @@ -429,12 +448,12 @@ where fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> { // NOTE(unsafe) atomic read with no side effects - let isr = unsafe { (*USART::ptr()).isr.read() }; + let isr = unsafe { (*U::ptr()).isr.read() }; if isr.txe().bit_is_set() { // NOTE(unsafe) atomic write to stateless register // NOTE(write_volatile) 8-bit write that's not possible through the svd2rust API - unsafe { ptr::write_volatile(&(*USART::ptr()).tdr as *const _ as *mut _, byte) } + unsafe { ptr::write_volatile(core::ptr::addr_of!((*U::ptr()).tdr) as *mut u8, byte) } Ok(()) } else { Err(nb::Error::WouldBlock) @@ -527,12 +546,12 @@ pub trait Instance: Deref + Enable + Reset macro_rules! impl_instance { ($( - $USARTX:ident: ($usartXsel:ident), + $UARTX:ident: ($usartXsel:ident), )+) => { $( - impl Instance for $USARTX { + impl Instance for $UARTX { fn ptr() -> *const pac::usart1::RegisterBlock { - $USARTX::ptr() + $UARTX::ptr() } fn select_sysclock(rcc: &pac::rcc::RegisterBlock, sys: bool) { @@ -554,9 +573,9 @@ impl_instance! { UART7: (uart7sel), } -impl fmt::Write for Tx +impl fmt::Write for Tx where - Tx: serial::Write, + Tx: serial::Write, { fn write_str(&mut self, s: &str) -> fmt::Result { let _ = s.as_bytes().iter().map(|c| block!(self.write(*c))).last(); diff --git a/src/spi.rs b/src/spi.rs index 13c4018..d75036d 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -386,9 +386,7 @@ macro_rules! impl_instance { // to access it. This is safe, as `&self.dr` is a // memory-mapped register. let value = unsafe { - ptr::read_volatile( - &self.dr as *const _ as *const _, - ) + ptr::read_volatile(self.dr_address() as *mut _) }; return Ok(value); @@ -424,7 +422,7 @@ macro_rules! impl_instance { // memory-mapped register. unsafe { ptr::write_volatile( - &self.dr as *const _ as *mut _, + self.dr_address() as *mut _, word, ); } @@ -436,7 +434,7 @@ macro_rules! impl_instance { } fn dr_address(&self) -> u32 { - &self.dr as *const _ as _ + core::ptr::addr_of!(self.dr) as u32 } }