diff --git a/Cargo.toml b/Cargo.toml index 0374ed9a..e26a8d26 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,8 @@ embedded-hal = { version = "0.2.6", features = ["unproven"] } embedded-dma = "0.2.0" cortex-m = { version = "^0.7.7", features = ["critical-section-single-core"] } defmt = { version = ">=0.2.0,<0.4", optional = true } -stm32h7 = { version = "0.16.0", package = "stm32h7-staging", features = ["critical-section"], default-features = false } +stm32h7 = { git = "https://github.com/stm32-rs/stm32-rs-nightlies", features = ["critical-section"], default-features = false } +#stm32h7 = { version = "0.17.0", package = "stm32h7-staging", features = ["critical-section"], default-features = false } void = { version = "1.0.2", default-features = false } cast = { version = "0.3.0", default-features = false } nb = "1.0.0" diff --git a/src/adc.rs b/src/adc.rs index e75861e5..580ddab0 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -734,10 +734,10 @@ macro_rules! adc_hal { /// Enable ADC pub fn enable(mut self) -> Adc<$ADC, Enabled> { // Refer to RM0433 Rev 7 - Chapter 25.4.9 - self.rb.isr().modify(|_, w| w.adrdy().set_bit()); - self.rb.cr().modify(|_, w| w.aden().set_bit()); + self.rb.isr().modify(|_, w| w.adrdy().clear()); + self.rb.cr().modify(|_, w| w.aden().enabled()); while self.rb.isr().read().adrdy().bit_is_clear() {} - self.rb.isr().modify(|_, w| w.adrdy().set_bit()); + self.rb.isr().modify(|_, w| w.adrdy().clear()); self.configure(); diff --git a/src/dma/bdma.rs b/src/dma/bdma.rs index a0e40df3..2aeaf4a4 100644 --- a/src/dma/bdma.rs +++ b/src/dma/bdma.rs @@ -587,161 +587,84 @@ where } } -// Macro that creates a struct representing a stream on either BDMA controller +// A struct representing a stream on either BDMA controller // // The implementation does the heavy lifting of mapping to the right fields on // the stream -macro_rules! bdma_stream { - ($(($name:ident, $number:expr, - $ifcr:ident, $tcif:ident, $htif:ident, $teif:ident, $gif:ident, - $isr:ident, $tcisr:ident, $htisr:ident, $teisr:ident, $gisr:ident) - ),+$(,)*) => { - $( - impl InstanceStream for StreamX { - #[inline(always)] - fn stream_clear_interrupts(&mut self) { - //NOTE(unsafe) Atomic write with no side-effects and we only access the bits - // that belongs to the StreamX - let dma = unsafe { &*I::ptr() }; - dma.$ifcr().write(|w| w - .$tcif().set_bit() //Clear transfer complete interrupt flag - .$htif().set_bit() //Clear half transfer interrupt flag - .$teif().set_bit() //Clear transfer error interrupt flag - .$gif().set_bit() //Clear global interrupt flag - ); - let _ = dma.$isr().read(); - let _ = dma.$isr().read(); // Delay 2 peripheral clocks - } +impl InstanceStream for StreamX { + #[inline(always)] + fn stream_clear_interrupts(&mut self) { + //NOTE(unsafe) Atomic write with no side-effects and we only access the bits + // that belongs to the StreamX + let dma = unsafe { &*I::ptr() }; + dma.ifcr().write( + |w| { + w.ctcif(S) + .set_bit() //Clear transfer complete interrupt flag + .chtif(S) + .set_bit() //Clear half transfer interrupt flag + .cteif(S) + .set_bit() //Clear transfer error interrupt flag + .cgif(S) + .set_bit() + }, //Clear global interrupt flag + ); + let _ = dma.isr().read(); + let _ = dma.isr().read(); // Delay 2 peripheral clocks + } - #[inline(always)] - fn stream_clear_transfer_complete_flag(&mut self) { - //NOTE(unsafe) Atomic write with no side-effects and we only access the bits - // that belongs to the StreamX - let dma = unsafe { &*I::ptr() }; - dma.$ifcr().write(|w| w.$tcif().set_bit()); - } + #[inline(always)] + fn stream_clear_transfer_complete_flag(&mut self) { + //NOTE(unsafe) Atomic write with no side-effects and we only access the bits + // that belongs to the StreamX + let dma = unsafe { &*I::ptr() }; + dma.ifcr().write(|w| w.ctcif(S).set_bit()); + } - #[inline(always)] - fn stream_clear_transfer_complete_interrupt(&mut self) { - self.stream_clear_transfer_complete_flag(); - //NOTE(unsafe) Atomic read with no side-effects. - let dma = unsafe { &*I::ptr() }; - let _ = dma.$isr().read(); - let _ = dma.$isr().read(); // Delay 2 peripheral clocks - } + #[inline(always)] + fn stream_clear_transfer_complete_interrupt(&mut self) { + self.stream_clear_transfer_complete_flag(); + //NOTE(unsafe) Atomic read with no side-effects. + let dma = unsafe { &*I::ptr() }; + let _ = dma.isr().read(); + let _ = dma.isr().read(); // Delay 2 peripheral clocks + } - #[inline(always)] - fn stream_clear_transfer_error_interrupt(&mut self) { - //NOTE(unsafe) Atomic write with no side-effects and we only access the bits - // that belongs to the StreamX - let dma = unsafe { &*I::ptr() }; - dma.$ifcr().write(|w| w.$teif().set_bit()); - let _ = dma.$isr().read(); - let _ = dma.$isr().read(); // Delay 2 peripheral clocks - } + #[inline(always)] + fn stream_clear_transfer_error_interrupt(&mut self) { + //NOTE(unsafe) Atomic write with no side-effects and we only access the bits + // that belongs to the StreamX + let dma = unsafe { &*I::ptr() }; + dma.ifcr().write(|w| w.cteif(S).set_bit()); + let _ = dma.isr().read(); + let _ = dma.isr().read(); // Delay 2 peripheral clocks + } - #[inline(always)] - fn stream_get_transfer_complete_flag() -> bool { - //NOTE(unsafe) Atomic read with no side effects - let dma = unsafe { &*I::ptr() }; - dma.$isr().read().$tcisr().bit_is_set() - } + #[inline(always)] + fn stream_get_transfer_complete_flag() -> bool { + //NOTE(unsafe) Atomic read with no side effects + let dma = unsafe { &*I::ptr() }; + dma.isr().read().tcif(S).bit_is_set() + } - #[inline(always)] - fn stream_get_half_transfer_flag() -> bool { - //NOTE(unsafe) Atomic read with no side effects - let dma = unsafe { &*I::ptr() }; - dma.$isr().read().$htisr().bit_is_set() - } + #[inline(always)] + fn stream_get_half_transfer_flag() -> bool { + //NOTE(unsafe) Atomic read with no side effects + let dma = unsafe { &*I::ptr() }; + dma.isr().read().htif(S).bit_is_set() + } - #[inline(always)] - fn stream_clear_half_transfer_interrupt(&mut self) { - //NOTE(unsafe) Atomic write with no side-effects and we only access the bits - // that belongs to the StreamX - let dma = unsafe { &*I::ptr() }; - dma.$ifcr().write(|w| w.$htif().set_bit()); - let _ = dma.$isr().read(); - let _ = dma.$isr().read(); // Delay 2 peripheral clocks - } - } - )+ - }; + #[inline(always)] + fn stream_clear_half_transfer_interrupt(&mut self) { + //NOTE(unsafe) Atomic write with no side-effects and we only access the bits + // that belongs to the StreamX + let dma = unsafe { &*I::ptr() }; + dma.ifcr().write(|w| w.chtif(S).set_bit()); + let _ = dma.isr().read(); + let _ = dma.isr().read(); // Delay 2 peripheral clocks + } } -#[cfg(not(feature = "rm0468"))] -bdma_stream!( - // Note: the field names start from one, unlike the RM where they start from - // zero. May need updating if it gets fixed upstream. - ( - Stream0, 0, ifcr, ctcif1, chtif1, cteif1, cgif1, isr, tcif1, htif1, - teif1, gif1 - ), - ( - Stream1, 1, ifcr, ctcif2, chtif2, cteif2, cgif2, isr, tcif2, htif2, - teif2, gif2 - ), - ( - Stream2, 2, ifcr, ctcif3, chtif3, cteif3, cgif3, isr, tcif3, htif3, - teif3, gif3 - ), - ( - Stream3, 3, ifcr, ctcif4, chtif4, cteif4, cgif4, isr, tcif4, htif4, - teif4, gif4 - ), - ( - Stream4, 4, ifcr, ctcif5, chtif5, cteif5, cgif5, isr, tcif5, htif5, - teif5, gif5 - ), - ( - Stream5, 5, ifcr, ctcif6, chtif6, cteif6, cgif6, isr, tcif6, htif6, - teif6, gif6 - ), - ( - Stream6, 6, ifcr, ctcif7, chtif7, cteif7, cgif7, isr, tcif7, htif7, - teif7, gif7 - ), - ( - Stream7, 7, ifcr, ctcif8, chtif8, cteif8, cgif8, isr, tcif8, htif8, - teif8, gif8 - ), -); -#[cfg(feature = "rm0468")] -bdma_stream!( - // For this sub-familiy, the field names do match the RM. - ( - Stream0, 0, ifcr, ctcif0, chtif0, cteif0, cgif0, isr, tcif0, htif0, - teif0, gif0 - ), - ( - Stream1, 1, ifcr, ctcif1, chtif1, cteif1, cgif1, isr, tcif1, htif1, - teif1, gif1 - ), - ( - Stream2, 2, ifcr, ctcif2, chtif2, cteif2, cgif2, isr, tcif2, htif2, - teif2, gif2 - ), - ( - Stream3, 3, ifcr, ctcif3, chtif3, cteif3, cgif3, isr, tcif3, htif3, - teif3, gif3 - ), - ( - Stream4, 4, ifcr, ctcif4, chtif4, cteif4, cgif4, isr, tcif4, htif4, - teif4, gif4 - ), - ( - Stream5, 5, ifcr, ctcif5, chtif5, cteif5, cgif5, isr, tcif5, htif5, - teif5, gif5 - ), - ( - Stream6, 6, ifcr, ctcif6, chtif6, cteif6, cgif6, isr, tcif6, htif6, - teif6, gif6 - ), - ( - Stream7, 7, ifcr, ctcif7, chtif7, cteif7, cgif7, isr, tcif7, htif7, - teif7, gif7 - ), -); - /// Type alias for the DMA Request Multiplexer /// pub type DMAReq = pac::dmamux2::ccr::DMAREQ_ID; diff --git a/src/flash/mod.rs b/src/flash/mod.rs index 78880a78..832e47f8 100644 --- a/src/flash/mod.rs +++ b/src/flash/mod.rs @@ -277,8 +277,10 @@ const UNLOCK_KEY2: u32 = 0xCDEF_89AB; #[allow(unused_unsafe)] fn unlock(bank: &BANK) { - bank.keyr().write(|w| unsafe { w.keyr().bits(UNLOCK_KEY1) }); - bank.keyr().write(|w| unsafe { w.keyr().bits(UNLOCK_KEY2) }); + bank.keyr() + .write(|w| unsafe { w.key1r().bits(UNLOCK_KEY1) }); + bank.keyr() + .write(|w| unsafe { w.key1r().bits(UNLOCK_KEY2) }); assert!(!bank.cr().read().lock().bit()) } diff --git a/src/flash/operations.rs b/src/flash/operations.rs index 3e440215..5a5a2052 100644 --- a/src/flash/operations.rs +++ b/src/flash/operations.rs @@ -53,6 +53,12 @@ impl NorFlashError for Error { impl Error { fn read(flash_bank: &BANK) -> Option { let sr = flash_bank.sr().read(); + + #[cfg(not(feature = "rm0455"))] + if sr.operr().bit() { + return Some(Error::Operation); + } + if sr.pgserr().bit() { Some(Error::ProgrammingSequence) } else if sr.wrperr().bit() { @@ -61,8 +67,6 @@ impl Error { Some(Error::Strobe) } else if sr.incerr().bit() { Some(Error::Inconsistency) - } else if sr.operr().bit() { - Some(Error::Operation) } else if sr.rdperr().bit() { Some(Error::ReadProtection) } else if sr.rdserr().bit() { @@ -75,22 +79,25 @@ impl Error { } } fn clear_error_flags(regs: &BANK) { - regs.sr().modify(|_, w| { - w.pgserr() - .set_bit() - .wrperr() + regs.ccr().write(|w| { + let w = w + .clr_pgserr() .set_bit() - .strberr() + .clr_wrperr() .set_bit() - .incerr() + .clr_strberr() .set_bit() - .operr() - .set_bit() - .rdperr() + .clr_incerr(); + + #[cfg(not(feature = "rm0455"))] + let w = w.set_bit().clr_operr(); + + w.set_bit() + .clr_rdperr() .set_bit() - .rdserr() + .clr_rdserr() .set_bit() - .dbeccerr() + .clr_dbeccerr() .set_bit() }); } @@ -167,15 +174,19 @@ impl UnlockedFlashBank<'_> { #[rustfmt::skip] self.bank.cr().modify(|_, w| unsafe { - w - // start - .start().set_bit() - // sector number - .snb().bits(sector) - // sector erase - .ser().set_bit() + // sector number + #[cfg(feature = "rm0455")] + let w = w.ssn().bits(sector); + + #[cfg(not(feature = "rm0455"))] + let w = w.snb().bits(sector); + + // sector erase + w.ser().set_bit() // not programming .pg().clear_bit() + // start + .start().set_bit() }); self.wait_ready(); self.ok() @@ -214,11 +225,13 @@ impl UnlockedFlashBank<'_> { #[rustfmt::skip] #[allow(unused_unsafe)] self.bank.cr().modify(|_, w| unsafe { - w + #[cfg(not(feature = "rm0455"))] + let w = w // double-word parallelism - .psize().bits(0b11) - // not sector erase - .ser().clear_bit() + .psize().bits(0b11); + + // not sector erase + w.ser().clear_bit() // programming .pg().set_bit() }); diff --git a/src/i2c.rs b/src/i2c.rs index bdced3bf..87c6a391 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -130,14 +130,13 @@ macro_rules! busy_wait { if isr.$flag().$variant() { break; } else if isr.berr().is_error() { - $i2c.icr().write(|w| w.berrcf().set_bit()); + $i2c.icr().write(|w| w.berrcf().clear()); return Err(Error::Bus); } else if isr.arlo().is_lost() { - $i2c.icr().write(|w| w.arlocf().set_bit()); + $i2c.icr().write(|w| w.arlocf().clear()); return Err(Error::Arbitration); } else if isr.nackf().bit_is_set() { - $i2c.icr() - .write(|w| w.stopcf().set_bit().nackcf().set_bit()); + $i2c.icr().write(|w| w.stopcf().clear().nackcf().clear()); flush_txdr!($i2c); return Err(Error::NotAcknowledge); } else { @@ -375,12 +374,12 @@ macro_rules! i2c { pub fn clear_irq(&mut self, event: Event) { self.i2c.icr().write(|w| { match event { - Event::Stop => w.stopcf().set_bit(), + Event::Stop => w.stopcf().clear(), Event::Errors => w - .berrcf().set_bit() - .arlocf().set_bit() - .ovrcf().set_bit(), - Event::NotAcknowledge => w.nackcf().set_bit(), + .berrcf().clear() + .arlocf().clear() + .ovrcf().clear(), + Event::NotAcknowledge => w.nackcf().clear(), _ => w } }); diff --git a/src/rcc/backup.rs b/src/rcc/backup.rs index 2b6c4ec1..73378751 100644 --- a/src/rcc/backup.rs +++ b/src/rcc/backup.rs @@ -110,6 +110,15 @@ mod rtc { }); self } + + /// # Safety + /// Caller has to ensure there are no other instances of this type + #[inline(always)] + unsafe fn new() -> Self { + Rtc { + _marker: PhantomData, + } + } } /// RTC kernel clock source selection diff --git a/src/rcc/rec.rs b/src/rcc/rec.rs index 9de147de..381e0a99 100644 --- a/src/rcc/rec.rs +++ b/src/rcc/rec.rs @@ -87,6 +87,10 @@ pub trait ResetEnable { /// Reset this peripheral #[allow(clippy::return_self_not_must_use)] fn reset(self) -> Self; + + /// # Safety + /// Caller has to ensure there are no other instances of this type + unsafe fn new() -> Self; } /// The clock gating state of a peripheral in low-power mode @@ -341,6 +345,11 @@ macro_rules! peripheral_reset_and_enable_control_generator { }); self } + /// # Safety + /// Caller has to ensure there are no other instances of this type + unsafe fn new() -> Self { + Self { _marker: PhantomData } + } } $( #[ $pmeta ] )* impl $p { diff --git a/src/rtc.rs b/src/rtc.rs index 70ca8d39..83ae8452 100644 --- a/src/rtc.rs +++ b/src/rtc.rs @@ -197,8 +197,17 @@ impl Rtc { rtc.wpr().write(|w| unsafe { w.bits(0x53) }); // Enter initialization mode - rtc.isr().modify(|_, w| w.init().set_bit()); - while rtc.isr().read().initf().bit_is_clear() {} + #[cfg(feature = "rm0455")] + { + rtc.icsr().modify(|_, w| w.init().init_mode()); + while rtc.icsr().read().initf().is_not_allowed() {} + } + + #[cfg(not(feature = "rm0455"))] + { + rtc.isr().modify(|_, w| w.init().init_mode()); + while rtc.isr().read().initf().is_not_allowed() {} + } // Enable Shadow Register Bypass rtc.cr().modify(|_, w| w.bypshad().set_bit()); @@ -238,6 +247,10 @@ impl Rtc { }); // Exit initialization mode + #[cfg(feature = "rm0455")] + rtc.icsr().modify(|_, w| w.init().free_running_mode()); + + #[cfg(not(feature = "rm0455"))] rtc.isr().modify(|_, w| w.init().clear_bit()); Rtc { reg: rtc, prec } @@ -248,6 +261,7 @@ impl Rtc { /// # Panics /// /// Panics if `reg` is greater than 31. + #[cfg(not(feature = "rm0455"))] // TODO: How should this be done? pub fn read_backup_reg(&self, reg: u8) -> u32 { self.reg.bkpr(reg as usize).read().bkp().bits() } @@ -257,6 +271,7 @@ impl Rtc { /// # Panics /// /// Panics if `reg` is greater than 31. + #[cfg(not(feature = "rm0455"))] // TODO: How should this be done? pub fn write_backup_reg(&mut self, reg: u8, value: u32) { self.reg.bkpr(reg as usize).write(|w| w.bkp().set(value)); } @@ -269,8 +284,8 @@ impl Rtc { /// when debug assertions are enabled. pub fn set_date_time(&mut self, date_time: NaiveDateTime) { // Enter initialization mode - self.reg.isr().modify(|_, w| w.init().set_bit()); - while self.reg.isr().read().initf().bit_is_clear() {} + + self.enter_init_mode(); let hour = date_time.hour() as u8; let ht = hour / 10; @@ -334,7 +349,7 @@ impl Rtc { }); // Exit initialization mode - self.reg.isr().modify(|_, w| w.init().clear_bit()); + self.exit_init_mode(); } /// De-initializes the calendar and clock @@ -342,19 +357,23 @@ impl Rtc { /// For when you lose confidince in the stored time e.g. if the LSE clock fails. pub fn clear_date_time(&mut self) { // Enter initialization mode - self.reg.isr().modify(|_, w| w.init().set_bit()); - while self.reg.isr().read().initf().bit_is_clear() {} + self.enter_init_mode(); self.reg.tr().reset(); self.reg.dr().reset(); // Exit initialization mode - self.reg.isr().modify(|_, w| w.init().clear_bit()); + self.exit_init_mode(); } /// Returns `None` if the calendar is uninitialized fn calendar_initialized(&self) -> Option<()> { - match self.reg.isr().read().inits().bit() { + #[cfg(feature = "rm0455")] + let is_initalized = self.reg.icsr().read().inits().is_initalized(); + + #[cfg(not(feature = "rm0455"))] + let is_initalized = self.reg.isr().read().inits().is_initalized(); + match is_initalized { true => Some(()), false => None, } @@ -563,8 +582,14 @@ impl Rtc { /// Panics if interval is greater than 2¹⁷-1. pub fn enable_wakeup(&mut self, interval: u32) { self.reg.cr().modify(|_, w| w.wute().clear_bit()); - self.reg.isr().modify(|_, w| w.wutf().clear_bit()); - while self.reg.isr().read().wutwf().bit_is_clear() {} + + #[cfg(feature = "rm0455")] + self.reg.scr().write(|w| w.cwutf().clear()); + + #[cfg(not(feature = "rm0455"))] + self.reg.isr().modify(|_, w| w.wutf().clear()); + + while !self.sr().read().wutf().is_zero() {} if interval > 1 << 16 { self.reg @@ -590,13 +615,23 @@ impl Rtc { /// Disables the wakeup timer pub fn disable_wakeup(&mut self) { self.reg.cr().modify(|_, w| w.wute().clear_bit()); - self.reg.isr().modify(|_, w| w.wutf().clear_bit()); + #[cfg(feature = "rm0455")] + self.reg.scr().write(|w| w.cwutf().clear()); + + #[cfg(not(feature = "rm0455"))] + self.reg.isr().modify(|_, w| w.wutf().clear()); } /// Configures the timestamp to be captured when the RTC switches to Vbat power pub fn enable_vbat_timestamp(&mut self) { self.reg.cr().modify(|_, w| w.tse().clear_bit()); - self.reg.isr().modify(|_, w| w.tsf().clear_bit()); + + #[cfg(feature = "rm0455")] + self.reg.scr().write(|w| w.ctsf().clear()); + + #[cfg(not(feature = "rm0455"))] + self.reg.isr().modify(|_, w| w.tsf().clear()); + self.reg.cr().modify(|_, w| w.itse().set_bit()); self.reg.cr().modify(|_, w| w.tse().set_bit()); } @@ -604,14 +639,19 @@ impl Rtc { /// Disables the timestamp pub fn disable_timestamp(&mut self) { self.reg.cr().modify(|_, w| w.tse().clear_bit()); - self.reg.isr().modify(|_, w| w.tsf().clear_bit()); + + #[cfg(feature = "rm0455")] + self.reg.scr().write(|w| w.ctsf().clear()); + + #[cfg(not(feature = "rm0455"))] + self.reg.isr().modify(|_, w| w.tsf().clear()); } /// Reads the stored value of the timestamp if present /// /// Clears the timestamp interrupt flags. pub fn read_timestamp(&self) -> Option { - if !self.reg.isr().read().tsf().bit_is_clear() { + if self.sr().read().tsf().is_timestamp_event() { return None; } @@ -641,9 +681,11 @@ impl Rtc { // Clear timestamp interrupt and internal timestamp interrupt (VBat transition) // TODO: Timestamp overflow flag - self.reg - .isr() - .modify(|_, w| w.tsf().clear_bit().itsf().clear_bit()); + #[cfg(feature = "rm0455")] + self.reg.scr().write(|w| w.ctsf().clear().citsf().clear()); + + #[cfg(not(feature = "rm0455"))] + self.reg.isr().modify(|_, w| w.tsf().clear().itsf().clear()); Some(date.and_time(time)) } @@ -733,12 +775,18 @@ impl Rtc { // unsafe: Only we can do anything with this bit let rcc = unsafe { &*RCC::ptr() }; + #[cfg(feature = "rm0455")] + let sr = self.reg.sr(); + + #[cfg(not(feature = "rm0455"))] + let sr = self.reg.isr(); + match event { Event::LseCss => rcc.cifr().read().lsecssf().bit_is_set(), - Event::AlarmA => self.reg.isr().read().alraf().bit_is_set(), - Event::AlarmB => self.reg.isr().read().alrbf().bit_is_set(), - Event::Wakeup => self.reg.isr().read().wutf().bit_is_set(), - Event::Timestamp => self.reg.isr().read().tsf().bit_is_set(), + Event::AlarmA => sr.read().alraf().bit_is_set(), + Event::AlarmB => sr.read().alrbf().bit_is_set(), + Event::Wakeup => sr.read().wutf().bit_is_set(), + Event::Timestamp => sr.read().tsf().bit_is_set(), } } @@ -748,25 +796,50 @@ impl Rtc { // unsafe: Only we can do anything with these bits let rcc = unsafe { &*RCC::ptr() }; + #[cfg(feature = "rm0455")] + match event { + Event::LseCss => { + rcc.cicr().write(|w| w.lsecssc().clear()); + exti.unpend(ExtiEvent::RTC_OTHER); + } + Event::AlarmA => { + self.reg.scr().write(|w| w.calraf().clear()); + exti.unpend(ExtiEvent::RTC_ALARM); + } + Event::AlarmB => { + self.reg.scr().write(|w| w.calrbf().clear()); + exti.unpend(ExtiEvent::RTC_ALARM); + } + Event::Wakeup => { + self.reg.scr().write(|w| w.cwutf().clear()); + exti.unpend(ExtiEvent::RTC_WAKEUP); + } + Event::Timestamp => { + self.reg.scr().write(|w| w.ctsf().clear()); + exti.unpend(ExtiEvent::RTC_OTHER); + } + } + + #[cfg(not(feature = "rm0455"))] match event { Event::LseCss => { rcc.cicr().write(|w| w.lsecssc().clear()); exti.unpend(ExtiEvent::RTC_OTHER); } Event::AlarmA => { - self.reg.isr().modify(|_, w| w.alraf().clear_bit()); + self.reg.isr().modify(|_, w| w.alraf().clear()); exti.unpend(ExtiEvent::RTC_ALARM); } Event::AlarmB => { - self.reg.isr().modify(|_, w| w.alrbf().clear_bit()); + self.reg.isr().modify(|_, w| w.alrbf().clear()); exti.unpend(ExtiEvent::RTC_ALARM); } Event::Wakeup => { - self.reg.isr().modify(|_, w| w.wutf().clear_bit()); + self.reg.isr().modify(|_, w| w.wutf().clear()); exti.unpend(ExtiEvent::RTC_WAKEUP); } Event::Timestamp => { - self.reg.isr().modify(|_, w| w.tsf().clear_bit()); + self.reg.isr().modify(|_, w| w.tsf().clear()); exti.unpend(ExtiEvent::RTC_OTHER); } } @@ -799,4 +872,36 @@ impl Rtc { pub fn inner_mut(&mut self) -> &mut RTC { &mut self.reg } + + #[cfg(feature = "rm0455")] + fn sr(&self) -> &stm32h7::Reg { + self.reg.sr() + } + + #[cfg(not(feature = "rm0455"))] + fn sr(&self) -> &stm32h7::Reg { + self.reg.isr() + } + + fn enter_init_mode(&mut self) { + #[cfg(feature = "rm0455")] + { + self.reg.icsr().modify(|_, w| w.init().init_mode()); + while self.reg.icsr().read().initf().is_not_allowed() {} + } + + #[cfg(not(feature = "rm0455"))] + { + self.reg.isr().modify(|_, w| w.init().init_mode()); + while self.reg.isr().read().initf().is_not_allowed() {} + } + } + + fn exit_init_mode(&mut self) { + #[cfg(feature = "rm0455")] + self.reg.icsr().modify(|_, w| w.init().free_running_mode()); + + #[cfg(not(feature = "rm0455"))] + self.reg.isr().modify(|_, w| w.init().free_running_mode()); + } } diff --git a/src/sai/mod.rs b/src/sai/mod.rs index 9dcb9940..1dedba5f 100644 --- a/src/sai/mod.rs +++ b/src/sai/mod.rs @@ -9,8 +9,6 @@ //! - [SAI with DMA](https://github.com/stm32-rs/stm32h7xx-hal/blob/master/examples/sai_dma_passthru.rs) //! - [SAI with I2S](https://github.com/stm32-rs/stm32h7xx-hal/blob/master/examples/sai-i2s-passthru.rs) -use core::marker::PhantomData; - #[cfg(any(feature = "rm0455", feature = "rm0468"))] use crate::stm32::sai1::CH; #[cfg(any(feature = "rm0433", feature = "rm0399"))] @@ -186,172 +184,181 @@ pub struct Sai { interface: INTERFACE, } -macro_rules! sai_hal { - ($($SAIX:ident: ($saiX:ident, $Rec:ident),)+) => { - $( - // Common to all interfaces - impl Sai<$SAIX, INTERFACE> { - /// Low level RCC initialisation - fn sai_rcc_init(&mut self, prec: rec::$Rec) - { - let _ = prec.enable().reset(); // drop, can be recreated by free method - } - - /// Access to the current master channel - fn master_channel(&self, func: F) -> T - where F: FnOnce(&CH) -> T, - { - func(&self.rb.ch(self.master_channel as usize)) - } +#[cfg(feature = "rm0455")] +#[allow(clippy::upper_case_acronyms)] +pub(crate) type SAI = + stm32h7::Periph; + +#[cfg(not(feature = "rm0455"))] +#[allow(clippy::upper_case_acronyms)] +pub(crate) type SAI = + stm32h7::Periph; + +// Common to all interfaces +impl Sai, INTERFACE> +where + SAI: GetClkSAI, +{ + /// Low level RCC initialisation + fn sai_rcc_init(&mut self, prec: as GetClkSAI>::Rec) { + let _ = prec.enable().reset(); // drop, can be recreated by free method + } - /// Access to the current slave channel, if set - fn slave_channel(&self, func: F) -> Option - where F: FnOnce(&CH) -> T, - { - match self.slave_channel { - Some(channel) => Some(func(&self.rb.ch(channel as usize))), - None => None - } - } + /// Access to the current master channel + fn master_channel(&self, func: F) -> T + where + F: FnOnce(&CH) -> T, + { + func(self.rb.ch(self.master_channel as usize)) + } - /// Start listening for `event` on a given `channel` - pub fn listen(&mut self, channel: SaiChannel, event: Event) { - let ch = &self.rb.ch(channel as usize); - match event { - Event::Overdue => ch.im().modify(|_, w| w.ovrudrie().set_bit()), - Event::Muted => ch.im().modify(|_, w| w.mutedetie().set_bit()), - Event::WrongClock => ch.im().modify(|_, w| w.wckcfgie().set_bit()), - Event::Data => ch.im().modify(|_, w| w.freqie().set_bit()), - Event::AnticipatedFrameSync => ch.im().modify(|_, w| w.afsdetie().set_bit()), - Event::LateFrameSync => ch.im().modify(|_, w| w.lfsdetie().set_bit()), - }; - } + /// Access to the current slave channel, if set + fn slave_channel(&self, func: F) -> Option + where + F: FnOnce(&CH) -> T, + { + self.slave_channel + .map(|channel| func(self.rb.ch(channel as usize))) + } - /// Stop listening for `event` on a given `channel` - pub fn unlisten(&mut self, channel: SaiChannel, event: Event) { - let ch = &self.rb.ch(channel as usize); - match event { - Event::Overdue => ch.im().modify(|_, w| w.ovrudrie().clear_bit()), - Event::Muted => ch.im().modify(|_, w| w.mutedetie().clear_bit()), - Event::WrongClock => ch.im().modify(|_, w| w.wckcfgie().clear_bit()), - Event::Data => ch.im().modify(|_, w| w.freqie().clear_bit()), - Event::AnticipatedFrameSync => ch.im().modify(|_, w| w.afsdetie().clear_bit()), - Event::LateFrameSync => ch.im().modify(|_, w| w.lfsdetie().clear_bit()), - }; - let _ = ch.im().read(); - let _ = ch.im().read(); // Delay 2 peripheral clocks - } + /// Start listening for `event` on a given `channel` + pub fn listen(&mut self, channel: SaiChannel, event: Event) { + let ch = &self.rb.ch(channel as usize); + match event { + Event::Overdue => ch.im().modify(|_, w| w.ovrudrie().set_bit()), + Event::Muted => ch.im().modify(|_, w| w.mutedetie().set_bit()), + Event::WrongClock => ch.im().modify(|_, w| w.wckcfgie().set_bit()), + Event::Data => ch.im().modify(|_, w| w.freqie().set_bit()), + Event::AnticipatedFrameSync => { + ch.im().modify(|_, w| w.afsdetie().set_bit()) + } + Event::LateFrameSync => { + ch.im().modify(|_, w| w.lfsdetie().set_bit()) + } + }; + } - /// Clears interrupt flag `event` on the `channel` - /// - /// Note: Event::Data is accepted but does nothing as that flag is cleared by reading/writing data - pub fn clear_irq(&mut self, channel: SaiChannel, event: Event) { - let ch = &self.rb.ch(channel as usize); - match event { - Event::Overdue => ch.clrfr().write(|w| w.covrudr().set_bit()), - Event::Muted => ch.clrfr().write(|w| w.cmutedet().set_bit()), - Event::WrongClock => ch.clrfr().write(|w| w.cwckcfg().set_bit()), - Event::Data => 0, // Cleared by reading/writing data - Event::AnticipatedFrameSync => ch.clrfr().write(|w| w.cafsdet().set_bit()), - Event::LateFrameSync => ch.clrfr().write(|w| w.clfsdet().set_bit()), - }; - let _ = ch.sr().read(); - let _ = ch.sr().read(); // Delay 2 peripheral clocks - } + /// Stop listening for `event` on a given `channel` + pub fn unlisten(&mut self, channel: SaiChannel, event: Event) { + let ch = &self.rb.ch(channel as usize); + match event { + Event::Overdue => ch.im().modify(|_, w| w.ovrudrie().clear_bit()), + Event::Muted => ch.im().modify(|_, w| w.mutedetie().clear_bit()), + Event::WrongClock => { + ch.im().modify(|_, w| w.wckcfgie().clear_bit()) + } + Event::Data => ch.im().modify(|_, w| w.freqie().clear_bit()), + Event::AnticipatedFrameSync => { + ch.im().modify(|_, w| w.afsdetie().clear_bit()) + } + Event::LateFrameSync => { + ch.im().modify(|_, w| w.lfsdetie().clear_bit()) + } + }; + let _ = ch.im().read(); + let _ = ch.im().read(); // Delay 2 peripheral clocks + } - /// Clears all interrupts on the `channel` - pub fn clear_all_irq(&mut self, channel: SaiChannel) { - let ch = &self.rb.ch(channel as usize); - unsafe { - ch.clrfr().write(|w| w.bits(CLEAR_ALL_FLAGS_BITS)); - } - let _ = ch.sr().read(); - let _ = ch.sr().read(); // Delay 2 peripheral clocks - } + /// Clears interrupt flag `event` on the `channel` + /// + /// Note: Event::Data is accepted but does nothing as that flag is cleared by reading/writing data + pub fn clear_irq(&mut self, channel: SaiChannel, event: Event) { + let ch = &self.rb.ch(channel as usize); + match event { + Event::Overdue => ch.clrfr().write(|w| w.covrudr().set_bit()), + Event::Muted => ch.clrfr().write(|w| w.cmutedet().set_bit()), + Event::WrongClock => ch.clrfr().write(|w| w.cwckcfg().set_bit()), + Event::Data => 0, // Cleared by reading/writing data + Event::AnticipatedFrameSync => { + ch.clrfr().write(|w| w.cafsdet().set_bit()) + } + Event::LateFrameSync => ch.clrfr().write(|w| w.clfsdet().set_bit()), + }; + let _ = ch.sr().read(); + let _ = ch.sr().read(); // Delay 2 peripheral clocks + } - /// Mute `channel`, this is checked at the start of each frame - /// Meaningful only in Tx mode - pub fn mute(&mut self, channel: SaiChannel) { - self.rb.ch(channel as usize).cr2().modify(|_, w| w.mute().enabled()); - } + /// Clears all interrupts on the `channel` + pub fn clear_all_irq(&mut self, channel: SaiChannel) { + let ch = &self.rb.ch(channel as usize); + unsafe { + ch.clrfr().write(|w| w.bits(CLEAR_ALL_FLAGS_BITS)); + } + let _ = ch.sr().read(); + let _ = ch.sr().read(); // Delay 2 peripheral clocks + } - /// Unmute `channel`, this is checked at the start of each frame - /// Meaningful only in Tx mode - pub fn unmute(&mut self, channel: SaiChannel) { - self.rb.ch(channel as usize).cr2().modify(|_, w| w.mute().disabled()); - } + /// Mute `channel`, this is checked at the start of each frame + /// Meaningful only in Tx mode + pub fn mute(&mut self, channel: SaiChannel) { + self.rb + .ch(channel as usize) + .cr2() + .modify(|_, w| w.mute().enabled()); + } - /// Used to operate the audio block(s) with an external SAI for synchronization - /// Refer to RM0433 rev 7 section 51.4.4 for valid values - /// - /// In short 0-3 maps SAI1-4 with the ones pointing to self being reserved. - /// e.g. for SAI1 1-3 are valid and 0 is invalid - pub fn set_sync_input(&mut self, selection: u8) { - assert!(selection < 0b1_00); - unsafe { self.rb.gcr().modify(|_, w| w.syncout().bits(selection)) }; - } + /// Unmute `channel`, this is checked at the start of each frame + /// Meaningful only in Tx mode + pub fn unmute(&mut self, channel: SaiChannel) { + self.rb + .ch(channel as usize) + .cr2() + .modify(|_, w| w.mute().disabled()); + } - /// Synchronization output for other SAI blocks - pub fn set_sync_output(&mut self, channel: Option) { - match channel { - Some(SaiChannel::ChannelA) => unsafe { &self.rb.gcr().modify(|_, w| w.syncout().bits(0b01) ) }, - Some(SaiChannel::ChannelB) => unsafe { &self.rb.gcr().modify(|_, w| w.syncout().bits(0b10) ) }, - None => unsafe { &self.rb.gcr().modify(|_, w| w.syncout().bits(0b00) ) }, - }; - } + /// Used to operate the audio block(s) with an external SAI for synchronization + /// Refer to RM0433 rev 7 section 51.4.4 for valid values + /// + /// In short 0-3 maps SAI1-4 with the ones pointing to self being reserved. + /// e.g. for SAI1 1-3 are valid and 0 is invalid + pub fn set_sync_input(&mut self, selection: u8) { + assert!(selection < 0b1_00); + unsafe { self.rb.gcr().modify(|_, w| w.syncout().bits(selection)) }; + } - /// Enable DMA for the SAI peripheral. - pub fn enable_dma(&mut self, channel: SaiChannel) { - self.rb.ch(channel as usize).cr1().modify(|_, w| w.dmaen().enabled()); - } + /// Synchronization output for other SAI blocks + pub fn set_sync_output(&mut self, channel: Option) { + match channel { + Some(SaiChannel::ChannelA) => unsafe { + &self.rb.gcr().modify(|_, w| w.syncout().bits(0b01)) + }, + Some(SaiChannel::ChannelB) => unsafe { + &self.rb.gcr().modify(|_, w| w.syncout().bits(0b10)) + }, + None => unsafe { + &self.rb.gcr().modify(|_, w| w.syncout().bits(0b00)) + }, + }; + } - /// Releases the SAI peripheral - pub fn free(self) -> ($SAIX, rec::$Rec) { - // Refer to RM0433 Rev 7 51.4.15 Disabling the SAI + /// Enable DMA for the SAI peripheral. + pub fn enable_dma(&mut self, channel: SaiChannel) { + self.rb + .ch(channel as usize) + .cr1() + .modify(|_, w| w.dmaen().enabled()); + } - // Master: Clear SAIEN - self.master_channel(|ch| { - ch.cr1().modify(|_, w| w.saien().disabled()) - }); + /// Releases the SAI peripheral + pub fn free(self) -> (SAI, as GetClkSAI>::Rec) { + // Refer to RM0433 Rev 7 51.4.15 Disabling the SAI - // Master: Wait for SAI to clear at the end of the - // frame - while self.master_channel(|ch| { - ch.cr1().read().saien().bit_is_set() - }) {} + // Master: Clear SAIEN + self.master_channel(|ch| ch.cr1().modify(|_, w| w.saien().disabled())); - // Slave: Clear SAIEN - self.slave_channel(|ch| { - ch.cr1().modify(|_, w| w.saien().disabled()) - }); + // Master: Wait for SAI to clear at the end of the + // frame + while self.master_channel(|ch| ch.cr1().read().saien().bit_is_set()) {} - // Slave: Wait for SAI to clear - while self.slave_channel(|ch| { - ch.cr1().read().saien().bit_is_set() - }).unwrap_or(false) {} + // Slave: Clear SAIEN + self.slave_channel(|ch| ch.cr1().modify(|_, w| w.saien().disabled())); + // Slave: Wait for SAI to clear + while self + .slave_channel(|ch| ch.cr1().read().saien().bit_is_set()) + .unwrap_or(false) + {} - (self.rb, rec::$Rec { _marker: PhantomData }) - } - } - )+ + (self.rb, unsafe { as GetClkSAI>::Rec::new() }) } } - -sai_hal! { - SAI1: (sai1, Sai1), -} -#[cfg(any(feature = "rm0433", feature = "rm0399"))] -sai_hal! { - SAI2: (sai2, Sai2), - SAI3: (sai3, Sai3), - SAI4: (sai4, Sai4), -} -#[cfg(feature = "rm0455")] -sai_hal! { - SAI2: (sai2, Sai2), -} -#[cfg(feature = "rm0468")] -sai_hal! { - SAI4: (sai4, Sai4), -} diff --git a/src/sai/pdm.rs b/src/sai/pdm.rs index e37e5d93..98adffb3 100644 --- a/src/sai/pdm.rs +++ b/src/sai/pdm.rs @@ -15,8 +15,8 @@ //! let _ = block!(sai.read_data()).unwrap(); //! ``` -use crate::rcc::{rec, CoreClocks, ResetEnable}; -use crate::sai::{GetClkSAI, Sai, SaiChannel, INTERFACE}; +use crate::rcc::CoreClocks; +use crate::sai::{GetClkSAI, Sai, SaiChannel, INTERFACE, SAI}; use crate::stm32::SAI1; #[cfg(not(feature = "rm0455"))] @@ -164,39 +164,155 @@ pub struct Pdm { impl INTERFACE for Pdm {} /// Trait to extend SAI peripherals -pub trait SaiPdmExt: Sized { - type Rec: ResetEnable; - +pub trait SaiPdmExt: Sized + GetClkSAI { fn pdm( self, _pins: PINS, clock: Hertz, prec: Self::Rec, clocks: &CoreClocks, - ) -> Sai + ) -> Sai where PINS: PulseDensityPins; } +impl SaiPdmExt for SAI +where + Self: GetClkSAI, +{ + fn pdm( + self, + _pins: PINS, + clock: Hertz, + prec: Self::Rec, + clocks: &CoreClocks, + ) -> Sai + where + PINS: PulseDensityPins, + { + let micnbr = match PINS::MAX_MICROPHONES { + 2 => 0, // Up to 2 microphones + _ => unimplemented!(), + }; + let frl = (16 * (micnbr + 1)) - 1; // Frame length + let ds = 0b100; // 16 bits + let nbslot: u8 = 0; // One slot + + // Calculate bit clock SCK_a + let sck_a_hz = 2 * clock; + + // Calculate master clock MCLK_a + let mclk_a_hz = sck_a_hz; // For NODIV = 1, SCK_a = MCLK_a + + // Calculate divider + let ker_ck_a = SAI::::sai_a_ker_ck(&prec, clocks); + let kernel_clock_divider: u8 = + (ker_ck_a / mclk_a_hz).try_into().expect(concat!( + stringify!($SAIX), + ": Kernel clock is out of range for required MCLK" + )); + + // Configure SAI peripeheral + let mut s = Sai { + rb: self, + master_channel: SaiChannel::ChannelA, + slave_channel: None, + interface: Pdm { + // count slots for 2 frames + invalid_countdown: 2 * (nbslot + 1), + }, + }; + // RCC enable, reset + s.sai_rcc_init(prec); + + // Configure block 1 + let audio_ch_a = &s.rb.cha(); + + unsafe { + audio_ch_a.cr1().modify(|_, w| { + w.mode() + .master_rx() // Master receiver + .prtcfg() + .free() + .ds() + .bits(ds) + .lsbfirst() + .clear_bit() // MSB first + .ckstr() + .clear_bit() // Rising edge + .mono() + .stereo() // Stereo + .nodiv() + .no_div() // No division from MCLK to SCK + .mckdiv() + .bits(kernel_clock_divider - 1) + }); + + audio_ch_a.frcr().modify(|_, w| { + w.fsoff() + .clear_bit() + .fspol() + .set_bit() // FS active high + .fsdef() + .clear_bit() + .fsall() + .bits(0) // Pulse width = 1 bit clock + .frl() + .bits(frl) + }); + + audio_ch_a.slotr().modify(|_, w| { + w.fboff() + .bits(0) // No offset on slot + .slotsz() + .bits(0) // Equal to ACR1.DS + .nbslot() + .bits(nbslot) + .sloten() + .bits(0x1) // Bitfield + }); + + // PDM Control Register + if PINS::ENABLE_BITSTREAM_CLOCK_1 { + s.rb.pdmcr().modify(|_, w| { + w.cken1().set_bit() // CKEN1 + }); + } + if PINS::ENABLE_BITSTREAM_CLOCK_2 { + s.rb.pdmcr().modify(|_, w| { + w.cken2().set_bit() // CKEN2 + }); + } + if PINS::ENABLE_BITSTREAM_CLOCK_3 { + s.rb.pdmcr().modify(|_, w| { + w.cken3().set_bit() // CKEN3 + }); + } + if PINS::ENABLE_BITSTREAM_CLOCK_4 { + s.rb.pdmcr().modify(|_, w| { + w.cken4().set_bit() // CKEN4 + }); + } + s.rb.pdmcr().modify(|_, w| { + w.micnbr() + .bits(micnbr) // 2, 4, 6 or 8 microphones + .pdmen() + .set_bit() // Enabled + }); + } + + // Enable SAI_A + audio_ch_a.cr1().modify(|_, w| w.saien().enabled()); + + // SAI + s + } +} + macro_rules! hal { ($($SAIX:ident, $Rec:ident: ($pdm_saiX:ident)),+) => { $( - impl SaiPdmExt<$SAIX> for $SAIX { - type Rec = rec::$Rec; - fn pdm( - self, - _pins: PINS, - clock: Hertz, - prec: rec::$Rec, - clocks: &CoreClocks, - ) -> Sai - where - PINS: PulseDensityPins, - { - Sai::$pdm_saiX(self, _pins, clock, prec, clocks) - } - } impl Sai<$SAIX, Pdm> { /// Read a single data word (one 'slot') pub fn read_data(&mut self) -> nb::Result { @@ -217,136 +333,6 @@ macro_rules! hal { Ok(self.rb.cha().dr().read().bits() & 0xFFFF) } - - /// Initialise SAI in PDM mode - pub fn $pdm_saiX( - sai: $SAIX, - _pins: PINS, - clock: Hertz, - prec: rec::$Rec, - clocks: &CoreClocks, - ) -> Self - where - PINS: PulseDensityPins<$SAIX>, - { - let micnbr = match PINS::MAX_MICROPHONES { - 2 => 0, // Up to 2 microphones - _ => unimplemented!(), - }; - let frl = (16 * (micnbr + 1)) - 1; // Frame length - let ds = 0b100; // 16 bits - let nbslot: u8 = 0; // One slot - - // Calculate bit clock SCK_a - let sck_a_hz = 2 * clock; - - // Calculate master clock MCLK_a - let mclk_a_hz = sck_a_hz; // For NODIV = 1, SCK_a = MCLK_a - - // Calculate divider - let ker_ck_a = $SAIX::sai_a_ker_ck(&prec, clocks); - let kernel_clock_divider: u8 = (ker_ck_a / mclk_a_hz) - .try_into() - .expect(concat!(stringify!($SAIX), - ": Kernel clock is out of range for required MCLK" - )); - - - // Configure SAI peripeheral - let mut s = Sai { - rb: sai, - master_channel: SaiChannel::ChannelA, - slave_channel: None, - interface: Pdm { - // count slots for 2 frames - invalid_countdown: 2 * (nbslot + 1), - }, - }; - // RCC enable, reset - s.sai_rcc_init(prec); - - // Configure block 1 - let audio_ch_a = &s.rb.cha(); - - unsafe { - audio_ch_a.cr1().modify(|_, w| { - w.mode() - .master_rx() // Master receiver - .prtcfg() - .free() - .ds() - .bits(ds) - .lsbfirst() - .clear_bit() // MSB first - .ckstr() - .clear_bit() // Rising edge - .mono() - .stereo() // Stereo - .nodiv() - .no_div() // No division from MCLK to SCK - .mckdiv() - .bits(kernel_clock_divider - 1) - }); - - audio_ch_a.frcr().modify(|_, w| { - w.fsoff() - .clear_bit() - .fspol() - .set_bit() // FS active high - .fsdef() - .clear_bit() - .fsall() - .bits(0) // Pulse width = 1 bit clock - .frl() - .bits(frl) - }); - - audio_ch_a.slotr().modify(|_, w| { - w.fboff() - .bits(0) // No offset on slot - .slotsz() - .bits(0) // Equal to ACR1.DS - .nbslot() - .bits(nbslot) - .sloten() - .bits(0x1) // Bitfield - }); - - // PDM Control Register - if PINS::ENABLE_BITSTREAM_CLOCK_1 { - s.rb.pdmcr().modify(|_, w| { - w.cken1().set_bit() // CKEN1 - }); - } - if PINS::ENABLE_BITSTREAM_CLOCK_2 { - s.rb.pdmcr().modify(|_, w| { - w.cken2().set_bit() // CKEN2 - }); - } - if PINS::ENABLE_BITSTREAM_CLOCK_3 { - s.rb.pdmcr().modify(|_, w| { - w.cken3().set_bit() // CKEN3 - }); - } - if PINS::ENABLE_BITSTREAM_CLOCK_4 { - s.rb.pdmcr().modify(|_, w| { - w.cken4().set_bit() // CKEN4 - }); - } - s.rb.pdmcr().modify(|_, w| { - w.micnbr() - .bits(micnbr) // 2, 4, 6 or 8 microphones - .pdmen() - .set_bit() // Enabled - }); - } - - // Enable SAI_A - audio_ch_a.cr1().modify(|_, w| w.saien().enabled()); - - // SAI - s - } } )+ } diff --git a/src/serial.rs b/src/serial.rs index 1c3224de..70d78fc5 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -865,7 +865,7 @@ macro_rules! usart { /// Clear the line idle status bit pub fn clear_idle(&mut self) { - unsafe { (*$USARTX::ptr()).icr().write(|w| w.idlecf().set_bit()); } + unsafe { (*$USARTX::ptr()).icr().write(|w| w.idlecf().clear()); } let _ = self.usart.isr().read(); let _ = self.usart.isr().read(); // Delay 2 peripheral clocks } @@ -1043,7 +1043,7 @@ macro_rules! usart { /// Clear the line idle status bit pub fn clear_idle(&mut self) { let usart = unsafe { &*$USARTX::ptr() }; - usart.icr().write(|w| w.idlecf().set_bit()); + usart.icr().write(|w| w.idlecf().clear()); let _ = usart.isr().read(); let _ = usart.isr().read(); // Delay 2 peripheral clocks } diff --git a/src/spi.rs b/src/spi.rs index 613c0bc0..c2207649 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -944,18 +944,18 @@ macro_rules! spi { fn listen(&mut self, event: Event) { match event { Event::Rxp => self.spi.ier().modify(|_, w| - w.rxpie().not_masked()), + w.rxpie().enabled()), Event::Txp => self.spi.ier().modify(|_, w| - w.txpie().not_masked()), + w.txpie().enabled()), Event::Error => self.spi.ier().modify(|_, w| { w.udrie() // Underrun - .not_masked() + .enabled() .ovrie() // Overrun - .not_masked() + .enabled() .crceie() // CRC error - .not_masked() + .enabled() .modfie() // Mode fault - .not_masked() + .enabled() }), }; } @@ -967,21 +967,21 @@ macro_rules! spi { fn unlisten(&mut self, event: Event) { match event { Event::Rxp => { - self.spi.ier().modify(|_, w| w.rxpie().masked()); + self.spi.ier().modify(|_, w| w.rxpie().disabled()); } Event::Txp => { - self.spi.ier().modify(|_, w| w.txpie().masked()); + self.spi.ier().modify(|_, w| w.txpie().disabled()); } Event::Error => { self.spi.ier().modify(|_, w| { w.udrie() // Underrun - .masked() + .disabled() .ovrie() // Overrun - .masked() + .disabled() .crceie() // CRC error - .masked() + .disabled() .modfie() // Mode fault - .masked() + .disabled() }); } } diff --git a/src/usb_hs.rs b/src/usb_hs.rs index 6b726a3b..304475fd 100644 --- a/src/usb_hs.rs +++ b/src/usb_hs.rs @@ -308,7 +308,7 @@ unsafe impl UsbPeripheral for USB1_ULPI { rcc.ahb1enr().modify(|_, w| w.usb1otgen().enabled()); // Enable ULPI Clock - rcc.ahb1enr().modify(|_, w| w.usb1ulpien().enabled()); + rcc.ahb1enr().modify(|_, w| w.usb1otgulpien().enabled()); // Reset USB peripheral rcc.ahb1rstr().modify(|_, w| w.usb1otgrst().set_bit());