Skip to content

Commit 75ca72f

Browse files
committed
remove (almost all of) transcSetup
1 parent 826dc63 commit 75ca72f

File tree

2 files changed

+29
-224
lines changed

2 files changed

+29
-224
lines changed

cores/arduino/USBCore.cpp

Lines changed: 25 additions & 217 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ static uint8_t* stringDescs[] = {
120120

121121
usb_desc desc = {
122122
.dev_desc = (uint8_t *)&devDesc,
123-
.config_desc = (uint8_t *)&configDesc,
123+
.config_desc = nullptr,
124124
.bos_desc = nullptr,
125125
.strings = stringDescs
126126
};
@@ -304,29 +304,6 @@ uint8_t* EPBuffer<L>::ptr()
304304
return this->buf;
305305
}
306306

307-
// Busy loop until an OUT packet has been received. Returns ‘false’ if
308-
// the device has been reset.
309-
// Must be called via ISR
310-
template<size_t L>
311-
bool EPBuffer<L>::waitForReadComplete()
312-
{
313-
Serial1.print(F("RW"));
314-
Serial1.println(this->ep);
315-
Serial1.flush();
316-
// auto start = getCurrentMillis();
317-
auto ok = true;
318-
while (ok && this->rxWaiting) {
319-
ok = EPBuffers().pollEPStatus();
320-
// if (getCurrentMillis() - start > 5) {
321-
// EPBuffers().buf(ep).transcIn();
322-
// return false;
323-
// }
324-
}
325-
Serial1.println(ok);
326-
Serial1.flush();
327-
return ok;
328-
}
329-
330307
// Busy loop until the latest IN packet has been sent. Returns ‘true’
331308
// if a new packet can be queued when this call completes.
332309
// Must run with interrupts disabled, which will be temporarily reenabled
@@ -337,16 +314,11 @@ bool EPBuffer<L>::waitForWriteComplete()
337314
auto ok = true;
338315
do {
339316
usb_enable_interrupts();
340-
ok = EPBuffers().pollEPStatus();
341317
switch (USBCore().usbDev().cur_status) {
342318
case USBD_DEFAULT:
343319
case USBD_ADDRESSED:
344-
// For non-EP0, abort if no longer configured
345-
if (ep != 0) {
346-
ok = false;
347-
break;
348-
}
349-
// fall through
320+
ok = false;
321+
break;
350322
default:
351323
break;
352324
}
@@ -387,90 +359,6 @@ EPDesc* EPBuffers_<L, C>::desc(uint8_t ep)
387359
return &descs[ep];
388360
}
389361

