|
| 1 | +#![no_main] |
| 2 | +#![no_std] |
| 3 | + |
| 4 | +use panic_halt as _; |
| 5 | +use stm32f0xx_hal as hal; |
| 6 | + |
| 7 | +use crate::hal::{ |
| 8 | + flash::{FlashExt, LockedFlash}, |
| 9 | + pac, |
| 10 | + prelude::*, |
| 11 | +}; |
| 12 | + |
| 13 | +use cortex_m_rt::entry; |
| 14 | +use embedded_storage::nor_flash::{NorFlash, ReadNorFlash}; |
| 15 | + |
| 16 | +/// # NOTE |
| 17 | +/// This example assumes a flash size of more than 16K. If your MCU has less or equal than 16K Bytes |
| 18 | +/// of flash memory, adjust the `memory.x` file and `OFFSET_START` + `OFFSET_END` constants accordingly. |
| 19 | +#[entry] |
| 20 | +fn main() -> ! { |
| 21 | + if let Some(mut p) = pac::Peripherals::take() { |
| 22 | + let _ = p.RCC.configure().freeze(&mut p.FLASH); |
| 23 | + |
| 24 | + // Check that flash is big enough for this example |
| 25 | + assert!(p.FLASH.len() > 16 * 1024); |
| 26 | + |
| 27 | + // All examples use the first 16K of flash for the program so we use the first page after that |
| 28 | + const OFFSET_START: u32 = 16 * 1024; |
| 29 | + const OFFSET_END: u32 = OFFSET_START + 1024; |
| 30 | + // Unlock flash before writing |
| 31 | + let mut unlocked_flash = p.FLASH.unlocked(); |
| 32 | + |
| 33 | + NorFlash::erase(&mut unlocked_flash, OFFSET_START, OFFSET_END).unwrap(); |
| 34 | + |
| 35 | + // Write some data to the start of that page |
| 36 | + let write_data = [0xC0_u8, 0xFF_u8, 0xEE_u8, 0x00_u8]; |
| 37 | + match NorFlash::write(&mut unlocked_flash, OFFSET_START, &write_data) { |
| 38 | + Err(_) => panic!(), |
| 39 | + Ok(_) => (), |
| 40 | + } |
| 41 | + |
| 42 | + // Read back the written data from flash |
| 43 | + let mut read_buffer: [u8; 4] = [0; 4]; |
| 44 | + unlocked_flash.read(OFFSET_START, &mut read_buffer).unwrap(); |
| 45 | + assert_eq!(write_data, read_buffer); |
| 46 | + |
| 47 | + // Lock flash by dropping it |
| 48 | + drop(unlocked_flash); |
| 49 | + |
| 50 | + // It is also possible to read "manually" using core functions |
| 51 | + let read_data = unsafe { |
| 52 | + core::slice::from_raw_parts( |
| 53 | + (p.FLASH.address() + OFFSET_START as usize) as *const u8, |
| 54 | + write_data.len(), |
| 55 | + ) |
| 56 | + }; |
| 57 | + for (i, d) in read_data.iter().enumerate() { |
| 58 | + read_buffer[i] = *d; |
| 59 | + } |
| 60 | + |
| 61 | + assert_eq!(write_data, read_buffer); |
| 62 | + |
| 63 | + // Reading is also possible on locked flash |
| 64 | + let mut locked_flash = LockedFlash::new(p.FLASH); |
| 65 | + locked_flash.read(OFFSET_START, &mut read_buffer).unwrap(); |
| 66 | + |
| 67 | + assert_eq!(write_data, read_buffer); |
| 68 | + } |
| 69 | + loop { |
| 70 | + continue; |
| 71 | + } |
| 72 | +} |
0 commit comments