From c0c1566bea34419a8b165a489278114363de5a5e Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 Apr 2026 23:50:12 +0700 Subject: [PATCH 1/2] rp2040: fix RP2350 hard fault in unaligned_memcpy to USB DPRAM Use volatile byte accesses to prevent the compiler from widening the byte-by-byte copy loop into 16/32-bit accesses, which cause a hard fault on RP2350 when targeting USB DPRAM (device memory). Closes #3554 --- src/portable/raspberrypi/rp2040/rp2040_usb.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 1b13934d31..f5ba81dd72 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -51,10 +51,14 @@ critical_section_t rp2usb_lock; //--------------------------------------------------------------------+ // Implementation //--------------------------------------------------------------------+ -// Provide own byte by byte memcpy as not all copies are aligned +// Provide own byte by byte memcpy as not all copies are aligned. +// Use volatile to prevent compiler from widening to 16/32-bit accesses +// which cause hard fault on RP2350 when dst/src points to USB DPRAM. static void unaligned_memcpy(uint8_t *dst, const uint8_t *src, size_t n) { + volatile uint8_t *vdst = dst; + const volatile uint8_t *vsrc = src; while (n--) { - *dst++ = *src++; + *vdst++ = *vsrc++; } } From 9515ba8e795a582f4e62955b8d4398066e2acbb1 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Thu, 2 Apr 2026 23:55:12 +0700 Subject: [PATCH 2/2] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/portable/raspberrypi/rp2040/rp2040_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index f5ba81dd72..83ac48ec29 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -53,7 +53,7 @@ critical_section_t rp2usb_lock; //--------------------------------------------------------------------+ // Provide own byte by byte memcpy as not all copies are aligned. // Use volatile to prevent compiler from widening to 16/32-bit accesses -// which cause hard fault on RP2350 when dst/src points to USB DPRAM. +// which cause hard fault on RP2350 when dst/src point to USB DPRAM. static void unaligned_memcpy(uint8_t *dst, const uint8_t *src, size_t n) { volatile uint8_t *vdst = dst; const volatile uint8_t *vsrc = src;