Skip to content

Commit 7b1fc90

Browse files
committed
Turn off frame IRQ when it is not in use.
1 parent 1f2b850 commit 7b1fc90

File tree

3 files changed

+74
-6
lines changed

3 files changed

+74
-6
lines changed

libraries/UHS_host/UHS_settings.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,16 @@ e-mail : [email protected]
7676
#define DEBUG_PRINTF_EXTRA_HUGE 0
7777
#endif
7878

79+
////////////////////////////////////////////////////////////////////////////////
80+
// Special Cases
81+
////////////////////////////////////////////////////////////////////////////////
82+
83+
/* Set this to 1 to disable device polling within the IRQ. If you enable this,
84+
* you will need to call usb.Task() periodically instead. */
85+
#ifndef USB_HOST_MANUAL_POLL
86+
#define USB_HOST_MANUAL_POLL 0
87+
#endif
88+
7989
////////////////////////////////////////////////////////////////////////////////
8090
// Manual board activation
8191
////////////////////////////////////////////////////////////////////////////////

libraries/UHS_host/USB_HOST_SHIELD/USB_HOST_SHIELD.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,25 @@ public UHS_USB_HOST_BASE
309309
volatile bool counted;
310310
volatile bool condet;
311311
volatile bool doingreset;
312+
313+
bool UHS_NI pollDevices(void);
314+
// Frame timer control
315+
316+
volatile bool frame_irq_enabled = false;
317+
318+
bool enable_frame_irq(bool enable) {
319+
const bool prev_state = frame_irq_enabled;
320+
if(prev_state != enable) {
321+
if(enable)
322+
regWr(rHIEN, regRd(rHIEN) | bmFRAMEIE);
323+
else
324+
regWr(rHIEN, regRd(rHIEN) & ~bmFRAMEIE);
325+
frame_irq_enabled = enable;
326+
}
327+
return prev_state;
328+
}
329+
330+
312331
public:
313332
SPISettings MAX3421E_SPI_Settings;
314333
uint8_t ss_pin;
@@ -356,6 +375,7 @@ public UHS_USB_HOST_BASE
356375
};
357376

358377
virtual bool UHS_NI sof_delay(uint16_t x) {
378+
const bool saved_state = enable_frame_irq(true);
359379
sof_countdown = x;
360380
while((sof_countdown != 0) && !condet) {
361381

@@ -364,6 +384,7 @@ public UHS_USB_HOST_BASE
364384
#endif
365385
}
366386
// Serial.println("...Wake");
387+
enable_frame_irq(saved_state);
367388
return (!condet);
368389
};
369390

@@ -421,6 +442,7 @@ public UHS_USB_HOST_BASE
421442
// Enable interrupts
422443
noInterrupts();
423444
#endif
445+
enable_frame_irq(true);
424446
sofevent = true;
425447
#if USB_HOST_SHIELD_USE_ISR
426448
DDSB();

libraries/UHS_host/USB_HOST_SHIELD/USB_HOST_SHIELD_INLINE.h

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ void UHS_NI MAX3421E_HOST::busprobe(void) {
206206
regWr(rMODE, MODE_LS_HOST); // start low-speed host
207207
vbusState = LSHOST;
208208
}
209+
enable_frame_irq(true);
209210
tmpdata = regRd(rMODE) | bmSOFKAENAB; // start SOF generation
210211
regWr(rHIRQ, bmFRAMEIRQ); // see data sheet.
211212
regWr(rMODE, tmpdata);
@@ -219,6 +220,7 @@ void UHS_NI MAX3421E_HOST::busprobe(void) {
219220
regWr(rMODE, MODE_FS_HOST); // start full-speed host
220221
vbusState = FSHOST;
221222
}
223+
enable_frame_irq(true);
222224
tmpdata = regRd(rMODE) | bmSOFKAENAB; // start SOF generation
223225
regWr(rHIRQ, bmFRAMEIRQ); // see data sheet.
224226
regWr(rMODE, tmpdata);
@@ -814,13 +816,22 @@ void UHS_NI MAX3421E_HOST::ISRbottom(void) {
814816
usb_task_state = UHS_USB_HOST_STATE_RUNNING;
815817
break;
816818
case UHS_USB_HOST_STATE_RUNNING:
817-
Poll_Others();
818-
for(x = 0; (usb_task_state == UHS_USB_HOST_STATE_RUNNING) && (x < UHS_HOST_MAX_INTERFACE_DRIVERS); x++) {
819-
if(devConfig[x]) {
820-
if(devConfig[x]->bPollEnable) devConfig[x]->Poll();
819+
#if USB_HOST_MANUAL_POLL && USB_HOST_SHIELD_USE_ISR
820+
enable_frame_irq(false);
821+
#else
822+
// If no device requires polling, it is okay to shutoff
823+
// the frame irq to free up some CPU cycles until the
824+
// next device insertion/removal
825+
if(!pollDevices()) {
826+
enable_frame_irq(false);
821827
}
822-
}
823-
// fall thru
828+
#endif
829+
break;
830+
case UHS_USB_HOST_STATE_ERROR:
831+
case UHS_USB_HOST_STATE_IDLE:
832+
case UHS_USB_HOST_STATE_ILLEGAL:
833+
enable_frame_irq(false);
834+
break;
824835
default:
825836
// Do nothing
826837
break;
@@ -844,6 +855,24 @@ void UHS_NI MAX3421E_HOST::ISRbottom(void) {
844855
DDSB();
845856
}
846857

858+
/* Allows devices to run periodic tasks. Returns "true" if any devices
859+
* have polling enabled. */
860+
bool UHS_NI MAX3421E_HOST::pollDevices(void) {
861+
bool is_polling = false;
862+
#if defined(UHS_LOAD_BT) || defined(UHS_LOAD_HID)
863+
Poll_Others();
864+
is_polling = true;
865+
#endif
866+
867+
for(uint8_t x = 0; x < UHS_HOST_MAX_INTERFACE_DRIVERS; x++) {
868+
if(devConfig[x] && devConfig[x]->bPollEnable) {
869+
devConfig[x]->Poll();
870+
is_polling = true;
871+
}
872+
}
873+
return is_polling;
874+
}
875+
847876

848877
/* USB main task. Services the MAX3421e */
849878
#if !USB_HOST_SHIELD_USE_ISR
@@ -854,6 +883,13 @@ void UHS_NI MAX3421E_HOST::Task(void)
854883
#else
855884

856885
void UHS_NI MAX3421E_HOST::Task(void) {
886+
#if USB_HOST_MANUAL_POLL
887+
if(usb_task_state == UHS_USB_HOST_STATE_RUNNING) {
888+
noInterrupts();
889+
pollDevices();
890+
interrupts();
891+
}
892+
#endif
857893
}
858894

859895
void UHS_NI MAX3421E_HOST::ISRTask(void)

0 commit comments

Comments
 (0)