Skip to content

Commit ee2d18e

Browse files
committed
A fix for the SerialUSB buffer overflow bug.
Send the data in chunks based on the buffer size instead of assuming that the whole send data will fit into the buffer.
1 parent 6f2482c commit ee2d18e

File tree

3 files changed

+30
-7
lines changed

3 files changed

+30
-7
lines changed

cores/arduino/USB/USBCore.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,32 @@ uint32_t USBD_Send(uint32_t ep, const void* d, uint32_t len)
120120
int r = len;
121121
const uint8_t* data = (const uint8_t*)d;
122122

123-
if (!_usbConfiguration)
124-
{
125-
TRACE_CORE(printf("pb conf\n\r");)
123+
if (!_usbConfiguration)
124+
{
125+
TRACE_CORE(printf("pb conf\n\r");)
126126
return -1;
127-
}
128-
UDD_Send(ep, data, len);
127+
}
128+
129+
size_t i = 0;
130+
// Ensure the chunk size is aligned 4
131+
size_t chunkSize = UDD_IN_CACHE_SIZE -(UDD_IN_CACHE_SIZE % 4);
132+
133+
// Send the full chunks
134+
for (i = 0; i < (len / chunkSize); i++)
135+
{
136+
UDD_Send(ep, data + (i*chunkSize), chunkSize);
137+
138+
/* Clear the transfer complete flag */
139+
udd_clear_IN_transf_cplt(ep);
140+
/* Set the bank as ready */
141+
udd_IN_transfer_allowed(ep);
142+
143+
/* Wait for transfer to complete */
144+
while (!udd_is_IN_transf_cplt(ep)); // need fire exit.
145+
}
146+
147+
// Send the remainder
148+
UDD_Send(ep, data + (i * chunkSize), len % chunkSize);
129149

130150
/* Clear the transfer complete flag */
131151
udd_clear_IN_transf_cplt(ep);

cores/arduino/USB/samd21_device.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ extern "C"{
3434
//#define TRACE_DEVICE(x) x
3535
#define TRACE_DEVICE(x)
3636

37-
__attribute__((__aligned__(4))) /*__attribute__((__section__(".bss_hram0")))*/ uint8_t udd_ep_out_cache_buffer[4][64];
38-
__attribute__((__aligned__(4))) /*__attribute__((__section__(".bss_hram0")))*/ uint8_t udd_ep_in_cache_buffer[4][128];
37+
__attribute__((__aligned__(4))) /*__attribute__((__section__(".bss_hram0")))*/ uint8_t udd_ep_out_cache_buffer[4][UDD_OUT_CACHE_SIZE];
38+
__attribute__((__aligned__(4))) /*__attribute__((__section__(".bss_hram0")))*/ uint8_t udd_ep_in_cache_buffer[4][UDD_IN_CACHE_SIZE];
3939

4040
/**
4141
* USB SRAM data containing pipe descriptor table

cores/arduino/USB/samd21_device.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ extern "C" {
2626
#define EP0 0
2727
#define EPX_SIZE 64// 64 for Full Speed, EPT size max is 1024
2828

29+
#define UDD_OUT_CACHE_SIZE 64
30+
#define UDD_IN_CACHE_SIZE 128
31+
2932
// Force device low speed mode
3033
#define udd_force_low_speed() USB->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_SPDCONF_Msk; USB->DEVICE.CTRLB.reg |= USB_DEVICE_CTRLB_SPDCONF_1_Val
3134
// Force full speed mode

0 commit comments

Comments
 (0)