|
| 1 | +//! Example code showing how to use the MT25QL128ABA on the STM32F746G Discovery Board. |
| 2 | +//! The intended behavior of the example is to write a known pattern to flash memory and |
| 3 | +//! read it back using both polling and DMA indirect modes of the QSPI HAL driver. |
| 4 | +//! The example will panic on failure and print messages over the debugger on success. |
| 5 | +//! See `mt25q.rs` for more details on the QSPI HAL driver. |
| 6 | +
|
| 7 | +#![no_main] |
| 8 | +#![no_std] |
| 9 | + |
| 10 | +extern crate panic_semihosting; |
| 11 | + |
| 12 | +use cortex_m_rt::entry; |
| 13 | +use cortex_m_semihosting::hprintln; |
| 14 | +use stm32f7xx_hal::{ |
| 15 | + dma::{Handle, Stream7, DMA}, |
| 16 | + pac::{self, DMA2}, |
| 17 | + prelude::*, |
| 18 | + rcc::{HSEClock, HSEClockMode, RccExt}, |
| 19 | + state, |
| 20 | +}; |
| 21 | + |
| 22 | +mod mt25q; |
| 23 | + |
| 24 | +#[entry] |
| 25 | +fn main() -> ! { |
| 26 | + let pac_periph = pac::Peripherals::take().unwrap(); |
| 27 | + let mut rcc = pac_periph.RCC; |
| 28 | + |
| 29 | + // Initialize flash driver, which will initialize QSPI driver |
| 30 | + let mut mt25q = mt25q::Mt25q::new( |
| 31 | + &mut rcc, |
| 32 | + pac_periph.GPIOB, |
| 33 | + pac_periph.GPIOD, |
| 34 | + pac_periph.GPIOE, |
| 35 | + pac_periph.QUADSPI, |
| 36 | + ); |
| 37 | + |
| 38 | + // Init clocks |
| 39 | + let hse_cfg = HSEClock::new(25.mhz(), HSEClockMode::Oscillator); |
| 40 | + let mut rcc = rcc.constrain(); |
| 41 | + |
| 42 | + // Setup DMA |
| 43 | + let dma = DMA::new(pac_periph.DMA2); |
| 44 | + let stream = dma.streams.stream7; |
| 45 | + let dma = dma.handle.enable(&mut rcc.ahb1); |
| 46 | + |
| 47 | + // Ramp up clocks to 216 MHz |
| 48 | + rcc.cfgr.hse(hse_cfg).sysclk(216.mhz()).freeze(); |
| 49 | + |
| 50 | + // Check that we can communicate with the flash device |
| 51 | + mt25q.check_id(); |
| 52 | + |
| 53 | + memory_example_polling(&mut mt25q); |
| 54 | + memory_example_dma(&mut mt25q, &dma, stream); |
| 55 | + |
| 56 | + loop {} |
| 57 | +} |
| 58 | + |
| 59 | +fn memory_example_polling(mt25q: &mut mt25q::Mt25q) { |
| 60 | + // Create a set of buffers for a memory at address `ADDR` of size `LEN` bytes |
| 61 | + const ADDR: u32 = 0x7003; |
| 62 | + const LEN: usize = 1035; |
| 63 | + let mut read_buffer: [u8; LEN] = [0; LEN]; |
| 64 | + let mut write_buffer: [u8; LEN] = [0; LEN]; |
| 65 | + for i in 0..LEN { |
| 66 | + write_buffer[i] = i as u8; |
| 67 | + } |
| 68 | + |
| 69 | + // Test erase + read |
| 70 | + let (num_erase, addr_erase) = mt25q.erase(ADDR, LEN); |
| 71 | + assert!(LEN <= num_erase as usize); |
| 72 | + assert!(addr_erase <= ADDR); |
| 73 | + |
| 74 | + mt25q.read(&mut read_buffer, ADDR, LEN); |
| 75 | + for i in 0..LEN { |
| 76 | + assert!(read_buffer[i] == 0xFF); |
| 77 | + } |
| 78 | + |
| 79 | + // Test write + read |
| 80 | + mt25q.write(ADDR, &mut write_buffer, LEN); |
| 81 | + mt25q.read(&mut read_buffer, ADDR, LEN); |
| 82 | + for i in 0..LEN { |
| 83 | + if write_buffer[i] != read_buffer[i] { |
| 84 | + panic!( |
| 85 | + "Error: Mismatch at address {:X}. Expected {:X} but read {:X}", |
| 86 | + ADDR + i as u32, |
| 87 | + write_buffer[i], |
| 88 | + read_buffer[i] |
| 89 | + ); |
| 90 | + } |
| 91 | + } |
| 92 | + |
| 93 | + hprintln!("Flash device memory test successful!").unwrap(); |
| 94 | +} |
| 95 | + |
| 96 | +fn memory_example_dma( |
| 97 | + mt25q: &mut mt25q::Mt25q, |
| 98 | + dma: &Handle<DMA2, state::Enabled>, |
| 99 | + stream: Stream7<DMA2>, |
| 100 | +) { |
| 101 | + // Create a set of buffers for a memory at address `ADDR` of size `LEN` bytes |
| 102 | + const ADDR: u32 = 0x7000; |
| 103 | + const LEN: usize = 4096; |
| 104 | + let mut read_buffer: [u8; LEN] = [0; LEN]; |
| 105 | + let mut write_buffer: [u8; LEN] = [0; LEN]; |
| 106 | + for i in 0..LEN { |
| 107 | + write_buffer[i] = i as u8; |
| 108 | + } |
| 109 | + |
| 110 | + // Test erase + read |
| 111 | + let (num_erase, addr_erase) = mt25q.erase(ADDR, LEN); |
| 112 | + assert!(LEN <= num_erase as usize); |
| 113 | + assert!(addr_erase <= ADDR); |
| 114 | + |
| 115 | + let stream = mt25q.read_dma(&mut read_buffer, ADDR, LEN, dma, stream); |
| 116 | + for i in 0..LEN { |
| 117 | + assert!(read_buffer[i] == 0xFF); |
| 118 | + } |
| 119 | + |
| 120 | + // Test write + read |
| 121 | + let stream = mt25q.write_dma(ADDR, &mut write_buffer, LEN, dma, stream); |
| 122 | + mt25q.read_dma(&mut read_buffer, ADDR, LEN, dma, stream); |
| 123 | + for i in 0..LEN { |
| 124 | + if write_buffer[i] != read_buffer[i] { |
| 125 | + panic!( |
| 126 | + "Error: Mismatch at address {:X}. Expected {:X} but read {:X}", |
| 127 | + ADDR + i as u32, |
| 128 | + write_buffer[i], |
| 129 | + read_buffer[i] |
| 130 | + ); |
| 131 | + } |
| 132 | + } |
| 133 | + |
| 134 | + hprintln!("Flash device memory DMA test successful!").unwrap(); |
| 135 | +} |
0 commit comments