From 4684411769523267726e458caeec8da6ef7586f7 Mon Sep 17 00:00:00 2001 From: Rahix Date: Sun, 5 May 2024 00:41:16 +0200 Subject: [PATCH 1/9] [NO MERGE] Temporarily use git version of avr-device Use latest avr-device as a git dependency for testing the upcoming version. --- Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index ca159ee2b2..e90571796a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,3 +42,6 @@ exclude = [ "ravedude", ] resolver = "2" + +[patch.crates-io] +avr-device = { git = "https://github.com/rahix/avr-device", rev = "330cdf1fb1a7301b9d6cf62491c16e69d6aa7312" } From eb7ba7be204c558d353e5aa4aca52ffb37c04ee0 Mon Sep 17 00:00:00 2001 From: Rahix Date: Tue, 5 Nov 2024 00:28:54 +0100 Subject: [PATCH 2/9] [NO MERGE] ci: Temporarily disable fail-fast This allows us to see which targets are currently failing the build. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4cdee2156a..d9ba0387ab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: ci: name: "${{ matrix.m.type }}: ${{ matrix.m.name }}" strategy: - fail-fast: true + fail-fast: false matrix: m: - type: board From edf64808bfa60c7e850dff436bc75bce03984feb Mon Sep 17 00:00:00 2001 From: Rahix Date: Sun, 5 May 2024 01:05:34 +0200 Subject: [PATCH 3/9] treewide: Apply changes for new svd2rust API As avr-device is upgrading to use svd2rust version 0.33.1, there are some significant changes in the generated API. We have to adapt the HAL code to use the new API whereever relevant. This commit was mostly generated using the following command, which adds the parentheses behind each register access to change it from struct-field access to method call. cargo build --message-format json 2>/dev/null \ | jq '.message.children[].spans[] | {file: .file_name, line: .line_start, col: (.text[0].highlight_start - 1), insert: .suggested_replacement}' 2>/dev/null \ | jq -r '"sed -ri '"'"'" + (.line | tostring) + "s/^(.{" + (.col | tostring) + "})/\\1" + .insert + "/'"'"' $(cd ../..; realpath " + .file + ")"' \ | sort | uniq | bash Shell magic for the win :) Beyond this, .bits() had to be converted to .set() where safe accesses are performed. --- avr-hal-generic/src/adc.rs | 10 +- avr-hal-generic/src/eeprom.rs | 49 +-- avr-hal-generic/src/i2c.rs | 40 +-- avr-hal-generic/src/port.rs | 32 +- avr-hal-generic/src/simple_pwm.rs | 4 +- avr-hal-generic/src/spi.rs | 12 +- avr-hal-generic/src/usart.rs | 24 +- avr-hal-generic/src/wdt.rs | 8 +- .../arduino-uno/src/bin/uno-ext-interrupt.rs | 4 +- examples/arduino-uno/src/bin/uno-hc-sr04.rs | 12 +- examples/arduino-uno/src/bin/uno-infrared.rs | 12 +- .../arduino-uno/src/bin/uno-manual-servo.rs | 12 +- examples/arduino-uno/src/bin/uno-millis.rs | 8 +- .../src/bin/uno-pin-change-interrupt.rs | 4 +- examples/arduino-uno/src/bin/uno-timer.rs | 12 +- examples/arduino-uno/src/bin/uno-watchdog.rs | 2 +- examples/nano168/src/bin/nano168-millis.rs | 8 +- examples/nano168/src/bin/nano168-watchdog.rs | 2 +- mcu/atmega-hal/src/adc.rs | 24 +- mcu/atmega-hal/src/eeprom.rs | 16 +- mcu/atmega-hal/src/simple_pwm.rs | 316 +++++++++--------- mcu/atmega-hal/src/usart.rs | 77 ++--- mcu/attiny-hal/src/adc.rs | 16 +- mcu/attiny-hal/src/eeprom.rs | 6 +- mcu/attiny-hal/src/simple_pwm.rs | 60 ++-- 25 files changed, 386 insertions(+), 384 deletions(-) diff --git a/avr-hal-generic/src/adc.rs b/avr-hal-generic/src/adc.rs index 0d6904c2d4..acf5ec4c62 100644 --- a/avr-hal-generic/src/adc.rs +++ b/avr-hal-generic/src/adc.rs @@ -250,17 +250,17 @@ macro_rules! impl_adc { #[inline] fn raw_read_adc(&self) -> u16 { - self.adc.read().bits() + self.adc().read().bits() } #[inline] fn raw_is_converting(&self) -> bool { - self.adcsra.read().adsc().bit_is_set() + self.adcsra().read().adsc().bit_is_set() } #[inline] fn raw_start_conversion(&mut self) { - self.adcsra.modify(|_, w| w.adsc().set_bit()); + self.adcsra().modify(|_, w| w.adsc().set_bit()); } #[inline] @@ -276,7 +276,7 @@ macro_rules! impl_adc { match channel { $( x if x == $pin_channel => { - $(self.$didr.modify(|_, w| w.$didr_method().set_bit());)? + $(self.$didr().modify(|_, w| w.$didr_method().set_bit());)? } )+ _ => unreachable!(), @@ -288,7 +288,7 @@ macro_rules! impl_adc { match channel { $( x if x == $pin_channel => { - $(self.$didr.modify(|_, w| w.$didr_method().clear_bit());)? + $(self.$didr().modify(|_, w| w.$didr_method().clear_bit());)? } )+ _ => unreachable!(), diff --git a/avr-hal-generic/src/eeprom.rs b/avr-hal-generic/src/eeprom.rs index ce9094519b..b57982030a 100644 --- a/avr-hal-generic/src/eeprom.rs +++ b/avr-hal-generic/src/eeprom.rs @@ -159,8 +159,8 @@ macro_rules! impl_eeprom_common { $set_address } - self.eecr.write(|w| w.eere().set_bit()); - self.eedr.read().bits() + self.eecr().write(|w| w.eere().set_bit()); + self.eedr().read().bits() } } @@ -173,8 +173,8 @@ macro_rules! impl_eeprom_common { } //Start EEPROM read operation - self.eecr.write(|w| w.eere().set_bit()); - let old_value = self.eedr.read().bits(); + self.eecr().write(|w| w.eere().set_bit()); + let old_value = self.eedr().read().bits(); let diff_mask = old_value ^ data; // Check if any bits are changed to '1' in the new value. @@ -184,20 +184,20 @@ macro_rules! impl_eeprom_common { // Check if any bits in the new value are '0'. if data != 0xff { // Now we know that some bits need to be programmed to '0' also. - self.eedr.write(|w| w.bits(data)); // Set EEPROM data register. + self.eedr().write(|w| w.bits(data)); // Set EEPROM data register. { let $periph_ewmode_var = &self; $set_erasewrite_mode } - self.eecr.modify(|_, w| w.eepe().set_bit()); // Start Erase+Write operation. + self.eecr().modify(|_, w| w.eepe().set_bit()); // Start Erase+Write operation. } else { // Now we know that all bits should be erased. { let $periph_emode_var = &self; $set_erase_mode } - self.eecr.modify(|_, w| w.eepe().set_bit()); // Start Erase-only operation. + self.eecr().modify(|_, w| w.eepe().set_bit()); // Start Erase-only operation. } } //Now we know that _no_ bits need to be erased to '1'. @@ -205,12 +205,12 @@ macro_rules! impl_eeprom_common { // Check if any bits are changed from '1' in the old value. if diff_mask != 0 { // Now we know that _some_ bits need to the programmed to '0'. - self.eedr.write(|w| w.bits(data)); // Set EEPROM data register. + self.eedr().write(|w| w.bits(data)); // Set EEPROM data register. { let $periph_wmode_var = &self; $set_write_mode } - self.eecr.modify(|_, w| w.eepe().set_bit()); // Start Write-only operation. + self.eecr().modify(|_, w| w.eepe().set_bit()); // Start Write-only operation. } } } @@ -229,7 +229,7 @@ macro_rules! impl_eeprom_common { $set_erase_mode } // Start Erase-only operation. - self.eecr.modify(|_, w| w.eepe().set_bit()); + self.eecr().modify(|_, w| w.eepe().set_bit()); } } } @@ -249,7 +249,7 @@ macro_rules! impl_eeprom_atmega_old { #[inline] pub unsafe fn wait_read(regs: &$EEPROM) { //Wait for completion of previous write. - while regs.eecr.read().eewe().bit_is_set() {} + while regs.eecr().read().eewe().bit_is_set() {} } #[inline] @@ -268,8 +268,8 @@ macro_rules! impl_eeprom_atmega_old { unsafe { atmega_helper::set_address(&self, address); } - self.eecr.write(|w| w.eere().set_bit()); - self.eedr.read().bits() + self.eecr().write(|w| w.eere().set_bit()); + self.eedr().read().bits() } fn raw_write_byte(&mut self, address: u16, data: u8) { @@ -278,11 +278,12 @@ macro_rules! impl_eeprom_atmega_old { } //Start EEPROM read operation - self.eedr.write(|w| unsafe { w.bits(data) }); + self.eedr().write(|w| unsafe { w.bits(data) }); - self.eecr.write(|w| w.eemwe().set_bit().eewe().clear_bit()); + self.eecr() + .write(|w| w.eemwe().set_bit().eewe().clear_bit()); - self.eecr.write(|w| w.eewe().set_bit()); + self.eecr().write(|w| w.eewe().set_bit()); } fn raw_erase_byte(&mut self, address: u16) { @@ -305,7 +306,7 @@ macro_rules! impl_eeprom_atmega { #[inline] pub unsafe fn wait_read(regs: &$EEPROM) { //Wait for completion of previous write. - while regs.eecr.read().eepe().bit_is_set() {} + while regs.eecr().read().eepe().bit_is_set() {} } #[inline] pub unsafe fn set_address(regs: &$EEPROM, address: $addrwidth) { @@ -316,21 +317,21 @@ macro_rules! impl_eeprom_atmega { } #[inline] pub unsafe fn set_erasewrite_mode(regs: &$EEPROM) { - regs.eecr.write(|w| { + regs.eecr().write(|w| { // Set Master Write Enable bit, and and Erase+Write mode mode.. w.eempe().set_bit().eepm().val_0x00() }) } #[inline] pub unsafe fn set_erase_mode(regs: &$EEPROM) { - regs.eecr.write(|w| { + regs.eecr().write(|w| { // Set Master Write Enable bit, and Erase-only mode.. w.eempe().set_bit().eepm().val_0x01() }); } #[inline] pub unsafe fn set_write_mode(regs: &$EEPROM) { - regs.eecr.write(|w| { + regs.eecr().write(|w| { // Set Master Write Enable bit, and Write-only mode.. w.eempe().set_bit().eepm().val_0x02() }); @@ -362,7 +363,7 @@ macro_rules! impl_eeprom_attiny { mod attiny_helper { #[inline] pub unsafe fn wait_read(regs: &$EEPROM) { - while regs.eecr.read().eepe().bit_is_set() {} + while regs.eecr().read().eepe().bit_is_set() {} } #[inline] pub unsafe fn set_address(regs: &$EEPROM, address: $addrwidth) { @@ -373,21 +374,21 @@ macro_rules! impl_eeprom_attiny { } #[inline] pub unsafe fn set_erasewrite_mode(regs: &$EEPROM) { - regs.eecr.write(|w| { + regs.eecr().write(|w| { // Set Master Write Enable bit...and and Erase+Write mode mode.. w.eempe().set_bit().eepm().atomic() }); } #[inline] pub unsafe fn set_erase_mode(regs: &$EEPROM) { - regs.eecr.write(|w| { + regs.eecr().write(|w| { // Set Master Write Enable bit, and Erase-only mode.. w.eempe().set_bit().eepm().erase() }); } #[inline] pub unsafe fn set_write_mode(regs: &$EEPROM) { - regs.eecr.write(|w| { + regs.eecr().write(|w| { // Set Master Write Enable bit, and Write-only mode.. w.eempe().set_bit().eepm().write() }); diff --git a/avr-hal-generic/src/i2c.rs b/avr-hal-generic/src/i2c.rs index 1159ce2cf6..839e0a4a6a 100644 --- a/avr-hal-generic/src/i2c.rs +++ b/avr-hal-generic/src/i2c.rs @@ -466,22 +466,22 @@ macro_rules! impl_i2c_twi { fn raw_setup(&mut self, speed: u32) { // Calculate TWBR register value let twbr = ((CLOCK::FREQ / speed) - 16) / 2; - self.twbr.write(|w| unsafe { w.bits(twbr as u8) }); + self.twbr().write(|w| unsafe { w.bits(twbr as u8) }); // Disable prescaler - self.twsr.write(|w| w.twps().prescaler_1()); + self.twsr().write(|w| w.twps().prescaler_1()); } #[inline] fn raw_start(&mut self, address: u8, direction: Direction) -> Result<(), Error> { // Write start condition - self.twcr + self.twcr() .write(|w| w.twen().set_bit().twint().set_bit().twsta().set_bit()); // wait() - while self.twcr.read().twint().bit_is_clear() {} + while self.twcr().read().twint().bit_is_clear() {} // Validate status - match self.twsr.read().tws().bits() { + match self.twsr().read().tws().bits() { $crate::i2c::twi_status::TW_START | $crate::i2c::twi_status::TW_REP_START => (), $crate::i2c::twi_status::TW_MT_ARB_LOST | $crate::i2c::twi_status::TW_MR_ARB_LOST => { @@ -502,13 +502,13 @@ macro_rules! impl_i2c_twi { 0 }; let rawaddr = (address << 1) | dirbit; - self.twdr.write(|w| unsafe { w.bits(rawaddr) }); + self.twdr().write(|w| unsafe { w.bits(rawaddr) }); // transact() - self.twcr.write(|w| w.twen().set_bit().twint().set_bit()); - while self.twcr.read().twint().bit_is_clear() {} + self.twcr().write(|w| w.twen().set_bit().twint().set_bit()); + while self.twcr().read().twint().bit_is_clear() {} // Check if the slave responded - match self.twsr.read().tws().bits() { + match self.twsr().read().tws().bits() { $crate::i2c::twi_status::TW_MT_SLA_ACK | $crate::i2c::twi_status::TW_MR_SLA_ACK => (), $crate::i2c::twi_status::TW_MT_SLA_NACK @@ -535,12 +535,12 @@ macro_rules! impl_i2c_twi { #[inline] fn raw_write(&mut self, bytes: &[u8]) -> Result<(), Error> { for byte in bytes { - self.twdr.write(|w| unsafe { w.bits(*byte) }); + self.twdr().write(|w| unsafe { w.bits(*byte) }); // transact() - self.twcr.write(|w| w.twen().set_bit().twint().set_bit()); - while self.twcr.read().twint().bit_is_clear() {} + self.twcr().write(|w| w.twen().set_bit().twint().set_bit()); + while self.twcr().read().twint().bit_is_clear() {} - match self.twsr.read().tws().bits() { + match self.twsr().read().tws().bits() { $crate::i2c::twi_status::TW_MT_DATA_ACK => (), $crate::i2c::twi_status::TW_MT_DATA_NACK => { self.raw_stop()?; @@ -565,17 +565,17 @@ macro_rules! impl_i2c_twi { let last = buffer.len() - 1; for (i, byte) in buffer.iter_mut().enumerate() { if i != last { - self.twcr + self.twcr() .write(|w| w.twint().set_bit().twen().set_bit().twea().set_bit()); // wait() - while self.twcr.read().twint().bit_is_clear() {} + while self.twcr().read().twint().bit_is_clear() {} } else { - self.twcr.write(|w| w.twint().set_bit().twen().set_bit()); + self.twcr().write(|w| w.twint().set_bit().twen().set_bit()); // wait() - while self.twcr.read().twint().bit_is_clear() {} + while self.twcr().read().twint().bit_is_clear() {} } - match self.twsr.read().tws().bits() { + match self.twsr().read().tws().bits() { $crate::i2c::twi_status::TW_MR_DATA_ACK | $crate::i2c::twi_status::TW_MR_DATA_NACK => (), $crate::i2c::twi_status::TW_MR_ARB_LOST => { @@ -589,14 +589,14 @@ macro_rules! impl_i2c_twi { } } - *byte = self.twdr.read().bits(); + *byte = self.twdr().read().bits(); } Ok(()) } #[inline] fn raw_stop(&mut self) -> Result<(), Error> { - self.twcr + self.twcr() .write(|w| w.twen().set_bit().twint().set_bit().twsto().set_bit()); Ok(()) } diff --git a/avr-hal-generic/src/port.rs b/avr-hal-generic/src/port.rs index 2e44ffc950..9e1259f07f 100644 --- a/avr-hal-generic/src/port.rs +++ b/avr-hal-generic/src/port.rs @@ -633,7 +633,7 @@ macro_rules! impl_port_traditional_base { #[inline] unsafe fn out_set(&mut self) { match self.port { - $(DynamicPort::[] => (*<$port>::ptr()).[].modify(|r, w| { + $(DynamicPort::[] => (*<$port>::ptr()).[]().modify(|r, w| { w.bits(r.bits() | self.mask) }),)+ } @@ -642,7 +642,7 @@ macro_rules! impl_port_traditional_base { #[inline] unsafe fn out_clear(&mut self) { match self.port { - $(DynamicPort::[] => (*<$port>::ptr()).[].modify(|r, w| { + $(DynamicPort::[] => (*<$port>::ptr()).[]().modify(|r, w| { w.bits(r.bits() & !self.mask) }),)+ } @@ -653,14 +653,14 @@ macro_rules! impl_port_traditional_base { match self.port { $(DynamicPort::[] => { if $chip_supports_atomic_toggle { - (*<$port>::ptr()).[].write(|w| { + (*<$port>::ptr()).[]().write(|w| { w.bits(self.mask) }) } else { // This read-modify-write sequence cannot be optimized into a single sbi/cbi instruction, // so it is wrapped in a critical section which ensures we will never hit a race-condition here. $crate::avr_device::interrupt::free(|_| { - (*<$port>::ptr()).[].modify(|r, w| { + (*<$port>::ptr()).[]().modify(|r, w| { w.bits(r.bits() ^ self.mask) }) }) @@ -673,7 +673,7 @@ macro_rules! impl_port_traditional_base { unsafe fn out_get(&self) -> bool { match self.port { $(DynamicPort::[] => { - (*<$port>::ptr()).[].read().bits() & self.mask != 0 + (*<$port>::ptr()).[]().read().bits() & self.mask != 0 })+ } } @@ -682,7 +682,7 @@ macro_rules! impl_port_traditional_base { unsafe fn in_get(&self) -> bool { match self.port { $(DynamicPort::[] => { - (*<$port>::ptr()).[].read().bits() & self.mask != 0 + (*<$port>::ptr()).[]().read().bits() & self.mask != 0 })+ } } @@ -690,7 +690,7 @@ macro_rules! impl_port_traditional_base { #[inline] unsafe fn make_output(&mut self) { match self.port { - $(DynamicPort::[] => (*<$port>::ptr()).[].modify(|r, w| { + $(DynamicPort::[] => (*<$port>::ptr()).[]().modify(|r, w| { w.bits(r.bits() | self.mask) }),)+ } @@ -699,7 +699,7 @@ macro_rules! impl_port_traditional_base { #[inline] unsafe fn make_input(&mut self, pull_up: bool) { match self.port { - $(DynamicPort::[] => (*<$port>::ptr()).[].modify(|r, w| { + $(DynamicPort::[] => (*<$port>::ptr()).[]().modify(|r, w| { w.bits(r.bits() & !self.mask) }),)+ } @@ -728,14 +728,14 @@ macro_rules! impl_port_traditional_base { #[inline] unsafe fn out_set(&mut self) { - (*<$port>::ptr()).[].modify(|_, w| { + (*<$port>::ptr()).[]().modify(|_, w| { w.[

]().set_bit() }) } #[inline] unsafe fn out_clear(&mut self) { - (*<$port>::ptr()).[].modify(|_, w| { + (*<$port>::ptr()).[]().modify(|_, w| { w.[

]().clear_bit() }) } @@ -743,14 +743,14 @@ macro_rules! impl_port_traditional_base { #[inline] unsafe fn out_toggle(&mut self) { if $chip_supports_atomic_toggle { - (*<$port>::ptr()).[].write(|w| { + (*<$port>::ptr()).[]().write(|w| { w.[

]().set_bit() }) } else { // This read-modify-write sequence cannot be optimized into a single sbi/cbi instruction, // so it is wrapped in a critical section which ensures we will never hit a race-condition here. $crate::avr_device::interrupt::free(|_| { - (*<$port>::ptr()).[].modify(|r, w| { + (*<$port>::ptr()).[]().modify(|r, w| { w.[

]().bit(!r.[

]().bit()) }) }) @@ -759,24 +759,24 @@ macro_rules! impl_port_traditional_base { #[inline] unsafe fn out_get(&self) -> bool { - (*<$port>::ptr()).[].read().[

]().bit() + (*<$port>::ptr()).[]().read().[

]().bit() } #[inline] unsafe fn in_get(&self) -> bool { - (*<$port>::ptr()).[].read().[

]().bit() + (*<$port>::ptr()).[]().read().[

]().bit() } #[inline] unsafe fn make_output(&mut self) { - (*<$port>::ptr()).[].modify(|_, w| { + (*<$port>::ptr()).[]().modify(|_, w| { w.[

]().set_bit() }) } #[inline] unsafe fn make_input(&mut self, pull_up: bool) { - (*<$port>::ptr()).[].modify(|_, w| { + (*<$port>::ptr()).[]().modify(|_, w| { w.[

]().clear_bit() }); if pull_up { diff --git a/avr-hal-generic/src/simple_pwm.rs b/avr-hal-generic/src/simple_pwm.rs index 93b4081bf5..b0330927c6 100644 --- a/avr-hal-generic/src/simple_pwm.rs +++ b/avr-hal-generic/src/simple_pwm.rs @@ -175,7 +175,7 @@ macro_rules! impl_simple_pwm { } fn get_duty(&self) -> Self::Duty { - unsafe { (&*<$TIMER>::ptr()) }.$ocr.read().bits() as Self::Duty + unsafe { (&*<$TIMER>::ptr()) }.$ocr().read().bits() as Self::Duty } fn get_max_duty(&self) -> Self::Duty { @@ -185,7 +185,7 @@ macro_rules! impl_simple_pwm { fn set_duty(&mut self, duty: Self::Duty) { // SAFETY: This register is exclusively used here so there are no concurrency // issues. - unsafe { (&*<$TIMER>::ptr()).$ocr.write(|w| w.bits(duty.into())); }; + unsafe { (&*<$TIMER>::ptr()).$ocr().write(|w| w.bits(duty.into())); }; } } )+ diff --git a/avr-hal-generic/src/spi.rs b/avr-hal-generic/src/spi.rs index 6a1bdbf154..cf90fb9f64 100644 --- a/avr-hal-generic/src/spi.rs +++ b/avr-hal-generic/src/spi.rs @@ -460,7 +460,7 @@ macro_rules! impl_spi { use $crate::hal::spi; // set up control register - self.spcr.write(|w| { + self.spcr().write(|w| { // enable SPI w.spe().set_bit(); // Set to primary mode @@ -492,7 +492,7 @@ macro_rules! impl_spi { } }); // set up 2x clock rate status bit - self.spsr.write(|w| match settings.clock { + self.spsr().write(|w| match settings.clock { SerialClockRate::OscfOver2 => w.spi2x().set_bit(), SerialClockRate::OscfOver4 => w.spi2x().clear_bit(), SerialClockRate::OscfOver8 => w.spi2x().set_bit(), @@ -504,19 +504,19 @@ macro_rules! impl_spi { } fn raw_release(&mut self) { - self.spcr.write(|w| w.spe().clear_bit()); + self.spcr().write(|w| w.spe().clear_bit()); } fn raw_check_iflag(&self) -> bool { - self.spsr.read().spif().bit_is_set() + self.spsr().read().spif().bit_is_set() } fn raw_read(&self) -> u8 { - self.spdr.read().bits() + self.spdr().read().bits() } fn raw_write(&mut self, byte: u8) { - self.spdr.write(|w| unsafe { w.bits(byte) }); + self.spdr().write(|w| unsafe { w.bits(byte) }); } fn raw_transaction(&mut self, byte: u8) -> u8 { diff --git a/avr-hal-generic/src/usart.rs b/avr-hal-generic/src/usart.rs index d929cf553b..ed670014c5 100644 --- a/avr-hal-generic/src/usart.rs +++ b/avr-hal-generic/src/usart.rs @@ -484,18 +484,18 @@ macro_rules! impl_usart_traditional { $crate::port::Pin<$crate::port::mode::Output, $txpin>, > for $USART { fn raw_init(&mut self, baudrate: $crate::usart::Baudrate) { - self.[].write(|w| unsafe { w.bits(baudrate.ubrr) }); - self.[].write(|w| w.[]().bit(baudrate.u2x)); + self.[]().write(|w| unsafe { w.bits(baudrate.ubrr) }); + self.[]().write(|w| w.[]().bit(baudrate.u2x)); // Enable receiver and transmitter but leave interrupts disabled. - self.[].write(|w| w + self.[]().write(|w| w .[]().set_bit() .[]().set_bit() ); // Set frame format to 8n1 for now. At some point, this should be made // configurable, similar to what is done in other HALs. - self.[].write(|w| w + self.[]().write(|w| w .[]().usart_async() .[]().chr8() .[]().stop1() @@ -506,11 +506,11 @@ macro_rules! impl_usart_traditional { fn raw_deinit(&mut self) { // Wait for any ongoing transfer to finish. $crate::nb::block!(self.raw_flush()).ok(); - self.[].reset(); + self.[]().reset(); } fn raw_flush(&mut self) -> $crate::nb::Result<(), core::convert::Infallible> { - if self.[].read().[]().bit_is_clear() { + if self.[]().read().[]().bit_is_clear() { Err($crate::nb::Error::WouldBlock) } else { Ok(()) @@ -521,26 +521,26 @@ macro_rules! impl_usart_traditional { // Call flush to make sure the data-register is empty self.raw_flush()?; - self.[].write(|w| unsafe { w.bits(byte) }); + self.[]().write(|w| unsafe { w.bits(byte) }); Ok(()) } fn raw_read(&mut self) -> $crate::nb::Result { - if self.[].read().[]().bit_is_clear() { + if self.[]().read().[]().bit_is_clear() { return Err($crate::nb::Error::WouldBlock); } - Ok(self.[].read().bits()) + Ok(self.[]().read().bits()) } fn raw_interrupt(&mut self, event: $crate::usart::Event, state: bool) { match event { $crate::usart::Event::RxComplete => - self.[].modify(|_, w| w.[]().bit(state)), + self.[]().modify(|_, w| w.[]().bit(state)), $crate::usart::Event::TxComplete => - self.[].modify(|_, w| w.[]().bit(state)), + self.[]().modify(|_, w| w.[]().bit(state)), $crate::usart::Event::DataRegisterEmpty => - self.[].modify(|_, w| w.[]().bit(state)), + self.[]().modify(|_, w| w.[]().bit(state)), } } } diff --git a/avr-hal-generic/src/wdt.rs b/avr-hal-generic/src/wdt.rs index 94d0a2d7ed..bb0da54fda 100644 --- a/avr-hal-generic/src/wdt.rs +++ b/avr-hal-generic/src/wdt.rs @@ -112,10 +112,10 @@ macro_rules! impl_wdt { // Reset the watchdog timer. self.raw_feed(); // Enable watchdog configuration mode. - self.$wdtcsr + self.$wdtcsr() .modify(|_, w| w.wdce().set_bit().wde().set_bit()); // Enable watchdog and set interval. - self.$wdtcsr.write(|w| { + self.$wdtcsr().write(|w| { let $to = timeout; let $w = w; ($to_match).wde().set_bit().wdce().clear_bit() @@ -143,10 +143,10 @@ macro_rules! impl_wdt { // Reset the watchdog timer. self.raw_feed(); // Enable watchdog configuration mode. - self.$wdtcsr + self.$wdtcsr() .modify(|_, w| w.wdce().set_bit().wde().set_bit()); // Disable watchdog. - self.$wdtcsr.reset(); + self.$wdtcsr().reset(); }) } } diff --git a/examples/arduino-uno/src/bin/uno-ext-interrupt.rs b/examples/arduino-uno/src/bin/uno-ext-interrupt.rs index ee6ebc3d05..425c033556 100644 --- a/examples/arduino-uno/src/bin/uno-ext-interrupt.rs +++ b/examples/arduino-uno/src/bin/uno-ext-interrupt.rs @@ -47,9 +47,9 @@ fn main() -> ! { // thanks to tsemczyszyn and Rahix: https://github.com/Rahix/avr-hal/issues/240 // Configure INT0 for falling edge. 0x03 would be rising edge. - dp.EXINT.eicra.modify(|_, w| w.isc0().bits(0x02)); + dp.EXINT.eicra().modify(|_, w| w.isc0().set(0x02)); // Enable the INT0 interrupt source. - dp.EXINT.eimsk.modify(|_, w| w.int0().set_bit()); + dp.EXINT.eimsk().modify(|_, w| w.int0().set_bit()); let mut leds: [Pin; 4] = [ pins.d3.into_output().downgrade(), diff --git a/examples/arduino-uno/src/bin/uno-hc-sr04.rs b/examples/arduino-uno/src/bin/uno-hc-sr04.rs index 336aa78d66..6e08fdaa33 100644 --- a/examples/arduino-uno/src/bin/uno-hc-sr04.rs +++ b/examples/arduino-uno/src/bin/uno-hc-sr04.rs @@ -30,11 +30,11 @@ fn main() -> ! { // since the clock register size is 16 bits, the timer is full every // 1/(16e6/64)*2^16 ≈ 260 ms let timer1 = dp.TC1; - timer1.tccr1b.write(|w| w.cs1().prescale_64()); + timer1.tccr1b().write(|w| w.cs1().prescale_64()); 'outer: loop { // the timer is reinitialized with value 0. - timer1.tcnt1.write(|w| w.bits(0)); + timer1.tcnt1().write(|w| w.set(0)); // the trigger must be set to high under 10 µs as per the HC-SR04 datasheet trig.set_high(); @@ -44,7 +44,7 @@ fn main() -> ! { while echo.is_low() { // exiting the loop if the timer has reached 200 ms. // 0.2s/4µs = 50000 - if timer1.tcnt1.read().bits() >= 50000 { + if timer1.tcnt1().read().bits() >= 50000 { // jump to the beginning of the outer loop if no obstacle is detected ufmt::uwriteln!( &mut serial, @@ -55,7 +55,7 @@ fn main() -> ! { } } // Restarting the timer - timer1.tcnt1.write(|w| w.bits(0)); + timer1.tcnt1().write(|w| w.set(0)); // Wait for the echo to get low again while echo.is_high() {} @@ -66,7 +66,7 @@ fn main() -> ! { // some HC-SR04 labeled sensor holds the echo pin in high state for very long time, // thus overflowing the u16 value when multiplying the timer1 value with 4. // overflow during runtime causes panic! so it must be handled - let temp_timer = timer1.tcnt1.read().bits().saturating_mul(4); + let temp_timer = timer1.tcnt1().read().bits().saturating_mul(4); let value = match temp_timer { u16::MAX => { ufmt::uwriteln!( @@ -81,7 +81,7 @@ fn main() -> ! { // Await 100 ms before sending the next trig // 0.1s/4µs = 25000 - while timer1.tcnt1.read().bits() < 25000 {} + while timer1.tcnt1().read().bits() < 25000 {} ufmt::uwriteln!( &mut serial, diff --git a/examples/arduino-uno/src/bin/uno-infrared.rs b/examples/arduino-uno/src/bin/uno-infrared.rs index 6cc2a5a89c..0c1ba59318 100644 --- a/examples/arduino-uno/src/bin/uno-infrared.rs +++ b/examples/arduino-uno/src/bin/uno-infrared.rs @@ -62,10 +62,10 @@ fn main() -> ! { irdroino_led2.set_low(); // Enable group 2 (PORTD) - dp.EXINT.pcicr.write(|w| unsafe { w.bits(0b100) }); + dp.EXINT.pcicr().write(|w| unsafe { w.bits(0b100) }); // Enable pin change interrupts on PCINT18 which is pin PD2 (= d2) - dp.EXINT.pcmsk2.write(|w| w.bits(0b100)); + dp.EXINT.pcmsk2().write(|w| w.set(0b100)); let ir = Receiver::with_pin(Clock::FREQ, pins.d2); @@ -141,12 +141,12 @@ impl Clock { pub fn start(&self, tc0: arduino_hal::pac::TC0) { // Configure the timer for the above interval (in CTC mode) - tc0.tccr0a.write(|w| w.wgm0().ctc()); - tc0.ocr0a.write(|w| w.bits(Self::TOP)); - tc0.tccr0b.write(|w| w.cs0().variant(Self::PRESCALER)); + tc0.tccr0a().write(|w| w.wgm0().ctc()); + tc0.ocr0a().write(|w| w.set(Self::TOP)); + tc0.tccr0b().write(|w| w.cs0().variant(Self::PRESCALER)); // Enable interrupt - tc0.timsk0.write(|w| w.ocie0a().set_bit()); + tc0.timsk0().write(|w| w.ocie0a().set_bit()); } pub fn now(&self) -> u32 { diff --git a/examples/arduino-uno/src/bin/uno-manual-servo.rs b/examples/arduino-uno/src/bin/uno-manual-servo.rs index 9402446e7d..ee67fa8357 100644 --- a/examples/arduino-uno/src/bin/uno-manual-servo.rs +++ b/examples/arduino-uno/src/bin/uno-manual-servo.rs @@ -30,17 +30,17 @@ fn main() -> ! { // - Each count increases the duty-cycle by 4us. // - Use OC1A which is connected to D9 of the Arduino Uno. let tc1 = dp.TC1; - tc1.icr1.write(|w| w.bits(4999)); - tc1.tccr1a - .write(|w| w.wgm1().bits(0b10).com1a().match_clear()); - tc1.tccr1b - .write(|w| w.wgm1().bits(0b11).cs1().prescale_64()); + tc1.icr1().write(|w| w.set(4999)); + tc1.tccr1a() + .write(|w| w.wgm1().set(0b10).com1a().match_clear()); + tc1.tccr1b() + .write(|w| w.wgm1().set(0b11).cs1().prescale_64()); loop { // 100 counts => 0.4ms // 700 counts => 2.8ms for duty in 100..=700 { - tc1.ocr1a.write(|w| w.bits(duty)); + tc1.ocr1a().write(|w| w.set(duty)); arduino_hal::delay_ms(20); } } diff --git a/examples/arduino-uno/src/bin/uno-millis.rs b/examples/arduino-uno/src/bin/uno-millis.rs index 58042b5efb..e9c22eee62 100644 --- a/examples/arduino-uno/src/bin/uno-millis.rs +++ b/examples/arduino-uno/src/bin/uno-millis.rs @@ -38,16 +38,16 @@ static MILLIS_COUNTER: avr_device::interrupt::Mutex> = fn millis_init(tc0: arduino_hal::pac::TC0) { // Configure the timer for the above interval (in CTC mode) // and enable its interrupt. - tc0.tccr0a.write(|w| w.wgm0().ctc()); - tc0.ocr0a.write(|w| w.bits(TIMER_COUNTS as u8)); - tc0.tccr0b.write(|w| match PRESCALER { + tc0.tccr0a().write(|w| w.wgm0().ctc()); + tc0.ocr0a().write(|w| w.set(TIMER_COUNTS as u8)); + tc0.tccr0b().write(|w| match PRESCALER { 8 => w.cs0().prescale_8(), 64 => w.cs0().prescale_64(), 256 => w.cs0().prescale_256(), 1024 => w.cs0().prescale_1024(), _ => panic!(), }); - tc0.timsk0.write(|w| w.ocie0a().set_bit()); + tc0.timsk0().write(|w| w.ocie0a().set_bit()); // Reset the global millisecond counter avr_device::interrupt::free(|cs| { diff --git a/examples/arduino-uno/src/bin/uno-pin-change-interrupt.rs b/examples/arduino-uno/src/bin/uno-pin-change-interrupt.rs index b731b528a0..42a71d3750 100644 --- a/examples/arduino-uno/src/bin/uno-pin-change-interrupt.rs +++ b/examples/arduino-uno/src/bin/uno-pin-change-interrupt.rs @@ -49,10 +49,10 @@ fn main() -> ! { ]; // Enable the PCINT2 pin change interrupt - dp.EXINT.pcicr.write(|w| unsafe { w.bits(0b100) }); + dp.EXINT.pcicr().write(|w| unsafe { w.bits(0b100) }); // Enable pin change interrupts on PCINT18 which is pin PD2 (= d2) - dp.EXINT.pcmsk2.write(|w| w.bits(0b100)); + dp.EXINT.pcmsk2().write(|w| w.set(0b100)); //From this point on an interrupt can happen unsafe { avr_device::interrupt::enable() }; diff --git a/examples/arduino-uno/src/bin/uno-timer.rs b/examples/arduino-uno/src/bin/uno-timer.rs index bb315464a5..83b163d8f6 100644 --- a/examples/arduino-uno/src/bin/uno-timer.rs +++ b/examples/arduino-uno/src/bin/uno-timer.rs @@ -60,7 +60,7 @@ fn main() -> ! { ufmt::uwriteln!( &mut serial, "configured timer output compare register = {}", - tmr1.ocr1a.read().bits() + tmr1.ocr1a().read().bits() ) .unwrap_infallible(); @@ -107,16 +107,16 @@ pub fn rig_timer>(tmr1: &TC1, ser ) .unwrap_infallible(); - tmr1.tccr1a.write(|w| w.wgm1().bits(0b00)); - tmr1.tccr1b.write(|w| { + tmr1.tccr1a().write(|w| w.wgm1().set(0b00)); + tmr1.tccr1b().write(|w| { w.cs1() //.prescale_256() .variant(CLOCK_SOURCE) .wgm1() - .bits(0b01) + .set(0b01) }); - tmr1.ocr1a.write(|w| w.bits(ticks)); - tmr1.timsk1.write(|w| w.ocie1a().set_bit()); //enable this specific interrupt + tmr1.ocr1a().write(|w| w.set(ticks)); + tmr1.timsk1().write(|w| w.ocie1a().set_bit()); //enable this specific interrupt } #[avr_device::interrupt(atmega328p)] diff --git a/examples/arduino-uno/src/bin/uno-watchdog.rs b/examples/arduino-uno/src/bin/uno-watchdog.rs index 4871210e6a..1801b127ce 100644 --- a/examples/arduino-uno/src/bin/uno-watchdog.rs +++ b/examples/arduino-uno/src/bin/uno-watchdog.rs @@ -24,7 +24,7 @@ fn main() -> ! { arduino_hal::delay_ms(100); } - let mut watchdog = wdt::Wdt::new(dp.WDT, &dp.CPU.mcusr); + let mut watchdog = wdt::Wdt::new(dp.WDT, &dp.CPU.mcusr()); watchdog.start(wdt::Timeout::Ms2000).unwrap(); loop { diff --git a/examples/nano168/src/bin/nano168-millis.rs b/examples/nano168/src/bin/nano168-millis.rs index 0375607ee7..85e906c61e 100644 --- a/examples/nano168/src/bin/nano168-millis.rs +++ b/examples/nano168/src/bin/nano168-millis.rs @@ -36,16 +36,16 @@ static MILLIS_COUNTER: avr_device::interrupt::Mutex> = fn millis_init(tc0: arduino_hal::pac::TC0) { // Configure the timer for the above interval (in CTC mode) // and enable its interrupt. - tc0.tccr0a.write(|w| w.wgm0().ctc()); - tc0.ocr0a.write(|w| w.bits(TIMER_COUNTS as u8)); - tc0.tccr0b.write(|w| match PRESCALER { + tc0.tccr0a().write(|w| w.wgm0().ctc()); + tc0.ocr0a().write(|w| w.set(TIMER_COUNTS as u8)); + tc0.tccr0b().write(|w| match PRESCALER { 8 => w.cs0().prescale_8(), 64 => w.cs0().prescale_64(), 256 => w.cs0().prescale_256(), 1024 => w.cs0().prescale_1024(), _ => panic!(), }); - tc0.timsk0.write(|w| w.ocie0a().set_bit()); + tc0.timsk0().write(|w| w.ocie0a().set_bit()); // Reset the global millisecond counter avr_device::interrupt::free(|cs| { diff --git a/examples/nano168/src/bin/nano168-watchdog.rs b/examples/nano168/src/bin/nano168-watchdog.rs index aac0426ea3..f7d7d8a613 100644 --- a/examples/nano168/src/bin/nano168-watchdog.rs +++ b/examples/nano168/src/bin/nano168-watchdog.rs @@ -23,7 +23,7 @@ fn main() -> ! { } ufmt::uwriteln!(&mut serial, "\nEnabling watchdog...").unwrap_infallible(); - let mut watchdog = wdt::Wdt::new(dp.WDT, &dp.CPU.mcusr); + let mut watchdog = wdt::Wdt::new(dp.WDT, &dp.CPU.mcusr()); watchdog.start(wdt::Timeout::Ms4000).unwrap(); ufmt::uwriteln!(&mut serial, "\nWatchdog on watch...").unwrap_infallible(); diff --git a/mcu/atmega-hal/src/adc.rs b/mcu/atmega-hal/src/adc.rs index 2881ae62fa..6dd225a751 100644 --- a/mcu/atmega-hal/src/adc.rs +++ b/mcu/atmega-hal/src/adc.rs @@ -56,7 +56,7 @@ pub struct AdcSettings { } fn apply_settings(peripheral: &crate::pac::ADC, settings: AdcSettings) { - peripheral.adcsra.write(|w| { + peripheral.adcsra().write(|w| { w.aden().set_bit(); match settings.clock_divider { ClockDivider::Factor2 => w.adps().prescaler_2(), @@ -68,7 +68,7 @@ fn apply_settings(peripheral: &crate::pac::ADC, settings: AdcSettings) { ClockDivider::Factor128 => w.adps().prescaler_128(), } }); - peripheral.admux.write(|w| match settings.ref_voltage { + peripheral.admux().write(|w| match settings.ref_voltage { ReferenceVoltage::Aref => w.refs().aref(), ReferenceVoltage::AVcc => w.refs().avcc(), ReferenceVoltage::Internal => w.refs().internal(), @@ -183,7 +183,7 @@ avr_hal_generic::impl_adc! { apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, channel_id: crate::pac::adc::admux::MUX_A, set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); + peripheral.admux().modify(|_, w| w.mux().variant(id)); }, pins: { port::PC0: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), @@ -213,7 +213,7 @@ avr_hal_generic::impl_adc! { apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, channel_id: crate::pac::adc::admux::MUX_A, set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); + peripheral.admux().modify(|_, w| w.mux().variant(id)); }, pins: { port::PA0: (crate::pac::adc::admux::MUX_A::ADC0), @@ -239,8 +239,8 @@ avr_hal_generic::impl_adc! { apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, channel_id: u8, set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().bits(id & 0x1f)); - peripheral.adcsrb.modify(|_, w| w.mux5().bit(id & 0x20 != 0)); + peripheral.admux().modify(|_, w| w.mux().set(id & 0x1f)); + peripheral.adcsrb().modify(|_, w| w.mux5().bit(id & 0x20 != 0)); }, pins: { port::PF0: (0b000000, didr0::adc0d), @@ -271,7 +271,7 @@ avr_hal_generic::impl_adc! { apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, channel_id: crate::pac::adc::admux::MUX_A, set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); + peripheral.admux().modify(|_, w| w.mux().variant(id)); }, pins: { port::PF0: (crate::pac::adc::admux::MUX_A::ADC0), @@ -297,8 +297,8 @@ avr_hal_generic::impl_adc! { apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, channel_id: u8, set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().bits(id & 0x1f)); - peripheral.adcsrb.modify(|_, w| w.mux5().bit(id & 0x20 != 0)); + peripheral.admux().modify(|_, w| w.mux().set(id & 0x1f)); + peripheral.adcsrb().modify(|_, w| w.mux5().bit(id & 0x20 != 0)); }, pins: { port::PF0: (0b000000, didr0::adc0d), @@ -332,7 +332,7 @@ avr_hal_generic::impl_adc! { apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, channel_id: crate::pac::adc::admux::MUX_A, set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); + peripheral.admux().modify(|_, w| w.mux().variant(id)); }, pins: { port::PA0: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), @@ -360,7 +360,7 @@ avr_hal_generic::impl_adc! { apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, channel_id: crate::pac::adc::admux::MUX_A, set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); + peripheral.admux().modify(|_, w| w.mux().variant(id)); }, pins: { port::PC0: (crate::pac::adc::admux::MUX_A::ADC0), @@ -388,7 +388,7 @@ avr_hal_generic::impl_adc! { apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, channel_id: crate::pac::adc::admux::MUX_A, set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); + peripheral.admux().modify(|_, w| w.mux().variant(id)); }, pins: { port::PA0: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), diff --git a/mcu/atmega-hal/src/eeprom.rs b/mcu/atmega-hal/src/eeprom.rs index 865929676f..d20db81269 100644 --- a/mcu/atmega-hal/src/eeprom.rs +++ b/mcu/atmega-hal/src/eeprom.rs @@ -30,7 +30,7 @@ avr_hal_generic::impl_eeprom_atmega! { capacity: 256, addr_width: u8, set_address: |peripheral, address| { - peripheral.eearl.write(|w| w.bits(address)); + peripheral.eearl().write(|w| w.bits(address)); }, } @@ -41,7 +41,7 @@ avr_hal_generic::impl_eeprom_atmega! { capacity: 512, addr_width: u16, set_address: |peripheral, address| { - peripheral.eear.write(|w| w.bits(address)); + peripheral.eear().write(|w| w.bits(address)); }, } @@ -52,7 +52,7 @@ avr_hal_generic::impl_eeprom_atmega! { capacity: 512, addr_width: u16, set_address: |peripheral, address| { - peripheral.eear.write(|w| w.bits(address)); + peripheral.eear().write(|w| w.bits(address)); }, } @@ -67,7 +67,7 @@ avr_hal_generic::impl_eeprom_atmega! { capacity: 1024, addr_width: u16, set_address: |peripheral, address| { - peripheral.eear.write(|w| w.bits(address)); + peripheral.eear().write(|w| w.bits(address)); }, } @@ -82,7 +82,7 @@ avr_hal_generic::impl_eeprom_atmega! { capacity: 4096, addr_width: u16, set_address: |peripheral, address| { - peripheral.eear.write(|w| w.bits(address)); + peripheral.eear().write(|w| w.bits(address)); }, } @@ -93,7 +93,7 @@ avr_hal_generic::impl_eeprom_atmega_old! { capacity: 512, addr_width: u16, set_address: |peripheral, address| { - peripheral.eear.write(|w| w.bits(address)); + peripheral.eear().write(|w| w.bits(address)); }, } @@ -104,7 +104,7 @@ avr_hal_generic::impl_eeprom_atmega_old! { capacity: 1024, addr_width: u16, set_address: |peripheral, address| { - peripheral.eear.write(|w| w.bits(address)); + peripheral.eear().write(|w| w.bits(address)); }, } @@ -115,6 +115,6 @@ avr_hal_generic::impl_eeprom_atmega_old! { capacity: 4096, addr_width: u16, set_address: |peripheral, address| { - peripheral.eear.write(|w| w.bits(address)); + peripheral.eear().write(|w| w.bits(address)); }, } diff --git a/mcu/atmega-hal/src/simple_pwm.rs b/mcu/atmega-hal/src/simple_pwm.rs index 296280f3c9..bdf13e25f1 100644 --- a/mcu/atmega-hal/src/simple_pwm.rs +++ b/mcu/atmega-hal/src/simple_pwm.rs @@ -26,8 +26,8 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer0Pwm { timer: crate::pac::TC0, init: |tim, prescaler| { - tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast()); - tim.tccr0b.modify(|_r, w| match prescaler { + tim.tccr0a().modify(|_r, w| w.wgm0().pwm_fast()); + tim.tccr0b().modify(|_r, w| match prescaler { Prescaler::Direct => w.cs0().direct(), Prescaler::Prescale8 => w.cs0().prescale_8(), Prescaler::Prescale64 => w.cs0().prescale_64(), @@ -39,18 +39,18 @@ avr_hal_generic::impl_simple_pwm! { PD6: { ocr: ocr0a, into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0a().match_clear()); + tim.tccr0a().modify(|_r, w| w.com0a().match_clear()); } else { - tim.tccr0a.modify(|_r, w| w.com0a().disconnected()); + tim.tccr0a().modify(|_r, w| w.com0a().disconnected()); }, }, PD5: { ocr: ocr0b, into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0b().match_clear()); + tim.tccr0a().modify(|_r, w| w.com0b().match_clear()); } else { - tim.tccr0a.modify(|_r, w| w.com0b().disconnected()); + tim.tccr0a().modify(|_r, w| w.com0b().disconnected()); }, }, }, @@ -80,9 +80,9 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer1Pwm { timer: crate::pac::TC1, init: |tim, prescaler| { - tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_r, w| { - w.wgm1().bits(0b01); + tim.tccr1a().modify(|_r, w| w.wgm1().set(0b01)); + tim.tccr1b().modify(|_r, w| { + w.wgm1().set(0b01); match prescaler { Prescaler::Direct => w.cs1().direct(), @@ -97,18 +97,18 @@ avr_hal_generic::impl_simple_pwm! { PB1: { ocr: ocr1a, into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1a().match_clear()); + tim.tccr1a().modify(|_r, w| w.com1a().match_clear()); } else { - tim.tccr1a.modify(|_r, w| w.com1a().disconnected()); + tim.tccr1a().modify(|_r, w| w.com1a().disconnected()); }, }, PB2: { ocr: ocr1b, into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1b().match_clear()); + tim.tccr1a().modify(|_r, w| w.com1b().match_clear()); } else { - tim.tccr1a.modify(|_r, w| w.com1b().disconnected()); + tim.tccr1a().modify(|_r, w| w.com1b().disconnected()); }, }, }, @@ -138,8 +138,8 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer2Pwm { timer: crate::pac::TC2, init: |tim, prescaler| { - tim.tccr2a.modify(|_r, w| w.wgm2().pwm_fast()); - tim.tccr2b.modify(|_r, w| match prescaler { + tim.tccr2a().modify(|_r, w| w.wgm2().pwm_fast()); + tim.tccr2b().modify(|_r, w| match prescaler { Prescaler::Direct => w.cs2().direct(), Prescaler::Prescale8 => w.cs2().prescale_8(), Prescaler::Prescale64 => w.cs2().prescale_64(), @@ -151,18 +151,18 @@ avr_hal_generic::impl_simple_pwm! { PB3: { ocr: ocr2a, into_pwm: |tim| if enable { - tim.tccr2a.modify(|_r, w| w.com2a().match_clear()); + tim.tccr2a().modify(|_r, w| w.com2a().match_clear()); } else { - tim.tccr2a.modify(|_r, w| w.com2a().disconnected()); + tim.tccr2a().modify(|_r, w| w.com2a().disconnected()); }, }, PD3: { ocr: ocr2b, into_pwm: |tim| if enable { - tim.tccr2a.modify(|_r, w| w.com2b().match_clear()); + tim.tccr2a().modify(|_r, w| w.com2b().match_clear()); } else { - tim.tccr2a.modify(|_r, w| w.com2b().disconnected()); + tim.tccr2a().modify(|_r, w| w.com2b().disconnected()); }, }, }, @@ -175,8 +175,8 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer3Pwm { timer: crate::pac::TC3, init: |tim, prescaler| { - tim.tccr3a.modify(|_r, w| w.wgm3().bits(0b01)); - tim.tccr3b.modify(|_r, w| { + tim.tccr3a().modify(|_r, w| w.wgm3().set(0b01)); + tim.tccr3b().modify(|_r, w| { unsafe { w.wgm3().bits(0b01) }; match prescaler { @@ -192,18 +192,18 @@ avr_hal_generic::impl_simple_pwm! { PD0: { ocr: ocr3a, into_pwm: |tim| if enable { - tim.tccr3a.modify(|_r, w| w.com3a().match_clear()); + tim.tccr3a().modify(|_r, w| w.com3a().match_clear()); } else { - tim.tccr3a.modify(|_r, w| w.com3a().disconnected()); + tim.tccr3a().modify(|_r, w| w.com3a().disconnected()); }, }, PD2: { ocr: ocr3b, into_pwm: |tim| if enable { - tim.tccr3a.modify(|_r, w| w.com3b().match_clear()); + tim.tccr3a().modify(|_r, w| w.com3b().match_clear()); } else { - tim.tccr3a.modify(|_r, w| w.com3b().disconnected()); + tim.tccr3a().modify(|_r, w| w.com3b().disconnected()); }, }, }, @@ -216,8 +216,8 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer4Pwm { timer: crate::pac::TC4, init: |tim, prescaler| { - tim.tccr4a.modify(|_r, w| w.wgm4().bits(0b01)); - tim.tccr4b.modify(|_r, w| { + tim.tccr4a().modify(|_r, w| w.wgm4().set(0b01)); + tim.tccr4b().modify(|_r, w| { unsafe { w.wgm4().bits(0b01) }; match prescaler { @@ -233,18 +233,18 @@ avr_hal_generic::impl_simple_pwm! { PD1: { ocr: ocr4a, into_pwm: |tim| if enable { - tim.tccr4a.modify(|_r, w| w.com4a().match_clear()); + tim.tccr4a().modify(|_r, w| w.com4a().match_clear()); } else { - tim.tccr4a.modify(|_r, w| w.com4a().disconnected()); + tim.tccr4a().modify(|_r, w| w.com4a().disconnected()); }, }, PD2: { ocr: ocr4b, into_pwm: |tim| if enable { - tim.tccr4a.modify(|_r, w| w.com4b().match_clear()); + tim.tccr4a().modify(|_r, w| w.com4b().match_clear()); } else { - tim.tccr4a.modify(|_r, w| w.com4b().disconnected()); + tim.tccr4a().modify(|_r, w| w.com4b().disconnected()); }, }, }, @@ -268,8 +268,8 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer0Pwm { timer: crate::pac::TC0, init: |tim, prescaler| { - tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast()); - tim.tccr0b.modify(|_r, w| match prescaler { + tim.tccr0a().modify(|_r, w| w.wgm0().pwm_fast()); + tim.tccr0b().modify(|_r, w| match prescaler { Prescaler::Direct => w.cs0().direct(), Prescaler::Prescale8 => w.cs0().prescale_8(), Prescaler::Prescale64 => w.cs0().prescale_64(), @@ -281,18 +281,18 @@ avr_hal_generic::impl_simple_pwm! { PB7: { ocr: ocr0a, into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0a().match_clear()); + tim.tccr0a().modify(|_r, w| w.com0a().match_clear()); } else { - tim.tccr0a.modify(|_r, w| w.com0a().disconnected()); + tim.tccr0a().modify(|_r, w| w.com0a().disconnected()); }, }, PG5: { ocr: ocr0b, into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0b().match_clear()); + tim.tccr0a().modify(|_r, w| w.com0b().match_clear()); } else { - tim.tccr0a.modify(|_r, w| w.com0b().disconnected()); + tim.tccr0a().modify(|_r, w| w.com0b().disconnected()); }, }, }, @@ -317,8 +317,8 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer1Pwm { timer: crate::pac::TC1, init: |tim, prescaler| { - tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_r, w| match prescaler { + tim.tccr1a().modify(|_r, w| w.wgm1().set(0b01)); + tim.tccr1b().modify(|_r, w| match prescaler { Prescaler::Direct => w.cs1().direct(), Prescaler::Prescale8 => w.cs1().prescale_8(), Prescaler::Prescale64 => w.cs1().prescale_64(), @@ -330,27 +330,27 @@ avr_hal_generic::impl_simple_pwm! { PB5: { ocr: ocr1a, into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1a().match_clear()); + tim.tccr1a().modify(|_r, w| w.com1a().match_clear()); } else { - tim.tccr1a.modify(|_r, w| w.com1a().disconnected()); + tim.tccr1a().modify(|_r, w| w.com1a().disconnected()); }, }, PB6: { ocr: ocr1b, into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1b().match_clear()); + tim.tccr1a().modify(|_r, w| w.com1b().match_clear()); } else { - tim.tccr1a.modify(|_r, w| w.com1b().disconnected()); + tim.tccr1a().modify(|_r, w| w.com1b().disconnected()); }, }, PB7: { ocr: ocr1c, into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1c().match_clear()); + tim.tccr1a().modify(|_r, w| w.com1c().match_clear()); } else { - tim.tccr1a.modify(|_r, w| w.com1c().disconnected()); + tim.tccr1a().modify(|_r, w| w.com1c().disconnected()); }, }, }, @@ -375,8 +375,8 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer2Pwm { timer: crate::pac::TC2, init: |tim, prescaler| { - tim.tccr2a.modify(|_r, w| w.wgm2().bits(0b01)); - tim.tccr2b.modify(|_r, w| { + tim.tccr2a().modify(|_r, w| w.wgm2().set(0b01)); + tim.tccr2b().modify(|_r, w| { w.wgm22().clear_bit(); match prescaler { @@ -392,18 +392,18 @@ avr_hal_generic::impl_simple_pwm! { PB4: { ocr: ocr2a, into_pwm: |tim| if enable { - tim.tccr2a.modify(|_r, w| w.com2a().match_clear()); + tim.tccr2a().modify(|_r, w| w.com2a().match_clear()); } else { - tim.tccr2a.modify(|_r, w| w.com2a().disconnected()); + tim.tccr2a().modify(|_r, w| w.com2a().disconnected()); }, }, PH6: { ocr: ocr2b, into_pwm: |tim| if enable { - tim.tccr2a.modify(|_r, w| w.com2b().match_clear()); + tim.tccr2a().modify(|_r, w| w.com2b().match_clear()); } else { - tim.tccr2a.modify(|_r, w| w.com2b().disconnected()); + tim.tccr2a().modify(|_r, w| w.com2b().disconnected()); }, }, }, @@ -428,9 +428,9 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer3Pwm { timer: crate::pac::TC3, init: |tim, prescaler| { - tim.tccr3a.modify(|_r, w| w.wgm3().bits(0b01)); - tim.tccr3b.modify(|_r, w| { - w.wgm3().bits(0b01); + tim.tccr3a().modify(|_r, w| w.wgm3().set(0b01)); + tim.tccr3b().modify(|_r, w| { + w.wgm3().set(0b01); match prescaler { Prescaler::Direct => w.cs3().direct(), @@ -445,27 +445,27 @@ avr_hal_generic::impl_simple_pwm! { PE3: { ocr: ocr3a, into_pwm: |tim| if enable { - tim.tccr3a.modify(|_r, w| w.com3a().match_clear()); + tim.tccr3a().modify(|_r, w| w.com3a().match_clear()); } else { - tim.tccr3a.modify(|_r, w| w.com3a().disconnected()); + tim.tccr3a().modify(|_r, w| w.com3a().disconnected()); }, }, PE4: { ocr: ocr3b, into_pwm: |tim| if enable { - tim.tccr3a.modify(|_r, w| w.com3b().match_clear()); + tim.tccr3a().modify(|_r, w| w.com3b().match_clear()); } else { - tim.tccr3a.modify(|_r, w| w.com3b().disconnected()); + tim.tccr3a().modify(|_r, w| w.com3b().disconnected()); }, }, PE5: { ocr: ocr3c, into_pwm: |tim| if enable { - tim.tccr3a.modify(|_r, w| w.com3c().match_clear()); + tim.tccr3a().modify(|_r, w| w.com3c().match_clear()); } else { - tim.tccr3a.modify(|_r, w| w.com3c().disconnected()); + tim.tccr3a().modify(|_r, w| w.com3c().disconnected()); }, }, @@ -491,9 +491,9 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer4Pwm { timer: crate::pac::TC4, init: |tim, prescaler| { - tim.tccr4a.modify(|_r, w| w.wgm4().bits(0b01)); - tim.tccr4b.modify(|_r, w| { - w.wgm4().bits(0b01); + tim.tccr4a().modify(|_r, w| w.wgm4().set(0b01)); + tim.tccr4b().modify(|_r, w| { + w.wgm4().set(0b01); match prescaler { Prescaler::Direct => w.cs4().direct(), @@ -508,27 +508,27 @@ avr_hal_generic::impl_simple_pwm! { PH3: { ocr: ocr4a, into_pwm: |tim| if enable { - tim.tccr4a.modify(|_r, w| w.com4a().match_clear()); + tim.tccr4a().modify(|_r, w| w.com4a().match_clear()); } else { - tim.tccr4a.modify(|_r, w| w.com4a().disconnected()); + tim.tccr4a().modify(|_r, w| w.com4a().disconnected()); }, }, PH4: { ocr: ocr4b, into_pwm: |tim| if enable { - tim.tccr4a.modify(|_r, w| w.com4b().match_clear()); + tim.tccr4a().modify(|_r, w| w.com4b().match_clear()); } else { - tim.tccr4a.modify(|_r, w| w.com4b().disconnected()); + tim.tccr4a().modify(|_r, w| w.com4b().disconnected()); }, }, PH5: { ocr: ocr4c, into_pwm: |tim| if enable { - tim.tccr4a.modify(|_r, w| w.com4c().match_clear()); + tim.tccr4a().modify(|_r, w| w.com4c().match_clear()); } else { - tim.tccr4a.modify(|_r, w| w.com4c().disconnected()); + tim.tccr4a().modify(|_r, w| w.com4c().disconnected()); }, }, @@ -554,9 +554,9 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer5Pwm { timer: crate::pac::TC5, init: |tim, prescaler| { - tim.tccr5a.modify(|_r, w| w.wgm5().bits(0b01)); - tim.tccr5b.modify(|_r, w| { - w.wgm5().bits(0b01); + tim.tccr5a().modify(|_r, w| w.wgm5().set(0b01)); + tim.tccr5b().modify(|_r, w| { + w.wgm5().set(0b01); match prescaler { Prescaler::Direct => w.cs5().direct(), @@ -571,27 +571,27 @@ avr_hal_generic::impl_simple_pwm! { PL3: { ocr: ocr5a, into_pwm: |tim| if enable { - tim.tccr5a.modify(|_r, w| w.com5a().match_clear()); + tim.tccr5a().modify(|_r, w| w.com5a().match_clear()); } else { - tim.tccr5a.modify(|_r, w| w.com5a().disconnected()); + tim.tccr5a().modify(|_r, w| w.com5a().disconnected()); }, }, PL4: { ocr: ocr5b, into_pwm: |tim| if enable { - tim.tccr5a.modify(|_r, w| w.com5b().match_clear()); + tim.tccr5a().modify(|_r, w| w.com5b().match_clear()); } else { - tim.tccr5a.modify(|_r, w| w.com5b().disconnected()); + tim.tccr5a().modify(|_r, w| w.com5b().disconnected()); }, }, PL5: { ocr: ocr5c, into_pwm: |tim| if enable { - tim.tccr5a.modify(|_r, w| w.com5c().match_clear()); + tim.tccr5a().modify(|_r, w| w.com5c().match_clear()); } else { - tim.tccr5a.modify(|_r, w| w.com5c().disconnected()); + tim.tccr5a().modify(|_r, w| w.com5c().disconnected()); }, }, @@ -616,8 +616,8 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer0Pwm { timer: crate::pac::TC0, init: |tim, prescaler| { - tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast()); - tim.tccr0b.modify(|_r, w| match prescaler { + tim.tccr0a().modify(|_r, w| w.wgm0().pwm_fast()); + tim.tccr0b().modify(|_r, w| match prescaler { Prescaler::Direct => w.cs0().direct(), Prescaler::Prescale8 => w.cs0().prescale_8(), Prescaler::Prescale64 => w.cs0().prescale_64(), @@ -629,18 +629,18 @@ avr_hal_generic::impl_simple_pwm! { PB7: { ocr: ocr0a, into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0a().match_clear()); + tim.tccr0a().modify(|_r, w| w.com0a().match_clear()); } else { - tim.tccr0a.modify(|_r, w| w.com0a().disconnected()); + tim.tccr0a().modify(|_r, w| w.com0a().disconnected()); }, }, PD0: { ocr: ocr0b, into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0b().match_clear()); + tim.tccr0a().modify(|_r, w| w.com0b().match_clear()); } else { - tim.tccr0a.modify(|_r, w| w.com0b().disconnected()); + tim.tccr0a().modify(|_r, w| w.com0b().disconnected()); }, }, }, @@ -665,10 +665,10 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer1Pwm { timer: crate::pac::TC1, init: |tim, prescaler| { - tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_r, w| w.wgm1().bits(0b01)); + tim.tccr1a().modify(|_r, w| w.wgm1().set(0b01)); + tim.tccr1b().modify(|_r, w| w.wgm1().set(0b01)); - tim.tccr1b.modify(|_r, w| match prescaler { + tim.tccr1b().modify(|_r, w| match prescaler { Prescaler::Direct => w.cs1().direct(), Prescaler::Prescale8 => w.cs1().prescale_8(), Prescaler::Prescale64 => w.cs1().prescale_64(), @@ -680,27 +680,27 @@ avr_hal_generic::impl_simple_pwm! { PB5: { ocr: ocr1a, into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1a().match_clear()); + tim.tccr1a().modify(|_r, w| w.com1a().match_clear()); } else { - tim.tccr1a.modify(|_r, w| w.com1a().disconnected()); + tim.tccr1a().modify(|_r, w| w.com1a().disconnected()); }, }, PB6: { ocr: ocr1b, into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1b().match_clear()); + tim.tccr1a().modify(|_r, w| w.com1b().match_clear()); } else { - tim.tccr1a.modify(|_r, w| w.com1b().disconnected()); + tim.tccr1a().modify(|_r, w| w.com1b().disconnected()); }, }, PB7: { ocr: ocr1c, into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1c().match_clear()); + tim.tccr1a().modify(|_r, w| w.com1c().match_clear()); } else { - tim.tccr1a.modify(|_r, w| w.com1c().disconnected()); + tim.tccr1a().modify(|_r, w| w.com1c().disconnected()); }, }, }, @@ -723,10 +723,10 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer3Pwm { timer: crate::pac::TC3, init: |tim, prescaler| { - tim.tccr3a.modify(|_r, w| w.wgm3().bits(0b01)); - tim.tccr3b.modify(|_r, w| w.wgm3().bits(0b01)); + tim.tccr3a().modify(|_r, w| w.wgm3().set(0b01)); + tim.tccr3b().modify(|_r, w| w.wgm3().set(0b01)); - tim.tccr3b.modify(|_r, w| match prescaler { + tim.tccr3b().modify(|_r, w| match prescaler { Prescaler::Direct => w.cs3().direct(), Prescaler::Prescale8 => w.cs3().prescale_8(), Prescaler::Prescale64 => w.cs3().prescale_64(), @@ -738,9 +738,9 @@ avr_hal_generic::impl_simple_pwm! { PC6: { ocr: ocr3a, into_pwm: |tim| if enable { - tim.tccr3a.modify(|_r, w| w.com3a().match_clear()); + tim.tccr3a().modify(|_r, w| w.com3a().match_clear()); } else { - tim.tccr3a.modify(|_r, w| w.com3a().disconnected()); + tim.tccr3a().modify(|_r, w| w.com3a().disconnected()); }, }, }, @@ -765,11 +765,11 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer4Pwm { timer: crate::pac::TC4, init: |tim, prescaler| { - tim.tccr4a.modify(|_r, w| w.pwm4a().set_bit()); - tim.tccr4a.modify(|_r, w| w.pwm4b().set_bit()); - tim.tccr4c.modify(|_r, w| w.pwm4d().set_bit()); + tim.tccr4a().modify(|_r, w| w.pwm4a().set_bit()); + tim.tccr4a().modify(|_r, w| w.pwm4b().set_bit()); + tim.tccr4c().modify(|_r, w| w.pwm4d().set_bit()); - tim.tccr4b.modify(|_r, w| match prescaler { + tim.tccr4b().modify(|_r, w| match prescaler { Prescaler::Direct => w.cs4().direct(), Prescaler::Prescale8 => w.cs4().prescale_8(), Prescaler::Prescale64 => w.cs4().prescale_64(), @@ -781,27 +781,27 @@ avr_hal_generic::impl_simple_pwm! { PB6: { ocr: ocr4b, into_pwm: |tim| if enable { - tim.tccr4a.modify(|_r, w| w.com4b().match_clear()); + tim.tccr4a().modify(|_r, w| w.com4b().match_clear()); } else { - tim.tccr4a.modify(|_r, w| w.com4b().disconnected()); + tim.tccr4a().modify(|_r, w| w.com4b().disconnected()); }, }, PC7: { ocr: ocr4a, into_pwm: |tim| if enable { - tim.tccr4a.modify(|_r, w| w.com4a().match_clear()); + tim.tccr4a().modify(|_r, w| w.com4a().match_clear()); } else { - tim.tccr4a.modify(|_r, w| w.com4a().disconnected()); + tim.tccr4a().modify(|_r, w| w.com4a().disconnected()); }, }, PD7: { ocr: ocr4d, into_pwm: |tim| if enable { - tim.tccr4c.modify(|_r, w| w.com4d().match_clear()); + tim.tccr4c().modify(|_r, w| w.com4d().match_clear()); } else { - tim.tccr4c.modify(|_r, w| w.com4d().disconnected()); + tim.tccr4c().modify(|_r, w| w.com4d().disconnected()); }, }, }, @@ -825,8 +825,8 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer0Pwm { timer: crate::pac::TC0, init: |tim, prescaler| { - tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast()); - tim.tccr0b.modify(|_r, w| match prescaler { + tim.tccr0a().modify(|_r, w| w.wgm0().pwm_fast()); + tim.tccr0b().modify(|_r, w| match prescaler { Prescaler::Direct => w.cs0().direct(), Prescaler::Prescale8 => w.cs0().prescale_8(), Prescaler::Prescale64 => w.cs0().prescale_64(), @@ -838,18 +838,18 @@ avr_hal_generic::impl_simple_pwm! { PB3: { ocr: ocr0a, into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0a().match_clear()); + tim.tccr0a().modify(|_r, w| w.com0a().match_clear()); } else { - tim.tccr0a.modify(|_r, w| w.com0a().disconnected()); + tim.tccr0a().modify(|_r, w| w.com0a().disconnected()); }, }, PB4: { ocr: ocr0b, into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0b().match_clear()); + tim.tccr0a().modify(|_r, w| w.com0b().match_clear()); } else { - tim.tccr0a.modify(|_r, w| w.com0b().disconnected()); + tim.tccr0a().modify(|_r, w| w.com0b().disconnected()); }, }, }, @@ -873,9 +873,9 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer1Pwm { timer: crate::pac::TC1, init: |tim, prescaler| { - tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_r, w| { - w.wgm1().bits(0b01); + tim.tccr1a().modify(|_r, w| w.wgm1().set(0b01)); + tim.tccr1b().modify(|_r, w| { + w.wgm1().set(0b01); match prescaler { Prescaler::Direct => w.cs1().direct(), @@ -890,18 +890,18 @@ avr_hal_generic::impl_simple_pwm! { PD5: { ocr: ocr1a, into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1a().match_clear()); + tim.tccr1a().modify(|_r, w| w.com1a().match_clear()); } else { - tim.tccr1a.modify(|_r, w| w.com1a().disconnected()); + tim.tccr1a().modify(|_r, w| w.com1a().disconnected()); }, }, PD4: { ocr: ocr1b, into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1b().match_clear()); + tim.tccr1a().modify(|_r, w| w.com1b().match_clear()); } else { - tim.tccr1a.modify(|_r, w| w.com1b().disconnected()); + tim.tccr1a().modify(|_r, w| w.com1b().disconnected()); }, }, }, @@ -925,8 +925,8 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer2Pwm { timer: crate::pac::TC2, init: |tim, prescaler| { - tim.tccr2a.modify(|_r, w| w.wgm2().pwm_fast()); - tim.tccr2b.modify(|_r, w| match prescaler { + tim.tccr2a().modify(|_r, w| w.wgm2().pwm_fast()); + tim.tccr2b().modify(|_r, w| match prescaler { Prescaler::Direct => w.cs2().direct(), Prescaler::Prescale8 => w.cs2().prescale_8(), Prescaler::Prescale64 => w.cs2().prescale_64(), @@ -938,18 +938,18 @@ avr_hal_generic::impl_simple_pwm! { PD7: { ocr: ocr2a, into_pwm: |tim| if enable { - tim.tccr2a.modify(|_r, w| w.com2a().match_clear()); + tim.tccr2a().modify(|_r, w| w.com2a().match_clear()); } else { - tim.tccr2a.modify(|_r, w| w.com2a().disconnected()); + tim.tccr2a().modify(|_r, w| w.com2a().disconnected()); }, }, PD6: { ocr: ocr2b, into_pwm: |tim| if enable { - tim.tccr2a.modify(|_r, w| w.com2b().match_clear()); + tim.tccr2a().modify(|_r, w| w.com2b().match_clear()); } else { - tim.tccr2a.modify(|_r, w| w.com2b().disconnected()); + tim.tccr2a().modify(|_r, w| w.com2b().disconnected()); }, }, }, @@ -962,9 +962,9 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer3Pwm { timer: crate::pac::TC3, init: |tim, prescaler| { - tim.tccr3a.modify(|_r, w| w.wgm3().bits(0b01)); - tim.tccr3b.modify(|_r, w| { - w.wgm3().bits(0b01); + tim.tccr3a().modify(|_r, w| w.wgm3().set(0b01)); + tim.tccr3b().modify(|_r, w| { + w.wgm3().set(0b01); match prescaler { Prescaler::Direct => w.cs3().direct(), @@ -979,18 +979,18 @@ avr_hal_generic::impl_simple_pwm! { PB6: { ocr: ocr3a, into_pwm: |tim| if enable { - tim.tccr3a.modify(|_r, w| w.com3a().match_clear()); + tim.tccr3a().modify(|_r, w| w.com3a().match_clear()); } else { - tim.tccr3a.modify(|_r, w| w.com3a().disconnected()); + tim.tccr3a().modify(|_r, w| w.com3a().disconnected()); }, }, PB7: { ocr: ocr3b, into_pwm: |tim| if enable { - tim.tccr3a.modify(|_r, w| w.com3b().match_clear()); + tim.tccr3a().modify(|_r, w| w.com3b().match_clear()); } else { - tim.tccr3a.modify(|_r, w| w.com3b().disconnected()); + tim.tccr3a().modify(|_r, w| w.com3b().disconnected()); }, }, }, @@ -1014,9 +1014,9 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer1Pwm { timer: crate::pac::TC1, init: |tim, prescaler| { - tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_r, w| { - w.wgm1().bits(0b01); + tim.tccr1a().modify(|_r, w| w.wgm1().set(0b01)); + tim.tccr1b().modify(|_r, w| { + w.wgm1().set(0b01); match prescaler { Prescaler::Direct => w.cs1().direct(), @@ -1031,18 +1031,18 @@ avr_hal_generic::impl_simple_pwm! { PB1: { ocr: ocr1a, into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1a().match_clear()); + tim.tccr1a().modify(|_r, w| w.com1a().match_clear()); } else { - tim.tccr1a.modify(|_r, w| w.com1a().disconnected()); + tim.tccr1a().modify(|_r, w| w.com1a().disconnected()); }, }, PB2: { ocr: ocr1b, into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1b().match_clear()); + tim.tccr1a().modify(|_r, w| w.com1b().match_clear()); } else { - tim.tccr1a.modify(|_r, w| w.com1b().disconnected()); + tim.tccr1a().modify(|_r, w| w.com1b().disconnected()); }, }, }, @@ -1066,8 +1066,8 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer2Pwm { timer: crate::pac::TC2, init: |tim, prescaler| { - tim.tccr2.modify(|_r, w| w.wgm20().set_bit().wgm21().set_bit()); - tim.tccr2.modify(|_r, w| match prescaler { + tim.tccr2().modify(|_r, w| w.wgm20().set_bit().wgm21().set_bit()); + tim.tccr2().modify(|_r, w| match prescaler { Prescaler::Direct => w.cs2().direct(), Prescaler::Prescale8 => w.cs2().prescale_8(), Prescaler::Prescale64 => w.cs2().prescale_64(), @@ -1079,9 +1079,9 @@ avr_hal_generic::impl_simple_pwm! { PB3: { ocr: ocr2, into_pwm: |tim| if enable { - tim.tccr2.modify(|_r, w| w.com2().match_clear()); + tim.tccr2().modify(|_r, w| w.com2().match_clear()); } else { - tim.tccr2.modify(|_r, w| w.com2().disconnected()); + tim.tccr2().modify(|_r, w| w.com2().disconnected()); }, }, }, @@ -1104,10 +1104,10 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer0Pwm { timer: crate::pac::TC0, init: |tim, prescaler| { - tim.tccr0a.modify(|_r, w| w.wgm0().bits(0b11)); - tim.tccr0a.modify(|_r, w| w.com0a().bits(0b00)); + tim.tccr0a().modify(|_r, w| w.wgm0().set(0b11)); + tim.tccr0a().modify(|_r, w| w.com0a().set(0b00)); - tim.tccr0b.modify(|_r, w| match prescaler { + tim.tccr0b().modify(|_r, w| match prescaler { Prescaler::Direct => w.cs0().running_no_prescaling(), Prescaler::Prescale8 => w.cs0().running_clk_8(), Prescaler::Prescale64 => w.cs0().running_clk_64(), @@ -1119,9 +1119,9 @@ avr_hal_generic::impl_simple_pwm! { PB3: { ocr: ocr0a, into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0a().bits(0b11)); + tim.tccr0a().modify(|_r, w| w.com0a().set(0b11)); } else { - tim.tccr0a.modify(|_r, w| w.com0a().bits(0b00)); + tim.tccr0a().modify(|_r, w| w.com0a().set(0b00)); }, }, }, @@ -1147,11 +1147,11 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer1Pwm { timer: crate::pac::TC1, init: |tim, prescaler| { - tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); - tim.tccr1a.modify(|_r, w| w.com1a().bits(0b00)); - tim.tccr1a.modify(|_r, w| w.com1b().bits(0b00)); + tim.tccr1a().modify(|_r, w| w.wgm1().set(0b01)); + tim.tccr1a().modify(|_r, w| w.com1a().set(0b00)); + tim.tccr1a().modify(|_r, w| w.com1b().set(0b00)); #[cfg(any(feature = "atmega164pa"))] - tim.tccr1b.modify(|_r, w| match prescaler { + tim.tccr1b().modify(|_r, w| match prescaler { Prescaler::Direct => w.cs1().running_no_prescaling(), Prescaler::Prescale8 => w.cs1().running_clk_8(), Prescaler::Prescale64 => w.cs1().running_clk_64(), @@ -1171,17 +1171,17 @@ avr_hal_generic::impl_simple_pwm! { PD4: { ocr: ocr1a, into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1a().bits(0b11)); + tim.tccr1a().modify(|_r, w| w.com1a().set(0b11)); } else { - tim.tccr1a.modify(|_r, w| w.com1a().bits(0b00)); + tim.tccr1a().modify(|_r, w| w.com1a().set(0b00)); }, }, PD5: { ocr: ocr1b, into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1b().bits(0b11)); + tim.tccr1a().modify(|_r, w| w.com1b().set(0b11)); } else { - tim.tccr1a.modify(|_r, w| w.com1b().bits(0b00)); + tim.tccr1a().modify(|_r, w| w.com1b().set(0b00)); }, }, }, diff --git a/mcu/atmega-hal/src/usart.rs b/mcu/atmega-hal/src/usart.rs index 6f630fcfd3..5c1bd09d10 100644 --- a/mcu/atmega-hal/src/usart.rs +++ b/mcu/atmega-hal/src/usart.rs @@ -197,13 +197,13 @@ impl // msb of ubrrh has to be 0 to set ubrrh register. (see atmega8 datasheet) let ubrrh: u8 = ((baudrate.ubrr >> 8) & 0x0F) as u8; let ubrrl: u8 = (baudrate.ubrr & 0xFF) as u8; - self.ubrrh().write(|w| w.bits(ubrrh)); - self.ubrrl.write(|w| w.bits(ubrrl)); - self.ucsra.write(|w| w.u2x().bit(baudrate.u2x)); + self.ubrrh().write(|w| w.set(ubrrh)); + self.ubrrl().write(|w| w.set(ubrrl)); + self.ucsra().write(|w| w.u2x().bit(baudrate.u2x)); // Enable receiver and transmitter but leave interrupts disabled. #[rustfmt::skip] - self.ucsrb.write(|w| w + self.ucsrb().write(|w| w .txen().set_bit() .rxen().set_bit() ); @@ -223,11 +223,11 @@ impl fn raw_deinit(&mut self) { // Wait for any ongoing transfer to finish. avr_hal_generic::nb::block!(self.raw_flush()).ok(); - self.ucsrb.reset(); + self.ucsrb().reset(); } fn raw_flush(&mut self) -> avr_hal_generic::nb::Result<(), core::convert::Infallible> { - if self.ucsra.read().udre().bit_is_clear() { + if self.ucsra().read().udre().bit_is_clear() { Err(avr_hal_generic::nb::Error::WouldBlock) } else { Ok(()) @@ -241,24 +241,24 @@ impl // Call flush to make sure the data-register is empty self.raw_flush()?; - self.udr.write(|w| w.bits(byte)); + self.udr().write(|w| w.set(byte)); Ok(()) } fn raw_read(&mut self) -> avr_hal_generic::nb::Result { - if self.ucsra.read().rxc().bit_is_clear() { + if self.ucsra().read().rxc().bit_is_clear() { return Err(avr_hal_generic::nb::Error::WouldBlock); } - Ok(self.udr.read().bits()) + Ok(self.udr().read().bits()) } fn raw_interrupt(&mut self, event: crate::usart::Event, state: bool) { match event { - crate::usart::Event::RxComplete => self.ucsrb.modify(|_, w| w.rxcie().bit(state)), - crate::usart::Event::TxComplete => self.ucsrb.modify(|_, w| w.txcie().bit(state)), + crate::usart::Event::RxComplete => self.ucsrb().modify(|_, w| w.rxcie().bit(state)), + crate::usart::Event::TxComplete => self.ucsrb().modify(|_, w| w.txcie().bit(state)), crate::usart::Event::DataRegisterEmpty => { - self.ucsrb.modify(|_, w| w.udrie().bit(state)) + self.ucsrb().modify(|_, w| w.udrie().bit(state)) } } } @@ -277,13 +277,13 @@ impl fn raw_init(&mut self, baudrate: crate::usart::Baudrate) { let ubrr1h: u8 = (baudrate.ubrr >> 8) as u8; let ubrr1l: u8 = baudrate.ubrr as u8; - self.ubrr1h.write(|w| w.bits(ubrr1h)); - self.ubrr1l.write(|w| w.bits(ubrr1l)); - self.ucsr1a.write(|w| w.u2x1().bit(baudrate.u2x)); + self.ubrr1h().write(|w| w.set(ubrr1h)); + self.ubrr1l().write(|w| w.set(ubrr1l)); + self.ucsr1a().write(|w| w.u2x1().bit(baudrate.u2x)); // Enable receiver and transmitter but leave interrupts disabled. #[rustfmt::skip] - self.ucsr1b.write(|w| w + self.ucsr1b().write(|w| w .txen1().set_bit() .rxen1().set_bit() ); @@ -291,7 +291,7 @@ impl // Set frame format to 8n1 for now. At some point, this should be made // configurable, similar to what is done in other HALs. #[rustfmt::skip] - self.ucsr1c.write(|w| w + self.ucsr1c().write(|w| w .umsel1().usart_async() .ucsz1().chr8() .usbs1().stop1() @@ -302,11 +302,11 @@ impl fn raw_deinit(&mut self) { // Wait for any ongoing transfer to finish. avr_hal_generic::nb::block!(self.raw_flush()).ok(); - self.ucsr1b.reset(); + self.ucsr1b().reset(); } fn raw_flush(&mut self) -> avr_hal_generic::nb::Result<(), core::convert::Infallible> { - if self.ucsr1a.read().udre1().bit_is_clear() { + if self.ucsr1a().read().udre1().bit_is_clear() { Err(avr_hal_generic::nb::Error::WouldBlock) } else { Ok(()) @@ -320,24 +320,24 @@ impl // Call flush to make sure the data-register is empty self.raw_flush()?; - self.udr1.write(|w| w.bits(byte)); + self.udr1().write(|w| w.set(byte)); Ok(()) } fn raw_read(&mut self) -> avr_hal_generic::nb::Result { - if self.ucsr1a.read().rxc1().bit_is_clear() { + if self.ucsr1a().read().rxc1().bit_is_clear() { return Err(avr_hal_generic::nb::Error::WouldBlock); } - Ok(self.udr1.read().bits()) + Ok(self.udr1().read().bits()) } fn raw_interrupt(&mut self, event: crate::usart::Event, state: bool) { match event { - crate::usart::Event::RxComplete => self.ucsr1b.modify(|_, w| w.rxcie1().bit(state)), - crate::usart::Event::TxComplete => self.ucsr1b.modify(|_, w| w.txcie1().bit(state)), + crate::usart::Event::RxComplete => self.ucsr1b().modify(|_, w| w.rxcie1().bit(state)), + crate::usart::Event::TxComplete => self.ucsr1b().modify(|_, w| w.txcie1().bit(state)), crate::usart::Event::DataRegisterEmpty => { - self.ucsr1b.modify(|_, w| w.udrie1().bit(state)) + self.ucsr1b().modify(|_, w| w.udrie1().bit(state)) } } } @@ -357,17 +357,18 @@ impl fn raw_init(&mut self, baudrate: crate::usart::Baudrate) { let ubrr0h: u8 = (baudrate.ubrr >> 8) as u8; let ubrr0l: u8 = baudrate.ubrr as u8; - self.ubrr0h.write(|w| w.bits(ubrr0h)); - self.ubrr0l.write(|w| w.bits(ubrr0l)); - self.ucsr0a.write(|w| w.u2x0().bit(baudrate.u2x)); + self.ubrr0h().write(|w| w.set(ubrr0h)); + self.ubrr0l().write(|w| w.set(ubrr0l)); + self.ucsr0a().write(|w| w.u2x0().bit(baudrate.u2x)); // Enable receiver and transmitter but leave interrupts disabled. - self.ucsr0b.write(|w| w.txen0().set_bit().rxen0().set_bit()); + self.ucsr0b() + .write(|w| w.txen0().set_bit().rxen0().set_bit()); // Set frame format to 8n1 for now. At some point, this should be made // configurable, similar to what is done in other HALs. #[rustfmt::skip] - self.ucsr0c.write(|w| w + self.ucsr0c().write(|w| w .umsel0().usart_async() .ucsz0().chr8() .usbs0().stop1() @@ -378,11 +379,11 @@ impl fn raw_deinit(&mut self) { // Wait for any ongoing transfer to finish. avr_hal_generic::nb::block!(self.raw_flush()).ok(); - self.ucsr0b.reset(); + self.ucsr0b().reset(); } fn raw_flush(&mut self) -> avr_hal_generic::nb::Result<(), core::convert::Infallible> { - if self.ucsr0a.read().udre0().bit_is_clear() { + if self.ucsr0a().read().udre0().bit_is_clear() { Err(avr_hal_generic::nb::Error::WouldBlock) } else { Ok(()) @@ -396,24 +397,24 @@ impl // Call flush to make sure the data-register is empty self.raw_flush()?; - self.udr0.write(|w| w.bits(byte)); + self.udr0().write(|w| w.set(byte)); Ok(()) } fn raw_read(&mut self) -> avr_hal_generic::nb::Result { - if self.ucsr0a.read().rxc0().bit_is_clear() { + if self.ucsr0a().read().rxc0().bit_is_clear() { return Err(avr_hal_generic::nb::Error::WouldBlock); } - Ok(self.udr0.read().bits()) + Ok(self.udr0().read().bits()) } fn raw_interrupt(&mut self, event: crate::usart::Event, state: bool) { match event { - crate::usart::Event::RxComplete => self.ucsr0b.modify(|_, w| w.rxcie0().bit(state)), - crate::usart::Event::TxComplete => self.ucsr0b.modify(|_, w| w.txcie0().bit(state)), + crate::usart::Event::RxComplete => self.ucsr0b().modify(|_, w| w.rxcie0().bit(state)), + crate::usart::Event::TxComplete => self.ucsr0b().modify(|_, w| w.txcie0().bit(state)), crate::usart::Event::DataRegisterEmpty => { - self.ucsr0b.modify(|_, w| w.udrie0().bit(state)) + self.ucsr0b().modify(|_, w| w.udrie0().bit(state)) } } } diff --git a/mcu/attiny-hal/src/adc.rs b/mcu/attiny-hal/src/adc.rs index 0856312086..8b422b59f3 100644 --- a/mcu/attiny-hal/src/adc.rs +++ b/mcu/attiny-hal/src/adc.rs @@ -87,7 +87,7 @@ pub mod channel { } fn apply_clock(peripheral: &crate::pac::ADC, settings: AdcSettings) { - peripheral.adcsra.write(|w| { + peripheral.adcsra().write(|w| { w.aden().set_bit(); match settings.clock_divider { ClockDivider::Factor2 => w.adps().prescaler_2(), @@ -108,7 +108,7 @@ avr_hal_generic::impl_adc! { settings: AdcSettings, apply_settings: |peripheral, settings| { apply_clock(peripheral, settings); - peripheral.admux.write(|w| match settings.ref_voltage { + peripheral.admux().write(|w| match settings.ref_voltage { ReferenceVoltage::Aref => w.refs().aref(), ReferenceVoltage::AVcc => w.refs().vcc(), ReferenceVoltage::Internal1_1 => w.refs().internal().refs2().clear_bit(), @@ -117,7 +117,7 @@ avr_hal_generic::impl_adc! { }, channel_id: crate::pac::adc::admux::MUX_A, set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); + peripheral.admux().modify(|_, w| w.mux().variant(id)); }, pins: { port::PB5: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), @@ -139,14 +139,14 @@ avr_hal_generic::impl_adc! { settings: AdcSettings, apply_settings: |peripheral, settings| { apply_clock(peripheral, settings); - peripheral.admux.write(|w| match settings.ref_voltage { + peripheral.admux().write(|w| match settings.ref_voltage { ReferenceVoltage::AVcc => w.refs0().avcc(), ReferenceVoltage::Internal1_1 => w.refs0().internal(), }); }, channel_id: crate::pac::adc::admux::MUX_A, set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); + peripheral.admux().modify(|_, w| w.mux().variant(id)); }, pins: { port::PC0: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), @@ -172,11 +172,11 @@ avr_hal_generic::impl_adc! { settings: AdcSettings, apply_settings: |peripheral, settings| { apply_clock(peripheral, settings); - peripheral.amiscr.write(|w| match settings.ref_voltage { + peripheral.amiscr().write(|w| match settings.ref_voltage { ReferenceVoltage::Aref => w.arefen().set_bit(), _ => w.arefen().clear_bit(), }); - peripheral.admux.write(|w| match settings.ref_voltage { + peripheral.admux().write(|w| match settings.ref_voltage { ReferenceVoltage::Aref => w.refs().avcc(), ReferenceVoltage::AVcc => w.refs().avcc(), ReferenceVoltage::Internal1_1 => w.refs().internal_11(), @@ -185,7 +185,7 @@ avr_hal_generic::impl_adc! { }, channel_id: crate::pac::adc::admux::MUX_A, set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); + peripheral.admux().modify(|_, w| w.mux().variant(id)); }, pins: { port::PA0: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), diff --git a/mcu/attiny-hal/src/eeprom.rs b/mcu/attiny-hal/src/eeprom.rs index f325215dfb..85da367d45 100644 --- a/mcu/attiny-hal/src/eeprom.rs +++ b/mcu/attiny-hal/src/eeprom.rs @@ -29,7 +29,7 @@ avr_hal_generic::impl_eeprom_attiny! { capacity: 128, addr_width: u8, set_address: |peripheral, address| { - peripheral.eear.write(|w| w.bits(address)); + peripheral.eear().write(|w| w.bits(address)); }, } @@ -40,7 +40,7 @@ avr_hal_generic::impl_eeprom_attiny! { capacity: 512, addr_width: u16, set_address: |peripheral, address| { - peripheral.eear.write(|w| w.bits(address)); + peripheral.eear().write(|w| w.bits(address)); }, } @@ -51,6 +51,6 @@ avr_hal_generic::impl_eeprom_attiny! { capacity: 64, addr_width: u8, set_address: |peripheral, address| { - peripheral.eearl.write(|w| w.bits(address)); + peripheral.eearl().write(|w| w.bits(address)); }, } diff --git a/mcu/attiny-hal/src/simple_pwm.rs b/mcu/attiny-hal/src/simple_pwm.rs index f16a89c9c0..960032c0ad 100644 --- a/mcu/attiny-hal/src/simple_pwm.rs +++ b/mcu/attiny-hal/src/simple_pwm.rs @@ -9,8 +9,8 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer0Pwm { timer: crate::pac::TC0, init: |tim, prescaler| { - tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast()); - tim.tccr0b.modify(|_r, w| match prescaler { + tim.tccr0a().modify(|_r, w| w.wgm0().pwm_fast()); + tim.tccr0b().modify(|_r, w| match prescaler { Prescaler::Direct => w.cs0().direct(), Prescaler::Prescale8 => w.cs0().prescale_8(), Prescaler::Prescale64 => w.cs0().prescale_64(), @@ -22,18 +22,18 @@ avr_hal_generic::impl_simple_pwm! { PB2: { ocr: ocr0a, into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0a().match_clear()); + tim.tccr0a().modify(|_r, w| w.com0a().match_clear()); } else { - tim.tccr0a.modify(|_r, w| w.com0a().disconnected()); + tim.tccr0a().modify(|_r, w| w.com0a().disconnected()); }, }, PA7: { ocr: ocr0b, into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0b().match_clear()); + tim.tccr0a().modify(|_r, w| w.com0b().match_clear()); } else { - tim.tccr0a.modify(|_r, w| w.com0b().disconnected()); + tim.tccr0a().modify(|_r, w| w.com0b().disconnected()); }, }, }, @@ -46,10 +46,10 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer1Pwm { timer: crate::pac::TC1, init: |tim, prescaler| { - tim.tccr1a.modify(|_, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_, w| w.wgm1().bits(0b01)); + tim.tccr1a().modify(|_, w| w.wgm1().set(0b01)); + tim.tccr1b().modify(|_, w| w.wgm1().set(0b01)); - tim.tccr1b.modify(|_r, w| match prescaler { + tim.tccr1b().modify(|_r, w| match prescaler { Prescaler::Direct => w.cs1().direct(), Prescaler::Prescale8 => w.cs1().prescale_8(), Prescaler::Prescale64 => w.cs1().prescale_64(), @@ -61,18 +61,18 @@ avr_hal_generic::impl_simple_pwm! { PA6: { ocr: ocr1a, into_pwm: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1a().bits(0b10)); + tim.tccr1a().modify(|_, w| w.com1a().set(0b10)); } else { - tim.tccr1a.modify(|_, w| w.com1a().disconnected()); + tim.tccr1a().modify(|_, w| w.com1a().disconnected()); }, }, PA5: { ocr: ocr1b, into_pwm: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1b().bits(0b10)); + tim.tccr1a().modify(|_, w| w.com1b().set(0b10)); } else { - tim.tccr1a.modify(|_, w| w.com1b().disconnected()); + tim.tccr1a().modify(|_, w| w.com1b().disconnected()); }, }, }, @@ -96,8 +96,8 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer0Pwm { timer: crate::pac::TC0, init: |tim, prescaler| { - tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast()); - tim.tccr0b.modify(|_r, w| match prescaler { + tim.tccr0a().modify(|_r, w| w.wgm0().pwm_fast()); + tim.tccr0b().modify(|_r, w| match prescaler { Prescaler::Direct => w.cs0().direct(), Prescaler::Prescale8 => w.cs0().prescale_8(), Prescaler::Prescale64 => w.cs0().prescale_64(), @@ -109,18 +109,18 @@ avr_hal_generic::impl_simple_pwm! { PB0: { ocr: ocr0a, into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0a().match_clear()); + tim.tccr0a().modify(|_r, w| w.com0a().match_clear()); } else { - tim.tccr0a.modify(|_r, w| w.com0a().disconnected()); + tim.tccr0a().modify(|_r, w| w.com0a().disconnected()); }, }, PB1: { ocr: ocr0b, into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0b().match_clear()); + tim.tccr0a().modify(|_r, w| w.com0b().match_clear()); } else { - tim.tccr0a.modify(|_r, w| w.com0b().disconnected()); + tim.tccr0a().modify(|_r, w| w.com0b().disconnected()); }, }, }, @@ -143,9 +143,9 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer1Pwm { timer: crate::pac::TC1, init: |tim, prescaler| { - tim.gtccr.modify(|_, w| w.pwm1b().bit(true)); + tim.gtccr().modify(|_, w| w.pwm1b().bit(true)); - tim.tccr1.modify(|_r, w| match prescaler { + tim.tccr1().modify(|_r, w| match prescaler { Prescaler::Direct => w.cs1().direct(), Prescaler::Prescale8 => w.cs1().prescale_8(), Prescaler::Prescale64 => w.cs1().prescale_64(), @@ -157,9 +157,9 @@ avr_hal_generic::impl_simple_pwm! { PB4: { ocr: ocr1b, into_pwm: |tim| if enable { - tim.gtccr.modify(|_, w| w.com1b().bits(0b10)); + tim.gtccr().modify(|_, w| w.com1b().set(0b10)); } else { - tim.gtccr.modify(|_, w| w.com1b().disconnected()); + tim.gtccr().modify(|_, w| w.com1b().disconnected()); }, }, }, @@ -183,10 +183,10 @@ avr_hal_generic::impl_simple_pwm! { pub struct Timer1Pwm { timer: crate::pac::TC1, init: |tim, prescaler| { - tim.tccr1a.modify(|_, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_, w| w.wgm1().bits(0b01)); + tim.tccr1a().modify(|_, w| w.wgm1().set(0b01)); + tim.tccr1b().modify(|_, w| w.wgm1().set(0b01)); - tim.tccr1b.modify(|_r, w| match prescaler { + tim.tccr1b().modify(|_r, w| match prescaler { Prescaler::Direct => w.cs1().direct(), Prescaler::Prescale8 => w.cs1().prescale_8(), Prescaler::Prescale64 => w.cs1().prescale_64(), @@ -198,18 +198,18 @@ avr_hal_generic::impl_simple_pwm! { PB1: { ocr: ocr1a, into_pwm: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1a().bits(0b10)); + tim.tccr1a().modify(|_, w| w.com1a().set(0b10)); } else { - tim.tccr1a.modify(|_, w| w.com1a().disconnected()); + tim.tccr1a().modify(|_, w| w.com1a().disconnected()); }, }, PB2: { ocr: ocr1b, into_pwm: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1b().bits(0b10)); + tim.tccr1a().modify(|_, w| w.com1b().set(0b10)); } else { - tim.tccr1a.modify(|_, w| w.com1b().disconnected()); + tim.tccr1a().modify(|_, w| w.com1b().disconnected()); }, }, }, From da4681c83494b7049f20f93723336a99d7d0d199 Mon Sep 17 00:00:00 2001 From: Rahix Date: Wed, 30 Apr 2025 02:03:19 +0200 Subject: [PATCH 4/9] treewide: Remove critical-section-impl crate features avr-device no longer has a `critical-section-impl` feature. Instead it now has a `critical-section` feature that is enabled by default [1]. As such, we can drop the re-exposed feature here. [1]: https://github.com/Rahix/avr-device/pull/195 --- arduino-hal/Cargo.toml | 2 -- mcu/atmega-hal/Cargo.toml | 2 -- mcu/attiny-hal/Cargo.toml | 2 -- 3 files changed, 6 deletions(-) diff --git a/arduino-hal/Cargo.toml b/arduino-hal/Cargo.toml index aa70ba2558..a44fd1711e 100644 --- a/arduino-hal/Cargo.toml +++ b/arduino-hal/Cargo.toml @@ -14,8 +14,6 @@ categories = ["no-std", "embedded", "hardware-support"] default = ["rt"] rt = ["avr-device/rt"] -critical-section-impl = ["avr-device/critical-section-impl"] - board-selected = [] mcu-atmega = [] mcu-attiny = [] diff --git a/mcu/atmega-hal/Cargo.toml b/mcu/atmega-hal/Cargo.toml index bff9738b51..f76e83cf19 100644 --- a/mcu/atmega-hal/Cargo.toml +++ b/mcu/atmega-hal/Cargo.toml @@ -29,8 +29,6 @@ atmega1284p = ["avr-device/atmega1284p", "device-selected"] atmega8 = ["avr-device/atmega8", "device-selected"] atmega88p = ["avr-device/atmega88p", "device-selected"] -critical-section-impl = ["avr-device/critical-section-impl"] - # Allow certain downstream crates to overwrite the device selection error by themselves. disable-device-selection-error = [] diff --git a/mcu/attiny-hal/Cargo.toml b/mcu/attiny-hal/Cargo.toml index 737224607d..8c8f66b0b2 100644 --- a/mcu/attiny-hal/Cargo.toml +++ b/mcu/attiny-hal/Cargo.toml @@ -19,8 +19,6 @@ attiny88 = ["avr-device/attiny88", "device-selected"] attiny167 = ["avr-device/attiny167", "device-selected"] attiny2313 = ["avr-device/attiny2313", "device-selected"] -critical-section-impl = ["avr-device/critical-section-impl"] - # Allow certain downstream crates to overwrite the device selection error by themselves. disable-device-selection-error = [] From ddfe35bf01829f9db01610bca84f594b365af3c6 Mon Sep 17 00:00:00 2001 From: Rahix Date: Wed, 30 Apr 2025 01:31:11 +0200 Subject: [PATCH 5/9] generic: Accommodate for new return value of write() and modify() In svd2rust 0.34.0, the `.write()` and `.modify()` register access functions were changed to return the written register value. As avr-device is upgrading to a more recent svd2rust version, we need to adjust accordingly. Fixup the few places where the return value of `.write()` or `.modify()` mattered due to expression form calls. --- avr-hal-generic/src/eeprom.rs | 2 +- avr-hal-generic/src/port.rs | 46 ++++++++++++++++++++--------------- avr-hal-generic/src/usart.rs | 15 +++++++----- mcu/atmega-hal/src/usart.rs | 30 ++++++++++++++++------- 4 files changed, 58 insertions(+), 35 deletions(-) diff --git a/avr-hal-generic/src/eeprom.rs b/avr-hal-generic/src/eeprom.rs index b57982030a..c25d2308c0 100644 --- a/avr-hal-generic/src/eeprom.rs +++ b/avr-hal-generic/src/eeprom.rs @@ -320,7 +320,7 @@ macro_rules! impl_eeprom_atmega { regs.eecr().write(|w| { // Set Master Write Enable bit, and and Erase+Write mode mode.. w.eempe().set_bit().eepm().val_0x00() - }) + }); } #[inline] pub unsafe fn set_erase_mode(regs: &$EEPROM) { diff --git a/avr-hal-generic/src/port.rs b/avr-hal-generic/src/port.rs index 9e1259f07f..570b0b8262 100644 --- a/avr-hal-generic/src/port.rs +++ b/avr-hal-generic/src/port.rs @@ -633,18 +633,22 @@ macro_rules! impl_port_traditional_base { #[inline] unsafe fn out_set(&mut self) { match self.port { - $(DynamicPort::[] => (*<$port>::ptr()).[]().modify(|r, w| { - w.bits(r.bits() | self.mask) - }),)+ + $(DynamicPort::[] => { + (*<$port>::ptr()).[]().modify(|r, w| { + w.bits(r.bits() | self.mask) + }); + })+ } } #[inline] unsafe fn out_clear(&mut self) { match self.port { - $(DynamicPort::[] => (*<$port>::ptr()).[]().modify(|r, w| { - w.bits(r.bits() & !self.mask) - }),)+ + $(DynamicPort::[] => { + (*<$port>::ptr()).[]().modify(|r, w| { + w.bits(r.bits() & !self.mask) + }); + })+ } } @@ -655,7 +659,7 @@ macro_rules! impl_port_traditional_base { if $chip_supports_atomic_toggle { (*<$port>::ptr()).[]().write(|w| { w.bits(self.mask) - }) + }); } else { // This read-modify-write sequence cannot be optimized into a single sbi/cbi instruction, // so it is wrapped in a critical section which ensures we will never hit a race-condition here. @@ -663,7 +667,7 @@ macro_rules! impl_port_traditional_base { (*<$port>::ptr()).[]().modify(|r, w| { w.bits(r.bits() ^ self.mask) }) - }) + }); } },)+ } @@ -690,18 +694,22 @@ macro_rules! impl_port_traditional_base { #[inline] unsafe fn make_output(&mut self) { match self.port { - $(DynamicPort::[] => (*<$port>::ptr()).[]().modify(|r, w| { - w.bits(r.bits() | self.mask) - }),)+ + $(DynamicPort::[] => { + (*<$port>::ptr()).[]().modify(|r, w| { + w.bits(r.bits() | self.mask) + }); + })+ } } #[inline] unsafe fn make_input(&mut self, pull_up: bool) { match self.port { - $(DynamicPort::[] => (*<$port>::ptr()).[]().modify(|r, w| { - w.bits(r.bits() & !self.mask) - }),)+ + $(DynamicPort::[] => { + (*<$port>::ptr()).[]().modify(|r, w| { + w.bits(r.bits() & !self.mask) + }); + })+ } if pull_up { self.out_set() @@ -730,14 +738,14 @@ macro_rules! impl_port_traditional_base { unsafe fn out_set(&mut self) { (*<$port>::ptr()).[]().modify(|_, w| { w.[

]().set_bit() - }) + }); } #[inline] unsafe fn out_clear(&mut self) { (*<$port>::ptr()).[]().modify(|_, w| { w.[

]().clear_bit() - }) + }); } #[inline] @@ -745,14 +753,14 @@ macro_rules! impl_port_traditional_base { if $chip_supports_atomic_toggle { (*<$port>::ptr()).[]().write(|w| { w.[

]().set_bit() - }) + }); } else { // This read-modify-write sequence cannot be optimized into a single sbi/cbi instruction, // so it is wrapped in a critical section which ensures we will never hit a race-condition here. $crate::avr_device::interrupt::free(|_| { (*<$port>::ptr()).[]().modify(|r, w| { w.[

]().bit(!r.[

]().bit()) - }) + }); }) } } @@ -771,7 +779,7 @@ macro_rules! impl_port_traditional_base { unsafe fn make_output(&mut self) { (*<$port>::ptr()).[]().modify(|_, w| { w.[

]().set_bit() - }) + }); } #[inline] diff --git a/avr-hal-generic/src/usart.rs b/avr-hal-generic/src/usart.rs index ed670014c5..9964e362ad 100644 --- a/avr-hal-generic/src/usart.rs +++ b/avr-hal-generic/src/usart.rs @@ -535,12 +535,15 @@ macro_rules! impl_usart_traditional { fn raw_interrupt(&mut self, event: $crate::usart::Event, state: bool) { match event { - $crate::usart::Event::RxComplete => - self.[]().modify(|_, w| w.[]().bit(state)), - $crate::usart::Event::TxComplete => - self.[]().modify(|_, w| w.[]().bit(state)), - $crate::usart::Event::DataRegisterEmpty => - self.[]().modify(|_, w| w.[]().bit(state)), + $crate::usart::Event::RxComplete => { + self.[]().modify(|_, w| w.[]().bit(state)); + } + $crate::usart::Event::TxComplete => { + self.[]().modify(|_, w| w.[]().bit(state)); + } + $crate::usart::Event::DataRegisterEmpty => { + self.[]().modify(|_, w| w.[]().bit(state)); + } } } } diff --git a/mcu/atmega-hal/src/usart.rs b/mcu/atmega-hal/src/usart.rs index 5c1bd09d10..a2552aa72e 100644 --- a/mcu/atmega-hal/src/usart.rs +++ b/mcu/atmega-hal/src/usart.rs @@ -255,10 +255,14 @@ impl fn raw_interrupt(&mut self, event: crate::usart::Event, state: bool) { match event { - crate::usart::Event::RxComplete => self.ucsrb().modify(|_, w| w.rxcie().bit(state)), - crate::usart::Event::TxComplete => self.ucsrb().modify(|_, w| w.txcie().bit(state)), + crate::usart::Event::RxComplete => { + self.ucsrb().modify(|_, w| w.rxcie().bit(state)); + } + crate::usart::Event::TxComplete => { + self.ucsrb().modify(|_, w| w.txcie().bit(state)); + } crate::usart::Event::DataRegisterEmpty => { - self.ucsrb().modify(|_, w| w.udrie().bit(state)) + self.ucsrb().modify(|_, w| w.udrie().bit(state)); } } } @@ -334,10 +338,14 @@ impl fn raw_interrupt(&mut self, event: crate::usart::Event, state: bool) { match event { - crate::usart::Event::RxComplete => self.ucsr1b().modify(|_, w| w.rxcie1().bit(state)), - crate::usart::Event::TxComplete => self.ucsr1b().modify(|_, w| w.txcie1().bit(state)), + crate::usart::Event::RxComplete => { + self.ucsr1b().modify(|_, w| w.rxcie1().bit(state)); + } + crate::usart::Event::TxComplete => { + self.ucsr1b().modify(|_, w| w.txcie1().bit(state)); + } crate::usart::Event::DataRegisterEmpty => { - self.ucsr1b().modify(|_, w| w.udrie1().bit(state)) + self.ucsr1b().modify(|_, w| w.udrie1().bit(state)); } } } @@ -411,10 +419,14 @@ impl fn raw_interrupt(&mut self, event: crate::usart::Event, state: bool) { match event { - crate::usart::Event::RxComplete => self.ucsr0b().modify(|_, w| w.rxcie0().bit(state)), - crate::usart::Event::TxComplete => self.ucsr0b().modify(|_, w| w.txcie0().bit(state)), + crate::usart::Event::RxComplete => { + self.ucsr0b().modify(|_, w| w.rxcie0().bit(state)); + } + crate::usart::Event::TxComplete => { + self.ucsr0b().modify(|_, w| w.txcie0().bit(state)); + } crate::usart::Event::DataRegisterEmpty => { - self.ucsr0b().modify(|_, w| w.udrie0().bit(state)) + self.ucsr0b().modify(|_, w| w.udrie0().bit(state)); } } } From 3e0578573dbd041aa8cb94607c9fef30c218df9e Mon Sep 17 00:00:00 2001 From: Rahix Date: Wed, 30 Apr 2025 23:20:35 +0200 Subject: [PATCH 6/9] examples: nano168: Fix wrong interrupt annotation Previous versions of `avr-device` allowed accidentally mis-specifying the MCU in the interrupt definition. Now that this is caught, fix one such mistake here. --- examples/nano168/src/bin/nano168-millis.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/nano168/src/bin/nano168-millis.rs b/examples/nano168/src/bin/nano168-millis.rs index 85e906c61e..240fe9724b 100644 --- a/examples/nano168/src/bin/nano168-millis.rs +++ b/examples/nano168/src/bin/nano168-millis.rs @@ -53,7 +53,7 @@ fn millis_init(tc0: arduino_hal::pac::TC0) { }); } -#[avr_device::interrupt(atmega328p)] +#[avr_device::interrupt(atmega168)] fn TIMER0_COMPA() { avr_device::interrupt::free(|cs| { let counter_cell = MILLIS_COUNTER.borrow(cs); From 223a3d79f490c7b2eb084c4715767e2a5b61ee74 Mon Sep 17 00:00:00 2001 From: Tom Vijlbrief Date: Mon, 9 Jun 2025 18:39:03 +0200 Subject: [PATCH 7/9] Add some modern avr support --- Cargo.toml | 2 + arduino-hal/Cargo.toml | 10 + arduino-hal/src/clock.rs | 6 +- arduino-hal/src/lib.rs | 57 ++++- arduino-hal/src/port/attiny1614.rs | 24 ++ arduino-hal/src/port/attiny402.rs | 17 ++ arduino-hal/src/port/mod.rs | 8 + avr-hal-generic/src/port.rs | 220 ++++++++++++++++++ avr-hal-generic/src/usart.rs | 84 +++++++ examples/avrmodern/.cargo/config.toml | 16 ++ examples/avrmodern/Cargo.toml | 23 ++ examples/avrmodern/README.md | 42 ++++ examples/avrmodern/attiny402-flash.sh | 7 + examples/avrmodern/src/bin/avrmodern-blink.rs | 32 +++ examples/avrmodern/src/bin/avrmodern-usart.rs | 35 +++ mcu/avrmodern-hal/Cargo.toml | 45 ++++ mcu/avrmodern-hal/src/lib.rs | 107 +++++++++ mcu/avrmodern-hal/src/port.rs | 52 +++++ mcu/avrmodern-hal/src/usart.rs | 73 ++++++ 19 files changed, 854 insertions(+), 6 deletions(-) create mode 100644 arduino-hal/src/port/attiny1614.rs create mode 100644 arduino-hal/src/port/attiny402.rs create mode 100644 examples/avrmodern/.cargo/config.toml create mode 100644 examples/avrmodern/Cargo.toml create mode 100644 examples/avrmodern/README.md create mode 100644 examples/avrmodern/attiny402-flash.sh create mode 100644 examples/avrmodern/src/bin/avrmodern-blink.rs create mode 100644 examples/avrmodern/src/bin/avrmodern-usart.rs create mode 100644 mcu/avrmodern-hal/Cargo.toml create mode 100644 mcu/avrmodern-hal/src/lib.rs create mode 100644 mcu/avrmodern-hal/src/port.rs create mode 100644 mcu/avrmodern-hal/src/usart.rs diff --git a/Cargo.toml b/Cargo.toml index ca159ee2b2..aaea15fb00 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ members = [ # MCU HAL crates "mcu/atmega-hal", "mcu/attiny-hal", + "mcu/avrmodern-hal", # Higher level crates "arduino-hal", @@ -36,6 +37,7 @@ members = [ "examples/sparkfun-promini-5v", "examples/trinket-pro", "examples/trinket", + "examples/avrmodern", ] exclude = [ # The RAVEDUDE! Yeah! diff --git a/arduino-hal/Cargo.toml b/arduino-hal/Cargo.toml index aa70ba2558..82421e07d5 100644 --- a/arduino-hal/Cargo.toml +++ b/arduino-hal/Cargo.toml @@ -19,6 +19,7 @@ critical-section-impl = ["avr-device/critical-section-impl"] board-selected = [] mcu-atmega = [] mcu-attiny = [] +mcu-avrmodern = [] arduino-diecimila = ["mcu-atmega", "atmega-hal/atmega168", "board-selected"] arduino-leonardo = ["mcu-atmega", "atmega-hal/atmega32u4", "board-selected"] arduino-mega2560 = ["mcu-atmega", "atmega-hal/atmega2560", "board-selected"] @@ -31,6 +32,10 @@ sparkfun-promini-3v3 = ["mcu-atmega", "atmega-hal/atmega328p", "atmega-hal/enabl sparkfun-promini-5v = ["mcu-atmega", "atmega-hal/atmega328p", "atmega-hal/enable-extra-adc", "board-selected"] trinket = ["mcu-attiny", "attiny-hal/attiny85", "board-selected"] nano168 = ["mcu-atmega", "atmega-hal/atmega168", "atmega-hal/enable-extra-adc", "board-selected"] +attiny402 = ["mcu-avrmodern", "avrmodern-hal/attiny402", "board-selected"] +attiny1614 = ["mcu-avrmodern", "avrmodern-hal/attiny1614", "board-selected"] +#attiny3224 = ["mcu-avrmodern", "avrmodern-hal/attiny3224", "board-selected"] +#avr128db28 = ["mcu-avrmodern", "avrmodern-hal/avr128db28", "board-selected"] # We must select a board to build on docs.rs docsrs = ["arduino-uno"] @@ -57,6 +62,11 @@ features = ["disable-device-selection-error"] path = "../mcu/attiny-hal/" optional = true +[dependencies.avrmodern-hal] +path = "../mcu/avrmodern-hal/" +optional = true +features = ["disable-device-selection-error"] + [dependencies.avr-device] version = "0.7" diff --git a/arduino-hal/src/clock.rs b/arduino-hal/src/clock.rs index 7c53088015..1af729a020 100644 --- a/arduino-hal/src/clock.rs +++ b/arduino-hal/src/clock.rs @@ -27,6 +27,10 @@ pub(crate) mod default { feature = "nano168", ))] pub type DefaultClock = avr_hal_generic::clock::MHz16; - #[cfg(any(feature = "trinket", feature = "sparkfun-promini-3v3"))] + #[cfg(any( + feature = "trinket", feature = "sparkfun-promini-3v3", + feature = "attiny402", feature = "attiny1614", + // feature = "attiny3224", + ))] pub type DefaultClock = avr_hal_generic::clock::MHz8; } diff --git a/arduino-hal/src/lib.rs b/arduino-hal/src/lib.rs index eb513bb354..a9d9f34887 100644 --- a/arduino-hal/src/lib.rs +++ b/arduino-hal/src/lib.rs @@ -24,6 +24,10 @@ #![cfg_attr(feature = "trinket-pro", doc = "**Trinket Pro**.")] #![cfg_attr(feature = "trinket", doc = "**Trinket**.")] #![cfg_attr(feature = "nano168", doc = "**Nano clone (ATmega168)**.")] +#![cfg_attr(feature = "attiny402", doc = "**ATtiny402**.")] +#![cfg_attr(feature = "attiny1614", doc = "**ATtiny1614**.")] +// #![cfg_attr(feature = "attiny3224", doc = "**ATtiny3224**.")] +// #![cfg_attr(feature = "avr128db28", doc = "**avr128db28**.")] //! This means that only items which are available for this board are visible. If you are using a //! different board, try building the documentation locally with //! @@ -72,6 +76,8 @@ compile_error!( * trinket-pro * trinket * nano168 + * attiny402 + * attiny1614 " ); @@ -101,6 +107,13 @@ pub use atmega_hal as hal; #[cfg(feature = "mcu-atmega")] pub use atmega_hal::pac; +#[doc(no_inline)] +#[cfg(feature = "mcu-avrmodern")] +pub use avrmodern_hal as hal; +#[doc(no_inline)] +#[cfg(feature = "mcu-avrmodern")] +pub use avrmodern_hal::pac; + #[doc(no_inline)] #[cfg(feature = "mcu-attiny")] pub use attiny_hal as hal; @@ -165,7 +178,7 @@ pub mod spi { #[cfg(feature = "mcu-atmega")] pub use spi::Spi; -#[cfg(feature = "mcu-atmega")] +#[cfg(any(feature = "mcu-atmega", feature = "mcu-avrmodern"))] pub mod usart { pub use crate::hal::usart::{Baudrate, UsartOps}; @@ -177,15 +190,15 @@ pub mod usart { } #[doc(no_inline)] -#[cfg(feature = "mcu-atmega")] +#[cfg(any(feature = "mcu-atmega", feature = "mcu-avrmodern"))] pub use usart::Usart; -#[cfg(feature = "board-selected")] +#[cfg(any(feature = "mcu-atmega", feature = "mcu-attiny"))] pub mod eeprom { pub use crate::hal::eeprom::{Eeprom, EepromOps, OutOfBoundsError}; } #[doc(no_inline)] -#[cfg(feature = "board-selected")] +#[cfg(any(feature = "mcu-atmega", feature = "mcu-attiny"))] pub use eeprom::Eeprom; #[cfg(feature = "board-selected")] @@ -197,7 +210,7 @@ pub mod simple_pwm { pub use attiny_hal::simple_pwm::*; } -#[cfg(feature = "mcu-atmega")] +#[cfg(any(feature = "mcu-atmega", feature = "mcu-avrmodern"))] pub mod prelude { pub use crate::hal::prelude::*; @@ -340,3 +353,37 @@ macro_rules! default_serial { ) }; } + +/// Convenience macro to instantiate the [`Usart`] driver for this board. +/// +/// # Example +/// ```no_run +/// let dp = arduino_hal::Peripherals::take().unwrap(); +/// let pins = arduino_hal::pins!(dp); +/// let serial = arduino_hal::default_serial!(dp, pins, 57600); +/// ``` +#[cfg(any(feature = "attiny402"))] +#[macro_export] +macro_rules! default_serial { + ($p:expr, $pins:expr, $baud:expr) => { + $crate::Usart::new( + $p.USART0, + $pins.a7, + $pins.a6.into_output(), + $crate::hal::usart::BaudrateExt::into_baudrate($baud), + ) + }; +} + +#[cfg(any(feature = "attiny1614"))] +#[macro_export] +macro_rules! default_serial { + ($p:expr, $pins:expr, $baud:expr) => { + $crate::Usart::new( + $p.USART0, + $pins.b3, + $pins.b2.into_output(), + $crate::hal::usart::BaudrateExt::into_baudrate($baud), + ) + }; +} diff --git a/arduino-hal/src/port/attiny1614.rs b/arduino-hal/src/port/attiny1614.rs new file mode 100644 index 0000000000..e79f6ed04d --- /dev/null +++ b/arduino-hal/src/port/attiny1614.rs @@ -0,0 +1,24 @@ +pub use avrmodern_hal::port::{mode, Pin, PinMode, PinOps}; + +avr_hal_generic::renamed_pins! { + pub struct Pins { + pub a0: avrmodern_hal::port::PA0 = pa0, + pub a1: avrmodern_hal::port::PA1 = pa1, + pub a2: avrmodern_hal::port::PA2 = pa2, + pub a3: avrmodern_hal::port::PA3 = pa3, + pub a4: avrmodern_hal::port::PA4 = pa4, + pub a5: avrmodern_hal::port::PA5 = pa5, + pub a6: avrmodern_hal::port::PA6 = pa6, + pub a7: avrmodern_hal::port::PA7 = pa7, + + pub b0: avrmodern_hal::port::PB0 = pb0, + pub b1: avrmodern_hal::port::PB1 = pb1, + pub b2: avrmodern_hal::port::PB2 = pb2, + pub b3: avrmodern_hal::port::PB3 = pb3, + } + + impl Pins { + type Pin = Pin; + type McuPins = avrmodern_hal::Pins; + } +} diff --git a/arduino-hal/src/port/attiny402.rs b/arduino-hal/src/port/attiny402.rs new file mode 100644 index 0000000000..e856647d51 --- /dev/null +++ b/arduino-hal/src/port/attiny402.rs @@ -0,0 +1,17 @@ +pub use avrmodern_hal::port::{mode, Pin, PinMode, PinOps}; + +avr_hal_generic::renamed_pins! { + pub struct Pins { + pub a0: avrmodern_hal::port::PA0 = pa0, + pub a1: avrmodern_hal::port::PA1 = pa1, + pub a2: avrmodern_hal::port::PA2 = pa2, + pub a3: avrmodern_hal::port::PA3 = pa3, + pub a6: avrmodern_hal::port::PA6 = pa6, + pub a7: avrmodern_hal::port::PA7 = pa7, + } + + impl Pins { + type Pin = Pin; + type McuPins = avrmodern_hal::Pins; + } +} diff --git a/arduino-hal/src/port/mod.rs b/arduino-hal/src/port/mod.rs index 160d3f9811..958971b595 100644 --- a/arduino-hal/src/port/mod.rs +++ b/arduino-hal/src/port/mod.rs @@ -55,3 +55,11 @@ pub use trinket_pro::*; mod trinket; #[cfg(feature = "trinket")] pub use trinket::*; +#[cfg(feature = "attiny402")] +mod attiny402; +#[cfg(feature = "attiny402")] +pub use attiny402::*; +#[cfg(feature = "attiny1614")] +mod attiny1614; +#[cfg(feature = "attiny1614")] +pub use attiny1614::*; diff --git a/avr-hal-generic/src/port.rs b/avr-hal-generic/src/port.rs index 2e44ffc950..6324dcb891 100644 --- a/avr-hal-generic/src/port.rs +++ b/avr-hal-generic/src/port.rs @@ -791,6 +791,218 @@ macro_rules! impl_port_traditional_base { }; } +#[macro_export] +macro_rules! impl_port_new_base { + ( + $(#[$pins_attr:meta])* + enum Ports { + $($name:ident: $port:ty = [$($pin:literal),+],)+ + }, + $input_field:expr + ) => { + /// Type-alias for a pin type which can represent any concrete pin. + /// + /// Sometimes it is easier to handle pins if they are all of the same type. By default, + /// each pin gets its own distinct type in `avr-hal`, but by + /// [downgrading][avr_hal_generic::port::Pin#downgrading], you can cast them into this + /// "dynamic" type. Do note, however, that using this dynamic type has a runtime cost. + pub type Pin = $crate::port::Pin; + + $crate::paste::paste! { + $(#[$pins_attr])* + pub struct Pins { + $($(pub [

]: Pin< + mode::Input, + [

], + >,)+)+ + } + + impl Pins { + pub fn new( + $(_: $port,)+ + ) -> Self { + Self { + $($([

]: $crate::port::Pin::new( + [

] { _private: (), } + ),)+)+ + } + } + } + } + + $crate::paste::paste! { + #[repr(u8)] + pub enum DynamicPort { + $([]),+ + } + } + + pub struct Dynamic { + port: DynamicPort, + // We'll store the mask instead of the pin number because this allows much less code to + // be generated for the trait method implementations. + mask: u8, + } + + impl Dynamic { + fn new(port: DynamicPort, num: u8) -> Self { + Self { + port, + mask: 1u8 << num, + } + } + } + + $crate::paste::paste! { + impl $crate::port::PinOps for Dynamic { + type Dynamic = Self; + + #[inline] + fn into_dynamic(self) -> Self::Dynamic { + self + } + + #[inline] + unsafe fn out_set(&mut self) { + match self.port { + $(DynamicPort::[] => (*<$port>::ptr()).out.modify(|r, w| { + w.bits(r.bits() | self.mask) + }),)+ + } + } + + #[inline] + unsafe fn out_clear(&mut self) { + match self.port { + $(DynamicPort::[] => (*<$port>::ptr()).out.modify(|r, w| { + w.bits(r.bits() & !self.mask) + }),)+ + } + } + + #[inline] + unsafe fn out_toggle(&mut self) { + match self.port { + $(DynamicPort::[] => { + (*<$port>::ptr()).outtgl.write(|w| { + w.bits(self.mask) + }) + },)+ + } + } + + #[inline] + unsafe fn out_get(&self) -> bool { + match self.port { + $(DynamicPort::[] => { + (*<$port>::ptr()).out.read().bits() & self.mask != 0 + })+ + } + } + + #[inline] + unsafe fn in_get(&self) -> bool { + match self.port { + $(DynamicPort::[] => { + (*<$port>::ptr()).$input_field.read().bits() & self.mask != 0 + })+ + } + } + + #[inline] + unsafe fn make_output(&mut self) { + match self.port { + $(DynamicPort::[] => (*<$port>::ptr()).dir.modify(|r, w| { + w.bits(r.bits() | self.mask) + }),)+ + } + } + + #[inline] + unsafe fn make_input(&mut self, pull_up: bool) { + match self.port { + $(DynamicPort::[] => (*<$port>::ptr()).dir.modify(|r, w| { + w.bits(r.bits() & !self.mask) + }),)+ + } + if pull_up { + self.out_set() + } else { + self.out_clear() + } + } + } + } + + $crate::paste::paste! { + $($( + pub struct [

] { + _private: () + } + + impl $crate::port::PinOps for [

] { + type Dynamic = Dynamic; + + #[inline] + fn into_dynamic(self) -> Self::Dynamic { + Dynamic::new(DynamicPort::[], $pin) + } + + #[inline] + unsafe fn out_set(&mut self) { + (*<$port>::ptr()).outset.write(|w| { + w.[

]().set_bit() + }) + } + + #[inline] + unsafe fn out_clear(&mut self) { + (*<$port>::ptr()).outclr.write(|w| { + w.[

]().set_bit() + }) + } + + #[inline] + unsafe fn out_toggle(&mut self) { + (*<$port>::ptr()).outtgl.write(|w| { + w.[

]().set_bit() + }) + } + + #[inline] + unsafe fn out_get(&self) -> bool { + (*<$port>::ptr()).out.read().[

]().bit() + } + + #[inline] + unsafe fn in_get(&self) -> bool { + (*<$port>::ptr()).$input_field.read().[

]().bit() + } + + #[inline] + unsafe fn make_output(&mut self) { + (*<$port>::ptr()).dir.modify(|_, w| { + w.[

]().set_bit() + }) + } + + #[inline] + unsafe fn make_input(&mut self, pull_up: bool) { + (*<$port>::ptr()).dir.modify(|_, w| { + w.[

]().clear_bit() + }); + if pull_up { + self.out_set() + } else { + self.out_clear() + } + } + } + )+)+ + } + }; +} + /// A macro that implements port handling for a microcontroller. #[macro_export] macro_rules! impl_port_traditional { @@ -799,6 +1011,14 @@ macro_rules! impl_port_traditional { }; } +/// A macro that implements port handling for a microcontroller. +#[macro_export] +macro_rules! impl_port_new { + ($($tts:tt)*) => { + $crate::impl_port_new_base!($($tts)*); + }; +} + /// A macro that implements port handling for an old microcontroller, /// that does not support toggling the output via the PIN register. #[macro_export] diff --git a/avr-hal-generic/src/usart.rs b/avr-hal-generic/src/usart.rs index d929cf553b..b1b84cce9d 100644 --- a/avr-hal-generic/src/usart.rs +++ b/avr-hal-generic/src/usart.rs @@ -15,6 +15,8 @@ use crate::port; pub struct Baudrate { /// Value of the `UBRR#` register pub ubrr: u16, + /// Value of the `baud#` register for modern AVR + pub modbr: u16, /// Value of the `U2X#` bit pub u2x: bool, /// The baudrate calculation depends on the configured clock rate, thus a `CLOCK` generic @@ -52,6 +54,7 @@ impl Baudrate { /// Calculate parameters for a certain baudrate at a certain `CLOCK` speed. pub fn new(baud: u32) -> Baudrate { let mut ubrr = (CLOCK::FREQ / 4 / baud - 1) / 2; + let modbr = 4 * CLOCK::FREQ / baud; let mut u2x = true; debug_assert!(ubrr <= u16::MAX as u32); if ubrr > 4095 { @@ -61,6 +64,7 @@ impl Baudrate { Baudrate { ubrr: ubrr as u16, + modbr: modbr as u16, u2x, _clock: marker::PhantomData, } @@ -72,6 +76,7 @@ impl Baudrate { pub fn with_exact(u2x: bool, ubrr: u16) -> Baudrate { Baudrate { ubrr, + modbr: 0, u2x, _clock: marker::PhantomData, } @@ -547,3 +552,82 @@ macro_rules! impl_usart_traditional { } }; } + +#[macro_export] +macro_rules! impl_usart_modern { + ( + hal: $HAL:ty, + peripheral: $USART:ty, + rx: $rxpin:ty, + tx: $txpin:ty, + ) => { + $crate::paste::paste! { + impl $crate::usart::UsartOps< + $HAL, + $crate::port::Pin<$crate::port::mode::Input, $rxpin>, + $crate::port::Pin<$crate::port::mode::Output, $txpin>, + > for $USART { + fn raw_init(&mut self, baudrate: $crate::usart::Baudrate) { + self.baud.write(|w| unsafe { w.bits(baudrate.modbr)}); + + // Enable receiver and transmitter but leave interrupts disabled. + self.ctrlb.write(|w| w + .txen().set_bit() + .rxen().set_bit() + ); + + // Set frame format to 8n1 for now. At some point, this should be made + // configurable, similar to what is done in other HALs. + // Defaults to 8bit after reset. + // self.ctrlc.write(|w| w + // .chsize()._8bit() // Note that chsize() is a field for attiny402, but not for attiny1614! + // ); + } + + fn raw_deinit(&mut self) { + // Wait for any ongoing transfer to finish. + $crate::nb::block!(self.raw_flush()).ok(); + // self.[].reset(); // TODO? + } + + fn raw_flush(&mut self) -> $crate::nb::Result<(), core::convert::Infallible> { + if self.status.read().dreif() == false { + Err($crate::nb::Error::WouldBlock) + } else { + Ok(()) + } + } + + fn raw_write(&mut self, byte: u8) -> $crate::nb::Result<(), core::convert::Infallible> { + // Call flush to make sure the data-register is empty + self.raw_flush()?; + + self.txdatal.write(|w| unsafe { w.bits(byte) }); + Ok(()) + } + + fn raw_read(&mut self) -> $crate::nb::Result { + if self.status.read().rxcif() == false { + return Err($crate::nb::Error::WouldBlock); + } + + Ok(self.rxdatal.read().bits()) + } + + fn raw_interrupt(&mut self, event: $crate::usart::Event, state: bool) { + // TODO + /* + match event { + $crate::usart::Event::RxComplete => + self.[].modify(|_, w| w.[]().bit(state)), + $crate::usart::Event::TxComplete => + self.[].modify(|_, w| w.[]().bit(state)), + $crate::usart::Event::DataRegisterEmpty => + self.[].modify(|_, w| w.[]().bit(state)), + } + */ + } + } + } + }; +} diff --git a/examples/avrmodern/.cargo/config.toml b/examples/avrmodern/.cargo/config.toml new file mode 100644 index 0000000000..ebcb2eddf4 --- /dev/null +++ b/examples/avrmodern/.cargo/config.toml @@ -0,0 +1,16 @@ +[build] +target = "avr-none" +rustflags = ["-C", "target-cpu=attiny402"] +#rustflags = ["-C", "target-cpu=attiny1614"] +#This works for AVR128DB28 for programs > 32kB: +#rustflags = ["-C", "target-cpu=atxmega128a3", "-C", "link-args=-Wl,--defsym=__DATA_REGION_ORIGIN__=16384", "-C", "link-args=-Wl,--defsym=__DATA_REGION_LENGTH__=16384", "-C", "link-args=-Wl,--defsym=__stack=32767" ] +# note that we use the known attiny1614 to build for the unknown avr128db28 by specifying the correct flash size to the linker: +#rustflags = ["-C", "target-cpu=attiny1614", "-C", "link-args=-Wl,--defsym=__TEXT_REGION_LENGTH__=131072"] +# for attiny3224: +#rustflags = ["-C", "target-cpu=attiny1614", "-C", "link-args=-Wl,--defsym=__TEXT_REGION_LENGTH__=32768"] + +[target.'cfg(target_arch = "avr")'] +runner = "ravedude" + +[unstable] +build-std = ["core"] diff --git a/examples/avrmodern/Cargo.toml b/examples/avrmodern/Cargo.toml new file mode 100644 index 0000000000..3715095fcb --- /dev/null +++ b/examples/avrmodern/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "attiny402-examples" +description = "Examples for attiny402 and other modern chips" +version = "0.0.0" +authors = ["tvijlbrief@gmail.com"] +edition = "2021" +publish = false + +[dependencies] +panic-halt = "1.0.0" +ufmt = "0.2.0" +nb = "1.1.0" +embedded-hal = "1.0" + +[dependencies.arduino-hal] +path = "../../arduino-hal/" +features = ["attiny402"] +#features = ["attiny1614"] +#features = ["attiny3224"] +#features = ["avr128db28"] + +[dependencies.avr-device] +version = "0.7" diff --git a/examples/avrmodern/README.md b/examples/avrmodern/README.md new file mode 100644 index 0000000000..1d21229f91 --- /dev/null +++ b/examples/avrmodern/README.md @@ -0,0 +1,42 @@ +`avr-modern` examples for attiny402, attiny1614, attiny3224, avr128db28 +================================ +The subdirectories here contain various examples which demonstrate how to write +firmware using `avrmodern-hal`. Please note that often examples for a different +chip can be easily ported to others. + +Currently only port and uart functionality have been ported from atmega-hal. + +Note that Ubuntu has an old avr-gcc compiler suite with incomplete support for modern AVR chips. + +Install Arduino and https://github.com/SpenceKonde/megaTinyCore and use that compiler and the UPDI flash program. + +Add this to your `.profile`: +``` +PATH="$HOME/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin:$PATH" + +``` + +`attiny402-flash.sh` is an example how to flash. + +Adapt `.cargo/config.toml` and uncomment the chip you are using before running `cargo build --release`. + +The current rust compiler does not support `target-cpu` for all modern AVR chips, but that is not really a problem. +You can pick any modern chip, but note that you should use `attiny402` for chips with 8kB or less flash memory (these have a 2 byte vector table) and `attiny1614` for bigger flash memories. The amount of flash should be specified with a linker argument (which overrules the CRT file), so for the AVR128DB28 we can use: + +``` +rustflags = ["-C", "target-cpu=attiny1614", "-C", "link-args=-Wl,--defsym=__TEXT_REGION_LENGTH__=131072"] +``` + +For programs up to 32kB we need to set the flash mapping: + +``` +dp.CPU.ccp().write(|w| w.ccp().ioreg()); // remove protection +dp.NVMCTRL.ctrlb().write(|w| w.flmap().bits(0)); // Set the memory flash mapping for AVR128DB28 +``` + +For programs bigger than 32Kb the following works for AVR128DB28 +``` +rustflags = ["-C", "target-cpu=atxmega128a3", "-C", "link-args=-Wl,--defsym=__DATA_REGION_ORIGIN__=16384", "-C", "link-args=-Wl,--defsym=__DATA_REGION_LENGTH__=16384", "-C", "link-args=-Wl,--defsym=__stack=32767" ] +``` +Note that this will copy readonly objects in flash into the 16kB RAM of the AVR128DB28, so you lose some RAM. +For programs less than 32kB the `target-cpu=attiny1614` line specified above combined with the flash mapping, might be better, but in general 16kB RAM will be sufficient. diff --git a/examples/avrmodern/attiny402-flash.sh b/examples/avrmodern/attiny402-flash.sh new file mode 100644 index 0000000000..a158ae078d --- /dev/null +++ b/examples/avrmodern/attiny402-flash.sh @@ -0,0 +1,7 @@ +# Flash attiny402 with UPDI + +FILE=../../target/avr-none/release/avrmodern-blink.elf +#FILE=../../target/avr-none/release/avrmodern-usart.elf + +objcopy -O ihex $FILE output.hex +"$HOME/.arduino15/packages/megaTinyCore/tools/python3/3.7.2-post1/python3" -u "$HOME/.arduino15/packages/megaTinyCore/hardware/megaavr/2.6.10/tools/prog.py" -t uart -u /dev/ttyUSB0 -b 230400 -d attiny402 --fuses 0:0b00000000 2:0x01 6:0x04 7:0x00 8:0x00 "-foutput.hex" -a write -v diff --git a/examples/avrmodern/src/bin/avrmodern-blink.rs b/examples/avrmodern/src/bin/avrmodern-blink.rs new file mode 100644 index 0000000000..6a460a6e28 --- /dev/null +++ b/examples/avrmodern/src/bin/avrmodern-blink.rs @@ -0,0 +1,32 @@ +#![no_std] +#![no_main] + +use panic_halt as _; + +/// +/// We use the 16Mhz oscillator (fuse setting) for the attiny. +/// Startup divider is 6, init_clock() changes it to 2, resulting in a 8Mhz system clock. +/// +pub fn init_clock(dp: &arduino_hal::Peripherals) { + dp.CPU.ccp.write(|w| w.ccp().ioreg()); // remove protection + dp.CLKCTRL + .mclkctrlb + .write(|w| w.pen().set_bit().pdiv()._2x()); // change frequency divider from 6 to 2, so we get 16/2 = 8 Mhz +} + +#[arduino_hal::entry] +fn main() -> ! { + let dp = arduino_hal::Peripherals::take().unwrap(); + init_clock(&dp); + let pins = arduino_hal::pins!(dp); + + // Digital pin A7 is a LED + let mut led = pins.a7.into_output(); + + loop { + led.set_high(); + arduino_hal::delay_ms(10); + led.set_low(); + arduino_hal::delay_ms(990); + } +} diff --git a/examples/avrmodern/src/bin/avrmodern-usart.rs b/examples/avrmodern/src/bin/avrmodern-usart.rs new file mode 100644 index 0000000000..ba58fd115d --- /dev/null +++ b/examples/avrmodern/src/bin/avrmodern-usart.rs @@ -0,0 +1,35 @@ +#![no_std] +#![no_main] + +use arduino_hal::prelude::*; +use panic_halt as _; + +/// +/// We use the 16Mhz oscillator (fuse setting) for the attiny. +/// Startup divider is 6, init_clock() changes it to 2, resulting in a 8Mhz system clock. +/// +pub fn init_clock(dp: &arduino_hal::Peripherals) { + dp.CPU.ccp.write(|w| w.ccp().ioreg()); // remove protection + dp.CLKCTRL + .mclkctrlb + .write(|w| w.pen().set_bit().pdiv()._2x()); // change frequency divider from 6 to 2, so we get 16/2 = 8 Mhz +} + +#[arduino_hal::entry] +fn main() -> ! { + let dp = arduino_hal::Peripherals::take().unwrap(); + init_clock(&dp); + + let pins = arduino_hal::pins!(dp); + let mut serial = arduino_hal::default_serial!(dp, pins, 115200); + + ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap_infallible(); + + loop { + // Read a byte from the serial connection + let b = nb::block!(serial.read()).unwrap_infallible(); + + // Answer + ufmt::uwriteln!(&mut serial, "Got {}!\r", b).unwrap_infallible(); + } +} diff --git a/mcu/avrmodern-hal/Cargo.toml b/mcu/avrmodern-hal/Cargo.toml new file mode 100644 index 0000000000..881b915f7b --- /dev/null +++ b/mcu/avrmodern-hal/Cargo.toml @@ -0,0 +1,45 @@ +[package] +name = "avrmodern-hal" +version = "0.0.1" + +authors = ["Rahix ", "tvijlbrief@gmail.com"] +edition = "2021" +description = "HAL crate for modern attiny and AVR* microcontrollers" +license = "MIT OR Apache-2.0" +repository = "https://github.com/rahix/avr-hal" +keywords = ["avr", "arduino"] +categories = ["no-std", "embedded", "hardware-support"] + +[features] +rt = ["avr-device/rt"] +device-selected = [] +enable-extra-adc = [] +attiny402 = ["avr-device/attiny402", "device-selected"] +attiny1614 = ["avr-device/attiny1614", "device-selected"] +#attiny3224 = ["avr-device/attiny3224", "device-selected"] +#avr128db28 = ["avr-device/avr128db28", "device-selected"] + +critical-section-impl = ["avr-device/critical-section-impl"] + +# Allow certain downstream crates to overwrite the device selection error by themselves. +disable-device-selection-error = [] + +# We must select a microcontroller to build on docs.rs +docsrs = ["attiny402"] + +[dependencies] +avr-hal-generic = { path = "../../avr-hal-generic/" } + +[dependencies.avr-device] +version = "0.7" + +# Because this crate has its own check that at least one device is selected, we +# can safely "circumvent" the check in `avr-device`. +# +# Why would we want that? Otherwise, as `avr-device` is compiled first, its +# error will be shown and ours won't which leads to a degraded user experience +# as the displayed error message does not really tell what needs to be done... +features = ["device-selected"] + +[package.metadata.docs.rs] +features = ["docsrs"] diff --git a/mcu/avrmodern-hal/src/lib.rs b/mcu/avrmodern-hal/src/lib.rs new file mode 100644 index 0000000000..880239fbd6 --- /dev/null +++ b/mcu/avrmodern-hal/src/lib.rs @@ -0,0 +1,107 @@ +#![no_std] + +//! `avrmodern-hal` +//! ============= +//! Common HAL (hardware abstraction layer) for modern AVR microcontrollers. +//! +//! **Note**: This version of the documentation was built for +#![cfg_attr(feature = "attiny402", doc = "**ATtiny402**.")] +#![cfg_attr(feature = "attiny1614", doc = "**ATtiny1614**.")] +//! This means that only items which are available for this MCU are visible. If you are using +//! a different chip, try building the documentation locally with: +//! +//! ```text +//! cargo doc --features --open +//! ``` + +#[cfg(all( + not(feature = "device-selected"), + not(feature = "disable-device-selection-error") +))] +compile_error!( + "This crate requires you to specify your target chip as a feature. + + Please select one of the following + + * attiny402 + * attiny1614 + " +); + +#[cfg(feature = "attiny1614")] +pub use avr_device::attiny1614 as pac; +/// Reexport of `attiny402`, etc from `avr-device` +/// +#[cfg(feature = "attiny402")] +pub use avr_device::attiny402 as pac; +// #[cfg(feature = "attiny3224")] +// pub use avr_device::attiny3224 as pac; +// #[cfg(feature = "avr128db28")] +// pub use avr_device::avr128db28 as pac; + +/// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). +#[cfg(feature = "rt")] +pub use avr_device::entry; + +#[cfg(feature = "device-selected")] +pub use pac::Peripherals; + +pub use avr_hal_generic::clock; +pub use avr_hal_generic::delay; +pub use avr_hal_generic::prelude; + +//#[cfg(feature = "device-selected")] +//pub mod adc; +//#[cfg(feature = "device-selected")] +//pub use adc::Adc; + +//#[cfg(feature = "device-selected")] +//pub mod i2c; +//#[cfg(feature = "device-selected")] +//pub use i2c::I2c; + +//#[cfg(feature = "device-selected")] +//pub mod spi; +//#[cfg(feature = "device-selected")] +//pub use spi::Spi; + +#[cfg(feature = "device-selected")] +pub mod port; +#[cfg(feature = "device-selected")] +pub use port::Pins; + +//#[cfg(feature = "device-selected")] +//pub mod simple_pwm; + +#[cfg(feature = "device-selected")] +pub mod usart; +#[cfg(feature = "device-selected")] +pub use usart::Usart; + +//#[cfg(feature = "device-selected")] +//pub mod wdt; +//#[cfg(feature = "device-selected")] +//pub use wdt::Wdt; + +//#[cfg(feature = "device-selected")] +//pub mod eeprom; +//#[cfg(feature = "device-selected")] +//pub use eeprom::Eeprom; + +pub struct Avrmodern; + +#[cfg(any(feature = "attiny402",))] +#[macro_export] +macro_rules! pins { + ($p:expr) => { + $crate::Pins::new($p.PORTA) + }; +} + +#[cfg(any(feature = "attiny1614",))] +#[macro_export] +macro_rules! pins { + ($p:expr) => { + $crate::Pins::new($p.PORTA, $p.PORTB) + }; +} diff --git a/mcu/avrmodern-hal/src/port.rs b/mcu/avrmodern-hal/src/port.rs new file mode 100644 index 0000000000..e1aab69828 --- /dev/null +++ b/mcu/avrmodern-hal/src/port.rs @@ -0,0 +1,52 @@ +//! Port +//! +//! # Example +//! +//! Complete example source code can be found in the repository: +//! [`atmega2560-blink.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-blink.rs) +//! +//! ``` +//! let dp = avrmodern_hal::Peripherals::take().unwrap(); +//! let pins = avrmodern_hal::pins!(dp); +//! +//! let mut led = pins.pb7.into_output(); +//! +//! loop { +//! led.toggle(); +//! delay_ms(1000); +//! } +//! ``` + +pub use avr_hal_generic::port::{mode, PinMode, PinOps}; + +#[cfg(feature = "attiny402")] +avr_hal_generic::impl_port_new! { + enum Ports { + A: crate::pac::PORTA = [0, 1, 2, 3, 6, 7], + }, + input +} + +#[cfg(any( + feature = "attiny1614", + //feature = "attiny3224", +))] +avr_hal_generic::impl_port_new! { + enum Ports { + A: crate::pac::PORTA = [0, 1, 2, 3, 4, 5, 6, 7], + B: crate::pac::PORTB = [0, 1, 2, 3], + }, + in_ +} + +/* +#[cfg(any(feature = "avr128db28"))] +avr_hal_generic::impl_port_new! { + enum Ports { + A: crate::pac::PORTA = [0, 1, 2, 3, 4, 5, 6, 7], + C: crate::pac::PORTC = [0, 1, 2, 3], + D: crate::pac::PORTD = [1, 2, 3, 4, 5, 6, 7], + F: crate::pac::PORTF = [0, 1, 6], + } +} +*/ diff --git a/mcu/avrmodern-hal/src/usart.rs b/mcu/avrmodern-hal/src/usart.rs new file mode 100644 index 0000000000..dcbe744342 --- /dev/null +++ b/mcu/avrmodern-hal/src/usart.rs @@ -0,0 +1,73 @@ +//! USART +//! +//! # Example +//! +//! Complete example source code can be found in the repository: +//! [`atmega2560-usart.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-usart.rs) +//! +//! *Note: [ufmt](https://crates.io/crates/ufmt/) is used instead of `core::fmt` because +//! `core::fmt` code quickly grows too large for AVR platforms.* +//! +//! ``` +//! let dp = atmega_hal::Peripherals::take().unwrap(); +//! let pins = atmega_hal::pins!(dp); +//! +//! let mut serial = Usart::new( +//! dp.USART0, +//! pins.pe0, +//! pins.pe1.into_output(), +//! Baudrate::::new(57600), +//! ); +//! +//! ufmt::uwriteln!(&mut serial, "Hello from ATmega!").unwrap(); +//! +//! loop { +//! // Read a byte from the serial connection +//! let b = nb::block!(serial.read()).unwrap(); +//! // Answer +//! ufmt::uwriteln!(&mut serial, "Got {}!", b).unwrap(); +//! } +//! ``` + +#[allow(unused_imports)] +use crate::port; +pub use avr_hal_generic::usart::*; + +pub type Usart = + avr_hal_generic::usart::Usart; +pub type UsartWriter = + avr_hal_generic::usart::UsartWriter; +pub type UsartReader = + avr_hal_generic::usart::UsartReader; + +#[cfg(any(feature = "attiny402"))] +pub type Usart0 = Usart< + crate::pac::USART0, + port::Pin, + port::Pin, + CLOCK, +>; + +#[cfg(feature = "attiny402")] +avr_hal_generic::impl_usart_modern! { + hal: crate::Avrmodern, + peripheral: crate::pac::USART0, + rx: port::PA7, + tx: port::PA6, +} + +#[cfg(any(feature = "attiny1614"))] +pub type Usart0 = Usart< + crate::pac::USART0, + port::Pin, + port::Pin, + CLOCK, +>; + +#[cfg(feature = "attiny1614")] +avr_hal_generic::impl_usart_modern! { + hal: crate::Avrmodern, + peripheral: crate::pac::USART0, + rx: port::PB3, + tx: port::PB2, +} From 7f2ff6ae84dd2bfa5761a4585d6bbe000427e275 Mon Sep 17 00:00:00 2001 From: Tom Vijlbrief Date: Wed, 11 Jun 2025 16:30:01 +0200 Subject: [PATCH 8/9] Fix avr-hal-generic/port.rs --- avr-hal-generic/src/port.rs | 38 ++++++++++++++++++++---------------- mcu/avrmodern-hal/Cargo.toml | 3 ++- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/avr-hal-generic/src/port.rs b/avr-hal-generic/src/port.rs index d26bc12868..69a44be0ce 100644 --- a/avr-hal-generic/src/port.rs +++ b/avr-hal-generic/src/port.rs @@ -873,18 +873,22 @@ macro_rules! impl_port_new_base { #[inline] unsafe fn out_set(&mut self) { match self.port { - $(DynamicPort::[] => (*<$port>::ptr()).out.modify(|r, w| { + $(DynamicPort::[] => { + (*<$port>::ptr()).out().modify(|r, w| { w.bits(r.bits() | self.mask) - }),)+ + }); + })+ } } #[inline] unsafe fn out_clear(&mut self) { match self.port { - $(DynamicPort::[] => (*<$port>::ptr()).out.modify(|r, w| { + $(DynamicPort::[] => { + (*<$port>::ptr()).out().modify(|r, w| { w.bits(r.bits() & !self.mask) - }),)+ + }); + })+ } } @@ -892,10 +896,10 @@ macro_rules! impl_port_new_base { unsafe fn out_toggle(&mut self) { match self.port { $(DynamicPort::[] => { - (*<$port>::ptr()).outtgl.write(|w| { + (*<$port>::ptr()).outtgl().write(|w| { w.bits(self.mask) - }) - },)+ + }); + })+ } } @@ -958,28 +962,28 @@ macro_rules! impl_port_new_base { #[inline] unsafe fn out_set(&mut self) { - (*<$port>::ptr()).outset.write(|w| { + (*<$port>::ptr()).outset().write(|w| { w.[

]().set_bit() - }) + }); } #[inline] unsafe fn out_clear(&mut self) { - (*<$port>::ptr()).outclr.write(|w| { + (*<$port>::ptr()).outclr().write(|w| { w.[

]().set_bit() - }) + }); } #[inline] unsafe fn out_toggle(&mut self) { - (*<$port>::ptr()).outtgl.write(|w| { + (*<$port>::ptr()).outtgl().write(|w| { w.[

]().set_bit() - }) + }); } #[inline] unsafe fn out_get(&self) -> bool { - (*<$port>::ptr()).out.read().[

]().bit() + (*<$port>::ptr()).out().read().[

]().bit() } #[inline] @@ -989,14 +993,14 @@ macro_rules! impl_port_new_base { #[inline] unsafe fn make_output(&mut self) { - (*<$port>::ptr()).dir.modify(|_, w| { + (*<$port>::ptr()).dir().modify(|_, w| { w.[

]().set_bit() - }) + }); } #[inline] unsafe fn make_input(&mut self, pull_up: bool) { - (*<$port>::ptr()).dir.modify(|_, w| { + (*<$port>::ptr()).dir().modify(|_, w| { w.[

]().clear_bit() }); if pull_up { diff --git a/mcu/avrmodern-hal/Cargo.toml b/mcu/avrmodern-hal/Cargo.toml index 881b915f7b..88377d6005 100644 --- a/mcu/avrmodern-hal/Cargo.toml +++ b/mcu/avrmodern-hal/Cargo.toml @@ -19,7 +19,7 @@ attiny1614 = ["avr-device/attiny1614", "device-selected"] #attiny3224 = ["avr-device/attiny3224", "device-selected"] #avr128db28 = ["avr-device/avr128db28", "device-selected"] -critical-section-impl = ["avr-device/critical-section-impl"] +#critical-section-impl = ["avr-device/critical-section-impl"] # Allow certain downstream crates to overwrite the device selection error by themselves. disable-device-selection-error = [] @@ -31,6 +31,7 @@ docsrs = ["attiny402"] avr-hal-generic = { path = "../../avr-hal-generic/" } [dependencies.avr-device] +#avr-device = { git = "https://github.com/rahix/avr-device", rev = "330cdf1fb1a7301b9d6cf62491c16e69d6aa7312" } version = "0.7" # Because this crate has its own check that at least one device is selected, we From 4d6749c31dd582b6d14c57ba414a392f69ed5fa6 Mon Sep 17 00:00:00 2001 From: Tom Vijlbrief Date: Fri, 13 Jun 2025 16:54:04 +0200 Subject: [PATCH 9/9] Some more avr-device-next changes --- avr-hal-generic/src/usart.rs | 12 ++++++------ examples/avrmodern/.cargo/config.toml | 4 ++-- examples/avrmodern/README.md | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/avr-hal-generic/src/usart.rs b/avr-hal-generic/src/usart.rs index 3cb7534bdd..212957953a 100644 --- a/avr-hal-generic/src/usart.rs +++ b/avr-hal-generic/src/usart.rs @@ -571,10 +571,10 @@ macro_rules! impl_usart_modern { $crate::port::Pin<$crate::port::mode::Output, $txpin>, > for $USART { fn raw_init(&mut self, baudrate: $crate::usart::Baudrate) { - self.baud.write(|w| unsafe { w.bits(baudrate.modbr)}); + self.baud().write(|w| unsafe { w.bits(baudrate.modbr)}); // Enable receiver and transmitter but leave interrupts disabled. - self.ctrlb.write(|w| w + self.ctrlb().write(|w| w .txen().set_bit() .rxen().set_bit() ); @@ -594,7 +594,7 @@ macro_rules! impl_usart_modern { } fn raw_flush(&mut self) -> $crate::nb::Result<(), core::convert::Infallible> { - if self.status.read().dreif() == false { + if self.status().read().dreif() == false { Err($crate::nb::Error::WouldBlock) } else { Ok(()) @@ -605,16 +605,16 @@ macro_rules! impl_usart_modern { // Call flush to make sure the data-register is empty self.raw_flush()?; - self.txdatal.write(|w| unsafe { w.bits(byte) }); + self.txdatal().write(|w| unsafe { w.bits(byte) }); Ok(()) } fn raw_read(&mut self) -> $crate::nb::Result { - if self.status.read().rxcif() == false { + if self.status().read().rxcif() == false { return Err($crate::nb::Error::WouldBlock); } - Ok(self.rxdatal.read().bits()) + Ok(self.rxdatal().read().bits()) } fn raw_interrupt(&mut self, event: $crate::usart::Event, state: bool) { diff --git a/examples/avrmodern/.cargo/config.toml b/examples/avrmodern/.cargo/config.toml index ebcb2eddf4..b107ae1e4c 100644 --- a/examples/avrmodern/.cargo/config.toml +++ b/examples/avrmodern/.cargo/config.toml @@ -4,8 +4,8 @@ rustflags = ["-C", "target-cpu=attiny402"] #rustflags = ["-C", "target-cpu=attiny1614"] #This works for AVR128DB28 for programs > 32kB: #rustflags = ["-C", "target-cpu=atxmega128a3", "-C", "link-args=-Wl,--defsym=__DATA_REGION_ORIGIN__=16384", "-C", "link-args=-Wl,--defsym=__DATA_REGION_LENGTH__=16384", "-C", "link-args=-Wl,--defsym=__stack=32767" ] -# note that we use the known attiny1614 to build for the unknown avr128db28 by specifying the correct flash size to the linker: -#rustflags = ["-C", "target-cpu=attiny1614", "-C", "link-args=-Wl,--defsym=__TEXT_REGION_LENGTH__=131072"] +# note that we use the known attiny1614 to build for the unknown avr128db28 by specifying the correct sizes to the linker: +#rustflags = ["-C", "target-cpu=attiny1614", "-C", "link-args=-Wl,--defsym=__TEXT_REGION_LENGTH__=131072", "-C", "link-args=-Wl,--defsym=__DATA_REGION_ORIGIN__=16384", "-C", "link-args=-Wl,--defsym=__DATA_REGION_LENGTH__=16384", "-C", "link-args=-Wl,--defsym=__stack=32767" ] # for attiny3224: #rustflags = ["-C", "target-cpu=attiny1614", "-C", "link-args=-Wl,--defsym=__TEXT_REGION_LENGTH__=32768"] diff --git a/examples/avrmodern/README.md b/examples/avrmodern/README.md index 1d21229f91..645073c34a 100644 --- a/examples/avrmodern/README.md +++ b/examples/avrmodern/README.md @@ -24,7 +24,7 @@ The current rust compiler does not support `target-cpu` for all modern AVR chips You can pick any modern chip, but note that you should use `attiny402` for chips with 8kB or less flash memory (these have a 2 byte vector table) and `attiny1614` for bigger flash memories. The amount of flash should be specified with a linker argument (which overrules the CRT file), so for the AVR128DB28 we can use: ``` -rustflags = ["-C", "target-cpu=attiny1614", "-C", "link-args=-Wl,--defsym=__TEXT_REGION_LENGTH__=131072"] +rustflags = ["-C", "target-cpu=attiny1614", "-C", "link-args=-Wl,--defsym=__TEXT_REGION_LENGTH__=32768", "-C", "link-args=-Wl,--defsym=__DATA_REGION_ORIGIN__=16384", "-C", "link-args=-Wl,--defsym=__DATA_REGION_LENGTH__=16384", "-C", "link-args=-Wl,--defsym=__stack=32767" ] ``` For programs up to 32kB we need to set the flash mapping: