]> git.donarmstrong.com Git - qmk_firmware.git/blobdiff - tmk_core/protocol/vusb/vusb.c
Configure Vagrant to use qmk_base_container (#6194)
[qmk_firmware.git] / tmk_core / protocol / vusb / vusb.c
index 7d0292ed171336022bf16ee7c54fa40f3217dd72..60e48c3a9cfbcaf5786f2464c804a2604d38de0f 100644 (file)
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+#include <avr/eeprom.h>
+#include <avr/wdt.h>
 #include <stdint.h>
 #include "usbdrv.h"
 #include "usbconfig.h"
@@ -24,6 +26,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "debug.h"
 #include "host_driver.h"
 #include "vusb.h"
+#include "bootloader.h"
+#include <util/delay.h>
 
 
 static uint8_t vusb_keyboard_leds = 0;
@@ -43,19 +47,26 @@ typedef struct {
 
 static keyboard_report_t keyboard_report; // sent to PC
 
+#define VUSB_TRANSFER_KEYBOARD_MAX_TRIES 10
+
 /* transfer keyboard report from buffer */
 void vusb_transfer_keyboard(void)
 {
-    if (usbInterruptIsReady()) {
-        if (kbuf_head != kbuf_tail) {
-            usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t));
-            kbuf_tail = (kbuf_tail + 1) % KBUF_SIZE;
-            if (debug_keyboard) {
-                print("V-USB: kbuf["); pdec(kbuf_tail); print("->"); pdec(kbuf_head); print("](");
-                phex((kbuf_head < kbuf_tail) ? (KBUF_SIZE - kbuf_tail + kbuf_head) : (kbuf_head - kbuf_tail));
-                print(")\n");
+    for (int i = 0; i < VUSB_TRANSFER_KEYBOARD_MAX_TRIES; i++) {
+        if (usbInterruptIsReady()) {
+            if (kbuf_head != kbuf_tail) {
+                usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t));
+                kbuf_tail = (kbuf_tail + 1) % KBUF_SIZE;
+                if (debug_keyboard) {
+                    print("V-USB: kbuf["); pdec(kbuf_tail); print("->"); pdec(kbuf_head); print("](");
+                    phex((kbuf_head < kbuf_tail) ? (KBUF_SIZE - kbuf_tail + kbuf_head) : (kbuf_head - kbuf_tail));
+                    print(")\n");
+                }
             }
+            break;
         }
+        usbPoll();
+        _delay_ms(1);
     }
 }
 
@@ -163,6 +174,7 @@ static struct {
     uint16_t        len;
     enum {
         NONE,
+        BOOTLOADER,
         SET_LED
     }               kind;
 } last_req;
@@ -193,6 +205,11 @@ usbRequest_t    *rq = (void *)data;
                 debug("SET_LED: ");
                 last_req.kind = SET_LED;
                 last_req.len = rq->wLength.word;
+#ifdef BOOTLOADER_SIZE
+            } else if(rq->wValue.word == 0x0301) {
+                last_req.kind = BOOTLOADER;
+                last_req.len = rq->wLength.word;
+#endif
             }
             return USB_NO_MSG; // to get data in usbFunctionWrite
         } else {
@@ -220,6 +237,11 @@ uchar usbFunctionWrite(uchar *data, uchar len)
             last_req.len = 0;
             return 1;
             break;
+        case BOOTLOADER:
+            usbDeviceDisconnect();
+            bootloader_jump();
+            return 1;
+            break;
         case NONE:
         default:
             return -1;
@@ -266,7 +288,7 @@ const PROGMEM uchar keyboard_hid_report[] = {
     0x95, 0x06,          //   Report Count (6),
     0x75, 0x08,          //   Report Size (8),
     0x15, 0x00,          //   Logical Minimum (0),
-    0x25, 0xFF,          //   Logical Maximum(255),
+    0x26, 0xFF, 0x00,    //   Logical Maximum(255),
     0x05, 0x07,          //   Usage Page (Key Codes),
     0x19, 0x00,          //   Usage Minimum (0),
     0x29, 0xFF,          //   Usage Maximum (255),
@@ -336,7 +358,7 @@ const PROGMEM uchar mouse_hid_report[] = {
     0xa1, 0x01,                    // COLLECTION (Application)
     0x85, REPORT_ID_SYSTEM,        //   REPORT_ID (2)
     0x15, 0x01,                    //   LOGICAL_MINIMUM (0x1)
-    0x25, 0xb7,                    //   LOGICAL_MAXIMUM (0xb7)
+    0x26, 0xb7, 0x00,              //   LOGICAL_MAXIMUM (0xb7)
     0x19, 0x01,                    //   USAGE_MINIMUM (0x1)
     0x29, 0xb7,                    //   USAGE_MAXIMUM (0xb7)
     0x75, 0x10,                    //   REPORT_SIZE (16)
@@ -481,11 +503,11 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq)
             /* interface index */
             switch (rq->wIndex.word) {
                 case 0:
-                    usbMsgPtr = keyboard_hid_report;
+                    usbMsgPtr = (unsigned char *)keyboard_hid_report;
                     len = sizeof(keyboard_hid_report);
                     break;
                 case 1:
-                    usbMsgPtr = mouse_hid_report;
+                    usbMsgPtr = (unsigned char *)mouse_hid_report;
                     len = sizeof(mouse_hid_report);
                     break;
             }