Skip to content

Commit a24b778

Browse files
committed
Fix for drivers that require polling.
- Now sof_timer will only be set to go to sleep if no drivers need to poll. - Added option to perform polling manually.
1 parent 72c579e commit a24b778

File tree

2 files changed

+47
-12
lines changed

2 files changed

+47
-12
lines changed

libraries/UHS_host/USB_HOST_SHIELD/USB_HOST_SHIELD.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,9 @@ public UHS_USB_HOST_BASE
357357
volatile bool counted;
358358
volatile bool condet;
359359
volatile bool doingreset;
360+
361+
bool UHS_NI pollDevices(void);
362+
360363
public:
361364
SPISettings MAX3421E_SPI_Settings;
362365
uint8_t ss_pin;

libraries/UHS_host/USB_HOST_SHIELD/USB_HOST_SHIELD_INLINE.h

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,15 @@ uint8_t UHS_NI MAX3421E_HOST::gpioRd(void) {
128128
uint16_t UHS_NI MAX3421E_HOST::reset(void) {
129129
uint16_t i = 0;
130130

131+
// Initiate chip reset
131132
regWr(rUSBCTL, bmCHIPRES);
132133
regWr(rUSBCTL, 0x00);
133134

134135
int32_t now;
135136
uint32_t expires = micros() + 65535;
136137

138+
// Enable full-duplex SPI so we can read rUSBIRQ
139+
regWr(rPINCTL, bmFDUPSPI);
137140
while((int32_t)(micros() - expires) < 0L) {
138141
if((regRd(rUSBIRQ) & bmOSCOKIRQ)) {
139142
break;
@@ -308,8 +311,6 @@ int16_t UHS_NI MAX3421E_HOST::Init(int16_t mseconds) {
308311
uint32_t spd = UHS_MAX3421E_SPD;
309312
again:
310313
MAX3421E_SPI_Settings = SPISettings(spd, MSBFIRST, SPI_MODE0);
311-
/* MAX3421E - full-duplex SPI, interrupt kind, vbus off */
312-
regWr(rPINCTL, (bmFDUPSPI | bmIRQ_SENSE | GPX_VBDET));
313314
if(reset() == 0) {
314315
MAX_HOST_DEBUG("Fail SPI speed %lu\r\n", spd);
315316
if(spd > 1999999) {
@@ -340,11 +341,13 @@ int16_t UHS_NI MAX3421E_HOST::Init(int16_t mseconds) {
340341

341342
MAX_HOST_DEBUG("Pass SPI speed %lu\r\n", spd);
342343
#endif
343-
/* MAX3421E - full-duplex SPI, interrupt kind, vbus off */
344+
344345
if(reset() == 0) { //OSCOKIRQ hasn't asserted in time
345346
MAX_HOST_DEBUG("OSCOKIRQ hasn't asserted in time");
346347
return ( -1);
347348
}
349+
350+
/* MAX3421E - full-duplex SPI, interrupt kind, vbus off */
348351
regWr(rPINCTL, (bmFDUPSPI | bmIRQ_SENSE | GPX_VBDET));
349352

350353
// Delay a minimum of 1 second to ensure any capacitors are drained.
@@ -356,9 +359,9 @@ int16_t UHS_NI MAX3421E_HOST::Init(int16_t mseconds) {
356359

357360
regWr(rMODE, bmDPPULLDN | bmDMPULLDN | bmHOST); // set pull-downs, Host
358361

359-
// Enable interrupts on condition detections and bus events
362+
// Set the MAX3421e to issue interrupts on bus condition detections and events
360363
regWr(rHIEN, bmCONDETIE | bmBUSEVENTIE);
361-
// Enable interrupt pin, set pulse width for edge
364+
// Enable interrupt pin on the MAX3421e, set pulse width for edge
362365
regWr(rCPUCTL, (bmIE | bmPULSEWIDTH));
363366

364367
/* check if device is connected */
@@ -687,7 +690,7 @@ UHS_EpInfo * UHS_NI MAX3421E_HOST::ctrlReqOpen(uint8_t addr, uint64_t Request, u
687690

688691
uint8_t UHS_NI MAX3421E_HOST::ctrlReqRead(UHS_EpInfo *pep, uint16_t *left, uint16_t *read, uint16_t nbytes, uint8_t *dataptr) {
689692
*read = 0;
690-
uint16_t nak_limit = 0;
693+
uint16_t nak_limit = USB_HOST_NAK_LIMIT;
691694
MAX_HOST_DEBUG("ctrlReqRead left: %i\r\n", *left);
692695
if(*left) {
693696
again:
@@ -821,13 +824,17 @@ void UHS_NI MAX3421E_HOST::ISRbottom(void) {
821824
usb_task_state = UHS_USB_HOST_STATE_RUNNING;
822825
break;
823826
case UHS_USB_HOST_STATE_RUNNING:
824-
Poll_Others();
825-
for(x = 0; (usb_task_state == UHS_USB_HOST_STATE_RUNNING) && (x < UHS_HOST_MAX_INTERFACE_DRIVERS); x++) {
826-
if(devConfig[x]) {
827-
if(devConfig[x]->bPollEnable) devConfig[x]->Poll();
827+
#if USB_HOST_MANUAL_POLL && USB_HOST_SHIELD_USE_ISR
828+
sof_timer.sleep();
829+
#else
830+
// If no device requires polling, it is okay to shutoff
831+
// the sof_timer to free up some CPU cycles until the
832+
// next device insertion/removal
833+
if(!pollDevices()) {
834+
sof_timer.sleep();
828835
}
829-
}
830-
// fall-thru
836+
#endif
837+
break;
831838
case UHS_USB_HOST_STATE_ERROR:
832839
case UHS_USB_HOST_STATE_IDLE:
833840
case UHS_USB_HOST_STATE_ILLEGAL:
@@ -856,6 +863,24 @@ void UHS_NI MAX3421E_HOST::ISRbottom(void) {
856863
DDSB();
857864
}
858865

866+
/* Allows devices to run periodic tasks. Returns "true" if any devices
867+
* have polling enabled. */
868+
bool UHS_NI MAX3421E_HOST::pollDevices(void) {
869+
bool is_polling = false;
870+
#if defined(UHS_LOAD_BT) || defined(UHS_LOAD_HID)
871+
Poll_Others();
872+
is_polling = true;
873+
#endif
874+
875+
for(uint8_t x = 0; x < UHS_HOST_MAX_INTERFACE_DRIVERS; x++) {
876+
if(devConfig[x] && devConfig[x]->bPollEnable) {
877+
devConfig[x]->Poll();
878+
is_polling = true;
879+
}
880+
}
881+
return is_polling;
882+
}
883+
859884

860885
/* USB main task. Services the MAX3421e */
861886
#if !USB_HOST_SHIELD_USE_ISR
@@ -866,6 +891,13 @@ void UHS_NI MAX3421E_HOST::Task(void)
866891
#else
867892

868893
void UHS_NI MAX3421E_HOST::Task(void) {
894+
#if USB_HOST_MANUAL_POLL
895+
if(usb_task_state == UHS_USB_HOST_STATE_RUNNING) {
896+
noInterrupts();
897+
pollDevices();
898+
interrupts();
899+
}
900+
#endif
869901
}
870902

871903
void UHS_NI MAX3421E_HOST::ISRTask(void)

0 commit comments

Comments
 (0)