1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
//! This example test the flash connected to the RP2040 chip.
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
use defmt::*;
use embassy_executor::Spawner;
use embassy_rp::flash::{Async, ERASE_SIZE, FLASH_BASE};
use embassy_rp::peripherals::FLASH;
use embassy_time::Timer;
use {defmt_rtt as _, panic_probe as _};
const ADDR_OFFSET: u32 = 0x100000;
const FLASH_SIZE: usize = 2 * 1024 * 1024;
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_rp::init(Default::default());
info!("Hello World!");
// add some delay to give an attached debug probe time to parse the
// defmt RTT header. Reading that header might touch flash memory, which
// interferes with flash write operations.
// https://github.com/knurling-rs/defmt/pull/683
Timer::after_millis(10).await;
let mut flash = embassy_rp::flash::Flash::<_, Async, FLASH_SIZE>::new(p.FLASH, p.DMA_CH0);
// Get JEDEC id
let jedec = flash.blocking_jedec_id().unwrap();
info!("jedec id: 0x{:x}", jedec);
// Get unique id
let mut uid = [0; 8];
flash.blocking_unique_id(&mut uid).unwrap();
info!("unique id: {:?}", uid);
erase_write_sector(&mut flash, 0x00);
multiwrite_bytes(&mut flash, ERASE_SIZE as u32);
background_read(&mut flash, (ERASE_SIZE * 2) as u32).await;
loop {}
}
fn multiwrite_bytes(flash: &mut embassy_rp::flash::Flash<'_, FLASH, Async, FLASH_SIZE>, offset: u32) {
info!(">>>> [multiwrite_bytes]");
let mut read_buf = [0u8; ERASE_SIZE];
defmt::unwrap!(flash.blocking_read(ADDR_OFFSET + offset, &mut read_buf));
info!("Addr of flash block is {:x}", ADDR_OFFSET + offset + FLASH_BASE as u32);
info!("Contents start with {=[u8]}", read_buf[0..4]);
defmt::unwrap!(flash.blocking_erase(ADDR_OFFSET + offset, ADDR_OFFSET + offset + ERASE_SIZE as u32));
defmt::unwrap!(flash.blocking_read(ADDR_OFFSET + offset, &mut read_buf));
info!("Contents after erase starts with {=[u8]}", read_buf[0..4]);
if read_buf.iter().any(|x| *x != 0xFF) {
defmt::panic!("unexpected");
}
defmt::unwrap!(flash.blocking_write(ADDR_OFFSET + offset, &[0x01]));
defmt::unwrap!(flash.blocking_write(ADDR_OFFSET + offset + 1, &[0x02]));
defmt::unwrap!(flash.blocking_write(ADDR_OFFSET + offset + 2, &[0x03]));
defmt::unwrap!(flash.blocking_write(ADDR_OFFSET + offset + 3, &[0x04]));
defmt::unwrap!(flash.blocking_read(ADDR_OFFSET + offset, &mut read_buf));
info!("Contents after write starts with {=[u8]}", read_buf[0..4]);
if &read_buf[0..4] != &[0x01, 0x02, 0x03, 0x04] {
defmt::panic!("unexpected");
}
}
fn erase_write_sector(flash: &mut embassy_rp::flash::Flash<'_, FLASH, Async, FLASH_SIZE>, offset: u32) {
info!(">>>> [erase_write_sector]");
let mut buf = [0u8; ERASE_SIZE];
defmt::unwrap!(flash.blocking_read(ADDR_OFFSET + offset, &mut buf));
info!("Addr of flash block is {:x}", ADDR_OFFSET + offset + FLASH_BASE as u32);
info!("Contents start with {=[u8]}", buf[0..4]);
defmt::unwrap!(flash.blocking_erase(ADDR_OFFSET + offset, ADDR_OFFSET + offset + ERASE_SIZE as u32));
defmt::unwrap!(flash.blocking_read(ADDR_OFFSET + offset, &mut buf));
info!("Contents after erase starts with {=[u8]}", buf[0..4]);
if buf.iter().any(|x| *x != 0xFF) {
defmt::panic!("unexpected");
}
for b in buf.iter_mut() {
*b = 0xDA;
}
defmt::unwrap!(flash.blocking_write(ADDR_OFFSET + offset, &buf));
defmt::unwrap!(flash.blocking_read(ADDR_OFFSET + offset, &mut buf));
info!("Contents after write starts with {=[u8]}", buf[0..4]);
if buf.iter().any(|x| *x != 0xDA) {
defmt::panic!("unexpected");
}
}
async fn background_read(flash: &mut embassy_rp::flash::Flash<'_, FLASH, Async, FLASH_SIZE>, offset: u32) {
info!(">>>> [background_read]");
let mut buf = [0u32; 8];
defmt::unwrap!(flash.background_read(ADDR_OFFSET + offset, &mut buf)).await;
info!("Addr of flash block is {:x}", ADDR_OFFSET + offset + FLASH_BASE as u32);
info!("Contents start with {=u32:x}", buf[0]);
defmt::unwrap!(flash.blocking_erase(ADDR_OFFSET + offset, ADDR_OFFSET + offset + ERASE_SIZE as u32));
defmt::unwrap!(flash.background_read(ADDR_OFFSET + offset, &mut buf)).await;
info!("Contents after erase starts with {=u32:x}", buf[0]);
if buf.iter().any(|x| *x != 0xFFFFFFFF) {
defmt::panic!("unexpected");
}
for b in buf.iter_mut() {
*b = 0xDABA1234;
}
defmt::unwrap!(flash.blocking_write(ADDR_OFFSET + offset, unsafe {
core::slice::from_raw_parts(buf.as_ptr() as *const u8, buf.len() * 4)
}));
defmt::unwrap!(flash.background_read(ADDR_OFFSET + offset, &mut buf)).await;
info!("Contents after write starts with {=u32:x}", buf[0]);
if buf.iter().any(|x| *x != 0xDABA1234) {
defmt::panic!("unexpected");
}
}
|