390-
// Check if any endpoints have a received data or finished sending
391-
// data, updating their ‘waiting’ flags as a side-effect.
392-
//
393-
// Returns ‘false’ if the host has reset the device.
394-
template<size_t L, size_t C>
395-
bool EPBuffers_<L, C>::pollEPStatus()
396-
{
397-
/*
398-
* I’m not sure how much of this is necessary, but this is the
399-
* series of checks that’s used by ‘usbd_isr’ to verify the IN
400-
* packet has been sent.
401-
*/
402-
403-
uint16_t int_status = (uint16_t)USBD_INTF;
404-
uint8_t ep_num = int_status & INTF_EPNUM;
405-
/*
406-
* If we are in interrupt context, we need to check for a
407-
* device reset and terminate early so we don't spin forever
408-
* waiting to complete a packet the host is no longer paying
409-
* attention to.
410-
*
411-
* We /do not/ clear the flag, allowing the ISR to fire as
412-
* soon as we've left this call, which will call into the
413-
* normal reset routine.
414-
*/
415-
auto ok = true;
416-
if ((int_status & INTF_RSTIF) == INTF_RSTIF) {
417-
// Indicate the device was reset to callers.
418-
ok = false;
419-
} else if ((int_status & INTF_STIF) == INTF_STIF) {
420-
if ((int_status & INTF_DIR) == INTF_DIR
421-
&& (USBD_EPxCS(ep_num) & EPxCS_RX_ST) == EPxCS_RX_ST) {
422-
423-
if (USBD_EPxCS(ep_num) & EPxCS_SETUP) {
424-
/*
425-
* We should abort a control transfer if we receive an
426-
* unexpected SETUP token, but unwinding all of that deeply
427-
* nested control flow is too error-prone.
428-
*
429-
* Also, we'd have to check whether the current flush is
430-
* part of a control transfer, or a non-control transfer,
431-
* so we can decide whether to abort the flush.
432-
*/
433-
Serial1.println(F("SURPRISE SETUP"));
434-
Serial1.flush();
435-
}
436-
usb_transc *transc = &USBCore().usbDev().transc_out[ep_num];
437-
auto count = 0;
438-
if (transc->xfer_buf) {
439-
count = USBCore().usbDev().drv_handler->ep_read(transc->xfer_buf, ep_num, (uint8_t)EP_BUF_SNG);
440-
transc->xfer_buf += count;
441-
transc->xfer_count += count;
442-
}
443-
if ((transc->xfer_count >= transc->xfer_len)
444-
|| (count < transc->max_len)) {
445-
/*
446-
* This bypasses the low-level Setup Data OUT stage
447-
* completion handlers, because we might need to read more
448-
* than one packet.
449-
*/
450-
EPBuffers().buf(ep_num).transcOut();
451-
} else {
452-
/*
453-
* Low-level firmware does the following, which we won't
454-
* do, because we only ever configure the transc to read a
455-
* single packet at a time.
456-
*/
457-
// udev->drv_handler->ep_rx_enable(udev, ep_num);
458-
}
459-
USBD_EP_RX_ST_CLEAR(ep_num);
460-
} else if ((int_status & INTF_DIR) == 0
461-
&& (USBD_EPxCS(ep_num) & EPxCS_TX_ST) == EPxCS_TX_ST) {
462-
/*
463-
* This bypasses low-level Setup Data IN stage completion
464-
* handlers, because we might need to write more than one
465-
* packet.
466-
*/
467-
EPBuffers().buf(ep_num).transcIn();
468-
USBD_EP_TX_ST_CLEAR(ep_num);
469-
}
470-
}
471-
return ok;
472-
}
473-
474362
EPBuffers_<USB_EP_SIZE, EP_COUNT>& EPBuffers()
475363
{
476364
static EPBuffers_<USB_EP_SIZE, EP_COUNT> obj;
@@ -558,6 +446,7 @@ class ClassCore
558446
// TODO: remove this copy.
559447
arduino::USBSetup setup;
560448
memcpy(&setup, req, sizeof(setup));
449+
USBCore().setupClass(req->wLength);
561450
if (setup.bRequest == USB_GET_DESCRIPTOR) {
562451
auto sent = PluggableUSB().getDescriptor(setup);
563452
if (sent > 0) {
@@ -671,16 +560,11 @@ USBCore_::USBCore_()
671560

672561
this->oldTranscSetup = usbd.ep_transc[0][TRANSC_SETUP];
673562
usbd.ep_transc[0][TRANSC_SETUP] = USBCore_::transcSetupHelper;
674-
675-
this->oldTranscOut = usbd.ep_transc[0][TRANSC_OUT];
676-
usbd.ep_transc[0][TRANSC_OUT] = USBCore_::transcOutHelper;
677-
678-
this->oldTranscIn = usbd.ep_transc[0][TRANSC_IN];
679-
usbd.ep_transc[0][TRANSC_IN] = USBCore_::transcInHelper;
680563
}
681564

682565
void USBCore_::connect()
683566
{
567+
USBCore().buildDeviceConfigDescriptor();
684568
usb_connect();
685569
}
686570

@@ -689,6 +573,14 @@ void USBCore_::disconnect()
689573
usb_disconnect();
690574
}
691575

576+
void USBCore_::setupClass(uint16_t wLength)
577+
{
578+
this->ctlIdx = 0;
579+
this->ctlOutBuf = NULL;
580+
this->ctlOutLen = 0;
581+
this->maxWrite = wLength;
582+
}
583+
692584
// Send ‘len’ octets of ‘d’ through the control pipe (endpoint 0).
693585
// Blocks until ‘len’ octets are sent. Returns the number of octets
694586
// sent, or -1 on error.
@@ -912,36 +804,11 @@ usb_dev& USBCore_::usbDev()
912804
return usbd;
913805
}
914806

