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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user