Merge #888
888: Extend QSPI config with freq, delay, spi mode, and address mode r=Dirbaio a=TilBlechschmidt Fixes #886 among some of the TODOs which have been flying around in the source file :) I'll make one more commit to remove some old commented out code from the file and take some time this evening to verify that it works. Co-authored-by: Til Blechschmidt <til@blechschmidt.de>
This commit is contained in:
commit
a903215423
@ -12,18 +12,9 @@ use crate::interrupt::{Interrupt, InterruptExt};
|
|||||||
pub use crate::pac::qspi::ifconfig0::{
|
pub use crate::pac::qspi::ifconfig0::{
|
||||||
ADDRMODE_A as AddressMode, PPSIZE_A as WritePageSize, READOC_A as ReadOpcode, WRITEOC_A as WriteOpcode,
|
ADDRMODE_A as AddressMode, PPSIZE_A as WritePageSize, READOC_A as ReadOpcode, WRITEOC_A as WriteOpcode,
|
||||||
};
|
};
|
||||||
|
pub use crate::pac::qspi::ifconfig1::SPIMODE_A as SpiMode;
|
||||||
use crate::{pac, Peripheral};
|
use crate::{pac, Peripheral};
|
||||||
|
|
||||||
// TODO
|
|
||||||
// - config:
|
|
||||||
// - 32bit address mode
|
|
||||||
// - SPI freq
|
|
||||||
// - SPI sck delay
|
|
||||||
// - Deep power down mode (DPM)
|
|
||||||
// - SPI mode 3
|
|
||||||
// - activate/deactivate
|
|
||||||
// - set gpio in high drive
|
|
||||||
|
|
||||||
pub struct DeepPowerDownConfig {
|
pub struct DeepPowerDownConfig {
|
||||||
/// Time required for entering DPM, in units of 16us
|
/// Time required for entering DPM, in units of 16us
|
||||||
pub enter_time: u16,
|
pub enter_time: u16,
|
||||||
@ -31,6 +22,25 @@ pub struct DeepPowerDownConfig {
|
|||||||
pub exit_time: u16,
|
pub exit_time: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum Frequency {
|
||||||
|
M32 = 0,
|
||||||
|
M16 = 1,
|
||||||
|
M10_7 = 2,
|
||||||
|
M8 = 3,
|
||||||
|
M6_4 = 4,
|
||||||
|
M5_3 = 5,
|
||||||
|
M4_6 = 6,
|
||||||
|
M4 = 7,
|
||||||
|
M3_6 = 8,
|
||||||
|
M3_2 = 9,
|
||||||
|
M2_9 = 10,
|
||||||
|
M2_7 = 11,
|
||||||
|
M2_5 = 12,
|
||||||
|
M2_3 = 13,
|
||||||
|
M2_1 = 14,
|
||||||
|
M2 = 15,
|
||||||
|
}
|
||||||
|
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub xip_offset: u32,
|
pub xip_offset: u32,
|
||||||
@ -38,6 +48,12 @@ pub struct Config {
|
|||||||
pub write_opcode: WriteOpcode,
|
pub write_opcode: WriteOpcode,
|
||||||
pub write_page_size: WritePageSize,
|
pub write_page_size: WritePageSize,
|
||||||
pub deep_power_down: Option<DeepPowerDownConfig>,
|
pub deep_power_down: Option<DeepPowerDownConfig>,
|
||||||
|
pub frequency: Frequency,
|
||||||
|
/// Value is specified in number of 16 MHz periods (62.5 ns)
|
||||||
|
pub sck_delay: u8,
|
||||||
|
/// Whether data is captured on the clock rising edge and data is output on a falling edge (MODE0) or vice-versa (MODE3)
|
||||||
|
pub spi_mode: SpiMode,
|
||||||
|
pub address_mode: AddressMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
@ -48,6 +64,10 @@ impl Default for Config {
|
|||||||
xip_offset: 0,
|
xip_offset: 0,
|
||||||
write_page_size: WritePageSize::_256BYTES,
|
write_page_size: WritePageSize::_256BYTES,
|
||||||
deep_power_down: None,
|
deep_power_down: None,
|
||||||
|
frequency: Frequency::M8,
|
||||||
|
sck_delay: 80,
|
||||||
|
spi_mode: SpiMode::MODE0,
|
||||||
|
address_mode: AddressMode::_24BIT,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,7 +122,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
|
|||||||
r.psel.io3.write(|w| unsafe { w.bits(io3.psel_bits()) });
|
r.psel.io3.write(|w| unsafe { w.bits(io3.psel_bits()) });
|
||||||
|
|
||||||
r.ifconfig0.write(|w| {
|
r.ifconfig0.write(|w| {
|
||||||
w.addrmode().variant(AddressMode::_24BIT);
|
w.addrmode().variant(config.address_mode);
|
||||||
w.dpmenable().bit(config.deep_power_down.is_some());
|
w.dpmenable().bit(config.deep_power_down.is_some());
|
||||||
w.ppsize().variant(config.write_page_size);
|
w.ppsize().variant(config.write_page_size);
|
||||||
w.readoc().variant(config.read_opcode);
|
w.readoc().variant(config.read_opcode);
|
||||||
@ -119,10 +139,10 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
r.ifconfig1.write(|w| unsafe {
|
r.ifconfig1.write(|w| unsafe {
|
||||||
w.sckdelay().bits(80);
|
w.sckdelay().bits(config.sck_delay);
|
||||||
w.dpmen().exit();
|
w.dpmen().exit();
|
||||||
w.spimode().mode0();
|
w.spimode().variant(config.spi_mode);
|
||||||
w.sckfreq().bits(3);
|
w.sckfreq().bits(config.frequency as u8);
|
||||||
w
|
w
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -289,13 +309,10 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn start_write(&mut self, address: usize, data: &[u8]) -> Result<(), Error> {
|
fn start_write(&mut self, address: usize, data: &[u8]) -> Result<(), Error> {
|
||||||
//info!("start_write ptr {}", data.as_ptr() as u32);
|
|
||||||
assert_eq!(data.as_ptr() as u32 % 4, 0);
|
assert_eq!(data.as_ptr() as u32 % 4, 0);
|
||||||
//info!("start_write OK ptr");
|
|
||||||
assert_eq!(data.len() as u32 % 4, 0);
|
assert_eq!(data.len() as u32 % 4, 0);
|
||||||
//info!("start_write OK len");
|
|
||||||
assert_eq!(address as u32 % 4, 0);
|
assert_eq!(address as u32 % 4, 0);
|
||||||
//info!("start_write OK addr");
|
|
||||||
if address > FLASH_SIZE {
|
if address > FLASH_SIZE {
|
||||||
return Err(Error::OutOfBounds);
|
return Err(Error::OutOfBounds);
|
||||||
}
|
}
|
||||||
@ -343,11 +360,8 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
|
|||||||
pub async fn write(&mut self, address: usize, data: &[u8]) -> Result<(), Error> {
|
pub async fn write(&mut self, address: usize, data: &[u8]) -> Result<(), Error> {
|
||||||
let bomb = DropBomb::new();
|
let bomb = DropBomb::new();
|
||||||
|
|
||||||
//info!("WRITE {} bytes at {}", data.len(), address);
|
|
||||||
self.start_write(address, data)?;
|
self.start_write(address, data)?;
|
||||||
//info!("STARTED");
|
|
||||||
self.wait_ready().await;
|
self.wait_ready().await;
|
||||||
//info!("WRITE DONE");
|
|
||||||
|
|
||||||
bomb.defuse();
|
bomb.defuse();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user