somethings wrong..
This commit is contained in:
parent
6e48bf8d24
commit
21186af3bf
@ -105,7 +105,6 @@ fn main() -> ! {
|
|||||||
(RomSck, RomMiso, RomMosi),
|
(RomSck, RomMiso, RomMosi),
|
||||||
// These values are taken from the vorago bootloader app, don't want to experiment here..
|
// These values are taken from the vorago bootloader app, don't want to experiment here..
|
||||||
SpiConfig::default().clk_cfg(SpiClkConfig::new(2, 4)),
|
SpiConfig::default().clk_cfg(SpiClkConfig::new(2, 4)),
|
||||||
None,
|
|
||||||
);
|
);
|
||||||
let mut nvm =
|
let mut nvm =
|
||||||
M95M01::new(ExclusiveDevice::new_no_delay(spi, dummy_pin::DummyPin::new_low()).unwrap())
|
M95M01::new(ExclusiveDevice::new_no_delay(spi, dummy_pin::DummyPin::new_low()).unwrap())
|
||||||
|
@ -17,7 +17,7 @@ use crate::{
|
|||||||
PeripheralSelect,
|
PeripheralSelect,
|
||||||
};
|
};
|
||||||
use core::{convert::Infallible, fmt::Debug, marker::PhantomData, ops::Deref};
|
use core::{convert::Infallible, fmt::Debug, marker::PhantomData, ops::Deref};
|
||||||
use embedded_hal::spi::Mode;
|
use embedded_hal::spi::{Mode, MODE_0};
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Defintions
|
// 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
|
/// Configuration options for the whole SPI bus. See Programmer Guide p.92 for more details
|
||||||
pub struct SpiConfig {
|
pub struct SpiConfig {
|
||||||
clk: SpiClkConfig,
|
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)
|
/// By default, configure SPI for master mode (ms == false)
|
||||||
ms: bool,
|
ms: bool,
|
||||||
/// Slave output disable. Useful if separate GPIO pins or decoders are used for CS control
|
/// 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 {
|
impl Default for SpiConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
init_mode: MODE_0,
|
||||||
|
blockmode: true,
|
||||||
// Default value is definitely valid.
|
// Default value is definitely valid.
|
||||||
clk: SpiClkConfig::from_div(DEFAULT_CLK_DIV).unwrap(),
|
clk: SpiClkConfig::from_div(DEFAULT_CLK_DIV).unwrap(),
|
||||||
ms: Default::default(),
|
ms: Default::default(),
|
||||||
@ -392,6 +400,16 @@ impl SpiConfig {
|
|||||||
self
|
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 {
|
pub fn clk_cfg(mut self, clk_cfg: SpiClkConfig) -> Self {
|
||||||
self.clk = clk_cfg;
|
self.clk = clk_cfg;
|
||||||
self
|
self
|
||||||
@ -599,28 +617,17 @@ where
|
|||||||
spi: SpiI,
|
spi: SpiI,
|
||||||
pins: (Sck, Miso, Mosi),
|
pins: (Sck, Miso, Mosi),
|
||||||
spi_cfg: SpiConfig,
|
spi_cfg: SpiConfig,
|
||||||
transfer_cfg: Option<&TransferConfig>,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
enable_peripheral_clock(syscfg, SpiI::PERIPH_SEL);
|
enable_peripheral_clock(syscfg, SpiI::PERIPH_SEL);
|
||||||
let SpiConfig {
|
let SpiConfig {
|
||||||
clk,
|
clk,
|
||||||
|
init_mode,
|
||||||
|
blockmode,
|
||||||
ms,
|
ms,
|
||||||
slave_output_disable,
|
slave_output_disable,
|
||||||
loopback_mode,
|
loopback_mode,
|
||||||
master_delayer_capture,
|
master_delayer_capture,
|
||||||
} = spi_cfg;
|
} = 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);
|
let (cpo_bit, cph_bit) = mode_to_cpo_cph_bit(init_mode);
|
||||||
spi.ctrl0().write(|w| {
|
spi.ctrl0().write(|w| {
|
||||||
@ -639,8 +646,8 @@ where
|
|||||||
w.sod().bit(slave_output_disable);
|
w.sod().bit(slave_output_disable);
|
||||||
w.ms().bit(ms);
|
w.ms().bit(ms);
|
||||||
w.mdlycap().bit(master_delayer_capture);
|
w.mdlycap().bit(master_delayer_capture);
|
||||||
w.blockmode().bit(init_blockmode);
|
w.blockmode().bit(blockmode);
|
||||||
unsafe { w.ss().bits(ss) }
|
unsafe { w.ss().bits(0) }
|
||||||
});
|
});
|
||||||
spi.clkprescale()
|
spi.clkprescale()
|
||||||
.write(|w| unsafe { w.bits(clk.prescale_val as u32) });
|
.write(|w| unsafe { w.bits(clk.prescale_val as u32) });
|
||||||
@ -658,7 +665,7 @@ where
|
|||||||
cfg: spi_cfg,
|
cfg: spi_cfg,
|
||||||
sys_clk: sys_clk.into(),
|
sys_clk: sys_clk.into(),
|
||||||
fill_word: Default::default(),
|
fill_word: Default::default(),
|
||||||
blockmode: init_blockmode,
|
blockmode,
|
||||||
word: PhantomData,
|
word: PhantomData,
|
||||||
},
|
},
|
||||||
pins,
|
pins,
|
||||||
@ -685,15 +692,22 @@ where
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn spi(&self) -> &SpiI;
|
pub fn spi(&self) -> &SpiI;
|
||||||
|
|
||||||
|
/// Configure the hardware chip select given a hardware chip select ID.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn cfg_hw_cs(&mut self, hw_cs: HwChipSelectId);
|
pub fn cfg_hw_cs(&mut self, hw_cs: HwChipSelectId);
|
||||||
|
|
||||||
|
/// Configure the hardware chip select given a physical hardware CS pin.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn cfg_hw_cs_with_pin<HwCs: OptionalHwCs<SpiI>>(&mut self, _hwcs: &HwCs);
|
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]
|
#[inline]
|
||||||
pub fn cfg_hw_cs_disable(&mut self);
|
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>>(
|
pub fn cfg_transfer<HwCs: OptionalHwCs<SpiI>>(
|
||||||
&mut self, transfer_cfg: &TransferConfigWithHwcs<HwCs>
|
&mut self, transfer_cfg: &TransferConfigWithHwcs<HwCs>
|
||||||
);
|
);
|
||||||
@ -769,6 +783,7 @@ where
|
|||||||
self.spi.perid().read().bits()
|
self.spi.perid().read().bits()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Configure the hardware chip select given a hardware chip select ID.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn cfg_hw_cs(&mut self, hw_cs: HwChipSelectId) {
|
pub fn cfg_hw_cs(&mut self, hw_cs: HwChipSelectId) {
|
||||||
if hw_cs == HwChipSelectId::Invalid {
|
if hw_cs == HwChipSelectId::Invalid {
|
||||||
@ -783,11 +798,15 @@ where
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Configure the hardware chip select given a physical hardware CS pin.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn cfg_hw_cs_with_pin<HwCs: OptionalHwCs<SpiInstance>>(&mut self, _: &HwCs) {
|
pub fn cfg_hw_cs_with_pin<HwCs: OptionalHwCs<SpiInstance>>(&mut self, _: &HwCs) {
|
||||||
self.cfg_hw_cs(HwCs::CS_ID);
|
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) {
|
pub fn cfg_hw_cs_disable(&mut self) {
|
||||||
self.spi.ctrl1().modify(|_, w| {
|
self.spi.ctrl1().modify(|_, w| {
|
||||||
w.sod().set_bit();
|
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>>(
|
pub fn cfg_transfer<HwCs: OptionalHwCs<SpiInstance>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
transfer_cfg: &TransferConfigWithHwcs<HwCs>,
|
transfer_cfg: &TransferConfigWithHwcs<HwCs>,
|
||||||
@ -966,7 +988,7 @@ where
|
|||||||
<Word as TryFrom<u32>>::Error: core::fmt::Debug,
|
<Word as TryFrom<u32>>::Error: core::fmt::Debug,
|
||||||
{
|
{
|
||||||
fn read(&mut self, words: &mut [Word]) -> Result<(), Self::Error> {
|
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_read_idx = 0;
|
||||||
let mut current_write_idx = self.initial_send_fifo_pumping_with_fill_words(words.len());
|
let mut current_write_idx = self.initial_send_fifo_pumping_with_fill_words(words.len());
|
||||||
loop {
|
loop {
|
||||||
@ -986,7 +1008,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn write(&mut self, words: &[Word]) -> Result<(), Self::Error> {
|
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);
|
let mut current_write_idx = self.initial_send_fifo_pumping_with_words(words);
|
||||||
while current_write_idx < words.len() {
|
while current_write_idx < words.len() {
|
||||||
self.send_blocking(words[current_write_idx]);
|
self.send_blocking(words[current_write_idx]);
|
||||||
@ -1000,7 +1022,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn transfer(&mut self, read: &mut [Word], write: &[Word]) -> Result<(), Self::Error> {
|
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_read_idx = 0;
|
||||||
let mut current_write_idx = self.initial_send_fifo_pumping_with_words(write);
|
let mut current_write_idx = self.initial_send_fifo_pumping_with_words(write);
|
||||||
while current_read_idx < read.len() || current_write_idx < write.len() {
|
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> {
|
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_read_idx = 0;
|
||||||
let mut current_write_idx = self.initial_send_fifo_pumping_with_words(words);
|
let mut current_write_idx = self.initial_send_fifo_pumping_with_words(words);
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ fn main() -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let pinsa = PinsA::new(&mut dp.sysconfig, None, dp.porta);
|
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) = (
|
let (sck, mosi, miso) = (
|
||||||
pinsa.pa20.into_funsel_2(),
|
pinsa.pa20.into_funsel_2(),
|
||||||
pinsa.pa19.into_funsel_2(),
|
pinsa.pa19.into_funsel_2(),
|
||||||
@ -143,19 +143,13 @@ fn main() -> ! {
|
|||||||
.set_high()
|
.set_high()
|
||||||
.expect("Setting accelerometer chip select high failed");
|
.expect("Setting accelerometer chip select high failed");
|
||||||
|
|
||||||
let transfer_cfg = TransferConfigWithHwcs::new_no_hw_cs(
|
let transfer_cfg = TransferConfigWithHwcs::new_no_hw_cs(None, Some(spi::MODE_0), true, false);
|
||||||
Some(SpiClkConfig::from_clk(SYS_CLK, 3.MHz()).unwrap()),
|
|
||||||
Some(spi::MODE_0),
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
let spi = Spi::new(
|
let spi = Spi::new(
|
||||||
&mut dp.sysconfig,
|
&mut dp.sysconfig,
|
||||||
50.MHz(),
|
50.MHz(),
|
||||||
dp.spib,
|
dp.spib,
|
||||||
(sck, miso, mosi),
|
(sck, miso, mosi),
|
||||||
spi_cfg,
|
spi_cfg,
|
||||||
Some(&transfer_cfg.downgrade()),
|
|
||||||
)
|
)
|
||||||
.downgrade();
|
.downgrade();
|
||||||
let delay_provider = CountDownTimer::new(&mut dp.sysconfig, 50.MHz(), dp.tim1);
|
let delay_provider = CountDownTimer::new(&mut dp.sysconfig, 50.MHz(), dp.tim1);
|
||||||
|
@ -30,15 +30,10 @@ fn main() -> ! {
|
|||||||
(RomSck, RomMiso, RomMosi),
|
(RomSck, RomMiso, RomMosi),
|
||||||
// These values are taken from the vorago bootloader app, don't want to experiment here..
|
// These values are taken from the vorago bootloader app, don't want to experiment here..
|
||||||
SpiConfig::default().clk_cfg(SpiClkConfig::new(2, 4)),
|
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];
|
let mut read_buf: [u8; 2] = [0; 2];
|
||||||
spi.transfer(&mut read_buf, &[RDSR, 0]);
|
spi.transfer(&mut read_buf, &[RDSR, 0]);
|
||||||
rprintln!("read buf {:?}", read_buf);
|
rprintln!("read buf {:?}", read_buf);
|
||||||
/*
|
|
||||||
let mut nvm =
|
let mut nvm =
|
||||||
M95M01::new(ExclusiveDevice::new_no_delay(spi, dummy_pin::DummyPin::new_low()).unwrap())
|
M95M01::new(ExclusiveDevice::new_no_delay(spi, dummy_pin::DummyPin::new_low()).unwrap())
|
||||||
.expect("creating NVM structure failed");
|
.expect("creating NVM structure failed");
|
||||||
@ -56,6 +51,5 @@ fn main() -> ! {
|
|||||||
nvm.write(0x4000, &write_buf).unwrap();
|
nvm.write(0x4000, &write_buf).unwrap();
|
||||||
nvm.read(0x4000, &mut read_buf[0..4]).unwrap();
|
nvm.read(0x4000, &mut read_buf[0..4]).unwrap();
|
||||||
assert_eq!(&read_buf[0..4], write_buf);
|
assert_eq!(&read_buf[0..4], write_buf);
|
||||||
*/
|
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
use embedded_hal::spi::SpiDevice;
|
use embedded_hal::spi::{Operation, SpiDevice};
|
||||||
|
|
||||||
bitfield::bitfield! {
|
bitfield::bitfield! {
|
||||||
pub struct StatusReg(u8);
|
pub struct StatusReg(u8);
|
||||||
@ -97,13 +97,15 @@ where
|
|||||||
pub fn write(&mut self, address: u32, data: &[u8]) -> Result<(), Spi::Error> {
|
pub fn write(&mut self, address: u32, data: &[u8]) -> Result<(), Spi::Error> {
|
||||||
nb::block!(self.writes_are_done())?;
|
nb::block!(self.writes_are_done())?;
|
||||||
self.write_enable()?;
|
self.write_enable()?;
|
||||||
self.spi.write(&[
|
self.spi.transaction(&mut [
|
||||||
|
Operation::Write(&[
|
||||||
WRITE,
|
WRITE,
|
||||||
((address >> 16) & 0xff) as u8,
|
((address >> 16) & 0xff) as u8,
|
||||||
((address >> 8) & 0xff) as u8,
|
((address >> 8) & 0xff) as u8,
|
||||||
(address & 0xff) as u8,
|
(address & 0xff) as u8,
|
||||||
|
]),
|
||||||
|
Operation::Write(data),
|
||||||
])?;
|
])?;
|
||||||
self.spi.write(data)?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,13 +114,16 @@ where
|
|||||||
return Err(Error::BufTooShort);
|
return Err(Error::BufTooShort);
|
||||||
}
|
}
|
||||||
nb::block!(self.writes_are_done())?;
|
nb::block!(self.writes_are_done())?;
|
||||||
self.spi.write(&[
|
|
||||||
|
self.spi.transaction(&mut [
|
||||||
|
Operation::Write(&[
|
||||||
READ,
|
READ,
|
||||||
((address >> 16) & 0xff) as u8,
|
((address >> 16) & 0xff) as u8,
|
||||||
((address >> 8) & 0xff) as u8,
|
((address >> 8) & 0xff) as u8,
|
||||||
(address & 0xff) as u8,
|
(address & 0xff) as u8,
|
||||||
|
]),
|
||||||
|
Operation::Read(buf),
|
||||||
])?;
|
])?;
|
||||||
self.spi.read(buf)?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user