somethings wrong..

This commit is contained in:
Robin Müller 2024-09-19 18:37:44 +02:00
parent 6e48bf8d24
commit 21186af3bf
Signed by: muellerr
GPG Key ID: A649FB78196E3849
5 changed files with 63 additions and 49 deletions

View File

@ -105,7 +105,6 @@ fn main() -> ! {
(RomSck, RomMiso, RomMosi),
// These values are taken from the vorago bootloader app, don't want to experiment here..
SpiConfig::default().clk_cfg(SpiClkConfig::new(2, 4)),
None,
);
let mut nvm =
M95M01::new(ExclusiveDevice::new_no_delay(spi, dummy_pin::DummyPin::new_low()).unwrap())

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);

View File

@ -124,7 +124,7 @@ fn main() -> ! {
}
let pinsa = PinsA::new(&mut dp.sysconfig, None, dp.porta);
let spi_cfg = SpiConfig::default();
let spi_cfg = SpiConfig::default().clk_cfg(SpiClkConfig::from_clk(SYS_CLK, 3.MHz()).unwrap());
let (sck, mosi, miso) = (
pinsa.pa20.into_funsel_2(),
pinsa.pa19.into_funsel_2(),
@ -143,19 +143,13 @@ fn main() -> ! {
.set_high()
.expect("Setting accelerometer chip select high failed");
let transfer_cfg = TransferConfigWithHwcs::new_no_hw_cs(
Some(SpiClkConfig::from_clk(SYS_CLK, 3.MHz()).unwrap()),
Some(spi::MODE_0),
true,
false,
);
let transfer_cfg = TransferConfigWithHwcs::new_no_hw_cs(None, Some(spi::MODE_0), true, false);
let spi = Spi::new(
&mut dp.sysconfig,
50.MHz(),
dp.spib,
(sck, miso, mosi),
spi_cfg,
Some(&transfer_cfg.downgrade()),
)
.downgrade();
let delay_provider = CountDownTimer::new(&mut dp.sysconfig, 50.MHz(), dp.tim1);

View File

@ -30,15 +30,10 @@ fn main() -> ! {
(RomSck, RomMiso, RomMosi),
// These values are taken from the vorago bootloader app, don't want to experiment here..
SpiConfig::default().clk_cfg(SpiClkConfig::new(2, 4)),
None,
);
spi.cfg_mode(MODE_0);
spi.cfg_hw_cs(va108xx_hal::spi::HwChipSelectId::Id0);
spi.spi().ctrl1().modify(|_, w| w.blockmode().set_bit());
let mut read_buf: [u8; 2] = [0; 2];
spi.transfer(&mut read_buf, &[RDSR, 0]);
rprintln!("read buf {:?}", read_buf);
/*
let mut nvm =
M95M01::new(ExclusiveDevice::new_no_delay(spi, dummy_pin::DummyPin::new_low()).unwrap())
.expect("creating NVM structure failed");
@ -56,6 +51,5 @@ fn main() -> ! {
nvm.write(0x4000, &write_buf).unwrap();
nvm.read(0x4000, &mut read_buf[0..4]).unwrap();
assert_eq!(&read_buf[0..4], write_buf);
*/
loop {}
}

View File

@ -1,5 +1,5 @@
use core::fmt::Debug;
use embedded_hal::spi::SpiDevice;
use embedded_hal::spi::{Operation, SpiDevice};
bitfield::bitfield! {
pub struct StatusReg(u8);
@ -97,13 +97,15 @@ where
pub fn write(&mut self, address: u32, data: &[u8]) -> Result<(), Spi::Error> {
nb::block!(self.writes_are_done())?;
self.write_enable()?;
self.spi.write(&[
WRITE,
((address >> 16) & 0xff) as u8,
((address >> 8) & 0xff) as u8,
(address & 0xff) as u8,
self.spi.transaction(&mut [
Operation::Write(&[
WRITE,
((address >> 16) & 0xff) as u8,
((address >> 8) & 0xff) as u8,
(address & 0xff) as u8,
]),
Operation::Write(data),
])?;
self.spi.write(data)?;
Ok(())
}
@ -112,13 +114,16 @@ where
return Err(Error::BufTooShort);
}
nb::block!(self.writes_are_done())?;
self.spi.write(&[
READ,
((address >> 16) & 0xff) as u8,
((address >> 8) & 0xff) as u8,
(address & 0xff) as u8,
self.spi.transaction(&mut [
Operation::Write(&[
READ,
((address >> 16) & 0xff) as u8,
((address >> 8) & 0xff) as u8,
(address & 0xff) as u8,
]),
Operation::Read(buf),
])?;
self.spi.read(buf)?;
Ok(())
}