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/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index 70e7338..8a741e3 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -18,6 +18,7 @@ jobs: - stm32g070 - stm32g071 - stm32g081 + - stm32g0b1 steps: - uses: actions/checkout@v1 - run: rustup component add clippy 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 3e87d31..32ebe0b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,8 +23,8 @@ embedded-hal = "1.0.0" bare-metal = "1.0.0" [dependencies.stm32g0] -version = "0.15.1" -features = ["rt"] +package = "stm32g0-staging" +version = "0.16.0" [dependencies.void] default-features = false @@ -48,6 +48,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/examples/adc_ext_trig_double_dma_serial.rs b/examples/adc_ext_trig_double_dma_serial.rs deleted file mode 100644 index dd618a2..0000000 --- a/examples/adc_ext_trig_double_dma_serial.rs +++ /dev/null @@ -1,200 +0,0 @@ -// has been tested on nucleo-32 with STM32G031 -// command build: cargo build --example adc_ext_trig_double_dma_serial --features stm32g031 -// command run: cargo run --example adc_ext_trig_double_dma_serial --features stm32g031 - -#![no_main] -#![no_std] - -extern crate cortex_m; -extern crate cortex_m_rt as rt; -use cortex_m_semihosting::hprintln; - -extern crate nb; -extern crate panic_halt; -extern crate stm32g0; -extern crate stm32g0xx_hal as hal; - -use hal::analog::adc; -use hal::prelude::*; -use hal::serial::*; -use hal::stm32; -use rt::entry; - -use core::cell::RefCell; -use cortex_m::interrupt::Mutex; - -use crate::hal::analog::adc::DmaMode; -use crate::hal::analog::adc::InjectMode; -use crate::hal::stm32::{interrupt, Interrupt}; -use hal::analog::adc::{InjTrigSource, Precision, SampleTime}; //, VTemp -use hal::dma::{self, Channel, Target}; - -// Make dma globally available -static G_DMA: Mutex>> = Mutex::new(RefCell::new(None)); - -const BUFFER_SIZE: u16 = 4; -// Make the buffer pointer globally available -static G_DMA_BUFFER_ADDR: Mutex>> = Mutex::new(RefCell::new(None)); - -#[interrupt] -unsafe fn DMA_CHANNEL1() { - static mut DMA: Option = None; - static mut DMA_BUFFER_ADDR: Option = None; - - let dma_ch = DMA.get_or_insert_with(|| { - cortex_m::interrupt::free(|cs| { - // Move dma here, leaving a None in its place - G_DMA.borrow(cs).replace(None).unwrap() - }) - }); - - let dma_buf_addr = DMA_BUFFER_ADDR.get_or_insert_with(|| { - cortex_m::interrupt::free(|cs| { - // Move dma buffer pointer here, leaving a None in its place - G_DMA_BUFFER_ADDR.borrow(cs).replace(None).unwrap() - }) - }); - - let tx_dma_buf_first_addr: u32 = *dma_buf_addr; - let tx_dma_buf_second_addr: u32 = *dma_buf_addr + (BUFFER_SIZE) as u32; - // Address is in byte, value in 2Bytes, this is why second dma buffer ist added with BUFFER_SIZE - // and not BUFFER_SIZE/2 - - let dma = &(*hal::stm32::DMA::ptr()); - let htif1 = dma.isr.read().htif1().bit(); - let tcif1 = dma.isr.read().tcif1().bit(); - // set the global clear bit of DMA channel1 - dma.ifcr.write(|w| w.cgif1().set_bit()); - - dma_ch.ch2.disable(); - dma_ch.ch2.set_transfer_length(BUFFER_SIZE as u16); - if htif1 == true { - dma_ch.ch2.set_memory_address(tx_dma_buf_first_addr, true); - dma_ch.ch2.enable(); - // hprintln!("DMA_CHANNEL1 half transfer compleated {:?} {:?}", htif1, tx_dma_buf_first_addr).unwrap(); - } else if tcif1 == true { - dma_ch.ch2.set_memory_address(tx_dma_buf_second_addr, true); - dma_ch.ch2.enable(); - // hprintln!("DMA_CHANNEL1 transfer compleated {:?} {:?}", tcif1, tx_dma_buf_second_addr).unwrap(); - } -} - -#[entry] -fn main() -> ! { - let dp = stm32::Peripherals::take().expect("cannot take peripherals"); - let mut rcc = dp.RCC.constrain(); - - let gpioa = dp.GPIOA.split(&mut rcc); - - let mut timer = dp.TIM2.timer(&mut rcc); - - let usart1 = dp - .USART1 - .usart( - // TX: pa9, => CN3 Pin-D5 - // RX: pa10, => CN3 Pin-D4 - (gpioa.pa9, gpioa.pa10), - FullConfig::default().baudrate(460800.bps()).fifo_enable(), // enable fifo, so that dma can fill it fast, otherwise it may not finish before ch1 is requested again - &mut rcc, - ) - .unwrap(); - - // DMA example - //================================================== - let adc_buffer1: [u16; BUFFER_SIZE as usize] = [0; BUFFER_SIZE as usize]; - - let mut dma = dp.DMA.split(&mut rcc, dp.DMAMUX); - - let adc_ptr = unsafe { &(*hal::stm32::ADC::ptr()) }; - let adc_data_register_addr = &adc_ptr.dr as *const _ as u32; - - let adc_buffer1_addr: u32 = adc_buffer1.as_ptr() as u32; - - dma.ch1.set_word_size(dma::WordSize::BITS16); - dma.ch1.set_direction(dma::Direction::FromPeripheral); - dma.ch1.set_memory_address(adc_buffer1_addr, true); - dma.ch1 - .set_peripheral_address(adc_data_register_addr, false); - dma.ch1.set_transfer_length(adc_buffer1.len() as u16); - - hprintln!("adc_data_register_addr {:?}", adc_buffer1_addr); // will output addr in dec - // in gdb read the data bytes with: x /32xh 0x??????? (last is addr in hex) - // or put addr in dec format: x /32xh 536878092 - // https://sourceware.org/gdb/current/onlinedocs/gdb/Memory.html - - // dma ch1 reads from ADC register into memory - dma.ch1.select_peripheral(hal::dmamux::DmaMuxIndex::ADC); - // The dma continuesly fills the buffer, when its full, it starts over again - dma.ch1.set_circular_mode(true); - - // Enabel dma irq for half and full buffer, when reached, so that the second dma ch2 can be started - dma.ch1.listen(hal::dma::Event::HalfTransfer); - dma.ch1.listen(hal::dma::Event::TransferComplete); - - let (mut tx, mut _rx) = usart1.split(); - - let usart = unsafe { &(*stm32::USART1::ptr()) }; - let tx_data_register_addr = &usart.tdr as *const _ as u32; - - dma.ch2.set_direction(dma::Direction::FromMemory); - dma.ch2.set_peripheral_address(tx_data_register_addr, false); - dma.ch2.set_word_size(hal::dma::WordSize::BITS8); - - dma.ch2.select_peripheral(tx.dmamux()); - - tx.enable_dma(); - - // start dma transfer - dma.ch1.enable(); - - cortex_m::interrupt::free(|cs| *G_DMA.borrow(cs).borrow_mut() = Some(dma)); - cortex_m::interrupt::free(|cs| { - *G_DMA_BUFFER_ADDR.borrow(cs).borrow_mut() = Some(adc_buffer1_addr) - }); - - //================================================== - // Set up adc - - let mut adc = dp.ADC.constrain(&mut rcc); - adc.set_sample_time(SampleTime::T_80); - adc.set_precision(Precision::B_12); - let mut pa3 = gpioa.pa5.into_analog(); - let u_raw = adc.read(&mut pa3).expect("adc read failed"); - let u = u_raw.saturating_sub(32) as f32 / 4_096_f32 * 3.3; - hprintln!("u: {:.4} V ", u); - - adc.set_oversampling_ratio(adc::OversamplingRatio::X_16); - adc.set_oversampling_shift(4); - adc.oversampling_enable(true); - adc.prepare_injected(&mut pa3, InjTrigSource::TRG_2); - adc.start_injected(); - - // Enable timer to trigger external sources in mms value of cr2 - // 011: Compare Pulse - The trigger output send a positive pulse when the CC1IF flag is to be - // set (even if it was already high), as soon as a capture or a compare match occurred. - // ouput is (TRGO) - // according to reference manual chapter 22.4.2 - // this is only available on timer TIM2, TIM3, TIM4 and TIM1 - unsafe { - // get pointer of timer 2 - let tim = &(*hal::stm32::TIM2::ptr()); - // - tim.cr2.modify(|_, w| w.mms().bits(3 as u8)); - } - - // enable dma to be called, when adc is ready to read - adc.dma_enable(true); - adc.dma_circualr_mode(true); - - // don't enabel the timer bevor the dma - // Set up a timer expiring after - timer.start(50.micros()); - timer.listen(); - - //enable DMA_CHANNEL1 interrupt - unsafe { - cortex_m::peripheral::NVIC::unmask(Interrupt::DMA_CHANNEL1); - } - - loop {} -} diff --git a/examples/uart_dma.rs b/examples/uart_dma.rs deleted file mode 100644 index 99c8622..0000000 --- a/examples/uart_dma.rs +++ /dev/null @@ -1,89 +0,0 @@ -#![no_main] -#![no_std] - -extern crate cortex_m_rt as rt; -extern crate panic_halt; -extern crate stm32g0xx_hal as hal; - -use core::fmt::Write; - -use hal::dma::{self, Channel, Event, Target}; -use hal::prelude::*; -use hal::serial::*; -use hal::stm32; - -use rt::entry; - -#[entry] -fn main() -> ! { - let dp = stm32::Peripherals::take().expect("cannot take peripherals"); - let mut rcc = dp.RCC.constrain(); - let gpioa = dp.GPIOA.split(&mut rcc); - - let mut led = gpioa.pa5.into_push_pull_output(); - - let mut usart1 = dp - .USART1 - .usart( - (gpioa.pa9, gpioa.pa10), - FullConfig::default().baudrate(115200.bps()), - &mut rcc, - ) - .unwrap(); - - writeln!(usart1, "Hello without DMA\r\n").unwrap(); - - let tx_buffer: [u8; 16] = *b"Hello with DMA!\n"; - - let (mut tx, _rx) = usart1.split(); - - let mut dma = dp.DMA.split(&mut rcc, dp.DMAMUX); - - // Setup DMA for USART1 TX with dma channel 1. - let usart = unsafe { &(*stm32::USART1::ptr()) }; - let tx_data_register_addr = &usart.tdr as *const _ as u32; - let tx_dma_buf_addr: u32 = tx_buffer.as_ptr() as u32; - - dma.ch1.set_direction(dma::Direction::FromMemory); - dma.ch1.set_memory_address(tx_dma_buf_addr, true); - dma.ch1.set_peripheral_address(tx_data_register_addr, false); - dma.ch1.set_transfer_length(tx_buffer.len() as u16); - - // Configure dmamux for dma ch1 and usart tx - dma.ch1.select_peripheral(tx.dmamux()); - - dma.ch1.listen(Event::TransferComplete); - - tx.enable_dma(); - dma.ch1.enable(); - - // Create a second buffer to send after the first dma transfer has completed - let mut tx_buffer2: [u8; 23] = *b"Transfer complete {0}!\n"; - let tx_dma_buf_addr: u32 = tx_buffer2.as_ptr() as u32; - - let mut delay = dp.TIM1.delay(&mut rcc); - - loop { - if dma.ch1.event_occurred(Event::TransferComplete) { - dma.ch1.clear_event(Event::TransferComplete); - - // update the char between '{ }' in tx_buffer2 - tx_buffer2[19] += 1; - - // wrap around to ascii value 33 == '!', so that we only use printable characters. - if tx_buffer2[19] > 126 { - tx_buffer2[19] = 33; - } - - dma.ch1.disable(); - - led.toggle().unwrap(); - - dma.ch1.set_memory_address(tx_dma_buf_addr, true); - dma.ch1.set_transfer_length(tx_buffer2.len() as u16); - dma.ch1.enable(); - } - - delay.delay(500.millis()); - } -} diff --git a/src/analog/adc.rs b/src/analog/adc.rs index b784203..779d6f3 100644 --- a/src/analog/adc.rs +++ b/src/analog/adc.rs @@ -124,7 +124,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, @@ -138,11 +138,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) }); } } @@ -155,8 +157,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 @@ -169,7 +171,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 @@ -178,7 +180,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 @@ -199,24 +201,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) { @@ -224,7 +226,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 @@ -283,7 +285,7 @@ impl Adc { _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() @@ -291,18 +293,18 @@ impl Adc { }); 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 { @@ -342,15 +344,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() {} } } @@ -379,10 +381,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) @@ -392,12 +394,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()) }); } } @@ -413,17 +415,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 } } } @@ -439,15 +441,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..4e34ad4 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 da5094a..ca45e2d 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: DelayNs, { 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) }); - delay.delay_us(64_000_u32); - if dac.sr.read().$cal_flag().bit() { + dac.ccr().modify(|_, w| unsafe { w.$trim().bits(trim) }); + delay.delay_us(64_u32); + 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 fe7a10f..ce143b8 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. @@ -161,20 +163,17 @@ pub trait Channel: private::Channel { /// Panics if this channel is enabled. fn set_transfer_length(&mut self, len: u16) { assert!(!self.is_enabled()); - #[cfg(not(any(feature = "stm32g070")))] - self.ch().ndtr.write(|w| w.ndt().bits(len)); - #[cfg(feature = "stm32g070")] - 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) }); @@ -183,84 +182,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(); - #[cfg(not(any(feature = "stm32g070")))] - self.ch().cr.modify(|_, w| w.pl().bits(pl)); - #[cfg(feature = "stm32g070")] - 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() } } 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; /// DMA channels @@ -280,13 +273,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) } } } @@ -306,12 +299,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(), } } @@ -320,11 +313,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(), }); } } @@ -334,27 +327,33 @@ macro_rules! dma { } } -#[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))] +#[cfg(any( + feature = "stm32g070", + feature = "stm32g071", + feature = "stm32g081", + feature = "stm32g0b1", + feature = "stm32g0c1", +))] 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), + 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), }, ); @@ -388,11 +387,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..6fae9b4 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); @@ -107,20 +113,21 @@ impl ExtiExt for EXTI { feature = "stm32g030", feature = "stm32g070", feature = "stm32g031", - feature = "stm32g041" + feature = "stm32g041", + feature = "stm32g0b1" ))] - 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 +142,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 +156,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 +180,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 +191,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 9f4664e..aca84bd 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -64,22 +64,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 { impl OutputPin for $PXx> { 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(&mut 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) } } @@ -260,7 +264,7 @@ macro_rules! gpio { fn is_low(&mut 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) } } @@ -277,7 +281,7 @@ macro_rules! gpio { fn is_low(&mut 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) } } @@ -328,10 +332,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)) }) }; @@ -343,10 +347,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)) }) }; @@ -358,10 +362,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)) }) }; @@ -373,10 +377,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)) }); } @@ -396,13 +400,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)) }) }; @@ -422,13 +426,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)) }) }; @@ -439,10 +443,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)) }); }; @@ -450,20 +454,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 } } @@ -472,7 +476,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)) }); }; @@ -487,16 +491,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)) }); } @@ -506,11 +510,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))) }; } } } @@ -550,7 +554,7 @@ macro_rules! gpio { fn is_set_low(&mut 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) } } @@ -563,7 +567,7 @@ macro_rules! gpio { fn is_low(&mut 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) } } @@ -590,7 +594,7 @@ macro_rules! gpio { fn is_low(&mut 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) } } @@ -711,6 +715,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 81db20a..ecc45a1 100644 --- a/src/i2c/blocking.rs +++ b/src/i2c/blocking.rs @@ -35,22 +35,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(); }; }; } @@ -61,25 +61,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. @@ -92,7 +93,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 @@ -168,40 +169,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 @@ -213,21 +211,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()); + } _ => {}, } } @@ -252,30 +252,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) @@ -283,7 +282,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. @@ -291,29 +290,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; } } @@ -327,22 +325,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 { @@ -351,7 +348,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; } } @@ -366,33 +363,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; } } @@ -402,12 +398,12 @@ macro_rules! i2c { impl I2cSlave for I2c<$I2CX, SDA, SCL> { 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 @@ -439,14 +435,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 { @@ -455,13 +451,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)); } } } @@ -472,15 +468,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); @@ -492,7 +487,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 027380d..cbb6d46 100644 --- a/src/rng.rs +++ b/src/rng.rs @@ -63,11 +63,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 } } } @@ -85,9 +85,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 304b745..4d6af7f 100644 --- a/src/serial/usart.rs +++ b/src/serial/usart.rs @@ -227,65 +227,85 @@ 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()); } } impl Rx<$USARTX, Config> { pub 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 } @@ -303,19 +323,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 } } @@ -323,7 +347,7 @@ macro_rules! uart_shared { impl Tx<$USARTX, Config> { pub fn flush(&mut self) -> nb::Result<(), nb::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) @@ -332,8 +356,14 @@ macro_rules! uart_shared { pub fn write(&mut self, byte: u8) -> nb::Result<(), nb::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) @@ -368,7 +398,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()); }); } @@ -376,7 +406,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()); }); } @@ -390,7 +420,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()); }); } @@ -398,7 +428,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()); }); } @@ -434,16 +464,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() @@ -457,8 +487,8 @@ macro_rules! uart_basic { .ps() .bit(config.parity == Parity::ParityOdd) }); - #[allow(unused_unsafe)] - usart.cr2.write(|w| unsafe { + + usart.cr2().write(|w| unsafe { w.stop() .bits(match config.stopbits { StopBits::STOP1 => 0b00, @@ -474,13 +504,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 { @@ -499,9 +529,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()); + } _ => {} } } @@ -509,16 +545,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 @@ -526,7 +568,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) }); } } @@ -576,30 +618,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() @@ -612,7 +650,7 @@ macro_rules! uart_full { .bit(PINS::DRIVER_ENABLE) }); - usart.cr1.modify(|_, w| { + usart.cr1().modify(|_, w| { w.ue() .set_bit() .te() @@ -651,9 +689,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()); + } _ => {} } } @@ -661,16 +705,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 @@ -678,7 +728,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) }); } } @@ -687,7 +737,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() } } @@ -696,19 +746,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() } } @@ -806,6 +856,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), @@ -828,7 +879,12 @@ uart_full!(USART1, usart1, 1); #[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))] uart_full!(USART2, usart2, 1); -#[cfg(any(feature = "stm32g030", feature = "stm32g031", feature = "stm32g041"))] +#[cfg(any( + feature = "stm32g030", + feature = "stm32g031", + feature = "stm32g041", + feature = "stm32g0b1" +))] uart_basic!(USART2, usart2, 1); #[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))] @@ -841,4 +897,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 3959e19..5565c45 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -2,8 +2,10 @@ use crate::gpio::*; use crate::rcc::*; use crate::stm32::{SPI1, SPI2}; use crate::time::Hertz; -use core::{cell, ptr}; -pub use hal::spi::*; +use core::ptr; +pub use hal::spi::{ + ErrorKind, ErrorType, Mode, Phase, Polarity, SpiBus, MODE_0, MODE_1, MODE_2, MODE_3, +}; use nb::block; /// SPI error @@ -159,7 +161,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!(), @@ -173,55 +175,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) ); } @@ -242,7 +234,7 @@ macro_rules! spi { impl Spi<$SPIX, PINS> { pub 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) @@ -254,7 +246,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 @@ -262,8 +254,7 @@ macro_rules! spi { } pub 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) } else if sr.modf().bit_is_set() { @@ -271,9 +262,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 f34877c..fe605da 100644 --- a/src/timer/delay.rs +++ b/src/timer/delay.rs @@ -79,12 +79,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 0030ff0..b3f4233 100644 --- a/src/timer/mod.rs +++ b/src/timer/mod.rs @@ -20,10 +20,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 { @@ -96,73 +102,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(()) } } @@ -199,15 +205,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()); )* }, } @@ -217,24 +223,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), @@ -242,7 +262,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 55d0853..0145a16 100644 --- a/src/timer/pwm.rs +++ b/src/timer/pwm.rs @@ -83,11 +83,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() } }; @@ -107,40 +107,41 @@ macro_rules! pwm { pub fn set_freq(&mut self, freq: Hertz) { let ratio = self.clk / freq; let psc = (ratio - 1) / 0xffff; - self.tim.psc.write(|w| w.psc().bits(psc as u16)); - $( + + unsafe { let arr = ratio / (psc + 1) - 1; - unsafe { - self.tim.arr.write(|w| w.$arr().bits(arr 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.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.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)) } } )+ @@ -169,7 +170,7 @@ macro_rules! pwm_hal { impl PwmPin<$TIMX, $CH> { pub fn disable(&mut self) { unsafe { - (*$TIMX::ptr()).ccer.modify(|_, w| w.$ccxe().clear_bit()); + (*$TIMX::ptr()).ccer().modify(|_, w| w.$ccxe().clear_bit()); } } @@ -177,20 +178,22 @@ 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()); } } + pub fn get_duty(&self) -> u32 { - unsafe { (*$TIMX::ptr()).$ccrx.read().bits() } + unsafe { (*$TIMX::ptr()).$ccrx().read().bits() } } pub fn get_max_duty(&self) -> u32 { - unsafe { (*$TIMX::ptr()).arr.read().bits() } + unsafe { (*$TIMX::ptr()).arr().read().bits() } + } pub 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)); } } } @@ -227,7 +230,7 @@ macro_rules! pwm_advanced_hal { impl PwmPin<$TIMX, $CH> { pub fn disable(&mut self) { unsafe { - (*$TIMX::ptr()).ccer.modify(|_, w| w.$ccxe().clear_bit()); + (*$TIMX::ptr()).ccer().modify(|_, w| w.$ccxe().clear_bit()); } } @@ -235,26 +238,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()); )* } } pub fn get_duty(&self) -> u16 { - unsafe { (*$TIMX::ptr()).$ccrx.read().$ccrx().bits() } + unsafe { (*$TIMX::ptr()).$ccrx(<$CH>::N).read().$ccrx().bits() } } pub fn get_max_duty(&self) -> u16 { - unsafe { (*$TIMX::ptr()).arr.read().arr().bits() } + unsafe { (*$TIMX::ptr()).arr().read().arr().bits() } } pub 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)); } } } @@ -286,18 +289,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")] @@ -322,7 +325,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), @@ -330,7 +333,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 a0d525c..507dd24 100644 --- a/src/timer/qei.rs +++ b/src/timer/qei.rs @@ -62,10 +62,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() @@ -82,7 +85,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 } } @@ -91,11 +94,13 @@ macro_rules! qei { } pub 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 } pub fn direction(&self) -> Direction { - if self.tim.cr1.read().dir().bit_is_clear() { + if self.tim.cr1().read().dir().bit_is_clear() { Direction::Upcounting } else { Direction::Downcounting @@ -114,10 +119,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 f490cc1..0d09215 100644 --- a/src/watchdog.rs +++ b/src/watchdog.rs @@ -9,7 +9,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) { @@ -26,17 +26,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) }); } } @@ -63,7 +63,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) { @@ -79,17 +79,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 { @@ -99,7 +101,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()); } }