@@ -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