Skip to content

Commit fdd7557

Browse files
Preserve PSRAM QMI interface around flash ops (#2539)
The flash ROM routines seem to overwrite the QMI configuration we set for PSRAM, rendering it unreadable after any erase or write or ID command. Wrap the 4 flash control functions to preserve the QMI state on the RP2350. On the RP2040, simply pass through the call. Fixes #2537
1 parent 49f83c4 commit fdd7557

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

cores/rp2040/flash_wrapper.cpp

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
Flash wrappers to protect PSRAM access on the RP2350
3+
4+
Copyright (c) 2024 Earle F. Philhower, III <[email protected]>
5+
6+
This library is free software; you can redistribute it and/or
7+
modify it under the terms of the GNU Lesser General Public
8+
License as published by the Free Software Foundation; either
9+
version 2.1 of the License, or (at your option) any later version.
10+
11+
This library is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
Lesser General Public License for more details.
15+
16+
You should have received a copy of the GNU Lesser General Public
17+
License along with this library; if not, write to the Free Software
18+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19+
*/
20+
21+
#include <hardware/flash.h>
22+
23+
#ifdef PICO_RP2350
24+
#include <hardware/structs/qmi.h>
25+
#endif
26+
27+
extern "C" {
28+
extern void __real_flash_range_erase(uint32_t flash_offs, size_t count);
29+
void __wrap_flash_range_erase(uint32_t flash_offs, size_t count) {
30+
#ifdef PICO_RP2350
31+
auto s = qmi_hw->m[1];
32+
#endif
33+
__real_flash_range_erase(flash_offs, count);
34+
#ifdef PICO_RP2350
35+
qmi_hw->m[1] = s;
36+
__compiler_memory_barrier();
37+
#endif
38+
}
39+
40+
extern void __real_flash_range_program(uint32_t flash_offs, const uint8_t *data, size_t count);
41+
void __wrap_flash_range_program(uint32_t flash_offs, const uint8_t *data, size_t count) {
42+
#ifdef PICO_RP2350
43+
auto s = qmi_hw->m[1];
44+
#endif
45+
__real_flash_range_program(flash_offs, data, count);
46+
#ifdef PICO_RP2350
47+
qmi_hw->m[1] = s;
48+
__compiler_memory_barrier();
49+
#endif
50+
}
51+
52+
extern void __real_flash_get_unique_id(uint8_t *id_out);
53+
void __wrap_flash_get_unique_id(uint8_t *id_out) {
54+
#ifdef PICO_RP2350
55+
auto s = qmi_hw->m[1];
56+
#endif
57+
__real_flash_get_unique_id(id_out);
58+
#ifdef PICO_RP2350
59+
qmi_hw->m[1] = s;
60+
__compiler_memory_barrier();
61+
#endif
62+
}
63+
64+
extern void __real_flash_do_cmd(const uint8_t *txbuf, uint8_t *rxbuf, size_t count);
65+
void __wrap_flash_do_cmd(const uint8_t *txbuf, uint8_t *rxbuf, size_t count) {
66+
#ifdef PICO_RP2350
67+
auto s = qmi_hw->m[1];
68+
#endif
69+
__real_flash_do_cmd(txbuf, rxbuf, count);
70+
#ifdef PICO_RP2350
71+
qmi_hw->m[1] = s;
72+
__compiler_memory_barrier();
73+
#endif
74+
}
75+
};

lib/core_wrap.txt

+5
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,8 @@
6767
-Wl,--wrap=cyw43_tcpip_link_status
6868
-Wl,--wrap=cyw43_cb_tcpip_init
6969
-Wl,--wrap=cyw43_cb_tcpip_deinit
70+
71+
-Wl,--wrap=flash_range_erase
72+
-Wl,--wrap=flash_range_program
73+
-Wl,--wrap=flash_get_unique_id
74+
-Wl,--wrap=flash_do_cmd

0 commit comments

Comments
 (0)