-
Notifications
You must be signed in to change notification settings - Fork 231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UsartSpi
Support
#562
UsartSpi
Support
#562
Changes from 2 commits
4a110c9
8ac3a86
2cd0cbd
82ad09a
ab5fad0
5debde9
a37cbc2
c5b076f
9ddb92b
b88cf04
d9bfd46
597b073
54990d0
46f4183
893f775
8fa453f
3593202
0f0c38c
7b21e5c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,91 @@ | ||||||||||||||||||||
//! MSPIM Implimentation | ||||||||||||||||||||
use crate::spi; | ||||||||||||||||||||
|
||||||||||||||||||||
// 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<H, USART, SCLKPIN, MOSIPIN, MISOPIN, CSPIN> = | ||||||||||||||||||||
spi::Spi<H, USART, SCLKPIN, MOSIPIN, MISOPIN, CSPIN>; | ||||||||||||||||||||
|
||||||||||||||||||||
// 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 { | ||||||||||||||||||||
CoolSlimbo marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||
fn raw_setup(&mut self, settings: &Settings) { | ||||||||||||||||||||
use $crate::hal::spi; | ||||||||||||||||||||
|
||||||||||||||||||||
// Setup control registers | ||||||||||||||||||||
// We start by setting the UBBRn to 0 | ||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't comment what code is doing, that should be obvious from reading the line below. Please comment why it is doing this — what's the purpose of setting UBBRn to 0 here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unsure of the purpose. But code examples in the data sheet all do so, explicitly setting it to 0, before setting the baudrate (which I will update the calculation for) |
||||||||||||||||||||
self.[<ubrr $n>].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.[<ucsr $n c>].write(|w| { | ||||||||||||||||||||
w.[<umsel $n>]().spi_master(); | ||||||||||||||||||||
|
||||||||||||||||||||
match settings.data_order { | ||||||||||||||||||||
DataOrder::MostSignificantFirst => match settings.mode.phase { | ||||||||||||||||||||
spi::Phase::CaptureOnFirstTransition => w.[<ucsz $n>]().chr5(), | ||||||||||||||||||||
spi::Phase::CaptureOnSecondTransition => w.[<ucsz $n>]().chr6(), | ||||||||||||||||||||
}, | ||||||||||||||||||||
DataOrder::LeastSignificantFirst => match settings.mode.phase { | ||||||||||||||||||||
spi::Phase::CaptureOnFirstTransition => w.[<ucsz $n>]().chr7(), | ||||||||||||||||||||
spi::Phase::CaptureOnSecondTransition => w.[<ucsz $n>]().chr8(), | ||||||||||||||||||||
}, | ||||||||||||||||||||
}; | ||||||||||||||||||||
|
||||||||||||||||||||
match settings.mode.polarity { | ||||||||||||||||||||
spi::Polarity::IdleLow => w.[<ucpol $n>]().clear_bit(), | ||||||||||||||||||||
spi::Polarity::IdleHigh => w.[<ucpol $n>]().set_bit(), | ||||||||||||||||||||
} | ||||||||||||||||||||
}); | ||||||||||||||||||||
|
||||||||||||||||||||
// Enable receiver and transmitter, and also the rec interrupt. | ||||||||||||||||||||
self.[<ucsr $n b>].write(|w| w | ||||||||||||||||||||
.[<txen $n>]().set_bit() | ||||||||||||||||||||
.[<rxen $n>]().set_bit() | ||||||||||||||||||||
.[<rxcie $n>]().set_bit() | ||||||||||||||||||||
); | ||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't enable the interrupt by default - it should always be explicitly enabled by the user through a method call, see e.g. avr-hal/avr-hal-generic/src/usart.rs Lines 300 to 308 in 65b304e
You don't need to implement this here, though — it should be part of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you elaborate on what you mean by this? I understand why to remove it (idk why it was there to begin with), but do you want me to add methods to change the interrupts? Or something other, because I don't understand "it should be part of the spi module" |
||||||||||||||||||||
|
||||||||||||||||||||
// Set the baudrate of the UBRRn, idk what it should be set to, so for now, it'll be set to 0 | ||||||||||||||||||||
self.[<ubrr $n>].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.[<ucsr $n c>].write(|w| w.[<umsel $n>]().usart_async()); | ||||||||||||||||||||
} | ||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to the USART code, you also need to disable the USART peripheral here: avr-hal/avr-hal-generic/src/usart.rs Lines 506 to 510 in 65b304e
(The UCSRnB reset is the important part). With that included, you can drop your comment. |
||||||||||||||||||||
|
||||||||||||||||||||
fn raw_check_iflag(&self) -> bool { | ||||||||||||||||||||
self.[<ucsr $n a>].read().[<rxc $n>]().bit_is_set() | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
fn raw_read(&self) -> u8 { | ||||||||||||||||||||
self.[<udr $n>].read().bits() | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
fn raw_write(&mut self, byte: u8) { | ||||||||||||||||||||
self.[<udr $n>].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() | ||||||||||||||||||||
} | ||||||||||||||||||||
} | ||||||||||||||||||||
} | ||||||||||||||||||||
}; | ||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,66 @@ avr_hal_generic::impl_spi! { | |
cs: port::PB0, | ||
} | ||
|
||
#[cfg(any( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
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", | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.