Zoltan Hudak / UsbHostMAX3421E

Dependents:   UsbHostMAX3421E_Hello

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers hidboot.cpp Source File

hidboot.cpp

00001 /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
00002 
00003 This software may be distributed and modified under the terms of the GNU
00004 General Public License version 2 (GPL2) as published by the Free Software
00005 Foundation and appearing in the file GPL2.TXT included in the packaging of
00006 this file. Please note that GPL2 Section 2[b] requires that all works based
00007 on this software must also be made publicly available under the terms of
00008 the GPL2 ("Copyleft").
00009 
00010 Contact information
00011 -------------------
00012 
00013 Circuits At Home, LTD
00014 Web      :  http://www.circuitsathome.com
00015 e-mail   :  support@circuitsathome.com
00016  */
00017 #include "hidboot.h"
00018 
00019 void MouseReportParser::Parse(USBHID *hid __attribute__((unused)), bool is_rpt_id __attribute__((unused)), uint8_t len __attribute__((unused)), uint8_t *buf) {
00020         MOUSEINFO *pmi = (MOUSEINFO*)buf;
00021         // Future:
00022         // bool event;
00023 
00024 #if 0
00025         if (prevState.mouseInfo.bmLeftButton == 0 && pmi->bmLeftButton == 1)
00026                 OnLeftButtonDown(pmi);
00027 
00028         if (prevState.mouseInfo.bmLeftButton == 1 && pmi->bmLeftButton == 0)
00029                 OnLeftButtonUp(pmi);
00030 
00031         if (prevState.mouseInfo.bmRightButton == 0 && pmi->bmRightButton == 1)
00032                 OnRightButtonDown(pmi);
00033 
00034         if (prevState.mouseInfo.bmRightButton == 1 && pmi->bmRightButton == 0)
00035                 OnRightButtonUp(pmi);
00036 
00037         if (prevState.mouseInfo.bmMiddleButton == 0 && pmi->bmMiddleButton == 1)
00038                 OnMiddleButtonDown(pmi);
00039 
00040         if (prevState.mouseInfo.bmMiddleButton == 1 && pmi->bmMiddleButton == 0)
00041                 OnMiddleButtonUp(pmi);
00042 
00043         if (prevState.mouseInfo.dX != pmi->dX || prevState.mouseInfo.dY != pmi->dY)
00044                 OnMouseMove(pmi);
00045 
00046         if (len > sizeof (MOUSEINFO))
00047                 for (uint8_t i = 0; i<sizeof (MOUSEINFO); i++)
00048                         prevState.bInfo[i] = buf[i];
00049 #else
00050         //
00051         // Optimization idea:
00052         //
00053         // 1: Don't pass the structure on every event. Buttons would not need it.
00054         // 2: Only pass x/y values in the movement routine.
00055         //
00056         // These two changes (with the ones I have made) will save extra flash.
00057         // The only "bad" thing is that it could break old code.
00058         //
00059         // Future thoughts:
00060         //
00061         // The extra space gained can be used for a generic mouse event that can be called
00062         // when there are _ANY_ changes. This one you _MAY_ want to pass everything, however the
00063         // sketch could already have noted these facts to support drag/drop scroll wheel stuff, etc.
00064         //
00065 
00066         // Why do we need to pass the structure for buttons?
00067         // The function call not enough of a hint for what is happening?
00068         if(prevState.mouseInfo.bmLeftButton != pmi->bmLeftButton ) {
00069                 if(pmi->bmLeftButton) {
00070                         OnLeftButtonDown(pmi);
00071                 } else {
00072                         OnLeftButtonUp(pmi);
00073                 }
00074                 // Future:
00075                 // event = true;
00076         }
00077 
00078         if(prevState.mouseInfo.bmRightButton != pmi->bmRightButton) {
00079                 if(pmi->bmRightButton) {
00080                         OnRightButtonDown(pmi);
00081                 } else {
00082                         OnRightButtonUp(pmi);
00083                 }
00084                 // Future:
00085                 // event = true;
00086         }
00087 
00088         if(prevState.mouseInfo.bmMiddleButton != pmi->bmMiddleButton) {
00089                 if(pmi->bmMiddleButton) {
00090                         OnMiddleButtonDown(pmi);
00091                 } else {
00092                         OnMiddleButtonUp(pmi);
00093                 }
00094                 // Future:
00095                 // event = true;
00096         }
00097 
00098         //
00099         // Scroll wheel(s), are not part of the spec, but we could support it.
00100         // Logitech wireless keyboard and mouse combo reports scroll wheel in byte 4
00101         // We wouldn't even need to save this information.
00102         //if(len > 3) {
00103         //}
00104         //
00105 
00106         // Mice only report motion when they actually move!
00107         // Why not just pass the x/y values to simplify things??
00108         if(pmi->dX || pmi->dY) {
00109                 OnMouseMove(pmi);
00110                 // Future:
00111                 // event = true;
00112         }
00113 
00114         //
00115         // Future:
00116         // Provide a callback that operates on the gathered events from above.
00117         //
00118         // if(event) OnMouse();
00119         //
00120 
00121         // Only the first byte matters (buttons). We do NOT need to save position info.
00122         prevState.bInfo[0] = buf[0];
00123 #endif
00124 
00125 };
00126 
00127 void KeyboardReportParser::Parse(USBHID *hid, bool is_rpt_id __attribute__((unused)), uint8_t len __attribute__((unused)), uint8_t *buf) {
00128         // On error - return
00129         if (buf[2] == 1)
00130                 return;
00131 
00132         //KBDINFO       *pki = (KBDINFO*)buf;
00133 
00134         // provide event for changed control key state
00135         if (prevState.bInfo[0x00] != buf[0x00]) {
00136                 OnControlKeysChanged(prevState.bInfo[0x00], buf[0x00]);
00137         }
00138 
00139         for (uint8_t i = 2; i < 8; i++) {
00140                 bool down = false;
00141                 bool up = false;
00142 
00143                 for (uint8_t j = 2; j < 8; j++) {
00144                         if (buf[i] == prevState.bInfo[j] && buf[i] != 1)
00145                                 down = true;
00146                         if (buf[j] == prevState.bInfo[i] && prevState.bInfo[i] != 1)
00147                                 up = true;
00148                 }
00149                 if (!down) {
00150                         HandleLockingKeys(hid, buf[i]);
00151                         OnKeyDown(*buf, buf[i]);
00152                 }
00153                 if (!up)
00154                         OnKeyUp(prevState.bInfo[0], prevState.bInfo[i]);
00155         }
00156         for (uint8_t i = 0; i < 8; i++)
00157                 prevState.bInfo[i] = buf[i];
00158 };
00159 
00160 const uint8_t KeyboardReportParser::numKeys[10] PROGMEM = {'!', '@', '#', '$', '%', '^', '&', '*', '(', ')'};
00161 const uint8_t KeyboardReportParser::symKeysUp[12] PROGMEM = {'_', '+', '{', '}', '|', '~', ':', '"', '~', '<', '>', '?'};
00162 const uint8_t KeyboardReportParser::symKeysLo[12] PROGMEM = {'-', '=', '[', ']', '\\', ' ', ';', '\'', '`', ',', '.', '/'};
00163 const uint8_t KeyboardReportParser::padKeys[5] PROGMEM = {'/', '*', '-', '+', '\r'};
00164 
00165 uint8_t KeyboardReportParser::OemToAscii(uint8_t mod, uint8_t key) {
00166         uint8_t shift = (mod & 0x22);
00167 
00168         // [a-z]
00169         if (VALUE_WITHIN(key, 0x04, 0x1d)) {
00170                 // Upper case letters
00171                 if ((kbdLockingKeys.kbdLeds.bmCapsLock == 0 && shift) ||
00172                         (kbdLockingKeys.kbdLeds.bmCapsLock == 1 && shift == 0))
00173                         return (key - 4 + 'A');
00174 
00175                         // Lower case letters
00176                 else
00177                         return (key - 4 + 'a');
00178         }// Numbers
00179         else if (VALUE_WITHIN(key, 0x1e, 0x27)) {
00180                 if (shift)
00181                         return ((uint8_t)pgm_read_byte(&getNumKeys()[key - 0x1e]));
00182                 else
00183                         return ((key == UHS_HID_BOOT_KEY_ZERO) ? '0' : key - 0x1e + '1');
00184         }// Keypad Numbers
00185         else if(VALUE_WITHIN(key, 0x59, 0x61)) {
00186                 if(kbdLockingKeys.kbdLeds.bmNumLock == 1)
00187                         return (key - 0x59 + '1');
00188         } else if(VALUE_WITHIN(key, 0x2d, 0x38))
00189                 return ((shift) ? (uint8_t)pgm_read_byte(&getSymKeysUp()[key - 0x2d]) : (uint8_t)pgm_read_byte(&getSymKeysLo()[key - 0x2d]));
00190         else if(VALUE_WITHIN(key, 0x54, 0x58))
00191                 return (uint8_t)pgm_read_byte(&getPadKeys()[key - 0x54]);
00192         else {
00193                 switch(key) {
00194                         case UHS_HID_BOOT_KEY_SPACE: return (0x20);
00195                         case UHS_HID_BOOT_KEY_ENTER: return ('\r'); // Carriage return (0x0D)
00196                         case UHS_HID_BOOT_KEY_ZERO2: return ((kbdLockingKeys.kbdLeds.bmNumLock == 1) ? '0': 0);
00197                         case UHS_HID_BOOT_KEY_PERIOD: return ((kbdLockingKeys.kbdLeds.bmNumLock == 1) ? '.': 0);
00198                 }
00199         }
00200         return ( 0);
00201 }