Skip to content

Commit 3c0fc11

Browse files
authored
Merge pull request #404 from arduino/cdc-bugfix
Removal of delay within USBDevice::ISRHandler
2 parents 67bf93e + 4c5ac51 commit 3c0fc11

File tree

1 file changed

+31
-13
lines changed

1 file changed

+31
-13
lines changed

cores/arduino/USB/USBCore.cpp

+31-13
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ void USBDeviceClass::initEP(uint32_t ep, uint32_t config)
425425

426426
// Setup Control IN
427427
usbd.epBank1SetSize(ep, 64);
428-
usbd.epBank1SetAddress(ep, &udd_ep_in_cache_buffer[0]);
428+
usbd.epBank1SetAddress(ep, &udd_ep_in_cache_buffer[ep]);
429429
usbd.epBank1SetType(ep, 1); // CONTROL IN
430430

431431
// Release OUT EP
@@ -469,9 +469,6 @@ uint32_t USBDeviceClass::recvControl(void *_data, uint32_t len)
469469
{
470470
uint8_t *data = reinterpret_cast<uint8_t *>(_data);
471471

472-
// The RAM Buffer is empty: we can receive data
473-
usbd.epBank0ResetReady(0);
474-
475472
//usbd.epBank0AckSetupReceived(0);
476473
uint32_t read = armRecvCtrlOUT(0);
477474
if (read > len)
@@ -551,7 +548,17 @@ uint8_t USBDeviceClass::armRecvCtrlOUT(uint32_t ep)
551548
{
552549
// Get endpoint configuration from setting register
553550
usbd.epBank0SetAddress(ep, &udd_ep_out_cache_buffer[ep]);
554-
usbd.epBank0SetMultiPacketSize(ep, 8);
551+
/* Atmel-42181G–SAM-D21_Datasheet–09/2015 / Page 806
552+
*
553+
* For OUT endpoints, MULTI_PACKET_SIZE holds the total
554+
* data size for the complete transfer. This value must
555+
* be a multiple of the maximum packet size.
556+
*
557+
* Since SIZE is 64 (see 'USBDeviceClass::initEP') for
558+
* all endpoints MULTI_PACKET_SIZE should not be set to
559+
* a value < SIZE, this means at least to 64.
560+
*/
561+
usbd.epBank0SetMultiPacketSize(ep, 64);
555562
usbd.epBank0SetByteCount(ep, 0);
556563

557564
usbd.epBank0ResetReady(ep);
@@ -830,23 +837,34 @@ void USBDeviceClass::ISRHandler()
830837
#endif
831838
}
832839

840+
/* Remove any stall requests for endpoint #0 */
841+
if (usbd.epBank0IsStalled(0)) { usbd.epBank0DisableStalled(0); }
842+
833843
// Endpoint 0 Received Setup interrupt
834844
if (usbd.epBank0IsSetupReceived(0))
835845
{
836-
USBSetup *setup = reinterpret_cast<USBSetup *>(udd_ep_out_cache_buffer[0]);
837-
838-
delayMicroseconds(20);
839-
/* Clear the Bank 0 ready flag on Control OUT */
840-
// The RAM Buffer is empty: we can receive data
846+
/* Retrieve received endpoint #0 data from buffer */
847+
USBSetup setup;
848+
memcpy(&setup, udd_ep_out_cache_buffer[0], sizeof(USBSetup));
849+
850+
/* Tell the USB hardware that we are ready to receive more data for endpoint #0 and also reset the byte count
851+
* for endpoint #0 - the clearing seems to be necessary for the code to function correctly, although the datasheet
852+
* is not clear on the subject.
853+
*
854+
* Atmel-42181G–SAM-D21_Datasheet–09/2015 / Page 806
855+
* For IN endpoints, BYTE_COUNT holds the number of bytes to be sent in the next IN transaction.
856+
* For OUT endpoint or SETUP endpoints, BYTE_COUNT holds the number of bytes received upon the last OUT or SETUP transaction.
857+
*/
858+
usbd.epBank0SetByteCount(0, 0);
841859
usbd.epBank0ResetReady(0);
842860

843861
bool ok;
844-
if (REQUEST_STANDARD == (setup->bmRequestType & REQUEST_TYPE)) {
862+
if (REQUEST_STANDARD == (setup.bmRequestType & REQUEST_TYPE)) {
845863
// Standard Requests
846-
ok = handleStandardSetup(*setup);
864+
ok = handleStandardSetup(setup);
847865
} else {
848866
// Class Interface Requests
849-
ok = handleClassInterfaceSetup(*setup);
867+
ok = handleClassInterfaceSetup(setup);
850868
}
851869

852870
if (ok) {

0 commit comments

Comments
 (0)