From 8c74128ff6aaa2f785d8e994e82746a6e937e46c Mon Sep 17 00:00:00 2001 From: fenugrec Date: Fri, 15 Apr 2016 21:47:48 -0400 Subject: [PATCH] usb: st_usbfs_v2: allow unaligned buffers for st_usbfs_copy_from_pm() The previous implementation of copy_from_pm assumed the destination buffer was aligned on a 16-bit boundary. On M0/M0+ cores (stm32F0*, stm32L0*) this causes a hard fault. This implementation is from Kuldeep Dhaka's tree; it does a 16-bit copy only if the destination buffer is aligned, otherwise a bytewise copy. Fixes GH issues #401, #461 --- lib/stm32/st_usbfs_v2.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/stm32/st_usbfs_v2.c b/lib/stm32/st_usbfs_v2.c index 0ef1c24e..f6a41783 100644 --- a/lib/stm32/st_usbfs_v2.c +++ b/lib/stm32/st_usbfs_v2.c @@ -79,15 +79,23 @@ void st_usbfs_copy_to_pm(volatile void *vPM, const void *buf, uint16_t len) */ void st_usbfs_copy_from_pm(void *buf, const volatile void *vPM, uint16_t len) { - uint16_t *lbuf = buf; const volatile uint16_t *PM = vPM; uint8_t odd = len & 1; + len >>= 1; - for (len >>= 1; len; PM++, lbuf++, len--) { - *lbuf = *PM; + if (((uintptr_t) buf) & 0x01) { + for (; len; PM++, len--) { + uint16_t value = *PM; + *(uint8_t *) buf++ = value; + *(uint8_t *) buf++ = value >> 8; + } + } else { + for (; len; PM++, buf += 2, len--) { + *(uint16_t *) buf = *PM; + } } if (odd) { - *(uint8_t *) lbuf = *(uint8_t *) PM; + *(uint8_t *) buf = *(uint8_t *) PM; } }