diff --git a/main.c b/main.c index 86c20bd..74ab1f5 100644 --- a/main.c +++ b/main.c @@ -36,6 +36,7 @@ #include "hiddata.h" #include "usbstrings.h" #include "intervaltimer.h" +#include "intervaltimer2.h" #include "requests.h" #include "stkchk.h" @@ -453,6 +454,7 @@ int main(void) usart1_init(); eeprom_init(); intervaltimer_init(); + intervaltimer2_init(); stkchk_init(); switch (g_eeprom_data.cfg.mode) @@ -510,6 +512,9 @@ int main(void) sei(); usb_init(&usb_params); + // Timebase for force feedback 'loop count' + intervaltimer2_set16ms(); + while (1) { static char last_v[MAX_PLAYERS] = { }; @@ -520,6 +525,12 @@ int main(void) usb_doTasks(); hiddata_doTask(&hiddata_ops); + // Run vibration tasks + if (intervaltimer2_get()) { + for (channel=0; channel < num_players; channel++) { + usbpad_vibrationTask(&usbpads[channel]); + } + } switch(state) { diff --git a/usbpad.c b/usbpad.c index 0a3b6be..c49c73d 100644 --- a/usbpad.c +++ b/usbpad.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "usb.h" #include "gamepads.h" #include "usbpad.h" @@ -236,6 +237,18 @@ void usbpad_forceVibrate(struct usbpad *pad, char force) pad->force_vibrate = force; } +void usbpad_vibrationTask(struct usbpad *pad) +{ + uint8_t sreg; + + sreg = SREG; + cli(); + if (pad->_loop_count) { + pad->_loop_count--; + } + SREG = sreg; +} + char usbpad_mustVibrate(struct usbpad *pad) { if (pad->force_vibrate) { @@ -245,11 +258,16 @@ char usbpad_mustVibrate(struct usbpad *pad) if (!pad->vibration_on) { pad->gamepad_vibrate = 0; } else { - if (pad->constant_force > 0x7f) { - pad->gamepad_vibrate = 1; - } else if (pad->periodic_magnitude > 0x7f) { - pad->gamepad_vibrate = 1; + if (pad->_loop_count > 0) { + if (pad->constant_force > 0x7f) { + pad->gamepad_vibrate = 1; + } else if (pad->periodic_magnitude > 0x7f) { + pad->gamepad_vibrate = 1; + } else { + pad->gamepad_vibrate = 0; + } } else { + // Loop count = 0 -> Stop pad->gamepad_vibrate = 0; } } @@ -380,9 +398,12 @@ uint8_t usbpad_hid_set_report(struct usbpad *pad, const struct usb_request *rq, * Byte 1 : bit 7=rom flag, bits 6-0=effect block index * Byte 2 : Effect operation * Byte 3 : Loop count */ - pad->_loop_count = data[3]<<3; - printf_P(PSTR("EFFECT OP: rom=%s, idx=0x%02x"), data[1] & 0x80 ? "Yes":"No", data[1] & 0x7F); + // scale this up so vibration stays on longer. + // main.c uses a 16ms interval timer for vibration "loops" + pad->_loop_count = (data[3]+1)*3; + + printf_P(PSTR("EFFECT OP: rom=%s, idx=0x%02x : "), data[1] & 0x80 ? "Yes":"No", data[1] & 0x7F); switch(data[1] & 0x7F) // Effect block index { diff --git a/usbpad.h b/usbpad.h index 12a6ac3..aecccfc 100644 --- a/usbpad.h +++ b/usbpad.h @@ -25,6 +25,7 @@ int usbpad_getReportSize(void); unsigned char *usbpad_getReportBuffer(struct usbpad *pad); void usbpad_update(struct usbpad *pad, const gamepad_data *pad_data); +void usbpad_vibrationTask(struct usbpad *pad); char usbpad_mustVibrate(struct usbpad *pad); void usbpad_forceVibrate(struct usbpad *pad, char force);