diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6def2ec..f6a201f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,6 +17,7 @@ jobs: - stm32g070 - stm32g071 - stm32g081 + - stm32g0b1 steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 diff --git a/.zed/settings.json b/.zed/settings.json new file mode 100644 index 0000000..fc85630 --- /dev/null +++ b/.zed/settings.json @@ -0,0 +1,15 @@ +{ + "lsp": { + "rust-analyzer": { + "initialization_options": { + "cargo": { + "features": ["stm32g071", "rt"] + }, + "check": { + "allTargets": false, + "targets": "thumbv6m-none-eabi" + } + } + } + } +} diff --git a/Cargo.toml b/Cargo.toml index 3c3a2ef..8c3f265 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,8 +21,8 @@ nb = "1.0.0" fugit = "0.3.5" [dependencies.stm32g0] -version = "0.15.1" -features = ["rt"] +package = "stm32g0-staging" +version = "0.16.0" [dependencies.bare-metal] version = "1.0.0" @@ -41,7 +41,7 @@ cortex-m-rtic = "1.0.0" cortex-m-semihosting = "0.3.5" embedded-graphics = "0.5" embedded-sdmmc = "0.2.1" -infrared = "0.11.0" +infrared = "0.11.0" panic-halt = "0.2.0" panic-semihosting = "0.5.3" smart-leds = "0.3.0" @@ -58,6 +58,8 @@ stm32g031 = ["stm32g0/stm32g031", "stm32g0x1", "device-selected"] stm32g041 = ["stm32g0/stm32g041", "stm32g0x1", "device-selected"] stm32g071 = ["stm32g0/stm32g071", "stm32g0x1", "device-selected"] stm32g081 = ["stm32g0/stm32g081", "stm32g0x1", "device-selected"] +stm32g0b1 = ["stm32g0/stm32g0b1", "stm32g0x1", "device-selected"] +stm32g0c1 = ["stm32g0/stm32g0c1", "stm32g0x1", "device-selected"] stm32g0x0 = [] stm32g0x1 = [] diff --git a/src/analog/adc.rs b/src/analog/adc.rs index ba54f1e..3cd9ee7 100644 --- a/src/analog/adc.rs +++ b/src/analog/adc.rs @@ -118,7 +118,7 @@ impl Adc { // Enable ADC clocks ADC::enable(rcc); - adc.cr.modify(|_, w| w.advregen().set_bit()); + adc.cr().modify(|_, w| w.advregen().set_bit()); Self { rb: adc, @@ -132,11 +132,13 @@ impl Adc { /// Sets ADC source pub fn set_clock_source(&mut self, clock_source: ClockSource) { match clock_source { - ClockSource::Pclk(div) => self.rb.cfgr2.modify(|_, w| w.ckmode().bits(div as u8)), + ClockSource::Pclk(div) => { + self.rb.cfgr2().modify(|_, w| w.ckmode().set(div as u8)); + } ClockSource::Async(div) => { - self.rb.cfgr2.modify(|_, w| w.ckmode().bits(0)); + self.rb.cfgr2().modify(|_, w| w.ckmode().set(0)); self.rb - .ccr + .ccr() .modify(|_, w| unsafe { w.presc().bits(div as u8) }); } } @@ -149,8 +151,8 @@ impl Adc { /// /// Do not call if an ADC reading is ongoing. pub fn calibrate(&mut self) { - self.rb.cr.modify(|_, w| w.adcal().set_bit()); - while self.rb.cr.read().adcal().bit_is_set() {} + self.rb.cr().modify(|_, w| w.adcal().set_bit()); + while self.rb.cr().read().adcal().bit_is_set() {} } /// Returns the calibration factors used by the ADC @@ -163,7 +165,7 @@ impl Adc { /// Note that VDDA changes and to a lesser extent temperature changes affect the ADC operating conditions and /// calibration should be run again for the best accuracy. pub fn get_calibration(&self) -> CalibrationFactor { - CalibrationFactor(self.rb.calfact.read().calfact().bits()) + CalibrationFactor(self.rb.calfact().read().calfact().bits()) } /// Writes the calibration factors used by the ADC @@ -172,7 +174,7 @@ impl Adc { /// /// Do not call if an ADC reading is ongoing. pub fn set_calibration(&mut self, calfact: CalibrationFactor) { - self.rb.calfact.write(|w| w.calfact().bits(calfact.0)); + self.rb.calfact().write(|w| w.calfact().set(calfact.0)); } /// Set the Adc sampling time @@ -193,24 +195,24 @@ impl Adc { /// The nuber of bits, the oversampling result is shifted in bits at the end of oversampling pub fn set_oversampling_shift(&mut self, nrbits: u8) { self.rb - .cfgr2 + .cfgr2() .modify(|_, w| unsafe { w.ovss().bits(nrbits) }); } /// Oversampling of adc according to datasheet of stm32g0, when oversampling is enabled pub fn set_oversampling_ratio(&mut self, ratio: OversamplingRatio) { - self.rb.cfgr2.modify(|_, w| w.ovsr().bits(ratio as u8)); + self.rb.cfgr2().modify(|_, w| w.ovsr().set(ratio as u8)); } pub fn oversampling_enable(&mut self, enable: bool) { - self.rb.cfgr2.modify(|_, w| w.ovse().bit(enable)); + self.rb.cfgr2().modify(|_, w| w.ovse().bit(enable)); } pub fn start_injected(&mut self) { - self.rb.cr.modify(|_, w| w.adstart().set_bit()); + self.rb.cr().modify(|_, w| w.adstart().set_bit()); // ADSTART bit is cleared to 0 bevor using this function // enable self.rb.isr.eos() flag is set after each converstion - self.rb.ier.modify(|_, w| w.eocie().set_bit()); // end of sequence interupt enable + self.rb.ier().modify(|_, w| w.eocie().set_bit()); // end of sequence interupt enable } pub fn stop_injected(&mut self) { @@ -218,7 +220,7 @@ impl Adc { // ADSTART bit is cleared to 0 bevor using this function // disable EOS interrupt // maybe self.rb.cr.adstp().set_bit() must be performed before interrupt is disabled + wait abortion - self.rb.ier.modify(|_, w| w.eocie().clear_bit()); // end of sequence interupt disable + self.rb.ier().modify(|_, w| w.eocie().clear_bit()); // end of sequence interupt disable } /// Read actual VREF voltage using the internal reference @@ -301,15 +303,15 @@ impl Adc { } fn power_up(&mut self) { - self.rb.isr.modify(|_, w| w.adrdy().set_bit()); - self.rb.cr.modify(|_, w| w.aden().set_bit()); - while self.rb.isr.read().adrdy().bit_is_clear() {} + self.rb.isr().modify(|_, w| w.adrdy().set_bit()); + self.rb.cr().modify(|_, w| w.aden().set_bit()); + while self.rb.isr().read().adrdy().bit_is_clear() {} } fn power_down(&mut self) { - self.rb.cr.modify(|_, w| w.addis().set_bit()); - self.rb.isr.modify(|_, w| w.adrdy().set_bit()); - while self.rb.cr.read().aden().bit_is_set() {} + self.rb.cr().modify(|_, w| w.addis().set_bit()); + self.rb.isr().modify(|_, w| w.adrdy().set_bit()); + while self.rb.cr().read().aden().bit_is_set() {} } } @@ -338,10 +340,10 @@ where fn prepare_injected(&mut self, _pin: &mut PIN, triger_source: InjTrigSource) { self.rb - .cfgr1 + .cfgr1() .modify(|_, w| unsafe { w.exten().bits(1).extsel().bits(triger_source as u8) }); - self.rb.cfgr1.modify(|_, w| { + self.rb.cfgr1().modify(|_, w| unsafe { w.res() // set ADC resolution bits (ADEN must be =0) .bits(self.precision as u8) .align() // set alignment bit is (ADSTART must be 0) @@ -351,12 +353,12 @@ where self.power_up(); self.rb - .smpr // set sampling time set 1 (ADSTART must be 0) - .modify(|_, w| w.smp1().bits(self.sample_time as u8)); + .smpr() // set sampling time set 1 (ADSTART must be 0) + .modify(|_, w| w.smp1().set(self.sample_time as u8)); self.rb .chselr0() // set active channel acording chapter 15.12.9 (ADC_CFGR1; CHSELRMOD=0) - .modify(|_, w| unsafe { w.chsel().bits(1 << PIN::channel()) }); + .modify(|_, w| unsafe { w.bits(1 << PIN::channel()) }); } } @@ -372,17 +374,17 @@ impl DmaMode for Adc { fn dma_enable(&mut self, enable: bool) { if enable { - self.rb.cfgr1.modify(|_, w| w.dmaen().set_bit()); // enable dma beeing called + self.rb.cfgr1().modify(|_, w| w.dmaen().set_bit()); // enable dma beeing called } else { - self.rb.cfgr1.modify(|_, w| w.dmaen().clear_bit()); // disable dma beeing called + self.rb.cfgr1().modify(|_, w| w.dmaen().clear_bit()); // disable dma beeing called } } fn dma_circualr_mode(&mut self, enable: bool) { if enable { - self.rb.cfgr1.modify(|_, w| w.dmacfg().set_bit()); // activate circular mode + self.rb.cfgr1().modify(|_, w| w.dmacfg().set_bit()); // activate circular mode } else { - self.rb.cfgr1.modify(|_, w| w.dmacfg().clear_bit()); // disable circular mode + self.rb.cfgr1().modify(|_, w| w.dmacfg().clear_bit()); // disable circular mode } } } @@ -396,7 +398,7 @@ where fn read(&mut self, _pin: &mut PIN) -> nb::Result { self.power_up(); - self.rb.cfgr1.modify(|_, w| { + self.rb.cfgr1().modify(|_, w| unsafe { w.res() .bits(self.precision as u8) .align() @@ -404,18 +406,18 @@ where }); self.rb - .smpr - .modify(|_, w| w.smp1().bits(self.sample_time as u8)); + .smpr() + .modify(|_, w| w.smp1().set(self.sample_time as u8)); self.rb .chselr0() - .modify(|_, w| unsafe { w.chsel().bits(1 << PIN::channel()) }); + .modify(|_, w| unsafe { w.bits(1 << PIN::channel()) }); - self.rb.isr.modify(|_, w| w.eos().set_bit()); - self.rb.cr.modify(|_, w| w.adstart().set_bit()); - while self.rb.isr.read().eos().bit_is_clear() {} + self.rb.isr().modify(|_, w| w.eos().set_bit()); + self.rb.cr().modify(|_, w| w.adstart().set_bit()); + while self.rb.isr().read().eos().bit_is_clear() {} - let res = self.rb.dr.read().bits() as u16; + let res = self.rb.dr().read().bits() as u16; let val = if self.align == Align::Left && self.precision == Precision::B_6 { res << 8 } else { @@ -438,15 +440,15 @@ macro_rules! int_adc { } pub fn enable(&mut self, adc: &mut Adc) { - adc.rb.ccr.modify(|_, w| w.$en().set_bit()); + adc.rb.ccr().modify(|_, w| w.$en().set_bit()); } pub fn disable(&mut self, adc: &mut Adc) { - adc.rb.ccr.modify(|_, w| w.$en().clear_bit()); + adc.rb.ccr().modify(|_, w| w.$en().clear_bit()); } pub fn enabled(&self, adc: &Adc) -> bool { - adc.rb.ccr.read().$en().bit_is_set() + adc.rb.ccr().read().$en().bit_is_set() } } diff --git a/src/analog/comparator.rs b/src/analog/comparator.rs index 07e0db8..dcec6b4 100644 --- a/src/analog/comparator.rs +++ b/src/analog/comparator.rs @@ -27,7 +27,7 @@ impl COMP1 { pub fn csr(&self) -> &COMP1_CSR { // SAFETY: The COMP1 type is only constructed with logical ownership of // these registers. - &unsafe { &*COMP::ptr() }.comp1_csr + &unsafe { &*COMP::ptr() }.comp1_csr() } } @@ -39,7 +39,7 @@ impl COMP2 { pub fn csr(&self) -> &COMP2_CSR { // SAFETY: The COMP1 type is only constructed with logical ownership of // these registers. - &unsafe { &*COMP::ptr() }.comp2_csr + &unsafe { &*COMP::ptr() }.comp2_csr() } } @@ -136,7 +136,7 @@ macro_rules! window_input_pin { ($COMP:ident, $pin:ty) => { impl PositiveInput<$COMP> for $pin { fn setup(&self, comp: &$COMP) { - comp.csr().modify(|_, w| w.winmode().set_bit()) + comp.csr().modify(|_, w| w.winmode().set_bit()); } } }; @@ -149,7 +149,7 @@ macro_rules! positive_input_pin { ($COMP:ident, $pin:ty, $bits:expr) => { impl PositiveInput<$COMP> for $pin { fn setup(&self, comp: &$COMP) { - comp.csr().modify(|_, w| unsafe { w.inpsel().bits($bits) }) + comp.csr().modify(|_, w| unsafe { w.inpsel().bits($bits) }); } } }; @@ -169,7 +169,7 @@ macro_rules! negative_input_pin { ($COMP:ident, $pin:ty, $bits:expr) => { impl NegativeInput<$COMP> for $pin { fn setup(&self, comp: &$COMP) { - comp.csr().modify(|_, w| unsafe { w.inmsel().bits($bits) }) + comp.csr().modify(|_, w| unsafe { w.inmsel().bits($bits) }); } } }; @@ -200,7 +200,7 @@ macro_rules! refint_input { impl NegativeInput<$COMP> for RefintInput { 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) }); } } }; @@ -213,7 +213,7 @@ macro_rules! dac_input { ($COMP:ident, $channel:ty, $bits:expr) => { impl NegativeInput<$COMP> for &$channel { fn setup(&self, comp: &$COMP) { - comp.csr().modify(|_, w| unsafe { w.inmsel().bits($bits) }) + comp.csr().modify(|_, w| unsafe { w.inmsel().bits($bits) }); } } }; @@ -499,11 +499,11 @@ pub fn window_comparator21< /// Enables the comparator peripheral, and splits the [`COMP`] into independent [`COMP1`] and [`COMP2`] pub fn split(_comp: COMP, rcc: &mut Rcc) -> (COMP1, COMP2) { // Enable COMP, SYSCFG, VREFBUF clocks - rcc.rb.apbenr2.modify(|_, w| w.syscfgen().set_bit()); + rcc.rb.apbenr2().modify(|_, w| w.syscfgen().set_bit()); // Reset COMP, SYSCFG, VREFBUF - rcc.rb.apbrstr2.modify(|_, w| w.syscfgrst().set_bit()); - rcc.rb.apbrstr2.modify(|_, w| w.syscfgrst().clear_bit()); + rcc.rb.apbrstr2().modify(|_, w| w.syscfgrst().set_bit()); + rcc.rb.apbrstr2().modify(|_, w| w.syscfgrst().clear_bit()); (COMP1 { _rb: PhantomData }, COMP2 { _rb: PhantomData }) } diff --git a/src/analog/dac.rs b/src/analog/dac.rs index a1d9677..eafa730 100644 --- a/src/analog/dac.rs +++ b/src/analog/dac.rs @@ -106,8 +106,8 @@ macro_rules! dac { pub fn enable(self) -> $CX { let dac = unsafe { &(*DAC::ptr()) }; - dac.mcr.modify(|_, w| unsafe { w.$mode().bits(1) }); - dac.cr.modify(|_, w| w.$en().set_bit()); + dac.mcr().modify(|_, w| unsafe { w.$mode().bits(1) }); + dac.cr().modify(|_, w| w.$en().set_bit()); $CX { _enabled: PhantomData, @@ -117,8 +117,8 @@ macro_rules! dac { pub fn enable_unbuffered(self) -> $CX { let dac = unsafe { &(*DAC::ptr()) }; - dac.mcr.modify(|_, w| unsafe { w.$mode().bits(2) }); - dac.cr.modify(|_, w| w.$en().set_bit()); + dac.mcr().modify(|_, w| unsafe { w.$mode().bits(2) }); + dac.cr().modify(|_, w| w.$en().set_bit()); $CX { _enabled: PhantomData, @@ -128,8 +128,8 @@ macro_rules! dac { pub fn enable_generator(self, config: GeneratorConfig) -> $CX { let dac = unsafe { &(*DAC::ptr()) }; - dac.mcr.modify(|_, w| unsafe { w.$mode().bits(1) }); - dac.cr.modify(|_, w| unsafe { + dac.mcr().modify(|_, w| unsafe { w.$mode().bits(1) }); + dac.cr().modify(|_, w| unsafe { w.$wave().bits(config.mode); w.$ten().set_bit(); w.$mamp().bits(config.amp); @@ -159,19 +159,19 @@ macro_rules! dac { T: DelayUs, { let dac = unsafe { &(*DAC::ptr()) }; - 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()); + 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.ccr.modify(|_, w| unsafe { w.$trim().bits(trim) }); + dac.ccr().modify(|_, w| unsafe { w.$trim().bits(trim) }); delay.delay_us(64_u32); - if dac.sr.read().$cal_flag().bit() { + if dac.sr().read().$cal_flag().bit() { break; } trim += 1; } - dac.cr.modify(|_, w| w.$cen().clear_bit()); + dac.cr().modify(|_, w| w.$cen().clear_bit()); $CX { _enabled: PhantomData, @@ -181,7 +181,7 @@ macro_rules! dac { /// Disable the DAC channel pub fn disable(self) -> $CX { let dac = unsafe { &(*DAC::ptr()) }; - dac.cr.modify(|_, w| unsafe { + dac.cr().modify(|_, w| unsafe { w.$en().clear_bit().$wave().bits(0).$ten().clear_bit() }); @@ -196,12 +196,12 @@ macro_rules! dac { 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.$dac_dor().read().bits() as u16 } } @@ -209,7 +209,7 @@ macro_rules! dac { impl $CX { pub fn trigger(&mut self) { let dac = unsafe { &(*DAC::ptr()) }; - dac.swtrgr.write(|w| { w.$swtrig().set_bit() }); + dac.swtrgr().write(|w| { w.$swtrig().set_bit() }); } } )+ diff --git a/src/crc.rs b/src/crc.rs index fa1bd68..1c0ef4b 100644 --- a/src/crc.rs +++ b/src/crc.rs @@ -120,9 +120,9 @@ impl Config { Some(BitReversal::ByWord) => 0b11, }; - crc.init.write(|w| unsafe { w.crc_init().bits(init) }); - crc.pol.write(|w| unsafe { w.bits(poly) }); - crc.cr.write(|w| { + crc.init().write(|w| unsafe { w.crc_init().bits(init) }); + crc.pol().write(|w| unsafe { w.bits(poly) }); + crc.cr().write(|w| { unsafe { w.rev_in() .bits(in_rev_bits) @@ -152,7 +152,7 @@ impl Crc { pub fn reset(&mut self) { let crc = unsafe { &(*CRC::ptr()) }; - crc.cr.modify(|_, w| w.reset().set_bit()); + crc.cr().modify(|_, w| w.reset().set_bit()); } /// This will reset the CRC to its initial condition, however with a specific initial value. @@ -163,9 +163,9 @@ impl Crc { pub fn reset_with_inital_value(&mut self, initial_value: u32) { let crc = unsafe { &(*CRC::ptr()) }; - crc.init + crc.init() .write(|w| unsafe { w.crc_init().bits(initial_value) }); - crc.cr.modify(|_, w| w.reset().set_bit()); + crc.cr().modify(|_, w| w.reset().set_bit()); } /// Feed the CRC with data @@ -173,12 +173,7 @@ impl Crc { pub fn feed(&mut self, data: &[u8]) { let crc = unsafe { &(*CRC::ptr()) }; for byte in data { - unsafe { - core::ptr::write_volatile( - core::cell::UnsafeCell::raw_get(&crc.dr as *const _ as _), - byte, - ) - } + crc.dr().write(|w| unsafe { w.dr().bits((*byte).into()) }); } } @@ -199,7 +194,7 @@ impl Crc { pub fn peek_result(&self) -> u32 { let crc = unsafe { &(*CRC::ptr()) }; - crc.dr.read().bits() + crc.dr().read().bits() } } diff --git a/src/dma.rs b/src/dma.rs index 1cb74fb..6e40348 100644 --- a/src/dma.rs +++ b/src/dma.rs @@ -1,4 +1,6 @@ //! Direct Memory Access Engine + +// TODO: add DMA2 for B1, C1 use crate::dmamux::DmaMuxIndex; use crate::rcc::Rcc; use crate::stm32::DMAMUX; @@ -91,7 +93,7 @@ mod private { /// Channel methods private to this module pub trait Channel { /// Return the register block for this channel - fn ch(&self) -> &stm32::dma::CH; + fn ch(&self) -> &stm32::dma1::CH; } } @@ -115,10 +117,10 @@ pub trait Channel: private::Channel { /// Reset the control registers of this channel. /// This stops any ongoing transfers. fn reset(&mut self) { - self.ch().cr.reset(); - self.ch().ndtr.reset(); - self.ch().par.reset(); - self.ch().mar.reset(); + self.ch().cr().reset(); + self.ch().ndtr().reset(); + self.ch().par().reset(); + self.ch().mar().reset(); self.clear_event(Event::Any); } @@ -133,8 +135,8 @@ pub trait Channel: private::Channel { fn set_peripheral_address(&mut self, address: u32, inc: bool) { assert!(!self.is_enabled()); - self.ch().par.write(|w| unsafe { w.pa().bits(address) }); - self.ch().cr.modify(|_, w| w.pinc().bit(inc)); + self.ch().par().write(|w| unsafe { w.pa().bits(address) }); + self.ch().cr().modify(|_, w| w.pinc().bit(inc)); } /// Set the base address of the memory area from/to which @@ -148,8 +150,8 @@ pub trait Channel: private::Channel { fn set_memory_address(&mut self, address: u32, inc: bool) { assert!(!self.is_enabled()); - self.ch().mar.write(|w| unsafe { w.ma().bits(address) }); - self.ch().cr.modify(|_, w| w.minc().bit(inc)); + self.ch().mar().write(|w| unsafe { w.ma().bits(address) }); + self.ch().cr().modify(|_, w| w.minc().bit(inc)); } /// Set the number of words to transfer. @@ -162,17 +164,17 @@ pub trait Channel: private::Channel { fn set_transfer_length(&mut self, len: u16) { assert!(!self.is_enabled()); - self.ch().ndtr.write(|w| unsafe { w.ndt().bits(len) }); + self.ch().ndtr().write(|w| unsafe { w.ndt().bits(len) }); } /// Get the number of words left to transfer. fn get_transfer_remaining(&mut self) -> u16 { - self.ch().ndtr.read().ndt().bits() + self.ch().ndtr().read().ndt().bits() } /// Set the word size. fn set_word_size(&mut self, wsize: WordSize) { - self.ch().cr.modify(|_, w| unsafe { + self.ch().cr().modify(|_, w| unsafe { w.psize().bits(wsize as u8); w.msize().bits(wsize as u8) }); @@ -181,83 +183,78 @@ pub trait Channel: private::Channel { /// Set the priority level of this channel fn set_priority_level(&mut self, priority: Priority) { let pl = priority.into(); - self.ch().cr.modify(|_, w| unsafe { w.pl().bits(pl) }); + self.ch().cr().modify(|_, w| unsafe { w.pl().bits(pl) }); } /// Set the transfer direction fn set_direction(&mut self, direction: Direction) { let dir = direction.into(); - self.ch().cr.modify(|_, w| w.dir().bit(dir)); + self.ch().cr().modify(|_, w| w.dir().bit(dir)); } /// Set the circular mode of this channel fn set_circular_mode(&mut self, circular: bool) { - self.ch().cr.modify(|_, w| w.circ().bit(circular)); + self.ch().cr().modify(|_, w| w.circ().bit(circular)); } /// Enable the interrupt for the given event fn listen(&mut self, event: Event) { use Event::*; match event { - HalfTransfer => self.ch().cr.modify(|_, w| w.htie().set_bit()), - TransferComplete => self.ch().cr.modify(|_, w| w.tcie().set_bit()), - TransferError => self.ch().cr.modify(|_, w| w.teie().set_bit()), - Any => self.ch().cr.modify(|_, w| { + HalfTransfer => self.ch().cr().modify(|_, w| w.htie().set_bit()), + TransferComplete => self.ch().cr().modify(|_, w| w.tcie().set_bit()), + TransferError => self.ch().cr().modify(|_, w| w.teie().set_bit()), + Any => self.ch().cr().modify(|_, w| { w.htie().set_bit(); w.tcie().set_bit(); w.teie().set_bit() }), - } + }; } /// Disable the interrupt for the given event fn unlisten(&mut self, event: Event) { use Event::*; match event { - HalfTransfer => self.ch().cr.modify(|_, w| w.htie().clear_bit()), - TransferComplete => self.ch().cr.modify(|_, w| w.tcie().clear_bit()), - TransferError => self.ch().cr.modify(|_, w| w.teie().clear_bit()), - Any => self.ch().cr.modify(|_, w| { + HalfTransfer => self.ch().cr().modify(|_, w| w.htie().clear_bit()), + TransferComplete => self.ch().cr().modify(|_, w| w.tcie().clear_bit()), + TransferError => self.ch().cr().modify(|_, w| w.teie().clear_bit()), + Any => self.ch().cr().modify(|_, w| { w.htie().clear_bit(); w.tcie().clear_bit(); w.teie().clear_bit() }), - } + }; } /// Start a transfer fn enable(&mut self) { self.clear_event(Event::Any); - self.ch().cr.modify(|_, w| w.en().set_bit()); + self.ch().cr().modify(|_, w| w.en().set_bit()); } /// Stop the current transfer fn disable(&mut self) { - self.ch().cr.modify(|_, w| w.en().clear_bit()); + self.ch().cr().modify(|_, w| w.en().clear_bit()); } /// Is there a transfer in progress on this channel? fn is_enabled(&self) -> bool { - self.ch().cr.read().en().bit_is_set() + self.ch().cr().read().en().bit_is_set() } } -// TODO: Blocked by https://github.com/stm32-rs/stm32-rs/pull/695 -#[cfg(any(feature = "stm32g030", feature = "stm32g031", feature = "stm32g041"))] macro_rules! dma { ( channels: { - $( $Ci:ident: ( - $chi:ident, - $htifi:ident, $tcifi:ident, $teifi:ident, $gifi:ident, - $chtifi:ident, $ctcifi:ident, $cteifi:ident, $cgifi:ident, - $MuxCi: ident - ), )+ + $( + $Ci:ident: ($chi:ident, $i: literal), + )+ }, ) => { use crate::dmamux; use crate::rcc::{Enable, Reset}; - use crate::stm32::{self, DMA}; + use crate::stm32::{self, DMA1 as DMA}; use crate::dmamux::DmaMuxExt; @@ -278,13 +275,13 @@ macro_rules! dma { $( /// Singleton that represents a DMA channel pub struct $Ci { - mux: dmamux::$MuxCi, + mux: dmamux::Channel<$i>, } impl private::Channel for $Ci { - fn ch(&self) -> &stm32::dma::CH { + fn ch(&self) -> &stm32::dma1::CH { // NOTE(unsafe) $Ci grants exclusive access to this register - unsafe { &(*DMA::ptr()).$chi } + unsafe { &(*DMA::ptr()).ch($i) } } } @@ -304,12 +301,12 @@ macro_rules! dma { use Event::*; // NOTE(unsafe) atomic read - let flags = unsafe { (*DMA::ptr()).isr.read() }; + let flags = unsafe { (*DMA::ptr()).isr().read() }; match event { - HalfTransfer => flags.$htifi().bit_is_set(), - TransferComplete => flags.$tcifi().bit_is_set(), - TransferError => flags.$teifi().bit_is_set(), - Any => flags.$gifi().bit_is_set(), + HalfTransfer => flags.htif($i).bit_is_set(), + TransferComplete => flags.tcif($i).bit_is_set(), + TransferError => flags.teif($i).bit_is_set(), + Any => flags.gif($i).bit_is_set(), } } @@ -318,11 +315,11 @@ macro_rules! dma { // NOTE(unsafe) atomic write to a stateless register unsafe { - let _ = &(*DMA::ptr()).ifcr.write(|w| match event { - HalfTransfer => w.$chtifi().set_bit(), - TransferComplete => w.$ctcifi().set_bit(), - TransferError => w.$cteifi().set_bit(), - Any => w.$cgifi().set_bit(), + let _ = &(*DMA::ptr()).ifcr().write(|w| match event { + HalfTransfer => w.chtif($i).set_bit(), + TransferComplete => w.ctcif($i).set_bit(), + TransferError => w.cteif($i).set_bit(), + Any => w.cgif($i).set_bit(), }); } } @@ -332,32 +329,36 @@ macro_rules! dma { } } -// TODO: Blocked by https://github.com/stm32-rs/stm32-rs/pull/695 -// #[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))] -// dma!( -// channels: { -// C1: (ch1, htif1, tcif1, teif1, gif1, chtif1, ctcif1, cteif1, cgif1, C0), -// C2: (ch2, htif2, tcif2, teif2, gif2, chtif2, ctcif2, cteif2, cgif2, C1), -// C3: (ch3, htif3, tcif3, teif3, gif3, chtif3, ctcif3, cteif3, cgif3, C2), -// C4: (ch4, htif4, tcif4, teif4, gif4, chtif4, ctcif4, cteif4, cgif4, C3), -// C5: (ch5, htif5, tcif5, teif5, gif5, chtif5, ctcif5, cteif5, cgif5, C4), -// C6: (ch6, htif6, tcif6, teif6, gif6, chtif6, ctcif6, cteif6, cgif6, C5), -// C7: (ch7, htif7, tcif7, teif7, gif7, chtif7, ctcif7, cteif7, cgif7, C6), -// }, -// ); +#[cfg(any( + feature = "stm32g070", + feature = "stm32g071", + feature = "stm32g081", + feature = "stm32g0b1", + feature = "stm32g0c1", +))] +dma!( + channels: { + C1: (ch1, 0), + C2: (ch2, 1), + C3: (ch3, 2), + C4: (ch4, 3), + C5: (ch5, 4), + C6: (ch6, 5), + C7: (ch7, 6), + }, +); #[cfg(any(feature = "stm32g030", feature = "stm32g031", feature = "stm32g041"))] dma!( channels: { - C1: (ch1, htif1, tcif1, teif1, gif1, chtif1, ctcif1, cteif1, cgif1, C0), - C2: (ch2, htif2, tcif2, teif2, gif2, chtif2, ctcif2, cteif2, cgif2, C1), - C3: (ch3, htif3, tcif3, teif3, gif3, chtif3, ctcif3, cteif3, cgif3, C2), - C4: (ch4, htif4, tcif4, teif4, gif4, chtif4, ctcif4, cteif4, cgif4, C3), - C5: (ch5, htif5, tcif5, teif5, gif5, chtif5, ctcif5, cteif5, cgif5, C4), + C1: (ch1, 0), + C2: (ch2, 1), + C3: (ch3, 2), + C4: (ch4, 3), + C5: (ch5, 4), }, ); -#[cfg(any(feature = "stm32g030", feature = "stm32g031", feature = "stm32g041"))] impl DmaExt for DMA { type Channels = Channels; @@ -388,11 +389,23 @@ impl DmaExt for DMA { ch5: C5 { mux: muxchannels.ch4, }, - #[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))] + #[cfg(any( + feature = "stm32g070", + feature = "stm32g071", + feature = "stm32g081", + feature = "stm32g0b1", + feature = "stm32g0c1", + ))] ch6: C6 { mux: muxchannels.ch5, }, - #[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))] + #[cfg(any( + feature = "stm32g070", + feature = "stm32g071", + feature = "stm32g081", + feature = "stm32g0b1", + feature = "stm32g0c1", + ))] ch7: C7 { mux: muxchannels.ch6, }, diff --git a/src/dmamux.rs b/src/dmamux.rs index 67b8b2b..70ad1d2 100644 --- a/src/dmamux.rs +++ b/src/dmamux.rs @@ -149,77 +149,71 @@ pub trait DmaMuxChannel { fn select_peripheral(&mut self, index: DmaMuxIndex); } -macro_rules! dma_mux { - ( - channels: { - $( $Ci:ident: ($chi:ident, $cr:ident), )+ - }, - ) => { - - /// DMAMUX channels - pub struct Channels { - $( pub $chi: $Ci, )+ - } - - $( - /// Singleton that represents a DMAMUX channel - pub struct $Ci { - _0: (), - } - - impl DmaMuxChannel for $Ci { - fn select_peripheral(&mut self, index: DmaMuxIndex) { - let reg = unsafe { &(*DMAMUX::ptr()).$cr }; - reg.write( |w| unsafe { - w.dmareq_id().bits(index.val()) - .ege().set_bit() - }); - - } - } - )+ +pub struct Channel { + _0: (), +} +impl DmaMuxChannel for Channel { + fn select_peripheral(&mut self, index: DmaMuxIndex) { + let reg = unsafe { &(*DMAMUX::ptr()).ccr(N) }; + reg.write(|w| unsafe { w.dmareq_id().bits(index.val()).ege().set_bit() }); } } -#[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))] -dma_mux!( - channels: { - C0: (ch0, c0cr), - C1: (ch1, c1cr), - C2: (ch2, c2cr), - C3: (ch3, c3cr), - C4: (ch4, c4cr), - C5: (ch5, c5cr), - C6: (ch6, c6cr), - }, -); +#[cfg(any( + feature = "stm32g070", + feature = "stm32g071", + feature = "stm32g081", + feature = "stm32g0b1", + feature = "stm32g0c1", +))] +/// DMAMUX channels +pub struct Channels { + pub ch0: Channel<0>, + pub ch1: Channel<1>, + pub ch2: Channel<2>, + pub ch3: Channel<3>, + pub ch4: Channel<4>, + pub ch5: Channel<5>, + pub ch6: Channel<6>, +} #[cfg(any(feature = "stm32g030", feature = "stm32g031", feature = "stm32g041"))] -dma_mux!( - channels: { - C0: (ch0, c0cr), - C1: (ch1, c1cr), - C2: (ch2, c2cr), - C3: (ch3, c3cr), - C4: (ch4, c4cr), - }, -); +/// DMAMUX channels +pub struct Channels { + pub ch0: Channel<0>, + pub ch1: Channel<1>, + pub ch2: Channel<2>, + pub ch3: Channel<3>, + pub ch4: Channel<4>, +} impl DmaMuxExt for DMAMUX { type Channels = Channels; fn split(self) -> Self::Channels { Channels { - ch0: C0 { _0: () }, - ch1: C1 { _0: () }, - ch2: C2 { _0: () }, - ch3: C3 { _0: () }, - ch4: C4 { _0: () }, - #[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))] - ch5: C5 { _0: () }, - #[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))] - ch6: C6 { _0: () }, + ch0: Channel::<0> { _0: () }, + ch1: Channel::<1> { _0: () }, + ch2: Channel::<2> { _0: () }, + ch3: Channel::<3> { _0: () }, + ch4: Channel::<4> { _0: () }, + #[cfg(any( + feature = "stm32g070", + feature = "stm32g071", + feature = "stm32g081", + feature = "stm32g0b1", + feature = "stm32g0c1", + ))] + ch5: Channel::<5> { _0: () }, + #[cfg(any( + feature = "stm32g070", + feature = "stm32g071", + feature = "stm32g081", + feature = "stm32g0b1", + feature = "stm32g0c1", + ))] + ch6: Channel::<6> { _0: () }, } } } diff --git a/src/exti.rs b/src/exti.rs index 509e5f3..4b2b3f2 100644 --- a/src/exti.rs +++ b/src/exti.rs @@ -67,6 +67,8 @@ impl Event { } } +#[cfg(any(feature = "stm32g0b1", feature = "stm32g0c1"))] +const TRIGGER_MAX: u8 = 20; #[cfg(any(feature = "stm32g071", feature = "stm32g081"))] const TRIGGER_MAX: u8 = 18; #[cfg(any(feature = "stm32g031", feature = "stm32g041"))] @@ -89,14 +91,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::All => { - 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); @@ -109,18 +115,18 @@ impl ExtiExt for EXTI { feature = "stm32g031", feature = "stm32g041" ))] - self.imr1 + self.imr1() .modify(|r, w| unsafe { w.bits(r.bits() | 1 << ev as u8) }); #[cfg(any(feature = "stm32g071", feature = "stm32g081"))] 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) { @@ -135,10 +141,13 @@ impl ExtiExt for EXTI { { let line = ev as u8; 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 <= TRIGGER_MAX { - 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) }); } } @@ -146,15 +155,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 <= TRIGGER_MAX { - 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) }); } } } @@ -166,10 +179,10 @@ impl ExtiExt for EXTI { } let mask = 1 << line; match edge { - SignalEdge::Rising => self.rpr1.read().bits() & mask != 0, - SignalEdge::Falling => self.fpr1.read().bits() & mask != 0, + SignalEdge::Rising => self.rpr1().read().bits() & mask != 0, + SignalEdge::Falling => self.fpr1().read().bits() & mask != 0, SignalEdge::All => { - (self.rpr1.read().bits() & mask != 0) || (self.fpr1.read().bits() & mask != 0) + (self.rpr1().read().bits() & mask != 0) || (self.fpr1().read().bits() & mask != 0) } } } @@ -177,8 +190,8 @@ impl ExtiExt for EXTI { fn unpend(&self, ev: Event) { let line = ev as u8; if line <= TRIGGER_MAX { - self.rpr1.modify(|_, w| unsafe { w.bits(1 << line) }); - self.fpr1.modify(|_, w| unsafe { w.bits(1 << line) }); + self.rpr1().modify(|_, w| unsafe { w.bits(1 << line) }); + self.fpr1().modify(|_, w| unsafe { w.bits(1 << line) }); } } } diff --git a/src/flash/mod.rs b/src/flash/mod.rs index b77105a..39da8d5 100644 --- a/src/flash/mod.rs +++ b/src/flash/mod.rs @@ -33,14 +33,17 @@ pub trait FlashExt { impl FlashExt for FLASH { fn unlock(self) -> core::result::Result { // Wait, while the memory interface is busy. - while self.sr.read().bsy().bit_is_set() {} + #[cfg(feature = "stm32g0x0")] + while self.sr().read().bsy1().bit_is_set() {} + #[cfg(not(feature = "stm32g0x0"))] + while self.sr().read().bsy().bit_is_set() {} // Unlock flash - self.keyr.write(|w| unsafe { w.keyr().bits(FLASH_KEY1) }); - self.keyr.write(|w| unsafe { w.keyr().bits(FLASH_KEY2) }); + self.keyr().write(|w| unsafe { w.key().bits(FLASH_KEY1) }); + self.keyr().write(|w| unsafe { w.key().bits(FLASH_KEY2) }); // Verify success - if self.cr.read().lock().bit_is_clear() { + if self.cr().read().lock().bit_is_clear() { Ok(UnlockedFlash { f: self }) } else { Err(self) @@ -56,7 +59,7 @@ pub struct UnlockedFlash { impl UnlockedFlash { /// Consumes the unlocked flash instance returning the locked one pub fn lock(self) -> FLASH { - self.f.cr.modify(|_, w| w.lock().set_bit()); + self.f.cr().modify(|_, w| w.lock().set_bit()); self.f } } @@ -84,8 +87,13 @@ impl WriteErase for UnlockedFlash { type NativeType = u64; fn status(&self) -> Result { - let sr = self.f.sr.read(); + let sr = self.f.sr().read(); + #[cfg(feature = "stm32g0x0")] + if sr.bsy1().bit_is_set() { + return Err(Error::Busy); + } + #[cfg(not(feature = "stm32g0x0"))] if sr.bsy().bit_is_set() { return Err(Error::Busy); } @@ -103,7 +111,10 @@ impl WriteErase for UnlockedFlash { } // Wait, while the memory interface is busy. - while self.f.sr.read().bsy().bit_is_set() {} + #[cfg(feature = "stm32g0x0")] + while self.f.sr().read().bsy1().bit_is_set() {} + #[cfg(not(feature = "stm32g0x0"))] + while self.f.sr().read().bsy().bit_is_set() {} self.clear_errors(); @@ -112,24 +123,36 @@ impl WriteErase for UnlockedFlash { // access to the vector table or interrupt handlers that might be // caused by an interrupt. interrupt::free(|_| { - self.f.cr.modify(|_, w| unsafe { - w.per().set_bit().pnb().bits(page.0 as u8).strt().set_bit() + self.f.cr().modify(|_, w| { + w.per().set_bit(); + #[cfg(feature = "stm32g0x0")] + unsafe { + w.pnb().bits(page.0 as u16); + } + #[cfg(not(feature = "stm32g0x0"))] + unsafe { + w.pnb().bits(page.0 as u8); + } + w.strt().set_bit() }); }); let result = self.wait(); - self.f.cr.modify(|_, w| w.per().clear_bit()); + self.f.cr().modify(|_, w| w.per().clear_bit()); result } fn write_native(&mut self, address: usize, array: &[Self::NativeType]) -> Result { // Wait, while the memory interface is busy. - while self.f.sr.read().bsy().bit_is_set() {} + #[cfg(feature = "stm32g0x0")] + while self.f.sr().read().bsy1().bit_is_set() {} + #[cfg(not(feature = "stm32g0x0"))] + while self.f.sr().read().bsy().bit_is_set() {} // Enable Flash programming self.clear_errors(); - self.f.cr.modify(|_, w| w.pg().set_bit()); + self.f.cr().modify(|_, w| w.pg().set_bit()); // It is only possible to program a double word (2 x 32-bit data). let mut address = address as *mut u32; @@ -151,12 +174,12 @@ impl WriteErase for UnlockedFlash { self.wait()?; - if self.f.sr.read().eop().bit_is_set() { - self.f.sr.modify(|_, w| w.eop().clear_bit()); + if self.f.sr().read().eop().bit_is_set() { + self.f.sr().modify(|_, w| w.eop().clear_bit()); } } - self.f.cr.modify(|_, w| w.pg().clear_bit()); + self.f.cr().modify(|_, w| w.pg().clear_bit()); Ok(()) } @@ -217,26 +240,23 @@ impl WriteErase for UnlockedFlash { impl UnlockedFlash { fn clear_errors(&mut self) { - self.f.sr.modify(|_, w| { - w.progerr() - .set_bit() - .pgserr() - .set_bit() - .rderr() - .set_bit() - .optverr() - .set_bit() - .sizerr() - .set_bit() - .pgaerr() - .set_bit() - .wrperr() - .set_bit() + self.f.sr().modify(|_, w| { + w.progerr().set_bit(); + w.pgserr().set_bit(); + #[cfg(not(feature = "stm32g0x0"))] + w.rderr().set_bit(); + w.optverr().set_bit(); + w.sizerr().set_bit(); + w.pgaerr().set_bit(); + w.wrperr().set_bit() }); } fn wait(&self) -> Result { - while self.f.sr.read().bsy().bit_is_set() {} + #[cfg(feature = "stm32g0x0")] + while self.f.sr().read().bsy1().bit_is_set() {} + #[cfg(not(feature = "stm32g0x0"))] + while self.f.sr().read().bsy().bit_is_set() {} self.status() } } diff --git a/src/gpio.rs b/src/gpio.rs index c2755a4..81ba0e5 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -65,22 +65,26 @@ macro_rules! gpio_trait { impl GpioRegExt for crate::stm32::$gpiox::RegisterBlock { fn is_low(&self, pos: u8) -> bool { // NOTE(unsafe) atomic read with no side effects - self.idr.read().bits() & (1 << pos) == 0 + self.idr().read().bits() & (1 << pos) == 0 } fn is_set_low(&self, pos: u8) -> bool { // NOTE(unsafe) atomic read with no side effects - self.odr.read().bits() & (1 << pos) == 0 + self.odr().read().bits() & (1 << pos) == 0 } fn set_high(&self, pos: u8) { // NOTE(unsafe) atomic write to a stateless register - unsafe { self.bsrr.write(|w| w.bits(1 << pos)) } + unsafe { + self.bsrr().write(|w| w.bits(1 << pos)); + } } fn set_low(&self, pos: u8) { // NOTE(unsafe) atomic write to a stateless register - unsafe { self.bsrr.write(|w| w.bits(1 << (pos + 16))) } + unsafe { + self.bsrr().write(|w| w.bits(1 << (pos + 16))); + } } } }; @@ -228,13 +232,13 @@ macro_rules! gpio { fn set_high(&mut self) -> Result<(), Self::Error> { // 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<(), Self::Error> { // 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(()) } } @@ -247,7 +251,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) } } @@ -265,7 +269,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) } } @@ -280,7 +284,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) } } @@ -331,10 +335,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)) }) }; @@ -346,10 +350,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)) }) }; @@ -361,10 +365,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)) }) }; @@ -376,10 +380,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)) }); } @@ -399,13 +403,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)) }) }; @@ -425,13 +429,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)) }) }; @@ -442,10 +446,10 @@ macro_rules! gpio { pub fn listen(self, edge: SignalEdge, exti: &mut EXTI) -> $PXi> { let offset = 2 * $i; unsafe { - let _ = &(*$GPIOX::ptr()).pupdr.modify(|r, w| { + let _ = &(*$GPIOX::ptr()).pupdr().modify(|r, w| { w.bits(r.bits() & !(0b11 << offset)) }); - let _ = &(*$GPIOX::ptr()).moder.modify(|r, w| { + let _ = &(*$GPIOX::ptr()).moder().modify(|r, w| { w.bits(r.bits() & !(0b11 << offset)) }); }; @@ -453,20 +457,20 @@ macro_rules! gpio { let mask = $Pxn << offset; let reset = !(0xff << offset); match $i as u8 { - 0..=3 => exti.exticr1.modify(|r, w| unsafe { + 0..=3 => exti.exticr1().modify(|r, w| unsafe { w.bits(r.bits() & reset | mask) }), - 4..=7 => exti.exticr2.modify(|r, w| unsafe { + 4..=7 => exti.exticr2().modify(|r, w| unsafe { w.bits(r.bits() & reset | mask) }), - 8..=11 => exti.exticr3.modify(|r, w| unsafe { + 8..=11 => exti.exticr3().modify(|r, w| unsafe { w.bits(r.bits() & reset | mask) }), - 12..=16 => exti.exticr4.modify(|r, w| unsafe { + 12..=16 => exti.exticr4().modify(|r, w| unsafe { w.bits(r.bits() & reset | mask) }), _ => unreachable!(), - } + }; exti.listen(Event::from_code($i), edge); $PXi { _mode: PhantomData } } @@ -475,7 +479,7 @@ macro_rules! gpio { pub fn set_speed(self, speed: Speed) -> Self { let offset = 2 * $i; unsafe { - let _ = &(*$GPIOX::ptr()).ospeedr.modify(|r, w| { + let _ = &(*$GPIOX::ptr()).ospeedr().modify(|r, w| { w.bits((r.bits() & !(0b11 << offset)) | ((speed as u32) << offset)) }); }; @@ -490,16 +494,16 @@ 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)) }); } @@ -509,11 +513,11 @@ macro_rules! gpio { match state { PinState::High => { // 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)) }; } PinState::Low => { // 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))) }; } } } @@ -551,7 +555,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) } } @@ -569,7 +573,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) } } @@ -594,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) } } @@ -715,6 +719,26 @@ gpio!(GPIOD, gpiod, PD, 3, [ PD15: (pd15, 15), ]); +#[cfg(feature = "stm32g0b1")] +gpio!(GPIOE, gpioe, PE, 4, [ + PE0: (pe0, 0), + PE1: (pe1, 1), + PE2: (pe2, 2), + PE3: (pe3, 3), + PE4: (pe4, 4), + PE5: (pe5, 5), + PE6: (pe6, 6), + PE7: (pe7, 7), + PE8: (pe8, 8), + PE9: (pe9, 9), + PE10: (pe10, 10), + PE11: (pe11, 11), + PE12: (pe12, 12), + PE13: (pe13, 13), + PE14: (pe14, 14), + PE15: (pe15, 15), +]); + gpio!(GPIOF, gpiof, PF, 5, [ PF0: (pf0, 0), PF1: (pf1, 1), diff --git a/src/i2c/blocking.rs b/src/i2c/blocking.rs index 6398e75..aef9fe3 100644 --- a/src/i2c/blocking.rs +++ b/src/i2c/blocking.rs @@ -36,22 +36,22 @@ pub trait I2cSlave { 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() { + $i2c.txdr().write(|w| w.txdata().set(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()); } }; } /// Sequence to flush the RXDR register. This resets the TXIS and TXE flags macro_rules! flush_rxdr { ($i2c:expr) => { - if $i2c.isr.read().rxne().bit_is_set() { + if $i2c.isr().read().rxne().bit_is_set() { // flush - let _ = $i2c.rxdr.read().rxdata().bits(); + let _ = $i2c.rxdr().read().rxdata().bits(); }; }; } @@ -62,25 +62,26 @@ macro_rules! flush_rxdr { macro_rules! busy_wait { ($i2c:expr, $flag:ident, $variant:ident, $idx:ident, $buflen: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.nackcf().set_bit()); + $i2c.icr().write(|w| w.nackcf().set_bit()); // Make one extra loop to wait on the stop condition } else if isr.tcr().bit_is_set() { // This condition Will only happen when reload == 1 and sbr == 1 (slave) and nbytes was written. // Send a NACK, set nbytes to clear tcr flag - $i2c.cr2.modify(|_, w| - w.nack().set_bit().nbytes().bits(1 as u8) - ); + $i2c.cr2().modify(|_, w| { + w.nack().set_bit(); + w.nbytes().set(1 as u8) + }); // Make one extra loop here to wait on the stop condition } else if isr.addr().bit_is_set() { // in case of a master write_read operation, this flag is the only exit for the function. @@ -93,7 +94,7 @@ macro_rules! busy_wait { } else if isr.stopf().bit_is_set() { flush_txdr!($i2c); // Clear the stop condition flag - $i2c.icr.write(|w| w.stopcf().set_bit()); + $i2c.icr().write(|w| w.stopcf().set_bit()); if $idx == $buflen { return Ok( () ) } else @@ -169,40 +170,37 @@ macro_rules! i2c { $I2CX::reset(rcc); // 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(rcc.clocks.apb_clk); - 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) - ); + i2c.cr1().modify(|_, w| { + w.pe().set_bit(); + w.dnf().set(config.digital_filter); + w.anfoff().bit(!config.analog_filter) + }); if config.slave_address_1 > 0 { - i2c.oar1.write(|w| - w.oa1().bits(config.slave_address_1) + i2c.oar1().write(|w| + unsafe { w.oa1().bits(config.slave_address_1) } .oa1mode().bit(config.address_11bits) .oa1en().set_bit() ); // Enable acknowlidge control - i2c.cr1.modify(|_, w| w.sbc().set_bit() ); + i2c.cr1().modify(|_, w| w.sbc().set_bit() ); } if config.slave_address_2 > 0 { - i2c.oar2.write( |w| - w.oa2msk().bits( config.slave_address_mask as u8) - .oa2().bits(config.slave_address_2) - .oa2en().set_bit() - ); + i2c.oar2().write(|w| { + w.oa2msk().set(config.slave_address_mask as u8); + w.oa2().set(config.slave_address_2); + w.oa2en().set_bit() + }); // Enable acknowlidge control - i2c.cr1.modify(|_, w| w.sbc().set_bit() ); + i2c.cr1().modify(|_, w| w.sbc().set_bit() ); } // Enable pins @@ -214,21 +212,23 @@ macro_rules! i2c { pub fn listen(&mut self, ev: i2c::Event) { match ev { - i2c::Event::AddressMatch => self.i2c.cr1.modify(|_, w| w.addrie().set_bit()), - i2c::Event::Rxne => self.i2c.cr1.modify(|_, w| w.rxie().set_bit()), - } + i2c::Event::AddressMatch => self.i2c.cr1().modify(|_, w| w.addrie().set_bit()), + i2c::Event::Rxne => self.i2c.cr1().modify(|_, w| w.rxie().set_bit()), + }; } pub fn unlisten(&mut self, ev: i2c::Event) { match ev { - i2c::Event::AddressMatch => self.i2c.cr1.modify(|_, w| w.addrie().clear_bit()), - i2c::Event::Rxne => self.i2c.cr1.modify(|_, w| w.rxie().clear_bit()), - } + i2c::Event::AddressMatch => self.i2c.cr1().modify(|_, w| w.addrie().clear_bit()), + i2c::Event::Rxne => self.i2c.cr1().modify(|_, w| w.rxie().clear_bit()), + }; } pub fn clear_irq(&mut self, ev: i2c::Event) { match ev { - i2c::Event::AddressMatch => self.i2c.icr.write(|w| w.addrcf().set_bit()), + i2c::Event::AddressMatch => { + self.i2c.icr().write(|w| w.addrcf().set_bit()); + } _ => {}, } } @@ -255,30 +255,29 @@ 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() {}; // flush i2c tx register - self.i2c.isr.write(|w| w.txe().set_bit()); + self.i2c.isr().write(|w| w.txe().set_bit()); // 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| - w - // Set number of bytes to transfer - .nbytes().bits(sndlen as u8) - // Set address to transfer to/from - .sadd().bits((addr << 1) as u16) - // 7-bit addressing mode - .add10().clear_bit() - // Set transfer direction to write - .rd_wrn().clear_bit() - // Software end mode - .autoend().clear_bit() - .reload().clear_bit() - // Start transfer - .start().set_bit() - ); + self.i2c.cr2().write(|w| { + // Set number of bytes to transfer + w.nbytes().set(sndlen as u8); + // Set address to transfer to/from + w.sadd().set((addr << 1) as u16); + // 7-bit addressing mode + w.add10().clear_bit(); + // Set transfer direction to write + w.rd_wrn().clear_bit(); + // Software end mode + w.autoend().clear_bit(); + w.reload().clear_bit(); + // Start transfer + w.start().set_bit() + }); let mut idx = 0; // Wait until we are allowed to send data // (START has been ACKed or last byte went through) @@ -286,7 +285,7 @@ macro_rules! i2c { for byte in snd_buffer { busy_wait!(self.i2c, txis, bit_is_set, idx, sndlen); // Put byte on the wire - self.i2c.txdr.write(|w| w.txdata().bits(*byte) ); + self.i2c.txdr().write(|w| w.txdata().set(*byte)); idx += 1; } // Wait until the write finishes before beginning to read. @@ -294,29 +293,28 @@ macro_rules! i2c { busy_wait!(self.i2c, tc, bit_is_set, idx, dummy ); // reSTART and prepare to receive bytes into `rcv_buffer` - self.i2c.cr2.write(|w| - w - // Set number of bytes to transfer - .nbytes().bits(rcvlen as u8) - // Set address to transfer to/from - .sadd().bits((addr << 1) as u16) - // 7-bit addressing mode - .add10().clear_bit() - // Set transfer direction to read - .rd_wrn().set_bit() - // Automatic end mode - .autoend().set_bit() - .reload().clear_bit() - // Start transfer - .start().set_bit() - ); + self.i2c.cr2().write(|w| { + // Set number of bytes to transfer + w.nbytes().set(rcvlen as u8); + // Set address to transfer to/from + w.sadd().set((addr << 1) as u16); + // 7-bit addressing mode + w.add10().clear_bit(); + // Set transfer direction to read + w.rd_wrn().set_bit(); + // Automatic end mode + w.autoend().set_bit(); + w.reload().clear_bit(); + // Start transfer + w.start().set_bit() + }); idx = 0; loop { // Wait until we have received something. Handle all state in busy_wait macro busy_wait!(self.i2c, rxne, bit_is_set, idx, rcvlen); if idx < rcvlen { - rcv_buffer[idx] = self.i2c.rxdr.read().rxdata().bits(); + rcv_buffer[idx] = self.i2c.rxdr().read().rxdata().bits(); idx +=1; } } @@ -332,22 +330,21 @@ 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() {}; - - self.i2c.cr2.modify(|_, w| - w - // Start transfer - .start().set_bit() - // Set number of bytes to transfer - .nbytes().bits(buflen as u8) - // Set address to transfer to/from - .sadd().bits((addr << 1) as u16) - // Set transfer direction to write - .rd_wrn().clear_bit() - // Automatic end mode - .autoend().set_bit() - .reload().clear_bit() - ); + while self.i2c.cr2().read().start().bit_is_set() {}; + + self.i2c.cr2().modify(|_, w| { + // Start transfer + w.start().set_bit(); + // Set number of bytes to transfer + w.nbytes().set(buflen as u8); + // Set address to transfer to/from + w.sadd().set((addr << 1) as u16); + // Set transfer direction to write + w.rd_wrn().clear_bit(); + // Automatic end mode + w.autoend().set_bit(); + w.reload().clear_bit() + }); let mut idx = 0; loop { @@ -356,7 +353,7 @@ macro_rules! i2c { // Put byte on the wire if idx < buflen { - self.i2c.txdr.write(|w| w.txdata().bits(bytes[idx]) ); + self.i2c.txdr().write(|w| w.txdata().set(bytes[idx])); idx += 1; } } @@ -373,33 +370,32 @@ 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() {}; // Flush rxdr register - let _ = self.i2c.rxdr.read().rxdata().bits(); + let _ = self.i2c.rxdr().read().rxdata().bits(); // 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| - w - // Start transfer - .start().set_bit() - // Set number of bytes to transfer - .nbytes().bits(buflen as u8) - // Set address to transfer to/from - .sadd().bits((addr << 1) as u16) - // Set transfer direction to read - .rd_wrn().set_bit() - // automatic end mode - .autoend().set_bit() - .reload().clear_bit() - ); + self.i2c.cr2().modify(|_, w| { + // Start transfer + w.start().set_bit(); + // Set number of bytes to transfer + w.nbytes().set(buflen as u8); + // Set address to transfer to/from + w.sadd().set((addr << 1) as u16); + // Set transfer direction to read + w.rd_wrn().set_bit(); + // automatic end mode + w.autoend().set_bit(); + w.reload().clear_bit() + }); let mut idx = 0; loop { // Wait until we have received something busy_wait!(self.i2c, rxne, bit_is_set, idx, buflen); if idx < buflen { - bytes[idx] = self.i2c.rxdr.read().rxdata().bits(); + bytes[idx] = self.i2c.rxdr().read().rxdata().bits(); idx +=1; } } @@ -410,12 +406,12 @@ macro_rules! i2c { fn slave_sbc(&mut self, sbc_enabled: bool) { // Enable Slave byte control - self.i2c.cr1.modify(|_, w| w.sbc().bit(sbc_enabled) ); + self.i2c.cr1().modify(|_, w| w.sbc().bit(sbc_enabled) ); } fn slave_addressed(&mut self) -> Result, Error> { - if self.i2c.isr.read().addr().bit_is_set() { - let isr = self.i2c.isr.read(); + if self.i2c.isr().read().addr().bit_is_set() { + let isr = self.i2c.isr().read(); let current_address = isr.addcode().bits() as u16; // if the dir bit is set it is a master write slave read operation @@ -447,14 +443,14 @@ macro_rules! i2c { assert!(buflen < 256 && buflen > 0); // Set the nbytes and prepare to send bytes into `buffer`. - self.i2c.cr2.modify(|_, w| - w.nbytes().bits( buflen as u8) - .reload().clear_bit() - ); + self.i2c.cr2().modify(|_, w| { + w.nbytes().set( buflen as u8); + w.reload().clear_bit() + }); // flush i2c tx register - self.i2c.isr.write(|w| w.txe().set_bit()); + self.i2c.isr().write(|w| w.txe().set_bit()); // end address phase, release clock stretching - self.i2c.icr.write(|w| w.addrcf().set_bit() ); + self.i2c.icr().write(|w| w.addrcf().set_bit() ); let mut idx = 0; loop { @@ -463,13 +459,13 @@ macro_rules! i2c { // Put byte on the wire if idx < buflen { - self.i2c.txdr.write(|w| w.txdata().bits(bytes[idx]) ); + self.i2c.txdr().write(|w| w.txdata().set(bytes[idx])); idx += 1; } else { // we will never reach here. In case the master wants to read more than buflen // the hardware will send 0xFF // Also means that on slave side we cannot detect this error case - self.i2c.txdr.write(|w| w.txdata().bits(0x21) ); + self.i2c.txdr().write(|w| w.txdata().set(0x21)); } } } @@ -480,15 +476,14 @@ macro_rules! i2c { assert!(buflen < 256 && buflen > 0); // Set the nbytes START and prepare to receive bytes into `buffer`. - self.i2c.cr2.modify(|_, w| - w - // Set number of bytes to transfer: maximum as all incoming bytes will be ACK'ed - .nbytes().bits(buflen as u8) - // during sending nbytes automatically send a ACK, stretch clock after last byte - .reload().set_bit() - ); + self.i2c.cr2().modify(|_, w| { + // Set number of bytes to transfer: maximum as all incoming bytes will be ACK'ed + w.nbytes().set(buflen as u8); + // during sending nbytes automatically send a ACK, stretch clock after last byte + w.reload().set_bit() + }); // end address phase, release clock stretching - self.i2c.icr.write(|w| + self.i2c.icr().write(|w| w.addrcf().set_bit() ); flush_rxdr!(self.i2c); @@ -500,7 +495,7 @@ macro_rules! i2c { // read byte from wire if idx < buflen { - bytes[idx] = self.i2c.rxdr.read().rxdata().bits(); + bytes[idx] = self.i2c.rxdr().read().rxdata().bits(); idx += 1; } } diff --git a/src/lib.rs b/src/lib.rs index 9e6f157..2562b8b 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -37,6 +37,9 @@ pub use stm32g0::stm32g081 as stm32; #[cfg(feature = "stm32g070")] pub use stm32g0::stm32g070 as stm32; +#[cfg(feature = "stm32g0b1")] +pub use stm32g0::stm32g0b1 as stm32; + #[cfg(feature = "rt")] pub use crate::stm32::interrupt; diff --git a/src/power.rs b/src/power.rs index 9dcb32b..cc94495 100644 --- a/src/power.rs +++ b/src/power.rs @@ -40,34 +40,44 @@ impl Power { } pub fn get_standby_flag(&mut self) -> bool { - self.rb.sr1.read().sbf().bit_is_set() + self.rb.sr1().read().sbf().bit_is_set() } pub fn get_wakeup_flag>(&self, lane: L) -> bool { match lane.into() { - WakeUp::Line1 => self.rb.sr1.read().wuf1().bit_is_set(), - WakeUp::Line2 => self.rb.sr1.read().wuf2().bit_is_set(), - WakeUp::Line4 => self.rb.sr1.read().wuf4().bit_is_set(), - WakeUp::Line5 => self.rb.sr1.read().wuf5().bit_is_set(), - WakeUp::Line6 => self.rb.sr1.read().wuf6().bit_is_set(), + WakeUp::Line1 => self.rb.sr1().read().wuf1().bit_is_set(), + WakeUp::Line2 => self.rb.sr1().read().wuf2().bit_is_set(), + WakeUp::Line4 => self.rb.sr1().read().wuf4().bit_is_set(), + WakeUp::Line5 => self.rb.sr1().read().wuf5().bit_is_set(), + WakeUp::Line6 => self.rb.sr1().read().wuf6().bit_is_set(), _ => false, } } pub fn clear_wakeup_flag>(&mut self, lane: L) { match lane.into() { - WakeUp::Line1 => self.rb.scr.write(|w| w.cwuf1().set_bit()), - WakeUp::Line2 => self.rb.scr.write(|w| w.cwuf2().set_bit()), - WakeUp::Line4 => self.rb.scr.write(|w| w.cwuf4().set_bit()), - WakeUp::Line5 => self.rb.scr.write(|w| w.cwuf5().set_bit()), - WakeUp::Line6 => self.rb.scr.write(|w| w.cwuf6().set_bit()), + WakeUp::Line1 => { + self.rb.scr().write(|w| w.cwuf1().set_bit()); + } + WakeUp::Line2 => { + self.rb.scr().write(|w| w.cwuf2().set_bit()); + } + WakeUp::Line4 => { + self.rb.scr().write(|w| w.cwuf4().set_bit()); + } + WakeUp::Line5 => { + self.rb.scr().write(|w| w.cwuf5().set_bit()); + } + WakeUp::Line6 => { + self.rb.scr().write(|w| w.cwuf6().set_bit()); + } _ => {} } } pub fn clear_standby_flag(&mut self) { - if self.rb.sr1.read().sbf().bit_is_set() { - self.rb.scr.write(|w| w.csbf().set_bit()); + if self.rb.sr1().read().sbf().bit_is_set() { + self.rb.scr().write(|w| w.csbf().set_bit()); } } @@ -77,62 +87,77 @@ impl Power { let edge = edge == SignalEdge::Falling; match lane.into() { WakeUp::Line1 => { - self.rb.cr3.modify(|_, w| w.ewup1().set_bit()); - self.rb.cr4.modify(|_, w| w.wp1().bit(edge)); + self.rb.cr3().modify(|_, w| w.ewup1().set_bit()); + self.rb.cr4().modify(|_, w| w.wp1().bit(edge)); } WakeUp::Line2 => { - self.rb.cr3.modify(|_, w| w.ewup2().set_bit()); - self.rb.cr4.modify(|_, w| w.wp2().bit(edge)); + self.rb.cr3().modify(|_, w| w.ewup2().set_bit()); + self.rb.cr4().modify(|_, w| w.wp2().bit(edge)); } WakeUp::Line4 => { - self.rb.cr3.modify(|_, w| w.ewup4().set_bit()); - self.rb.cr4.modify(|_, w| w.wp4().bit(edge)); + self.rb.cr3().modify(|_, w| w.ewup4().set_bit()); + self.rb.cr4().modify(|_, w| w.wp4().bit(edge)); } WakeUp::Line5 => { - self.rb.cr3.modify(|_, w| w.ewup5().set_bit()); - self.rb.cr4.modify(|_, w| w.wp5().bit(edge)); + self.rb.cr3().modify(|_, w| w.ewup5().set_bit()); + self.rb.cr4().modify(|_, w| w.wp5().bit(edge)); } WakeUp::Line6 => { - self.rb.cr3.modify(|_, w| w.ewup6().set_bit()); - self.rb.cr4.modify(|_, w| w.wp6().bit(edge)); + self.rb.cr3().modify(|_, w| w.ewup6().set_bit()); + self.rb.cr4().modify(|_, w| w.wp6().bit(edge)); + } + WakeUp::InternalLine => { + self.rb.cr3().modify(|_, w| w.eiwul().set_bit()); } - WakeUp::InternalLine => self.rb.cr3.modify(|_, w| w.eiwul().set_bit()), } } pub fn disable_wakeup_lane>(&mut self, lane: L) { match lane.into() { - WakeUp::Line1 => self.rb.cr3.modify(|_, w| w.ewup1().clear_bit()), - WakeUp::Line2 => self.rb.cr3.modify(|_, w| w.ewup2().clear_bit()), - WakeUp::Line4 => self.rb.cr3.modify(|_, w| w.ewup4().clear_bit()), - WakeUp::Line5 => self.rb.cr3.modify(|_, w| w.ewup5().clear_bit()), - WakeUp::Line6 => self.rb.cr3.modify(|_, w| w.ewup6().clear_bit()), - WakeUp::InternalLine => self.rb.cr3.modify(|_, w| w.eiwul().clear_bit()), - } + WakeUp::Line1 => self.rb.cr3().modify(|_, w| w.ewup1().clear_bit()), + WakeUp::Line2 => self.rb.cr3().modify(|_, w| w.ewup2().clear_bit()), + WakeUp::Line4 => self.rb.cr3().modify(|_, w| w.ewup4().clear_bit()), + WakeUp::Line5 => self.rb.cr3().modify(|_, w| w.ewup5().clear_bit()), + WakeUp::Line6 => self.rb.cr3().modify(|_, w| w.ewup6().clear_bit()), + WakeUp::InternalLine => self.rb.cr3().modify(|_, w| w.eiwul().clear_bit()), + }; } + #[cfg(not(feature = "stm32g0x0"))] pub fn set_mode(&mut self, mode: PowerMode) { match mode { PowerMode::Run => { - self.rb.cr1.modify(|_, w| w.lpr().clear_bit()); - while !self.rb.sr2.read().reglpf().bit_is_clear() {} + self.rb.cr1().modify(|_, w| w.lpr().clear_bit()); + while !self.rb.sr2().read().reglpf().bit_is_clear() {} } PowerMode::LowPower(sm) => { - self.rb.cr3.modify(|_, w| w.ulpen().clear_bit()); + self.rb.cr3().modify(|_, w| { + #[cfg(not(feature = "stm32g071"))] + w.enb_ulp().clear_bit(); + #[cfg(feature = "stm32g071")] + w.ulpen().clear_bit(); + w + }); self.rb - .cr1 + .cr1() .modify(|_, w| unsafe { w.lpr().set_bit().lpms().bits(sm as u8) }); - while !self.rb.sr2.read().reglps().bit_is_set() - || !self.rb.sr2.read().reglpf().bit_is_set() + while !self.rb.sr2().read().reglps().bit_is_set() + || !self.rb.sr2().read().reglpf().bit_is_set() {} } PowerMode::UltraLowPower(sm) => { - self.rb.cr3.modify(|_, w| w.ulpen().set_bit()); + self.rb.cr3().modify(|_, w| { + #[cfg(not(feature = "stm32g071"))] + w.enb_ulp().set_bit(); + #[cfg(feature = "stm32g071")] + w.ulpen().set_bit(); + w + }); self.rb - .cr1 + .cr1() .modify(|_, w| unsafe { w.lpr().set_bit().lpms().bits(sm as u8) }); - while !self.rb.sr2.read().reglps().bit_is_set() - || !self.rb.sr2.read().reglpf().bit_is_set() + while !self.rb.sr2().read().reglps().bit_is_set() + || !self.rb.sr2().read().reglpf().bit_is_set() {} } } diff --git a/src/rcc/clockout.rs b/src/rcc/clockout.rs index 8379367..4780e3c 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 { @@ -42,7 +42,7 @@ impl LSCOExt for LscoPin { }; rcc.unlock_rtc(); self.set_alt_mode(AltFunction::AF0); - rcc.bdcr.modify(|_, w| w.lscosel().bit(src_select_bit)); + rcc.bdcr().modify(|_, w| w.lscosel().bit(src_select_bit)); Lsco { pin: self } } } @@ -58,13 +58,13 @@ where { 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 { @@ -93,7 +93,7 @@ macro_rules! mco { _ => 0b111, }; - rcc.cfgr.modify(|r, w| unsafe { + rcc.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 cfe9a7f..8c4db1e 100644 --- a/src/rcc/enable.rs +++ b/src/rcc/enable.rs @@ -103,7 +103,6 @@ macro_rules! bus { bus! { CRC => (AHB, crcen, crcsmen, crcrst), // 12 FLASH => (AHB, flashen, flashsmen, flashrst), // 8 - DMA => (AHB, dmaen, dmasmen, dmarst), // 0 DBG => (APB1, dbgen, dbgsmen, dbgrst), // 27 I2C1 => (APB1, i2c1en, i2c1smen, i2c1rst), // 21 @@ -122,7 +121,23 @@ bus! { TIM16 => (APB2, tim16en, tim16smen, tim16rst), // 17 TIM17 => (APB2, tim17en, tim17smen, tim17rst), // 18 USART1 => (APB2, usart1en, usart1smen, usart1rst), // 14 +} + +#[cfg(any(feature = "stm32g0x0", feature = "stm32g0b1", feature = "stm32g0c1"))] +bus! { + GPIOA => (IOP, gpioaen, gpioasmen, gpioarst), // 0 + GPIOB => (IOP, gpioben, gpiobsmen, gpiobrst), // 1 + GPIOC => (IOP, gpiocen, gpiocsmen, gpiocrst), // 2 + GPIOD => (IOP, gpioden, gpiodsmen, gpiodrst), // 3 + GPIOF => (IOP, gpiofen, gpiofsmen, gpiofrst), // 5 +} +#[cfg(any(feature = "stm32g0b1", feature = "stm32g0c1"))] +bus! { + GPIOE => (IOP, gpioeen, gpioesmen, gpioerst), // 4 +} +#[cfg(not(any(feature = "stm32g0x0", feature = "stm32g0b1", feature = "stm32g0c1")))] +bus! { GPIOA => (IOP, iopaen, iopasmen, ioparst), // 0 GPIOB => (IOP, iopben, iopbsmen, iopbrst), // 1 GPIOC => (IOP, iopcen, iopcsmen, iopcrst), // 2 @@ -141,6 +156,20 @@ bus! { RNG => (AHB, rngen, rngsmen, rngrst), // 18 } +#[cfg(not(any(feature = "stm32g0x0", feature = "stm32g0b1", feature = "stm32g0c1")))] +bus! { + DMA1 => (AHB, dmaen, dmasmen, dmarst), // 0 +} + +#[cfg(any(feature = "stm32g0x0", feature = "stm32g0b1", feature = "stm32g0c1"))] +bus! { + DMA1 => (AHB, dma1en, dma1smen, dma1rst), // 0 +} +#[cfg(any(feature = "stm32g0b1", feature = "stm32g0c1"))] +bus! { + DMA2 => (AHB, dma2en, dma2smen, dma2rst), // 1 +} + #[cfg(any(feature = "stm32g071", feature = "stm32g081"))] bus! { HDMI_CEC => (APB1, cecen, cecsmen, cecrst), // 24 @@ -153,10 +182,20 @@ bus! { bus! { LPTIM1 => (APB1, lptim1en, lptim1smen, lptim1rst), // 31 LPTIM2 => (APB1, lptim2en, lptim2smen, lptim2rst), // 30 - LPUART => (APB1, lpuart1en, lpuart1smen, lpuart1rst), // 20 TIM2 => (APB1, tim2en, tim2smen, tim2rst), // 0 } +#[cfg(feature = "stm32g0x1")] +#[cfg(not(any(feature = "stm32g0b1", feature = "stm32g0c1")))] +bus! { + LPUART => (APB1, lpuart1en, lpuart1smen, lpuart1rst), // 20 +} + +#[cfg(any(feature = "stm32g0b1", feature = "stm32g0c1"))] +bus! { + LPUART1 => (APB1, lpuart1en, lpuart1smen, lpuart1rst), // 20 +} + #[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))] bus! { TIM6 => (APB1, tim6en, tim6smen, tim6rst), // 4 diff --git a/src/rcc/mod.rs b/src/rcc/mod.rs index df9427a..a6340dc 100644 --- a/src/rcc/mod.rs +++ b/src/rcc/mod.rs @@ -122,7 +122,7 @@ impl Rcc { Prescaler::Div128 => (HSI_FREQ / 128, 0b111), _ => (HSI_FREQ, 0b000), }; - self.cr.write(|w| unsafe { w.hsidiv().bits(div_bits) }); + self.cr().write(|w| unsafe { w.hsidiv().bits(div_bits) }); (freq.Hz(), 0b000) } }; @@ -150,7 +150,7 @@ impl Rcc { unsafe { // Adjust flash wait states let flash = &(*FLASH::ptr()); - flash.acr.modify(|_, w| { + flash.acr().modify(|_, w| { w.latency().bits(if sys_clk.raw() <= 24_000_000 { 0b000 } else if sys_clk.raw() <= 48_000_000 { @@ -158,10 +158,10 @@ impl Rcc { } else { 0b010 }) - }) + }); } - self.cfgr.modify(|_, w| unsafe { + self.cfgr().modify(|_, w| unsafe { w.hpre() .bits(ahb_psc_bits) .ppre() @@ -170,7 +170,7 @@ impl Rcc { .bits(sw_bits) }); - while self.cfgr.read().sws().bits() != sw_bits {} + while self.cfgr().read().sws().bits() != sw_bits {} Rcc { rb: self.rb, @@ -186,24 +186,26 @@ impl Rcc { } pub fn trim_hsi_clocks(&mut self, value: u8) { - self.icscr.modify(|_, w| unsafe { w.hsitrim().bits(value) }); + self.icscr() + .modify(|_, w| unsafe { w.hsitrim().bits(value) }); } + #[cfg(not(feature = "stm32g0x0"))] pub fn set_reset_mode(&mut self, mode: ResetMode) { unsafe { let flash = &(*FLASH::ptr()); // Unlock flash - flash.keyr.write(|w| w.keyr().bits(0x4567_0123)); - flash.keyr.write(|w| w.keyr().bits(0xcdef_89ab)); + flash.keyr().write(|w| w.key().bits(0x4567_0123)); + flash.keyr().write(|w| w.key().bits(0xcdef_89ab)); // Unlock flash OTP - flash.optkeyr.write(|w| w.optkeyr().bits(0x0819_2a3b)); - flash.optkeyr.write(|w| w.optkeyr().bits(0x4c5d_6e7f)); - flash.cr.modify(|_, w| w.optlock().clear_bit()); + flash.optkeyr().write(|w| w.optkey().bits(0x0819_2a3b)); + flash.optkeyr().write(|w| w.optkey().bits(0x4c5d_6e7f)); + flash.cr().modify(|_, w| w.optlock().clear_bit()); - flash.optr.modify(|_, w| w.nrst_mode().bits(mode as u8)); - flash.cr.modify(|_, w| w.optstrt().set_bit()); + flash.optr().modify(|_, w| w.nrst_mode().bits(mode as u8)); + flash.cr().modify(|_, w| w.optstrt().set_bit()); } } @@ -214,7 +216,7 @@ impl Rcc { // If the system is currently clocked from the PLL, then switch back to // the HSI before we disable the PLL, otherwise the PLL will refuse to // switch off. - self.cfgr.modify(|r, w| { + self.cfgr().modify(|r, w| { if r.sw().bits() == 0b010 { unsafe { w.sw().bits(0b000) }; } @@ -222,8 +224,8 @@ impl Rcc { }); // Disable PLL - self.cr.modify(|_, w| w.pllon().clear_bit()); - while self.cr.read().pllrdy().bit_is_set() {} + self.cr().modify(|_, w| w.pllon().clear_bit()); + while self.cr().read().pllrdy().bit_is_set() {} let (freq, pll_sw_bits) = match pll_cfg.mux { PLLSrc::HSI => { @@ -245,7 +247,7 @@ impl Rcc { let mut q = None; let mut p = None; - self.pllsyscfgr.write(|w| unsafe { + self.pllcfgr().write(|w| unsafe { w.pllsrc().bits(pll_sw_bits); w.pllm().bits(pll_cfg.m - 1); w.plln().bits(pll_cfg.n); @@ -269,47 +271,47 @@ impl Rcc { }); // Enable PLL - self.cr.modify(|_, w| w.pllon().set_bit()); - while self.cr.read().pllrdy().bit_is_clear() {} + self.cr().modify(|_, w| w.pllon().set_bit()); + while self.cr().read().pllrdy().bit_is_clear() {} PLLClocks { r, q, p } } pub(crate) fn enable_hsi(&self) { - self.cr.modify(|_, w| w.hsion().set_bit()); - while self.cr.read().hsirdy().bit_is_clear() {} + self.cr().modify(|_, w| w.hsion().set_bit()); + while self.cr().read().hsirdy().bit_is_clear() {} } pub(crate) fn enable_hse(&self, bypass: bool) { - self.cr + self.cr() .modify(|_, w| w.hseon().set_bit().hsebyp().bit(bypass)); - while self.cr.read().hserdy().bit_is_clear() {} + while self.cr().read().hserdy().bit_is_clear() {} } pub(crate) fn enable_lse(&self, bypass: bool) { - self.bdcr + self.bdcr() .modify(|_, w| w.lseon().bit(!bypass).lsebyp().bit(bypass)); - while !bypass && self.bdcr.read().lserdy().bit_is_clear() {} + while !bypass && self.bdcr().read().lserdy().bit_is_clear() {} } pub(crate) fn enable_lsi(&self) { - self.csr.modify(|_, w| w.lsion().set_bit()); - while self.csr.read().lsirdy().bit_is_clear() {} + self.csr().modify(|_, w| w.lsion().set_bit()); + while self.csr().read().lsirdy().bit_is_clear() {} } pub(crate) fn unlock_rtc(&self) { - self.apbenr1.modify(|_, w| w.pwren().set_bit()); + self.apbenr1().modify(|_, w| w.pwren().set_bit()); let pwr = unsafe { &(*PWR::ptr()) }; - pwr.cr1.modify(|_, w| w.dbp().set_bit()); - while pwr.cr1.read().dbp().bit_is_clear() {} + pwr.cr1().modify(|_, w| w.dbp().set_bit()); + while pwr.cr1().read().dbp().bit_is_clear() {} } pub(crate) fn enable_rtc(&self, src: RTCSrc) { self.unlock_rtc(); - self.apbenr1 + self.apbenr1() .modify(|_, w| w.rtcapben().set_bit().pwren().set_bit()); - self.apbsmenr1.modify(|_, w| w.rtcapbsmen().set_bit()); - self.bdcr.modify(|_, w| w.bdrst().set_bit()); + self.apbsmenr1().modify(|_, w| w.rtcapbsmen().set_bit()); + self.bdcr().modify(|_, w| w.bdrst().set_bit()); let rtc_sel = match src { RTCSrc::LSE | RTCSrc::LSE_BYPASS => 0b01, @@ -317,7 +319,7 @@ impl Rcc { RTCSrc::HSE | RTCSrc::HSE_BYPASS => 0b11, }; - self.bdcr.modify(|_, w| unsafe { + self.bdcr().modify(|_, w| unsafe { w.rtcsel() .bits(rtc_sel) .rtcen() @@ -438,15 +440,15 @@ macro_rules! bus_struct { impl $busX { #[inline(always)] fn enr(rcc: &RccRB) -> &rcc::$EN { - &rcc.$en + &rcc.$en() } #[inline(always)] fn smenr(rcc: &RccRB) -> &rcc::$SMEN { - &rcc.$smen + &rcc.$smen() } #[inline(always)] fn rstr(rcc: &RccRB) -> &rcc::$RST { - &rcc.$rst + &rcc.$rst() } } )+ diff --git a/src/rng.rs b/src/rng.rs index 833f964..7127036 100644 --- a/src/rng.rs +++ b/src/rng.rs @@ -64,11 +64,11 @@ impl RngExt for RNG { fn constrain(self, cfg: Config, rcc: &mut Rcc) -> Rng { RNG::enable(rcc); RNG::reset(rcc); - rcc.ccipr + rcc.ccipr() .modify(|_, w| unsafe { w.rngsel().bits(cfg.clk_src as u8) }); - rcc.ccipr + rcc.ccipr() .modify(|_, w| unsafe { w.rngdiv().bits(cfg.clk_div as u8) }); - self.cr.modify(|_, w| w.rngen().set_bit()); + self.cr().modify(|_, w| w.rngen().set_bit()); Rng { rb: self } } } @@ -86,9 +86,9 @@ pub struct Rng { impl Rng { pub fn gen(&mut self) -> Result { loop { - let status = self.rb.sr.read(); + let status = self.rb.sr().read(); if status.drdy().bit() { - return Ok(self.rb.dr.read().rndata().bits()); + return Ok(self.rb.dr().read().rndata().bits()); } if status.cecs().bit() { return Err(ErrorKind::ClockError); diff --git a/src/rtc.rs b/src/rtc.rs index 32a1e3c..764579e 100644 --- a/src/rtc.rs +++ b/src/rtc.rs @@ -114,7 +114,8 @@ impl Rtc { pub fn set_hour_format(&mut self, fmt: RtcHourFormat) { self.modify(|rb| { - rb.cr.modify(|_, w| w.fmt().bit(fmt == RtcHourFormat::H12)); + rb.cr() + .modify(|_, w| w.fmt().bit(fmt == RtcHourFormat::H12)); }); } @@ -124,7 +125,7 @@ impl Rtc { let (dt, du) = bcd2_encode(date.day); self.modify(|rb| { - rb.dr.write(|w| unsafe { + rb.dr().write(|w| unsafe { w.dt() .bits(dt) .du() @@ -148,7 +149,7 @@ impl Rtc { let (mnt, mnu) = bcd2_encode(time.minutes); let (st, su) = bcd2_encode(time.seconds); self.modify(|rb| { - rb.tr.write(|w| unsafe { + rb.tr().write(|w| unsafe { w.ht() .bits(ht) .hu() @@ -164,22 +165,22 @@ impl Rtc { .pm() .clear_bit() }); - rb.cr.modify(|_, w| w.fmt().bit(time.daylight_savings)); + rb.cr().modify(|_, w| w.fmt().bit(time.daylight_savings)); }); } pub fn get_time(&self) -> Time { - let timer = self.rb.tr.read(); + let timer = self.rb.tr().read(); Time::new( bcd2_decode(timer.ht().bits(), timer.hu().bits()).hours(), bcd2_decode(timer.mnt().bits(), timer.mnu().bits()).minutes(), bcd2_decode(timer.st().bits(), timer.su().bits()).secs(), - self.rb.cr.read().fmt().bit(), + self.rb.cr().read().fmt().bit(), ) } pub fn get_date(&self) -> Date { - let date = self.rb.dr.read(); + let date = self.rb.dr().read(); Date::new( (bcd2_decode(date.yt().bits(), date.yu().bits()) + 1970).year(), bcd2_decode(date.mt().bit() as u8, date.mu().bits()).month(), @@ -188,7 +189,7 @@ impl Rtc { } pub fn get_week_day(&self) -> u8 { - self.rb.dr.read().wdu().bits() + self.rb.dr().read().wdu().bits() } pub fn set_alarm_a(&mut self, alarm: impl Into) { @@ -199,13 +200,13 @@ impl Rtc { let (st, su) = bcd2_encode(alarm.seconds.unwrap_or_default()); self.modify(|rb| { - rb.alrmassr.write(|w| unsafe { + rb.alrmassr().write(|w| unsafe { w.maskss() .bits(alarm.subseconds_mask_bits) .ss() .bits(alarm.subseconds) }); - rb.alrmar.write(|w| unsafe { + rb.alrmar().write(|w| unsafe { w.wdsel().bit(alarm.use_weekday); w.msk1().bit(alarm.seconds.is_none()); w.msk2().bit(alarm.minutes.is_none()); @@ -221,7 +222,7 @@ impl Rtc { w.su().bits(su) }); - rb.cr.modify(|_, w| w.alrae().set_bit()); + rb.cr().modify(|_, w| w.alrae().set_bit()); }); } @@ -232,13 +233,13 @@ impl Rtc { let (st, su) = bcd2_encode(alarm.seconds.unwrap_or_default()); self.modify(|rb| { - rb.alrmbssr.write(|w| unsafe { + rb.alrmbssr().write(|w| unsafe { w.maskss() .bits(alarm.subseconds_mask_bits) .ss() .bits(alarm.subseconds) }); - rb.alrmbr.write(|w| unsafe { + rb.alrmbr().write(|w| unsafe { w.wdsel().bit(alarm.use_weekday); w.msk1().bit(alarm.seconds.is_none()); w.msk2().bit(alarm.minutes.is_none()); @@ -254,43 +255,49 @@ impl Rtc { w.su().bits(su) }); - rb.cr.modify(|_, w| w.alrbe().set_bit()); + rb.cr().modify(|_, w| w.alrbe().set_bit()); }); } pub fn listen(&mut self, ev: Event) { - self.modify(|rb| match ev { - Event::WakeupTimer => rb.cr.modify(|_, w| w.wutie().set_bit()), - Event::AlarmA => rb.cr.modify(|_, w| w.alraie().set_bit()), - Event::AlarmB => rb.cr.modify(|_, w| w.alrbie().set_bit()), - Event::Timestamp => rb.cr.modify(|_, w| w.tsie().set_bit()), + self.modify(|rb| { + match ev { + Event::WakeupTimer => rb.cr().modify(|_, w| w.wutie().set_bit()), + Event::AlarmA => rb.cr().modify(|_, w| w.alraie().set_bit()), + Event::AlarmB => rb.cr().modify(|_, w| w.alrbie().set_bit()), + Event::Timestamp => rb.cr().modify(|_, w| w.tsie().set_bit()), + }; }) } pub fn unlisten(&mut self, ev: Event) { - self.modify(|rb| match ev { - Event::WakeupTimer => rb.cr.modify(|_, w| w.wutie().clear_bit()), - Event::AlarmA => rb.cr.modify(|_, w| w.alraie().clear_bit()), - Event::AlarmB => rb.cr.modify(|_, w| w.alrbie().clear_bit()), - Event::Timestamp => rb.cr.modify(|_, w| w.tsie().clear_bit()), + self.modify(|rb| { + match ev { + Event::WakeupTimer => rb.cr().modify(|_, w| w.wutie().clear_bit()), + Event::AlarmA => rb.cr().modify(|_, w| w.alraie().clear_bit()), + Event::AlarmB => rb.cr().modify(|_, w| w.alrbie().clear_bit()), + Event::Timestamp => rb.cr().modify(|_, w| w.tsie().clear_bit()), + }; }) } pub fn is_pending(&self, ev: Event) -> bool { match ev { - Event::WakeupTimer => self.rb.sr.read().wutf().bit_is_set(), - Event::AlarmA => self.rb.sr.read().alraf().bit_is_set(), - Event::AlarmB => self.rb.sr.read().alrbf().bit_is_set(), - Event::Timestamp => self.rb.sr.read().tsf().bit_is_set(), + Event::WakeupTimer => self.rb.sr().read().wutf().bit_is_set(), + Event::AlarmA => self.rb.sr().read().alraf().bit_is_set(), + Event::AlarmB => self.rb.sr().read().alrbf().bit_is_set(), + Event::Timestamp => self.rb.sr().read().tsf().bit_is_set(), } } pub fn unpend(&mut self, ev: Event) { - self.modify(|rb| match ev { - Event::WakeupTimer => rb.scr.modify(|_, w| w.cwutf().set_bit()), - Event::AlarmA => rb.scr.modify(|_, w| w.calraf().set_bit()), - Event::AlarmB => rb.scr.modify(|_, w| w.calrbf().set_bit()), - Event::Timestamp => rb.scr.modify(|_, w| w.ctsf().set_bit()), + self.modify(|rb| { + match ev { + Event::WakeupTimer => rb.scr().write(|w| w.cwutf().set_bit()), + Event::AlarmA => rb.scr().write(|w| w.calraf().set_bit()), + Event::AlarmB => rb.scr().write(|w| w.calrbf().set_bit()), + Event::Timestamp => rb.scr().write(|w| w.ctsf().set_bit()), + }; }); } @@ -301,7 +308,7 @@ impl Rtc { ) { pin.setup(); self.modify(|rb| { - rb.cr.modify(|_, w| unsafe { + rb.cr().modify(|_, w| unsafe { w.osel() .bits(0b0) .out2en() @@ -321,21 +328,21 @@ impl Rtc { F: FnMut(&mut RTC), { // Disable write protection - self.rb.wpr.write(|w| unsafe { w.bits(0xCA) }); - self.rb.wpr.write(|w| unsafe { w.bits(0x53) }); + self.rb.wpr().write(|w| unsafe { w.bits(0xCA) }); + self.rb.wpr().write(|w| unsafe { w.bits(0x53) }); // Enter init mode - let isr = self.rb.icsr.read(); + let isr = self.rb.icsr().read(); if isr.initf().bit_is_clear() { - self.rb.icsr.write(|w| w.init().set_bit()); - self.rb.icsr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); - while self.rb.icsr.read().initf().bit_is_clear() {} + self.rb.icsr().write(|w| w.init().set_bit()); + self.rb.icsr().write(|w| unsafe { w.bits(0xFFFF_FFFF) }); + while self.rb.icsr().read().initf().bit_is_clear() {} } // Invoke closure closure(&mut self.rb); // Exit init mode - self.rb.icsr.write(|w| w.init().clear_bit()); + self.rb.icsr().write(|w| w.init().clear_bit()); // Enable_write_protection - self.rb.wpr.write(|w| unsafe { w.bits(0xFF) }); + self.rb.wpr().write(|w| unsafe { w.bits(0xFF) }); } } diff --git a/src/serial/usart.rs b/src/serial/usart.rs index 54555bc..19dad05 100644 --- a/src/serial/usart.rs +++ b/src/serial/usart.rs @@ -250,43 +250,47 @@ macro_rules! uart_shared { /// Listen for a data 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 a data 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() + #[cfg(not(any(feature = "stm32g0b1", feature = "stm32g0c1")))] + let f = usart.isr().read().rxne().bit_is_set(); + #[cfg(any(feature = "stm32g0b1", feature = "stm32g0c1"))] + let f = usart.isr().read().rxfne().bit_is_set(); + f } /// Listen for an idle interrupt event pub fn listen_idle(&mut self) { let usart = unsafe { &(*$USARTX::ptr()) }; - usart.cr1.modify(|_, w| w.idleie().set_bit()); + usart.cr1().modify(|_, w| w.idleie().set_bit()); } /// Stop listening for an idle interrupt event pub fn unlisten_idle(&mut self) { let usart = unsafe { &(*$USARTX::ptr()) }; - usart.cr1.modify(|_, w| w.idleie().clear_bit()); + usart.cr1().modify(|_, w| w.idleie().clear_bit()); } /// Return true if the idle event occured pub fn is_idle(&self) -> bool { let usart = unsafe { &(*$USARTX::ptr()) }; - usart.isr.read().idle().bit_is_set() + usart.isr().read().idle().bit_is_set() } /// Clear the idle event flag pub fn clear_idle(&mut self) { let usart = unsafe { &(*$USARTX::ptr()) }; - usart.icr.write(|w| w.idlecf().set_bit()); + usart.icr().write(|w| w.idlecf().set_bit()); } } @@ -295,22 +299,38 @@ 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()); + } else if { + #[cfg(not(any(feature = "stm32g0b1", feature = "stm32g0c1")))] + let f = isr.nf().bit_is_set(); + #[cfg(any(feature = "stm32g0b1", feature = "stm32g0c1"))] + let f = isr.ne().bit_is_set(); + f + } + { + #[cfg(not(any(feature = "stm32g0b1", feature = "stm32g0c1")))] + usart.icr().write(|w| w.ncf().set_bit()); + #[cfg(any(feature = "stm32g0b1", feature = "stm32g0c1"))] + usart.icr().write(|w| w.necf().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) + } else if { + #[cfg(not(any(feature = "stm32g0b1", feature = "stm32g0c1")))] + let f = isr.rxne().bit_is_set(); + #[cfg(any(feature = "stm32g0b1", feature = "stm32g0c1"))] + let f = isr.rxfne().bit_is_set(); + f + } { + return Ok(usart.rdr().read().bits() as u8) } else { nb::Error::WouldBlock } @@ -331,19 +351,23 @@ 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() + #[cfg(not(any(feature = "stm32g0b1", feature = "stm32g0c1")))] + let f = usart.isr().read().txe().bit_is_set(); + #[cfg(any(feature = "stm32g0b1", feature = "stm32g0c1"))] + let f = usart.isr().read().txfnf().bit_is_set(); + f } } @@ -353,7 +377,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) @@ -362,8 +386,14 @@ 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 { + #[cfg(not(any(feature = "stm32g0b1", feature = "stm32g0c1")))] + let f = usart.isr().read().txe().bit_is_set(); + #[cfg(any(feature = "stm32g0b1", feature = "stm32g0c1"))] + let f = usart.isr().read().txfnf().bit_is_set(); + f + } { + usart.tdr().write(|w| unsafe { w.bits(byte as u32) }); Ok(()) } else { Err(nb::Error::WouldBlock) @@ -403,7 +433,7 @@ macro_rules! uart_shared { fn enable_dma(&mut self) { // NOTE(unsafe) critical section prevents races interrupt::free(|_| unsafe { - let cr3 = &(*$USARTX::ptr()).cr3; + let cr3 = &(*$USARTX::ptr()).cr3(); cr3.modify(|_, w| w.dmar().set_bit()); }); } @@ -411,7 +441,7 @@ macro_rules! uart_shared { fn disable_dma(&mut self) { // 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()); }); } @@ -426,7 +456,7 @@ macro_rules! uart_shared { fn enable_dma(&mut self) { // 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()); }); } @@ -434,7 +464,7 @@ macro_rules! uart_shared { fn disable_dma(&mut self) { // 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()); }); } @@ -470,16 +500,16 @@ macro_rules! uart_basic { let clk = rcc.clocks.apb_clk.raw() as u64; let bdr = config.baudrate.0 as u64; let div = ($clk_mul * clk) / bdr; - usart.brr.write(|w| unsafe { w.bits(div as u32) }); + usart.brr().write(|w| unsafe { w.bits(div as u32) }); // Reset other registers to disable advanced USART features - usart.cr2.reset(); - usart.cr3.reset(); + usart.cr2().reset(); + usart.cr3().reset(); // Disable USART, there are many bits where UE=0 is required - usart.cr1.modify(|_, w| w.ue().clear_bit()); + usart.cr1().modify(|_, w| w.ue().clear_bit()); // Enable transmission and receiving - usart.cr1.write(|w| { + usart.cr1().write(|w| { w.te() .set_bit() .re() @@ -493,7 +523,7 @@ macro_rules! uart_basic { .ps() .bit(config.parity == Parity::ParityOdd) }); - usart.cr2.write(|w| unsafe { + usart.cr2().write(|w| unsafe { w.stop() .bits(match config.stopbits { StopBits::STOP1 => 0b00, @@ -509,13 +539,13 @@ macro_rules! uart_basic { .bit(config.swap) }); - usart.cr3.write(|w| w.dem().bit(PINS::DRIVER_ENABLE)); + usart.cr3().write(|w| w.dem().bit(PINS::DRIVER_ENABLE)); // Enable pins pins.setup(); // Enable USART - usart.cr1.modify(|_, w| w.ue().set_bit()); + usart.cr1().modify(|_, w| w.ue().set_bit()); Ok(Serial { tx: Tx { @@ -534,9 +564,15 @@ macro_rules! uart_basic { /// Starts listening for an interrupt event pub fn listen(&mut self, event: Event) { match event { - Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().set_bit()), - Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().set_bit()), - Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().set_bit()), + Event::Rxne => { + self.usart.cr1().modify(|_, w| w.rxneie().set_bit()); + } + Event::Txe => { + self.usart.cr1().modify(|_, w| w.txeie().set_bit()); + } + Event::Idle => { + self.usart.cr1().modify(|_, w| w.idleie().set_bit()); + } _ => {} } } @@ -544,16 +580,22 @@ macro_rules! uart_basic { /// Stop listening for an interrupt event pub fn unlisten(&mut self, event: Event) { match event { - Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().clear_bit()), - Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().clear_bit()), - Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().clear_bit()), + Event::Rxne => { + self.usart.cr1().modify(|_, w| w.rxneie().clear_bit()); + } + Event::Txe => { + self.usart.cr1().modify(|_, w| w.txeie().clear_bit()); + } + Event::Idle => { + self.usart.cr1().modify(|_, w| w.idleie().clear_bit()); + } _ => {} } } /// Check if interrupt event is pending pub fn is_pending(&mut self, event: Event) -> bool { - (self.usart.isr.read().bits() & event.val()) != 0 + (self.usart.isr().read().bits() & event.val()) != 0 } /// Clear pending interrupt @@ -561,7 +603,7 @@ macro_rules! uart_basic { // mask the allowed bits let mask: u32 = 0x123BFF; self.usart - .icr + .icr() .write(|w| unsafe { w.bits(event.val() & mask) }); } } @@ -597,30 +639,26 @@ macro_rules! uart_full { let bdr = config.baudrate.0 as u64; let clk_mul = 1; let div = (clk_mul * clk) / bdr; - usart.brr.write(|w| unsafe { w.bits(div as u32) }); + usart.brr().write(|w| unsafe { w.bits(div as u32) }); - usart.cr1.reset(); - usart.cr2.reset(); - usart.cr3.reset(); + usart.cr1().reset(); + usart.cr2().reset(); + usart.cr3().reset(); - usart.cr2.write(|w| { - w.stop() - .bits(config.stopbits.bits()) - .txinv() - .bit(config.inverted_tx) - .rxinv() - .bit(config.inverted_rx) - .swap() - .bit(config.swap) + usart.cr2().write(|w| unsafe { + w.stop().bits(config.stopbits.bits()); + w.txinv().bit(config.inverted_tx); + w.rxinv().bit(config.inverted_rx); + w.swap().bit(config.swap) }); 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| 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() @@ -633,7 +671,7 @@ macro_rules! uart_full { .bit(PINS::DRIVER_ENABLE) }); - usart.cr1.modify(|_, w| { + usart.cr1().modify(|_, w| { w.ue() .set_bit() .te() @@ -672,9 +710,15 @@ macro_rules! uart_full { /// Starts listening for an interrupt event pub fn listen(&mut self, event: Event) { match event { - Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().set_bit()), - Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().set_bit()), - Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().set_bit()), + Event::Rxne => { + self.usart.cr1().modify(|_, w| w.rxneie().set_bit()); + } + Event::Txe => { + self.usart.cr1().modify(|_, w| w.txeie().set_bit()); + } + Event::Idle => { + self.usart.cr1().modify(|_, w| w.idleie().set_bit()); + } _ => {} } } @@ -682,16 +726,22 @@ macro_rules! uart_full { /// Stop listening for an interrupt event pub fn unlisten(&mut self, event: Event) { match event { - Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().clear_bit()), - Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().clear_bit()), - Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().clear_bit()), + Event::Rxne => { + self.usart.cr1().modify(|_, w| w.rxneie().clear_bit()); + } + Event::Txe => { + self.usart.cr1().modify(|_, w| w.txeie().clear_bit()); + } + Event::Idle => { + self.usart.cr1().modify(|_, w| w.idleie().clear_bit()); + } _ => {} } } /// Check if interrupt event is pending pub fn is_pending(&mut self, event: Event) -> bool { - (self.usart.isr.read().bits() & event.val()) != 0 + (self.usart.isr().read().bits() & event.val()) != 0 } /// Clear pending interrupt @@ -699,7 +749,7 @@ macro_rules! uart_full { // mask the allowed bits let mask: u32 = 0x123BFF; self.usart - .icr + .icr() .write(|w| unsafe { w.bits(event.val() & mask) }); } } @@ -707,7 +757,7 @@ macro_rules! uart_full { /// 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() } } @@ -716,19 +766,19 @@ 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()); } /// 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() } } }; @@ -812,6 +862,7 @@ uart_shared!(USART4, USART4_RX, USART4_TX, ); #[cfg(feature = "stm32g0x1")] +#[cfg(not(any(feature = "stm32g0b1", feature = "stm32g0c1")))] uart_shared!(LPUART, LPUART_RX, LPUART_TX, tx: [ (PA2, AltFunction::AF6), @@ -847,4 +898,5 @@ uart_basic!(USART4, usart4, 1); // the basic feature set such as: Dual clock domain, FIFO or prescaler. // Or when Synchronous mode is implemented for the basic feature set, since the LP feature set does not have support. #[cfg(feature = "stm32g0x1")] +#[cfg(not(any(feature = "stm32g0b1", feature = "stm32g0c1")))] uart_basic!(LPUART, lpuart, 256); diff --git a/src/spi.rs b/src/spi.rs index 34b8c08..e60ecbc 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -2,7 +2,7 @@ use crate::gpio::*; use crate::rcc::*; use crate::stm32::{SPI1, SPI2}; use crate::time::Hertz; -use core::{cell, ptr}; +use core::ptr; pub use hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; /// SPI error @@ -148,7 +148,7 @@ macro_rules! spi { $SPIX::reset(rcc); // disable SS output - spi.cr2.write(|w| w.ssoe().clear_bit()); + spi.cr2().write(|w| w.ssoe().clear_bit()); let br = match rcc.clocks.apb_clk / speed { 0 => unreachable!(), @@ -162,55 +162,45 @@ macro_rules! spi { _ => 0b111, }; - spi.cr2.write(|w| unsafe { + spi.cr2().write(|w| unsafe { w.frxth().set_bit().ds().bits(0b111).ssoe().clear_bit() }); // Enable pins pins.setup(); - spi.cr1.write(|w| { - w.cpha() - .bit(mode.phase == Phase::CaptureOnSecondTransition) - .cpol() - .bit(mode.polarity == Polarity::IdleHigh) - .mstr() - .set_bit() - .br() - .bits(br) - .lsbfirst() - .clear_bit() - .ssm() - .set_bit() - .ssi() - .set_bit() - .rxonly() - .clear_bit() - .crcl() - .clear_bit() - .bidimode() - .clear_bit() - .spe() - .set_bit() + #[rustfmt::skip] + spi.cr1().write(|w| { + w.cpha().bit(mode.phase == Phase::CaptureOnSecondTransition); + w.cpol().bit(mode.polarity == Polarity::IdleHigh); + w.mstr().set_bit(); + w.br().set(br); + w.lsbfirst().clear_bit(); + w.ssm().set_bit(); + w.ssi().set_bit(); + w.rxonly().clear_bit(); + w.crcl().clear_bit(); + w.bidimode().clear_bit(); + w.spe().set_bit() }); Spi { spi, pins } } pub fn data_size(&mut self, nr_bits: u8) { - self.spi.cr2.modify(|_, w| unsafe { + self.spi.cr2().modify(|_, w| unsafe { w.ds().bits(nr_bits-1) }); } pub fn half_duplex_enable(&mut self, enable: bool) { - self.spi.cr1.modify(|_, w| + self.spi.cr1().modify(|_, w| w.bidimode().bit(enable) ); } pub fn half_duplex_output_enable(&mut self, enable: bool) { - self.spi.cr1.modify(|_, w| + self.spi.cr1().modify(|_, w| w.bidioe().bit(enable) ); } @@ -233,7 +223,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) @@ -245,7 +235,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 @@ -253,7 +243,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) @@ -262,9 +252,7 @@ macro_rules! spi { } else if sr.crcerr().bit_is_set() { nb::Error::Other(Error::Crc) } else if sr.txe().bit_is_set() { - unsafe { - ptr::write_volatile(cell::UnsafeCell::raw_get(&self.spi.dr as *const _ as _), byte) - } + self.spi.dr().write(|w| w.dr().set(byte.into())); return Ok(()); } else { nb::Error::WouldBlock diff --git a/src/timer/delay.rs b/src/timer/delay.rs index d5d066b..1e0b9cc 100644 --- a/src/timer/delay.rs +++ b/src/timer/delay.rs @@ -109,12 +109,12 @@ macro_rules! delays { while cycles > 0 { let reload = cmp::min(cycles, 0xffff); cycles -= reload; - self.tim.arr.write(|w| unsafe { w.bits(reload) }); - self.tim.cnt.reset(); - self.tim.cr1.modify(|_, w| w.cen().set_bit().urs().set_bit()); - while self.tim.sr.read().uif().bit_is_clear() {} - self.tim.sr.modify(|_, w| w.uif().clear_bit()); - self.tim.cr1.modify(|_, w| w.cen().clear_bit()); + self.tim.arr().write(|w| unsafe { w.bits(reload) }); + self.tim.cnt().reset(); + self.tim.cr1().modify(|_, w| w.cen().set_bit().urs().set_bit()); + while self.tim.sr().read().uif().bit_is_clear() {} + self.tim.sr().modify(|_, w| w.uif().clear_bit()); + self.tim.cr1().modify(|_, w| w.cen().clear_bit()); } } diff --git a/src/timer/mod.rs b/src/timer/mod.rs index 4b426c9..eabfb38 100644 --- a/src/timer/mod.rs +++ b/src/timer/mod.rs @@ -21,10 +21,16 @@ pub struct Timer { tim: TIM, } -pub struct Channel1; -pub struct Channel2; -pub struct Channel3; -pub struct Channel4; +pub struct Channel; + +impl Channel { + const N: usize = N; +} + +type Channel1 = Channel<0>; +type Channel2 = Channel<1>; +type Channel3 = Channel<2>; +type Channel4 = Channel<3>; /// System timer impl Timer { @@ -114,73 +120,73 @@ macro_rules! timers { /// Pauses timer pub fn pause(&mut self) { - self.tim.cr1.modify(|_, w| w.cen().clear_bit()); + self.tim.cr1().modify(|_, w| w.cen().clear_bit()); } /// Resumes timer pub fn resume(&mut self) { - self.tim.cr1.modify(|_, w| w.cen().set_bit()); + self.tim.cr1().modify(|_, w| w.cen().set_bit()); } /// Starts listening pub fn listen(&mut self) { - self.tim.dier.write(|w| w.uie().set_bit()); + self.tim.dier().write(|w| w.uie().set_bit()); } /// Stops listening pub fn unlisten(&mut self) { - self.tim.dier.write(|w| w.uie().clear_bit()); + self.tim.dier().write(|w| w.uie().clear_bit()); } /// Clears interrupt flag pub fn clear_irq(&mut self) { - self.tim.sr.modify(|_, w| w.uif().clear_bit()); + self.tim.sr().modify(|_, w| w.uif().clear_bit()); } /// Resets counter value pub fn reset(&mut self) { - self.tim.cnt.reset(); + self.tim.cnt().reset(); } /// Gets timer counter current value pub fn get_current(&self) -> u32 { let _high = 0; $( - let _high = self.tim.cnt.read().$cnt_h().bits() as u32; + let _high = self.tim.cnt().read().$cnt_h().bits() as u32; )* - let low = self.tim.cnt.read().$cnt().bits() as u32; + let low = self.tim.cnt().read().$cnt().bits() as u32; low | (_high << 16) } pub fn start(&mut self, timeout: MicroSecond) { // Pause the counter. Also set URS so that when we set UG below, it will // generate an update event *without* triggering an interrupt. - self.tim.cr1.modify(|_, w| w.cen().clear_bit().urs().set_bit()); + self.tim.cr1().modify(|_, w| w.cen().clear_bit().urs().set_bit()); // reset counter - self.tim.cnt.reset(); + self.tim.cnt().reset(); // clear interrupt flag - self.tim.sr.modify(|_, w| w.uif().clear_bit()); + self.tim.sr().modify(|_, w| w.uif().clear_bit()); // Calculate counter configuration let cycles = crate::time::cycles(timeout, self.clk); let psc = cycles / 0xffff; let arr = cycles / (psc + 1); - self.tim.psc.write(|w| w.psc().bits(psc as u16) ); - self.tim.arr.write(|w| unsafe { w.bits(arr) }); + self.tim.psc().write(|w| w.psc().set(psc as u16)); + self.tim.arr().write(|w| unsafe { w.bits(arr) }); // Generate an update event so that PSC and ARR values are copied into their // shadow registers. - self.tim.egr.write(|w| w.ug().set_bit()); + self.tim.egr().write(|w| w.ug().set_bit()); - self.tim.cr1.modify(|_, w| w.cen().set_bit()); + self.tim.cr1().modify(|_, w| w.cen().set_bit()); } pub 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(()) } } @@ -234,15 +240,15 @@ macro_rules! timers_external_clocks { self.clk = freq; match clk.mode() { ExternalClockMode::Mode1 => { - self.tim.smcr.modify(|_, w| unsafe { w.$sms().bits(0b111) }); + self.tim.smcr().modify(|_, w| unsafe { w.$sms().bits(0b111) }); $( - self.tim.smcr.modify(|_, w| w.$ece().clear_bit()); + self.tim.smcr().modify(|_, w| w.$ece().clear_bit()); )* }, ExternalClockMode::Mode2 => { - self.tim.smcr.modify(|_, w| unsafe { w.$sms().bits(0b0) }); + self.tim.smcr().modify(|_, w| unsafe { w.$sms().bits(0b0) }); $( - self.tim.smcr.modify(|_, w| w.$ece().set_bit()); + self.tim.smcr().modify(|_, w| w.$ece().set_bit()); )* }, } @@ -252,24 +258,38 @@ macro_rules! timers_external_clocks { } } +#[cfg(not(any(feature = "stm32g0b1", feature = "stm32g0c1")))] timers_external_clocks! { TIM1: (tim1, sms, ece), TIM3: (tim3, sms, ece), } +#[cfg(any(feature = "stm32g0b1", feature = "stm32g0c1"))] +timers_external_clocks! { + TIM1: (tim1, sms1, ece), + TIM2: (tim2, sms1, ece), + TIM3: (tim3, sms1, ece), +} + +#[cfg(not(any(feature = "stm32g0b1", feature = "stm32g0c1")))] #[cfg(feature = "stm32g0x1")] timers_external_clocks! { TIM2: (tim2, sms, ece), } -#[cfg(any(feature = "stm32g070", feature = "stm32g071"))] +#[cfg(any( + feature = "stm32g070", + feature = "stm32g071", + feature = "stm32g0b1", + feature = "stm32g0c1" +))] timers_external_clocks! { TIM15: (tim15, sms1), } timers! { TIM1: (tim1, cnt), - TIM3: (tim3, cnt_l, cnt_h), + TIM3: (tim3, cnt), TIM14: (tim14, cnt), TIM16: (tim16, cnt), TIM17: (tim17, cnt), @@ -277,7 +297,7 @@ timers! { #[cfg(feature = "stm32g0x1")] timers! { - TIM2: (tim2, cnt_l, cnt_h), + TIM2: (tim2, cnt), } #[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))] diff --git a/src/timer/opm.rs b/src/timer/opm.rs index ef61adf..e605fcc 100644 --- a/src/timer/opm.rs +++ b/src/timer/opm.rs @@ -66,17 +66,17 @@ macro_rules! opm { let reload = crate::time::cycles(pulse, freq); unsafe { let tim = &*$TIMX::ptr(); - tim.psc.write(|w| w.psc().bits(psc as u16)); - tim.arr.write(|w| w.$arr().bits(reload as u16)); + tim.psc().write(|w| w.psc().bits(psc as u16)); + tim.arr().write(|w| w.$arr().bits((reload as u16).into())); $( - tim.arr.modify(|_, w| w.$arr_h().bits((reload >> 16) as u16)); + tim.arr().modify(|_, w| w.$arr_h().bits((reload >> 16) as u16)); )* } } pub fn generate(&mut self) { let tim = unsafe {&*$TIMX::ptr()}; - tim.cr1.write(|w| w.opm().set_bit().cen().set_bit()); + tim.cr1().write(|w| w.opm().set_bit().cen().set_bit()); } } )+ @@ -91,17 +91,17 @@ macro_rules! opm_hal { impl OpmPin<$TIMX, $CH> { pub fn enable(&mut self) { let tim = unsafe {&*$TIMX::ptr()}; - tim.ccer.modify(|_, w| w.$ccxe().set_bit()); + tim.ccer().modify(|_, w| w.$ccxe().set_bit()); self.setup(); } pub fn disable(&mut self) { let tim = unsafe {&*$TIMX::ptr()}; - tim.ccer.modify(|_, w| w.$ccxe().clear_bit()); + tim.ccer().modify(|_, w| w.$ccxe().clear_bit()); } pub fn get_max_delay(&mut self) -> u32 { - unsafe { (*$TIMX::ptr()).arr.read().bits() } + unsafe { (*$TIMX::ptr()).arr().read().bits() } } pub fn set_delay(&mut self, delay: u32) { @@ -112,7 +112,7 @@ macro_rules! opm_hal { fn setup(&mut self) { unsafe { let tim = &*$TIMX::ptr(); - tim.$ccrx.write(|w| w.bits(self.delay)); + tim.$ccrx().write(|w| w.bits(self.delay)); tim.$ccmrx_output().modify(|_, w| w.$ocxm().bits(7).$ocxfe().set_bit()); } } @@ -145,7 +145,7 @@ opm_hal! { opm! { TIM1: (tim1, arr), - TIM3: (tim3, arr_l, arr_h), + TIM3: (tim3, arr), TIM14: (tim14, arr), TIM16: (tim16, arr), TIM17: (tim17, arr), @@ -153,7 +153,7 @@ opm! { #[cfg(feature = "stm32g0x1")] opm! { - TIM2: (tim2, arr_l, arr_h), + TIM2: (tim2, arr), } #[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))] diff --git a/src/timer/pins.rs b/src/timer/pins.rs index 339e7d5..5936a23 100644 --- a/src/timer/pins.rs +++ b/src/timer/pins.rs @@ -68,16 +68,19 @@ macro_rules! trigger_pins { let ts = match edge { SignalEdge::All => 0b100, SignalEdge::Falling => { - tim.ccer.modify(|_, w| w.$ccp().set_bit()); + tim.ccer().modify(|_, w| w.$ccp().set_bit()); 0b101 }, SignalEdge::Rising => { - tim.ccer.modify(|_, w| w.$ccp().clear_bit()); + tim.ccer().modify(|_, w| w.$ccp().clear_bit()); 0b101 } }; - tim.smcr.modify(|_, w| unsafe { w.ts().bits(ts) }); + #[cfg(not(any(feature = "stm32g0b1", feature = "stm32g0c1")))] + tim.smcr().modify(|_, w| unsafe { w.ts().bits(ts) }); + #[cfg(any(feature = "stm32g0b1", feature = "stm32g0c1"))] + tim.smcr().modify(|_, w| unsafe { w.ts1().bits(ts) }); Self { pin, diff --git a/src/timer/pwm.rs b/src/timer/pwm.rs index facc4e4..873a2d3 100644 --- a/src/timer/pwm.rs +++ b/src/timer/pwm.rs @@ -82,11 +82,11 @@ macro_rules! pwm { let clk = match clock_source { ClockSource::ApbTim => { - rcc.ccipr.modify(|_, w| w.tim1sel().clear_bit()); + rcc.ccipr().modify(|_, w| w.tim1sel().clear_bit()); rcc.clocks.apb_tim_clk } ClockSource::Pllq => { - rcc.ccipr.modify(|_, w| w.tim1sel().set_bit()); + rcc.ccipr().modify(|_, w| w.tim1sel().set_bit()); rcc.clocks.pll_clk.q.unwrap() } }; @@ -109,38 +109,38 @@ macro_rules! pwm { let arr = ratio / (psc + 1) - 1; unsafe { - self.tim.psc.write(|w| w.psc().bits(psc as u16)); - self.tim.arr.write(|w| w.$arr().bits(arr as u16)); + self.tim.psc().write(|w| w.psc().bits(psc as u16)); + self.tim.arr().write(|w| w.$arr().bits((arr as u16).into())); $( - self.tim.arr.modify(|_, w| w.$arr_h().bits((arr >> 16) as u16)); + self.tim.arr().modify(|_, w| w.$arr_h().bits((arr >> 16) as u16)); )* - self.tim.cr1.write(|w| w.cen().set_bit()) + self.tim.cr1().write(|w| w.cen().set_bit()); } } /// Starts listening pub fn listen(&mut self) { - self.tim.dier.write(|w| w.uie().set_bit()); + self.tim.dier().write(|w| w.uie().set_bit()); } /// Stops listening pub fn unlisten(&mut self) { - self.tim.dier.write(|w| w.uie().clear_bit()); + self.tim.dier().write(|w| w.uie().clear_bit()); } /// Clears interrupt flag pub fn clear_irq(&mut self) { - self.tim.sr.modify(|_, w| w.uif().clear_bit()); + self.tim.sr().modify(|_, w| w.uif().clear_bit()); } /// Resets counter value pub fn reset(&mut self) { - self.tim.cnt.reset(); + self.tim.cnt().reset(); } /// Returns the currently configured frequency pub fn freq(&self) -> Hertz { Hertz::from_raw(self.clk.raw() - / (self.tim.psc.read().bits() + 1) - / (self.tim.arr.read().bits() + 1)) + / (self.tim.psc().read().bits() + 1) + / (self.tim.arr().read().bits() + 1)) } } )+ @@ -171,7 +171,7 @@ macro_rules! pwm_hal { fn disable(&mut self) { unsafe { - (*$TIMX::ptr()).ccer.modify(|_, w| w.$ccxe().clear_bit()); + (*$TIMX::ptr()).ccer().modify(|_, w| w.$ccxe().clear_bit()); } } @@ -179,20 +179,20 @@ macro_rules! pwm_hal { unsafe { let tim = &*$TIMX::ptr(); tim.$ccmrx_output().modify(|_, w| w.$ocxpe().set_bit().$ocxm().bits(6)); - tim.ccer.modify(|_, w| w.$ccxe().set_bit()); + tim.ccer().modify(|_, w| w.$ccxe().set_bit()); } } fn get_duty(&self) -> u32 { - unsafe { (*$TIMX::ptr()).$ccrx.read().bits() } + unsafe { (*$TIMX::ptr()).$ccrx().read().bits() } } fn get_max_duty(&self) -> u32 { - unsafe { (*$TIMX::ptr()).arr.read().bits() } + unsafe { (*$TIMX::ptr()).arr().read().bits() } } fn set_duty(&mut self, duty: u32) { - unsafe { (*$TIMX::ptr()).$ccrx.write(|w| w.bits(duty)) } + unsafe { (*$TIMX::ptr()).$ccrx().write(|w| w.bits(duty)); } } } )+ @@ -216,7 +216,7 @@ macro_rules! pwm_advanced_hal { fn disable(&mut self) { unsafe { - (*$TIMX::ptr()).ccer.modify(|_, w| w.$ccxe().clear_bit()); + (*$TIMX::ptr()).ccer().modify(|_, w| w.$ccxe().clear_bit()); } } @@ -224,26 +224,26 @@ macro_rules! pwm_advanced_hal { unsafe { let tim = &*$TIMX::ptr(); tim.$ccmrx_output().modify(|_, w| w.$ocxpe().set_bit().$ocxm().bits(6)); - tim.ccer.modify(|_, w| w.$ccxe().set_bit()); + tim.ccer().modify(|_, w| w.$ccxe().set_bit()); $( - tim.ccer.modify(|_, w| w.$ccxne().bit(true)); + tim.ccer().modify(|_, w| w.$ccxne().bit(true)); )* $( - tim.bdtr.modify(|_, w| w.$moe().set_bit()); + tim.bdtr().modify(|_, w| w.$moe().set_bit()); )* } } fn get_duty(&self) -> u16 { - unsafe { (*$TIMX::ptr()).$ccrx.read().$ccrx().bits() } + unsafe { (*$TIMX::ptr()).$ccrx(<$CH>::N).read().$ccrx().bits() } } fn get_max_duty(&self) -> u16 { - unsafe { (*$TIMX::ptr()).arr.read().arr().bits() } + unsafe { (*$TIMX::ptr()).arr().read().arr().bits() } } fn set_duty(&mut self, duty: u16) { - unsafe { (*$TIMX::ptr()).$ccrx.write(|w| w.$ccrx().bits(duty)) } + unsafe { (*$TIMX::ptr()).$ccrx(<$CH>::N).write(|w| w.$ccrx().bits(duty)); } } } @@ -260,18 +260,18 @@ macro_rules! pwm_advanced_hal { } pwm_advanced_hal! { - TIM1: (Channel1, cc1e: cc1ne, ccmr1_output, oc1pe, oc1m, ccr1, moe), - TIM1: (Channel2, cc2e: cc2ne, ccmr1_output, oc2pe, oc2m, ccr2, moe), - TIM1: (Channel3, cc3e: cc3ne, ccmr2_output, oc3pe, oc3m, ccr3, moe), - TIM1: (Channel4, cc4e, ccmr2_output, oc4pe, oc4m, ccr4, moe), - TIM14: (Channel1, cc1e, ccmr1_output, oc1pe, oc1m, ccr1), - TIM16: (Channel1, cc1e: cc1ne, ccmr1_output, oc1pe, oc1m, ccr1, moe), - TIM17: (Channel1, cc1e: cc1ne, ccmr1_output, oc1pe, oc1m, ccr1, moe), + TIM1: (Channel1, cc1e: cc1ne, ccmr1_output, oc1pe, oc1m, ccr, moe), + TIM1: (Channel2, cc2e: cc2ne, ccmr1_output, oc2pe, oc2m, ccr, moe), + TIM1: (Channel3, cc3e: cc3ne, ccmr2_output, oc3pe, oc3m, ccr, moe), + TIM1: (Channel4, cc4e, ccmr2_output, oc4pe, oc4m, ccr, moe), + TIM14: (Channel1, cc1e, ccmr1_output, oc1pe, oc1m, ccr), + TIM16: (Channel1, cc1e: cc1ne, ccmr1_output, oc1pe, oc1m, ccr, moe), + TIM17: (Channel1, cc1e: cc1ne, ccmr1_output, oc1pe, oc1m, ccr, moe), } #[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))] pwm_advanced_hal! { - TIM15: (Channel1, cc1e: cc1ne, ccmr1_output, oc1pe, oc1m, ccr1, moe), + TIM15: (Channel1, cc1e: cc1ne, ccmr1_output, oc1pe, oc1m, ccr, moe), } #[cfg(feature = "stm32g0x1")] @@ -296,7 +296,7 @@ pwm_hal! { pwm! { TIM1: (tim1, arr), - TIM3: (tim3, arr_l, arr_h), + TIM3: (tim3, arr), TIM14: (tim14, arr), TIM16: (tim16, arr), TIM17: (tim17, arr), @@ -304,7 +304,7 @@ pwm! { #[cfg(feature = "stm32g0x1")] pwm! { - TIM2: (tim2, arr_l, arr_h), + TIM2: (tim2, arr), } #[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))] diff --git a/src/timer/qei.rs b/src/timer/qei.rs index a78d22f..d5531d9 100644 --- a/src/timer/qei.rs +++ b/src/timer/qei.rs @@ -57,10 +57,13 @@ macro_rules! qei { }); // Encoder mode 2. - tim.smcr.write(|w| unsafe { w.sms().bits(0b010) }); + #[cfg(not(any(feature = "stm32g0b1", feature = "stm32g0c1")))] + tim.smcr().write(|w| unsafe { w.sms().bits(0b010) }); + #[cfg(any(feature = "stm32g0b1", feature = "stm32g0c1"))] + tim.smcr().write(|w| unsafe { w.sms1().bits(0b010) }); // Enable and configure to capture on rising edge - tim.ccer.write(|w| { + tim.ccer().write(|w| { w.cc1e() .set_bit() .cc2e() @@ -77,7 +80,7 @@ macro_rules! qei { pins.setup(); - tim.cr1.write(|w| w.cen().set_bit()); + tim.cr1().write(|w| w.cen().set_bit()); Qei { tim, pins } } @@ -90,11 +93,13 @@ macro_rules! qei { type Count = u16; fn count(&self) -> u16 { - self.tim.cnt.read().$cnt().bits() + // TODO: this impl should change to u32 for counters that + // have > 16 bits of resolution. + self.tim.cnt().read().$cnt().bits() as u16 } fn direction(&self) -> Direction { - if self.tim.cr1.read().dir().bit_is_clear() { + if self.tim.cr1().read().dir().bit_is_clear() { hal::Direction::Upcounting } else { hal::Direction::Downcounting @@ -113,10 +118,10 @@ macro_rules! qei { qei! { TIM1: (tim1, arr, cnt), - TIM3: (tim3, arr_l, cnt_l), + TIM3: (tim3, arr_l, cnt), } #[cfg(feature = "stm32g0x1")] qei! { - TIM2: (tim2, arr_l, cnt_l), + TIM2: (tim2, arr_l, cnt), // TODO: missing high value register? } diff --git a/src/timer/stopwatch.rs b/src/timer/stopwatch.rs index c650984..c1a4a75 100644 --- a/src/timer/stopwatch.rs +++ b/src/timer/stopwatch.rs @@ -20,7 +20,7 @@ macro_rules! stopwatches { $TIM::enable(rcc); $TIM::reset(rcc); - tim.cr1.modify(|_, w| w.cen().set_bit()); + tim.cr1().modify(|_, w| w.cen().set_bit()); Stopwatch { tim, clk: rcc.clocks.apb_tim_clk, @@ -40,20 +40,20 @@ macro_rules! stopwatches { /// /// The counter frequency is equal to the input clock divided by the prescaler + 1. pub fn set_prescaler(&mut self, prescaler: u16) { - self.tim.psc.write(|w| w.psc().bits(prescaler) ); - self.tim.egr.write(|w| w.ug().set_bit()); + self.tim.psc().write(|w| w.psc().set(prescaler)); + self.tim.egr().write(|w| w.ug().set_bit()); } pub fn reset(&mut self) { - self.tim.cnt.reset(); + self.tim.cnt().reset(); } pub fn pause(&mut self) { - self.tim.cr1.modify(|_, w| w.cen().clear_bit()); + self.tim.cr1().modify(|_, w| w.cen().clear_bit()); } pub fn resume(&mut self) { - self.tim.cr1.modify(|_, w| w.cen().set_bit()); + self.tim.cr1().modify(|_, w| w.cen().set_bit()); } pub fn release(self) -> $TIM { @@ -61,13 +61,13 @@ macro_rules! stopwatches { } pub fn now(&self) -> Instant { - Instant::from_ticks(self.tim.cnt.read().bits()) + Instant::from_ticks(self.tim.cnt().read().bits()) } pub fn elapsed(&self, ts: Instant) -> MicroSecond { let now = self.now().ticks(); let cycles = (now as $depth).wrapping_sub(ts.ticks() as $depth) as u32; - duration(self.clk, cycles * (1 + self.tim.psc.read().bits())) + duration(self.clk, cycles * (1 + self.tim.psc().read().bits())) } pub fn trace(&self, mut closure: F) -> MicroSecond @@ -77,7 +77,7 @@ macro_rules! stopwatches { let started = self.now().ticks(); closure(); let now = self.now().ticks(); - duration(self.clk, now.wrapping_sub(started) * (1 + self.tim.psc.read().bits())) + duration(self.clk, now.wrapping_sub(started) * (1 + self.tim.psc().read().bits())) } } diff --git a/src/watchdog.rs b/src/watchdog.rs index a1999b2..dcee850 100644 --- a/src/watchdog.rs +++ b/src/watchdog.rs @@ -10,7 +10,7 @@ pub struct IndependedWatchdog { impl IndependedWatchdog { pub fn feed(&mut self) { - self.iwdg.kr.write(|w| unsafe { w.key().bits(0xaaaa) }); + self.iwdg.kr().write(|w| unsafe { w.key().bits(0xaaaa) }); } pub fn start(&mut self, period: MicroSecond) { @@ -27,17 +27,17 @@ impl IndependedWatchdog { } // Enable watchdog - self.iwdg.kr.write(|w| unsafe { w.key().bits(0xcccc) }); + self.iwdg.kr().write(|w| unsafe { w.key().bits(0xcccc) }); // Enable access to RLR/PR - self.iwdg.kr.write(|w| unsafe { w.key().bits(0x5555) }); + self.iwdg.kr().write(|w| unsafe { w.key().bits(0x5555) }); - self.iwdg.pr.write(|w| w.pr().bits(psc)); - self.iwdg.rlr.write(|w| w.rl().bits(reload as u16)); + self.iwdg.pr().write(|w| unsafe { w.pr().bits(psc) }); + self.iwdg.rlr().write(|w| w.rl().set(reload as u16)); - while self.iwdg.sr.read().bits() > 0 {} + while self.iwdg.sr().read().bits() > 0 {} - self.iwdg.kr.write(|w| unsafe { w.key().bits(0xaaaa) }); + self.iwdg.kr().write(|w| unsafe { w.key().bits(0xaaaa) }); } } @@ -81,7 +81,7 @@ pub struct WindowWatchdog { impl WindowWatchdog { pub fn feed(&mut self) { - self.wwdg.cr.write(|w| w.t().bits(0xff)); + self.wwdg.cr().write(|w| w.t().set(0xff)); } pub fn set_window(&mut self, window: MicroSecond) { @@ -97,17 +97,19 @@ impl WindowWatchdog { cycles /= 2; } assert!(window <= 0x40); - self.wwdg - .cfr - .write(|w| w.wdgtb().bits(psc).w().bits(window as u8)); + + self.wwdg.cfr().write(|w| { + w.wdgtb().set(psc); + w.w().set(window as u8) + }); } pub fn listen(&mut self) { - self.wwdg.cfr.write(|w| w.ewi().set_bit()); + self.wwdg.cfr().write(|w| w.ewi().set_bit()); } pub fn unlisten(&mut self) { - self.wwdg.cfr.write(|w| w.ewi().clear_bit()); + self.wwdg.cfr().write(|w| w.ewi().clear_bit()); } pub fn release(self) -> WWDG { @@ -117,7 +119,7 @@ impl WindowWatchdog { pub fn start(&mut self, period: MicroSecond) { self.set_window(period); self.feed(); - self.wwdg.cr.write(|w| w.wdga().set_bit()); + self.wwdg.cr().write(|w| w.wdga().set_bit()); } }