]> git.friedersdorff.com Git - max/tmk_keyboard.git/blobdiff - tmk_core/protocol/chibios/usb_main.c
Rename chibios example keyboard.
[max/tmk_keyboard.git] / tmk_core / protocol / chibios / usb_main.c
index 875f47dc491dfcf488e6ed84a0bcc676135c879f..2625c42575d6c64d35fe7b05882cb307b96c5526 100644 (file)
 
 #include "usb_main.h"
 
+#include "host.h"
+#include "debug.h"
+#ifdef SLEEP_LED_ENABLE
+#include "sleep_led.h"
+#include "led.h"
+#endif
+
 /* ---------------------------------------------------------
  *       Global interface variables and declarations
  * ---------------------------------------------------------
@@ -32,10 +39,16 @@ volatile uint16_t keyboard_idle_count = 0;
 static virtual_timer_t keyboard_idle_timer;
 static void keyboard_idle_timer_cb(void *arg);
 #ifdef NKRO_ENABLE
-bool keyboard_nkro = true;
+extern bool keyboard_nkro;
 #endif /* NKRO_ENABLE */
 
 report_keyboard_t keyboard_report_sent = {{0}};
+#ifdef MOUSE_ENABLE
+report_mouse_t mouse_report_blank = {0};
+#endif /* MOUSE_ENABLE */
+#ifdef EXTRAKEY_ENABLE
+uint8_t extra_report_blank[3] = {0};
+#endif /* EXTRAKEY_ENABLE */
 
 #ifdef CONSOLE_ENABLE
 /* The emission queue */