915-
/*
916-
* TODO: This is a heck of a monkey patch that just seems to get more
917-
* fragile every time functionality is needed in the rest of the
918-
* Arduino core.
919-
*
920-
* It was initially intended to try and use as much of the firmware
921-
* library’s code as possible, but it’s just not a good fit, and
922-
* should probably be scrapped and started again now that more of its
923-
* scope is known.
924-
*/
807+
/* Log the raw Setup stage data packet */
925808
void USBCore_::transcSetup(usb_dev* usbd, uint8_t ep)
926809
{
927810
(void)ep;
928-
this->didCtlIn = false;
929-
this->didCtlOut = false;
930-
this->ctlIdx = 0;
931-
this->ctlOutBuf = NULL;
932-
// Configure empty transactions for default
933-
usb_transc_config(&usbd->transc_in[0], NULL, 0, 0);
934-
usb_transc_config(&usbd->transc_out[0], NULL, 0, 0);
935-
936-
usb_reqsta reqstat = REQ_NOTSUPP;
937-
938-
uint16_t count = usbd->drv_handler->ep_read((uint8_t *)(&usbd->control.req), 0, (uint8_t)EP_BUF_SNG);
939-
940-
if (count != USB_SETUP_PACKET_LEN) {
941-
usbd_ep_stall(usbd, 0);
942-
943-
return;
944-
}
811+
(void)usbd->drv_handler->ep_read((uint8_t *)(&usbd->control.req), 0, (uint8_t)EP_BUF_SNG);
945812

946813
for (int i = 0; i < 8; i++) {
947814
uint8_t x = ((uint8_t *)&usbd->control.req)[i];
@@ -952,88 +819,30 @@ void USBCore_::transcSetup(usb_dev* usbd, uint8_t ep)
952819
Serial1.println();
953820
Serial1.flush();
954821

955-
this->maxWrite = usbd->control.req.wLength;
956-
switch (usbd->control.req.bmRequestType & USB_REQTYPE_MASK) {
957-
/* standard device request */
958-
case USB_REQTYPE_STRD:
959-
if (usbd->control.req.bRequest == USB_GET_DESCRIPTOR
960-
&& (usbd->control.req.bmRequestType & USB_RECPTYPE_MASK) == USB_RECPTYPE_DEV) {
961-
if ((usbd->control.req.wValue >> 8) == USB_DESCTYPE_CONFIG) {
962-
this->sendDeviceConfigDescriptor();
963-
reqstat = REQ_SUPP;
964-
break;
965-
}
966-
}
967-
// This calls into ClassCore for class descriptors
968-
reqstat = usbd_standard_request(usbd, &usbd->control.req);
969-
break;
970-
971-
/* device class request */
972-
case USB_REQTYPE_CLASS:
973-
// Calls into class_core->req_process, does nothing else.
974-
reqstat = usbd_class_request(usbd, &usbd->control.req);
975-
break;
976-
977-
/* vendor defined request */
978-
case USB_REQTYPE_VENDOR:
979-
// Does nothing.
980-
reqstat = usbd_vendor_request(usbd, &usbd->control.req);
981-
break;
982-
983-
default:
984-
break;
985-
}
986-
987-
if (reqstat != REQ_SUPP) {
988-
usbd_ep_stall(usbd, 0);
989-
return;
990-
}
991-
if (usbd->control.req.wLength == 0) {
992-
/* USB control transfer status in stage */
993-
this->sendZLP(usbd, 0);
994-
return;
995-
}
996-
if (usbd->control.req.bmRequestType & USB_TRX_IN) {
997-
if (!this->didCtlIn) {
998-
// Low-level firmware configured IN buffer,
999-
// or ZLP because PluggableUSB accepted but sent nothing
1000-
usbd_ep_send(usbd, 0, usbd->transc_in[0].xfer_buf, usbd->transc_in[0].xfer_len);
1001-
}
1002-
// Either way, _usb_in0_transc will take care of Status OUT
1003-
} else {
1004-
if (!this->didCtlOut) {
1005-
// Low-level firmware configured OUT buffer,
1006-
// or force a read because PluggableUSB accepted but read nothing
1007-
usbd->drv_handler->ep_rx_enable(usbd, 0);
1008-
// _usb_out0_transc will take care of Status IN
1009-
} else {
1010-
// Status IN after PluggableUSB did a read
1011-
this->sendZLP(usbd, 0);
1012-
}
1013-
}
822+
this->oldTranscSetup(usbd, ep);
1014823
}
1015824

1016825
// Called in interrupt context.
1017826
void USBCore_::transcOut(usb_dev* usbd, uint8_t ep)
1018827
{
1019-
EPBuffers().buf(ep).transcOut();
1020828
if (ep == 0) {
1021-
this->oldTranscOut(usbd, ep);
829+
return;
1022830
}
831+
EPBuffers().buf(ep).transcOut();
1023832
}
1024833

1025834
// Called in interrupt context.
1026835
void USBCore_::transcIn(usb_dev* usbd, uint8_t ep)
1027836
{
1028-
EPBuffers().buf(ep).transcIn();
1029837
if (ep == 0) {
1030-
this->oldTranscIn(usbd, ep);
838+
return;
1031839
}
840+
EPBuffers().buf(ep).transcIn();
1032841
}
1033842

1034-
void USBCore_::sendDeviceConfigDescriptor()
843+
void USBCore_::buildDeviceConfigDescriptor()
1035844
{
1036-
auto oldMaxWrite = this->maxWrite;
845+
this->ctlIdx = 0;
1037846
this->maxWrite = 0;
1038847
uint8_t interfaceCount = 0;
1039848
uint16_t len = 0;
@@ -1045,7 +854,7 @@ void USBCore_::sendDeviceConfigDescriptor()
1045854

1046855
configDesc.wTotalLength = sizeof(configDesc) + len;
1047856
configDesc.bNumInterfaces = interfaceCount;
1048-
this->maxWrite = oldMaxWrite;
857+
this->maxWrite = this->CTL_BUFSZ;
1049858
this->ctlIdx = 0;
1050859
this->sendControl(0, &configDesc, sizeof(configDesc));
1051860
interfaceCount = 0;
@@ -1054,9 +863,8 @@ void USBCore_::sendDeviceConfigDescriptor()
1054863
CDCACM().getInterface();
1055864
#endif
1056865
PluggableUSB().getInterface(&interfaceCount);
1057-
// TODO: verify this sends ZLP properly when:
1058-
// wTotalLength % sizeof(this->buf) == 0
1059-
this->flush(0);
866+
memcpy(this->cfgDesc, this->ctlBuf, this->ctlIdx);
867+
USBCore().usbDev().desc->config_desc = this->cfgDesc;
1060868
}
1061869

1062870
void USBCore_::sendZLP(usb_dev* usbd, uint8_t ep)

cores/arduino/USBCore.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,6 @@ class EPBuffer
8282
void transcIn();
8383
void transcOut();
8484

85-
/*
86-
* Busy loop until the endpoint has a packet available.
87-
*/
88-
bool waitForReadComplete();
8985
/*
9086
* Busy loop until the endpoint has finished its current
9187
* transmission.
@@ -132,8 +128,6 @@ class EPBuffers_
132128

133129
static EPDesc* desc(uint8_t ep);
134130

135-
bool pollEPStatus();
136-
137131
private:
138132
EPBuffer<L> epBufs[C];
139133
};
@@ -162,6 +156,7 @@ class USBCore_
162156
int recv(uint8_t ep);
163157
int flush(uint8_t ep);
164158

159+
void setupClass(uint16_t wLength);
165160
void ctlOut(usb_dev* udev);
166161
/*
167162
* Static member function helpers called from ISR.
@@ -195,6 +190,8 @@ class USBCore_
195190
uint8_t *ctlOutBuf;
196191
size_t ctlOutLen;
197192

193+
uint8_t cfgDesc[CTL_BUFSZ];
194+
198195
/*
199196
* Pointers to the transaction routines specified by ‘usbd_init’.
200197
*/
@@ -206,7 +203,7 @@ class USBCore_
206203
void transcOut(usb_dev* usbd, uint8_t ep);
207204
void transcIn(usb_dev* usbd, uint8_t ep);
208205

209-
void sendDeviceConfigDescriptor();
206+
void buildDeviceConfigDescriptor();
210207

211208
void sendZLP(usb_dev* usbd, uint8_t ep);
212209
};

0 commit comments

Comments
 (0)