diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db7b1060..61c78cb6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,8 +22,8 @@ jobs: - stm32g474 - stm32g483 - stm32g484 - #- stm32g491 # Does not seem ready yet - #- stm32g4a1 # Does not seem ready yet + - stm32g491 # Does not seem ready yet + - stm32g4a1 # Does not seem ready yet features: - log-rtt,defmt # TODO: -log-rtt # log-rtt without defmt, more combos? diff --git a/Cargo.toml b/Cargo.toml index b78d4e2b..8bac4fc7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,8 @@ version = "0.0.2" [dependencies] nb = "0.1.1" -stm32g4 = "0.15.1" +#stm32g4 = { git = "https://github.com/stm32-rs/stm32-rs-nightlies" } #"0.15.1" +stm32g4 = { version = "0.17.0", package = "stm32g4-staging" } paste = "1.0" bitflags = "1.2" vcell = "0.1" diff --git a/examples/flash_with_rtic.rs b/examples/flash_with_rtic.rs index 9e2d00e8..9db939d1 100644 --- a/examples/flash_with_rtic.rs +++ b/examples/flash_with_rtic.rs @@ -73,7 +73,7 @@ mod app { unsafe { let mut flash = &(*stm32g4xx_hal::stm32::FLASH::ptr()); - flash.acr.modify(|_, w| { + flash.acr().modify(|_, w| { w.latency().bits(0b1000) // 8 wait states }); } diff --git a/src/adc.rs b/src/adc.rs index b40df49a..600e8bcf 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -1301,7 +1301,7 @@ impl Conversion { /// /// //Channel 1 /// //Disable the channel before configuring it -/// tim.ccer.modify(|_, w| w.cc1e().clear_bit()); +/// tim.ccer().modify(|_, w| w.cc1e().clear_bit()); /// /// tim.ccmr1_output().modify(|_, w| w /// //Preload enable for channel @@ -1313,14 +1313,14 @@ impl Conversion { /// /// //Set the duty cycle, 0 won't work in pwm mode but might be ok in /// //toggle mode or match mode -/// let max_duty = tim.arr.read().arr().bits() as u16; -/// tim.ccr1.modify(|_, w| w.ccr().bits(max_duty / 2)); +/// let max_duty = tim.arr().read().arr().bits() as u16; +/// tim.ccr1().modify(|_, w| w.ccr().bits(max_duty / 2)); /// /// //Enable the channel -/// tim.ccer.modify(|_, w| w.cc1e().set_bit()); +/// tim.ccer().modify(|_, w| w.cc1e().set_bit()); /// /// //Enable the TIM main Output -/// tim.bdtr.modify(|_, w| w.moe().set_bit()); +/// tim.bdtr().modify(|_, w| w.moe().set_bit()); /// } /// ``` #[derive(Clone, Copy)] @@ -1413,7 +1413,7 @@ pub trait TriggerType { #[inline(always)] fn configure_clock_source12(cs: ClockSource, rcc: &Rcc) { // Select system clock as ADC clock source - rcc.rb.ccipr.modify(|_, w| { + rcc.rb.ccipr().modify(|_, w| { // This is sound, as `0b10` is a valid value for this field. unsafe { w.adc12sel().bits(cs.into()); @@ -1427,7 +1427,7 @@ fn configure_clock_source12(cs: ClockSource, rcc: &Rcc) { #[allow(dead_code)] fn configure_clock_source345(cs: ClockSource, rcc: &Rcc) { // Select system clock as ADC clock source - rcc.rb.ccipr.modify(|_, w| { + rcc.rb.ccipr().modify(|_, w| { // This is sound, as `0b10` is a valid value for this field. unsafe { w.adc345sel().bits(cs.into()); @@ -1608,21 +1608,21 @@ macro_rules! adc { /// Enables the Deep Power Down Modus #[inline(always)] pub fn enable_deeppwd_down(&mut self) { - self.adc_reg.cr.modify(|_, w| w.deeppwd().set_bit()); + self.adc_reg.cr().modify(|_, w| w.deeppwd().set_bit()); } /// Disables the Deep Power Down Modus #[inline(always)] pub fn disable_deeppwd_down(&mut self) { - self.adc_reg.cr.modify(|_, w| w.deeppwd().clear_bit()); + self.adc_reg.cr().modify(|_, w| w.deeppwd().clear_bit()); } /// Enables the Voltage Regulator #[inline(always)] pub fn enable_vreg(&mut self, delay: &mut impl DelayUs) { - self.adc_reg.cr.modify(|_, w| w.advregen().set_bit()); - while !self.adc_reg.cr.read().advregen().bit_is_set() {} + self.adc_reg.cr().modify(|_, w| w.advregen().set_bit()); + while !self.adc_reg.cr().read().advregen().bit_is_set() {} // According to the STM32G4xx Reference Manual, section 21.4.6, we need // to wait for T_ADCVREG_STUP after enabling the internal voltage @@ -1634,13 +1634,13 @@ macro_rules! adc { /// Disables the Voltage Regulator #[inline(always)] pub fn disable_vreg(&mut self) { - self.adc_reg.cr.modify(|_, w| w.advregen().clear_bit()); + self.adc_reg.cr().modify(|_, w| w.advregen().clear_bit()); } /// Returns if the ADC is enabled (ADEN) #[inline(always)] pub fn is_enabled(&self) -> bool { - self.adc_reg.cr.read().aden().bit_is_set() + self.adc_reg.cr().read().aden().bit_is_set() } /// Disables the adc, since we don't know in what state we get it. @@ -1650,11 +1650,11 @@ macro_rules! adc { self.cancel_conversion(); // Turn off ADC - self.adc_reg.cr.modify(|_, w| w.addis().set_bit()); - while self.adc_reg.cr.read().addis().bit_is_set() {} + self.adc_reg.cr().modify(|_, w| w.addis().set_bit()); + while self.adc_reg.cr().read().addis().bit_is_set() {} // Wait until the ADC has turned off - while self.adc_reg.cr.read().aden().bit_is_set() {} + while self.adc_reg.cr().read().aden().bit_is_set() {} } /// Enables the adc @@ -1663,14 +1663,14 @@ macro_rules! adc { self.calibrate_all(); self.apply_config(self.config); - self.adc_reg.isr.modify(|_, w| w.adrdy().set_bit()); - self.adc_reg.cr.modify(|_, w| w.aden().set_bit()); + self.adc_reg.isr().modify(|_, w| w.adrdy().set_bit()); + self.adc_reg.cr().modify(|_, w| w.aden().set_bit()); // Wait for adc to get ready - while !self.adc_reg.isr.read().adrdy().bit_is_set() {} + while !self.adc_reg.isr().read().adrdy().bit_is_set() {} // Clear ready flag - self.adc_reg.isr.modify(|_, w| w.adrdy().set_bit()); + self.adc_reg.isr().modify(|_, w| w.adrdy().set_bit()); self.clear_end_of_conversion_flag(); } @@ -1709,7 +1709,7 @@ macro_rules! adc { self.config.clock_mode = clock_mode; unsafe { let common = &(*stm32::$common_type::ptr()); - common.ccr.modify(|_, w| w.ckmode().bits(clock_mode.into())); + common.ccr().modify(|_, w| w.ckmode().bits(clock_mode.into())); } } @@ -1719,7 +1719,7 @@ macro_rules! adc { self.config.clock = clock; unsafe { let common = &(*stm32::$common_type::ptr()); - common.ccr.modify(|_, w| w.presc().bits(clock.into())); + common.ccr().modify(|_, w| w.presc().bits(clock.into())); } } @@ -1727,30 +1727,34 @@ macro_rules! adc { #[inline(always)] pub fn set_resolution(&mut self, resolution: config::Resolution) { self.config.resolution = resolution; - self.adc_reg.cfgr.modify(|_, w| w.res().bits(resolution.into())); + unsafe { + self.adc_reg.cfgr().modify(|_, w| w.res().bits(resolution.into())); + } } /// Enable oversampling #[inline(always)] pub fn set_oversampling(&mut self, oversampling: config::OverSampling, shift: config::OverSamplingShift) { - self.adc_reg.cfgr2.modify(|_, w| unsafe { w.ovsr().bits(oversampling.into()) - .ovss().bits(shift.into()) - .rovse().set_bit()}); + self.adc_reg.cfgr2().modify(|_, w| unsafe { + w.ovsr().bits(oversampling.into()) + .ovss().bits(shift.into()) + .rovse().set_bit() + }); } /// Sets the DR register alignment to left or right #[inline(always)] pub fn set_align(&mut self, align: config::Align) { self.config.align = align; - self.adc_reg.cfgr.modify(|_, w| w.align().bit(align.into())); + self.adc_reg.cfgr().modify(|_, w| w.align().bit(align.into())); } /// Sets which external trigger to use and if it is disabled, rising, falling or both #[inline(always)] pub fn set_external_trigger(&mut self, (edge, extsel): (config::TriggerMode, $trigger_type)) { self.config.external_trigger = (edge, extsel); - self.adc_reg.cfgr.modify(|_, w| unsafe { w + self.adc_reg.cfgr().modify(|_, w| unsafe { w .extsel().bits(extsel.into()) .exten().bits(edge.into()) }); @@ -1760,14 +1764,14 @@ macro_rules! adc { #[inline(always)] pub fn set_auto_delay(&mut self, delay: bool) { self.config.auto_delay = delay; - self.adc_reg.cfgr.modify(|_, w| w.autdly().bit(delay) ); + self.adc_reg.cfgr().modify(|_, w| w.autdly().bit(delay) ); } /// Enables and disables dis-/continuous mode #[inline(always)] pub fn set_continuous(&mut self, continuous: config::Continuous) { self.config.continuous = continuous; - self.adc_reg.cfgr.modify(|_, w| w + self.adc_reg.cfgr().modify(|_, w| w .cont().bit(continuous == config::Continuous::Continuous) .discen().bit(continuous == config::Continuous::Discontinuous) ); @@ -1777,7 +1781,9 @@ macro_rules! adc { // NOTE: The software is allowed to write these bits only when ADSTART = 0 fn set_subgroup_len(&mut self, subgroup_len: config::SubGroupLength) { self.config.subgroup_len = subgroup_len; - self.adc_reg.cfgr.modify(|_, w| w.discnum().bits(subgroup_len as u8)) + unsafe { + self.adc_reg.cfgr().modify(|_, w| w.discnum().bits(subgroup_len as u8)); + } } /// Sets DMA to disabled, single or continuous @@ -1789,7 +1795,7 @@ macro_rules! adc { config::Dma::Single => (false, true), config::Dma::Continuous => (true, true), }; - self.adc_reg.cfgr.modify(|_, w| w + self.adc_reg.cfgr().modify(|_, w| w //DDS stands for "DMA disable selection" //0 means do one DMA then stop //1 means keep sending DMA requests as long as DMA=1 @@ -1808,7 +1814,7 @@ macro_rules! adc { config::Eoc::Conversion => (true, true), config::Eoc::Sequence => (true, false), }; - self.adc_reg.ier.modify(|_, w|w + self.adc_reg.ier().modify(|_, w|w .eosie().bit(eocs) .eocie().bit(en) ); @@ -1818,7 +1824,7 @@ macro_rules! adc { /// /// This is triggered when the AD finishes a conversion before the last value was read by CPU/DMA pub fn set_overrun_interrupt(&mut self, enable: bool) { - self.adc_reg.ier.modify(|_, w| w.ovrie().bit(enable)); + self.adc_reg.ier().modify(|_, w| w.ovrie().bit(enable)); } /// Sets the default sample time that is used for one-shot conversions. @@ -1834,7 +1840,7 @@ macro_rules! adc { pub fn set_channel_input_type(&mut self, df: config::DifferentialSelection) { self.config.difsel = df; - self.adc_reg.difsel.modify(|_, w| {w + self.adc_reg.difsel().modify(|_, w| {w .difsel_0().bit(df.get_channel(0).into() ) .difsel_1().bit(df.get_channel(1).into() ) .difsel_2().bit(df.get_channel(2).into() ) @@ -1861,19 +1867,19 @@ macro_rules! adc { #[inline(always)] pub fn reset_sequence(&mut self) { //The reset state is One conversion selected - self.adc_reg.sqr1.modify(|_, w| w.l().bits(config::Sequence::One.into())); + self.adc_reg.sqr1().modify(|_, w| unsafe { w.l().bits(config::Sequence::One.into()) }); } /// Returns the current sequence length. Primarily useful for configuring DMA. #[inline(always)] pub fn sequence_length(&mut self) -> u8 { - self.adc_reg.sqr1.read().l().bits() + 1 + self.adc_reg.sqr1().read().l().bits() + 1 } /// Returns the address of the ADC data register. Primarily useful for configuring DMA. #[inline(always)] pub fn data_register_address(&self) -> u32 { - &self.adc_reg.dr as *const _ as u32 + &self.adc_reg.dr() as *const _ as u32 } /// Calibrate the adc for @@ -1881,15 +1887,15 @@ macro_rules! adc { pub fn calibrate(&mut self, it: config::InputType) { match it { config::InputType::SingleEnded => { - self.adc_reg.cr.modify(|_, w| w.adcaldif().clear_bit() ); + self.adc_reg.cr().modify(|_, w| w.adcaldif().clear_bit() ); }, config::InputType::Differential => { - self.adc_reg.cr.modify(|_, w| w.adcaldif().set_bit() ); + self.adc_reg.cr().modify(|_, w| w.adcaldif().set_bit() ); }, } - self.adc_reg.cr.modify(|_, w| w.adcal().set_bit() ); - while self.adc_reg.cr.read().adcal().bit_is_set() {} + self.adc_reg.cr().modify(|_, w| w.adcal().set_bit() ); + while self.adc_reg.cr().read().adcal().bit_is_set() {} } /// Calibrate the Adc for all Input Types @@ -1912,7 +1918,7 @@ macro_rules! adc { { //Check the sequence is long enough - self.adc_reg.sqr1.modify(|r, w| { + self.adc_reg.sqr1().modify(|r, w| unsafe { let prev: config::Sequence = r.l().bits().into(); if prev < sequence { w.l().bits(sequence.into()) @@ -1925,47 +1931,49 @@ macro_rules! adc { //Set the channel in the right sequence field match sequence { - config::Sequence::One => self.adc_reg.sqr1.modify(|_, w| unsafe {w.sq1().bits(channel) }), - config::Sequence::Two => self.adc_reg.sqr1.modify(|_, w| unsafe {w.sq2().bits(channel) }), - config::Sequence::Three => self.adc_reg.sqr1.modify(|_, w| unsafe {w.sq3().bits(channel) }), - config::Sequence::Four => self.adc_reg.sqr1.modify(|_, w| unsafe {w.sq4().bits(channel) }), - config::Sequence::Five => self.adc_reg.sqr2.modify(|_, w| unsafe {w.sq5().bits(channel) }), - config::Sequence::Six => self.adc_reg.sqr2.modify(|_, w| unsafe {w.sq6().bits(channel) }), - config::Sequence::Seven => self.adc_reg.sqr2.modify(|_, w| unsafe {w.sq7().bits(channel) }), - config::Sequence::Eight => self.adc_reg.sqr2.modify(|_, w| unsafe {w.sq8().bits(channel) }), - config::Sequence::Nine => self.adc_reg.sqr2.modify(|_, w| unsafe {w.sq9().bits(channel) }), - config::Sequence::Ten => self.adc_reg.sqr3.modify(|_, w| unsafe {w.sq10().bits(channel) }), - config::Sequence::Eleven => self.adc_reg.sqr3.modify(|_, w| unsafe {w.sq11().bits(channel) }), - config::Sequence::Twelve => self.adc_reg.sqr3.modify(|_, w| unsafe {w.sq12().bits(channel) }), - config::Sequence::Thirteen => self.adc_reg.sqr3.modify(|_, w| unsafe {w.sq13().bits(channel) }), - config::Sequence::Fourteen => self.adc_reg.sqr3.modify(|_, w| unsafe {w.sq14().bits(channel) }), - config::Sequence::Fifteen => self.adc_reg.sqr4.modify(|_, w| unsafe {w.sq15().bits(channel) }), - config::Sequence::Sixteen => self.adc_reg.sqr4.modify(|_, w| unsafe {w.sq16().bits(channel) }), - } + config::Sequence::One => self.adc_reg.sqr1().modify(|_, w| unsafe {w.sq1().bits(channel) }), + config::Sequence::Two => self.adc_reg.sqr1().modify(|_, w| unsafe {w.sq2().bits(channel) }), + config::Sequence::Three => self.adc_reg.sqr1().modify(|_, w| unsafe {w.sq3().bits(channel) }), + config::Sequence::Four => self.adc_reg.sqr1().modify(|_, w| unsafe {w.sq4().bits(channel) }), + config::Sequence::Five => self.adc_reg.sqr2().modify(|_, w| unsafe {w.sq5().bits(channel) }), + config::Sequence::Six => self.adc_reg.sqr2().modify(|_, w| unsafe {w.sq6().bits(channel) }), + config::Sequence::Seven => self.adc_reg.sqr2().modify(|_, w| unsafe {w.sq7().bits(channel) }), + config::Sequence::Eight => self.adc_reg.sqr2().modify(|_, w| unsafe {w.sq8().bits(channel) }), + config::Sequence::Nine => self.adc_reg.sqr2().modify(|_, w| unsafe {w.sq9().bits(channel) }), + config::Sequence::Ten => self.adc_reg.sqr3().modify(|_, w| unsafe {w.sq10().bits(channel) }), + config::Sequence::Eleven => self.adc_reg.sqr3().modify(|_, w| unsafe {w.sq11().bits(channel) }), + config::Sequence::Twelve => self.adc_reg.sqr3().modify(|_, w| unsafe {w.sq12().bits(channel) }), + config::Sequence::Thirteen => self.adc_reg.sqr3().modify(|_, w| unsafe {w.sq13().bits(channel) }), + config::Sequence::Fourteen => self.adc_reg.sqr3().modify(|_, w| unsafe {w.sq14().bits(channel) }), + config::Sequence::Fifteen => self.adc_reg.sqr4().modify(|_, w| unsafe {w.sq15().bits(channel) }), + config::Sequence::Sixteen => self.adc_reg.sqr4().modify(|_, w| unsafe {w.sq16().bits(channel) }), + }; //Set the sample time for the channel let st = u8::from(sample_time); - match channel { - 0 => self.adc_reg.smpr1.modify(|_, w| w.smp0().bits(st) ), - 1 => self.adc_reg.smpr1.modify(|_, w| w.smp1().bits(st) ), - 2 => self.adc_reg.smpr1.modify(|_, w| w.smp2().bits(st) ), - 3 => self.adc_reg.smpr1.modify(|_, w| w.smp3().bits(st) ), - 4 => self.adc_reg.smpr1.modify(|_, w| w.smp4().bits(st) ), - 5 => self.adc_reg.smpr1.modify(|_, w| w.smp5().bits(st) ), - 6 => self.adc_reg.smpr1.modify(|_, w| w.smp6().bits(st) ), - 7 => self.adc_reg.smpr1.modify(|_, w| w.smp7().bits(st) ), - 8 => self.adc_reg.smpr1.modify(|_, w| w.smp8().bits(st) ), - 9 => self.adc_reg.smpr1.modify(|_, w| w.smp9().bits(st) ), - 10 => self.adc_reg.smpr2.modify(|_, w| w.smp10().bits(st) ), - 11 => self.adc_reg.smpr2.modify(|_, w| w.smp11().bits(st) ), - 12 => self.adc_reg.smpr2.modify(|_, w| w.smp12().bits(st) ), - 13 => self.adc_reg.smpr2.modify(|_, w| w.smp13().bits(st) ), - 14 => self.adc_reg.smpr2.modify(|_, w| w.smp14().bits(st) ), - 15 => self.adc_reg.smpr2.modify(|_, w| w.smp15().bits(st) ), - 16 => self.adc_reg.smpr2.modify(|_, w| w.smp16().bits(st) ), - 17 => self.adc_reg.smpr2.modify(|_, w| w.smp17().bits(st) ), - 18 => self.adc_reg.smpr2.modify(|_, w| w.smp18().bits(st) ), - _ => unimplemented!(), + unsafe { + match channel { + 0 => self.adc_reg.smpr1().modify(|_, w| w.smp0().bits(st) ), + 1 => self.adc_reg.smpr1().modify(|_, w| w.smp1().bits(st) ), + 2 => self.adc_reg.smpr1().modify(|_, w| w.smp2().bits(st) ), + 3 => self.adc_reg.smpr1().modify(|_, w| w.smp3().bits(st) ), + 4 => self.adc_reg.smpr1().modify(|_, w| w.smp4().bits(st) ), + 5 => self.adc_reg.smpr1().modify(|_, w| w.smp5().bits(st) ), + 6 => self.adc_reg.smpr1().modify(|_, w| w.smp6().bits(st) ), + 7 => self.adc_reg.smpr1().modify(|_, w| w.smp7().bits(st) ), + 8 => self.adc_reg.smpr1().modify(|_, w| w.smp8().bits(st) ), + 9 => self.adc_reg.smpr1().modify(|_, w| w.smp9().bits(st) ), + 10 => self.adc_reg.smpr2().modify(|_, w| w.smp10().bits(st) ), + 11 => self.adc_reg.smpr2().modify(|_, w| w.smp11().bits(st) ), + 12 => self.adc_reg.smpr2().modify(|_, w| w.smp12().bits(st) ), + 13 => self.adc_reg.smpr2().modify(|_, w| w.smp13().bits(st) ), + 14 => self.adc_reg.smpr2().modify(|_, w| w.smp14().bits(st) ), + 15 => self.adc_reg.smpr2().modify(|_, w| w.smp15().bits(st) ), + 16 => self.adc_reg.smpr2().modify(|_, w| w.smp16().bits(st) ), + 17 => self.adc_reg.smpr2().modify(|_, w| w.smp17().bits(st) ), + 18 => self.adc_reg.smpr2().modify(|_, w| w.smp18().bits(st) ), + _ => unimplemented!(), + }; } } /// Synchronously convert a single sample @@ -1975,12 +1983,14 @@ macro_rules! adc { PIN: Channel { let saved_config = self.config; - self.adc_reg.cfgr.modify(|_, w| w - .dmaen().clear_bit() //Disable dma - .cont().clear_bit() //Disable continuous mode - .exten().bits(config::TriggerMode::Disabled.into()) //Disable trigger - ); - self.adc_reg.ier.modify(|_, w| w + unsafe { + self.adc_reg.cfgr().modify(|_, w| w + .dmaen().clear_bit() //Disable dma + .cont().clear_bit() //Disable continuous mode + .exten().bits(config::TriggerMode::Disabled.into()) //Disable trigger + ); + } + self.adc_reg.ier().modify(|_, w| w .eocie().clear_bit() //Disable end of conversion interrupt ); @@ -2005,116 +2015,116 @@ macro_rules! adc { /// Resets the end-of-conversion flag #[inline(always)] pub fn clear_end_of_conversion_flag(&mut self) { - self.adc_reg.isr.modify(|_, w| w.eoc().set_bit()); + self.adc_reg.isr().modify(|_, w| w.eoc().set_bit()); } /// Block until the conversion is completed and return to configured pub fn wait_for_conversion_sequence(&mut self) { - while !self.adc_reg.isr.read().eoc().bit_is_set() {} + while !self.adc_reg.isr().read().eoc().bit_is_set() {} } /// get current sample #[inline(always)] pub fn current_sample(&self) -> u16 { - self.adc_reg.dr.read().rdata().bits() + self.adc_reg.dr().read().rdata().bits() } /// Starts conversion sequence. Waits for the hardware to indicate it's actually started. #[inline(always)] pub fn start_conversion(&mut self) { //Start conversion - self.adc_reg.cr.modify(|_, w| w.adstart().set_bit()); + self.adc_reg.cr().modify(|_, w| w.adstart().set_bit()); } /// Cancels an ongoing conversion #[inline(always)] pub fn cancel_conversion(&mut self) { - self.adc_reg.cr.modify(|_, w| w.adstp().set_bit()); - while self.adc_reg.cr.read().adstart().bit_is_set() {} + self.adc_reg.cr().modify(|_, w| w.adstp().set_bit()); + while self.adc_reg.cr().read().adstart().bit_is_set() {} } /// Returns if the Voltage Regulator is enabled #[inline(always)] pub fn is_vreg_enabled(&self) -> bool { - self.adc_reg.cr.read().advregen().bit_is_set() + self.adc_reg.cr().read().advregen().bit_is_set() } /// Returns if Deep Power Down is enabled #[inline(always)] pub fn is_deeppwd_enabled(&self) -> bool { - self.adc_reg.cr.read().deeppwd().bit_is_set() + self.adc_reg.cr().read().deeppwd().bit_is_set() } /// Returns if a conversion is active #[inline(always)] pub fn is_conversion_active(&self) -> bool { - self.adc_reg.cr.read().adstart().bit_is_set() + self.adc_reg.cr().read().adstart().bit_is_set() } /// Enables the vbat internal channel #[inline(always)] pub fn enable_vbat(&self, common: &stm32::$common_type) { - common.ccr.modify(|_, w| w.vbatsel().set_bit()); + common.ccr().modify(|_, w| w.vbatsel().set_bit()); } /// Enables the vbat internal channel #[inline(always)] pub fn disable_vbat(&self, common: &stm32::$common_type) { - common.ccr.modify(|_, w| w.vbatsel().clear_bit()); + common.ccr().modify(|_, w| w.vbatsel().clear_bit()); } /// Returns if the vbat internal channel is enabled #[inline(always)] pub fn is_vbat_enabled(&mut self, common: &stm32::$common_type) -> bool { - common.ccr.read().vbatsel().bit_is_set() + common.ccr().read().vbatsel().bit_is_set() } /// Enables the temp internal channel. #[inline(always)] pub fn enable_temperature(&mut self, common: &stm32::$common_type) { - common.ccr.modify(|_, w| w.vsensesel().set_bit()); + common.ccr().modify(|_, w| w.vsensesel().set_bit()); } /// Disables the temp internal channel #[inline(always)] pub fn disable_temperature(&mut self, common: &stm32::$common_type) { - common.ccr.modify(|_, w| w.vsensesel().clear_bit()); + common.ccr().modify(|_, w| w.vsensesel().clear_bit()); } /// Returns if the temp internal channel is enabled #[inline(always)] pub fn is_temperature_enabled(&mut self, common: &stm32::$common_type) -> bool { - common.ccr.read().vsensesel().bit_is_set() + common.ccr().read().vsensesel().bit_is_set() } /// Enables the vref internal channel. #[inline(always)] pub fn enable_vref(&mut self, common: &stm32::$common_type) { - common.ccr.modify(|_, w| w.vrefen().set_bit()); + common.ccr().modify(|_, w| w.vrefen().set_bit()); } /// Disables the vref internal channel #[inline(always)] pub fn disable_vref(&mut self, common: &stm32::$common_type) { - common.ccr.modify(|_, w| w.vrefen().clear_bit()); + common.ccr().modify(|_, w| w.vrefen().clear_bit()); } /// Returns if the vref internal channel is enabled #[inline(always)] pub fn is_vref_enabled(&mut self, common: &stm32::$common_type) -> bool { - common.ccr.read().vrefen().bit_is_set() + common.ccr().read().vrefen().bit_is_set() } /// Read overrun flag #[inline(always)] pub fn get_overrun_flag(&self) -> bool { - self.adc_reg.isr.read().ovr().bit() + self.adc_reg.isr().read().ovr().bit() } /// Resets the overrun flag #[inline(always)] pub fn clear_overrun_flag(&mut self) { - self.adc_reg.isr.modify(|_, w| w.ovr().set_bit()); + self.adc_reg.isr().modify(|_, w| w.ovr().set_bit()); } } @@ -2834,6 +2844,15 @@ adc_opamp!( ))] adc_opamp!( opamp::Opamp3 => (ADC3, 13), +); + +#[cfg(any( + feature = "stm32g473", + feature = "stm32g474", + feature = "stm32g483", + feature = "stm32g484", +))] +adc_opamp!( opamp::Opamp4 => (ADC5, 5), opamp::Opamp5 => (ADC5, 3), opamp::Opamp6 => (ADC4, 17), diff --git a/src/can.rs b/src/can.rs index 697df9c4..15d171a2 100644 --- a/src/can.rs +++ b/src/can.rs @@ -55,9 +55,9 @@ where { Self::enable(&rcc.rb); - if rcc.rb.ccipr.read().fdcansel().is_hse() { + if rcc.rb.ccipr().read().fdcansel().is_hse() { // Select P clock as FDCAN clock source - rcc.rb.ccipr.modify(|_, w| { + rcc.rb.ccipr().modify(|_, w| { // This is sound, as `FdCanClockSource` only contains valid values for this field. unsafe { w.fdcansel().bits(FdCanClockSource::PCLK as u8); diff --git a/src/comparator.rs b/src/comparator.rs index d0597ea7..b5e80fc4 100644 --- a/src/comparator.rs +++ b/src/comparator.rs @@ -55,26 +55,26 @@ impl EnabledState for Enabled {} impl EnabledState for Locked {} macro_rules! impl_comp { - ($($t:ident: $reg_t:ident, $reg:ident,)+) => {$( + ($($t:ident: $reg:ident,)+) => {$( pub struct $t { _rb: PhantomData<()>, } impl $t { - pub fn csr(&self) -> &$crate::stm32::comp::$reg_t { + pub fn csr(&self) -> &$crate::stm32::comp::CCSR { // SAFETY: The COMP1 type is only constructed with logical ownership of // these registers. - &unsafe { &*COMP::ptr() }.$reg + &unsafe { &*COMP::ptr() }.$reg() } } )+}; } impl_comp! { - COMP1: C1CSR, c1csr, - COMP2: C2CSR, c2csr, - COMP3: C3CSR, c3csr, - COMP4: C4CSR, c4csr, + COMP1: c1csr, + COMP2: c2csr, + COMP3: c3csr, + COMP4: c4csr, } #[cfg(any( feature = "stm32g473", @@ -83,9 +83,9 @@ impl_comp! { feature = "stm32g484" ))] impl_comp! { - COMP5: C5CSR, c5csr, - COMP6: C6CSR, c6csr, - COMP7: C7CSR, c7csr, + COMP5: c5csr, + COMP6: c6csr, + COMP7: c7csr, } // TODO: Split COMP in PAC @@ -162,13 +162,13 @@ macro_rules! positive_input_pin { ($COMP:ident, $pin_0:ident, $pin_1:ident) => { impl PositiveInput<$COMP> for &$pin_0 { fn setup(&self, comp: &$COMP) { - comp.csr().modify(|_, w| w.inpsel().bit(false)) + comp.csr().modify(|_, w| w.inpsel().bit(false)); } } impl PositiveInput<$COMP> for &$pin_1 { fn setup(&self, comp: &$COMP) { - comp.csr().modify(|_, w| w.inpsel().bit(true)) + comp.csr().modify(|_, w| w.inpsel().bit(true)); } } }; @@ -213,7 +213,7 @@ macro_rules! negative_input_pin_helper { } fn setup(&self, comp: &$COMP) { - comp.csr().modify(|_, w| unsafe { w.inmsel().bits($bits) }) + comp.csr().modify(|_, w| unsafe { w.inmsel().bits($bits) }); } } }; @@ -268,7 +268,7 @@ macro_rules! refint_input { fn setup(&self, comp: &$COMP) { comp.csr() - .modify(|_, w| unsafe { w.inmsel().bits(*self as u8) }) + .modify(|_, w| unsafe { w.inmsel().bits(*self as u8) }); } } )+}; @@ -294,7 +294,7 @@ macro_rules! dac_input_helper { } fn setup(&self, comp: &$COMP) { - comp.csr().modify(|_, w| unsafe { w.inmsel().bits($bits) }) + comp.csr().modify(|_, w| unsafe { w.inmsel().bits($bits) }); } } }; @@ -541,11 +541,11 @@ type Comparators = (COMP1, COMP2, COMP3, COMP4, COMP5, COMP6, COMP7); /// Enables the comparator peripheral, and splits the [`COMP`] into independent [`COMP1`] and [`COMP2`] pub fn split(_comp: COMP, rcc: &mut Rcc) -> Comparators { // Enable COMP, SYSCFG, VREFBUF clocks - rcc.rb.apb2enr.modify(|_, w| w.syscfgen().set_bit()); + rcc.rb.apb2enr().modify(|_, w| w.syscfgen().set_bit()); // Reset COMP, SYSCFG, VREFBUF - rcc.rb.apb2rstr.modify(|_, w| w.syscfgrst().set_bit()); - rcc.rb.apb2rstr.modify(|_, w| w.syscfgrst().clear_bit()); + rcc.rb.apb2rstr().modify(|_, w| w.syscfgrst().set_bit()); + rcc.rb.apb2rstr().modify(|_, w| w.syscfgrst().clear_bit()); ( COMP1 { _rb: PhantomData }, diff --git a/src/cordic.rs b/src/cordic.rs index 05f7c0e2..eb095109 100644 --- a/src/cordic.rs +++ b/src/cordic.rs @@ -15,7 +15,7 @@ //! let mut cordic = dp //! .CORDIC //! .constrain(&mut rcc) -//! .freeze::(); // 16 bit arguments, 32 bit results, compute sine and cosine, 60 iterations +//! .freeze::(); // 16 bit arguments, 32 bit results, 60 iterations, compute sine and cosine //! //! // static operation (zero overhead) //! @@ -38,41 +38,65 @@ //! } //! ``` -use crate::{rcc::Rcc, stm32::CORDIC}; +use crate::{ + rcc::Rcc, + {stm32::cordic::csr, stm32::CORDIC}, +}; use core::marker::PhantomData; -/// Extension trait for constraining the CORDIC peripheral. +/// Extension trait for constraining the Cordic peripheral. pub trait Ext { - /// Constrain the CORDIC peripheral. + /// Constrain the Cordic peripheral. fn constrain(self, rcc: &mut Rcc) -> CordicReset; } impl Ext for CORDIC { #[inline] fn constrain(self, rcc: &mut Rcc) -> CordicReset { - rcc.rb.ahb1enr.modify(|_, w| w.cordicen().set_bit()); + rcc.rb.ahb1enr().modify(|_, w| w.cordicen().set_bit()); - // SAFETY: the resource is assumed to be - // in the "reset" configuration. - unsafe { Cordic::wrap(self) } + // SAFETY: we assume the resource is already + // in a reset state + // BONUS: this line enforces that the + // abstraction is of zero-size + unsafe { core::mem::transmute(()) } } } /// Traits and structures related to data types. pub mod types { + use super::csr; use fixed::traits::Fixed; pub use fixed::types::{I1F15, I1F31}; + pub(crate) mod sealed { + use super::Ext; + + /// Trait for tags to represent Cordic argument or result data. + pub trait Tag { + /// Internal fixed point representation. + type Repr: Ext; + } + } + /// q1.15 fixed point number. pub struct Q15; /// q1.31 fixed point number. pub struct Q31; + impl sealed::Tag for Q15 { + type Repr = I1F15; + } + + impl sealed::Tag for Q31 { + type Repr = I1F31; + } + /// Extension trait for fixed point types. pub trait Ext: Fixed { - /// Type-state representing this type. - type Repr: DataType; + /// Tag representing this type. + type Tag: sealed::Tag; /// Convert to bits of the register width, fn to_register(self) -> u32; @@ -81,58 +105,48 @@ pub mod types { } impl Ext for I1F15 { - type Repr = Q15; + type Tag = Q15; + #[inline] fn to_register(self) -> u32 { self.to_bits() as u16 as u32 } + + #[inline] fn from_register(bits: u32) -> Self { Self::from_bits(bits as u16 as i16) } } impl Ext for I1F31 { - type Repr = Q31; + type Tag = Q31; + #[inline] fn to_register(self) -> u32 { self.to_bits() as u32 } + #[inline] fn from_register(bits: u32) -> Self { Self::from_bits(bits as i32) } } - /// Trait for newtypes to represent CORDIC argument or result data. - pub trait DataType { - /// Internal fixed point representation. - type Inner: Ext; - } - - impl DataType for Q15 { - type Inner = I1F15; - } - - impl DataType for Q31 { - type Inner = I1F31; - } - /// Traits and structures related to argument type-states. - pub mod arg { - pub(crate) type Raw = crate::stm32::cordic::csr::ARGSIZE_A; + pub(crate) mod arg { + use super::{csr, sealed::Tag}; + + pub type Raw = csr::ARGSIZE; /// Trait for argument type-states. - pub(crate) trait State: super::DataType { + pub trait State: Tag { /// Raw representation of the configuration /// in the form of a bitfield variant. const RAW: Raw; /// Configure the resource to be represented /// by this type-state. - #[inline] - fn set(w: crate::stm32::cordic::csr::ARGSIZE_W) { - w.variant(Self::RAW); - } + fn set(w: csr::ARGSIZE_W) -> Self; } macro_rules! impls { @@ -140,6 +154,13 @@ pub mod types { $( impl State for $NAME { const RAW: Raw = Raw::$RAW; + + #[inline] + fn set(w: csr::ARGSIZE_W) -> Self { + w.variant(Self::RAW); + + Self + } } )+ }; @@ -152,21 +173,20 @@ pub mod types { } /// Traits and structures related to result type-states. - pub mod res { - pub(crate) type Raw = crate::stm32::cordic::csr::RESSIZE_A; + pub(crate) mod res { + use super::{csr, sealed::Tag}; + + pub type Raw = csr::RESSIZE; /// Trait for argument type-states. - pub(crate) trait State: super::DataType { + pub trait State: Tag { /// Raw representation of the configuration /// in the form of a bitfield variant. const RAW: Raw; /// Configure the resource to be represented /// by this type-state. - #[inline] - fn set(w: crate::stm32::cordic::csr::RESSIZE_W) { - w.variant(Self::RAW); - } + fn set(w: csr::RESSIZE_W) -> Self; } macro_rules! impls { @@ -174,6 +194,13 @@ pub mod types { $( impl State for $NAME { const RAW: Raw = Raw::$RAW; + + #[inline] + fn set(w: csr::RESSIZE_W) -> Self { + w.variant(Self::RAW); + + Self + } } )+ }; @@ -186,221 +213,344 @@ pub mod types { } } -/// Traits and structures related to function type-states. -pub mod func { - use super::*; - - /// For internal use. A means of indirectly specifying a signature property - /// based solely on the number of elements. - mod data_count { - use super::types; +/// Traits and structures related to data counts (argument or result). +pub(crate) mod reg_count { + use super::{csr, op::data_count, types, PhantomData}; - pub enum Count { - One, - Two, - } + pub struct NReg + where + T: types::sealed::Tag, + Count: data_count::Property, + { + _t: PhantomData, + _count: PhantomData, + } - /// One (primary) function argument/result. - pub struct One; - /// Two (primary and secondary) function arguments/results. - pub struct Two; + pub mod arg { + use super::{csr, data_count, types, NReg, PhantomData}; - pub trait Property - where - T: types::DataType, - { - type Signature: super::signature::Property; + type Raw = csr::NARGS; - const COUNT: Count; + pub(crate) trait State { + fn set(w: csr::NARGS_W) -> Self; } - impl Property for One + impl State for NReg where - T: types::DataType, + Arg: types::arg::State, + Count: data_count::Property, { - type Signature = T::Inner; + #[inline] + fn set(w: csr::NARGS_W) -> Self { + w.variant( + const { + match (Arg::RAW, Count::COUNT) { + (types::arg::Raw::Bits32, data_count::Count::Two) => Raw::Num2, + (_, _) => Raw::Num1, + } + }, + ); + + Self { + _t: PhantomData, + _count: PhantomData, + } + } + } + } - const COUNT: Count = Count::One; + pub mod res { + use super::{csr, data_count, types, NReg, PhantomData}; + + type Raw = csr::NRES; + + pub(crate) trait State { + fn set(w: csr::NRES_W) -> Self; } - impl Property for Two + impl State for NReg where - T: types::DataType, + Res: types::res::State, + Count: data_count::Property, { - type Signature = (T::Inner, T::Inner); - - const COUNT: Count = Count::Two; + #[inline] + fn set(w: csr::NRES_W) -> Self { + w.variant( + const { + match (Res::RAW, Count::COUNT) { + (types::res::Raw::Bits32, data_count::Count::Two) => Raw::Num2, + (_, _) => Raw::Num1, + } + }, + ); + + Self { + _t: PhantomData, + _count: PhantomData, + } + } } } +} - /// Traits and structures related to data counts (argument or result). - pub(crate) mod reg_count { - use super::{super::types, data_count, PhantomData}; +/// Traits and structures related to function scale type-states. +pub mod scale { + use super::csr; - pub struct NReg - where - T: types::DataType, - Count: data_count::Property, - { - _t: PhantomData, - _count: PhantomData, - } + pub(crate) type Raw = u8; - pub mod arg { - use super::{data_count, types, NReg}; + /// Trait for function scale type-states. + pub(crate) trait State { + /// Raw representation of the configuration + /// in the form of a bitfield variant. + const RAW: Raw; - type Raw = crate::stm32::cordic::csr::NARGS_A; + /// Configure the resource to be represented + /// by this type-state. + fn set(w: csr::SCALE_W) -> Self; + } - pub(crate) trait State { - fn set(w: crate::stm32::cordic::csr::NARGS_W); - } + /// Scale of 0. + pub struct N0; + /// Scale of 1. + pub struct N1; + /// Scale of 2. + pub struct N2; + /// Scale of 3. + pub struct N3; + /// Scale of 4. + pub struct N4; + /// Scale of 5. + pub struct N5; + /// Scale of 6. + pub struct N6; + /// Scale of 7. + pub struct N7; - impl State for NReg - where - Arg: types::arg::State, - Count: data_count::Property, - { - fn set(w: crate::stm32::cordic::csr::NARGS_W) { - w.variant( - const { - match (Arg::RAW, Count::COUNT) { - (types::arg::Raw::Bits32, data_count::Count::Two) => Raw::Num2, - (_, _) => Raw::Num1, - } - }, - ); + macro_rules! impls { + ( $( ($NAME:ident, $BITS:expr) $(,)? )+ ) => { + $( + impl State for $NAME { + const RAW: u8 = $BITS; + + #[inline] + fn set(w: csr::SCALE_W) -> Self { + // SAFETY: all bits are valid + unsafe { w.bits(::RAW) }; + + Self + } } - } - } + )+ + }; + } - pub mod res { - use super::{data_count, types, NReg}; + impls! { + (N0, 0), + (N1, 1), + (N2, 2), + (N3, 3), + (N4, 4), + (N5, 5), + (N6, 6), + (N7, 7), + } +} - type Raw = crate::stm32::cordic::csr::NRES_A; +/// Traits and structures related to precision type-states. +pub mod prec { + use super::csr; - pub(crate) trait State { - fn set(w: crate::stm32::cordic::csr::NRES_W); - } + /// Trait for precision type-states. + pub(crate) trait State { + /// Bit representation of the precision. + const BITS: u8; - impl State for NReg - where - Res: types::res::State, - Count: data_count::Property, - { - fn set(w: crate::stm32::cordic::csr::NRES_W) { - w.variant( - const { - match (Res::RAW, Count::COUNT) { - (types::res::Raw::Bits32, data_count::Count::Two) => Raw::Num2, - (_, _) => Raw::Num1, - } - }, - ); + /// Configure the resource to be represented + /// by this type-state. + fn set(w: csr::PRECISION_W) -> Self; + } + + /// 4 iterations. + pub struct P4; + /// 8 iterations. + pub struct P8; + /// 12 iterations. + pub struct P12; + /// 16 iterations. + pub struct P16; + /// 20 iterations. + pub struct P20; + /// 24 iterations. + pub struct P24; + /// 28 iterations. + pub struct P28; + /// 32 iterations. + pub struct P32; + /// 36 iterations. + pub struct P36; + /// 40 iterations. + pub struct P40; + /// 44 iterations. + pub struct P44; + /// 48 iterations. + pub struct P48; + /// 52 iterations. + pub struct P52; + /// 56 iterations. + pub struct P56; + /// 60 iterations. + pub struct P60; + + macro_rules! impls { + ( $( ($NAME:ident, $BITS:expr) $(,)? )+ ) => { + $( + impl State for $NAME { + const BITS: u8 = $BITS; + + #[inline] + fn set(w: csr::PRECISION_W) -> Self { + // SAFETY: reliant on valid type-state + // implementations. + unsafe { w.bits(::BITS) }; + + Self + } } - } - } + )+ + }; } - /// Traits and structures related to function scale type-states. - pub mod scale { - pub(crate) type Raw = u8; + impls! { + (P4, 1), + (P8, 2), + (P12, 3), + (P16, 4), + (P20, 5), + (P24, 6), + (P28, 7), + (P32, 8), + (P36, 9), + (P40, 10), + (P44, 11), + (P48, 12), + (P52, 13), + (P56, 14), + (P60, 15), + } +} - /// Trait for function scale type-states. - pub(crate) trait State { - /// Raw representation of the configuration - /// in the form of a bitfield variant. - const RAW: Raw; +/// Traits and structures related to function type-states. +pub(crate) mod func { + use super::csr; - /// Configure the resource to be represented - /// by this type-state. - #[inline] - fn set(w: crate::stm32::cordic::csr::SCALE_W) { - w.bits(::RAW); - } - } + pub type Raw = csr::FUNC; - /// Scale of 0. - pub struct N0; - /// Scale of 1. - pub struct N1; - /// Scale of 2. - pub struct N2; - /// Scale of 3. - pub struct N3; - /// Scale of 4. - pub struct N4; - /// Scale of 5. - pub struct N5; - /// Scale of 6. - pub struct N6; - /// Scale of 7. - pub struct N7; + /// Trait for function type-states. + pub trait State { + /// Raw representation of the function. + const RAW: Raw; - macro_rules! impls { - ( $( ($NAME:ident, $BITS:expr) $(,)? )+ ) => { - $( - impl State for $NAME { - const RAW: u8 = $BITS; + /// Configure the resource to be represented + /// by this type-state. + fn set(w: csr::FUNC_W) -> Self; + } + + pub struct Cos; + pub struct Sin; + pub struct ATan2; + pub struct Magnitude; + pub struct ATan; + pub struct CosH; + pub struct SinH; + pub struct ATanH; + pub struct Ln; + pub struct Sqrt; + + macro_rules! impls { + ( $( ($NAME:ident, $RAW:ident) $(,)? )+ ) => { + $( + impl State for $NAME { + const RAW: Raw = Raw::$RAW; + + #[inline] + fn set(w: csr::FUNC_W) -> Self { + w.variant(Self::RAW); + + Self } - )+ - }; - } + } + )+ + }; + } - impls! { - (N0, 0), - (N1, 1), - (N2, 2), - (N3, 3), - (N4, 4), - (N5, 5), - (N6, 6), - (N7, 7), - } + impls! { + (Cos, Cosine), + (Sin, Sine), + (ATan2, Phase), + (Magnitude, Modulus), + (ATan, Arctangent), + (CosH, HyperbolicCosine), + (SinH, HyperbolicSine), + (ATanH, Arctanh), + (Ln, NaturalLogarithm), + (Sqrt, SquareRoot), } +} + +/// Traits and structures related to operating the Cordic. +pub mod op { + use core::marker::PhantomData; - /// Traits and structures related to the function signature. - pub mod signature { - use super::{data_count, reg_count, types}; + use super::{func, prec, reg_count, scale, types, Cordic}; + + /// Traits and structures related to the operation signature. + pub(crate) mod signature { + use super::types; use types::arg::State as _; use types::res::State as _; - type WData = crate::stm32g4::Reg; - type RData = crate::stm32g4::Reg; + type WData = crate::stm32::cordic::WDATA; + type RData = crate::stm32::cordic::RDATA; - /// The signature is a property of the function type-state. + /// The signature is a property of the operation type-state. pub trait Property where T: types::Ext, { - /// Number of register operations required. - type NReg; - /// Write arguments to the argument register. - fn write(self, reg: &WData) + /// + /// # Safety: + /// Cordic must be configured to expect the + /// correct number of register writes. + unsafe fn write(self, reg: &WData) where - T::Repr: types::arg::State; + T::Tag: types::arg::State; /// Read results from the result register. - fn read(reg: &RData) -> Self + /// + /// # Safety: + /// Cordic must be configured to expect the + /// correct number of register reades. + unsafe fn read(reg: &RData) -> Self where - T::Repr: types::res::State; + T::Tag: types::res::State; } impl Property for T where T: types::Ext, { - type NReg = reg_count::NReg; - - fn write(self, reg: &WData) + #[inline] + unsafe fn write(self, reg: &WData) where - T::Repr: types::arg::State, + T::Tag: types::arg::State, { - let data = match const { T::Repr::RAW } { + let data = match const { T::Tag::RAW } { types::arg::Raw::Bits16 => { // $RM0440 17.4.2 // since we are only using the lower half of the register, - // the CORDIC **will** read the upper half if the function + // the Cordic **will** read the upper half if the function // accepts two arguments, so we fill it with +1 as per the // stated default. self.to_register() | (0x7fff << 16) @@ -408,12 +558,14 @@ pub mod func { types::arg::Raw::Bits32 => self.to_register(), }; - reg.write(|w| w.arg().bits(data)); + // SAFETY: all bits are valid + reg.write(|w| unsafe { w.arg().bits(data) }); } - fn read(reg: &RData) -> Self + #[inline] + unsafe fn read(reg: &RData) -> Self where - T::Repr: types::res::State, + T::Tag: types::res::State, { T::from_register(reg.read().res().bits()) } @@ -423,34 +575,37 @@ pub mod func { where T: types::Ext, { - type NReg = reg_count::NReg; - - fn write(self, reg: &WData) + #[inline] + unsafe fn write(self, reg: &WData) where - T::Repr: types::arg::State, + T::Tag: types::arg::State, { let (primary, secondary) = self; - match const { T::Repr::RAW } { + match const { T::Tag::RAW } { types::arg::Raw::Bits16 => { // $RM0440 17.4.2 - reg.write(|w| { + // SAFETY: all bits are valid + reg.write(|w| unsafe { w.arg() .bits(primary.to_register() | (secondary.to_register() << 16)) }); } types::arg::Raw::Bits32 => { - reg.write(|w| w.arg().bits(primary.to_register())); - reg.write(|w| w.arg().bits(secondary.to_register())); + // SAFETY: all bits are valid + reg.write(|w| unsafe { w.arg().bits(primary.to_register()) }); + // SAFETY: all bits are valid + reg.write(|w| unsafe { w.arg().bits(secondary.to_register()) }); } }; } - fn read(reg: &RData) -> Self + #[inline] + unsafe fn read(reg: &RData) -> Self where - T::Repr: types::res::State, + T::Tag: types::res::State, { - match const { T::Repr::RAW } { + match const { T::Tag::RAW } { types::res::Raw::Bits16 => { let data = reg.read().res().bits(); @@ -469,69 +624,131 @@ pub mod func { } } - pub(crate) type Raw = crate::stm32::cordic::csr::FUNC_A; + /// For internal use. A means of indirectly specifying a signature property + /// based solely on the number of elements. + pub(crate) mod data_count { + use super::types; - /// Trait for function type-states. - pub trait State { - /// Raw representation of the function. - const RAW: Raw; + pub enum Count { + One, + Two, + } - /// Configure the resource to be represented - /// by this type-state. - #[inline] - fn set(w: crate::stm32::cordic::csr::FUNC_W) { - w.variant(Self::RAW); + pub struct One; + pub struct Two; + + pub trait Property + where + T: types::sealed::Tag, + { + type Signature: super::signature::Property; + + const COUNT: Count; + } + + impl Property for One + where + T: types::sealed::Tag, + { + type Signature = T::Repr; + + const COUNT: Count = Count::One; + } + + impl Property for Two + where + T: types::sealed::Tag, + { + type Signature = (T::Repr, T::Repr); + + const COUNT: Count = Count::Two; + } + } + + pub(crate) mod sealed { + use super::types; + + /// An operation is a feature of the Cordic. + /// + /// Operations are permutations of: + /// - nargs + /// - nres + /// - scale + /// - func + pub trait Feature { + /// The required argument register writes. + type NArgs + where + Arg: types::arg::State + types::sealed::Tag; + /// The required result register reads. + type NRes + where + Res: types::res::State + types::sealed::Tag; + /// The scale to be applied. + type Scale; + /// The function to evaluate. + type Func; + + /// The number of arguments required. + type ArgCount; + /// The number of results produced. + type ResCount; } } - /// Define specific combinations - /// of states and properties for each function. - pub trait Feature: State + /// An operation of the Cordic. + /// + /// Enables writing and reading values + /// to and from the Cordic. + #[allow(unused)] + struct Operation<'a, Arg, Res, Op> where Arg: types::arg::State, Res: types::res::State, + Op: sealed::Feature, { - /// The number of arguments required. - type Arguments: signature::Property; - /// The number of arguments produced. - type Results: signature::Property; - - /// The operation to perform. - type Op: State; - /// The scale to be applied. - type Scale: scale::State; - /// The required argument register writes. - type NArgs: reg_count::arg::State; - /// The required result register reads. - type NRes: reg_count::res::State; - } - - impl Cordic + nargs: &'a Op::NArgs, + nres: &'a Op::NRes, + scale: &'a Op::Scale, + func: &'a Op::Func, + } + + impl<'a, Arg, Res, Op> Operation<'a, Arg, Res, Op> where Arg: types::arg::State, Res: types::res::State, - Func: Feature, - Prec: prec::State, - Func::Arguments: signature::Property, - Func::Results: signature::Property, + Op: sealed::Feature, { - /// Start the configured operation. - pub fn start(&mut self, args: Func::Arguments) { - use signature::Property as _; - - args.write(&self.rb.wdata); + /// Write arguments to the argument register. + #[inline] + fn write(&mut self, args: Args, reg: &crate::stm32::cordic::WDATA) + where + Arg: types::sealed::Tag, + Args: signature::Property, + Op::ArgCount: data_count::Property, + { + // SAFETY: Cordic is necessarily configured properly if + // an instance of `Operation` exists. + unsafe { + signature::Property::::write(args, reg); + } } - /// Get the result of an operation. - pub fn result(&mut self) -> Func::Results { - use signature::Property as _; - - Func::Results::read(&self.rb.rdata) + /// Read results from the result register. + #[inline] + fn read( + &mut self, + reg: &crate::stm32::cordic::RDATA, + ) -> >::Signature + where + Op::ResCount: data_count::Property, + { + // SAFETY: Cordic is necessarily configured properly if + // an instance of `Operation` exists. + unsafe { signature::Property::::read(reg) } } } - // function types with argument count encoded - /// Cosine of an angle theta divided by pi. pub struct Cos; /// Sine of an angle theta divided by pi. @@ -578,50 +795,42 @@ pub mod func { } macro_rules! impls { - ( $( ($NAME:ident < $SCALE:ident >, $RAW:ident, $NARGS:ident, $NRES:ident, start( $($START_PARAM:ident),+ )) $(,)?)+ ) => { + ( $( ($TAG:ident<$SCALE:ident>, $NARGS:ident, $NRES:ident, $FUNC:ident) $(,)?)+ ) => { $( - impl State for $NAME { - const RAW: Raw = Raw::$RAW; - } - - impl Feature for $NAME - where - Arg: types::arg::State, - Res: types::res::State, + impl sealed::Feature for $TAG { - type Arguments = >::Signature; - type Results = >::Signature; - - type Op = Self; + type NArgs = reg_count::NReg + where + Arg: types::arg::State + types::sealed::Tag; + type NRes = reg_count::NReg + where + Res: types::res::State + types::sealed::Tag; type Scale = scale::$SCALE; - type NArgs = >::NReg; - type NRes = >::NReg; + type Func = func::$FUNC; + + type ArgCount = data_count::$NARGS; + type ResCount = data_count::$NRES; } )+ }; } macro_rules! impls_multi_scale { - // root / config (almost identical to single scale) - ( $( ($NAME:ident < $( $SCALE:ident $(,)? )+ >, $RAW:ident, $NARGS:ident, $NRES:ident, start $START_PARAM:tt ) $(,)?)+ ) => { + ( $( ($TAG:ident<$($SCALE:ident $(,)?)+>, $NARGS:ident, $NRES:ident, $FUNC:ident) $(,)?)+ ) => { $( $( - impl State for $NAME { - const RAW: Raw = Raw::$RAW; - } - - impl Feature for $NAME - where - Arg: types::arg::State, - Res: types::res::State, - { - type Arguments = >::Signature; - type Results = >::Signature; - - type Op = Self; + impl sealed::Feature for $TAG { + type NArgs = reg_count::NReg + where + Arg: types::arg::State + types::sealed::Tag; + type NRes = reg_count::NReg + where + Res: types::res::State + types::sealed::Tag; type Scale = scale::$SCALE; - type NArgs = >::NReg; - type NRes = >::NReg; + type Func = func::$FUNC; + + type ArgCount = data_count::$NARGS; + type ResCount = data_count::$NRES; } )+ )+ @@ -629,194 +838,197 @@ pub mod func { } impls! { - (Cos, Cosine, One, One, start(angle)), - (Sin, Sine, One, One, start(angle)), - (SinCos, Sine, One, Two, start(angle)), - (CosM, Cosine, Two, One, start(angle, modulus)), - (SinM, Sine, Two, One, start(angle, modulus)), - (SinCosM, Sine, Two, Two, start(angle, modulus)), - (ATan2, Phase, Two, One, start(x, y)), - (Magnitude, Modulus, Two, One, start(x, y)), - (ATan2Magnitude, Phase, Two, Two, start(x, y)), - (CosH, HyperbolicCosine, One, One, start(x)), - (SinH, HyperbolicSine, One, One, start(x)), - (SinHCosH, HyperbolicSine, One, Two, start(x)), - (ATanH, Arctanh, One, One, start(x)), + (Cos, One, One, Cos), + (Sin, One, One, Sin), + (SinCos, One, Two, Sin), + (CosM, Two, One, Cos), + (SinM, Two, One, Sin), + (SinCosM, Two, Two, Sin), + (ATan2, Two, One, ATan2), + (Magnitude, Two, One, Magnitude), + (ATan2Magnitude, Two, Two, ATan2), + (CosH, One, One, CosH), + (SinH, One, One, SinH), + (SinHCosH, One, Two, SinH), + (ATanH, One, One, ATan), } impls_multi_scale! { - (ATan, Arctangent, One, One, start(x)), - (Ln, NaturalLogarithm, One, One, start(x)), - (Sqrt, SquareRoot, One, One, start(x)), + (ATan, One, One, ATan), + (Ln, One, One, Ln), + (Sqrt, One, One, Sqrt), + } + + impl Cordic + where + Arg: types::arg::State, + Res: types::res::State, + Prec: prec::State, + Op: sealed::Feature, + { + /// Start the configured operation. + #[inline] + pub fn start(&mut self, args: >::Signature) + where + Op::ArgCount: data_count::Property, + { + let config = &self.config; + let mut op = Operation:: { + nargs: &config.nargs, + nres: &config.nres, + scale: &config.scale, + func: &config.func, + }; + + op.write(args, self.rb.wdata()); + } + + /// Get the result of an operation. + #[inline] + pub fn result(&mut self) -> >::Signature + where + Op::ResCount: data_count::Property, + { + let config = &self.config; + let mut op = Operation:: { + nargs: &config.nargs, + nres: &config.nres, + scale: &config.scale, + func: &config.func, + }; + + op.read(self.rb.rdata()) + } } /// Traits and structures for dynamic function operation. pub mod dynamic { - use super::{prec, signature, types, Cordic, Feature}; + use super::{ + super::{prec, reg_count, Cordic}, + data_count, func, scale, + sealed::Feature, + types, Operation, + }; - /// Any function can be invoked with this type-state. + /// Any operation can be invoked with this type-state. pub struct Any; + impl Feature for Any { + type NArgs = () + where + Arg: types::arg::State + types::sealed::Tag; + type NRes = () + where + Res: types::res::State + types::sealed::Tag; + type Scale = (); + type Func = (); + + type ArgCount = (); + type ResCount = (); + } + /// A Cordic in dynamic mode. pub trait Mode where Arg: types::arg::State, Res: types::res::State, { - /// Run a function with provided arguments and get the result. + /// Run an operation with provided arguments and get the result. /// /// *Note: This employs the polling strategy. /// For less overhead, use static operations.* - fn run(&mut self, args: Func::Arguments) -> Func::Results + fn run( + &mut self, + args: >::Signature, + ) -> >::Signature where - Func: Feature; + Op: Feature, + Op::NArgs: reg_count::arg::State, + Op::NRes: reg_count::res::State, + Op::Scale: scale::State, + Op::Func: func::State, + Op::ArgCount: data_count::Property, + Op::ResCount: data_count::Property; } - impl Mode for Cordic + impl Mode for Cordic where Arg: types::arg::State, Res: types::res::State, Prec: prec::State, { - fn run(&mut self, args: Func::Arguments) -> Func::Results + #[inline] + fn run( + &mut self, + args: >::Signature, + ) -> >::Signature where - Func: Feature, + Op: Feature, + Op::NArgs: reg_count::arg::State, + Op::NRes: reg_count::res::State, + Op::Scale: scale::State, + Op::Func: func::State, + Op::ArgCount: data_count::Property, + Op::ResCount: data_count::Property, { - use signature::Property as _; - - self.apply_config::(); + use func::State as _; + use reg_count::{arg::State as _, res::State as _}; + use scale::State as _; + + let (nargs, nres, scale, func) = self.rb.csr().from_modify(|_, w| { + ( + Op::NArgs::set(w.nargs()), + Op::NRes::set(w.nres()), + Op::Scale::set(w.scale()), + Op::Func::set(w.func()), + ) + }); + + let mut op = Operation:: { + nargs: &nargs, + nres: &nres, + scale: &scale, + func: &func, + }; - args.write(&self.rb.wdata); - self.when_ready(|cordic| Func::Results::read(&cordic.rb.rdata)) + op.write(args, self.rb.wdata()); + self.when_ready(|cordic| op.read(cordic.rb.rdata())) } } } } -/// Traits and structures related to precision type-states. -pub mod prec { - /// Trait for precision type-states. - pub(crate) trait State { - /// Bit representation of the precision. - const BITS: u8; - - /// Configure the resource to be represented - /// by this type-state. - fn set(w: crate::stm32::cordic::csr::PRECISION_W); - } - - /// 4 iterations. - pub struct P4; - /// 8 iterations. - pub struct P8; - /// 12 iterations. - pub struct P12; - /// 16 iterations. - pub struct P16; - /// 20 iterations. - pub struct P20; - /// 24 iterations. - pub struct P24; - /// 28 iterations. - pub struct P28; - /// 32 iterations. - pub struct P32; - /// 36 iterations. - pub struct P36; - /// 40 iterations. - pub struct P40; - /// 44 iterations. - pub struct P44; - /// 48 iterations. - pub struct P48; - /// 52 iterations. - pub struct P52; - /// 56 iterations. - pub struct P56; - /// 60 iterations. - pub struct P60; - - macro_rules! impls { - ( $( ($NAME:ident, $BITS:expr) $(,)? )+ ) => { - $( - impl State for $NAME { - const BITS: u8 = $BITS; - - #[inline] - fn set(w: crate::stm32::cordic::csr::PRECISION_W) { - // SAFETY: reliant on valid type-state - // implementations. - unsafe { w.bits(::BITS) }; - } - } - )+ - }; - } - - impls! { - (P4, 1), - (P8, 2), - (P12, 3), - (P16, 4), - (P20, 5), - (P24, 6), - (P28, 7), - (P32, 8), - (P36, 9), - (P40, 10), - (P44, 11), - (P48, 12), - (P52, 13), - (P56, 14), - (P60, 15), - } +/// Configuration for the Cordic. +struct Config { + arg: Arg, + res: Res, + nargs: NArgs, + nres: NRes, + scale: Scale, + prec: Prec, + func: Func, } /// Cordic co-processor interface. -pub struct Cordic +pub struct Cordic where Arg: types::arg::State, Res: types::res::State, Prec: prec::State, + Op: op::sealed::Feature, { rb: CORDIC, - _arg_size: PhantomData, - _res_size: PhantomData, - _func: PhantomData, - _prec: PhantomData, + config: Config, Op::NRes, Op::Scale, Prec, Op::Func>, } // root impl -impl Cordic +impl Cordic where Arg: types::arg::State, Res: types::res::State, Prec: prec::State, + Op: op::sealed::Feature, { - fn apply_config(&mut self) - where - NewArg: types::arg::State, - NewRes: types::res::State, - NewFunc: func::Feature, - NewPrec: prec::State, - { - self.rb.csr.write(|w| { - use func::reg_count::arg::State as _; - use func::reg_count::res::State as _; - use func::scale::State as _; - - NewArg::set(w.argsize()); - NewRes::set(w.ressize()); - NewPrec::set(w.precision()); - NewFunc::set(w.func()); - NewFunc::NArgs::set(w.nargs()); - NewFunc::NRes::set(w.nres()); - NewFunc::Scale::set(w.scale()); - - w - }); - } - /// Configure the resource as dictated by the resulting /// type-states. The produced binding represents /// a frozen configuration, since it is represented @@ -826,26 +1038,43 @@ where /// /// *Note: The configuration is inferred from context because /// it is represented by generic type-states.* - pub fn freeze( - mut self, - ) -> Cordic + #[inline] + pub fn freeze(self) -> Cordic where NewArg: types::arg::State, NewRes: types::res::State, - NewFunc: func::Feature, NewPrec: prec::State, + NewOp: op::sealed::Feature, + NewOp::NArgs: reg_count::arg::State, + NewOp::NRes: reg_count::res::State, + NewOp::Scale: scale::State, + NewOp::Func: func::State, { - self.apply_config::(); + use func::State as _; + use reg_count::arg::State as _; + use reg_count::res::State as _; + use scale::State as _; + + let config = self.rb.csr().from_modify(|_, w| Config { + arg: NewArg::set(w.argsize()), + res: NewRes::set(w.ressize()), + nargs: NewOp::NArgs::set(w.nargs()), + nres: NewOp::NRes::set(w.nres()), + scale: NewOp::Scale::set(w.scale()), + prec: NewPrec::set(w.precision()), + func: NewOp::Func::set(w.func()), + }); - // SAFETY: the resource has been configured - // to represent the new type-states. - unsafe { Cordic::wrap(self.rb) } + Cordic { + rb: self.rb, + config, + } } /// Determine whether a result is pending or not. #[inline] pub fn is_ready(&self) -> bool { - self.rb.csr.read().rrdy().bit_is_set() + self.rb.csr().read().rrdy().bit_is_set() } /// Dispatch an operation once a result is @@ -868,93 +1097,83 @@ where /// Convert into a Cordic interface that supports /// runtime function selection. #[inline] - pub fn into_dynamic(self) -> Cordic { - unsafe { Cordic::wrap(self.rb) } - } - - /// Wrap the resource as a noop. - /// - /// # Safety - /// - /// If the resource configuration and - /// type-states are incongruent, the invariance - /// is broken and actions may exhibit - /// undefined behavior. - pub const unsafe fn wrap(rb: CORDIC) -> Self { - Self { - rb, - _arg_size: PhantomData, - _res_size: PhantomData, - _func: PhantomData, - _prec: PhantomData, + pub fn into_dynamic(self) -> Cordic { + Cordic { + rb: self.rb, + config: Config { + arg: self.config.arg, + res: self.config.res, + nargs: (), + nres: (), + scale: (), + prec: self.config.prec, + func: (), + }, } } } /// $RM0440 17.4.1 -pub type CordicReset = Cordic; +pub type CordicReset = Cordic; -// reset -impl Cordic +impl Cordic where Arg: types::arg::State, Res: types::res::State, - Func: func::Feature, Prec: prec::State, + Op: op::sealed::Feature, { - /// Configure the resource back to the "reset" - /// state. #[inline] - fn reset(self) -> CordicReset { + fn into_reset(self) -> CordicReset { self.freeze() } } // listen -impl Cordic +impl Cordic where Arg: types::arg::State, Res: types::res::State, - Func: func::Feature, Prec: prec::State, + Op: op::sealed::Feature, { /// Enable the result ready interrupt. #[inline] pub fn listen(&mut self) { - self.rb.csr.modify(|_, w| w.ien().set_bit()); + self.rb.csr().modify(|_, w| w.ien().set_bit()); } /// Disable the result ready interrupt. #[inline] pub fn unlisten(&mut self) { - self.rb.csr.modify(|_, w| w.ien().clear_bit()); + self.rb.csr().modify(|_, w| w.ien().clear_bit()); } } // release -impl Cordic +impl Cordic where Arg: types::arg::State, Res: types::res::State, - Func: func::Feature, Prec: prec::State, + Op: op::sealed::Feature, { - /// Release the CORDIC resource binding as a noop. + /// Release the Cordic resource binding as a noop. /// /// # Safety /// - /// The CORDIC peripheral is not reset. + /// The Cordic peripheral is not reset. #[inline] pub unsafe fn release(self) -> CORDIC { self.rb } - /// Release the CORDIC resource binding after reset. + /// Release the Cordic resource binding after reset. #[inline] pub fn release_and_reset(self, rcc: &mut Rcc) -> CORDIC { - let reset = self.reset(); + let reset = self.into_reset(); - rcc.rb.ahb1enr.modify(|_, w| w.cordicen().clear_bit()); + rcc.rb.ahb1enr().modify(|_, w| w.cordicen().clear_bit()); // SAFETY: the resource has been reset unsafe { reset.release() } diff --git a/src/dac.rs b/src/dac.rs index 109374c0..991e8467 100644 --- a/src/dac.rs +++ b/src/dac.rs @@ -179,7 +179,7 @@ macro_rules! dac_helper { $trim:ident, $mode:ident, $dhrx:ident, - $dac_dor:ident, + $dor:ident, $daccxdhr:ident, $wave:ident, $mamp:ident, @@ -193,8 +193,8 @@ macro_rules! dac_helper { pub fn enable(self) -> $CX { let dac = unsafe { &(*<$DAC>::ptr()) }; - dac.dac_mcr.modify(|_, w| unsafe { w.$mode().bits(MODE_BITS) }); - dac.dac_cr.modify(|_, w| w.$en().set_bit()); + dac.mcr().modify(|_, w| unsafe { w.$mode().bits(MODE_BITS) }); + dac.cr().modify(|_, w| w.$en().set_bit()); $CX { _enabled: PhantomData, @@ -204,8 +204,8 @@ macro_rules! dac_helper { pub fn enable_generator(self, config: GeneratorConfig) -> $CX { let dac = unsafe { &(*<$DAC>::ptr()) }; - dac.dac_mcr.modify(|_, w| unsafe { w.$mode().bits(MODE_BITS) }); - dac.dac_cr.modify(|_, w| unsafe { + dac.mcr().modify(|_, w| unsafe { w.$mode().bits(MODE_BITS) }); + dac.cr().modify(|_, w| unsafe { w.$wave().bits(config.mode); w.$ten().set_bit(); w.$mamp().bits(config.amp); @@ -235,19 +235,19 @@ macro_rules! dac_helper { T: DelayUs, { let dac = unsafe { &(*<$DAC>::ptr()) }; - dac.dac_cr.modify(|_, w| w.$en().clear_bit()); - dac.dac_mcr.modify(|_, w| unsafe { w.$mode().bits(0) }); - dac.dac_cr.modify(|_, w| w.$cen().set_bit()); + dac.cr().modify(|_, w| w.$en().clear_bit()); + dac.mcr().modify(|_, w| unsafe { w.$mode().bits(0) }); + dac.cr().modify(|_, w| w.$cen().set_bit()); let mut trim = 0; while true { - dac.dac_ccr.modify(|_, w| unsafe { w.$trim().bits(trim) }); + dac.ccr().modify(|_, w| unsafe { w.$trim().bits(trim) }); delay.delay_us(64_u32); - if dac.dac_sr.read().$cal_flag().bit() { + if dac.sr().read().$cal_flag().bit() { break; } trim += 1; } - dac.dac_cr.modify(|_, w| w.$cen().clear_bit()); + dac.cr().modify(|_, w| w.$cen().clear_bit()); $CX { _enabled: PhantomData, @@ -257,7 +257,7 @@ macro_rules! dac_helper { /// Disable the DAC channel pub fn disable(self) -> $CX { let dac = unsafe { &(*<$DAC>::ptr()) }; - dac.dac_cr.modify(|_, w| unsafe { + dac.cr().modify(|_, w| unsafe { w.$en().clear_bit().$wave().bits(0).$ten().clear_bit() }); @@ -272,12 +272,12 @@ macro_rules! dac_helper { impl DacOut for $CX { fn set_value(&mut self, val: u16) { let dac = unsafe { &(*<$DAC>::ptr()) }; - dac.$dhrx.write(|w| unsafe { w.bits(val as u32) }); + dac.$dhrx().write(|w| unsafe { w.bits(val as u32) }); } fn get_value(&mut self) -> u16 { let dac = unsafe { &(*<$DAC>::ptr()) }; - dac.$dac_dor.read().bits() as u16 + dac.$dor().read().bits() as u16 } } @@ -285,7 +285,7 @@ macro_rules! dac_helper { impl $CX { pub fn trigger(&mut self) { let dac = unsafe { &(*<$DAC>::ptr()) }; - dac.dac_swtrgr.write(|w| { w.$swtrig().set_bit() }); + dac.swtrgr().write(|w| { w.$swtrig().set_bit() }); } } )+ @@ -300,8 +300,8 @@ macro_rules! dac { cal_flag1, otrim1, mode1, - dac_dhr12r1, - dac_dor1, + dhr12r1, + dor1, dacc1dhr, wave1, mamp1, @@ -314,8 +314,8 @@ macro_rules! dac { cal_flag2, otrim2, mode2, - dac_dhr12r2, - dac_dor2, + dhr12r2, + dor2, dacc2dhr, wave2, mamp2, diff --git a/src/dma/stream.rs b/src/dma/stream.rs index 18dc4085..76cf60c6 100644 --- a/src/dma/stream.rs +++ b/src/dma/stream.rs @@ -131,13 +131,13 @@ pub trait DMAExt { impl DMAExt for DMA1 { fn split(self, rcc: &Rcc) -> StreamsTuple { // Enable DMAMux is not yet enabled - if !rcc.rb.ahb1enr.read().dmamuxen().bit_is_set() { + if !rcc.rb.ahb1enr().read().dmamuxen().bit_is_set() { // Enable peripheral - rcc.rb.ahb1enr.modify(|_, w| w.dmamuxen().set_bit()); + rcc.rb.ahb1enr().modify(|_, w| w.dmamuxen().set_bit()); } // Enable peripheral - rcc.rb.ahb1enr.modify(|_, w| w.dma1en().set_bit()); + rcc.rb.ahb1enr().modify(|_, w| w.dma1en().set_bit()); StreamsTuple::new(self) } @@ -146,13 +146,13 @@ impl DMAExt for DMA1 { impl DMAExt for DMA2 { fn split(self, rcc: &Rcc) -> StreamsTuple { // Enable DMAMux is not yet enabled - if !rcc.rb.ahb1enr.read().dmamuxen().bit_is_set() { + if !rcc.rb.ahb1enr().read().dmamuxen().bit_is_set() { // Enable peripheral - rcc.rb.ahb1enr.modify(|_, w| w.dmamuxen().set_bit()); + rcc.rb.ahb1enr().modify(|_, w| w.dmamuxen().set_bit()); } // Enable peripheral - rcc.rb.ahb1enr.modify(|_, w| w.dma2en().set_bit()); + rcc.rb.ahb1enr().modify(|_, w| w.dma2en().set_bit()); StreamsTuple::new(self) } @@ -181,11 +181,7 @@ impl StreamsTuple { // The implementation does the heavy lifting of mapping to the right fields on // the stream macro_rules! dma_stream { - ($(($name:ident, $number:expr, - regs => $ccr:ident, $cparX:ident, $cmarX:ident, $cndtrX:ident, - fields => $tcif:ident, $htif:ident, $teif:ident, $gif:ident, $tcisr:ident, $htisr:ident, $teisr:ident, $gisr:ident, - dmamux => $dma1_cXcr:ident, $dma2_cXcr:ident, ) - ),+$(,)*) => { + ($(($name:ident, $number:expr, $x:literal)),+$(,)*) => { $( impl Stream for $name { @@ -205,21 +201,23 @@ macro_rules! dma_stream { self.set_transfer_error_interrupt_enable( config.transfer_error_interrupt ); - } + } #[inline(always)] fn clear_interrupts(&mut self) { + let num = Self::NUMBER as u8; + //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 + dma.ifcr().write(|w| w + .ctcif(num).set_bit() //Clear transfer complete interrupt flag + .chtif(num).set_bit() //Clear half transfer interrupt flag + .cteif(num).set_bit() //Clear transfer error interrupt flag + .cgif(num).set_bit() //Clear global interrupt flag ); - let _ = dma.isr.read(); - let _ = dma.isr.read(); // Delay 2 peripheral clocks + let _ = dma.isr().read(); + let _ = dma.isr().read(); // Delay 2 peripheral clocks } #[inline(always)] @@ -227,7 +225,7 @@ macro_rules! dma_stream { //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()); + dma.ifcr().write(|w| w.ctcif(Self::NUMBER as u8).set_bit()); } #[inline(always)] @@ -235,8 +233,8 @@ macro_rules! dma_stream { self.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 + let _ = dma.isr().read(); + let _ = dma.isr().read(); // Delay 2 peripheral clocks } #[inline(always)] @@ -244,50 +242,50 @@ macro_rules! dma_stream { //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 + dma.ifcr().write(|w| w.ctcif(Self::NUMBER as u8).set_bit()); + let _ = dma.isr().read(); + let _ = dma.isr().read(); // Delay 2 peripheral clocks } #[inline(always)] fn 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() + dma.isr().read().tcif(Self::NUMBER as u8).bit_is_set() } #[inline(always)] fn get_transfer_error_flag() -> bool { //NOTE(unsafe) Atomic read with no side effects let dma = unsafe { &*I::ptr() }; - dma.isr.read().$teisr().bit_is_set() + dma.isr().read().tcif(Self::NUMBER as u8).bit_is_set() } #[inline(always)] unsafe fn enable(&mut self) { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dma = &*I::ptr(); - dma.$ccr.modify(|_, w| w.en().set_bit()); + let dma_ch = &unsafe { &*I::ptr() }.ch(Self::NUMBER); + dma_ch.cr().modify(|_, w| w.en().set_bit()); } #[inline(always)] fn is_enabled() -> bool { //NOTE(unsafe) Atomic read with no side effects - let dma = unsafe { &*I::ptr() }; - dma.$ccr.read().en().bit_is_set() + let dma_ch = &unsafe { &*I::ptr() }.ch(Self::NUMBER); + dma_ch.cr().read().en().bit_is_set() } fn disable(&mut self) { if Self::is_enabled() { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dma = unsafe { &*I::ptr() }; + let dma_ch = &unsafe { &*I::ptr() }.ch(Self::NUMBER); // Aborting an on-going transfer might cause interrupts to fire, disable // them let interrupts = Self::get_interrupts_enable(); self.disable_interrupts(); - dma.$ccr.modify(|_, w| w.en().clear_bit()); + dma_ch.cr().modify(|_, w| w.en().clear_bit()); while Self::is_enabled() {} self.clear_interrupts(); @@ -300,27 +298,22 @@ macro_rules! dma_stream { //NOTE(unsafe) We only access the registers that belongs to the StreamX let dmamux = unsafe { &*I::mux_ptr() }; unsafe { - if I::IS_DMA1 { - dmamux.$dma1_cXcr - .modify(|_, w| w.dmareq_id().bits(request_line)); - } else { - dmamux.$dma2_cXcr - .modify(|_, w| w.dmareq_id().bits(request_line)); - }; + dmamux.ccr($number) + .modify(|_, w| w.dmareq_id().bits(request_line)); } } #[inline(always)] fn set_priority(&mut self, priority: config::Priority) { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dma = unsafe { &*I::ptr() }; - dma.$ccr.modify(|_, w| unsafe { w.pl().bits(priority.bits()) }); + let dma_ch = &unsafe { &*I::ptr() }.ch(Self::NUMBER); + dma_ch.cr().modify(|_, w| unsafe { w.pl().bits(priority.bits()) }); } #[inline(always)] fn disable_interrupts(&mut self) { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dmacr = &unsafe { &*I::ptr() }.$ccr; + let dmacr = &unsafe { &*I::ptr() }.ch(Self::NUMBER).cr(); dmacr.modify(|_, w| w .tcie().clear_bit() .teie().clear_bit() @@ -332,19 +325,19 @@ macro_rules! dma_stream { #[inline(always)] fn enable_interrupts(&mut self, interrupt: Self::Interrupts) { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dma = unsafe { &*I::ptr() }; - dma.$ccr.modify(|_, w| w - .tcie().bit(interrupt.transfer_complete) - .teie().bit(interrupt.transfer_error) - .htie().bit(interrupt.half_transfer) + let dma_ch = &unsafe { &*I::ptr() }.ch(Self::NUMBER); + dma_ch.cr().modify(|_, w| w + .tcie().bit(interrupt.transfer_complete) + .teie().bit(interrupt.transfer_error) + .htie().bit(interrupt.half_transfer) ); } #[inline(always)] fn get_interrupts_enable() -> Self::Interrupts { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dma = unsafe { &*I::ptr() }; - let cr = dma.$ccr.read(); + let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); + let cr = dma_ch.cr().read(); DmaInterrupts { transfer_complete: cr.tcie().bit_is_set(), @@ -357,7 +350,7 @@ macro_rules! dma_stream { #[inline(always)] fn set_transfer_complete_interrupt_enable(&mut self, transfer_complete_interrupt: bool) { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dmacr = &unsafe { &*I::ptr() }.$ccr; + let dmacr = &unsafe { &*I::ptr() }.ch(Self::NUMBER).cr(); dmacr.modify(|_, w| w.tcie().bit(transfer_complete_interrupt)); let _ = dmacr.read(); let _ = dmacr.read(); // Delay 2 peripheral clocks @@ -366,7 +359,7 @@ macro_rules! dma_stream { #[inline(always)] fn set_transfer_error_interrupt_enable(&mut self, transfer_error_interrupt: bool) { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dmacr = &unsafe { &*I::ptr() }.$ccr; + let dmacr = &unsafe { &*I::ptr() }.ch(Self::NUMBER).cr(); dmacr.modify(|_, w| w.teie().bit(transfer_error_interrupt)); let _ = dmacr.read(); let _ = dmacr.read(); // Delay 2 peripheral clocks @@ -375,7 +368,7 @@ macro_rules! dma_stream { #[inline(always)] fn set_half_transfer_interrupt_enable(&mut self, half_transfer_interrupt: bool) { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dmacr = &unsafe { &*I::ptr() }.$ccr; + let dmacr = &unsafe { &*I::ptr() }.ch(Self::NUMBER).cr(); dmacr.modify(|_, w| w.htie().bit(half_transfer_interrupt)); let _ = dmacr.read(); let _ = dmacr.read(); // Delay 2 peripheral clocks @@ -385,7 +378,7 @@ macro_rules! dma_stream { fn 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() + dma.isr().read().htif(Self::NUMBER as u8).bit_is_set() } #[inline(always)] @@ -393,78 +386,78 @@ macro_rules! dma_stream { //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 + dma.ifcr().write(|w| w.chtif(Self::NUMBER as u8).set_bit()); + let _ = dma.isr().read(); + let _ = dma.isr().read(); // Delay 2 peripheral clocks } #[inline(always)] unsafe fn set_peripheral_address(&mut self, value: u32) { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dma = &*I::ptr(); - dma.$cparX.write(|w| w.pa().bits(value)); + let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); + dma_ch.par().write(|w| w.pa().bits(value)); } #[inline(always)] unsafe fn set_memory_address(&mut self, value: u32) { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dma = &*I::ptr(); - dma.$cmarX.write(|w| w.ma().bits(value) ); + let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); + dma_ch.mar().write(|w| w.ma().bits(value) ); } #[inline(always)] fn get_memory_address(&self) -> u32 { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dma = unsafe { &*I::ptr() }; - dma.$cmarX.read().ma().bits() + let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); + dma_ch.mar().read().ma().bits() } #[inline(always)] fn set_number_of_transfers(&mut self, value: u16) { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dma = unsafe { &*I::ptr() }; - dma.$cndtrX.write(|w| unsafe {w.ndt().bits(value) }); + let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); + dma_ch.ndtr().write(|w| unsafe {w.ndt().bits(value) }); } #[inline(always)] fn get_number_of_transfers() -> u16 { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dma = unsafe { &*I::ptr() }; - dma.$cndtrX.read().ndt().bits() + let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); + dma_ch.ndtr().read().ndt().bits() } #[inline(always)] unsafe fn set_memory_size(&mut self, size: u8) { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dma = &*I::ptr(); - dma.$ccr.modify(|_, w| w.msize().bits(size)); + let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); + dma_ch.cr().modify(|_, w| w.msize().bits(size)); } #[inline(always)] unsafe fn set_peripheral_size(&mut self, size: u8) { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dma = &*I::ptr(); - dma.$ccr.modify(|_, w| w.psize().bits(size)); + let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); + dma_ch.cr().modify(|_, w| w.psize().bits(size)); } #[inline(always)] fn set_memory_increment(&mut self, increment: bool) { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dma = unsafe { &*I::ptr() }; - dma.$ccr.modify(|_, w| w.minc().bit(increment)); + let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); + dma_ch.cr().modify(|_, w| w.minc().bit(increment)); } #[inline(always)] fn set_peripheral_increment(&mut self, increment: bool) { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dma = unsafe { &*I::ptr() }; - dma.$ccr.modify(|_, w| w.pinc().bit(increment)); + let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); + dma_ch.cr().modify(|_, w| w.pinc().bit(increment)); } #[inline(always)] fn set_direction(&mut self, direction: DmaDirection) { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dma = unsafe { &*I::ptr() }; - dma.$ccr.modify(|_, w| { + let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); + dma_ch.cr().modify(|_, w| { match direction { DmaDirection::PeripheralToMemory => w.dir().clear_bit().mem2mem().clear_bit(), @@ -479,8 +472,8 @@ macro_rules! dma_stream { #[inline(always)] fn set_circular_buffer(&mut self, circular_buffer: bool) { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dma = unsafe { &*I::ptr() }; - dma.$ccr.modify(|_, w| w.circ().bit(circular_buffer)); + let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); + dma_ch.cr().modify(|_, w| w.circ().bit(circular_buffer)); } } @@ -490,22 +483,22 @@ macro_rules! dma_stream { //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 + dma.ifcr().write(|w| w.chtif(Self::NUMBER as u8).set_bit()); + let _ = dma.isr().read(); + let _ = dma.isr().read(); // Delay 2 peripheral clocks } #[inline(always)] pub fn 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() + dma.isr().read().htif(Self::NUMBER as u8).bit_is_set() } #[inline(always)] pub fn set_half_transfer_interrupt_enable(&mut self, half_transfer_interrupt: bool) { //NOTE(unsafe) We only access the registers that belongs to the StreamX - let dmacr = &unsafe { &*I::ptr() }.$ccr; + let dmacr = &unsafe { &*I::ptr() }.ch(Self::NUMBER).cr(); dmacr.modify(|_, w| w.htie().bit(half_transfer_interrupt)); let _ = dmacr.read(); let _ = dmacr.read(); // Delay 2 peripheral clocks @@ -515,6 +508,17 @@ macro_rules! dma_stream { }; } +dma_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, 1), + (Stream1, 1, 2), + (Stream2, 2, 3), + (Stream3, 3, 4), + (Stream4, 4, 5), + (Stream5, 5, 6), +); + // Cat 3 and 4 devices #[cfg(any( feature = "stm32g471", @@ -528,95 +532,6 @@ macro_rules! dma_stream { dma_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, - regs => ccr1, cpar1, cmar1, cndtr1, - fields => tcif1, htif1, teif1, gif1, tcif1, htif1, teif1, gif1, - dmamux => c0cr, c8cr, - ), - ( - Stream1, 1, - regs => ccr2, cpar2, cmar2, cndtr2, - fields => tcif2, htif2, teif2, gif2, tcif2, htif2, teif2, gif2, - dmamux => c1cr, c9cr, - ), - ( - Stream2, 2, - regs => ccr3, cpar3, cmar3, cndtr3, - fields => tcif3, htif3, teif3, gif3, tcif3, htif3, teif3, gif3, - dmamux => c2cr, c10cr, - ), - ( - Stream3, 3, - regs => ccr4, cpar4, cmar4, cndtr4, - fields => tcif4, htif4, teif4, gif4, tcif4, htif4, teif4, gif4, - dmamux => c3cr, c11cr, - ), - ( - Stream4, 4, - regs => ccr5, cpar5, cmar5, cndtr5, - fields => tcif5, htif5, teif5, gif5, tcif5, htif5, teif5, gif5, - dmamux => c4cr, c12cr, - ), - ( - Stream5, 5, - regs => ccr6, cpar6, cmar6, cndtr6, - fields => tcif6, htif6, teif6, gif6, tcif6, htif6, teif6, gif6, - dmamux => c5cr, c13cr, - ), - ( - Stream6, 6, - regs => ccr7, cpar7, cmar7, cndtr7, - fields => tcif7, htif7, teif7, gif7, tcif7, htif7, teif7, gif7, - dmamux => c6cr, c14cr, - ), - ( - Stream7, 7, - regs => ccr8, cpar8, cmar8, cndtr8, - fields => tcif8, htif8, teif8, gif8, tcif8, htif8, teif8, gif8, - dmamux => c7cr, c15cr, - ), -); - -// Cat 2 devices -#[cfg(any(feature = "stm32g431", feature = "stm32g441",))] -dma_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, - regs => ccr1, cpar1, cmar1, cndtr1, - fields => tcif1, htif1, teif1, gif1, tcif1, htif1, teif1, gif1, - dmamux => c0cr, c6cr, - ), - ( - Stream1, 1, - regs => ccr2, cpar2, cmar2, cndtr2, - fields => tcif2, htif2, teif2, gif2, tcif2, htif2, teif2, gif2, - dmamux => c1cr, c7cr, - ), - ( - Stream2, 2, - regs => ccr3, cpar3, cmar3, cndtr3, - fields => tcif3, htif3, teif3, gif3, tcif3, htif3, teif3, gif3, - dmamux => c2cr, c8cr, - ), - ( - Stream3, 3, - regs => ccr4, cpar4, cmar4, cndtr4, - fields => tcif4, htif4, teif4, gif4, tcif4, htif4, teif4, gif4, - dmamux => c3cr, c9cr, - ), - ( - Stream4, 4, - regs => ccr5, cpar5, cmar5, cndtr5, - fields => tcif5, htif5, teif5, gif5, tcif5, htif5, teif5, gif5, - dmamux => c4cr, c10cr, - ), - ( - Stream5, 5, - regs => ccr6, cpar6, cmar6, cndtr6, - fields => tcif6, htif6, teif6, gif6, tcif6, htif6, teif6, gif6, - dmamux => c5cr, c11cr, - ), + (Stream6, 6, 7), + (Stream7, 7, 8), ); diff --git a/src/exti.rs b/src/exti.rs index bbdaffb7..83abc5af 100644 --- a/src/exti.rs +++ b/src/exti.rs @@ -88,14 +88,18 @@ impl ExtiExt for EXTI { let mask = 1 << line; match edge { SignalEdge::Rising => { - self.rtsr1.modify(|r, w| unsafe { w.bits(r.bits() | mask) }); + self.rtsr1() + .modify(|r, w| unsafe { w.bits(r.bits() | mask) }); } SignalEdge::Falling => { - self.ftsr1.modify(|r, w| unsafe { w.bits(r.bits() | mask) }); + self.ftsr1() + .modify(|r, w| unsafe { w.bits(r.bits() | mask) }); } SignalEdge::RisingFalling => { - self.rtsr1.modify(|r, w| unsafe { w.bits(r.bits() | mask) }); - self.ftsr1.modify(|r, w| unsafe { w.bits(r.bits() | mask) }); + self.rtsr1() + .modify(|r, w| unsafe { w.bits(r.bits() | mask) }); + self.ftsr1() + .modify(|r, w| unsafe { w.bits(r.bits() | mask) }); } } self.wakeup(ev); @@ -104,12 +108,12 @@ impl ExtiExt for EXTI { fn wakeup(&self, ev: Event) { match ev as u8 { line if line < 32 => self - .imr1 + .imr1() .modify(|r, w| unsafe { w.bits(r.bits() | 1 << line) }), line => self - .imr2 + .imr2() .modify(|r, w| unsafe { w.bits(r.bits() | 1 << (line - 32)) }), - } + }; } fn unlisten(&self, ev: Event) { @@ -117,15 +121,19 @@ impl ExtiExt for EXTI { match ev as u8 { line if line < 32 => { let mask = !(1 << line); - self.imr1.modify(|r, w| unsafe { w.bits(r.bits() & mask) }); + self.imr1() + .modify(|r, w| unsafe { w.bits(r.bits() & mask) }); if line <= 18 { - self.rtsr1.modify(|r, w| unsafe { w.bits(r.bits() & mask) }); - self.ftsr1.modify(|r, w| unsafe { w.bits(r.bits() & mask) }); + self.rtsr1() + .modify(|r, w| unsafe { w.bits(r.bits() & mask) }); + self.ftsr1() + .modify(|r, w| unsafe { w.bits(r.bits() & mask) }); } } line => { let mask = !(1 << (line - 32)); - self.imr2.modify(|r, w| unsafe { w.bits(r.bits() & mask) }) + self.imr2() + .modify(|r, w| unsafe { w.bits(r.bits() & mask) }); } } } @@ -136,13 +144,13 @@ impl ExtiExt for EXTI { return false; } let mask = 1 << line; - self.pr1.read().bits() & mask != 0 + self.pr1().read().bits() & mask != 0 } fn unpend(&self, ev: Event) { let line = ev as u8; if line <= 18 { - self.pr1.modify(|_, w| unsafe { w.bits(1 << line) }); + self.pr1().modify(|_, w| unsafe { w.bits(1 << line) }); } } } diff --git a/src/fdcan.rs b/src/fdcan.rs index 24e42088..997e11b9 100644 --- a/src/fdcan.rs +++ b/src/fdcan.rs @@ -286,9 +286,9 @@ where fn enter_init_mode(&mut self) { let can = self.registers(); - can.cccr.modify(|_, w| w.init().set_bit()); - while can.cccr.read().init().bit_is_clear() {} - can.cccr.modify(|_, w| w.cce().set_bit()); + can.cccr().modify(|_, w| w.init().set_bit()); + while can.cccr().read().init().bit_is_clear() {} + can.cccr().modify(|_, w| w.cce().set_bit()); } /// Returns the current FDCAN config settings @@ -311,20 +311,20 @@ where self.set_bus_monitoring_mode(mon); let can = self.registers(); - can.test.modify(|_, w| w.lbck().bit(lbck)); + can.test().modify(|_, w| w.lbck().bit(lbck)); } /// Enables or disables silent mode: Disconnects the TX signal from the pin. #[inline] fn set_bus_monitoring_mode(&mut self, enabled: bool) { let can = self.registers(); - can.cccr.modify(|_, w| w.mon().bit(enabled)); + can.cccr().modify(|_, w| w.mon().bit(enabled)); } #[inline] fn set_restricted_operations(&mut self, enabled: bool) { let can = self.registers(); - can.cccr.modify(|_, w| w.asm().bit(enabled)); + can.cccr().modify(|_, w| w.asm().bit(enabled)); } #[inline] @@ -335,14 +335,14 @@ where #[inline] fn set_test_mode(&mut self, enabled: bool) { let can = self.registers(); - can.cccr.modify(|_, w| w.test().bit(enabled)); + can.cccr().modify(|_, w| w.test().bit(enabled)); } #[inline] fn set_power_down_mode(&mut self, enabled: bool) { let can = self.registers(); - can.cccr.modify(|_, w| w.csr().bit(enabled)); - while can.cccr.read().csa().bit() != enabled {} + can.cccr().modify(|_, w| w.csr().bit(enabled)); + while can.cccr().read().csa().bit() != enabled {} } /// Enable/Disable the specific Interrupt Line @@ -350,8 +350,8 @@ where pub fn enable_interrupt_line(&mut self, line: InterruptLine, enabled: bool) { let can = self.registers(); match line { - InterruptLine::_0 => can.ile.modify(|_, w| w.eint1().bit(enabled)), - InterruptLine::_1 => can.ile.modify(|_, w| w.eint0().bit(enabled)), + InterruptLine::_0 => can.ile().modify(|_, w| w.eint1().bit(enabled)), + InterruptLine::_1 => can.ile().modify(|_, w| w.eint0().bit(enabled)), } } @@ -422,7 +422,7 @@ where /// Retrieve the current protocol status pub fn get_protocol_status(&self) -> ProtocolStatus { - let psr = self.registers().psr.read(); + let psr = self.registers().psr().read(); ProtocolStatus { activity: Activity::try_from(0 /*psr.act().bits()*/).unwrap(), //TODO: stm32g4 does not allow reading from this register transmitter_delay_comp: psr.tdcv().bits(), @@ -526,9 +526,9 @@ where { I::enable(&rcc.rb); - if rcc.rb.ccipr.read().fdcansel().is_hse() { + if rcc.rb.ccipr().read().fdcansel().is_hse() { // Select P clock as FDCAN clock source - rcc.rb.ccipr.modify(|_, w| { + rcc.rb.ccipr().modify(|_, w| { // This is sound, as `FdCanClockSource` only contains valid values for this field. unsafe { w.fdcansel().bits(FdCanClockSource::PCLK as u8); @@ -541,7 +541,7 @@ where let can = Self::create_can(FdCanConfig::default(), can_instance); let reg = can.registers(); - assert!(reg.endn.read().bits() == 0x87654321_u32); + assert!(reg.endn().read().bits() == 0x87654321_u32); can } @@ -562,7 +562,7 @@ where TX: sealed::Tx, RX: sealed::Rx, { - rcc.rb.ccipr.modify(|_, w| { + rcc.rb.ccipr().modify(|_, w| { // This is sound, as `FdCanClockSource` only contains valid values for this field. unsafe { w.fdcansel().bits(clock_source as u8); @@ -588,17 +588,17 @@ where // set TxBuffer to Queue Mode; // TODO: don't require this. - // can.txbc.write(|w| w.tfqm().set_bit()); + // can.txbc().write(|w| w.tfqm().set_bit()); //FIXME: stm32g4 has the wrong layout here! //We should be able to use the above, //But right now, we just set the 24th bit. - can.txbc.write(|w| unsafe { w.bits(1_u32 << 24) }); + can.txbc().write(|w| unsafe { w.bits(1_u32 << 24) }); // set standard filters list size to 28 // set extended filters list size to 8 // REQUIRED: we use the memory map as if these settings are set // instead of re-calculating them. - can.rxgfc.modify(|_, w| unsafe { + can.rxgfc().modify(|_, w| unsafe { w.lse() .bits(EXTENDED_FILTER_MAX) .lss() @@ -635,9 +635,9 @@ where self.apply_config(self.control.config); let can = self.registers(); - can.cccr.modify(|_, w| w.cce().clear_bit()); - can.cccr.modify(|_, w| w.init().clear_bit()); - while can.cccr.read().init().bit_is_set() {} + can.cccr().modify(|_, w| w.cce().clear_bit()); + can.cccr().modify(|_, w| w.init().clear_bit()); + while can.cccr().read().init().bit_is_set() {} } /// Moves out of ConfigMode and into InternalLoopbackMode @@ -736,7 +736,7 @@ where self.control.config.nbtr = btr; let can = self.registers(); - can.nbtp.write(|w| unsafe { + can.nbtp().write(|w| unsafe { w.nbrp() .bits(btr.nbrp() - 1) .ntseg1() @@ -755,7 +755,7 @@ where self.control.config.dbtr = btr; let can = self.registers(); - can.dbtp.write(|w| unsafe { + can.dbtp().write(|w| unsafe { w.dbrp() .bits(btr.dbrp() - 1) .dtseg1() @@ -776,7 +776,7 @@ where #[inline] pub fn set_automatic_retransmit(&mut self, enabled: bool) { let can = self.registers(); - can.cccr.modify(|_, w| w.dar().bit(!enabled)); + can.cccr().modify(|_, w| w.dar().bit(!enabled)); self.control.config.automatic_retransmit = enabled; } @@ -785,7 +785,7 @@ where #[inline] pub fn set_transmit_pause(&mut self, enabled: bool) { let can = self.registers(); - can.cccr.modify(|_, w| w.dar().bit(!enabled)); + can.cccr().modify(|_, w| w.dar().bit(!enabled)); self.control.config.transmit_pause = enabled; } @@ -794,7 +794,7 @@ where #[inline] pub fn set_non_iso_mode(&mut self, enabled: bool) { let can = self.registers(); - can.cccr.modify(|_, w| w.niso().bit(enabled)); + can.cccr().modify(|_, w| w.niso().bit(enabled)); self.control.config.non_iso_mode = enabled; } @@ -803,7 +803,7 @@ where #[inline] pub fn set_edge_filtering(&mut self, enabled: bool) { let can = self.registers(); - can.cccr.modify(|_, w| w.efbi().bit(enabled)); + can.cccr().modify(|_, w| w.efbi().bit(enabled)); self.control.config.edge_filtering = enabled; } @@ -818,7 +818,7 @@ where }; let can = self.registers(); - can.cccr.modify(|_, w| w.fdoe().bit(fdoe).brse().bit(brse)); + can.cccr().modify(|_, w| w.fdoe().bit(fdoe).brse().bit(brse)); self.control.config.frame_transmit = fts; } @@ -829,7 +829,7 @@ where pub fn set_interrupt_line_config(&mut self, l0int: Interrupts) { let can = self.registers(); - can.ils.modify(|_, w| unsafe { w.bits(l0int.bits()) }); + can.ils().modify(|_, w| unsafe { w.bits(l0int.bits()) }); self.control.config.interrupt_line_config = l0int; } @@ -839,7 +839,7 @@ where pub fn set_protocol_exception_handling(&mut self, enabled: bool) { let can = self.registers(); - can.cccr.modify(|_, w| w.pxhd().bit(!enabled)); + can.cccr().modify(|_, w| w.pxhd().bit(!enabled)); self.control.config.protocol_exception_handling = enabled; } @@ -850,7 +850,7 @@ where pub fn set_clock_divider(&mut self, div: ClockDivider) { let can = self.registers(); - can.ckdiv.write(|w| unsafe { w.pdiv().bits(div as u8) }); + can.ckdiv().write(|w| unsafe { w.pdiv().bits(div as u8) }); self.control.config.clock_divider = div; } @@ -873,7 +873,7 @@ where /// Configures the global filter settings #[inline] pub fn set_global_filter(&mut self, filter: GlobalFilter) { - self.registers().rxgfc.modify(|_, w| { + self.registers().rxgfc().modify(|_, w| { unsafe { w.anfs() .bits(filter.handle_standard_frames as u8) @@ -993,7 +993,7 @@ where pub fn get_receive_pin(&mut self) -> bool { let can = self.registers(); - can.test.read().rx().bit_is_set() + can.test().read().rx().bit_is_set() } /// Sets the state of the transmit pin according to TestTransmitPinState @@ -1001,7 +1001,7 @@ where let can = self.registers(); //SAFE: state has all possible values, and this can only occur in TestMode - can.test.modify(|_, w| unsafe { w.tx().bits(state as u8) }); + can.test().modify(|_, w| unsafe { w.tx().bits(state as u8) }); } } @@ -1159,10 +1159,11 @@ where #[inline] pub fn error_counters(&self) -> ErrorCounters { let can = self.registers(); - let cel: u8 = can.ecr.read().cel().bits(); - let rp: bool = can.ecr.read().rp().bit(); - let rec: u8 = can.ecr.read().rec().bits(); - let tec: u8 = can.ecr.read().tec().bits(); + let ecr = can.ecr().read(); + let cel: u8 = ecr.cel().bits(); + let rp: bool = ecr.rp().bit(); + let rec: u8 = ecr.rec().bits(); + let tec: u8 = ecr.tec().bits(); ErrorCounters { can_errors: cel, @@ -1177,28 +1178,28 @@ where /// Returns the current FdCan Timestamp counter #[inline] pub fn timestamp(&self) -> u16 { - self.registers().tscv.read().tsc().bits() + self.registers().tscv().read().tsc().bits() } /// Check if the interrupt is triggered #[inline] pub fn has_interrupt(&mut self, interrupt: Interrupt) -> bool { let can = self.registers(); - can.ir.read().bits() & (interrupt as u32) > 0 + can.ir().read().bits() & (interrupt as u32) > 0 } /// Clear specified interrupt #[inline] pub fn clear_interrupt(&mut self, interrupt: Interrupt) { let can = self.registers(); - can.ir.write(|w| unsafe { w.bits(interrupt as u32) }); + can.ir().write(|w| unsafe { w.bits(interrupt as u32) }); } /// Clear specified interrupts #[inline] pub fn clear_interrupts(&mut self, interrupts: Interrupts) { let can = self.registers(); - can.ir.write(|w| unsafe { w.bits(interrupts.bits()) }); + can.ir().write(|w| unsafe { w.bits(interrupts.bits()) }); } } @@ -1310,7 +1311,7 @@ where } } else { // Read the Write Pointer - let idx = can.txfqs.read().tfqpi().bits(); + let idx = can.txfqs().read().tfqpi().bits(); (Mailbox::new(idx), None) }; @@ -1323,7 +1324,7 @@ where /// Returns if the tx queue is able to accept new messages without having to cancel an existing one #[inline] pub fn tx_queue_is_full(&self) -> bool { - self.registers().txfqs.read().tfqf().bit() + self.registers().txfqs().read().tfqf().bit() } /// Returns `Ok` when the mailbox is free or if it contains pending frame with a @@ -1405,13 +1406,13 @@ where let idx = 1u8 << idx; // Abort Request - can.txbcr.write(|w| unsafe { w.cr().bits(idx) }); + can.txbcr().write(|w| unsafe { w.cr().bits(idx) }); // Wait for the abort request to be finished. loop { - if can.txbcf.read().cf().bits() & idx != 0 { + if can.txbcf().read().cf().bits() & idx != 0 { // Return false when a transmission has occured - break can.txbto.read().to().bits() & idx == 0; + break can.txbto().read().to().bits() & idx == 0; } } } else { @@ -1425,28 +1426,28 @@ where let idx: u8 = idx.into(); let idx = 1u8 << idx; - can.txbrp.read().trp().bits() & idx != 0 + can.txbrp().read().trp().bits() & idx != 0 } /// Returns `true` if no frame is pending for transmission. #[inline] pub fn is_idle(&self) -> bool { let can = self.registers(); - can.txbrp.read().trp().bits() == 0x0 + can.txbrp().read().trp().bits() == 0x0 } /// Clears the transmission complete flag. #[inline] pub fn clear_transmission_completed_flag(&mut self) { let can = self.registers(); - can.ir.write(|w| w.tc().set_bit()); + can.ir().write(|w| w.tc().set_bit()); } /// Clears the transmission cancelled flag. #[inline] pub fn clear_transmission_cancelled_flag(&mut self) { let can = self.registers(); - can.ir.write(|w| w.tcf().set_bit()); + can.ir().write(|w| w.tcf().set_bit()); } } @@ -1570,8 +1571,8 @@ where fn has_overrun(&self) -> bool { let can = self.registers(); match FIFONR::NR { - 0 => can.rxf0s.read().rf0l().bit(), - 1 => can.rxf1s.read().rf1l().bit(), + 0 => can.rxf0s().read().rf0l().bit(), + 1 => can.rxf1s().read().rf1l().bit(), _ => unreachable!(), } } @@ -1581,8 +1582,8 @@ where pub fn rx_fifo_is_empty(&self) -> bool { let can = self.registers(); match FIFONR::NR { - 0 => can.rxf0s.read().f0fl().bits() == 0, - 1 => can.rxf1s.read().f1fl().bits() == 0, + 0 => can.rxf0s().read().f0fl().bits() == 0, + 1 => can.rxf1s().read().f1fl().bits() == 0, _ => unreachable!(), } } @@ -1595,8 +1596,8 @@ where let can = self.registers(); match FIFONR::NR { - 0 => can.rxf0a.write(|w| unsafe { w.f0ai().bits(idx.into()) }), - 1 => can.rxf1a.write(|w| unsafe { w.f1ai().bits(idx.into()) }), + 0 => can.rxf0a().write(|w| unsafe { w.f0ai().bits(idx.into()) }), + 1 => can.rxf1a().write(|w| unsafe { w.f1ai().bits(idx.into()) }), _ => unreachable!(), } } @@ -1605,8 +1606,8 @@ where fn get_rx_mailbox(&self) -> Mailbox { let can = self.registers(); let idx = match FIFONR::NR { - 0 => can.rxf0s.read().f0gi().bits(), - 1 => can.rxf1s.read().f1gi().bits(), + 0 => can.rxf0s().read().f0gi().bits(), + 1 => can.rxf1s().read().f1gi().bits(), _ => unreachable!(), }; Mailbox::new(idx) @@ -1712,7 +1713,7 @@ mod impls { feature = "stm32g483", feature = "stm32g484", feature = "stm32g491", - feature = "stm32g4A1", + feature = "stm32g4a1", ))] mod fdcan2 { use crate::fdcan; diff --git a/src/flash.rs b/src/flash.rs index 26b60484..9edf1bfa 100644 --- a/src/flash.rs +++ b/src/flash.rs @@ -465,7 +465,7 @@ pub struct ACR { impl ACR { pub(crate) fn acr(&mut self) -> &flash::ACR { // NOTE(unsafe) this proxy grants exclusive access to this register - unsafe { &(*FLASH::ptr()).acr } + unsafe { (*FLASH::ptr()).acr() } } } @@ -478,7 +478,7 @@ pub struct CR { impl CR { pub(crate) fn cr(&mut self) -> &flash::CR { // NOTE(unsafe) this proxy grants exclusive access to this register - unsafe { &(*FLASH::ptr()).cr } + unsafe { (*FLASH::ptr()).cr() } } } @@ -491,7 +491,7 @@ pub struct ECCR { impl ECCR { pub(crate) fn eccr(&mut self) -> &flash::ECCR { // NOTE(unsafe) this proxy grants exclusive access to this register - unsafe { &(*FLASH::ptr()).eccr } + unsafe { (*FLASH::ptr()).eccr() } } } @@ -504,7 +504,7 @@ pub struct KEYR { impl KEYR { pub(crate) fn keyr(&mut self) -> &flash::KEYR { // NOTE(unsafe) this proxy grants exclusive access to this register - unsafe { &(*FLASH::ptr()).keyr } + unsafe { (*FLASH::ptr()).keyr() } } } @@ -517,7 +517,7 @@ pub struct OPTKEYR { impl OPTKEYR { pub(crate) fn optkeyr(&mut self) -> &flash::OPTKEYR { // NOTE(unsafe) this proxy grants exclusive access to this register - unsafe { &(*FLASH::ptr()).optkeyr } + unsafe { (*FLASH::ptr()).optkeyr() } } } @@ -530,7 +530,7 @@ pub struct OPTR { impl OPTR { pub(crate) fn optr(&mut self) -> &flash::OPTR { // NOTE(unsafe) this proxy grants exclusive access to this register - unsafe { &(*FLASH::ptr()).optr } + unsafe { (*FLASH::ptr()).optr() } } } @@ -543,7 +543,7 @@ pub struct PCROP1SR { impl PCROP1SR { pub(crate) fn pcrop1sr(&mut self) -> &flash::PCROP1SR { // NOTE(unsafe) this proxy grants exclusive access to this register - unsafe { &(*FLASH::ptr()).pcrop1sr } + unsafe { (*FLASH::ptr()).pcrop1sr() } } } @@ -556,7 +556,7 @@ pub struct PCROP1ER { impl PCROP1ER { pub(crate) fn pcrop1er(&mut self) -> &flash::PCROP1ER { // NOTE(unsafe) this proxy grants exclusive access to this register - unsafe { &(*FLASH::ptr()).pcrop1er } + unsafe { (*FLASH::ptr()).pcrop1er() } } } @@ -569,7 +569,7 @@ pub struct PDKEYR { impl PDKEYR { pub(crate) fn pdkeyr(&mut self) -> &flash::PDKEYR { // NOTE(unsafe) this proxy grants exclusive access to this register - unsafe { &(*FLASH::ptr()).pdkeyr } + unsafe { (*FLASH::ptr()).pdkeyr() } } } @@ -582,7 +582,7 @@ pub struct SEC1R { impl SEC1R { pub(crate) fn sec1r(&mut self) -> &flash::SEC1R { // NOTE(unsafe) this proxy grants exclusive access to this register - unsafe { &(*FLASH::ptr()).sec1r } + unsafe { (*FLASH::ptr()).sec1r() } } } @@ -595,7 +595,7 @@ pub struct SR { impl SR { pub(crate) fn sr(&mut self) -> &flash::SR { // NOTE(unsafe) this proxy grants exclusive access to this register - unsafe { &(*FLASH::ptr()).sr } + unsafe { (*FLASH::ptr()).sr() } } } @@ -608,7 +608,7 @@ pub struct WRP1AR { impl WRP1AR { pub(crate) fn wrp1ar(&mut self) -> &flash::WRP1AR { // NOTE(unsafe) this proxy grants exclusive access to this register - unsafe { &(*FLASH::ptr()).wrp1ar } + unsafe { (*FLASH::ptr()).wrp1ar() } } } @@ -621,6 +621,6 @@ pub struct WRP1BR { impl WRP1BR { pub(crate) fn wrp1br(&mut self) -> &flash::WRP1BR { // NOTE(unsafe) this proxy grants exclusive access to this register - unsafe { &(*FLASH::ptr()).wrp1br } + unsafe { (*FLASH::ptr()).wrp1br() } } } diff --git a/src/gpio.rs b/src/gpio.rs index bd43df0c..7bb05cef 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -99,22 +99,22 @@ macro_rules! exti_erased { let offset = 4 * (self.i % 4); match self.i { 0..=3 => { - syscfg.exticr1.modify(|r, w| unsafe { + syscfg.exticr1().modify(|r, w| unsafe { w.bits((r.bits() & !(0xf << offset)) | ($extigpionr << offset)) }); } 4..=7 => { - syscfg.exticr2.modify(|r, w| unsafe { + syscfg.exticr2().modify(|r, w| unsafe { w.bits((r.bits() & !(0xf << offset)) | ($extigpionr << offset)) }); } 8..=11 => { - syscfg.exticr3.modify(|r, w| unsafe { + syscfg.exticr3().modify(|r, w| unsafe { w.bits((r.bits() & !(0xf << offset)) | ($extigpionr << offset)) }); } 12..=15 => { - syscfg.exticr4.modify(|r, w| unsafe { + syscfg.exticr4().modify(|r, w| unsafe { w.bits((r.bits() & !(0xf << offset)) | ($extigpionr << offset)) }); } @@ -126,21 +126,21 @@ macro_rules! exti_erased { fn trigger_on_edge(&mut self, exti: &mut EXTI, edge: SignalEdge) { match edge { SignalEdge::Rising => { - exti.rtsr1 + exti.rtsr1() .modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.i)) }); - exti.ftsr1 + exti.ftsr1() .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << self.i)) }); } SignalEdge::Falling => { - exti.ftsr1 + exti.ftsr1() .modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.i)) }); - exti.rtsr1 + exti.rtsr1() .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << self.i)) }); } SignalEdge::RisingFalling => { - exti.rtsr1 + exti.rtsr1() .modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.i)) }); - exti.ftsr1 + exti.ftsr1() .modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.i)) }); } } @@ -148,24 +148,24 @@ macro_rules! exti_erased { /// Enable external interrupts from this pin. fn enable_interrupt(&mut self, exti: &mut EXTI) { - exti.imr1 + exti.imr1() .modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.i)) }); } /// Disable external interrupts from this pin fn disable_interrupt(&mut self, exti: &mut EXTI) { - exti.imr1 + exti.imr1() .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << self.i)) }); } /// Clear the interrupt pending bit for this pin fn clear_interrupt_pending_bit(&mut self) { - unsafe { (*EXTI::ptr()).pr1.write(|w| w.bits(1 << self.i)) }; + unsafe { (*EXTI::ptr()).pr1().write(|w| w.bits(1 << self.i)) }; } /// Reads the interrupt pending bit for this pin fn check_interrupt(&self) -> bool { - unsafe { ((*EXTI::ptr()).pr1.read().bits() & (1 << self.i)) != 0 } + unsafe { ((*EXTI::ptr()).pr1().read().bits() & (1 << self.i)) != 0 } } } }; @@ -177,7 +177,7 @@ macro_rules! exti { /// Configure EXTI Line $i to trigger from this pin. fn make_interrupt_source(&mut self, syscfg: &mut SysCfg) { let offset = 4 * ($i % 4); - syscfg.$exticri.modify(|r, w| unsafe { + syscfg.$exticri().modify(|r, w| unsafe { let mut exticr = r.bits(); exticr = (exticr & !(0xf << offset)) | ($extigpionr << offset); //FIXME: clears other pins w.bits(exticr) @@ -188,21 +188,21 @@ macro_rules! exti { fn trigger_on_edge(&mut self, exti: &mut EXTI, edge: SignalEdge) { match edge { SignalEdge::Rising => { - exti.rtsr1 + exti.rtsr1() .modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) }); - exti.ftsr1 + exti.ftsr1() .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) }); } SignalEdge::Falling => { - exti.ftsr1 + exti.ftsr1() .modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) }); - exti.rtsr1 + exti.rtsr1() .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) }); } SignalEdge::RisingFalling => { - exti.rtsr1 + exti.rtsr1() .modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) }); - exti.ftsr1 + exti.ftsr1() .modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) }); } } @@ -210,24 +210,24 @@ macro_rules! exti { /// Enable external interrupts from this pin. fn enable_interrupt(&mut self, exti: &mut EXTI) { - exti.imr1 + exti.imr1() .modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) }); } /// Disable external interrupts from this pin fn disable_interrupt(&mut self, exti: &mut EXTI) { - exti.imr1 + exti.imr1() .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) }); } /// Clear the interrupt pending bit for this pin fn clear_interrupt_pending_bit(&mut self) { - unsafe { (*EXTI::ptr()).pr1.write(|w| w.bits(1 << $i)) }; + unsafe { (*EXTI::ptr()).pr1().write(|w| w.bits(1 << $i)) }; } /// Reads the interrupt pending bit for this pin fn check_interrupt(&self) -> bool { - unsafe { ((*EXTI::ptr()).pr1.read().bits() & (1 << $i)) != 0 } + unsafe { ((*EXTI::ptr()).pr1().read().bits() & (1 << $i)) != 0 } } } }; @@ -257,7 +257,7 @@ macro_rules! gpio { type Parts = Parts; fn split(self, rcc: &mut Rcc) -> Parts { - rcc.rb.ahb2enr.modify(|_, w| w.$iopxenr().set_bit()); + rcc.rb.ahb2enr().modify(|_, w| w.$iopxenr().set_bit()); Parts { $( $pxi: $PXi { _mode: PhantomData }, @@ -277,13 +277,13 @@ macro_rules! gpio { fn set_high(&mut self) -> Result<(), ()> { // NOTE(unsafe) atomic write to a stateless register - unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << self.i)) }; + unsafe { (*$GPIOX::ptr()).bsrr().write(|w| w.bits(1 << self.i)) }; Ok(()) } fn set_low(&mut self) -> Result<(), ()> { // NOTE(unsafe) atomic write to a stateless register - unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (self.i + 16))) }; + unsafe { (*$GPIOX::ptr()).bsrr().write(|w| w.bits(1 << (self.i + 16))) }; Ok(()) } } @@ -296,7 +296,7 @@ macro_rules! gpio { fn is_set_low(&self) -> Result { // NOTE(unsafe) atomic read with no side effects - let is_set_low = unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << self.i) == 0 }; + let is_set_low = unsafe { (*$GPIOX::ptr()).odr().read().bits() & (1 << self.i) == 0 }; Ok(is_set_low) } } @@ -314,7 +314,7 @@ macro_rules! gpio { fn is_low(&self) -> Result { // NOTE(unsafe) atomic read with no side effects - let is_low = unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << self.i) == 0 }; + let is_low = unsafe { (*$GPIOX::ptr()).idr().read().bits() & (1 << self.i) == 0 }; Ok(is_low) } } @@ -329,7 +329,7 @@ macro_rules! gpio { fn is_low(&self) -> Result { // NOTE(unsafe) atomic read with no side effects - let is_low = unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << self.i) == 0 }; + let is_low = unsafe { (*$GPIOX::ptr()).idr().read().bits() & (1 << self.i) == 0 }; Ok(is_low) } } @@ -385,10 +385,10 @@ macro_rules! gpio { let offset = 2 * $i; unsafe { let gpio = &(*$GPIOX::ptr()); - gpio.pupdr.modify(|r, w| { + gpio.pupdr().modify(|r, w| { w.bits(r.bits() & !(0b11 << offset)) }); - gpio.moder.modify(|r, w| { + gpio.moder().modify(|r, w| { w.bits(r.bits() & !(0b11 << offset)) }) }; @@ -400,10 +400,10 @@ macro_rules! gpio { let offset = 2 * $i; unsafe { let gpio = &(*$GPIOX::ptr()); - gpio.pupdr.modify(|r, w| { + gpio.pupdr().modify(|r, w| { w.bits((r.bits() & !(0b11 << offset)) | (0b10 << offset)) }); - gpio.moder.modify(|r, w| { + gpio.moder().modify(|r, w| { w.bits(r.bits() & !(0b11 << offset)) }) }; @@ -415,10 +415,10 @@ macro_rules! gpio { let offset = 2 * $i; unsafe { let gpio = &(*$GPIOX::ptr()); - gpio.pupdr.modify(|r, w| { + gpio.pupdr().modify(|r, w| { w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset)) }); - gpio.moder.modify(|r, w| { + gpio.moder().modify(|r, w| { w.bits(r.bits() & !(0b11 << offset)) }) }; @@ -430,10 +430,10 @@ macro_rules! gpio { let offset = 2 * $i; unsafe { let gpio = &(*$GPIOX::ptr()); - gpio.pupdr.modify(|r, w| { + gpio.pupdr().modify(|r, w| { w.bits(r.bits() & !(0b11 << offset)) }); - gpio.moder.modify(|r, w| { + gpio.moder().modify(|r, w| { w.bits((r.bits() & !(0b11 << offset)) | (0b11 << offset)) }); } @@ -445,13 +445,13 @@ macro_rules! gpio { let offset = 2 * $i; unsafe { let gpio = &(*$GPIOX::ptr()); - gpio.pupdr.modify(|r, w| { + gpio.pupdr().modify(|r, w| { w.bits(r.bits() & !(0b11 << offset)) }); - gpio.otyper.modify(|r, w| { + gpio.otyper().modify(|r, w| { w.bits(r.bits() | (0b1 << $i)) }); - gpio.moder.modify(|r, w| { + gpio.moder().modify(|r, w| { w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset)) }) }; @@ -463,13 +463,13 @@ macro_rules! gpio { let offset = 2 * $i; unsafe { let gpio = &(*$GPIOX::ptr()); - gpio.pupdr.modify(|r, w| { + gpio.pupdr().modify(|r, w| { w.bits(r.bits() & !(0b11 << offset)) }); - gpio.otyper.modify(|r, w| { + gpio.otyper().modify(|r, w| { w.bits(r.bits() & !(0b1 << $i)) }); - gpio.moder.modify(|r, w| { + gpio.moder().modify(|r, w| { w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset)) }) }; @@ -486,9 +486,9 @@ macro_rules! gpio { pub fn set_speed(self, speed: Speed) -> Self { let offset = 2 * $i; unsafe { - (*$GPIOX::ptr()).ospeedr.modify(|r, w| { + (*$GPIOX::ptr()).ospeedr().modify(|r, w| { w.bits((r.bits() & !(0b11 << offset)) | ((speed as u32) << offset)) - }) + }); } self } @@ -500,19 +500,19 @@ macro_rules! gpio { unsafe { let gpio = &(*$GPIOX::ptr()); if offset2 < 32 { - gpio.afrl.modify(|r, w| { + gpio.afrl().modify(|r, w| { w.bits((r.bits() & !(0b1111 << offset2)) | (mode << offset2)) }); } else { let offset2 = offset2 - 32; - gpio.afrh.modify(|r, w| { + gpio.afrh().modify(|r, w| { w.bits((r.bits() & !(0b1111 << offset2)) | (mode << offset2)) }); } - gpio.moder.modify(|r, w| { + gpio.moder().modify(|r, w| { w.bits((r.bits() & !(0b11 << offset)) | (0b10 << offset)) }); - gpio.otyper.modify(|r, w| { + gpio.otyper().modify(|r, w| { w.bits(r.bits() & !(0b1 << $i)) }); } @@ -526,19 +526,19 @@ macro_rules! gpio { unsafe { let gpio = &(*$GPIOX::ptr()); if offset2 < 32 { - gpio.afrl.modify(|r, w| { + gpio.afrl().modify(|r, w| { w.bits((r.bits() & !(0b1111 << offset2)) | (mode << offset2)) }); } else { let offset2 = offset2 - 32; - gpio.afrh.modify(|r, w| { + gpio.afrh().modify(|r, w| { w.bits((r.bits() & !(0b1111 << offset2)) | (mode << offset2)) }); } - gpio.otyper.modify(|r, w| { + gpio.otyper().modify(|r, w| { w.bits(r.bits() | (0b1 << $i)) }); - gpio.moder.modify(|r, w| { + gpio.moder().modify(|r, w| { w.bits((r.bits() & !(0b11 << offset)) | (0b10 << offset)) }); } @@ -561,13 +561,13 @@ macro_rules! gpio { fn set_high(&mut self) -> Result<(), ()> { // NOTE(unsafe) atomic write to a stateless register - unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << $i)) }; + unsafe { (*$GPIOX::ptr()).bsrr().write(|w| w.bits(1 << $i)) }; Ok(()) } fn set_low(&mut self) -> Result<(), ()>{ // NOTE(unsafe) atomic write to a stateless register - unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << ($i + 16))) }; + unsafe { (*$GPIOX::ptr()).bsrr().write(|w| w.bits(1 << ($i + 16))) }; Ok(()) } } @@ -580,7 +580,7 @@ macro_rules! gpio { fn is_set_low(&self) -> Result { // NOTE(unsafe) atomic read with no side effects - let is_set_low = unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << $i) == 0 }; + let is_set_low = unsafe { (*$GPIOX::ptr()).odr().read().bits() & (1 << $i) == 0 }; Ok(is_set_low) } } @@ -598,7 +598,7 @@ macro_rules! gpio { fn is_low(&self) -> Result { // NOTE(unsafe) atomic read with no side effects - let is_low = unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << $i) == 0 }; + let is_low = unsafe { (*$GPIOX::ptr()).idr().read().bits() & (1 << $i) == 0 }; Ok(is_low) } } @@ -623,7 +623,7 @@ macro_rules! gpio { fn is_low(&self) -> Result { // NOTE(unsafe) atomic read with no side effects - let is_low = unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << $i) == 0 }; + let is_low = unsafe { (*$GPIOX::ptr()).idr().read().bits() & (1 << $i) == 0 }; Ok(is_low) } } diff --git a/src/i2c.rs b/src/i2c.rs index 33fa7a65..09477d9a 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -136,13 +136,15 @@ pub trait I2cExt { macro_rules! flush_txdr { ($i2c:expr) => { // If a pending TXIS flag is set, write dummy data to TXDR - if $i2c.isr.read().txis().bit_is_set() { - $i2c.txdr.write(|w| w.txdata().bits(0)); + if $i2c.isr().read().txis().bit_is_set() { + unsafe { + $i2c.txdr().write(|w| w.txdata().bits(0)); + } } // If TXDR is not flagged as empty, write 1 to flush it - if $i2c.isr.read().txe().bit_is_set() { - $i2c.isr.write(|w| w.txe().set_bit()); + if $i2c.isr().read().txe().bit_is_set() { + $i2c.isr().write(|w| w.txe().set_bit()); } }; } @@ -150,18 +152,19 @@ macro_rules! flush_txdr { macro_rules! busy_wait { ($i2c:expr, $flag:ident, $variant:ident) => { loop { - let isr = $i2c.isr.read(); + let isr = $i2c.isr().read(); if isr.$flag().$variant() { break; } else if isr.berr().bit_is_set() { - $i2c.icr.write(|w| w.berrcf().set_bit()); + $i2c.icr().write(|w| w.berrcf().set_bit()); return Err(Error::BusError); } else if isr.arlo().bit_is_set() { - $i2c.icr.write(|w| w.arlocf().set_bit()); + $i2c.icr().write(|w| w.arlocf().set_bit()); return Err(Error::ArbitrationLost); } else if isr.nackf().bit_is_set() { - $i2c.icr.write(|w| w.stopcf().set_bit().nackcf().set_bit()); + $i2c.icr() + .write(|w| w.stopcf().set_bit().nackcf().set_bit()); flush_txdr!($i2c); return Err(Error::Nack); } else { @@ -220,21 +223,23 @@ macro_rules! i2c { } // Make sure the I2C unit is disabled so we can configure it - i2c.cr1.modify(|_, w| w.pe().clear_bit()); + i2c.cr1().modify(|_, w| w.pe().clear_bit()); // Setup protocol timings let timing_bits = config.timing_bits(<$I2CX as RccBus>::Bus::get_frequency(&rcc.clocks)); - i2c.timingr.write(|w| unsafe { w.bits(timing_bits) }); + i2c.timingr().write(|w| unsafe { w.bits(timing_bits) }); // Enable the I2C processing - i2c.cr1.modify(|_, w| { - w.pe() - .set_bit() - .dnf() - .bits(config.digital_filter) - .anfoff() - .bit(!config.analog_filter) - }); + unsafe { + i2c.cr1().modify(|_, w| { + w.pe() + .set_bit() + .dnf() + .bits(config.digital_filter) + .anfoff() + .bit(!config.analog_filter) + }); + } I2c { i2c, sda, scl } } @@ -267,12 +272,12 @@ macro_rules! i2c { // Wait for any previous address sequence to end automatically. // This could be up to 50% of a bus cycle (ie. up to 0.5/freq) - while self.i2c.cr2.read().start().bit_is_set() {}; + while self.i2c.cr2().read().start().bit_is_set() {}; // Set START and prepare to send `bytes`. // The START bit can be set even if the bus is BUSY or // I2C is in slave mode. - self.i2c.cr2.write(|w| { + self.i2c.cr2().write(|w| unsafe { w // Start transfer .start().set_bit() @@ -294,14 +299,14 @@ macro_rules! i2c { busy_wait!(self.i2c, txis, bit_is_set); // Put byte on the wire - self.i2c.txdr.write(|w| { w.txdata().bits(*byte) }); + self.i2c.txdr().write(|w| unsafe { w.txdata().bits(*byte) }); } // Wait until the write finishes before beginning to read. busy_wait!(self.i2c, tc, bit_is_set); // reSTART and prepare to receive bytes into `buffer` - self.i2c.cr2.write(|w| { + self.i2c.cr2().write(|w| unsafe { w // Start transfer .start().set_bit() @@ -321,7 +326,7 @@ macro_rules! i2c { // Wait until we have received something busy_wait!(self.i2c, rxne, bit_is_set); - *byte = self.i2c.rxdr.read().rxdata().bits(); + *byte = self.i2c.rxdr().read().rxdata().bits(); } // automatic STOP @@ -336,7 +341,7 @@ macro_rules! i2c { fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> { assert!(bytes.len() < 256 && bytes.len() > 0); - self.i2c.cr2.modify(|_, w| { + self.i2c.cr2().modify(|_, w| unsafe { w // Start transfer .start().set_bit() @@ -356,7 +361,7 @@ macro_rules! i2c { busy_wait!(self.i2c, txis, bit_is_set); // Put byte on the wire - self.i2c.txdr.write(|w| w.txdata().bits(*byte) ); + self.i2c.txdr().write(|w| unsafe { w.txdata().bits(*byte) } ); } // automatic STOP @@ -374,12 +379,12 @@ macro_rules! i2c { // Wait for any previous address sequence to end automatically. // This could be up to 50% of a bus cycle (ie. up to 0.5/freq) - while self.i2c.cr2.read().start().bit_is_set() {}; + while self.i2c.cr2().read().start().bit_is_set() {}; // Set START and prepare to receive bytes into `buffer`. // The START bit can be set even if the bus // is BUSY or I2C is in slave mode. - self.i2c.cr2.modify(|_, w| { + self.i2c.cr2().modify(|_, w| unsafe { w // Start transfer .start().set_bit() @@ -397,7 +402,7 @@ macro_rules! i2c { // Wait until we have received something busy_wait!(self.i2c, rxne, bit_is_set); - *byte = self.i2c.rxdr.read().rxdata().bits(); + *byte = self.i2c.rxdr().read().rxdata().bits(); } // automatic STOP diff --git a/src/independent_watchdog.rs b/src/independent_watchdog.rs index 051047cb..3462f92a 100644 --- a/src/independent_watchdog.rs +++ b/src/independent_watchdog.rs @@ -12,7 +12,7 @@ //! //! Originally from stm32h7-hal, adapted for stm32g4xx-hal use crate::{ - stm32::{iwdg::pr::PR_A, IWDG}, + stm32::{iwdg::pr::PR, IWDG}, time::MicroSecond, }; use fugit::ExtU32; @@ -25,37 +25,33 @@ pub struct IndependentWatchdog { impl IndependentWatchdog { const CLOCK_SPEED: u32 = 32000; const MAX_COUNTER_VALUE: u32 = 0x00000FFF; - const MAX_MILLIS_FOR_PRESCALER: [(PR_A, u32); 8] = [ + const MAX_MILLIS_FOR_PRESCALER: [(PR, u32); 7] = [ ( - PR_A::DivideBy4, + PR::DivideBy4, (Self::MAX_COUNTER_VALUE * 1000) / (Self::CLOCK_SPEED / 4), ), ( - PR_A::DivideBy8, + PR::DivideBy8, (Self::MAX_COUNTER_VALUE * 1000) / (Self::CLOCK_SPEED / 8), ), ( - PR_A::DivideBy16, + PR::DivideBy16, (Self::MAX_COUNTER_VALUE * 1000) / (Self::CLOCK_SPEED / 16), ), ( - PR_A::DivideBy32, + PR::DivideBy32, (Self::MAX_COUNTER_VALUE * 1000) / (Self::CLOCK_SPEED / 32), ), ( - PR_A::DivideBy64, + PR::DivideBy64, (Self::MAX_COUNTER_VALUE * 1000) / (Self::CLOCK_SPEED / 64), ), ( - PR_A::DivideBy128, + PR::DivideBy128, (Self::MAX_COUNTER_VALUE * 1000) / (Self::CLOCK_SPEED / 128), ), ( - PR_A::DivideBy256, - (Self::MAX_COUNTER_VALUE * 1000) / (Self::CLOCK_SPEED / 256), - ), - ( - PR_A::DivideBy256bis, + PR::DivideBy256, (Self::MAX_COUNTER_VALUE * 1000) / (Self::CLOCK_SPEED / 256), ), ]; @@ -67,7 +63,7 @@ impl IndependentWatchdog { /// Feed the watchdog, resetting the timer to 0 pub fn feed(&mut self) { - self.iwdg.kr.write(|w| w.key().reset()); + self.iwdg.kr().write(|w| w.key().feed()); } /// Start the watchdog where it must be fed before the max time is over and @@ -77,27 +73,27 @@ impl IndependentWatchdog { let max_window_time: MicroSecond = max_window_time.into(); // Start the watchdog - self.iwdg.kr.write(|w| w.key().start()); + self.iwdg.kr().write(|w| w.key().start()); // Enable register access - self.iwdg.kr.write(|w| w.key().enable()); + self.iwdg.kr().write(|w| w.key().unlock()); // Set the prescaler let (prescaler, _) = Self::MAX_MILLIS_FOR_PRESCALER .iter() .find(|(_, max_millis)| *max_millis >= max_window_time.to_millis()) .expect("IWDG max time is greater than is possible"); - while self.iwdg.sr.read().pvu().bit_is_set() { + while self.iwdg.sr().read().pvu().bit_is_set() { cortex_m::asm::nop(); } - self.iwdg.pr.write(|w| w.pr().variant(*prescaler)); + self.iwdg.pr().write(|w| w.pr().variant(*prescaler)); // Reset the window value - while self.iwdg.sr.read().wvu().bit_is_set() { + while self.iwdg.sr().read().wvu().bit_is_set() { cortex_m::asm::nop(); } self.iwdg - .winr - .write(|w| w.win().bits(Self::MAX_COUNTER_VALUE as u16)); + .winr() + .write(|w| unsafe { w.win().bits(Self::MAX_COUNTER_VALUE as u16) }); // Calculate the counter values let reload_value = max_window_time.to_millis() * (Self::CLOCK_SPEED / 1000) @@ -106,25 +102,27 @@ impl IndependentWatchdog { / Self::get_prescaler_divider(prescaler); // Set the reload value - while self.iwdg.sr.read().rvu().bit_is_set() { + while self.iwdg.sr().read().rvu().bit_is_set() { cortex_m::asm::nop(); } - self.iwdg.rlr.write(|w| w.rl().bits(reload_value as u16)); + self.iwdg + .rlr() + .write(|w| unsafe { w.rl().bits(reload_value as u16) }); self.feed(); // Enable register access - self.iwdg.kr.write(|w| w.key().enable()); + self.iwdg.kr().write(|w| w.key().unlock()); // Set the window value - while self.iwdg.sr.read().wvu().bit_is_set() { + while self.iwdg.sr().read().wvu().bit_is_set() { cortex_m::asm::nop(); } self.iwdg - .winr - .write(|w| w.win().bits((reload_value - window_value) as u16)); + .winr() + .write(|w| unsafe { w.win().bits((reload_value - window_value) as u16) }); // Wait until everything is set - while self.iwdg.sr.read().bits() != 0 { + while self.iwdg.sr().read().bits() != 0 { cortex_m::asm::nop(); } @@ -136,16 +134,15 @@ impl IndependentWatchdog { self.start_windowed(0_u32.millis(), max_time.into()); } - fn get_prescaler_divider(prescaler: &PR_A) -> u32 { + fn get_prescaler_divider(prescaler: &PR) -> u32 { match prescaler { - PR_A::DivideBy4 => 4, - PR_A::DivideBy8 => 8, - PR_A::DivideBy16 => 16, - PR_A::DivideBy32 => 32, - PR_A::DivideBy64 => 64, - PR_A::DivideBy128 => 128, - PR_A::DivideBy256 => 256, - PR_A::DivideBy256bis => 256, + PR::DivideBy4 => 4, + PR::DivideBy8 => 8, + PR::DivideBy16 => 16, + PR::DivideBy32 => 32, + PR::DivideBy64 => 64, + PR::DivideBy128 => 128, + PR::DivideBy256 => 256, } } } diff --git a/src/opamp.rs b/src/opamp.rs index 0b549229..98cf644b 100644 --- a/src/opamp.rs +++ b/src/opamp.rs @@ -290,36 +290,36 @@ macro_rules! opamps { pub struct $opamp; impl LookupPgaGain for $opamp { - type PgaGainReg = crate::stm32::opamp::[<$opampreg _csr>]::PGA_GAIN_A; + type PgaGainReg = crate::stm32::opamp::[<$opampreg _csr>]::PGA_GAIN; fn pga_gain(mode: PgaMode, gain: Gain) -> Self::PgaGainReg { - use crate::stm32::opamp::[<$opampreg _csr>]::PGA_GAIN_A; + use crate::stm32::opamp::[<$opampreg _csr>]::PGA_GAIN; match (mode, gain) { - (PgaMode::Pga, Gain::Gain2) => PGA_GAIN_A::Gain2, - (PgaMode::Pga, Gain::Gain4) => PGA_GAIN_A::Gain4, - (PgaMode::Pga, Gain::Gain8) => PGA_GAIN_A::Gain8, - (PgaMode::Pga, Gain::Gain16) => PGA_GAIN_A::Gain16, - (PgaMode::Pga, Gain::Gain32) => PGA_GAIN_A::Gain32, - (PgaMode::Pga, Gain::Gain64) => PGA_GAIN_A::Gain64, - (PgaMode::PgaExternalFilter, Gain::Gain2) => PGA_GAIN_A::Gain2FilteringVinm0, - (PgaMode::PgaExternalFilter, Gain::Gain4) => PGA_GAIN_A::Gain4FilteringVinm0, - (PgaMode::PgaExternalFilter, Gain::Gain8) => PGA_GAIN_A::Gain8FilteringVinm0, - (PgaMode::PgaExternalFilter, Gain::Gain16) => PGA_GAIN_A::Gain16FilteringVinm0, - (PgaMode::PgaExternalFilter, Gain::Gain32) => PGA_GAIN_A::Gain32FilteringVinm0, - (PgaMode::PgaExternalFilter, Gain::Gain64) => PGA_GAIN_A::Gain64FilteringVinm0, - (PgaMode::PgaExternalBias, Gain::Gain2) => PGA_GAIN_A::Gain2InputVinm0, - (PgaMode::PgaExternalBias, Gain::Gain4) => PGA_GAIN_A::Gain4InputVinm0, - (PgaMode::PgaExternalBias, Gain::Gain8) => PGA_GAIN_A::Gain8InputVinm0, - (PgaMode::PgaExternalBias, Gain::Gain16) => PGA_GAIN_A::Gain16InputVinm0, - (PgaMode::PgaExternalBias, Gain::Gain32) => PGA_GAIN_A::Gain32InputVinm0, - (PgaMode::PgaExternalBias, Gain::Gain64) => PGA_GAIN_A::Gain64InputVinm0, - (PgaMode::PgaExternalBiasAndFilter, Gain::Gain2) => PGA_GAIN_A::Gain2InputVinm0filteringVinm1, - (PgaMode::PgaExternalBiasAndFilter, Gain::Gain4) => PGA_GAIN_A::Gain4InputVinm0filteringVinm1, - (PgaMode::PgaExternalBiasAndFilter, Gain::Gain8) => PGA_GAIN_A::Gain8InputVinm0filteringVinm1, - (PgaMode::PgaExternalBiasAndFilter, Gain::Gain16) => PGA_GAIN_A::Gain16InputVinm0filteringVinm1, - (PgaMode::PgaExternalBiasAndFilter, Gain::Gain32) => PGA_GAIN_A::Gain32InputVinm0filteringVinm1, - (PgaMode::PgaExternalBiasAndFilter, Gain::Gain64) => PGA_GAIN_A::Gain64InputVinm0filteringVinm1, + (PgaMode::Pga, Gain::Gain2) => PGA_GAIN::Gain2, + (PgaMode::Pga, Gain::Gain4) => PGA_GAIN::Gain4, + (PgaMode::Pga, Gain::Gain8) => PGA_GAIN::Gain8, + (PgaMode::Pga, Gain::Gain16) => PGA_GAIN::Gain16, + (PgaMode::Pga, Gain::Gain32) => PGA_GAIN::Gain32, + (PgaMode::Pga, Gain::Gain64) => PGA_GAIN::Gain64, + (PgaMode::PgaExternalFilter, Gain::Gain2) => PGA_GAIN::Gain2FilteringVinm0, + (PgaMode::PgaExternalFilter, Gain::Gain4) => PGA_GAIN::Gain4FilteringVinm0, + (PgaMode::PgaExternalFilter, Gain::Gain8) => PGA_GAIN::Gain8FilteringVinm0, + (PgaMode::PgaExternalFilter, Gain::Gain16) => PGA_GAIN::Gain16FilteringVinm0, + (PgaMode::PgaExternalFilter, Gain::Gain32) => PGA_GAIN::Gain32FilteringVinm0, + (PgaMode::PgaExternalFilter, Gain::Gain64) => PGA_GAIN::Gain64FilteringVinm0, + (PgaMode::PgaExternalBias, Gain::Gain2) => PGA_GAIN::Gain2InputVinm0, + (PgaMode::PgaExternalBias, Gain::Gain4) => PGA_GAIN::Gain4InputVinm0, + (PgaMode::PgaExternalBias, Gain::Gain8) => PGA_GAIN::Gain8InputVinm0, + (PgaMode::PgaExternalBias, Gain::Gain16) => PGA_GAIN::Gain16InputVinm0, + (PgaMode::PgaExternalBias, Gain::Gain32) => PGA_GAIN::Gain32InputVinm0, + (PgaMode::PgaExternalBias, Gain::Gain64) => PGA_GAIN::Gain64InputVinm0, + (PgaMode::PgaExternalBiasAndFilter, Gain::Gain2) => PGA_GAIN::Gain2InputVinm0filteringVinm1, + (PgaMode::PgaExternalBiasAndFilter, Gain::Gain4) => PGA_GAIN::Gain4InputVinm0filteringVinm1, + (PgaMode::PgaExternalBiasAndFilter, Gain::Gain8) => PGA_GAIN::Gain8InputVinm0filteringVinm1, + (PgaMode::PgaExternalBiasAndFilter, Gain::Gain16) => PGA_GAIN::Gain16InputVinm0filteringVinm1, + (PgaMode::PgaExternalBiasAndFilter, Gain::Gain32) => PGA_GAIN::Gain32InputVinm0filteringVinm1, + (PgaMode::PgaExternalBiasAndFilter, Gain::Gain64) => PGA_GAIN::Gain64InputVinm0filteringVinm1, } } } @@ -327,32 +327,32 @@ macro_rules! opamps { impl $opamp { #[inline(always)] unsafe fn _reset() { - (*crate::stm32::OPAMP::ptr()).[<$opampreg _csr>].reset() + (*crate::stm32::OPAMP::ptr()).[<$opampreg _csr>]().reset() } #[inline(always)] unsafe fn _disable_output() { - (*crate::stm32::OPAMP::ptr()).[<$opampreg _csr>].modify(|_, w| - w.opaintoen().adcchannel()) + (*crate::stm32::OPAMP::ptr()).[<$opampreg _csr>]().modify(|_, w| + w.opaintoen().adcchannel()); } #[inline(always)] unsafe fn _enable_output() { - (*crate::stm32::OPAMP::ptr()).[<$opampreg _csr>].modify(|_, w| - w.opaintoen().output_pin()) + (*crate::stm32::OPAMP::ptr()).[<$opampreg _csr>]().modify(|_, w| + w.opaintoen().output_pin()); } #[inline(always)] unsafe fn _lock() { // Write the lock bit - (*crate::stm32::OPAMP::ptr()).[<$opampreg _csr>].modify(|_, w| + (*crate::stm32::OPAMP::ptr()).[<$opampreg _csr>]().modify(|_, w| w.lock().set_bit()); // Write the lock bit for the corresponding TCMR register. // We don't currently expose TCMR functionality, but presumably // the user doesn't want anything changing if they care to set // the lock bit. - (*crate::stm32::OPAMP::ptr()).[<$opampreg _tcmr>].modify(|_, w| - w.lock().set_bit()) + (*crate::stm32::OPAMP::ptr()).[<$opampreg _tcmr>]().modify(|_, w| + w.lock().set_bit()); } } @@ -531,7 +531,7 @@ macro_rules! opamps { ) -> ( $(Disabled::<$opamp>,)* ) { - rcc.rb.apb2enr.modify(|_, w| w.syscfgen().set_bit()); + rcc.rb.apb2enr().modify(|_, w| w.syscfgen().set_bit()); ( $(Disabled::<$opamp> { opamp: PhantomData },)* @@ -581,9 +581,9 @@ macro_rules! opamps { ) -> Follower<$opamp, $input, InternalOutput> { let input = input.into(); unsafe { - use crate::stm32::opamp::[<$opampreg _csr>]::OPAINTOEN_A; + use crate::stm32::opamp::[<$opampreg _csr>]::OPAINTOEN; (*crate::stm32::OPAMP::ptr()) - .[<$opampreg _csr>] + .[<$opampreg _csr>]() .write(|csr_w| csr_w .vp_sel() @@ -591,7 +591,7 @@ macro_rules! opamps { .vm_sel() .output() .opaintoen() - .variant(OPAINTOEN_A::Adcchannel) + .variant(OPAINTOEN::Adcchannel) .opaen() .enabled() ); @@ -665,16 +665,16 @@ macro_rules! opamps { let non_inverting = non_inverting.into(); let inverting = inverting.into(); unsafe { - use crate::stm32::opamp::[<$opampreg _csr>]::OPAINTOEN_A; + use crate::stm32::opamp::[<$opampreg _csr>]::OPAINTOEN; (*crate::stm32::OPAMP::ptr()) - .[<$opampreg _csr>] + .[<$opampreg _csr>]() .write(|csr_w| csr_w.vp_sel() .$non_inverting_mask() .vm_sel() .$inverting_mask() .opaintoen() - .variant(OPAINTOEN_A::Adcchannel) + .variant(OPAINTOEN::Adcchannel) .opaen() .enabled() ); @@ -725,10 +725,10 @@ macro_rules! opamps { /// Configures the opamp for programmable gain operation. unsafe fn write_pga_reg(gain: Gain, mode: PgaMode, output_enable: bool) { - use crate::stm32::opamp::[<$opampreg _csr>]::OPAINTOEN_A; + use crate::stm32::opamp::[<$opampreg _csr>]::OPAINTOEN; (*crate::stm32::OPAMP::ptr()) - .[<$opampreg _csr>] + .[<$opampreg _csr>]() .write(|csr_w| csr_w.vp_sel() .$non_inverting_mask() @@ -738,8 +738,8 @@ macro_rules! opamps { .variant($opamp::pga_gain(mode, gain)) .opaintoen() .variant(match output_enable { - true => OPAINTOEN_A::OutputPin, - false => OPAINTOEN_A::Adcchannel, + true => OPAINTOEN::OutputPin, + false => OPAINTOEN::Adcchannel, }) .opaen() .enabled() @@ -864,7 +864,8 @@ macro_rules! opamps { }; } -#[cfg(any(feature = "stm32g431", feature = "stm32g441", feature = "stm32g471",))] +// TODO: Figure out a way to not duplicate this 3 times +#[cfg(any(feature = "stm32g431", feature = "stm32g441"))] opamps! { Opamp1 => opamp1: { vinm0: crate::gpio::gpioa::PA3, @@ -911,6 +912,67 @@ opamps! { }, } +#[cfg(any(feature = "stm32g471", feature = "stm32g491", feature = "stm32g4a1"))] +opamps! { + Opamp1 => opamp1: { + vinm0: crate::gpio::gpioa::PA3, + vinm1: crate::gpio::gpioc::PC5, + inverting: { + crate::gpio::gpioa::PA3: vinm0, + crate::gpio::gpioc::PC5: vinm1, + }, + non_inverting: { + crate::gpio::gpioa::PA1: vinp0, + crate::gpio::gpioa::PA3: vinp1, + crate::gpio::gpioa::PA7: vinp2, + }, + output: crate::gpio::gpioa::PA2, + }, + Opamp2 => opamp2: { + vinm0: crate::gpio::gpioa::PA5, + vinm1: crate::gpio::gpioc::PC5, + inverting: { + crate::gpio::gpioa::PA5: vinm0, + crate::gpio::gpioc::PC5: vinm1, + }, + non_inverting: { + crate::gpio::gpioa::PA7: vinp0, + crate::gpio::gpiob::PB14: vinp1, + crate::gpio::gpiob::PB0: vinp2, + crate::gpio::gpiod::PD14: vinp3, + }, + output: crate::gpio::gpioa::PA6, + }, + Opamp3 => opamp3: { + vinm0: crate::gpio::gpiob::PB2, + vinm1: crate::gpio::gpiob::PB10, + inverting: { + crate::gpio::gpiob::PB2: vinm0, + crate::gpio::gpiob::PB10: vinm1, + }, + non_inverting: { + crate::gpio::gpiob::PB0: vinp0, + crate::gpio::gpiob::PB13: vinp1, + crate::gpio::gpioa::PA1: vinp2, + }, + output: crate::gpio::gpiob::PB1, + }, + Opamp6 => opamp6: { + vinm0: crate::gpio::gpioa::PA1, + vinm1: crate::gpio::gpiob::PB1, + inverting: { + crate::gpio::gpioa::PA1: vinm0, + crate::gpio::gpiob::PB1: vinm1, + }, + non_inverting: { + crate::gpio::gpiob::PB12: vinp0, + crate::gpio::gpiod::PD9: vinp1, + crate::gpio::gpiob::PB13: vinp2, + }, + output: crate::gpio::gpiob::PB11, + }, +} + #[cfg(any( feature = "stm32g473", feature = "stm32g474", diff --git a/src/pwm.rs b/src/pwm.rs index 5f27211d..102e1185 100644 --- a/src/pwm.rs +++ b/src/pwm.rs @@ -874,7 +874,7 @@ pins! { feature = "stm32g483", feature = "stm32g484", feature = "stm32g491", - feature = "stm32g4a1" + feature = "stm32g4a1", ))] pins! { TIM20: @@ -1174,21 +1174,21 @@ macro_rules! tim_hal { }; // Write prescale - tim.psc.write(|w| { unsafe { w.psc().bits(prescale as u16) } }); + tim.psc().write(|w| { unsafe { w.psc().bits(prescale as u16) } }); // Write period - tim.arr.write(|w| { unsafe { w.arr().bits(period.into()) } }); + tim.arr().write(|w| { unsafe { w.arr().bits(period.into()) } }); // BDTR: Advanced-control timers $( // Set CCxP = OCxREF / CCxNP = !OCxREF // Refer to RM0433 Rev 6 - Table 324. - tim.$bdtr.write(|w| + tim.$bdtr().write(|w| w.moe().$moe_set() ); )* - tim.cr1.write(|w| w.cen().set_bit()); + tim.cr1().write(|w| w.cen().set_bit()); unsafe { MaybeUninit::::uninit().assume_init() } } @@ -1246,20 +1246,20 @@ macro_rules! tim_hal { }; // Write prescaler - tim.psc.write(|w| unsafe { w.psc().bits(prescaler as u16) }); + tim.psc().write(|w| unsafe { w.psc().bits(prescaler as u16) }); // Write period - tim.arr.write(|w| unsafe { w.arr().bits(period.into()) }); + tim.arr().write(|w| unsafe { w.arr().bits(period.into()) }); $( let (dtg, ckd) = calculate_deadtime(self.base_freq, self.deadtime); match ckd { - 1 => tim.cr1.modify(|_, w| unsafe { w.ckd().bits(0) }), - 2 => tim.cr1.modify(|_, w| unsafe { w.ckd().bits(1) }), - 4 => tim.cr1.modify(|_, w| unsafe { w.ckd().bits(2) }), + 1 => tim.cr1().modify(|_, w| unsafe { w.ckd().bits(0) }), + 2 => tim.cr1().modify(|_, w| unsafe { w.ckd().bits(1) }), + 4 => tim.cr1().modify(|_, w| unsafe { w.ckd().bits(2) }), _ => panic!("Should be unreachable, invalid deadtime prescaler"), - } + }; let bkp = match self.fault_polarity { Polarity::ActiveLow => false, @@ -1273,12 +1273,12 @@ macro_rules! tim_hal { // BKE = 1 -> break is enabled // BKP = 0 for active low, 1 for active high // Safety: bkf is set to a constant value (1) that is a valid value for the field per the reference manual - unsafe { tim.$bdtr.write(|w| w.dtg().bits(dtg).bkf().bits(1).aoe().clear_bit().bke().set_bit().bkp().bit(bkp).moe().$moe_set()); } + unsafe { tim.$bdtr().write(|w| w.dtg().bits(dtg).bkf().bits(1).aoe().clear_bit().bke().set_bit().bkp().bit(bkp).moe().$moe_set()); } // AF1: // BKINE = 1 -> break input enabled // BKINP should make input active high (BDTR BKP will set polarity), bit value varies timer to timer - tim.$af1.write(|w| w.bkine().set_bit().bkinp().$bkinp_setting()); + tim.$af1().write(|w| w.bkine().set_bit().bkinp().$bkinp_setting()); } $( // Not all timers that have break inputs have break2 inputs @@ -1289,37 +1289,37 @@ macro_rules! tim_hal { // BK2E = 1 -> break is enabled // BK2P = 0 for active low, 1 for active high // Safety: bkf is set to a constant value (1) that is a valid value for the field per the reference manual - unsafe { tim.$bdtr.write(|w| w.dtg().bits(dtg).bk2f().bits(1).aoe().clear_bit().bk2e().set_bit().bk2p().bit(bkp).moe().$moe_set()); } + unsafe { tim.$bdtr().write(|w| w.dtg().bits(dtg).bk2f().bits(1).aoe().clear_bit().bk2e().set_bit().bk2p().bit(bkp).moe().$moe_set()); } // AF2: // BKINE = 1 -> break input enabled // BKINP should make input active high (BDTR BKP will set polarity), bit value varies timer to timer - tim.af2.write(|w| w.bkine().set_bit().bk2inp().$bk2inp_setting()); + tim.af2().write(|w| w.bkine().set_bit().bk2inp().$bk2inp_setting()); } )* else { // Safety: the DTG field of BDTR allows any 8-bit deadtime value and the dtg variable is u8 unsafe { - tim.$bdtr.write(|w| w.dtg().bits(dtg).aoe().clear_bit().moe().$moe_set()); + tim.$bdtr().write(|w| w.dtg().bits(dtg).aoe().clear_bit().moe().$moe_set()); } } // BDTR: Advanced-control timers // Set CCxP = OCxREF / CCxNP = !OCxREF // Refer to RM0433 Rev 6 - Table 324. - tim.$bdtr.modify(|_, w| w.moe().$moe_set()); + tim.$bdtr().modify(|_, w| w.moe().$moe_set()); )* $( match self.alignment { Alignment::Left => { }, - Alignment::Right => { tim.cr1.modify(|_, w| w.dir().set_bit()); }, // Downcounter - Alignment::Center => { tim.cr1.modify(|_, w| unsafe { w.$cms().bits(3) }); } // Center-aligned mode 3 + Alignment::Right => { tim.cr1().modify(|_, w| w.dir().set_bit()); }, // Downcounter + Alignment::Center => { tim.cr1().modify(|_, w| unsafe { w.$cms().bits(3) }); } // Center-aligned mode 3 } )* - tim.cr1.modify(|_, w| w.cen().set_bit()); + tim.cr1().modify(|_, w| w.cen().set_bit()); unsafe { MaybeUninit::<(PwmControl<$TIMX, FAULT>, PINS::Channel)>::uninit() @@ -1427,19 +1427,19 @@ macro_rules! tim_hal { fn is_fault_active(&self) -> bool { let tim = unsafe { &*$TIMX::ptr() }; - !tim.$bdtr.read().moe().bit() + !tim.$bdtr().read().moe().bit() } fn clear_fault(&mut self) { let tim = unsafe { &*$TIMX::ptr() }; - tim.$bdtr.modify(|_, w| w.moe().set_bit()); + tim.$bdtr().modify(|_, w| w.moe().set_bit()); } fn set_fault(&mut self) { let tim = unsafe { &*$TIMX::ptr() }; - tim.$bdtr.modify(|_, w| w.moe().clear_bit()); + tim.$bdtr().modify(|_, w| w.moe().clear_bit()); } } )* @@ -1532,7 +1532,7 @@ macro_rules! tim_pin_hal { // Even though the field is 20 bits long for 16-bit counters, only 16 bits are // valid, so we convert to the appropriate type. - let arr = tim.arr.read().arr().bits() as $typ; + let arr = tim.arr().read().arr().bits() as $typ; // One PWM cycle is ARR+1 counts long // Valid PWM duty cycles are 0 to ARR+1 @@ -1558,12 +1558,12 @@ macro_rules! tim_pin_hal { fn ccer_enable(&mut self) { let tim = unsafe { &*$TIMX::ptr() }; - tim.ccer.modify(|_, w| w.$ccxe().set_bit()); + tim.ccer().modify(|_, w| w.$ccxe().set_bit()); } fn ccer_disable(&mut self) { let tim = unsafe { &*$TIMX::ptr() }; - tim.ccer.modify(|_, w| w.$ccxe().clear_bit()); + tim.ccer().modify(|_, w| w.$ccxe().clear_bit()); } } @@ -1571,7 +1571,7 @@ macro_rules! tim_pin_hal { pub fn into_active_low(self) -> Pwm<$TIMX, $CH, COMP, ActiveLow, NPOL> { let tim = unsafe { &*$TIMX::ptr() }; - tim.ccer.modify(|_, w| w.$ccxp().set_bit()); + tim.ccer().modify(|_, w| w.$ccxp().set_bit()); Pwm { _channel: PhantomData, @@ -1587,7 +1587,7 @@ macro_rules! tim_pin_hal { pub fn into_active_high(self) -> Pwm<$TIMX, $CH, COMP, ActiveHigh, NPOL> { let tim = unsafe { &*$TIMX::ptr() }; - tim.ccer.modify(|_, w| w.$ccxp().clear_bit()); + tim.ccer().modify(|_, w| w.$ccxp().clear_bit()); Pwm { _channel: PhantomData, @@ -1606,12 +1606,12 @@ macro_rules! tim_pin_hal { fn ccer_enable(&mut self) { let tim = unsafe { &*$TIMX::ptr() }; - tim.ccer.modify(|_, w| w.$ccxe().set_bit()); + tim.ccer().modify(|_, w| w.$ccxe().set_bit()); } fn ccer_disable(&mut self) { let tim = unsafe { &*$TIMX::ptr() }; - tim.ccer.modify(|_, w| w.$ccxe().clear_bit()); + tim.ccer().modify(|_, w| w.$ccxe().clear_bit()); } } @@ -1620,12 +1620,12 @@ macro_rules! tim_pin_hal { fn ccer_enable(&mut self) { let tim = unsafe { &*$TIMX::ptr() }; - tim.ccer.modify(|_, w| w.$ccxe().set_bit().$ccxne().set_bit()); + tim.ccer().modify(|_, w| w.$ccxe().set_bit().$ccxne().set_bit()); } fn ccer_disable(&mut self) { let tim = unsafe { &*$TIMX::ptr() }; - tim.ccer.modify(|_, w| w.$ccxe().clear_bit().$ccxne().clear_bit()); + tim.ccer().modify(|_, w| w.$ccxe().clear_bit().$ccxne().clear_bit()); } } @@ -1635,7 +1635,7 @@ macro_rules! tim_pin_hal { // Make sure we aren't switching to complementary after we enable the channel let tim = unsafe { &*$TIMX::ptr() }; - let enabled = tim.ccer.read().$ccxe().bit(); + let enabled = tim.ccer().read().$ccxe().bit(); assert!(!enabled); @@ -1653,7 +1653,7 @@ macro_rules! tim_pin_hal { pub fn into_comp_active_low(self) -> Pwm<$TIMX, $CH, ComplementaryEnabled, POL, ActiveLow> { let tim = unsafe { &*$TIMX::ptr() }; - tim.ccer.modify(|_, w| w.$ccxnp().set_bit()); + tim.ccer().modify(|_, w| w.$ccxnp().set_bit()); Pwm { _channel: PhantomData, @@ -1669,7 +1669,7 @@ macro_rules! tim_pin_hal { pub fn into_comp_active_high(self) -> Pwm<$TIMX, $CH, ComplementaryEnabled, POL, ActiveHigh> { let tim = unsafe { &*$TIMX::ptr() }; - tim.ccer.modify(|_, w| w.$ccxnp().clear_bit()); + tim.ccer().modify(|_, w| w.$ccxnp().clear_bit()); Pwm { _channel: PhantomData, @@ -1806,19 +1806,19 @@ macro_rules! lptim_hal { assert!(arr > 0); // CFGR - tim.cfgr.modify(|_, w| unsafe { w.presc().bits(prescale) }); + tim.cfgr().modify(|_, w| unsafe { w.presc().bits(prescale) }); // Enable - tim.cr.modify(|_, w| w.enable().set_bit()); + tim.cr().modify(|_, w| w.enable().set_bit()); // Write ARR: LPTIM must be enabled - tim.arr.write(|w| unsafe { w.arr().bits(arr as u16) }); - while !tim.isr.read().arrok().bit_is_set() {} - tim.icr.write(|w| w.arrokcf().set_bit()); + tim.arr().write(|w| unsafe { w.arr().bits(arr as u16) }); + while !tim.isr().read().arrok().bit_is_set() {} + tim.icr().write(|w| w.arrokcf().set_bit()); // PWM output is disabled by default, disable the // entire timer - tim.cr.modify(|_, w| w.enable().clear_bit()); + tim.cr().modify(|_, w| w.enable().clear_bit()); unsafe { MaybeUninit::::uninit().assume_init() } } @@ -1834,33 +1834,33 @@ macro_rules! lptim_hal { // LPTIM only has one output, so we disable the // entire timer - tim.cr.modify(|_, w| w.enable().clear_bit()); + tim.cr().modify(|_, w| w.enable().clear_bit()); } fn enable(&mut self) { let tim = unsafe { &*$TIMX::ptr() }; - tim.cr.modify(|_, w| w.cntstrt().set_bit().enable().set_bit()); + tim.cr().modify(|_, w| w.cntstrt().set_bit().enable().set_bit()); } fn get_duty(&self) -> u16 { let tim = unsafe { &*$TIMX::ptr() }; - tim.cmp.read().cmp().bits() + tim.cmp().read().cmp().bits() } fn get_max_duty(&self) -> u16 { let tim = unsafe { &*$TIMX::ptr() }; - tim.arr.read().arr().bits() + tim.arr().read().arr().bits() } fn set_duty(&mut self, duty: u16) { let tim = unsafe { &*$TIMX::ptr() }; - tim.cmp.write(|w| unsafe { w.cmp().bits(duty) }); - while !tim.isr.read().cmpok().bit_is_set() {} - tim.icr.write(|w| w.cmpokcf().set_bit()); + tim.cmp().write(|w| unsafe { w.cmp().bits(duty) }); + while !tim.isr().read().cmpok().bit_is_set() {} + tim.icr().write(|w| w.cmpokcf().set_bit()); } } )+ diff --git a/src/pwr.rs b/src/pwr.rs index bc5d8d0d..f451fbc7 100644 --- a/src/pwr.rs +++ b/src/pwr.rs @@ -103,10 +103,10 @@ pub(crate) fn current_vos() -> VoltageScale { // NOTE(unsafe): Read-only access let pwr = unsafe { &*PWR::ptr() }; - match pwr.cr1.read().vos().bits() { + match pwr.cr1().read().vos().bits() { 0b00 => unreachable!(), 0b01 => VoltageScale::Range1 { - enable_boost: pwr.cr5.read().r1mode().bit(), + enable_boost: pwr.cr5().read().r1mode().bit(), }, 0b10 => VoltageScale::Range2, 0b11 => unreachable!(), @@ -129,10 +129,10 @@ pub(crate) unsafe fn set_vos(vos: VoltageScale) { VoltageScale::Range1 { .. } => 0b01, VoltageScale::Range2 => 0b10, }; - pwr.cr1.modify(|_r, w| w.vos().bits(vos)); + pwr.cr1().modify(|_r, w| w.vos().bits(vos)); // Wait for ready - while pwr.sr2.read().vosf().bit() {} + while pwr.sr2().read().vosf().bit() {} } /// Set new voltage scale @@ -143,5 +143,5 @@ pub(crate) unsafe fn set_vos(vos: VoltageScale) { pub(crate) unsafe fn set_boost(enable_boost: bool) { let pwr = unsafe { &*PWR::ptr() }; let r1mode = !enable_boost; - pwr.cr5.modify(|_r, w| w.r1mode().bit(r1mode)); + pwr.cr5().modify(|_r, w| w.r1mode().bit(r1mode)); } diff --git a/src/rcc/clockout.rs b/src/rcc/clockout.rs index 07a3cdd9..b9f49944 100644 --- a/src/rcc/clockout.rs +++ b/src/rcc/clockout.rs @@ -11,12 +11,12 @@ pub struct Lsco { impl Lsco { pub fn enable(&self) { let rcc = unsafe { &(*RCC::ptr()) }; - rcc.bdcr.modify(|_, w| w.lscoen().set_bit()); + rcc.bdcr().modify(|_, w| w.lscoen().set_bit()); } pub fn disable(&self) { let rcc = unsafe { &(*RCC::ptr()) }; - rcc.bdcr.modify(|_, w| w.lscoen().clear_bit()); + rcc.bdcr().modify(|_, w| w.lscoen().clear_bit()); } pub fn release(self) -> LscoPin { @@ -41,7 +41,7 @@ impl LSCOExt for LscoPin { false } }; - rcc.rb.bdcr.modify(|_, w| w.lscosel().bit(src_select_bit)); + rcc.rb.bdcr().modify(|_, w| w.lscosel().bit(src_select_bit)); Lsco { pin: self.into_alternate(), } @@ -56,13 +56,13 @@ pub struct Mco { impl Mco { pub fn enable(&self) { let rcc = unsafe { &(*RCC::ptr()) }; - rcc.cfgr + rcc.cfgr() .modify(|_, w| unsafe { w.mcosel().bits(self.src_bits) }); } pub fn disable(&self) { let rcc = unsafe { &(*RCC::ptr()) }; - rcc.cfgr.modify(|_, w| unsafe { w.mcosel().bits(0) }); + rcc.cfgr().modify(|_, w| unsafe { w.mcosel().bits(0) }); } pub fn release(self) -> PIN { @@ -89,7 +89,7 @@ macro_rules! mco { Prescaler::Div64 => 0b110, _ => 0b111, }; - rcc.rb.cfgr.modify(|r, w| unsafe { + rcc.rb.cfgr().modify(|r, w| unsafe { w.bits((r.bits() & !(0b111 << 28)) | (psc_bits << 28)) }); diff --git a/src/rcc/enable.rs b/src/rcc/enable.rs index 4ab3d330..d8e4defc 100644 --- a/src/rcc/enable.rs +++ b/src/rcc/enable.rs @@ -89,7 +89,9 @@ bus! { feature = "stm32g473", feature = "stm32g474", feature = "stm32g483", - feature = "stm32g484" + feature = "stm32g484", + feature = "stm32g491", + feature = "stm32g4a1", ))] bus! { ADC3 => (AHB2, 14), @@ -158,6 +160,16 @@ bus! { FDCAN2 => (APB1_1, 25), } +#[cfg(any( + feature = "stm32g473", + feature = "stm32g474", + feature = "stm32g483", + feature = "stm32g484", +))] +bus! { + FDCAN3 => (APB1_1, 25), +} + #[cfg(any( feature = "stm32g471", feature = "stm32g473", @@ -167,10 +179,22 @@ bus! { ))] bus! { TIM5 => (APB1_1, 3), - UART5 => (APB1_1, 20), I2C4 => (APB1_2, 1), } +#[cfg(any( + feature = "stm32g471", + feature = "stm32g473", + feature = "stm32g474", + feature = "stm32g483", + feature = "stm32g484", + feature = "stm32g491", + feature = "stm32g4a1", +))] +bus! { + UART5 => (APB1_1, 20), +} + bus! { SYSCFG => (APB2, 0), TIM1 => (APB2, 11), @@ -198,10 +222,11 @@ bus! { feature = "stm32g473", feature = "stm32g474", feature = "stm32g483", - feature = "stm32g484" + feature = "stm32g484", + feature = "stm32g491", + feature = "stm32g4a1", ))] bus! { - FDCAN3 => (APB1_1, 25), TIM20 => (APB2, 20), } diff --git a/src/rcc/mod.rs b/src/rcc/mod.rs index c901ee7e..0503f574 100644 --- a/src/rcc/mod.rs +++ b/src/rcc/mod.rs @@ -188,7 +188,7 @@ impl Rcc { Self::configure_wait_states(&pwr_cfg, sys_freq); - self.rb.cfgr.modify(|_, w| unsafe { + self.rb.cfgr().modify(|_, w| unsafe { w.hpre() .bits(ahb_psc_bits) .ppre1() @@ -199,7 +199,7 @@ impl Rcc { .bits(sw_bits) }); - while self.rb.cfgr.read().sws().bits() != sw_bits {} + while self.rb.cfgr().read().sws().bits() != sw_bits {} // From RM: // The timer clock frequencies are automatically defined by hardware. There are two cases: @@ -232,15 +232,15 @@ impl Rcc { } pub fn unlock_rtc(&mut self) { - self.rb.apb1enr1.modify(|_, w| w.pwren().set_bit()); + self.rb.apb1enr1().modify(|_, w| w.pwren().set_bit()); let pwr = unsafe { &(*PWR::ptr()) }; - pwr.cr1.modify(|_, w| w.dbp().set_bit()); + pwr.cr1().modify(|_, w| w.dbp().set_bit()); } fn config_pll(&self, pll_cfg: PllConfig) -> PLLClocks { // Disable PLL - self.rb.cr.modify(|_, w| w.pllon().clear_bit()); - while self.rb.cr.read().pllrdy().bit_is_set() {} + self.rb.cr().modify(|_, w| w.pllon().clear_bit()); + while self.rb.cr().read().pllrdy().bit_is_set() {} // Enable the input clock feeding the PLL let (pll_input_freq, pll_src_bits) = match pll_cfg.mux { @@ -275,7 +275,7 @@ impl Rcc { .map(|r| ((pll_freq / r.divisor()).Hz(), r.register_setting())); // Set the M input divider, the N multiplier for the PLL, and the PLL source. - self.rb.pllcfgr.modify(|_, w| unsafe { + self.rb.pllcfgr().modify(|_, w| unsafe { // Set N, M, and source let w = w .plln() @@ -309,8 +309,8 @@ impl Rcc { }); // Enable PLL - self.rb.cr.modify(|_, w| w.pllon().set_bit()); - while self.rb.cr.read().pllrdy().bit_is_clear() {} + self.rb.cr().modify(|_, w| w.pllon().set_bit()); + while self.rb.cr().read().pllrdy().bit_is_clear() {} PLLClocks { r: r.map(|r| r.0), @@ -362,7 +362,7 @@ impl Rcc { unsafe { // Adjust flash wait states let flash = &(*FLASH::ptr()); - flash.acr.modify(|_, w| w.latency().bits(latency)) + flash.acr().modify(|_, w| w.latency().bits(latency)); } } @@ -379,11 +379,11 @@ impl Rcc { // The sequence to switch from Range11 normal mode to Range1 boost mode is: // 1. The system clock must be divided by 2 using the AHB prescaler before switching to a // higher system frequency. - let half_apb = (self.rb.cfgr.read().hpre().bits() + 1).clamp(0b1000, 0b1111); + let half_apb = (self.rb.cfgr().read().hpre().bits() + 1).clamp(0b1000, 0b1111); self.rb - .cfgr + .cfgr() .modify(|_r, w| unsafe { w.hpre().bits(half_apb) }); - while self.rb.cfgr.read().hpre().bits() != half_apb {} + while self.rb.cfgr().read().hpre().bits() != half_apb {} // 2. Clear the R1MODE bit is in the PWR_CR5 register. unsafe { pwr::set_boost(true) }; @@ -392,7 +392,7 @@ impl Rcc { Self::configure_wait_states(pwr_cfg, sys_freq); // 4. Configure and switch to new system frequency. - self.rb.cfgr.modify(|_, w| unsafe { + self.rb.cfgr().modify(|_, w| unsafe { w.ppre1() .bits(apb1_psc_bits) .ppre2() @@ -401,7 +401,7 @@ impl Rcc { .bits(sw_bits) }); - while self.rb.cfgr.read().sws().bits() != sw_bits {} + while self.rb.cfgr().read().sws().bits() != sw_bits {} // 5. Wait for at least 1us and then reconfigure the AHB prescaler to get the needed HCLK // clock frequency. @@ -412,41 +412,41 @@ impl Rcc { cortex_m::asm::delay(delay_cycles); self.rb - .cfgr + .cfgr() .modify(|_, w| unsafe { w.hpre().bits(ahb_psc_bits) }); } pub(crate) fn enable_hsi(&self) { - self.rb.cr.modify(|_, w| w.hsion().set_bit()); - while self.rb.cr.read().hsirdy().bit_is_clear() {} + self.rb.cr().modify(|_, w| w.hsion().set_bit()); + while self.rb.cr().read().hsirdy().bit_is_clear() {} } pub(crate) fn enable_hse(&self, bypass: bool) { self.rb - .cr + .cr() .modify(|_, w| w.hseon().set_bit().hsebyp().bit(bypass)); - while self.rb.cr.read().hserdy().bit_is_clear() {} + while self.rb.cr().read().hserdy().bit_is_clear() {} } pub(crate) fn enable_lse(&self, bypass: bool) { self.rb - .bdcr + .bdcr() .modify(|_, w| w.lseon().set_bit().lsebyp().bit(bypass)); - while self.rb.bdcr.read().lserdy().bit_is_clear() {} + while self.rb.bdcr().read().lserdy().bit_is_clear() {} } pub(crate) fn enable_lsi(&self) { - self.rb.csr.modify(|_, w| w.lsion().set_bit()); - while self.rb.csr.read().lsirdy().bit_is_clear() {} + self.rb.csr().modify(|_, w| w.lsion().set_bit()); + while self.rb.csr().read().lsirdy().bit_is_clear() {} } pub fn enable_hsi48(&self) { - self.rb.crrcr.modify(|_, w| w.hsi48on().set_bit()); - while self.rb.crrcr.read().hsi48rdy().bit_is_clear() {} + self.rb.crrcr().modify(|_, w| w.hsi48on().set_bit()); + while self.rb.crrcr().read().hsi48rdy().bit_is_clear() {} } pub fn get_reset_reason(&self) -> ResetReason { - let csr = self.rb.csr.read(); + let csr = self.rb.csr().read(); ResetReason { low_power: csr.lpwrstf().bit(), @@ -460,7 +460,7 @@ impl Rcc { } pub fn clear_reset_reason(&mut self) { - self.rb.csr.modify(|_, w| w.rmvf().set_bit()); + self.rb.csr().modify(|_, w| w.rmvf().set_bit()); } } @@ -531,16 +531,16 @@ pub struct AHB1 { impl AHB1 { #[inline(always)] fn enr(rcc: &RccRB) -> &rcc::AHB1ENR { - &rcc.ahb1enr + rcc.ahb1enr() } #[inline(always)] fn rstr(rcc: &RccRB) -> &rcc::AHB1RSTR { - &rcc.ahb1rstr + rcc.ahb1rstr() } #[allow(unused)] #[inline(always)] fn smenr(rcc: &RccRB) -> &rcc::AHB1SMENR { - &rcc.ahb1smenr + rcc.ahb1smenr() } } @@ -550,16 +550,16 @@ pub struct AHB2 { impl AHB2 { #[inline(always)] fn enr(rcc: &RccRB) -> &rcc::AHB2ENR { - &rcc.ahb2enr + rcc.ahb2enr() } #[inline(always)] fn rstr(rcc: &RccRB) -> &rcc::AHB2RSTR { - &rcc.ahb2rstr + rcc.ahb2rstr() } #[allow(unused)] #[inline(always)] fn smenr(rcc: &RccRB) -> &rcc::AHB2SMENR { - &rcc.ahb2smenr + rcc.ahb2smenr() } } @@ -570,17 +570,17 @@ impl AHB3 { #[allow(unused)] #[inline(always)] fn enr(rcc: &RccRB) -> &rcc::AHB3ENR { - &rcc.ahb3enr + rcc.ahb3enr() } #[allow(unused)] #[inline(always)] fn rstr(rcc: &RccRB) -> &rcc::AHB3RSTR { - &rcc.ahb3rstr + rcc.ahb3rstr() } #[allow(unused)] #[inline(always)] fn smenr(rcc: &RccRB) -> &rcc::AHB3SMENR { - &rcc.ahb3smenr + rcc.ahb3smenr() } } @@ -590,16 +590,16 @@ pub struct APB1_1 { impl APB1_1 { #[inline(always)] fn enr(rcc: &RccRB) -> &rcc::APB1ENR1 { - &rcc.apb1enr1 + rcc.apb1enr1() } #[inline(always)] fn rstr(rcc: &RccRB) -> &rcc::APB1RSTR1 { - &rcc.apb1rstr1 + rcc.apb1rstr1() } #[allow(unused)] #[inline(always)] fn smenr(rcc: &RccRB) -> &rcc::APB1SMENR1 { - &rcc.apb1smenr1 + rcc.apb1smenr1() } } @@ -609,16 +609,16 @@ pub struct APB1_2 { impl APB1_2 { #[inline(always)] fn enr(rcc: &RccRB) -> &rcc::APB1ENR2 { - &rcc.apb1enr2 + rcc.apb1enr2() } #[inline(always)] fn rstr(rcc: &RccRB) -> &rcc::APB1RSTR2 { - &rcc.apb1rstr2 + rcc.apb1rstr2() } #[allow(unused)] #[inline(always)] fn smenr(rcc: &RccRB) -> &rcc::APB1SMENR2 { - &rcc.apb1smenr2 + rcc.apb1smenr2() } } @@ -628,16 +628,16 @@ pub struct APB2 { impl APB2 { #[inline(always)] fn enr(rcc: &RccRB) -> &rcc::APB2ENR { - &rcc.apb2enr + rcc.apb2enr() } #[inline(always)] fn rstr(rcc: &RccRB) -> &rcc::APB2RSTR { - &rcc.apb2rstr + rcc.apb2rstr() } #[allow(unused)] #[inline(always)] fn smenr(rcc: &RccRB) -> &rcc::APB2SMENR { - &rcc.apb2smenr + rcc.apb2smenr() } } diff --git a/src/serial/usart.rs b/src/serial/usart.rs index d5779131..893b735d 100644 --- a/src/serial/usart.rs +++ b/src/serial/usart.rs @@ -166,25 +166,25 @@ macro_rules! uart_shared { /// Starts listening for an interrupt event pub fn listen(&mut self) { let usart = unsafe { &(*$USARTX::ptr()) }; - usart.cr1.modify(|_, w| w.rxneie().set_bit()); + usart.cr1().modify(|_, w| w.rxneie().set_bit()); } /// Stop listening for an interrupt event pub fn unlisten(&mut self) { let usart = unsafe { &(*$USARTX::ptr()) }; - usart.cr1.modify(|_, w| w.rxneie().clear_bit()); + usart.cr1().modify(|_, w| w.rxneie().clear_bit()); } /// Return true if the rx register is not empty (and can be read) pub fn is_rxne(&self) -> bool { let usart = unsafe { &(*$USARTX::ptr()) }; - usart.isr.read().rxne().bit_is_set() + usart.isr().read().rxne().bit_is_set() } /// Returns true if the rx fifo threshold has been reached. pub fn fifo_threshold_reached(&self) -> bool { let usart = unsafe { &(*$USARTX::ptr()) }; - usart.isr.read().rxft().bit_is_set() + usart.isr().read().rxft().bit_is_set() } } @@ -192,7 +192,7 @@ macro_rules! uart_shared { pub fn enable_dma(self) -> Rx<$USARTX, Pin, DMA> { // NOTE(unsafe) critical section prevents races cortex_m::interrupt::free(|_| unsafe { - let cr3 = &(*$USARTX::ptr()).cr3; + let cr3 = &(*$USARTX::ptr()).cr3(); cr3.modify(|_, w| w.dmar().set_bit()); }); @@ -208,7 +208,7 @@ macro_rules! uart_shared { pub fn disable_dma(self) -> Rx<$USARTX, Pin, NoDMA> { // NOTE(unsafe) critical section prevents races interrupt::free(|_| unsafe { - let cr3 = &(*$USARTX::ptr()).cr3; + let cr3 = &(*$USARTX::ptr()).cr3(); cr3.modify(|_, w| w.dmar().clear_bit()); }); @@ -225,22 +225,22 @@ macro_rules! uart_shared { fn read(&mut self) -> nb::Result { let usart = unsafe { &(*$USARTX::ptr()) }; - let isr = usart.isr.read(); + let isr = usart.isr().read(); Err( if isr.pe().bit_is_set() { - usart.icr.write(|w| w.pecf().set_bit()); + usart.icr().write(|w| w.pecf().set_bit()); nb::Error::Other(Error::Parity) } else if isr.fe().bit_is_set() { - usart.icr.write(|w| w.fecf().set_bit()); + usart.icr().write(|w| w.fecf().set_bit()); nb::Error::Other(Error::Framing) } else if isr.nf().bit_is_set() { - usart.icr.write(|w| w.ncf().set_bit()); + usart.icr().write(|w| w.ncf().set_bit()); nb::Error::Other(Error::Noise) } else if isr.ore().bit_is_set() { - usart.icr.write(|w| w.orecf().set_bit()); + usart.icr().write(|w| w.orecf().set_bit()); nb::Error::Other(Error::Overrun) } else if isr.rxne().bit_is_set() { - return Ok(usart.rdr.read().bits() as u8) + return Ok(usart.rdr().read().bits() as u8) } else { nb::Error::WouldBlock } @@ -260,25 +260,25 @@ macro_rules! uart_shared { /// Starts listening for an interrupt event pub fn listen(&mut self) { let usart = unsafe { &(*$USARTX::ptr()) }; - usart.cr1.modify(|_, w| w.txeie().set_bit()); + usart.cr1().modify(|_, w| w.txeie().set_bit()); } /// Stop listening for an interrupt event pub fn unlisten(&mut self) { let usart = unsafe { &(*$USARTX::ptr()) }; - usart.cr1.modify(|_, w| w.txeie().clear_bit()); + usart.cr1().modify(|_, w| w.txeie().clear_bit()); } /// Return true if the tx register is empty (and can accept data) pub fn is_txe(&self) -> bool { let usart = unsafe { &(*$USARTX::ptr()) }; - usart.isr.read().txe().bit_is_set() + usart.isr().read().txe().bit_is_set() } /// Returns true if the tx fifo threshold has been reached. pub fn fifo_threshold_reached(&self) -> bool { let usart = unsafe { &(*$USARTX::ptr()) }; - usart.isr.read().txft().bit_is_set() + usart.isr().read().txft().bit_is_set() } } @@ -286,7 +286,7 @@ macro_rules! uart_shared { pub fn enable_dma(self) -> Tx<$USARTX, Pin, DMA> { // NOTE(unsafe) critical section prevents races interrupt::free(|_| unsafe { - let cr3 = &(*$USARTX::ptr()).cr3; + let cr3 = &(*$USARTX::ptr()).cr3(); cr3.modify(|_, w| w.dmat().set_bit()); }); @@ -302,7 +302,7 @@ macro_rules! uart_shared { pub fn disable_dma(self) -> Tx<$USARTX, Pin, NoDMA> { // NOTE(unsafe) critical section prevents races interrupt::free(|_| unsafe { - let cr3 = &(*$USARTX::ptr()).cr3; + let cr3 = &(*$USARTX::ptr()).cr3(); cr3.modify(|_, w| w.dmat().clear_bit()); }); @@ -319,7 +319,7 @@ macro_rules! uart_shared { fn flush(&mut self) -> nb::Result<(), Self::Error> { let usart = unsafe { &(*$USARTX::ptr()) }; - if usart.isr.read().tc().bit_is_set() { + if usart.isr().read().tc().bit_is_set() { Ok(()) } else { Err(nb::Error::WouldBlock) @@ -328,8 +328,8 @@ macro_rules! uart_shared { fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> { let usart = unsafe { &(*$USARTX::ptr()) }; - if usart.isr.read().txe().bit_is_set() { - usart.tdr.write(|w| unsafe { w.bits(byte as u32) }); + if usart.isr().read().txe().bit_is_set() { + usart.tdr().write(|w| unsafe { w.bits(byte as u32) }); Ok(()) } else { Err(nb::Error::WouldBlock) @@ -379,7 +379,7 @@ macro_rules! uart_shared { /// changes. pub fn release(self) -> ($USARTX, TX, RX) { // Disable the UART as well as its clock. - self.tx.usart.cr1.modify(|_, w| w.ue().clear_bit()); + self.tx.usart.cr1().modify(|_, w| w.ue().clear_bit()); unsafe { let rcc_ptr = &(*RCC::ptr()); $USARTX::disable(rcc_ptr); @@ -392,7 +392,7 @@ macro_rules! uart_shared { #[inline(always)] fn address(&self) -> u32 { // unsafe: only the Tx part accesses the Tx register - &unsafe { &*<$USARTX>::ptr() }.tdr as *const _ as u32 + &unsafe { &*<$USARTX>::ptr() }.tdr() as *const _ as u32 } type MemSize = u8; @@ -404,7 +404,7 @@ macro_rules! uart_shared { #[inline(always)] fn address(&self) -> u32 { // unsafe: only the Rx part accesses the Rx register - &unsafe { &*<$USARTX>::ptr() }.rdr as *const _ as u32 + &unsafe { &*<$USARTX>::ptr() }.rdr() as *const _ as u32 } type MemSize = u8; @@ -464,21 +464,21 @@ macro_rules! uart_lp { // We need 16x oversampling. return Err(InvalidConfig); } - usart.brr.write(|w| unsafe { w.bits(div as u32) }); + usart.brr().write(|w| unsafe { w.bits(div as u32) }); // Reset the UART and disable it (UE=0) - usart.cr1.reset(); + usart.cr1().reset(); // Reset other registers to disable advanced USART features - usart.cr2.reset(); - usart.cr3.reset(); + usart.cr2().reset(); + usart.cr3().reset(); - usart.cr2.write(|w| unsafe { + usart.cr2().write(|w| unsafe { w.stop() .bits(config.stopbits.bits()) .swap() .bit(config.swap) }); - usart.cr3.write(|w| unsafe { + usart.cr3().write(|w| unsafe { w.txftcfg() .bits(config.tx_fifo_threshold.bits()) .rxftcfg() @@ -490,7 +490,7 @@ macro_rules! uart_lp { }); // Enable the UART and perform remaining configuration. - usart.cr1.write(|w| { + usart.cr1().write(|w| { w.ue() .set_bit() .te() @@ -526,26 +526,26 @@ macro_rules! uart_lp { /// Starts listening for an interrupt event pub fn listen(&mut self, event: Event) { match event { - Event::Rxne => self.tx.usart.cr1.modify(|_, w| w.rxneie().set_bit()), - Event::Txe => self.tx.usart.cr1.modify(|_, w| w.txeie().set_bit()), - Event::Idle => self.tx.usart.cr1.modify(|_, w| w.idleie().set_bit()), - _ => {} - } + Event::Rxne => self.tx.usart.cr1().modify(|_, w| w.rxneie().set_bit()), + Event::Txe => self.tx.usart.cr1().modify(|_, w| w.txeie().set_bit()), + Event::Idle => self.tx.usart.cr1().modify(|_, w| w.idleie().set_bit()), + _ => unimplemented!(), + }; } /// Stop listening for an interrupt event pub fn unlisten(&mut self, event: Event) { match event { - Event::Rxne => self.tx.usart.cr1.modify(|_, w| w.rxneie().clear_bit()), - Event::Txe => self.tx.usart.cr1.modify(|_, w| w.txeie().clear_bit()), - Event::Idle => self.tx.usart.cr1.modify(|_, w| w.idleie().clear_bit()), - _ => {} - } + Event::Rxne => self.tx.usart.cr1().modify(|_, w| w.rxneie().clear_bit()), + Event::Txe => self.tx.usart.cr1().modify(|_, w| w.txeie().clear_bit()), + Event::Idle => self.tx.usart.cr1().modify(|_, w| w.idleie().clear_bit()), + _ => unimplemented!(), + }; } /// Check if interrupt event is pending pub fn is_pending(&mut self, event: Event) -> bool { - (self.tx.usart.isr.read().bits() & event.val()) != 0 + (self.tx.usart.isr().read().bits() & event.val()) != 0 } /// Clear pending interrupt @@ -554,7 +554,7 @@ macro_rules! uart_lp { let mask: u32 = 0x123BFF; self.tx .usart - .icr + .icr() .write(|w| unsafe { w.bits(event.val() & mask) }); } } @@ -612,14 +612,14 @@ macro_rules! uart_full { // We need 16x oversampling. return Err(InvalidConfig); } - usart.brr.write(|w| unsafe { w.bits(div as u32) }); + usart.brr().write(|w| unsafe { w.bits(div as u32) }); // Reset the UART and disable it (UE=0) - usart.cr1.reset(); - usart.cr2.reset(); - usart.cr3.reset(); + usart.cr1().reset(); + usart.cr2().reset(); + usart.cr3().reset(); - usart.cr2.write(|w| unsafe { + usart.cr2().write(|w| unsafe { w.stop() .bits(config.stopbits.bits()) .swap() @@ -627,12 +627,12 @@ macro_rules! uart_full { }); if let Some(timeout) = config.receiver_timeout { - usart.cr1.write(|w| w.rtoie().set_bit()); - usart.cr2.modify(|_, w| w.rtoen().set_bit()); - usart.rtor.write(|w| unsafe { w.rto().bits(timeout) }); + usart.cr1().write(|w| w.rtoie().set_bit()); + usart.cr2().modify(|_, w| w.rtoen().set_bit()); + usart.rtor().write(|w| unsafe { w.rto().bits(timeout) }); } - usart.cr3.write(|w| unsafe { + usart.cr3().write(|w| unsafe { w.txftcfg() .bits(config.tx_fifo_threshold.bits()) .rxftcfg() @@ -644,7 +644,7 @@ macro_rules! uart_full { }); // Enable the UART and perform remaining configuration. - usart.cr1.modify(|_, w| { + usart.cr1().modify(|_, w| { w.ue() .set_bit() .te() @@ -680,26 +680,26 @@ macro_rules! uart_full { /// Starts listening for an interrupt event pub fn listen(&mut self, event: Event) { match event { - Event::Rxne => self.tx.usart.cr1.modify(|_, w| w.rxneie().set_bit()), - Event::Txe => self.tx.usart.cr1.modify(|_, w| w.txeie().set_bit()), - Event::Idle => self.tx.usart.cr1.modify(|_, w| w.idleie().set_bit()), - _ => {} - } + Event::Rxne => self.tx.usart.cr1().modify(|_, w| w.rxneie().set_bit()), + Event::Txe => self.tx.usart.cr1().modify(|_, w| w.txeie().set_bit()), + Event::Idle => self.tx.usart.cr1().modify(|_, w| w.idleie().set_bit()), + _ => unimplemented!(), + }; } /// Stop listening for an interrupt event pub fn unlisten(&mut self, event: Event) { match event { - Event::Rxne => self.tx.usart.cr1.modify(|_, w| w.rxneie().clear_bit()), - Event::Txe => self.tx.usart.cr1.modify(|_, w| w.txeie().clear_bit()), - Event::Idle => self.tx.usart.cr1.modify(|_, w| w.idleie().clear_bit()), - _ => {} - } + Event::Rxne => self.tx.usart.cr1().modify(|_, w| w.rxneie().clear_bit()), + Event::Txe => self.tx.usart.cr1().modify(|_, w| w.txeie().clear_bit()), + Event::Idle => self.tx.usart.cr1().modify(|_, w| w.idleie().clear_bit()), + _ => unimplemented!(), + }; } /// Check if interrupt event is pending pub fn is_pending(&mut self, event: Event) -> bool { - (self.tx.usart.isr.read().bits() & event.val()) != 0 + (self.tx.usart.isr().read().bits() & event.val()) != 0 } /// Clear pending interrupt @@ -708,7 +708,7 @@ macro_rules! uart_full { let mask: u32 = 0x123BFF; self.tx .usart - .icr + .icr() .write(|w| unsafe { w.bits(event.val() & mask) }); } } @@ -718,13 +718,13 @@ macro_rules! uart_full { /// Returns the current state of the ISR RTOF bit pub fn timeout_lapsed(&self) -> bool { let usart = unsafe { &(*$USARTX::ptr()) }; - usart.isr.read().rtof().bit_is_set() + usart.isr().read().rtof().bit_is_set() } /// Clear pending receiver timeout interrupt pub fn clear_timeout(&mut self) { let usart = unsafe { &(*$USARTX::ptr()) }; - usart.icr.write(|w| w.rtocf().set_bit()); + usart.icr().write(|w| w.rtocf().set_bit()); } } }; diff --git a/src/spi.rs b/src/spi.rs index 78cda675..27d94718 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -21,7 +21,6 @@ use crate::rcc::{Enable, GetBusFreq, Rcc, RccBus, Reset}; use crate::stm32::SPI4; use crate::stm32::{RCC, SPI1, SPI2, SPI3}; use crate::time::Hertz; -use core::cell::UnsafeCell; use core::ptr; pub use hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; @@ -118,7 +117,7 @@ macro_rules! spi { } // disable SS output - spi.cr2.write(|w| w.ssoe().clear_bit()); + spi.cr2().write(|w| w.ssoe().clear_bit()); let spi_freq = speed.into().raw(); let bus_freq = <$SPIX as RccBus>::Bus::get_frequency(&rcc.clocks).raw(); @@ -134,11 +133,11 @@ macro_rules! spi { _ => 0b111, }; - spi.cr2.write(|w| unsafe { + spi.cr2().write(|w| unsafe { w.frxth().set_bit().ds().bits(0b111).ssoe().clear_bit() }); - spi.cr1.write(|w| unsafe { + spi.cr1().write(|w| unsafe { w.cpha() .bit(mode.phase == Phase::CaptureOnSecondTransition) .cpol() @@ -173,7 +172,7 @@ macro_rules! spi { } pub fn enable_tx_dma(self) -> Spi<$SPIX, PINS> { - self.spi.cr2.modify(|_, w| w.txdmaen().set_bit()); + self.spi.cr2().modify(|_, w| w.txdmaen().set_bit()); Spi { spi: self.spi, pins: self.pins, @@ -195,7 +194,7 @@ macro_rules! spi { type Error = Error; fn read(&mut self) -> nb::Result { - let sr = self.spi.sr.read(); + let sr = self.spi.sr().read(); Err(if sr.ovr().bit_is_set() { nb::Error::Other(Error::Overrun) @@ -207,7 +206,7 @@ macro_rules! spi { // NOTE(read_volatile) read only 1 byte (the svd2rust API only allows // reading a half-word) return Ok(unsafe { - ptr::read_volatile(&self.spi.dr as *const _ as *const u8) + ptr::read_volatile(&self.spi.dr() as *const _ as *const u8) }); } else { nb::Error::WouldBlock @@ -215,7 +214,7 @@ macro_rules! spi { } fn send(&mut self, byte: u8) -> nb::Result<(), Error> { - let sr = self.spi.sr.read(); + let sr = self.spi.sr().read(); Err(if sr.ovr().bit_is_set() { nb::Error::Other(Error::Overrun) @@ -224,9 +223,9 @@ macro_rules! spi { } else if sr.crcerr().bit_is_set() { nb::Error::Other(Error::Crc) } else if sr.txe().bit_is_set() { - let dr = &self.spi.dr as *const _ as *const UnsafeCell; + let dr = self.spi.dr().as_ptr() as *mut u8; // NOTE(write_volatile) see note above - unsafe { ptr::write_volatile(UnsafeCell::raw_get(dr), byte) }; + unsafe { ptr::write_volatile(dr, byte) }; return Ok(()); } else { nb::Error::WouldBlock @@ -237,7 +236,7 @@ macro_rules! spi { #[inline(always)] fn address(&self) -> u32 { // unsafe: only the Tx part accesses the Tx register - &unsafe { &*<$SPIX>::ptr() }.dr as *const _ as u32 + &unsafe { &*<$SPIX>::ptr() }.dr() as *const _ as u32 } type MemSize = u8; diff --git a/src/syscfg.rs b/src/syscfg.rs index 19427bd8..b13833bb 100644 --- a/src/syscfg.rs +++ b/src/syscfg.rs @@ -15,7 +15,7 @@ impl SysCfgExt for SYSCFG { let rcc = &(*RCC::ptr()); // Enable clock. - bb::set(&rcc.apb2enr, 0); + bb::set(&rcc.apb2enr(), 0); // Stall the pipeline to work around erratum 2.1.13 (DM00037591) cortex_m::asm::dsb(); diff --git a/src/timer.rs b/src/timer.rs index b3d72267..26b89008 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -232,7 +232,7 @@ macro_rules! hal_ext_trgo { $( impl Timer<$TIM> { pub fn set_trigger_source(&mut self, trigger_source: TriggerSource) { - self.tim.cr2.modify(|_, w| unsafe {w.$mms().bits(trigger_source as u8)}); + self.tim.cr2().modify(|_, w| unsafe {w.$mms().bits(trigger_source as u8)}); } } )+ @@ -253,7 +253,7 @@ macro_rules! hal { match event { Event::TimeOut => { // Enable update event interrupt - self.tim.dier.write(|w| w.uie().set_bit()); + self.tim.dier().write(|w| w.uie().set_bit()); } } } @@ -266,7 +266,7 @@ macro_rules! hal { match event { Event::TimeOut => { // Clear interrupt flag - self.tim.sr.write(|w| w.uif().clear_bit()); + self.tim.sr().write(|w| w.uif().clear_bit()); } } } @@ -276,7 +276,7 @@ macro_rules! hal { match event { Event::TimeOut => { // Enable update event interrupt - self.tim.dier.write(|w| w.uie().clear_bit()); + self.tim.dier().write(|w| w.uie().clear_bit()); } } } @@ -284,7 +284,7 @@ macro_rules! hal { /// Releases the TIM peripheral pub fn release(self) -> $TIM { // pause counter - self.tim.cr1.modify(|_, w| w.cen().clear_bit()); + self.tim.cr1().modify(|_, w| w.cen().clear_bit()); self.tim } } @@ -297,33 +297,33 @@ macro_rules! hal { T: Into, { // pause - self.tim.cr1.modify(|_, w| w.cen().clear_bit()); + self.tim.cr1().modify(|_, w| w.cen().clear_bit()); // reset counter - self.tim.cnt.reset(); + self.tim.cnt().reset(); let ticks = crate::time::cycles(timeout.into(), self.clk); let psc = u16((ticks - 1) / (1 << 16)).unwrap(); - self.tim.psc.write(|w| unsafe {w.psc().bits(psc)} ); + self.tim.psc().write(|w| unsafe {w.psc().bits(psc)} ); // TODO: TIM2 and TIM5 are 32 bit let arr = u16(ticks / u32(psc + 1)).unwrap(); - self.tim.arr.write(|w| unsafe { w.bits(u32(arr)) }); + self.tim.arr().write(|w| unsafe { w.bits(u32(arr)) }); // Trigger update event to load the registers - self.tim.cr1.modify(|_, w| w.urs().set_bit()); - self.tim.egr.write(|w| w.ug().set_bit()); - self.tim.cr1.modify(|_, w| w.urs().clear_bit()); + self.tim.cr1().modify(|_, w| w.urs().set_bit()); + self.tim.egr().write(|w| w.ug().set_bit()); + self.tim.cr1().modify(|_, w| w.urs().clear_bit()); // start counter - self.tim.cr1.modify(|_, w| w.cen().set_bit()); + self.tim.cr1().modify(|_, w| w.cen().set_bit()); } fn wait(&mut self) -> nb::Result<(), Void> { - if self.tim.sr.read().uif().bit_is_clear() { + if self.tim.sr().read().uif().bit_is_clear() { Err(nb::Error::WouldBlock) } else { - self.tim.sr.modify(|_, w| w.uif().clear_bit()); + self.tim.sr().modify(|_, w| w.uif().clear_bit()); Ok(()) } } @@ -341,14 +341,14 @@ macro_rules! hal { type Error = Error; fn cancel(&mut self) -> Result<(), Self::Error> { - // let is_counter_enabled = self.tim.cr1.read().cen().is_enabled(); - let is_counter_enabled = self.tim.cr1.read().cen().bit_is_set(); + // let is_counter_enabled = self.tim.cr1().read().cen().is_enabled(); + let is_counter_enabled = self.tim.cr1().read().cen().bit_is_set(); if !is_counter_enabled { return Err(Self::Error::Disabled); } // disable counter - self.tim.cr1.modify(|_, w| w.cen().clear_bit()); + self.tim.cr1().modify(|_, w| w.cen().clear_bit()); Ok(()) } }