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::{ | ||||
|     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}; | ||||
| 
 | ||||
| // 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 { | ||||
|     /// Time required for entering DPM, in units of 16us
 | ||||
|     pub enter_time: u16, | ||||
| @ -31,6 +22,25 @@ pub struct DeepPowerDownConfig { | ||||
|     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] | ||||
| pub struct Config { | ||||
|     pub xip_offset: u32, | ||||
| @ -38,6 +48,12 @@ pub struct Config { | ||||
|     pub write_opcode: WriteOpcode, | ||||
|     pub write_page_size: WritePageSize, | ||||
|     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 { | ||||
| @ -48,6 +64,10 @@ impl Default for Config { | ||||
|             xip_offset: 0, | ||||
|             write_page_size: WritePageSize::_256BYTES, | ||||
|             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.ifconfig0.write(|w| { | ||||
|             w.addrmode().variant(AddressMode::_24BIT); | ||||
|             w.addrmode().variant(config.address_mode); | ||||
|             w.dpmenable().bit(config.deep_power_down.is_some()); | ||||
|             w.ppsize().variant(config.write_page_size); | ||||
|             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 { | ||||
|             w.sckdelay().bits(80); | ||||
|             w.sckdelay().bits(config.sck_delay); | ||||
|             w.dpmen().exit(); | ||||
|             w.spimode().mode0(); | ||||
|             w.sckfreq().bits(3); | ||||
|             w.spimode().variant(config.spi_mode); | ||||
|             w.sckfreq().bits(config.frequency as u8); | ||||
|             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> { | ||||
|         //info!("start_write ptr {}", data.as_ptr() as u32);
 | ||||
|         assert_eq!(data.as_ptr() as u32 % 4, 0); | ||||
|         //info!("start_write OK ptr");
 | ||||
|         assert_eq!(data.len() as u32 % 4, 0); | ||||
|         //info!("start_write OK len");
 | ||||
|         assert_eq!(address as u32 % 4, 0); | ||||
|         //info!("start_write OK addr");
 | ||||
| 
 | ||||
|         if address > FLASH_SIZE { | ||||
|             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> { | ||||
|         let bomb = DropBomb::new(); | ||||
| 
 | ||||
|         //info!("WRITE {} bytes at {}", data.len(), address);
 | ||||
|         self.start_write(address, data)?; | ||||
|         //info!("STARTED");
 | ||||
|         self.wait_ready().await; | ||||
|         //info!("WRITE DONE");
 | ||||
| 
 | ||||
|         bomb.defuse(); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user