mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-22 06:42:32 +00:00
Add set_config
method to RP SPI driver
Add a `set_config` method to `Spi` to allow reconfiguring SPI mode after creation. The existing implementation of the `embassy-embedded-hal` trait `SetConfig` is changed to use the new method. Existing uses of `SetConfig` trait may need to explicitly call the trait method to maintain current return type.
This commit is contained in:
parent
e350ca836a
commit
96362b33e8
@ -84,16 +84,9 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(inner);
|
into_ref!(inner);
|
||||||
|
|
||||||
let p = inner.regs();
|
Self::apply_config(&inner, &config);
|
||||||
let (presc, postdiv) = calc_prescs(config.frequency);
|
|
||||||
|
|
||||||
p.cpsr().write(|w| w.set_cpsdvsr(presc));
|
let p = inner.regs();
|
||||||
p.cr0().write(|w| {
|
|
||||||
w.set_dss(0b0111); // 8bit
|
|
||||||
w.set_spo(config.polarity == Polarity::IdleHigh);
|
|
||||||
w.set_sph(config.phase == Phase::CaptureOnSecondTransition);
|
|
||||||
w.set_scr(postdiv);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Always enable DREQ signals -- harmless if DMA is not listening
|
// Always enable DREQ signals -- harmless if DMA is not listening
|
||||||
p.dmacr().write(|reg| {
|
p.dmacr().write(|reg| {
|
||||||
@ -164,6 +157,23 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Private function to apply SPI configuration (phase, polarity, frequency) settings.
|
||||||
|
///
|
||||||
|
/// Driver should be disabled before making changes and reenabled after the modifications
|
||||||
|
/// are applied.
|
||||||
|
fn apply_config(inner: &PeripheralRef<'d, T>, config: &Config) {
|
||||||
|
let p = inner.regs();
|
||||||
|
let (presc, postdiv) = calc_prescs(config.frequency);
|
||||||
|
|
||||||
|
p.cpsr().write(|w| w.set_cpsdvsr(presc));
|
||||||
|
p.cr0().write(|w| {
|
||||||
|
w.set_dss(0b0111); // 8bit
|
||||||
|
w.set_spo(config.polarity == Polarity::IdleHigh);
|
||||||
|
w.set_sph(config.phase == Phase::CaptureOnSecondTransition);
|
||||||
|
w.set_scr(postdiv);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Write data to SPI blocking execution until done.
|
/// Write data to SPI blocking execution until done.
|
||||||
pub fn blocking_write(&mut self, data: &[u8]) -> Result<(), Error> {
|
pub fn blocking_write(&mut self, data: &[u8]) -> Result<(), Error> {
|
||||||
let p = self.inner.regs();
|
let p = self.inner.regs();
|
||||||
@ -244,6 +254,20 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
|
|||||||
// enable
|
// enable
|
||||||
p.cr1().write(|w| w.set_sse(true));
|
p.cr1().write(|w| w.set_sse(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set SPI config.
|
||||||
|
pub fn set_config(&mut self, config: &Config) {
|
||||||
|
let p = self.inner.regs();
|
||||||
|
|
||||||
|
// disable
|
||||||
|
p.cr1().write(|w| w.set_sse(false));
|
||||||
|
|
||||||
|
// change stuff
|
||||||
|
Self::apply_config(&self.inner, config);
|
||||||
|
|
||||||
|
// enable
|
||||||
|
p.cr1().write(|w| w.set_sse(true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> Spi<'d, T, Blocking> {
|
impl<'d, T: Instance> Spi<'d, T, Blocking> {
|
||||||
@ -696,15 +720,7 @@ impl<'d, T: Instance, M: Mode> SetConfig for Spi<'d, T, M> {
|
|||||||
type Config = Config;
|
type Config = Config;
|
||||||
type ConfigError = ();
|
type ConfigError = ();
|
||||||
fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
|
fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
|
||||||
let p = self.inner.regs();
|
self.set_config(config);
|
||||||
let (presc, postdiv) = calc_prescs(config.frequency);
|
|
||||||
p.cpsr().write(|w| w.set_cpsdvsr(presc));
|
|
||||||
p.cr0().write(|w| {
|
|
||||||
w.set_dss(0b0111); // 8bit
|
|
||||||
w.set_spo(config.polarity == Polarity::IdleHigh);
|
|
||||||
w.set_sph(config.phase == Phase::CaptureOnSecondTransition);
|
|
||||||
w.set_scr(postdiv);
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
// Now that the card is initialized, the SPI clock can go faster
|
// Now that the card is initialized, the SPI clock can go faster
|
||||||
let mut config = spi::Config::default();
|
let mut config = spi::Config::default();
|
||||||
config.frequency = 16_000_000;
|
config.frequency = 16_000_000;
|
||||||
sdcard.spi(|dev| dev.bus_mut().set_config(&config)).ok();
|
sdcard.spi(|dev| SetConfig::set_config(dev.bus_mut(), &config)).ok();
|
||||||
|
|
||||||
// Now let's look for volumes (also known as partitions) on our block device.
|
// Now let's look for volumes (also known as partitions) on our block device.
|
||||||
// To do this we need a Volume Manager. It will take ownership of the block device.
|
// To do this we need a Volume Manager. It will take ownership of the block device.
|
||||||
|
Loading…
Reference in New Issue
Block a user