somethings wrong..

This commit is contained in:
2024-09-19 18:37:44 +02:00
parent 6e48bf8d24
commit 21186af3bf
5 changed files with 63 additions and 49 deletions

View File

@ -17,7 +17,7 @@ use crate::{
PeripheralSelect,
};
use core::{convert::Infallible, fmt::Debug, marker::PhantomData, ops::Deref};
use embedded_hal::spi::Mode;
use embedded_hal::spi::{Mode, MODE_0};
//==================================================================================================
// Defintions
@ -363,6 +363,12 @@ impl<HwCs: HwCsProvider> TransferConfigProvider for TransferConfigWithHwcs<HwCs>
/// Configuration options for the whole SPI bus. See Programmer Guide p.92 for more details
pub struct SpiConfig {
clk: SpiClkConfig,
// SPI mode configuration
pub init_mode: Mode,
/// If this is enabled, all data in the FIFO is transmitted in a single frame unless
/// the BMSTOP bit is set on a dataword. A frame is defined as CSn being active for the
/// duration of multiple data words. Defaults to true.
pub blockmode: bool,
/// By default, configure SPI for master mode (ms == false)
ms: bool,
/// Slave output disable. Useful if separate GPIO pins or decoders are used for CS control
@ -376,6 +382,8 @@ pub struct SpiConfig {
impl Default for SpiConfig {
fn default() -> Self {
Self {
init_mode: MODE_0,
blockmode: true,
// Default value is definitely valid.
clk: SpiClkConfig::from_div(DEFAULT_CLK_DIV).unwrap(),
ms: Default::default(),
@ -392,6 +400,16 @@ impl SpiConfig {
self
}
pub fn blockmode(mut self, enable: bool) -> Self {
self.blockmode = enable;
self
}
pub fn mode(mut self, mode: Mode) -> Self {
self.init_mode = mode;
self
}
pub fn clk_cfg(mut self, clk_cfg: SpiClkConfig) -> Self {
self.clk = clk_cfg;
self
@ -599,28 +617,17 @@ where
spi: SpiI,
pins: (Sck, Miso, Mosi),
spi_cfg: SpiConfig,
transfer_cfg: Option<&TransferConfig>,
) -> Self {
enable_peripheral_clock(syscfg, SpiI::PERIPH_SEL);
let SpiConfig {
clk,
init_mode,
blockmode,
ms,
slave_output_disable,
loopback_mode,
master_delayer_capture,
} = spi_cfg;
let mut init_mode = embedded_hal::spi::MODE_0;
let mut ss = 0;
let mut init_blockmode = false;
if let Some(transfer_cfg) = transfer_cfg {
if let Some(mode) = transfer_cfg.mode {
init_mode = mode;
}
if transfer_cfg.hw_cs != HwChipSelectId::Invalid {
ss = transfer_cfg.hw_cs as u8;
}
init_blockmode = transfer_cfg.blockmode;
}
let (cpo_bit, cph_bit) = mode_to_cpo_cph_bit(init_mode);
spi.ctrl0().write(|w| {
@ -639,8 +646,8 @@ where
w.sod().bit(slave_output_disable);
w.ms().bit(ms);
w.mdlycap().bit(master_delayer_capture);
w.blockmode().bit(init_blockmode);
unsafe { w.ss().bits(ss) }
w.blockmode().bit(blockmode);
unsafe { w.ss().bits(0) }
});
spi.clkprescale()
.write(|w| unsafe { w.bits(clk.prescale_val as u32) });
@ -658,7 +665,7 @@ where
cfg: spi_cfg,
sys_clk: sys_clk.into(),
fill_word: Default::default(),
blockmode: init_blockmode,
blockmode,
word: PhantomData,
},
pins,
@ -685,15 +692,22 @@ where
#[inline]
pub fn spi(&self) -> &SpiI;
/// Configure the hardware chip select given a hardware chip select ID.
#[inline]
pub fn cfg_hw_cs(&mut self, hw_cs: HwChipSelectId);
/// Configure the hardware chip select given a physical hardware CS pin.
#[inline]
pub fn cfg_hw_cs_with_pin<HwCs: OptionalHwCs<SpiI>>(&mut self, _hwcs: &HwCs);
/// Disables the hardware chip select functionality. This can be used when performing
/// external chip select handling, for example with GPIO pins.
#[inline]
pub fn cfg_hw_cs_disable(&mut self);
/// Utility function to configure all relevant transfer parameters in one go.
/// This is useful if multiple devices with different clock and mode configurations
/// are connected to one bus.
pub fn cfg_transfer<HwCs: OptionalHwCs<SpiI>>(
&mut self, transfer_cfg: &TransferConfigWithHwcs<HwCs>
);
@ -769,6 +783,7 @@ where
self.spi.perid().read().bits()
}
/// Configure the hardware chip select given a hardware chip select ID.
#[inline]
pub fn cfg_hw_cs(&mut self, hw_cs: HwChipSelectId) {
if hw_cs == HwChipSelectId::Invalid {
@ -783,11 +798,15 @@ where
});
}
/// Configure the hardware chip select given a physical hardware CS pin.
#[inline]
pub fn cfg_hw_cs_with_pin<HwCs: OptionalHwCs<SpiInstance>>(&mut self, _: &HwCs) {
self.cfg_hw_cs(HwCs::CS_ID);
}
/// Disables the hardware chip select functionality. This can be used when performing
/// external chip select handling, for example with GPIO pins.
#[inline]
pub fn cfg_hw_cs_disable(&mut self) {
self.spi.ctrl1().modify(|_, w| {
w.sod().set_bit();
@ -795,6 +814,9 @@ where
});
}
/// Utility function to configure all relevant transfer parameters in one go.
/// This is useful if multiple devices with different clock and mode configurations
/// are connected to one bus.
pub fn cfg_transfer<HwCs: OptionalHwCs<SpiInstance>>(
&mut self,
transfer_cfg: &TransferConfigWithHwcs<HwCs>,
@ -966,7 +988,7 @@ where
<Word as TryFrom<u32>>::Error: core::fmt::Debug,
{
fn read(&mut self, words: &mut [Word]) -> Result<(), Self::Error> {
self.transfer_preparation(words)?;
//self.transfer_preparation(words)?;
let mut current_read_idx = 0;
let mut current_write_idx = self.initial_send_fifo_pumping_with_fill_words(words.len());
loop {
@ -986,7 +1008,7 @@ where
}
fn write(&mut self, words: &[Word]) -> Result<(), Self::Error> {
self.transfer_preparation(words)?;
// self.transfer_preparation(words)?;
let mut current_write_idx = self.initial_send_fifo_pumping_with_words(words);
while current_write_idx < words.len() {
self.send_blocking(words[current_write_idx]);
@ -1000,7 +1022,7 @@ where
}
fn transfer(&mut self, read: &mut [Word], write: &[Word]) -> Result<(), Self::Error> {
self.transfer_preparation(write)?;
//self.transfer_preparation(write)?;
let mut current_read_idx = 0;
let mut current_write_idx = self.initial_send_fifo_pumping_with_words(write);
while current_read_idx < read.len() || current_write_idx < write.len() {
@ -1018,7 +1040,7 @@ where
}
fn transfer_in_place(&mut self, words: &mut [Word]) -> Result<(), Self::Error> {
self.transfer_preparation(words)?;
//self.transfer_preparation(words)?;
let mut current_read_idx = 0;
let mut current_write_idx = self.initial_send_fifo_pumping_with_words(words);