From 529835346857fd74bde07673d1d6794a213e4dc0 Mon Sep 17 00:00:00 2001 From: pesceWanda Date: Tue, 5 Jul 2016 23:50:29 -0400 Subject: [PATCH] init --- Arduino-keyboard-0.2.hex | 253 +++++++++++++ ...ino-usbserial-atmega16u2-Mega2560-Rev3.hex | 254 +++++++++++++ arduino-keyboard-0.2.tgz | Bin 0 -> 16483 bytes flash_arduino | 5 + flash_key | 5 + kbd_usb_passthrough.pde | 200 ++++++++++ keymapper.ino | 354 ++++++++++++++++++ 7 files changed, 1071 insertions(+) create mode 100644 Arduino-keyboard-0.2.hex create mode 100644 Arduino-usbserial-atmega16u2-Mega2560-Rev3.hex create mode 100644 arduino-keyboard-0.2.tgz create mode 100644 flash_arduino create mode 100644 flash_key create mode 100644 kbd_usb_passthrough.pde create mode 100644 keymapper.ino diff --git a/Arduino-keyboard-0.2.hex b/Arduino-keyboard-0.2.hex new file mode 100644 index 0000000..616eac6 --- /dev/null +++ b/Arduino-keyboard-0.2.hex @@ -0,0 +1,253 @@ +:100000009EC00000B7C00000B5C00000B3C0000033 +:10001000B1C00000AFC00000ADC00000ABC0000028 +:10002000A9C00000A7C00000A5C00000E7C30000F1 +:10003000A1C000009FC000009DC000009BC0000048 +:1000400099C0000097C0000095C0000093C0000058 +:1000500091C000008FC000008DC0000056C100009C +:1000600089C0000087C0000085C0000083C0000078 +:1000700081C000007FC000007DC000007BC0000088 +:1000800079C0000077C0000075C0000073C0000098 +:1000900071C000006FC0000005010906A1017501D3 +:1000A0009508050719E029E715002501810295014A +:1000B0007508810395057501050819012905910247 +:1000C00095017503910395067508150025650507CB +:1000D000190029658100C01201100100000008EB21 +:1000E0000342200000010200010902220001010078 +:1000F000C0320904000001030101000921110100BF +:1001000001223F000705810308000A0403090410C7 +:1001100003410072006400750069006E006F00000A +:10012000001A034B006500790062006F00610072E5 +:10013000006400200030002E003200000000112476 +:100140001FBECFEFD2E0DEBFCDBF11E0A0E0B1E037 +:10015000E0EBFFE002C005900D92AE30B107D9F799 +:1001600011E0AEE0B1E001C01D92AE3AB107E1F797 +:100170004ED01CC745CFBF92CF92DF92EF92FF9235 +:100180000F931F93CF93DF9384B7877F84BF28E1BA +:100190000FB6F89420936000109260000FBE3CEC04 +:1001A000C32ED12C87E690E0F601918380839AECF0 +:1001B000E92EF12C86E0B82EF701B08208EC10E0B1 +:1001C000F8011082C9ECD0E02883539A5A9A0BD3D5 +:1001D00084E085BD5F9A579A1882F8011082F70172 +:1001E00010828FEC90E0F60191838083F701B0825A +:1001F00082E0F801808388E98883DF91CF911F91A5 +:100200000F91FF90EF90DF90CF90BF900895B3DFF4 +:100210002FB7F8948FE191E09093A00180939F0114 +:100220009093A2018093A1012FBF789480E091E088 +:10023000E7D584D4FBCF0895089580E091E0B8D548 +:10024000E2EEF0E0808184608083089580E091E0B8 +:1002500087C480910B0190910C01009729F00197C0 +:1002600090930C0180930B0108950F931F93CF93EC +:10027000DF93E8019FB7F8948091A3019FBF883076 +:1002800050F1AEE0B1E08FE191E0E091A101F09199 +:10029000A2015191F093A201E093A10141E0EF3955 +:1002A000F40721F49093A2018093A1016FB7F89411 +:1002B0004091A30141504093A3016FBF5D9341E082 +:1002C000A631B40711F7809116019091C80095FFEF +:1002D000FCCF8093CE00EEE0F1E0822F932FDC0183 +:1002E00081918D9381E0E631F807D1F788E090E0C5 +:1002F0009983888380E0DF91CF911F910F910895BA +:10030000F90180818093160108951F920F920FB614 +:100310000F9211242F938F939F93EF93FF938091CC +:10032000CE009EB39430F9F4E0919F01F091A001CA +:100330008083E0919F01F091A001CF0101969093FD +:10034000A00180939F0121E08F39920721F48FE172 +:1003500091E0928381839FB7F8948091A3018F5F8E +:100360008093A3019FBFFF91EF919F918F912F9158 +:100370000F900FBE0F901F901895933089F0943016 +:1003800028F4913059F1923071F505C09132E1F0C5 +:10039000923249F51EC022E230E0E9EEF0E027C0DB +:1003A000813049F0813018F08230E9F408C0EBE088 +:1003B000F1E0249107C0EFE0F1E0249103C0E1E215 +:1003C000F1E0249130E013C029E030E0EBEFF0E001 +:1003D0000EC02FE330E0E8E9F0E009C022E130E0B0 +:1003E000E7EDF0E004C020E030E0E0E0F0E0DA012A +:1003F0001196FC93EE93C901089528E030E040E0A7 +:1004000003C04F5F220F331F28173907D0F3842F03 +:100410008295807F08958093E900EBEEF0E0808183 +:1004200081608083EDEEF0E010826093EC00408309 +:100430008091EE00881F8827881F08951092F4008D +:1004400080E08093E9001092F0001092E800109292 +:10045000ED009091EB009E7F9093EB008F5F8530D5 +:1004600081F708958091A60187FF11C003C08EB364 +:100470008823B1F08091E80082FFF9CF8091E800F5 +:100480008B778093E80008958EB3882349F080919C +:10049000E80080FFF9CF8091E8008E778093E80034 +:1004A000089584E69091EC0090FF05C09091E800DB +:1004B00090FF05C01BC09091E80092FD17C09EB34D +:1004C0009923B1F09EB39530A9F09091EB0095FD82 +:1004D00013C09091E10092FFE5CF9091E1009B7FE6 +:1004E0009093E100882351F08150DCCF80E00895A3 +:1004F00082E0089583E0089581E0089584E00895FE +:10050000AF92BF92DF92EF92FF920F931F93DF9310 +:10051000CF930F92CDB7DEB7082F5B017A01998395 +:10052000C0DFD82E9981882331F5192F1CC0809106 +:10053000E80085FD10C08091E8008E778093E80088 +:10054000E114F10421F0F7010995813081F0A9DF70 +:10055000882349F00FC0F80181918F018093F10049 +:100560000894A108B108A114B10409F704C075E00A +:10057000D72E01C0D82E8D2D0F90CF91DF911F91D6 +:100580000F91FF90EF90DF90BF90AF900895282FCC +:10059000392FF9018091AC019091AD018617970731 +:1005A00018F4BC0190E032C061157105D9F7809153 +:1005B000E8008E778093E800F5CF8091E80083FD16 +:1005C00037C08091E80082FD2DC08EB38823A1F151 +:1005D0008EB3853079F18091E80080FF17C080915B +:1005E000F20006C091919093F100615070408F5FCE +:1005F0006115710511F08830A8F391E0883009F099 +:1006000090E08091E8008E778093E8006115710595 +:10061000A1F6992391F606C08EB3882369F08EB3B4 +:10062000853061F08091E80082FFF6CF80E0089588 +:1006300081E0089583E0089582E0089583E00895BD +:10064000282F392FC9012091AC013091AD01261717 +:10065000370718F4B90130E034C061157105D9F7D6 +:100660002091E8002E772093E800F5CF2091E80054 +:1006700023FD39C02091E80022FD2FC02EB3222394 +:10068000B1F12EB3253089F12091E80020FF19C087 +:100690002091F20008C0FC010196E491E093F10082 +:1006A000615070402F5F6115710511F0283098F38B +:1006B00031E0283009F030E02091E8002E772093D7 +:1006C000E8006115710591F6332381F606C08EB3FB +:1006D000882369F08EB3853061F08091E80082FF55 +:1006E000F6CF80E0089581E0089583E0089582E0E8 +:1006F000089583E008956115710519F51DC02091D5 +:10070000E80023FD2EC02EB3222379F12EB325302D +:1007100051F12091E80022FFF2CFE82FF92F07C016 +:100720008091F1008193CF016150704029F0CF0199 +:100730002091F2002223A1F72091E8002B7720934B +:10074000E80061157105D9F606C08EB3882369F0FB +:100750008EB3853061F08091E80080FFF6CF80E0B5 +:10076000089581E0089583E0089582E0089583E08C +:1007700008953ED040D01EBA1092A40184E089BDF5 +:1007800089B5826089BD09B400FEFDCF8091D80093 +:10079000982F9F779093D80080688093D80080919D +:1007A00063008E7F809363008091D8008F7D80935B +:1007B000D8008091E0008E7F8093E0008091E1007E +:1007C0008E7F8093E1008091E20081608093E2005F +:1007D0008091E100877F8093E1008091E200886052 +:1007E0008093E2000895C5DF81E08093A50108951C +:1007F0001092E20008951092E10008951F920F9266 +:100800000FB60F9211242F933F934F935F936F93E3 +:100810007F938F939F93AF93BF93EF93FF938091B9 +:10082000E10080FF1BC08091E20080FF17C0809133 +:10083000E1008E7F8093E1008091E2008E7F8093C3 +:10084000E2008091E20080618093E2008091D80014 +:1008500080628093D80019BC1EBAEEDC8091E10062 +:1008600084FF29C08091E20084FF25C084E089BD17 +:1008700089B5826089BD09B400FEFDCF8091D800A2 +:100880008F7D8093D8008091E1008F7E8093E1007E +:100890008091E2008F7E8093E2008091E20081608F +:1008A0008093E2008091A401882311F084E001C0CC +:1008B00081E08EBBC0DC8091E10083FF22C080918B +:1008C000E20083FF1EC08091E100877F8093E100FA +:1008D00082E08EBB1092A4018091E1008E7F809314 +:1008E000E1008091E2008E7F8093E2008091E2003F +:1008F00080618093E200A2DD80E060E042E08BDD79 +:100900001CD18091E10082FF0AC08091E20082FF49 +:1009100006C08091E1008B7F8093E1009ADCFF911B +:10092000EF91BF91AF919F918F917F916F915F9167 +:100930004F913F912F910F900FBE0F901F901895E0 +:100940001F93DF93CF9300D0CDB7DEB7E6EAF1E097 +:100950008091F100819381E0EE3AF807C9F7809128 +:10096000A6019091A701953009F46BC0963040F430 +:10097000913061F1913070F0933009F0C9C026C018 +:10098000983009F49BC0993009F4AAC0963009F058 +:10099000BFC075C0803809F4BCC0823809F0B8C047 +:1009A0008091AA0187708093E9009091EB001092EA +:1009B000E9008091E800877F8093E80081E095FF5F +:1009C00080E08093F1001092F10083C0882319F039 +:1009D000823009F09DC08F71823009F09AC08091F9 +:1009E000A801882341F52091AA01277009F491C03C +:1009F0002093E9008091EB0080FF8BC08091A701DC +:100A0000833021F48091EB00806213C08091EB0071 +:100A100080618093EB0081E090E002C0880F991F15 +:100A20002A95E2F78093EA001092EA008091EB00A9 +:100A300088608093EB001092E9008091E800877F46 +:100A40004BC0882309F064C01091A8018091E80090 +:100A5000877F8093E80006DD04C08EB3882309F405 +:100A600058C08091E80080FFF8CF1F7711F083E035 +:100A700001C082E08EBB10681093E3004AC080582A +:100A8000823008F045C08091A8019091A901609141 +:100A9000AA01AE014F5F5F4F70DCBC010097C9F146 +:100AA0008091E800877F8093E80089819A81C8DD82 +:100AB0008091E8008B778093E8002BC0803841F567 +:100AC0008091E800877F8093E8008091A401809363 +:100AD000F1008091E8008E778093E800C3DC19C0B4 +:100AE0008823B1F49091A801923098F48091E800A5 +:100AF000877F8093E8009093A401B4DC8091A401E7 +:100B0000882311F084E001C083E08EBB96DB01C036 +:100B10009DDB8091E80083FF0AC08091EB0080623A +:100B20008093EB008091E800877F8093E8000F902E +:100B30000F90CF91DF911F91089508951F938EB369 +:100B4000882361F01091E90017701092E9008091FC +:100B5000E80083FF01C0F4DE1093E9001F910895BF +:100B60006F927F928F929F92AF92BF92CF92DF92BD +:100B7000EF92FF920F931F93DF93CF9300D00F92CA +:100B8000CDB7DEB77C016DB67EB68091E80083FFFD +:100B9000F8C0F701808190E02091AA013091AB016B +:100BA0002817390709F0EDC08091A701833009F4B7 +:100BB00099C0843030F4813071F0823009F0E1C0A6 +:100BC000C8C08A3009F4AEC08B3009F498C08930AF +:100BD00009F0D7C04CC08091A601813A09F0D1C07C +:100BE000CDB6DEB69DB68D2C8091E800877F8093D0 +:100BF000E8001B821A828091A8010091A9018983D3 +:100C0000F7014781C41AD1080FB6F894DEBE0FBEB3 +:100C1000CDBE0894C11CD11CBC2CAD2CC60160E01B +:100C200070E050E0BCD1402F4150C701BE016F5F62 +:100C30007F4F96018E010E5F1F4F17DBF701258155 +:100C400036812115310529F04781C901B60150E0EF +:100C50009DD11092E9006A817B818B2D9A2D97DCC2 +:100C60008091E8008B778093E800940133C08091F5 +:100C7000A601813209F085C0CDB6DEB6BDB6AD2C79 +:100C80008091E800877F8093E8000091AC0110918B +:100C9000AD019090A8018090A9018DB79EB7801BEF +:100CA000910B0FB6F8949EBF0FBE8DBFCDB6DEB6CA +:100CB0000894C11CD11CC601B8011DDD482D41504E +:100CC000C701692D96011CDB8091E8008E77809327 +:100CD000E8009501832F922F0FB6F8949EBF0FBEA8 +:100CE0008DBF4FC08091A601813A09F04AC0809122 +:100CF000E800877F8093E800F70180853AC0809103 +:100D0000A601813209F03DC08091E800877F809381 +:100D1000E8009091A80181E0992309F480E0F701AF +:100D200080872EC08091A601813259F58091E8001C +:100D3000877F8093E8008091A8019091A90180703D +:100D400036E0969587953A95E1F7F7019287818786 +:100D500017C08091A601813AA1F48091E800877FB5 +:100D60008093E800F7018185928596958795969501 +:100D700087958093F1008091E8008E778093E8005A +:100D800071DB0FB6F8947EBE0FBE6DBE0F900F9054 +:100D90000F90CF91DF911F910F91FF90EF90DF9017 +:100DA000CF90BF90AF909F908F907F906F9008955D +:100DB0000F931F93CF93DF93FC010896DC0185E02E +:100DC000ED0119928A95E9F781E0808784EF91E03F +:100DD000928781872281338101818481882311F068 +:100DE00014E001C010E0C90108DB412F482B42602C +:100DF000802F61EC10DBDF91CF911F910F9108954F +:100E00004F925F926F927F928F929F92AF92BF921A +:100E1000CF92DF92EF92FF920F931F93DF93CF93C6 +:100E200000D00F92CDB7DEB77C016DB67EB68EB323 +:100E3000843009F085C0F70181818093E9008091B9 +:100E4000E80085FF7DC05DB6472C4781CDB6DEB694 +:100E5000C41AD1080FB6F894DEBE0FBECDBE0DB7D2 +:100E60001EB70F5F1F4FB02E912E19821B821A8260 +:100E7000C80160E070E050E092D0C701BE016F5F32 +:100E80007F4F40E098018E010E5F1F4FEED9882EF4 +:100E9000F70181859285009759F081E090E02385E4 +:100EA00034852115310511F080E090E06C0102C01D +:100EB000CC24DD24F701058116810115110599F077 +:100EC0004A815B818B2D992DB80153D0AA24A3941C +:100ED000009709F4AA24F7014781C8016B2D792DE9 +:100EE00050E054D001C0AA248A819B81009701F16F +:100EF000882029F4AA2019F4C114D104C9F0F701FB +:100F0000818592859487838781818093E900898197 +:100F1000882311F08093F1006A817B818B2D992DBC +:100F200040E050E0EDDA8091E8008E778093E800B1 +:100F30009201832F942D0FB6F8949EBF0FBE8DBFE4 +:100F40000FB6F8947EBE0FBE6DBE0F900F900F903F +:100F5000CF91DF911F910F91FF90EF90DF90CF9095 +:100F6000BF90AF909F908F907F906F905F904F90C9 +:100F70000895FB01DC0104C08D910190801921F4DA +:100F800041505040C8F7881B990B0895FB01DC01C4 +:100F900002C001900D9241505040D8F70895DC01F5 +:100FA00001C06D9341505040E0F70895F894FFCF91 +:0E0FB00000010800001701080000000000000A +:00000001FF diff --git a/Arduino-usbserial-atmega16u2-Mega2560-Rev3.hex b/Arduino-usbserial-atmega16u2-Mega2560-Rev3.hex new file mode 100644 index 0000000..efbbf15 --- /dev/null +++ b/Arduino-usbserial-atmega16u2-Mega2560-Rev3.hex @@ -0,0 +1,254 @@ +:1000000090C00000A9C00000A7C00000A5C000006B +:10001000A3C00000A1C000009FC000009DC0000060 +:100020009BC0000099C0000097C0000048C40000B9 +:100030000CC4000091C000008FC000008DC0000003 +:100040008BC0000089C0000087C0000085C0000090 +:1000500083C0000081C000007FC0000002C100001A +:100060007BC0000079C0000077C0000075C00000B0 +:1000700073C0000071C000006FC000006DC00000C0 +:100080006BC0000069C0000067C0000065C00000D0 +:1000900063C0000061C000001201100102000008EE +:1000A0004123420001000102DC0109023E0002017D +:1000B00000C0320904000001020201000524000111 +:1000C0001004240206052406000107058203080027 +:1000D000FF09040100020A000000070504024000B5 +:1000E00001070583024000010403090432034100B3 +:1000F00072006400750069006E006F002000280027 +:100100007700770077002E006100720064007500B0 +:1001100069006E006F002E0063006300290000007C +:10012000000011241FBECFEFD2E0DEBFCDBF11E033 +:10013000A0E0B1E0ECEAFFE002C005900D92A6312C +:10014000B107D9F712E0A6E1B1E001C01D92AF32CC +:10015000B107E1F7F1D028C753CF9C01DC01AE57BE +:10016000BF4FED91FC91119741911196FC93EE9345 +:1001700080589F4FE817F90711F42D933C939FB7D0 +:10018000F894F901EC57FF4F8081815080839FBF25 +:10019000842F0895DF92EF92FF920F931F93FC013B +:1001A0008489813019F0823021F405C040E3D42ED7 +:1001B00004C0DD2402C030E2D32E8389823011F4E2 +:1001C00088E0D82A8589873031F0883031F0863050 +:1001D00031F482E003C084E001C086E0D82A1092A6 +:1001E000C9001092C8001092CA00E784F088018903 +:1001F000128980E0E81681EEF80680E0080780E0CA +:10020000180719F420E130E00FC0C801B701969536 +:1002100087957795679560587B47814E9F4FA801DA +:100220009701A0D6215030403093CD002093CC00D0 +:10023000D092CA0080E0E81681EEF80680E0080758 +:1002400080E0180711F082E001C080E08093C800D0 +:1002500088E98093C9001F910F91FF90EF90DF9084 +:1002600008951F920F920FB60F9211242F938F9320 +:100270009F93EF93FF939091CE008EB38430F1F46F +:10028000E0919901F0919A019083E0919901F091A8 +:100290009A01CF01019690939A018093990189590F +:1002A000914021F489E191E0928381839FB7F89492 +:1002B00080919D018F5F80939D019FBFFF91EF9182 +:1002C0009F918F912F910F900FBE0F901F901895B7 +:1002D000FC01858580FF02C05F9808955F9A0895AC +:1002E00080E091E0D5C580E091E088C584B7877F44 +:1002F00084BF28E10FB6F89420936000109260004C +:100300000FBE87E690E09093CD008093CC0086E00E +:100310008093CA001092C8002093C900539A5A9A39 +:100320008AB180638AB98BB180638BB983D284E050 +:1003300085BD5F9A579A08950F931F93CF93DF93CC +:10034000D5DF2FB7F8948EE991E090931F02809348 +:100350001E0290932102809320022FBF2FB7F894A2 +:1003600089E191E090939A018093990190939C0187 +:1003700080939B012FBF7894CEE9D1E003E08FB743 +:10038000F894909122028FBF903809F180E091E0BB +:10039000ABD497FD1CC0E0911E02F0911F02808338 +:1003A000E0911E02F0911F02CF01019690931F026F +:1003B00080931E028E51924011F4D283C1839FB765 +:1003C000F894809122028F5F809322029FBF8FB7A3 +:1003D000F89410919D018FBFA89902C0113678F151 +:1003E000A89A80919D01882361F05D980093160181 +:1003F00008C089E191E0B1DE682F80E091E0DAD4B5 +:1004000011501123B1F780911601882351F080918A +:10041000160181508093160180911601882309F4FA +:100420005D9A80911701882351F0809117018150C6 +:100430008093170180911701882309F45C9A8FB784 +:10044000F894909122028FBF992369F08EE991E090 +:1004500084DE982F8091C80085FFFCCF9093CE005A +:100460005C980093170180E091E095D42AD487CF5F +:10047000DA01923049F0933061F09130F9F4E8E913 +:10048000F0E022E130E01EC0EAEAF0E02EE330E0E6 +:1004900019C0813049F0813018F0823079F408C0F9 +:1004A000E8EEF0E0849107C0ECEEF0E0849103C048 +:1004B000E0E2F1E08491282F30E004C0E0E0F0E0D9 +:1004C00020E030E0ED93FC93C901089528E030E08E +:1004D00040E003C04F5F220F331F28173907D0F3C6 +:1004E000842F8295807F08958093E9008091EB00AE +:1004F00081608093EB001092ED006093EC004093DC +:10050000ED008091EE00881F8827881F08951092C3 +:10051000F40090E09093E9001092F0001092E8004F +:100520001092ED008091EB008E7F8093EB009F5F37 +:10053000953081F708958091270288238CF403C0B9 +:100540008EB38823B1F08091E80082FFF9CF8091CB +:10055000E8008B778093E80008958EB3882349F0F4 +:100560008091E80080FFF9CF8091E8008E7780933A +:10057000E800089594E68091EC0080FF05C080912A +:10058000E80080FF05C023C08091E80082FD1FC005 +:100590008EB3882311F482E008958EB3853011F470 +:1005A00083E008958091EB0085FF02C081E008950B +:1005B0008091E10082FFDFCF8091E1008B7F80930B +:1005C000E100992311F484E008959150D4CF80E0A4 +:1005D00008959C0140912D0250912E024617570715 +:1005E00018F4F90120E038C06115710511F0AB0174 +:1005F000F8CF8091E8008E778093E80040E050E0EB +:10060000F0CF8091E80083FF02C081E008958091DF +:10061000E80082FD2DC08EB3882381F18EB3853032 +:1006200079F18091E80080FF17C09091F20006C038 +:1006300081918093F100415050409F5F41155105D9 +:1006400011F09830A8F320E0983009F421E080916F +:10065000E8008E778093E8004115510591F622233A +:1006600081F606C08EB3882349F08EB3853041F001 +:100670008091E80082FFF6CF80E0089582E008953F +:1006800083E008959C0140912D0250912E0246175F +:10069000570710F490E03BC06115710511F0AB01F4 +:1006A000F9CF8091E8008E778093E80040E050E039 +:1006B000F1CF8091E80083FF02C081E0089580912E +:1006C000E80082FD30C08EB3882399F18EB3853067 +:1006D00091F18091E80080FF1AC08091F20009C07A +:1006E000F9012F5F3F4FE491E093F10041505040FA +:1006F0008F5F4115510511F0883090F390E08830FC +:1007000009F491E08091E8008E778093E80041152C +:10071000510579F6992369F606C08EB3882349F00E +:100720008EB3853041F08091E80082FFF6CF80E003 +:10073000089582E0089583E008959C016115710594 +:1007400029F48091E8008B778093E800F90120C0BC +:100750008091E80083FF02C081E008958EB3882372 +:1007600039F18EB3853031F18091E80082FFF0CF0E +:1007700006C08091F10081936150704021F080911A +:10078000F2008823B1F78091E8008B778093E8002E +:1007900061157105E9F606C08EB3882349F08EB362 +:1007A000853041F08091E80080FFF6CF80E0089529 +:1007B00082E0089583E0089542D044D01EBA10929A +:1007C0002502109224021092230284E089BD89B58B +:1007D000826089BD09B400FEFDCF8091D800982FBA +:1007E0009F779093D80080688093D80080916300B1 +:1007F0008E7F809363008091D8008F7D8093D80096 +:100800008091E0008E7F8093E0008091E1008E7FF8 +:100810008093E1008091E20081608093E20080910A +:10082000E100877F8093E1008091E20088608093FF +:10083000E2000895C1DF81E08093260208951092BE +:10084000E20008951092E10008951F920F920FB6F2 +:100850000F9211241F932F933F934F935F936F93A6 +:100860007F938F939F93AF93BF93EF93FF93E9EEA3 +:10087000F0E0108117701082E0EFF0E08081877F58 +:1008800080837894C3D0F894A9EEB0E01C92E0EF96 +:10089000F0E08081886080831C93FF91EF91BF918D +:1008A000AF919F918F917F916F915F914F913F9108 +:1008B0002F911F910F900FBE0F901F9018951F92B0 +:1008C0000F920FB60F9211242F933F934F935F9384 +:1008D0006F937F938F939F93AF93BF93EF93FF9308 +:1008E0008091E10080FF1BC08091E20080FF17C073 +:1008F0008091E1008E7F8093E1008091E2008E7F05 +:100900008093E2008091E20080618093E200809118 +:10091000D80080628093D80019BC1EBAD1D18091D2 +:10092000E10084FF29C08091E20084FF25C084E0BB +:1009300089BD89B5826089BD09B400FEFDCF809173 +:10094000D8008F7D8093D8008091E1008F7E8093C6 +:10095000E1008091E2008F7E8093E2008091E200CE +:1009600081608093E20080912502882311F481E068 +:1009700001C084E08EBBA4D18091E10083FF27C039 +:100980008091E20083FF23C08091E100877F809304 +:10099000E10082E08EBB109225028091E1008E7F03 +:1009A0008093E1008091E2008E7F8093E20080914D +:1009B000E20080618093E200AADD80E060E042E036 +:1009C00093DD8091F00088608093F00079D1809170 +:1009D000E10082FF0AC08091E20082FF06C08091A0 +:1009E000E1008B7F8093E1006BD1FF91EF91BF918C +:1009F000AF919F918F917F916F915F914F913F91B7 +:100A00002F910F900FBE0F901F9018951F93DF939B +:100A1000CF93CDB7DEB7AC970FB6F894DEBF0FBE5D +:100A2000CDBFE7E2F2E08091F100819322E0EF3266 +:100A3000F207C9F78091270230912802353009F476 +:100A400087C0363040F43130C9F1313070F0333086 +:100A500009F01DC133C0383009F4EFC0393009F452 +:100A6000FEC0363009F013C192C0803821F08238C0 +:100A700009F00DC108C090912302809124028823BF +:100A800099F0926011C080912B0287708093E900E9 +:100A90008091EB0090E025E0969587952A95E1F707 +:100AA000982F91701092E9008091E800877F8093E1 +:100AB000E8009093F1001092F100CAC0882319F069 +:100AC000823009F0E4C090E08F719070009721F0BF +:100AD000029709F0DDC00CC080912902813009F035 +:100AE000D7C010922402333069F5809324022AC0C3 +:100AF00080912902882331F520912B02277009F477 +:100B0000C7C02093E9008091EB0080FFC1C0333063 +:100B100021F48091EB00806213C08091EB00806132 +:100B20008093EB0081E090E002C0880F991F2A9526 +:100B3000E2F78093EA001092EA008091EB0088606F +:100B40008093EB001092E9008091E800877F83C0DA +:100B5000882309F09CC0109129028091E800877FCA +:100B60008093E800E8DC04C08EB3882309F490C0C9 +:100B70008091E80080FFF8CF812F8F7711F492E009 +:100B800001C093E09EBB80688093E30081C08058E1 +:100B9000823008F07CC08091290290912A0223E0E3 +:100BA0008C3D920799F55FB7F894DE0115964EE0FB +:100BB00020E030E061E2E42FF0E0609357008491A0 +:100BC00020FF03C082958F704F5F982F9F70892FF1 +:100BD000805D8A3308F0895F8C9311961C9211977F +:100BE0002F5F3F4F12962431310529F75FBF8AE20C +:100BF0008B8383E08C838091E800877F8093E8007B +:100C0000CE0103966AE270E0E4DC11C060912B0231 +:100C1000AE014F5F5F4F2CDCBC010097C9F18091A2 +:100C2000E800877F8093E80089819A812BDD80919D +:100C3000E8008B778093E8002BC0803841F58091E5 +:100C4000E800877F8093E800809125028093F1007F +:100C50008091E8008E778093E8006DDC19C08823CE +:100C6000B1F490912902923098F48091E800877F46 +:100C70008093E800909325025EDC80912502882312 +:100C800011F483E001C084E08EBB2DDB01C028DBC2 +:100C90008091E80083FF0AC08091EB00806280931E +:100CA000EB008091E800877F8093E800AC960FB658 +:100CB000F894DEBF0FBECDBFCF91DF911F91089595 +:100CC00008951F938EB3882361F01091E90010926C +:100CD000E9008091E80083FF01C098DE177010934F +:100CE000E9001F9108950895FC018EB3843021F529 +:100CF00087859089A189B2890097A105B105E1F0A6 +:100D000085818093E9008091E80082FF15C0809181 +:100D1000F200882319F42FEF3FEF04C08091F10017 +:100D2000282F30E08091F200882341F48091E80080 +:100D30008B778093E80002C02FEF3FEFC901089541 +:100D4000FC018EB3843011F587859089A189B28921 +:100D50000097A105B105D1F081818093E9008091D0 +:100D6000F2008823A9F09091E8008091E8008E7746 +:100D70008093E80095FD0CC0FDDB982F882349F493 +:100D80008091E8008E778093E80003C092E001C074 +:100D900090E0892F0895FC018EB3843051F487854B +:100DA0009089A189B2890097A105B10511F0CF0101 +:100DB000C7CF08951F93FC01162F8EB38430D9F44A +:100DC00087859089A189B2890097A105B10599F01D +:100DD00081818093E9008091E80085FD08C08091C1 +:100DE000E8008E778093E800C5DB882329F4109310 +:100DF000F10080E001C082E01F9108950F931F93DE +:100E0000CF93DF93EC010D96FC0189E0DF011D9289 +:100E10008A95E9F72A813B8109818C81882311F425 +:100E200010E001C014E0C90151DB182B1260802FC3 +:100E300061E8412F59DB882329F12E813F810D8103 +:100E40008885882311F410E001C014E0C9013EDB5D +:100E5000182B1260802F60E8412F46DB882391F029 +:100E60002A853B8509858C85882311F410E001C013 +:100E700014E0C9012BDB182B1260802F61EC412F8D +:100E800033DB01C080E0DF91CF911F910F91089576 +:100E9000CF93DF93EC018091E80083FF60C08881ED +:100EA00090E020912B0230912C022817390709F08D +:100EB00056C080912802813261F0823220F4803263 +:100EC00009F04DC019C0823269F1833209F047C080 +:100ED00038C080912702813A09F041C08091E80032 +:100EE000877F8093E800CE010F9667E070E071DBAA +:100EF0008091E8008B7713C080912702813279F5C9 +:100F00008091E800877F8093E800CE010F9667E02C +:100F100070E013DCCE013ED98091E8008E7780939B +:100F2000E8001DC0809127028132C9F48091E80059 +:100F3000877F8093E800809129028D87CE01C8D9F0 +:100F40000DC080912702813251F48091E800877FA3 +:100F50008093E800CE0160912902C5DEECDADF91D2 +:100F6000CF910895A1E21A2EAA1BBB1BFD010DC053 +:100F7000AA1FBB1FEE1FFF1FA217B307E407F50749 +:100F800020F0A21BB30BE40BF50B661F771F881F25 +:100F9000991F1A9469F760957095809590959B01BB +:0C0FA000AC01BD01CF010895F894FFCF13 +:100FAC0000034000000440000002080000000000A4 +:060FBC000000000000002F +:00000001FF diff --git a/arduino-keyboard-0.2.tgz b/arduino-keyboard-0.2.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4de0453519dc477ce7f9e247295f7f35ca28465d GIT binary patch literal 16483 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 GMg{;U@zB!% literal 0 HcmV?d00001 diff --git a/flash_arduino b/flash_arduino new file mode 100644 index 0000000..a230cc3 --- /dev/null +++ b/flash_arduino @@ -0,0 +1,5 @@ +dfu-programmer atmega16u2 erase +dfu-programmer atmega16u2 flash Arduino-usbserial-atmega16u2-Mega2560-Rev3.hex +echo 'Disconnect Arduino now' + +dfu-programmer atmega16u2 reset diff --git a/flash_key b/flash_key new file mode 100644 index 0000000..fafe162 --- /dev/null +++ b/flash_key @@ -0,0 +1,5 @@ +dfu-programmer atmega16u2 erase +dfu-programmer atmega16u2 flash Arduino-keyboard-0.2.hex +echo 'Disconnect Arduino now' + +dfu-programmer atmega16u2 reset diff --git a/kbd_usb_passthrough.pde b/kbd_usb_passthrough.pde new file mode 100644 index 0000000..f3e7ff0 --- /dev/null +++ b/kbd_usb_passthrough.pde @@ -0,0 +1,200 @@ +/* Arduino Keyboard HID driver and USB host shield pass through */ + +/*- + * Copyright (c) 2011 Darran Hunt (darran [at] hunt dot net dot nz) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +/* keyboard data taken from configuration descriptor */ +#define KBD_ADDR 1 +#define KBD_EP 1 +#define KBD_IF 0 +#define EP_MAXPKTSIZE 8 +#define EP_POLL 0x0a + +/* Sticky keys */ +#define CAPSLOCK 0x39 +#define NUMLOCK 0x53 +#define SCROLLLOCK 0x47 + +/* Sticky keys output report bitmasks */ +#define REP_NUMLOCK 0x01 +#define REP_CAPSLOCK 0x02 +#define REP_SCROLLLOCK 0x04 + +EP_RECORD ep_record[2]; //endpoint record structure for the keyboard + +uint8_t buf[8] = { 0 }; // keyboard buffer +uint8_t old_buf[8] = { 0 }; // last poll + +/* Sticky key state */ +bool numLock = false; +bool capsLock = false; +bool scrollLock = false; + +void setup(); +void loop(); +bool key_is_new(byte key, byte *report); + +MAX3421E Max; +USB Usb; + +void setup() +{ + Serial.begin(9600); + Max.powerOn(); + delay(200); +} + +void loop() +{ + Max.Task(); + Usb.Task(); + + if (Usb.getUsbTaskState() == USB_STATE_CONFIGURING) { + kbd_init(); + Usb.setUsbTaskState( USB_STATE_RUNNING); + } + + if (Usb.getUsbTaskState() == USB_STATE_RUNNING) { + kbd_poll(); + } +} + +/* Initialize keyboard */ +void kbd_init( void ) +{ + byte rcode = 0; //return code + + /* Initialize data structures */ + ep_record[0] = *(Usb.getDevTableEntry(0,0)); //copy endpoint 0 parameters + ep_record[1].MaxPktSize = EP_MAXPKTSIZE; + ep_record[1].Interval = EP_POLL; + ep_record[1].sndToggle = bmSNDTOG0; + ep_record[1].rcvToggle = bmRCVTOG0; + Usb.setDevTableEntry(1, ep_record); //plug kbd.endpoint parameters to devtable + + /* Configure device */ + rcode = Usb.setConf(KBD_ADDR, 0, 1); + if (rcode) { + while(1); //stop + } + delay(2000); +} + +/* Poll USB keyboard for new key presses, send through to host via + * the Keyboard HID driver in the atmega8u2 + */ +void kbd_poll(void) +{ + char i; + byte rcode = 0; //return code + uint8_t ledReport; + static uint8_t lastLedReport = 0; + static uint8_t leds = 0; + static uint8_t lastLeds = 0; + + /* poll keyboard */ + rcode = Usb.inTransfer(KBD_ADDR, KBD_EP, 8, (char *)buf); + if (rcode != 0) { + return; + } + + /* Check for change */ + for (i=0; i<8; i++) { + if (buf[i] != old_buf[i]) { + /* Send the new key presses to the host */ + Serial.write(buf, 8); + + /* Get led report */ + ledReport = Serial.read(); +#if 0 + /* Not working yet, ledReport is always 0 */ + if (ledReport != lastLedReport) { + rcode = Usb.setReport( KBD_ADDR, 0, 1, KBD_IF, 0x02, 0, (char *)&ledReport ); + lastLedReport = ledReport; + } +#endif + break; + } + } + + /* Check for status keys and adjust led status */ + for (i=2; i<8; i++) { + if (buf[i] == 0) { + /* 0 marks end of keys in the report */ + break; + } + /* Check new keys for status change keys */ + if (key_is_new(buf[i], old_buf)) { + switch (buf[i]) { + case CAPSLOCK: + capsLock =! capsLock; + leds = capsLock ? leds |= REP_CAPSLOCK : leds &= ~REP_CAPSLOCK; + break; + case NUMLOCK: + numLock =! numLock; + leds = numLock ? leds |= REP_NUMLOCK : leds &= ~REP_NUMLOCK; + break; + case SCROLLLOCK: + scrollLock =! scrollLock; + leds = scrollLock ? leds |= REP_SCROLLLOCK : leds &= ~REP_SCROLLLOCK; + break; + default: + break; + } + } + } + + /* Got a change in LED status? */ + if (lastLeds != leds) { + Usb.setReport( KBD_ADDR, 0, 1, KBD_IF, 0x02, 0, (char *)&leds ); + lastLeds = leds; + } + + /* update the old buffer */ + for (i=0; i<8; i++) { + old_buf[i] = buf[i]; + } + +} + +/* +* Function: key_is_new(key, report) +* Description: see if key is new or is already in report +* Returns: false if found, true if not +*/ +bool key_is_new(uint8_t key, uint8_t *report) +{ + uint8_t ind; + for (ind=2; ind<8; ind++) { + if (report[ind] == key) { + return false; + } + } + return true; +} diff --git a/keymapper.ino b/keymapper.ino new file mode 100644 index 0000000..e519f2f --- /dev/null +++ b/keymapper.ino @@ -0,0 +1,354 @@ +/* Arduino Keyboard HID driver and USB host shield pass through */ + +/*- + * Copyright (c) 2011 Darran Hunt (darran [at] hunt dot net dot nz) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +/* keyboard data taken from configuration descriptor */ +#define KBD_ADDR 1 +#define KBD_EP 1 +#define KBD_IF 0 +#define EP_MAXPKTSIZE 8 +#define EP_POLL 0x0a + +/* Sticky keys */ +/*#define CAPSLOCK 0x39*/ // Is going to be considered ESC +#define NUMLOCK 0x53 +#define SCROLLLOCK 0x47 + +/* Sticky keys output report bitmasks */ +#define REP_NUMLOCK 0x01 +#define REP_CAPSLOCK 0x02 +#define REP_SCROLLLOCK 0x04 + +EP_RECORD ep_record[2]; //endpoint record structure for the keyboard + +uint8_t buf[8] = { 0 }; // keyboard buffer +uint8_t old_buf[8] = { 0 }; // last poll + +/* Sticky key state */ +bool numLock = false; +bool capsLock = false; +bool scrollLock = false; + +uint8_t dvorak_changer (uint8_t ch, uint8_t mod); +void setup(); +void loop(); +bool key_is_new(byte key, byte *report); + +MAX3421E Max; +USB Usb; + +void setup() +{ + Serial.begin(9600); + Max.powerOn(); + delay(200); + digitalWrite(13, HIGH); + delay (1000); + digitalWrite (13, LOW); +} + +void loop() +{ + Max.Task(); + Usb.Task(); + + if (Usb.getUsbTaskState() == USB_STATE_CONFIGURING) { + kbd_init(); + Usb.setUsbTaskState( USB_STATE_RUNNING); + } + + if (Usb.getUsbTaskState() == USB_STATE_RUNNING) { + kbd_poll(); + } +} + +/* Initialize keyboard */ +void kbd_init( void ) +{ + byte rcode = 0; //return code + + /* Initialize data structures */ + ep_record[0] = *(Usb.getDevTableEntry(0,0)); //copy endpoint 0 parameters + ep_record[1].MaxPktSize = EP_MAXPKTSIZE; + ep_record[1].Interval = EP_POLL; + ep_record[1].sndToggle = bmSNDTOG0; + ep_record[1].rcvToggle = bmRCVTOG0; + Usb.setDevTableEntry(1, ep_record); //plug kbd.endpoint parameters to devtable + + /* Configure device */ + rcode = Usb.setConf(KBD_ADDR, 0, 1); + if (rcode) { + while(1); //stop + } + delay(2000); +} + +/* Poll USB keyboard for new key presses, send through to host via + * the Keyboard HID driver in the atmega8u2 + */ +void kbd_poll(void) +{ + char i; + byte rcode = 0; //return code + uint8_t ledReport; + static uint8_t lastLedReport = 0; + static uint8_t leds = 0; + static uint8_t lastLeds = 0; + + /* poll keyboard */ + rcode = Usb.inTransfer(KBD_ADDR, KBD_EP, 8, (char *)buf); + if (rcode != 0) { + return; + } + + for (i = 2; i < 8; ++i) { + buf[i] = dvorak_changer (buf[i], buf[0]); + } + +// Serial.print ("Modifier = "); +// Serial.println (buf[0]); + + /* Check for change */ + for (i=0; i<8; i++) { + if (buf[i] != old_buf[i]) { + + /* Send the new key presses to the host */ + Serial.write(buf, 8); + + /* Get led report */ + ledReport = Serial.read(); + break; + } + } + +/* Check for status keys and adjust led status */ + for (i=2; i<8; i++) { + if (buf[i] == 0) { + /* 0 marks end of keys in the report */ + break; + } + /* Check new keys for status change keys */ + /*if (key_is_new(buf[i], old_buf)) {*/ + /*switch (buf[i]) {*/ + /*case CAPSLOCK:*/ + /*capsLock =! capsLock;*/ + /*leds = capsLock ? leds |= REP_CAPSLOCK : leds &= ~REP_CAPSLOCK;*/ + /*break;*/ + /*case NUMLOCK:*/ + /*numLock =! numLock;*/ + /*leds = numLock ? leds |= REP_NUMLOCK : leds &= ~REP_NUMLOCK;*/ + /*break;*/ + /*case SCROLLLOCK:*/ + /*scrollLock =! scrollLock;*/ + /*leds = scrollLock ? leds |= REP_SCROLLLOCK : leds &= ~REP_SCROLLLOCK;*/ + /*break;*/ + /*default:*/ + /*break;*/ + /*}*/ + /*//}*/ + } + + /* Got a change in LED status? */ + if (lastLeds != leds) { + Usb.setReport( KBD_ADDR, 0, 1, KBD_IF, 0x02, 0, (char *)&leds ); + lastLeds = leds; + } + + /* update the old buffer */ + for (i=0; i<8; i++) { + old_buf[i] = buf[i]; + } + +} + +/* +* Function: key_is_new(key, report) +* Description: see if key is new or is already in report +* Returns: false if found, true if not +*/ +bool key_is_new(uint8_t key, uint8_t *report) +{ + uint8_t ind; + for (ind=2; ind<8; ind++) { + if (report[ind] == key) { + return false; + } + } + return true; +} + + +/* + * Qwerty to dvorak hardware changer + * http://www.freebsddiary.org/APC/usb_hid_usages.php + * http://www.usb.org/developers/hidpage/Hut1_12v2.pdf + * + * Modifier keys: + * LEFT: + CTRL = 1 + ALT = 4 + SHIFT = 2 + WINKEY = 8 + * RIGHT: + CTRL = 16 + ALT = 64 + SHIFT = 32 + * + */ + +uint8_t dvorak_changer (uint8_t ch, uint8_t mod) +{ + + if (mod != 8) { // WINKEY as layer key + switch (ch){ + /* begin mid row*/ + + case 0x39: // CAPSLOCK --> ESC + return 0x29; + /*case 0x04: // A --> A*/ + /*return 0x04;*/ + case 0x16: // S --> A + return 0x12; + case 0x07: // D --> E + return 0x08; + case 0x09: // F --> U + return 0x18; + case 0x0A: // G --> I + return 0x0C; + case 0x0B: // H --> D + return 0x07; + case 0x0D: // J --> H + return 0x0B; + case 0x0E: // K --> T + return 0x17; + case 0x0F: // L --> N + return 0x11; + case 0x033: // : --> S + return 0x016; + case 0x34: // " --> - + return 0x2D; + + /* end of mid row */ + /* begin of upper row */ + + case 0x14: // Q --> '@ + if (mod == 2){ + return 0x1F; // Upper case Q to @ + } else { + return 0x34; // lowercase q to ' + } + case 0x1A: // W --> ,< + return 0x36; + case 0x08: // E --> .> + return 0x37; + case 0x15: // R --> P + return 0x13; + case 0x17: // T --> Y + return 0x1C; + case 0x1C: // Y --> F + return 0x09; + case 0x18: // U --> G + return 0x0A; + case 0x0C: // I --> C + return 0x06; + case 0x12: // O --> R + return 0x15; + case 0x13: // P --> L + return 0x0F; + case 0x2F: // [{ --> /? + return 0x38; + case 0x30: // ]} --> =+ + return 0x2E; + + /* end upper row */ + /* begin lower row */ + + case 0x2E: // += --> ]} + return 0x30; + case 0x2D: // -_ --> [{ + return 0x2F; + case 0x1D: // Z --> :; + return 0x33; + case 0x1B: // X --> Q + return 0x14; + case 0x06: // C --> J + return 0x0D; + case 0x19: // V --> K + return 0x0E; + case 0x05: // B --> X + return 0x1B; + case 0x11: // N --> B + return 0x05; + /*case 0x10: // M --> M*/ + /*return 0x10;*/ + case 0x36: // <, --> W + return 0x1A; + case 0x37: // >. --> V + return 0x19; + case 0x38: // ?/ --> Z + return 0x1D; + + /* end lower row */ + /* specials */ + + case 0x1F: // 2@ --> 2" + if (mod == 2) { + return 0x34; + } else { + return 0x1F; + } + case 0x31: // \| --> DEL + return 0x4C; + case 0x29: // ESC --> `¬ + return 0x35; + case 0x4C: // DEL --> / + return 0x54; + case 0x49: // INS --> BEGIN END + if (mod == 2) { + return 0x5D ; + } else { + return 0x4D; + } + } + } else { + switch (ch){ + case 0x0C: // WINKEY + I --> UpArrow + return 0x52; + case 0x0E: // WINKEY + K --> DownArrow + return 0x51; + case 0x0D: // WINKEY + J --> LeftArrow + return 0x50; + case 0x0F: // WINKEY + L --> RightArrow + return 0x4F; + } + } + +} +