usb-dwc: handle any-aligned buffers
This is required to support armv6m targets using this code.
This commit is contained in:
parent
a2ee90fbfe
commit
a0669421e1
@ -194,6 +194,10 @@ uint16_t dwc_ep_write_packet(usbd_device *usbd_dev, uint8_t addr,
|
|||||||
const void *buf, uint16_t len)
|
const void *buf, uint16_t len)
|
||||||
{
|
{
|
||||||
const uint32_t *buf32 = buf;
|
const uint32_t *buf32 = buf;
|
||||||
|
#if defined(__ARM_ARCH_6M__)
|
||||||
|
const uint8_t *buf8 = buf;
|
||||||
|
uint32_t word32;
|
||||||
|
#endif /* defined(__ARM_ARCH_6M__) */
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
addr &= 0x7F;
|
addr &= 0x7F;
|
||||||
@ -208,10 +212,28 @@ uint16_t dwc_ep_write_packet(usbd_device *usbd_dev, uint8_t addr,
|
|||||||
REBASE(OTG_DIEPCTL(addr)) |= OTG_DIEPCTL0_EPENA |
|
REBASE(OTG_DIEPCTL(addr)) |= OTG_DIEPCTL0_EPENA |
|
||||||
OTG_DIEPCTL0_CNAK;
|
OTG_DIEPCTL0_CNAK;
|
||||||
|
|
||||||
/* Copy buffer to endpoint FIFO, note - memcpy does not work */
|
/* Copy buffer to endpoint FIFO, note - memcpy does not work.
|
||||||
|
* ARMv7M supports non-word-aligned accesses, ARMv6M does not. */
|
||||||
|
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||||
for (i = len; i > 0; i -= 4) {
|
for (i = len; i > 0; i -= 4) {
|
||||||
REBASE(OTG_FIFO(addr)) = *buf32++;
|
REBASE(OTG_FIFO(addr)) = *buf32++;
|
||||||
}
|
}
|
||||||
|
#endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */
|
||||||
|
|
||||||
|
#if defined(__ARM_ARCH_6M__)
|
||||||
|
/* Take care of word-aligned and non-word-aligned buffers */
|
||||||
|
if (((uint32_t)buf8 & 0x3) == 0) {
|
||||||
|
for (i = len; i > 0; i -= 4) {
|
||||||
|
REBASE(OTG_FIFO(addr)) = *buf32++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = len; i > 0; i -= 4) {
|
||||||
|
memcpy(&word32, buf8, 4);
|
||||||
|
REBASE(OTG_FIFO(addr)) = word32;
|
||||||
|
buf8 += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* defined(__ARM_ARCH_6M__) */
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
@ -221,6 +243,10 @@ uint16_t dwc_ep_read_packet(usbd_device *usbd_dev, uint8_t addr,
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
uint32_t *buf32 = buf;
|
uint32_t *buf32 = buf;
|
||||||
|
#if defined(__ARM_ARCH_6M__)
|
||||||
|
uint8_t *buf8 = buf;
|
||||||
|
uint32_t word32;
|
||||||
|
#endif /* defined(__ARM_ARCH_6M__) */
|
||||||
uint32_t extra;
|
uint32_t extra;
|
||||||
|
|
||||||
/* We do not need to know the endpoint address since there is only one
|
/* We do not need to know the endpoint address since there is only one
|
||||||
@ -229,10 +255,32 @@ uint16_t dwc_ep_read_packet(usbd_device *usbd_dev, uint8_t addr,
|
|||||||
(void) addr;
|
(void) addr;
|
||||||
len = MIN(len, usbd_dev->rxbcnt);
|
len = MIN(len, usbd_dev->rxbcnt);
|
||||||
|
|
||||||
|
/* ARMv7M supports non-word-aligned accesses, ARMv6M does not. */
|
||||||
|
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||||
for (i = len; i >= 4; i -= 4) {
|
for (i = len; i >= 4; i -= 4) {
|
||||||
*buf32++ = REBASE(OTG_FIFO(0));
|
*buf32++ = REBASE(OTG_FIFO(0));
|
||||||
usbd_dev->rxbcnt -= 4;
|
usbd_dev->rxbcnt -= 4;
|
||||||
}
|
}
|
||||||
|
#endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */
|
||||||
|
|
||||||
|
#if defined(__ARM_ARCH_6M__)
|
||||||
|
/* Take care of word-aligned and non-word-aligned buffers */
|
||||||
|
if (((uint32_t)buf8 & 0x3) == 0) {
|
||||||
|
for (i = len; i >= 4; i -= 4) {
|
||||||
|
*buf32++ = REBASE(OTG_FIFO(0));
|
||||||
|
usbd_dev->rxbcnt -= 4;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = len; i >= 4; i -= 4) {
|
||||||
|
word32 = REBASE(OTG_FIFO(0));
|
||||||
|
memcpy(buf8, &word32, 4);
|
||||||
|
usbd_dev->rxbcnt -= 4;
|
||||||
|
buf8 += 4;
|
||||||
|
}
|
||||||
|
/* buf32 needs to be updated as it is used for extra */
|
||||||
|
buf32 = (uint32_t *)buf8;
|
||||||
|
}
|
||||||
|
#endif /* defined(__ARM_ARCH_6M__) */
|
||||||
|
|
||||||
if (i) {
|
if (i) {
|
||||||
extra = REBASE(OTG_FIFO(0));
|
extra = REBASE(OTG_FIFO(0));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user