From 4a110c9130da535ca8c2fb48eeabd1552356a092 Mon Sep 17 00:00:00 2001 From: CoolSlimbo Date: Sun, 23 Jun 2024 14:51:37 +1000 Subject: [PATCH 01/17] Inital implimentation. Adds in on USART0 only. Needs to be tested. Will test via Arudino UNO when I move them ig --- avr-hal-generic/src/lib.rs | 1 + avr-hal-generic/src/usart_spi.rs | 92 ++++++++++++++++++++++++++++++++ mcu/atmega-hal/src/spi.rs | 30 +++++++++++ 3 files changed, 123 insertions(+) create mode 100644 avr-hal-generic/src/usart_spi.rs diff --git a/avr-hal-generic/src/lib.rs b/avr-hal-generic/src/lib.rs index 41d3c9d688..524d73d00e 100644 --- a/avr-hal-generic/src/lib.rs +++ b/avr-hal-generic/src/lib.rs @@ -21,6 +21,7 @@ pub mod port; pub mod simple_pwm; pub mod spi; pub mod usart; +pub mod usart_spi; pub mod wdt; /// Prelude containing all HAL traits diff --git a/avr-hal-generic/src/usart_spi.rs b/avr-hal-generic/src/usart_spi.rs new file mode 100644 index 0000000000..17582838c7 --- /dev/null +++ b/avr-hal-generic/src/usart_spi.rs @@ -0,0 +1,92 @@ +//! MSPIM Implimentation +use crate::spi; +use core::marker::PhantomData; + +// This module just impliments a macro for SpiOps, since underlyingly, the Spi type can still be used since it just needs SpiOps + +pub type UsartSpi = + spi::Spi; + +// Impliment SpiOps trait for USART +#[macro_export] +macro_rules! impl_usart_spi { + ( + hal: $HAL:ty, + peripheral: $USART_SPI:ty, + register_suffix: $n:expr, + sclk: $sclkpin:ty, + mosi: $mosipin:ty, + miso: $misopin:ty, + cs: $cspin:ty, + ) => { + $crate::paste::paste! { + impl $crate::spi::SpiOps<$HAL, $sclkpin, $mosipin, $misopin, $cspin> for $USART_SPI { + fn raw_setup(&mut self, settings: &Settings) { + use $crate::hal::spi; + + // Setup control registers + // We start by setting the UBBRn to 0 + self.[].write(|w| w.bits(0)); + + // We have to translate the character size register into the 2 bits which are the MSB/LSB and the phase + // 5 Bit Char = MSB and 1st + // 6 Bit Char = MSB and 2nd + // 7 Bit Char = LSB and 1st + // 8 Bit Char = LSB and 2nd + self.[].write(|w| { + w.[]().spi_master(); + + match settings.data_order { + DataOrder::MostSignificantFirst => match settings.mode.phase { + spi::Phase::CaptureOnFirstTransition => w.[]().chr5(), + spi::Phase::CaptureOnSecondTransition => w.[]().chr6(), + }, + DataOrder::LeastSignificantFirst => match settings.mode.phase { + spi::Phase::CaptureOnFirstTransition => w.[]().chr7(), + spi::Phase::CaptureOnSecondTransition => w.[]().chr8(), + }, + }; + + match settings.mode.polarity { + spi::Polarity::IdleLow => w.[]().clear_bit(), + spi::Polarity::IdleHigh => w.[]().set_bit(), + } + }); + + // Enable receiver and transmitter, and also the rec interrupt. + self.[].write(|w| w + .[]().set_bit() + .[]().set_bit() + .[]().set_bit() + ); + + // Set the baudrate of the UBRRn, idk what it should be set to, so for now, it'll be set to 0 + self.[].write(|w| w.bits(0)); + } + + fn raw_release(&mut self) { + // Probably a better way to "release" the SPI interface, but from the datasheet, this is what they suggest, so ig it works + self.[].write(|w| w.[]().usart_async()); + } + + fn raw_check_iflag(&self) -> bool { + self.[].read().[]().bit_is_set() + } + + fn raw_read(&self) -> u8 { + self.[].read().bits() + } + + fn raw_write(&mut self, byte: u8) { + self.[].write(|w| unsafe { w.bits(byte) }); + } + + fn raw_transaction(&mut self, byte: u8) -> u8 { + self.raw_write(byte); + while !self.raw_check_iflag() {} + self.raw_read() + } + } + } + }; +} diff --git a/mcu/atmega-hal/src/spi.rs b/mcu/atmega-hal/src/spi.rs index 62c7988011..edf1a0e212 100644 --- a/mcu/atmega-hal/src/spi.rs +++ b/mcu/atmega-hal/src/spi.rs @@ -31,6 +31,36 @@ avr_hal_generic::impl_spi! { cs: port::PB0, } +#[cfg(any( + feature = "atmega128a", + feature = "atmega1280", + feature = "atmega2560", + feature = "atmega32u4" +))] +pub type Usart0Spi = avr_hal_generic::usart_spi::UsartSpi< + crate::Atmega, + crate::pac::USART0, + port::PE2, + port::PE1, + port::PE0, + port::Dynamic, +>; +#[cfg(any( + feature = "atmega128a", + feature = "atmega1280", + feature = "atmega2560", + feature = "atmega32u4" +))] +avr_hal_generic::impl_usart_spi! { + hal: crate::Atmega, + peripheral: crate::pac::USART0, + register_suffix: 0, + sclk: port::PE2, + mosi: port::PE1, + miso: port::PE0, + cs: port::Dynamic, +} + #[cfg(any( feature = "atmega168", feature = "atmega328p", From 8ac3a868a077f2a5ba78751f62d9c66949eb9dfc Mon Sep 17 00:00:00 2001 From: CoolSlimbo Date: Sun, 23 Jun 2024 14:59:51 +1000 Subject: [PATCH 02/17] Implimented atmega328p support. Also untested, because I don't have any SPI modules to test on... --- avr-hal-generic/src/usart_spi.rs | 1 - mcu/atmega-hal/src/spi.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/avr-hal-generic/src/usart_spi.rs b/avr-hal-generic/src/usart_spi.rs index 17582838c7..13535f1bfd 100644 --- a/avr-hal-generic/src/usart_spi.rs +++ b/avr-hal-generic/src/usart_spi.rs @@ -1,6 +1,5 @@ //! MSPIM Implimentation use crate::spi; -use core::marker::PhantomData; // This module just impliments a macro for SpiOps, since underlyingly, the Spi type can still be used since it just needs SpiOps diff --git a/mcu/atmega-hal/src/spi.rs b/mcu/atmega-hal/src/spi.rs index edf1a0e212..0fc5dfe9d6 100644 --- a/mcu/atmega-hal/src/spi.rs +++ b/mcu/atmega-hal/src/spi.rs @@ -61,6 +61,36 @@ avr_hal_generic::impl_usart_spi! { cs: port::Dynamic, } +#[cfg(any( + feature = "atmega168", + feature = "atmega328p", + feature = "atmega48p", + feature = "atmega8" +))] +pub type Usart0Spi = avr_hal_generic::usart_spi::UsartSpi< + crate::Atmega, + crate::pac::USART0, + port::PD4, + port::PD1, + port::PD0, + port::Dynamic, +>; +#[cfg(any( + feature = "atmega168", + feature = "atmega328p", + feature = "atmega48p", + feature = "atmega8" +))] +avr_hal_generic::impl_usart_spi! { + hal: crate::Atmega, + peripheral: crate::pac::USART0, + register_suffix: 0, + sclk: port::PD4, + mosi: port::PD1, + miso: port::PD0, + cs: port::Dynamic, +} + #[cfg(any( feature = "atmega168", feature = "atmega328p", From 2cd0cbd420aacf9ec19e175c40a6e9a0f69f0911 Mon Sep 17 00:00:00 2001 From: CoolSlimbo Date: Sun, 23 Jun 2024 17:04:39 +1000 Subject: [PATCH 03/17] Reoragnise the `usart_spi` into its own module. + Docs --- mcu/atmega-hal/src/lib.rs | 3 ++ mcu/atmega-hal/src/spi.rs | 60 --------------------------------- mcu/atmega-hal/src/usart_spi.rs | 35 +++++++++++++++++++ 3 files changed, 38 insertions(+), 60 deletions(-) create mode 100644 mcu/atmega-hal/src/usart_spi.rs diff --git a/mcu/atmega-hal/src/lib.rs b/mcu/atmega-hal/src/lib.rs index e2ce9bf2e1..53f75426cf 100644 --- a/mcu/atmega-hal/src/lib.rs +++ b/mcu/atmega-hal/src/lib.rs @@ -145,6 +145,9 @@ pub mod eeprom; #[cfg(feature = "device-selected")] pub use eeprom::Eeprom; +#[cfg(feature = "device-selected")] +pub mod usart_spi; + pub struct Atmega; #[cfg(any(feature = "atmega48p", feature = "atmega168", feature = "atmega328p"))] diff --git a/mcu/atmega-hal/src/spi.rs b/mcu/atmega-hal/src/spi.rs index 0fc5dfe9d6..62c7988011 100644 --- a/mcu/atmega-hal/src/spi.rs +++ b/mcu/atmega-hal/src/spi.rs @@ -31,66 +31,6 @@ avr_hal_generic::impl_spi! { cs: port::PB0, } -#[cfg(any( - feature = "atmega128a", - feature = "atmega1280", - feature = "atmega2560", - feature = "atmega32u4" -))] -pub type Usart0Spi = avr_hal_generic::usart_spi::UsartSpi< - crate::Atmega, - crate::pac::USART0, - port::PE2, - port::PE1, - port::PE0, - port::Dynamic, ->; -#[cfg(any( - feature = "atmega128a", - feature = "atmega1280", - feature = "atmega2560", - feature = "atmega32u4" -))] -avr_hal_generic::impl_usart_spi! { - hal: crate::Atmega, - peripheral: crate::pac::USART0, - register_suffix: 0, - sclk: port::PE2, - mosi: port::PE1, - miso: port::PE0, - cs: port::Dynamic, -} - -#[cfg(any( - feature = "atmega168", - feature = "atmega328p", - feature = "atmega48p", - feature = "atmega8" -))] -pub type Usart0Spi = avr_hal_generic::usart_spi::UsartSpi< - crate::Atmega, - crate::pac::USART0, - port::PD4, - port::PD1, - port::PD0, - port::Dynamic, ->; -#[cfg(any( - feature = "atmega168", - feature = "atmega328p", - feature = "atmega48p", - feature = "atmega8" -))] -avr_hal_generic::impl_usart_spi! { - hal: crate::Atmega, - peripheral: crate::pac::USART0, - register_suffix: 0, - sclk: port::PD4, - mosi: port::PD1, - miso: port::PD0, - cs: port::Dynamic, -} - #[cfg(any( feature = "atmega168", feature = "atmega328p", diff --git a/mcu/atmega-hal/src/usart_spi.rs b/mcu/atmega-hal/src/usart_spi.rs new file mode 100644 index 0000000000..25e542f02e --- /dev/null +++ b/mcu/atmega-hal/src/usart_spi.rs @@ -0,0 +1,35 @@ +//! The following list details how many USARTs and if the USARTs support MSPIM for each board choosable. +//! +//! | Board | USARTs | SPI | +//! |-------|--------|-----| +//! | `atmega48p` | 1 | Yes | +//! | `atmega164pa`, `atmega1284p` | 2 | Yes | +//! | `atmega328p`, `atmega328pb` | 1 | Yes | +//! | `atmega32a` | 1 | No | +//! | `atmega32u4` | 1 | Yes | +//! | `atmega2560`, `atmega1280` | 4 | Yes | +//! | `atmega128a` | 2 | No | +//! | `atmega8` | 1 | No | + +use crate::port; +use crate::spi::Settings; + +#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] +pub type Usart0Spi = avr_hal_generic::usart_spi::UsartSpi< + crate::Atmega, + crate::pac::USART0, + port::PE2, + port::PE1, + port::PE0, + port::Dynamic, +>; +#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] +avr_hal_generic::impl_usart_spi! { + hal: crate::Atmega, + peripheral: crate::pac::USART0, + register_suffix: 0, + sclk: port::PE2, + mosi: port::PE1, + miso: port::PE0, + cs: port::Dynamic, +} From 82ad09a437d7e799a104693eb1bf35677e4f42ae Mon Sep 17 00:00:00 2001 From: CoolSlimbo Date: Sun, 23 Jun 2024 17:11:12 +1000 Subject: [PATCH 04/17] Rejig the docs. --- mcu/atmega-hal/src/usart_spi.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/mcu/atmega-hal/src/usart_spi.rs b/mcu/atmega-hal/src/usart_spi.rs index 25e542f02e..81b4763141 100644 --- a/mcu/atmega-hal/src/usart_spi.rs +++ b/mcu/atmega-hal/src/usart_spi.rs @@ -1,14 +1,20 @@ +//! USART MSPIM implimentations +//! //! The following list details how many USARTs and if the USARTs support MSPIM for each board choosable. //! //! | Board | USARTs | SPI | //! |-------|--------|-----| //! | `atmega48p` | 1 | Yes | -//! | `atmega164pa`, `atmega1284p` | 2 | Yes | -//! | `atmega328p`, `atmega328pb` | 1 | Yes | +//! | `atmega164pa`| 2 | Yes | +//! | `atmega168` | 1 | Yes | +//! | `atmega328p` | 1 | Yes | +//! | `atmega328pb` | 1 | Yes | //! | `atmega32a` | 1 | No | //! | `atmega32u4` | 1 | Yes | -//! | `atmega2560`, `atmega1280` | 4 | Yes | +//! | `atmega2560` | 4 | Yes | //! | `atmega128a` | 2 | No | +//! | `atmega1280` | 4 | Yes | +//! | `atmega1284p` | 2 | Yes | //! | `atmega8` | 1 | No | use crate::port; From ab5fad0a5c262269a18fa89a8736b93cfad2141b Mon Sep 17 00:00:00 2001 From: CoolSlimbo Date: Sun, 23 Jun 2024 17:18:00 +1000 Subject: [PATCH 05/17] Atmega1280 and 2560 UsartSpi Implimentations --- mcu/atmega-hal/src/usart_spi.rs | 60 +++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/mcu/atmega-hal/src/usart_spi.rs b/mcu/atmega-hal/src/usart_spi.rs index 81b4763141..8b816e8e63 100644 --- a/mcu/atmega-hal/src/usart_spi.rs +++ b/mcu/atmega-hal/src/usart_spi.rs @@ -39,3 +39,63 @@ avr_hal_generic::impl_usart_spi! { miso: port::PE0, cs: port::Dynamic, } + +#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] +pub type Usart1Spi = avr_hal_generic::usart_spi::UsartSpi< + crate::Atmega, + crate::pac::USART1, + port::PD5, + port::PD3, + port::PD2, + port::Dynamic, +>; +#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] +avr_hal_generic::impl_usart_spi! { + hal: crate::Atmega, + peripheral: crate::pac::USART1, + register_suffix: 1, + sclk: port::PD5, + mosi: port::PD3, + miso: port::PD2, + cs: port::Dynamic, +} + +#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] +pub type Usart2Spi = avr_hal_generic::usart_spi::UsartSpi< + crate::Atmega, + crate::pac::USART2, + port::PH2, + port::PH1, + port::PH0, + port::Dynamic, +>; +#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] +avr_hal_generic::impl_usart_spi! { + hal: crate::Atmega, + peripheral: crate::pac::USART2, + register_suffix: 2, + sclk: port::PH2, + mosi: port::PH1, + miso: port::PH0, + cs: port::Dynamic, +} + +#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] +pub type Usart3Spi = avr_hal_generic::usart_spi::UsartSpi< + crate::Atmega, + crate::pac::USART3, + port::PJ2, + port::PJ1, + port::PJ0, + port::Dynamic, +>; +#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] +avr_hal_generic::impl_usart_spi! { + hal: crate::Atmega, + peripheral: crate::pac::USART3, + register_suffix: 3, + sclk: port::PJ2, + mosi: port::PJ1, + miso: port::PJ0, + cs: port::Dynamic, +} From 5debde9fe1f4ff47e61f4a29f3eab04e31d16dcf Mon Sep 17 00:00:00 2001 From: CoolSlimbo Date: Sun, 23 Jun 2024 17:24:04 +1000 Subject: [PATCH 06/17] Add 48p Normal Usart, idk what it was missing --- mcu/atmega-hal/src/usart.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mcu/atmega-hal/src/usart.rs b/mcu/atmega-hal/src/usart.rs index 3fbd8514cc..adea8344a5 100644 --- a/mcu/atmega-hal/src/usart.rs +++ b/mcu/atmega-hal/src/usart.rs @@ -14,7 +14,8 @@ pub type UsartReader = feature = "atmega328p", feature = "atmega328pb", feature = "atmega1284p", - feature = "atmega164pa" + feature = "atmega164pa", + feature = "atmega48p" ))] pub type Usart0 = Usart< crate::pac::USART0, @@ -27,7 +28,8 @@ pub type Usart0 = Usart< feature = "atmega328p", feature = "atmega328pb", feature = "atmega1284p", - feature = "atmega164pa" + feature = "atmega164pa", + feature = "atmega48p" ))] avr_hal_generic::impl_usart_traditional! { hal: crate::Atmega, From a37cbc2034b9c49ffa9c80d5bfc0cc23bb11db2a Mon Sep 17 00:00:00 2001 From: CoolSlimbo Date: Sun, 23 Jun 2024 17:32:29 +1000 Subject: [PATCH 07/17] Added some more. --- mcu/atmega-hal/src/usart_spi.rs | 34 +++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/mcu/atmega-hal/src/usart_spi.rs b/mcu/atmega-hal/src/usart_spi.rs index 8b816e8e63..2f82f7a968 100644 --- a/mcu/atmega-hal/src/usart_spi.rs +++ b/mcu/atmega-hal/src/usart_spi.rs @@ -99,3 +99,37 @@ avr_hal_generic::impl_usart_spi! { miso: port::PJ0, cs: port::Dynamic, } + +#[cfg(any( + feature = "atmega168", + feature = "atmega328p", + feature = "atmega328pb", + feature = "atmega1284p", + feature = "atmega164pa", + feature = "atmega48p" +))] +pub type Usart0Spi = avr_hal_generic::usart_spi::UsartSpi< + crate::Atmega, + crate::pac::USART0, + port::PD4, + port::PD1, + port::PD0, + port::Dynamic, +>; +#[cfg(any( + feature = "atmega168", + feature = "atmega328p", + feature = "atmega328pb", + feature = "atmega1284p", + feature = "atmega164pa", + feature = "atmega48p" +))] +avr_hal_generic::impl_usart_spi! { + hal: crate::Atmega, + peripheral: crate::pac::USART0, + register_suffix: 0, + sclk: port::PD4, + mosi: port::PD1, + miso: port::PD0, + cs: port::Dynamic, +} From c5b076f8952edb87365531c74718ea32d6a1d183 Mon Sep 17 00:00:00 2001 From: CoolSlimbo Date: Sun, 23 Jun 2024 18:59:05 +1000 Subject: [PATCH 08/17] Fixed issue regarding CI. --- avr-hal-generic/src/usart_spi.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/avr-hal-generic/src/usart_spi.rs b/avr-hal-generic/src/usart_spi.rs index 13535f1bfd..fc03cdccb0 100644 --- a/avr-hal-generic/src/usart_spi.rs +++ b/avr-hal-generic/src/usart_spi.rs @@ -36,11 +36,11 @@ macro_rules! impl_usart_spi { w.[]().spi_master(); match settings.data_order { - DataOrder::MostSignificantFirst => match settings.mode.phase { + crate::spi::DataOrder::MostSignificantFirst => match settings.mode.phase { spi::Phase::CaptureOnFirstTransition => w.[]().chr5(), spi::Phase::CaptureOnSecondTransition => w.[]().chr6(), }, - DataOrder::LeastSignificantFirst => match settings.mode.phase { + crate::spi::DataOrder::LeastSignificantFirst => match settings.mode.phase { spi::Phase::CaptureOnFirstTransition => w.[]().chr7(), spi::Phase::CaptureOnSecondTransition => w.[]().chr8(), }, From 9ddb92bed9b44de5bd24880d7fc2ee51371c6311 Mon Sep 17 00:00:00 2001 From: CoolSlimbo Date: Sun, 23 Jun 2024 20:19:51 +1000 Subject: [PATCH 09/17] Mark bit writes as unsafe. --- avr-hal-generic/src/usart_spi.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/avr-hal-generic/src/usart_spi.rs b/avr-hal-generic/src/usart_spi.rs index fc03cdccb0..349e0b962f 100644 --- a/avr-hal-generic/src/usart_spi.rs +++ b/avr-hal-generic/src/usart_spi.rs @@ -25,7 +25,7 @@ macro_rules! impl_usart_spi { // Setup control registers // We start by setting the UBBRn to 0 - self.[].write(|w| w.bits(0)); + self.[].write(|w| unsafe {w.bits(0)}); // We have to translate the character size register into the 2 bits which are the MSB/LSB and the phase // 5 Bit Char = MSB and 1st @@ -60,7 +60,7 @@ macro_rules! impl_usart_spi { ); // Set the baudrate of the UBRRn, idk what it should be set to, so for now, it'll be set to 0 - self.[].write(|w| w.bits(0)); + self.[].write(|w| unsafe{w.bits(0)}); } fn raw_release(&mut self) { From b88cf04663e86559da30a91513fb25cf600d28f0 Mon Sep 17 00:00:00 2001 From: CoolSlimbo Date: Mon, 24 Jun 2024 19:51:09 +1000 Subject: [PATCH 10/17] Optimise my laziness (remove the inital implimentation, only macros from here baby) --- avr-hal-generic/src/usart_spi.rs | 6 ++- mcu/atmega-hal/src/usart_spi.rs | 65 ++++---------------------------- 2 files changed, 11 insertions(+), 60 deletions(-) diff --git a/avr-hal-generic/src/usart_spi.rs b/avr-hal-generic/src/usart_spi.rs index 349e0b962f..ff991684ad 100644 --- a/avr-hal-generic/src/usart_spi.rs +++ b/avr-hal-generic/src/usart_spi.rs @@ -8,7 +8,7 @@ pub type UsartSpi = // Impliment SpiOps trait for USART #[macro_export] -macro_rules! impl_usart_spi { +macro_rules! add_usart_spi { ( hal: $HAL:ty, peripheral: $USART_SPI:ty, @@ -19,8 +19,10 @@ macro_rules! impl_usart_spi { cs: $cspin:ty, ) => { $crate::paste::paste! { + pub type [] = avr_hal_generic::usart_spi::UsartSpi<$HAL, $USART_SPI, $sclkpin, $mosipin, $misopin, $cspin>; + impl $crate::spi::SpiOps<$HAL, $sclkpin, $mosipin, $misopin, $cspin> for $USART_SPI { - fn raw_setup(&mut self, settings: &Settings) { + fn raw_setup(&mut self, settings: &crate::spi::Settings) { use $crate::hal::spi; // Setup control registers diff --git a/mcu/atmega-hal/src/usart_spi.rs b/mcu/atmega-hal/src/usart_spi.rs index 2f82f7a968..832167a4f5 100644 --- a/mcu/atmega-hal/src/usart_spi.rs +++ b/mcu/atmega-hal/src/usart_spi.rs @@ -17,20 +17,12 @@ //! | `atmega1284p` | 2 | Yes | //! | `atmega8` | 1 | No | +// Supress warning because it doesn't recognise us usign it in macros properly. +#[allow(unused_imports)] use crate::port; -use crate::spi::Settings; #[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -pub type Usart0Spi = avr_hal_generic::usart_spi::UsartSpi< - crate::Atmega, - crate::pac::USART0, - port::PE2, - port::PE1, - port::PE0, - port::Dynamic, ->; -#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -avr_hal_generic::impl_usart_spi! { +avr_hal_generic::add_usart_spi! { hal: crate::Atmega, peripheral: crate::pac::USART0, register_suffix: 0, @@ -41,16 +33,7 @@ avr_hal_generic::impl_usart_spi! { } #[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -pub type Usart1Spi = avr_hal_generic::usart_spi::UsartSpi< - crate::Atmega, - crate::pac::USART1, - port::PD5, - port::PD3, - port::PD2, - port::Dynamic, ->; -#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -avr_hal_generic::impl_usart_spi! { +avr_hal_generic::add_usart_spi! { hal: crate::Atmega, peripheral: crate::pac::USART1, register_suffix: 1, @@ -61,16 +44,7 @@ avr_hal_generic::impl_usart_spi! { } #[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -pub type Usart2Spi = avr_hal_generic::usart_spi::UsartSpi< - crate::Atmega, - crate::pac::USART2, - port::PH2, - port::PH1, - port::PH0, - port::Dynamic, ->; -#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -avr_hal_generic::impl_usart_spi! { +avr_hal_generic::add_usart_spi! { hal: crate::Atmega, peripheral: crate::pac::USART2, register_suffix: 2, @@ -81,16 +55,7 @@ avr_hal_generic::impl_usart_spi! { } #[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -pub type Usart3Spi = avr_hal_generic::usart_spi::UsartSpi< - crate::Atmega, - crate::pac::USART3, - port::PJ2, - port::PJ1, - port::PJ0, - port::Dynamic, ->; -#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -avr_hal_generic::impl_usart_spi! { +avr_hal_generic::add_usart_spi! { hal: crate::Atmega, peripheral: crate::pac::USART3, register_suffix: 3, @@ -108,23 +73,7 @@ avr_hal_generic::impl_usart_spi! { feature = "atmega164pa", feature = "atmega48p" ))] -pub type Usart0Spi = avr_hal_generic::usart_spi::UsartSpi< - crate::Atmega, - crate::pac::USART0, - port::PD4, - port::PD1, - port::PD0, - port::Dynamic, ->; -#[cfg(any( - feature = "atmega168", - feature = "atmega328p", - feature = "atmega328pb", - feature = "atmega1284p", - feature = "atmega164pa", - feature = "atmega48p" -))] -avr_hal_generic::impl_usart_spi! { +avr_hal_generic::add_usart_spi! { hal: crate::Atmega, peripheral: crate::pac::USART0, register_suffix: 0, From d9bfd46e169b7e14ee65e612edd5852fa8b07bfb Mon Sep 17 00:00:00 2001 From: CoolSlimbo Date: Mon, 24 Jun 2024 20:01:02 +1000 Subject: [PATCH 11/17] Finalise the remaining USART's (turns out I was right at the end). Includes rejig of pin layouts between boards. --- mcu/atmega-hal/src/usart_spi.rs | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/mcu/atmega-hal/src/usart_spi.rs b/mcu/atmega-hal/src/usart_spi.rs index 832167a4f5..be3f98fe7c 100644 --- a/mcu/atmega-hal/src/usart_spi.rs +++ b/mcu/atmega-hal/src/usart_spi.rs @@ -17,7 +17,7 @@ //! | `atmega1284p` | 2 | Yes | //! | `atmega8` | 1 | No | -// Supress warning because it doesn't recognise us usign it in macros properly. +// Supress warning because it doesn't recognise us using it in macros properly. #[allow(unused_imports)] use crate::port; @@ -69,8 +69,6 @@ avr_hal_generic::add_usart_spi! { feature = "atmega168", feature = "atmega328p", feature = "atmega328pb", - feature = "atmega1284p", - feature = "atmega164pa", feature = "atmega48p" ))] avr_hal_generic::add_usart_spi! { @@ -82,3 +80,25 @@ avr_hal_generic::add_usart_spi! { miso: port::PD0, cs: port::Dynamic, } + +#[cfg(any(feature = "atmega1284p", feature = "atmega164pa",))] +avr_hal_generic::add_usart_spi! { + hal: crate::Atmega, + peripheral: crate::pac::USART0, + register_suffix: 0, + sclk: port::PB0, + mosi: port::PD1, + miso: port::PD0, + cs: port::Dynamic, +} + +#[cfg(any(feature = "atmega1284p", feature = "atmega164pa",))] +avr_hal_generic::add_usart_spi! { + hal: crate::Atmega, + peripheral: crate::pac::USART1, + register_suffix: 1, + sclk: port::PD4, + mosi: port::PD3, + miso: port::PD2, + cs: port::Dynamic, +} From 597b0731ac11704795dcd95a28a1ee179babfbe6 Mon Sep 17 00:00:00 2001 From: CoolSlimbo Date: Fri, 28 Jun 2024 09:41:57 +1000 Subject: [PATCH 12/17] Added some docs to make it less confusing. --- avr-hal-generic/src/usart_spi.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/avr-hal-generic/src/usart_spi.rs b/avr-hal-generic/src/usart_spi.rs index ff991684ad..d7354f51e8 100644 --- a/avr-hal-generic/src/usart_spi.rs +++ b/avr-hal-generic/src/usart_spi.rs @@ -19,6 +19,8 @@ macro_rules! add_usart_spi { cs: $cspin:ty, ) => { $crate::paste::paste! { + // This is quite a messy way to get the doc string working properly... but it works! + #[doc = concat!("**Clock:** `", stringify!($sclkpin), "`
**MOSI:** `", stringify!($mosipin), "`
**MISO:** `", stringify!($misopin), "`
**CS:** `", stringify!($cspin), "`")] pub type [] = avr_hal_generic::usart_spi::UsartSpi<$HAL, $USART_SPI, $sclkpin, $mosipin, $misopin, $cspin>; impl $crate::spi::SpiOps<$HAL, $sclkpin, $mosipin, $misopin, $cspin> for $USART_SPI { From 54990d09641c81f20dfec6e409f308d640f284e5 Mon Sep 17 00:00:00 2001 From: CoolSlimbo Date: Fri, 28 Jun 2024 09:49:17 +1000 Subject: [PATCH 13/17] I haven't tested this because my atmega2560 is currently soldered and doesn't have the right pins. Will fix that soon. If someone else can test would be great. --- .../src/bin/atmega2560-usart_spi-feedback.rs | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 examples/atmega2560/src/bin/atmega2560-usart_spi-feedback.rs diff --git a/examples/atmega2560/src/bin/atmega2560-usart_spi-feedback.rs b/examples/atmega2560/src/bin/atmega2560-usart_spi-feedback.rs new file mode 100644 index 0000000000..3a2d1453a6 --- /dev/null +++ b/examples/atmega2560/src/bin/atmega2560-usart_spi-feedback.rs @@ -0,0 +1,58 @@ +//! This example demonstrates how to set up a SPI interface and communicate +//! over it. The physical hardware configuration consists of connecting a +//! jumper directly from pin `PB2` to pin `PB3`. +//! +//! Run the program using `cargo run`. +//! You should see it output the line `data: 42` repeatedly. +//! If the output you see is `data: 255`, you may need to check your jumper. + +#![no_std] +#![no_main] + +use atmega_hal::delay::Delay; +use atmega_hal::usart::{Baudrate, Usart}; +use atmega_hal::usart_spi; +use embedded_hal::delay::DelayNs; +use embedded_hal::spi::SpiBus; +use panic_halt as _; + +// Define core clock. This can be used in the rest of the project. +type CoreClock = atmega_hal::clock::MHz16; + +#[avr_device::entry] +fn main() -> ! { + let dp = atmega_hal::Peripherals::take().unwrap(); + let pins = atmega_hal::pins!(dp); + + let mut delay = Delay::::new(); + + // set up serial interface for text output + let mut serial = Usart::new( + dp.USART0, + pins.pe0, + pins.pe1.into_output(), + Baudrate::::new(57600), + ); + + // Create SPI interface. + let (mut spi, _) = usart_spi::Usart1Spi::new( + dp.SPI, + pins.pd5.into_output(), + pins.pd3.into_output(), + pins.pd2.into_pull_up_input(), + pins.pd4.into_output().downgrade(), + spi::Settings::default(), + ); + + loop { + // Send a byte + let data_out: [u8; 1] = [42]; + let mut data_in: [u8; 1] = [0]; + // Send a byte + // Because MISO is connected to MOSI, the read data should be the same + spi.transfer(&mut data_in, &data_out).unwrap(); + + ufmt::uwriteln!(&mut serial, "data: {}\r", data_in[0]).unwrap(); + delay.delay_ms(1000); + } +} From 46f4183e426bed2e1c8a46858ca146db2d47e3d8 Mon Sep 17 00:00:00 2001 From: CoolSlimbo Date: Wed, 24 Jul 2024 19:21:27 +1000 Subject: [PATCH 14/17] Adjust example to properly run. (Tested)[https://github.com/Rahix/avr-hal/pull/562#issuecomment-2247329492]. Introduces points for other examples commented in. --- .../src/bin/atmega2560-usart_spi-feedback.rs | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/examples/atmega2560/src/bin/atmega2560-usart_spi-feedback.rs b/examples/atmega2560/src/bin/atmega2560-usart_spi-feedback.rs index 3a2d1453a6..9ebec3639d 100644 --- a/examples/atmega2560/src/bin/atmega2560-usart_spi-feedback.rs +++ b/examples/atmega2560/src/bin/atmega2560-usart_spi-feedback.rs @@ -36,14 +36,34 @@ fn main() -> ! { // Create SPI interface. let (mut spi, _) = usart_spi::Usart1Spi::new( - dp.SPI, + dp.USART1, pins.pd5.into_output(), pins.pd3.into_output(), pins.pd2.into_pull_up_input(), pins.pd4.into_output().downgrade(), - spi::Settings::default(), + atmega_hal::spi::Settings::default(), ); + /* Other SPI examples for other USART's + let (mut spi, _) = usart_spi::Usart2Spi::new( + dp.USART2, + pins.ph2.into_output(), + pins.ph1.into_output(), + pins.ph0.into_pull_up_input(), + pins.pd4.into_output().downgrade(), + atmega_hal::spi::Settings::default(), + ); + + let (mut spi, _) = usart_spi::Usart3Spi::new( + dp.USART3, + pins.pj2.into_output(), + pins.pj1.into_output(), + pins.pj0.into_pull_up_input(), + pins.pd4.into_output().downgrade(), + atmega_hal::spi::Settings::default(), + ); + */ + loop { // Send a byte let data_out: [u8; 1] = [42]; From 8fa453f7144957d7e240c584d979ee7ca3bf50fe Mon Sep 17 00:00:00 2001 From: CoolSlimbo <47258749+CoolSlimbo@users.noreply.github.com> Date: Fri, 26 Jul 2024 16:00:51 +1000 Subject: [PATCH 15/17] Update avr-hal-generic/src/usart_spi.rs w/ armandas clock rates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Armandas JaruĊĦauskas --- avr-hal-generic/src/usart_spi.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/avr-hal-generic/src/usart_spi.rs b/avr-hal-generic/src/usart_spi.rs index d7354f51e8..660d103483 100644 --- a/avr-hal-generic/src/usart_spi.rs +++ b/avr-hal-generic/src/usart_spi.rs @@ -63,8 +63,18 @@ macro_rules! add_usart_spi { .[]().set_bit() ); - // Set the baudrate of the UBRRn, idk what it should be set to, so for now, it'll be set to 0 - self.[].write(|w| unsafe{w.bits(0)}); + // Set the clock divider for SPI clock. + self.[].write(|w| { + match settings.clock { + crate::spi::SerialClockRate::OscfOver2 => w.bits(0), + crate::spi::SerialClockRate::OscfOver4 => w.bits(1), + crate::spi::SerialClockRate::OscfOver8 => w.bits(3), + crate::spi::SerialClockRate::OscfOver16 => w.bits(7), + crate::spi::SerialClockRate::OscfOver32 => w.bits(15), + crate::spi::SerialClockRate::OscfOver64 => w.bits(31), + crate::spi::SerialClockRate::OscfOver128 => w.bits(63), + } + }); } fn raw_release(&mut self) { From 3593202edfdb4f6529f4e3fabbcc8eb6b90db1ac Mon Sep 17 00:00:00 2001 From: CoolSlimbo Date: Fri, 26 Jul 2024 16:12:28 +1000 Subject: [PATCH 16/17] Add dummy pin (figure out how to dynamic it) Add reset to USART. --- avr-hal-generic/src/usart_spi.rs | 34 +++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/avr-hal-generic/src/usart_spi.rs b/avr-hal-generic/src/usart_spi.rs index d7354f51e8..b051e676f5 100644 --- a/avr-hal-generic/src/usart_spi.rs +++ b/avr-hal-generic/src/usart_spi.rs @@ -1,8 +1,37 @@ //! MSPIM Implimentation -use crate::spi; +use crate::{port::PinOps, spi}; // This module just impliments a macro for SpiOps, since underlyingly, the Spi type can still be used since it just needs SpiOps +/// Dummy Pin for MPSPIM +pub struct UsartSPIDummyPin; + +impl PinOps for UsartSPIDummyPin { + type Dynamic = Dynamic; + + fn into_dynamic(self) -> Self::Dynamic { + todo!() + } + + unsafe fn out_set(&mut self) {} + + unsafe fn out_clear(&mut self) {} + + unsafe fn out_toggle(&mut self) {} + + unsafe fn out_get(&self) -> bool { + false + } + + unsafe fn in_get(&self) -> bool { + true + } + + unsafe fn make_output(&mut self) {} + + unsafe fn make_input(&mut self, pull_up: bool) {} +} + pub type UsartSpi = spi::Spi; @@ -60,7 +89,6 @@ macro_rules! add_usart_spi { self.[].write(|w| w .[]().set_bit() .[]().set_bit() - .[]().set_bit() ); // Set the baudrate of the UBRRn, idk what it should be set to, so for now, it'll be set to 0 @@ -68,8 +96,8 @@ macro_rules! add_usart_spi { } fn raw_release(&mut self) { - // Probably a better way to "release" the SPI interface, but from the datasheet, this is what they suggest, so ig it works self.[].write(|w| w.[]().usart_async()); + self.[].reset(); } fn raw_check_iflag(&self) -> bool { From 7b21e5c954fa3833648d9c006d677a1adef5f5f3 Mon Sep 17 00:00:00 2001 From: CoolSlimbo Date: Fri, 26 Jul 2024 16:16:46 +1000 Subject: [PATCH 17/17] Seriously... how do I do dynamic tho? --- avr-hal-generic/src/usart_spi.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/avr-hal-generic/src/usart_spi.rs b/avr-hal-generic/src/usart_spi.rs index f66909c842..acf86a608a 100644 --- a/avr-hal-generic/src/usart_spi.rs +++ b/avr-hal-generic/src/usart_spi.rs @@ -7,7 +7,7 @@ use crate::{port::PinOps, spi}; pub struct UsartSPIDummyPin; impl PinOps for UsartSPIDummyPin { - type Dynamic = Dynamic; + type Dynamic = todo!(); fn into_dynamic(self) -> Self::Dynamic { todo!() @@ -32,8 +32,8 @@ impl PinOps for UsartSPIDummyPin { unsafe fn make_input(&mut self, pull_up: bool) {} } -pub type UsartSpi = - spi::Spi; +pub type UsartSpi = + spi::Spi; // Impliment SpiOps trait for USART #[macro_export] @@ -45,12 +45,11 @@ macro_rules! add_usart_spi { sclk: $sclkpin:ty, mosi: $mosipin:ty, miso: $misopin:ty, - cs: $cspin:ty, ) => { $crate::paste::paste! { // This is quite a messy way to get the doc string working properly... but it works! #[doc = concat!("**Clock:** `", stringify!($sclkpin), "`
**MOSI:** `", stringify!($mosipin), "`
**MISO:** `", stringify!($misopin), "`
**CS:** `", stringify!($cspin), "`")] - pub type [] = avr_hal_generic::usart_spi::UsartSpi<$HAL, $USART_SPI, $sclkpin, $mosipin, $misopin, $cspin>; + pub type [] = avr_hal_generic::usart_spi::UsartSpi<$HAL, $USART_SPI, $sclkpin, $mosipin, $misopin>; impl $crate::spi::SpiOps<$HAL, $sclkpin, $mosipin, $misopin, $cspin> for $USART_SPI { fn raw_setup(&mut self, settings: &crate::spi::Settings) {