Skip to content

Commit 4c5ac51

Browse files
committed
Deleting superflous call to 'usbd.epBank0ResetReady' - this function is already called within 'USBDeviceClass::ISRHandler' and 'USBDeviceClass::recvControl' is called by 'handleClassInterfaceSetup' within the ISR
Bugfix - removal of delay within USBDeviceClass::ISRHandler - remove stall requests of endpoint #0 OUT (bank #0) if present - copy data from cache into structure instead of referencing it via pointer. When referencing via pointer the content of the structure can change if new data is written to the buffer. - Fixing MULTI_PACKET_SIZE parameter of call to 'usbd.epBank0SetMultiPacketSize' within 'USBDeviceClass::armRecvCtrlOUT' to correct size, MULTI_PACKET_SIZE should not be set to a value < SIZE, this means at least to 64. - resetting byte count for endpoint #0 seems to eliminate issue of the bootloader not being triggered.
1 parent f6ae6d8 commit 4c5ac51

File tree

1 file changed

+30
-12
lines changed

1 file changed

+30
-12
lines changed

cores/arduino/USB/USBCore.cpp

+30-12
Original file line numberDiff line numberDiff line change
@@ -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)