@@ -243,7 +256,7 @@ static const uint8_t console_hid_report_desc_data[] = {
   0x75, 0x08,       // report size = 8 bits
   0x15, 0x00,       // logical minimum = 0
   0x26, 0xFF, 0x00, // logical maximum = 255
-  0x95, CONSOLE_SIZE, // report count
+  0x95, CONSOLE_EPSIZE, // report count
   0x09, 0x75,       // usage
   0x81, 0x02,       // Input (array)
   0xC0              // end collection
@@ -367,7 +380,7 @@ static const uint8_t hid_configuration_descriptor_data[] = {
   /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
   USB_DESC_ENDPOINT(KBD_ENDPOINT | 0x80,  // bEndpointAddress
                     0x03,      // bmAttributes (Interrupt)
-                    KBD_SIZE,  // wMaxPacketSize
+                    KBD_EPSIZE,// wMaxPacketSize
                     10),       // bInterval
 
   #ifdef MOUSE_ENABLE
@@ -397,7 +410,7 @@ static const uint8_t hid_configuration_descriptor_data[] = {
   /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
   USB_DESC_ENDPOINT(MOUSE_ENDPOINT | 0x80,  // bEndpointAddress
                     0x03,      // bmAttributes (Interrupt)
-                    MOUSE_SIZE,  // wMaxPacketSize
+                    MOUSE_EPSIZE,  // wMaxPacketSize
                     1),        // bInterval
   #endif /* MOUSE_ENABLE */
 
@@ -423,7 +436,7 @@ static const uint8_t hid_configuration_descriptor_data[] = {
   /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
   USB_DESC_ENDPOINT(CONSOLE_ENDPOINT | 0x80,  // bEndpointAddress
                     0x03,      // bmAttributes (Interrupt)
-                    CONSOLE_SIZE, // wMaxPacketSize
+                    CONSOLE_EPSIZE, // wMaxPacketSize
                     1),        // bInterval
   #endif /* CONSOLE_ENABLE */
 
@@ -449,7 +462,7 @@ static const uint8_t hid_configuration_descriptor_data[] = {
   /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
   USB_DESC_ENDPOINT(EXTRA_ENDPOINT | 0x80,  // bEndpointAddress
                     0x03,      // bmAttributes (Interrupt)
-                    EXTRA_SIZE, // wMaxPacketSize
+                    EXTRA_EPSIZE, // wMaxPacketSize
                     10),       // bInterval
   #endif /* EXTRAKEY_ENABLE */
 
@@ -475,7 +488,7 @@ static const uint8_t hid_configuration_descriptor_data[] = {
   /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */
   USB_DESC_ENDPOINT(NKRO_ENDPOINT | 0x80,  // bEndpointAddress
                     0x03,      // bmAttributes (Interrupt)
-                    NKRO_SIZE, // wMaxPacketSize
+                    NKRO_EPSIZE, // wMaxPacketSize
                     1),       // bInterval
   #endif /* NKRO_ENABLE */
 };
@@ -658,7 +671,7 @@ static const USBEndpointConfig kbd_ep_config = {
   NULL,                         /* SETUP packet notification callback */
   kbd_in_cb,                    /* IN notification callback */
   NULL,                         /* OUT notification callback */
-  KBD_SIZE,                     /* IN maximum packet size */
+  KBD_EPSIZE,                   /* IN maximum packet size */
   0,                            /* OUT maximum packet size */
   &kbd_ep_state,                /* IN Endpoint state */
   NULL,                         /* OUT endpoint state */
@@ -676,7 +689,7 @@ static const USBEndpointConfig mouse_ep_config = {
   NULL,                         /* SETUP packet notification callback */
   mouse_in_cb,                  /* IN notification callback */
   NULL,                         /* OUT notification callback */
-  MOUSE_SIZE,                   /* IN maximum packet size */
+  MOUSE_EPSIZE,                 /* IN maximum packet size */
   0,                            /* OUT maximum packet size */
   &mouse_ep_state,              /* IN Endpoint state */
   NULL,                         /* OUT endpoint state */
@@ -695,7 +708,7 @@ static const USBEndpointConfig console_ep_config = {
   NULL,                         /* SETUP packet notification callback */
   console_in_cb,                /* IN notification callback */
   NULL,                         /* OUT notification callback */
-  CONSOLE_SIZE,                 /* IN maximum packet size */
+  CONSOLE_EPSIZE,               /* IN maximum packet size */
   0,                            /* OUT maximum packet size */
   &console_ep_state,            /* IN Endpoint state */
   NULL,                         /* OUT endpoint state */
@@ -714,7 +727,7 @@ static const USBEndpointConfig extra_ep_config = {
   NULL,                         /* SETUP packet notification callback */
   extra_in_cb,                  /* IN notification callback */
   NULL,                         /* OUT notification callback */
-  EXTRA_SIZE,                   /* IN maximum packet size */
+  EXTRA_EPSIZE,                 /* IN maximum packet size */
   0,                            /* OUT maximum packet size */
   &extra_ep_state,              /* IN Endpoint state */
   NULL,                         /* OUT endpoint state */
@@ -733,7 +746,7 @@ static const USBEndpointConfig nkro_ep_config = {
   NULL,                         /* SETUP packet notification callback */
   nkro_in_cb,                   /* IN notification callback */
   NULL,                         /* OUT notification callback */
-  NKRO_SIZE,                    /* IN maximum packet size */
+  NKRO_EPSIZE,                  /* IN maximum packet size */
   0,                            /* OUT maximum packet size */
   &nkro_ep_state,               /* IN Endpoint state */
   NULL,                         /* OUT endpoint state */
@@ -752,6 +765,7 @@ static const USBEndpointConfig nkro_ep_config = {
 static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
   switch(event) {
   case USB_EVENT_RESET:
+    //TODO: from ISR! print("[R]");
     return;
 
   case USB_EVENT_ADDRESS:
@@ -778,9 +792,21 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
     return;
 
   case USB_EVENT_SUSPEND:
+    //TODO: from ISR! print("[S]");
+    //TODO: signal suspend?
+#ifdef SLEEP_LED_ENABLE
+    sleep_led_enable();
+#endif /* SLEEP_LED_ENABLE */
     return;
 
   case USB_EVENT_WAKEUP:
+    //TODO: from ISR! print("[W]");
+    //TODO: suspend_wakeup_init();
+#ifdef SLEEP_LED_ENABLE
+    sleep_led_disable();
+    // NOTE: converters may not accept this
+    led_set(host_keyboard_leds());
+#endif /* SLEEP_LED_ENABLE */
     return;
 
   case USB_EVENT_STALLED:
@@ -838,6 +864,43 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
           return TRUE;
           break;
 
+#ifdef MOUSE_ENABLE
+        case MOUSE_INTERFACE:
+          usbSetupTransfer(usbp, (uint8_t *)&mouse_report_blank, sizeof(mouse_report_blank), NULL);
+          return TRUE;
+          break;
+#endif /* MOUSE_ENABLE */
+
+#ifdef CONSOLE_ENABLE
+        case CONSOLE_INTERFACE:
+          usbSetupTransfer(usbp, console_queue_buffer, CONSOLE_EPSIZE, NULL);
+          return TRUE;
+          break;
+#endif /* CONSOLE_ENABLE */
+
+#ifdef EXTRAKEY_ENABLE
+        case EXTRA_INTERFACE:
+          if(usbp->setup[3] == 1) { /* MSB(wValue) [Report Type] == 1 [Input Report] */
+            switch(usbp->setup[2]) { /* LSB(wValue) [Report ID] */
+              case REPORT_ID_SYSTEM:
+                extra_report_blank[0] = REPORT_ID_SYSTEM;
+                usbSetupTransfer(usbp, (uint8_t *)extra_report_blank, sizeof(extra_report_blank), NULL);
+                return TRUE;
+                break;
+              case REPORT_ID_CONSUMER:
+                extra_report_blank[0] = REPORT_ID_CONSUMER;
+                usbSetupTransfer(usbp, (uint8_t *)extra_report_blank, sizeof(extra_report_blank), NULL);
+                return TRUE;
+                break;
+              default:
+                return FALSE;
+            }
+          } else {
+            return FALSE;
+          }
+          break;
+#endif /* EXTRAKEY_ENABLE */
+
         default:
           usbSetupTransfer(usbp, NULL, 0, NULL);
           return TRUE;
@@ -886,7 +949,7 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
 #endif /* NKRO_ENABLE */
           /* arm the idle timer if boot protocol & idle */
             osalSysLockFromISR();
-            chVTSetI(&keyboard_idle_timer, 4*MS2ST(keyboard_idle), keyboard_idle_timer_cb, NULL);
+            chVTSetI(&keyboard_idle_timer, 4*MS2ST(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp);
             osalSysUnlockFromISR();
           }
         }
@@ -903,7 +966,7 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
         if(keyboard_idle) {
 #endif /* NKRO_ENABLE */
           osalSysLockFromISR();
-          chVTSetI(&keyboard_idle_timer, 4*MS2ST(keyboard_idle), keyboard_idle_timer_cb, NULL);
+          chVTSetI(&keyboard_idle_timer, 4*MS2ST(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp);
           osalSysUnlockFromISR();
         }
         usbSetupTransfer(usbp, NULL, 0, NULL);
@@ -943,20 +1006,20 @@ static const USBConfig usbcfg = {
 /*
  * Initialize the USB driver
  */
-void init_usb_driver(void) {
+void init_usb_driver(USBDriver *usbp) {
   /*
    * Activates the USB driver and then the USB bus pull-up on D+.
    * Note, a delay is inserted in order to not have to disconnect the cable
    * after a reset.
    */
-  usbDisconnectBus(&USB_DRIVER);
+  usbDisconnectBus(usbp);
   chThdSleepMilliseconds(1500);
-  usbStart(&USB_DRIVER, &usbcfg);
-  usbConnectBus(&USB_DRIVER);
+  usbStart(usbp, &usbcfg);
+  usbConnectBus(usbp);
 
   chVTObjectInit(&keyboard_idle_timer);
 #ifdef CONSOLE_ENABLE
-  oqObjectInit(&console_queue, console_queue_buffer, sizeof(console_queue_buffer), console_queue_onotify, NULL);
+  oqObjectInit(&console_queue, console_queue_buffer, sizeof(console_queue_buffer), console_queue_onotify, (void *)usbp);
   chVTObjectInit(&console_flush_timer);
 #endif
 }
@@ -992,12 +1055,12 @@ void kbd_sof_cb(USBDriver *usbp) {
 /* Idle requests timer code
  * callback (called from ISR, unlocked state) */
 static void keyboard_idle_timer_cb(void *arg) {
-  (void)arg;
+  USBDriver *usbp = (USBDriver *)arg;
 
   osalSysLockFromISR();
 
   /* check that the states of things are as they're supposed to */
-  if(usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
+  if(usbGetDriverStateI(usbp) != USB_ACTIVE) {
     /* do not rearm the timer, should be enabled on IDLE request */
     osalSysUnlockFromISR();
     return;
@@ -1010,11 +1073,11 @@ static void keyboard_idle_timer_cb(void *arg) {
 #endif /* NKRO_ENABLE */
     /* TODO: are we sure we want the KBD_ENDPOINT? */
     osalSysUnlockFromISR();
-    usbPrepareTransmit(&USB_DRIVER, KBD_ENDPOINT, (uint8_t *)&keyboard_report_sent, sizeof(keyboard_report_sent));
+    usbPrepareTransmit(usbp, KBD_ENDPOINT, (uint8_t *)&keyboard_report_sent, sizeof(keyboard_report_sent));
     osalSysLockFromISR();
-    usbStartTransmitI(&USB_DRIVER, KBD_ENDPOINT);
+    usbStartTransmitI(usbp, KBD_ENDPOINT);
     /* rearm the timer */
-    chVTSetI(&keyboard_idle_timer, 4*MS2ST(keyboard_idle), keyboard_idle_timer_cb, NULL);
+    chVTSetI(&keyboard_idle_timer, 4*MS2ST(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp);
   }
 
   /* do not rearm the timer if the condition above fails
@@ -1155,12 +1218,12 @@ void console_in_cb(USBDriver *usbp, usbep_t ep) {
   osalSysLockFromISR();
 
   /* rearm the timer */
-  chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, NULL);
+  chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp);
 
   /* Check if there is data to send left in the output queue */
-  if(chOQGetFullI(&console_queue) >= CONSOLE_SIZE) {
+  if(chOQGetFullI(&console_queue) >= CONSOLE_EPSIZE) {
     osalSysUnlockFromISR();
-    usbPrepareQueuedTransmit(usbp, CONSOLE_ENDPOINT, &console_queue, CONSOLE_SIZE);
+    usbPrepareQueuedTransmit(usbp, CONSOLE_ENDPOINT, &console_queue, CONSOLE_EPSIZE);
     osalSysLockFromISR();
     usbStartTransmitI(usbp, CONSOLE_ENDPOINT);
   }
@@ -1171,40 +1234,40 @@ void console_in_cb(USBDriver *usbp, usbep_t ep) {
 /* Callback when data is inserted into the output queue
  * Called from a locked state */
 void console_queue_onotify(io_queue_t *qp) {
-  (void)qp;
+  USBDriver *usbp = qGetLink(qp);
 
-  if(usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE)
+  if(usbGetDriverStateI(usbp) != USB_ACTIVE)
     return;
 
-  if(!usbGetTransmitStatusI(&USB_DRIVER, CONSOLE_ENDPOINT)
-     && (chOQGetFullI(&console_queue) >= CONSOLE_SIZE)) {
+  if(!usbGetTransmitStatusI(usbp, CONSOLE_ENDPOINT)
+     && (chOQGetFullI(&console_queue) >= CONSOLE_EPSIZE)) {
     osalSysUnlock();
-    usbPrepareQueuedTransmit(&USB_DRIVER, CONSOLE_ENDPOINT, &console_queue, CONSOLE_SIZE);
+    usbPrepareQueuedTransmit(usbp, CONSOLE_ENDPOINT, &console_queue, CONSOLE_EPSIZE);
     osalSysLock();
-    usbStartTransmitI(&USB_DRIVER, CONSOLE_ENDPOINT);
+    usbStartTransmitI(usbp, CONSOLE_ENDPOINT);
   }
 }
 
 /* Flush timer code
  * callback (called from ISR, unlocked state) */
 static void console_flush_cb(void *arg) {
-  (void)arg;
+  USBDriver *usbp = (USBDriver *)arg;
   size_t i, n;
-  uint8_t buf[CONSOLE_SIZE]; /* TODO: a solution without extra buffer? */
+  uint8_t buf[CONSOLE_EPSIZE]; /* TODO: a solution without extra buffer? */
   osalSysLockFromISR();
 
   /* check that the states of things are as they're supposed to */
-  if(usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
+  if(usbGetDriverStateI(usbp) != USB_ACTIVE) {
     /* rearm the timer */
-    chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, NULL);
+    chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp);
     osalSysUnlockFromISR();
     return;
   }
 
   /* don't do anything if the queue is empty or has enough stuff in it */
-  if(((n = oqGetFullI(&console_queue)) == 0) || (n >= CONSOLE_SIZE)) {
+  if(((n = oqGetFullI(&console_queue)) == 0) || (n >= CONSOLE_EPSIZE)) {
     /* rearm the timer */
-    chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, NULL);
+    chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp);
     osalSysUnlockFromISR();
     return;
   }
@@ -1212,15 +1275,15 @@ static void console_flush_cb(void *arg) {
   /* there's stuff hanging in the queue - so dequeue and send */
   for(i = 0; i < n; i++)
     buf[i] = (uint8_t)oqGetI(&console_queue);
-  for(i = n; i < CONSOLE_SIZE; i++)
+  for(i = n; i < CONSOLE_EPSIZE; i++)
     buf[i] = 0;
   osalSysUnlockFromISR();
-  usbPrepareTransmit(&USB_DRIVER, CONSOLE_ENDPOINT, buf, CONSOLE_SIZE);
+  usbPrepareTransmit(usbp, CONSOLE_ENDPOINT, buf, CONSOLE_EPSIZE);
   osalSysLockFromISR();
-  (void)usbStartTransmitI(&USB_DRIVER, CONSOLE_ENDPOINT);
+  (void)usbStartTransmitI(usbp, CONSOLE_ENDPOINT);
 
   /* rearm the timer */
-  chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, NULL);
+  chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp);
   osalSysUnlockFromISR();
 }