Skip to content

Commit b8af853

Browse files
Preserve PSRAM QMI interface around flash ops
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 b8af853

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

cores/rp2040/flash_wrapper.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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+
#ifdef PICO_RP2350
22+
#include <hardware/structs/qmi.h>
23+
#endif
24+
25+
extern "C" {
26+
extern void __real_flash_range_erase(uint32_t flash_offs, size_t count);
27+
void __wrap_flash_range_erase(uint32_t flash_offs, size_t count) {
28+
#ifdef PICO_RP2350
29+
auto s = qmi_hw->m[1];
30+
#endif
31+
__real_flash_range_erase(flash_offs, count);
32+
#ifdef PICO_RP2350
33+
qmi_hw->m[1] = s;
34+
__compiler_memory_barrier();
35+
#endif
36+
}
37+
38+
extern void __real_flash_range_program(uint32_t flash_offs, const uint8_t *data, size_t count);
39+
void __wrap_flash_range_program(uint32_t flash_offs, const uint8_t *data, size_t count) {
40+
#ifdef PICO_RP2350
41+
auto s = qmi_hw->m[1];
42+
#endif
43+
__real_flash_range_program(flash_offs, data, count);
44+
#ifdef PICO_RP2350
45+
qmi_hw->m[1] = s;
46+
__compiler_memory_barrier();
47+
#endif
48+
}
49+
50+
extern void __real_flash_get_unique_id(uint8_t *id_out);
51+
void __wrap_flash_get_unique_id(uint8_t *id_out) {
52+
#ifdef PICO_RP2350
53+
auto s = qmi_hw->m[1];
54+
#endif
55+
__real_flash_get_unique_id(id_out);
56+
#ifdef PICO_RP2350
57+
qmi_hw->m[1] = s;
58+
__compiler_memory_barrier();
59+
#endif
60+
}
61+
62+
extern void __real_flash_do_cmd(const uint8_t *txbuf, uint8_t *rxbuf, size_t count);
63+
void __wrap_flash_do_cmd(const uint8_t *txbuf, uint8_t *rxbuf, size_t count) {
64+
#ifdef PICO_RP2350
65+
auto s = qmi_hw->m[1];
66+
#endif
67+
__real_flash_do_cmd(txbuf, rxbuf, count);
68+
#ifdef PICO_RP2350
69+
qmi_hw->m[1] = s;
70+
__compiler_memory_barrier();
71+
#endif
72+
}
73+
};

lib/core_wrap.txt

Lines changed: 5 additions & 0 deletions
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)