New IRLremote branch.
authorMarkus Zehnder <zehnm@users.noreply.github.com>
Sun, 6 Mar 2016 16:15:02 +0000 (17:15 +0100)
committerMarkus Zehnder <zehnm@users.noreply.github.com>
Sun, 6 Mar 2016 16:15:02 +0000 (17:15 +0100)
Use IRLremote instead of IRRemote library.
Changed Plex device profile to Panasonic TV.

README.md
src/IR_USB_Keyboard/IR_USB_Keyboard.ino
src/IR_USB_Keyboard/Panasonic.h [new file with mode: 0644]
src/IR_USB_Keyboard/Sony.h [new file with mode: 0644]

index 084e7a8..3cd51d5 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,15 +1,13 @@
-# arduino-kodi-ir-keyboard / BootKeyboard branch
+# arduino-kodi-ir-keyboard / IRLremote + BootKeyboard branch
 Kodi optimized infrared USB keyboard for an Asus Chromebox running openELEC.
 
-IR device: Logitech Harmony 880 with remote profile: 'Plex Player'
+IR device: Logitech Harmony 880 with remote profile: 'Panasonic TV TX-43CXW754'
 
 Testing with: 
 - SparkFun Pro Micro, ATmega32u4 (5V, 16MHz)
-- MattairTech MT-DB-U4 (ATmega 32U4), 16MHZ 5V, CDC_HID
-
-Arduino IDE 1.6.7
-HID Project 2.4.3
-IRRemote 2.0.1
+- Arduino IDE 1.6.7
+- HID Project 2.4.3
+- IRLremote   1.7.4
 
 Initial proof of concept with HID-Project instead of standard Keyboard library: 
 - Kodi control works pretty well already :-)
@@ -17,11 +15,11 @@ Initial proof of concept with HID-Project instead of standard Keyboard library:
 - boot protocol mode works (tested on a MacMini)
 
 ## Issues:
-- Stability issues: program hangs within 0..60 minutes 
-   (Watch dog reset didn't work either, according to Google this is most likely a bootloader bug)
+- Most promising branch yet :)
+- IRLremote doesn't work with Logitech Plex Remote profile. Now (ab)using Panasonic TV TX-43CXW754 device template.
+- Watch dog reset doesn't work, according to Google this is most likely an Arduino bootloader bug.
+  
 ## TODO:
-- Stable operation: continue testing with an Arduino Leonardo
 - Power off / sleep / wakeup
 - CTRL+D / CTRL+W key combinations for boot selection 
 - Chromebox hardware modification to control power toggle switch with Arduino
dissimilarity index 64%
index ed58482..74819dd 100644 (file)
-/*
-The MIT License (MIT)
-
-Copyright (c) 2016 Markus Zehnder
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-/* IR to USB keyboard optimized for KODI openELEC running on Asus Chromebox.
- * IR device: Logitech Harmony 880 with remote profile: 'Plex Player'
- * Testing with: 
- * - SparkFun Pro Micro, ATmega32u4 (5V, 16MHz)
- * - MattairTech MT-DB-U4 (ATmega 32U4), 16MHZ 5V, CDC_HID
- * 
- * Arduino IDE 1.6.7
- * HID Project 2.4.3
- * IRRemote 2.0.1
- * 
- * Initial proof of concept: 
- * - Kodi control works pretty well already :-)
- * - key repeat works
- * - boot protocol mode works (tested on a MacMini)
- * 
- * ISSUES:
- * - Stability issues: program hangs within 0..60 minutes 
- *   (Watch dog reset didn't work either, according to Google this is most likely a bootloader bug)
- * 
- * TODO:
- * - Stable operation: continue testing with an Arduino Leonardo
- * - Power off / sleep / wakeup
- * - CTRL+D / CTRL+W key combinations for boot selection on the Asus Chromebox
- * - Chromebox hardware modification to control power toggle switch with Arduino
- */
-
-#ifdef WATCHDOG
-  #include <avr/wdt.h>
-#endif
-
-// hack for MattairTech MT-DB-U4 1.6.9-mt1
-#ifndef USB_EP_SIZE
- #define USB_EP_SIZE USB_DEFAULT_EP_SIZE
-#endif
-
-#include <HID-Project.h>
-#include <IRremote.h>
-
-//#define DEBUG_SKETCH
-#include "Debug.h"
-
-// --------CONSTANTS ---------------
-
-// pin assignments
-#define RECV_PIN 20
-
-struct CodeMap {
-  unsigned long   irCode;
-  KeyboardKeycode keyCode;
-};
-
-// Logitech "Plex Player" device as KODI remote
-#define IR_CLEAR        0x77E12059
-#define IR_ENTER        0x77E14099
-#define IR_LEFT         0x77E11069
-#define IR_RIGHT        0x77E1E069
-#define IR_UP           0x77E1D069
-#define IR_DOWN         0x77E1B069
-#define IR_OK           0x77E12069
-#define IR_MENU         0x77E14069
-#define IR_EXIT         0x77E150D9
-#define IR_POWER_OFF    0x77E14059
-#define IR_GUIDE        0x77E1A0B9
-#define IR_INFO         0x77E1D099
-#define IR_STOP         0x77E1A0E9
-#define IR_PLAY         0x77E1C0E9
-#define IR_PAUSE        0x77E1C019
-#define IR_REC          0x77E130D9
-#define IR_REW          0x77E1D059
-#define IR_FWD          0x77E1B059
-#define IR_REPLAY       0x77E1D005
-#define IR_SKIP         0x77E1B005
-#define IR_PREV         0x77E1B099
-#define IR_PGDOWN       0x77E1B0F9
-#define IR_PGUP         0x77E1D0F9
-#define IR_BLUE         0x77E140F9
-#define IR_RED          0x77E110F9
-#define IR_GREEN        0x77E1E0F9
-#define IR_YELLOW       0x77E120F9
-#define IR_1            0x77E150E9
-#define IR_2            0x77E130E9
-#define IR_3            0x77E190E9
-#define IR_4            0x77E160E9
-#define IR_5            0x77E19019
-#define IR_6            0x77E16019
-#define IR_7            0x77E11099
-#define IR_8            0x77E1E099
-#define IR_9            0x77E11059
-#define IR_0            0x77E1E059
-#define IR_F1           0x77E190D9
-#define IR_F2           0x77E160D9
-#define IR_F3           0x77E1A0D9
-#define IR_F4           0x77E1C0D9
-#define IR_F5           0x77E11005
-#define IR_F6           0x77E1E005
-#define IR_F7           0x77E12005
-#define IR_F8           0x77E14005
-#define IR_MUTE         0x77E1A019
-#define IR_VOL_UP       0x77E15019
-#define IR_VOL_DOWN     0x77E13019
-#define IR_CH_UP        0x77E15079
-#define IR_CH_DOWN      0x77E13079
-#define IR_POWER_TOGGLE 0x77E1C0B9
-#define IR_SLEEP        0x77E14059
-#define IR_QUEUE        0x77E130B9
-#define IR_ASPECT       0x77E150B9
-
-// Key press time must be slightly higher then the repeat IR code duration. 
-// My Logitech resends the first repeat after 40ms and afterwards every 110ms
-const int KEY_PRESS_TIME = 150;
-
-// IR code to key mapping
-// Kodi keyboard controls: http://kodi.wiki/view/Keyboard_controls
-const CodeMap irToKeyMap[] = {
-  {IR_LEFT  , KEY_LEFT_ARROW},
-  {IR_RIGHT , KEY_RIGHT_ARROW},
-  {IR_UP    , HID_KEYBOARD_UPARROW},
-  {IR_DOWN  , KEY_DOWN_ARROW},
-  {IR_OK    , KEY_RETURN},
-  {IR_ENTER , KEY_TAB},  // Fullscreen playback
-  {IR_MENU  , KEY_C},
-  {IR_EXIT  , KEY_ESC},
-  {IR_F8    , KEY_BACKSPACE},
-  {IR_GUIDE , KEY_E},
-  {IR_INFO  , KEY_I},
-  {IR_STOP  , KEY_X},
-  {IR_PLAY  , KEY_P},
-  {IR_PAUSE , KEY_SPACE},
-  {IR_REC   , KEY_B},
-  {IR_REW   , KEY_R},
-  {IR_FWD   , KEY_F},
-  {IR_PREV  , KEY_QUOTE}, // FIXME doesn't seem to work with non-us keyboard layout
-  {IR_SKIP  , KEY_PERIOD},
-  {IR_REPLAY, KEY_COMMA},
-  {IR_PGDOWN, KEY_PAGE_DOWN},
-  {IR_PGUP  , KEY_PAGE_UP},
-  {IR_BLUE  , KEY_T},      // toggle subtitles 
-  {IR_RED   , KEY_W},      // Marked as watched / unwatched
-  {IR_GREEN , KEY_S},      // Shutdown menu
-  {IR_YELLOW, KEY_DELETE},
-  {IR_1     , KEY_1},
-  {IR_2     , KEY_2},
-  {IR_3     , KEY_3},
-  {IR_4     , KEY_4},
-  {IR_5     , KEY_5},
-  {IR_6     , KEY_6},
-  {IR_7     , KEY_7},
-  {IR_8     , KEY_8},
-  {IR_9     , KEY_9},
-  {IR_0     , KEY_0},
-
-// TODO:
-// CTRL + D -> boot ChromeOS
-// CTRL + W -> boot openELEC
-};
-
-const int IR_KEY_MAP_SIZE = sizeof(irToKeyMap) / sizeof(CodeMap);
-
-//------------ VARIABLES ---------------------
-
-IRrecv irrecv(RECV_PIN);
-decode_results results;
-
-unsigned long lastIRValue = 0;  // previously received IR code value
-unsigned long timeKeyDown = 0;  // time of key press initiation
-
-//========================================
-
-void setup() {                
-  // open debug console
-  #ifndef DEBUG
-  Serial.begin(115200);  // afaik the baudrate is ignored on a 32u4
-  #endif
-  DEBUG_PRINTLN("Chromebox_IR_USB_Keyboard");
-
-  // initialize control over the keyboard:
-  BootKeyboard.begin();
-  
-  // Start the receiver
-  irrecv.enableIRIn();
-
-#ifdef WATCHDOG
-  // enable watch dog 
-  // maybe this solves the frequent hangs on the Pro Micro...
-  wdt_enable(WDTO_1S);
-#endif
-}
-
-//========================================
-
-void loop() {
-#ifdef WATCHDOG  
-    //Test if watchdog interrupt enabled
-    // http://forum.arduino.cc/index.php?topic=295345.msg2628807#msg2628807
-    if (WDTCSR & (1<<WDIE)) {   
-        //Prolong wtachdog timer
-        wdt_reset();
-    }
-    //No interrupt enabled - Test if watchdog reset enabled
-    else if (WDTCSR & (1<<WDE)) {
-        //Bootloader about to reset - do not prolong watchdog
-    }
-    //It has ben disabled - Enable and prolong
-    else {
-        //Watchdog disabled - Enable again
-        wdt_enable(WDTO_1S);
-    }
-#endif
-
-    if (irrecv.decode(&results) && results.decode_type == NEC) {
-      // check if it's a NEC repeat code
-      if (results.value == 0xFFFFFFFF) {
-        results.value = lastIRValue;
-      } else {
-        lastIRValue = results.value;
-      }
-
-      if (results.value != lastIRValue) {
-        // immediately release last key if a different IR value is received. We don't want multiple keys pressed at the same time.
-        releaseKeys(); 
-      }
-
-      for (int i = 0; i < IR_KEY_MAP_SIZE; i++) {
-        if (irToKeyMap[i].irCode == results.value) {
-            // only press key if not yet pressed
-            if (timeKeyDown == 0) {
-              KeyboardKeycode keyCode = irToKeyMap[i].keyCode;
-              DEBUG_PRINT(millis()); DEBUG_PRINT(" Press key: 0x"); DEBUG_PRINTLN(keyCode, HEX);
-              BootKeyboard.press(keyCode);              
-            }
-            timeKeyDown = millis();
-            break;
-        }
-      }
-
-      DEBUG_PRINT(millis()); DEBUG_PRINT(" IR: 0x"); DEBUG_PRINTLN(results.value, HEX);
-
-      irrecv.resume(); // restarts decoding state machine
-    } else {
-      // check if it's time to release a previously pressed key
-      if (timeKeyDown > 0 && (millis() - timeKeyDown >= KEY_PRESS_TIME)) {
-        releaseKeys(); 
-      }
-    }
-}
-
-//========================================
-
-void releaseKeys() {
-    timeKeyDown = 0;
-    BootKeyboard.releaseAll();
-    DEBUG_PRINT(millis()); DEBUG_PRINTLN(" Release keys");   
-}
-
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 Markus Zehnder
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+/* IR to USB keyboard optimized for KODI openELEC running on Asus Chromebox.
+ * IR device: Logitech Harmony 880 with remote profile: 'Panasonic TV TX-43CXW754'
+ * 
+ * Initial proof of concept.
+ * 
+ * Testing with: 
+ * - SparkFun Pro Micro, ATmega32u4 (5V, 16MHz)
+ * - Arduino IDE 1.6.7
+ * - HID Project 2.4.3
+ * - IRLremote   1.7.4
+ * 
+ * ISSUES:
+ * - Most promising branch yet :)
+ * - IRLremote doesn't work with Logitech Plex Remote profile. Now (ab)using Panasonic TV TX-43CXW754 device template.
+ * - Watch dog reset doesn't work, according to Google this is most likely an Arduino bootloader bug.
+ */
+// --------GLOBAL FLAGS ---------------
+// enable debugging output over usb
+#define DEBUG_SKETCH
+//#define WATCHDOG
+
+// hack for MattairTech MT-DB-U4 1.6.9-mt1
+#ifndef USB_EP_SIZE
+ #define USB_EP_SIZE USB_DEFAULT_EP_SIZE
+#endif
+
+// --------INCLUDES ---------------
+
+#ifdef WATCHDOG
+  #include <avr/wdt.h>
+#endif
+#include <HID-Project.h>
+#include <IRLremote.h>
+#include "Debug.h"
+// either include Panasonic or Sony definitions
+#include "Panasonic.h"
+//#include "Sony.h"
+
+// --------CONSTANTS ---------------
+
+// pin assignments
+#define RECV_PIN 7
+
+struct CodeMap {
+  uint32_t        irCommand;
+  KeyboardKeycode keyCode;
+};
+
+// Key press time must be slightly higher then the repeat IR code duration. 
+// My Logitech resends the first repeat after 40ms and afterwards every 110ms
+const int KEY_PRESS_TIME = 150;
+
+// TODO not sure yet if a loop delay is required. With the IRRemote library it increased realibility...
+const int LOOP_DELAY = KEY_PRESS_TIME / 3;
+
+// IR code to key mapping
+// Kodi keyboard controls: http://kodi.wiki/view/Keyboard_controls
+const CodeMap irToKeyMap[] = {
+  {REMOTE_LEFT  , KEY_LEFT_ARROW},
+  {REMOTE_RIGHT , KEY_RIGHT_ARROW},
+  {REMOTE_UP    , KEY_UP_ARROW},
+  {REMOTE_DOWN  , KEY_DOWN_ARROW},
+  {REMOTE_OK    , KEY_RETURN},
+  {REMOTE_ENTER , KEY_TAB},  // Fullscreen playback
+  {REMOTE_MENU  , KEY_C},
+  {REMOTE_BACK  , KEY_BACKSPACE},
+  {REMOTE_EXIT  , KEY_ESC},
+  {REMOTE_GUIDE , KEY_E},
+  {REMOTE_INFO  , KEY_I},
+  {REMOTE_STOP  , KEY_X},
+  {REMOTE_PLAY  , KEY_P},
+  {REMOTE_PAUSE , KEY_SPACE},
+  {REMOTE_REC   , KEY_B},
+  {REMOTE_REW   , KEY_R},
+  {REMOTE_FWD   , KEY_F},
+  {REMOTE_PREV  , KEY_QUOTE}, // FIXME doesn't seem to work with non-us keyboard layout
+  {REMOTE_SKIP  , KEY_PERIOD},
+  {REMOTE_REPLAY, KEY_COMMA},
+  {REMOTE_BLUE  , KEY_T},      // toggle subtitles 
+  {REMOTE_RED   , KEY_W},      // Marked as watched / unwatched
+  {REMOTE_GREEN , KEY_S},      // Shutdown menu
+  {REMOTE_YELLOW, KEY_DELETE},
+  {REMOTE_1     , KEY_1},
+  {REMOTE_2     , KEY_2},
+  {REMOTE_3     , KEY_3},
+  {REMOTE_4     , KEY_4},
+  {REMOTE_5     , KEY_5},
+  {REMOTE_6     , KEY_6},
+  {REMOTE_7     , KEY_7},
+  {REMOTE_8     , KEY_8},
+  {REMOTE_9     , KEY_9},
+  {REMOTE_0     , KEY_0},
+
+// TODO:
+// CTRL + D -> boot ChromeOS
+// CTRL + W -> boot openELEC
+};
+
+const int IR_KEY_MAP_SIZE = sizeof(irToKeyMap) / sizeof(CodeMap);
+
+//------------ VARIABLES ---------------------
+
+unsigned long lastIRValue = 0;  // previously received IR code value
+unsigned long timeKeyDown = 0;  // time of key press initiation
+
+// temporary variables to save latest IR input
+uint8_t IRProtocol = 0;
+uint16_t IRAddress = 0;
+uint32_t IRCommand = 0;
+
+//========================================
+
+void setup() {                
+    // open debug console
+    #ifdef DEBUG_SKETCH
+      delay(3000);
+      Serial.begin(115200);  // afaik the baudrate is ignored on a 32u4
+    #endif
+    DEBUG_PRINTLN("Chromebox_REMOTE_USB_Keyboard");
+    
+    // initialize control over the keyboard:
+    BootKeyboard.begin();
+    
+    // Start the receiver
+    attachInterrupt(digitalPinToInterrupt(RECV_PIN), IRLinterrupt<irType>, CHANGE);
+    
+    #ifdef WATCHDOG
+      // enable watch dog 
+      wdt_enable(WDTO_1S);
+    #endif
+}
+
+//========================================
+
+void loop() {
+#ifdef WATCHDOG  
+    //Test if watchdog interrupt enabled
+    // http://forum.arduino.cc/index.php?topic=295345.msg2628807#msg2628807
+    if (WDTCSR & (1<<WDIE)) {   
+        //Prolong wtachdog timer
+        wdt_reset();
+    }
+    //No interrupt enabled - Test if watchdog reset enabled
+    else if (WDTCSR & (1<<WDE)) {
+        //Bootloader about to reset - do not prolong watchdog
+    }
+    //It has ben disabled - Enable and prolong
+    else {
+        //Watchdog disabled - Enable again
+        wdt_enable(WDTO_1S);
+    }
+#endif
+
+    // temporary disable interrupts and print newest input
+    // TODO read up on interrup handling
+    uint8_t oldSREG = SREG;
+    cli();
+
+    if (IRProtocol) {
+        DEBUG_PRINT(IRProtocol);DEBUG_PRINT("/0x");DEBUG_PRINT(IRAddress, HEX);DEBUG_PRINT("/0x");DEBUG_PRINTLN(IRCommand, HEX);
+        
+        if (IRProtocol == irType) {
+            // check if it's a NEC repeat code
+            if (IRCommand == 0xFFFF) {
+                IRCommand = lastIRValue;
+            } else {
+                lastIRValue = IRCommand;
+            }
+            
+            if (IRCommand != lastIRValue) {
+                // immediately release last key if a different IR value is received. We don't want multiple keys pressed at the same time.
+                releaseKeys(); 
+            }
+            
+            for (int i = 0; i < IR_KEY_MAP_SIZE; i++) {
+                if (irToKeyMap[i].irCommand == IRCommand) {  // irToKeyMap[i].irAddress == IRAddress && 
+                    // only press key if not yet pressed
+                    if (timeKeyDown == 0) {
+                        KeyboardKeycode keyCode = irToKeyMap[i].keyCode;
+                        DEBUG_PRINT(millis()); DEBUG_PRINT(" Press key: 0x"); DEBUG_PRINTLN(keyCode, HEX);
+                        BootKeyboard.press(keyCode);              
+                    }
+                    timeKeyDown = millis();
+                    break;
+                }
+            }
+        }     
+    
+    } else {
+        // check if it's time to release a previously pressed key
+        if (timeKeyDown > 0 && (millis() - timeKeyDown >= KEY_PRESS_TIME)) {
+            releaseKeys(); 
+        }
+    }
+
+    IRProtocol = 0;
+    SREG = oldSREG;
+    
+    sei();
+    
+    // TODO required?
+    delay(LOOP_DELAY);
+}
+
+//========================================
+
+void releaseKeys() {
+    timeKeyDown = 0;
+    BootKeyboard.releaseAll();
+    DEBUG_PRINT(millis()); DEBUG_PRINTLN(" Release keys");   
+}
+
+//========================================
+
+// IR decoding callback: update the values to the newest valid input
+void IREvent(uint8_t protocol, uint16_t address, uint32_t command) {
+    // called when directly received a valid IR signal.
+    // do not use Serial inside, it can crash your program!
+    
+    // dont update value if not yet processed
+    if (!IRProtocol) {
+        IRProtocol = protocol;
+        IRAddress = address;
+        IRCommand = command;
+    }
+}
diff --git a/src/IR_USB_Keyboard/Panasonic.h b/src/IR_USB_Keyboard/Panasonic.h
new file mode 100644 (file)
index 0000000..e2a6d58
--- /dev/null
@@ -0,0 +1,100 @@
+
+const IRType irType = IR_PANASONIC;
+
+// address: 0x2002
+#define IR_PANA_1            0x90100080
+#define IR_PANA_2            0x91110080
+#define IR_PANA_3            0x92120080
+#define IR_PANA_4            0x93130080
+#define IR_PANA_5            0x94140080
+#define IR_PANA_6            0x95150080
+#define IR_PANA_7            0x96160080
+#define IR_PANA_8            0x97170080
+#define IR_PANA_9            0x98180080
+#define IR_PANA_0            0x99190080
+#define IR_PANA_CH_UP        0xB4340080
+#define IR_PANA_CH_DOWN      0xB5350080
+#define IR_PANA_VOL_UP       0xA0200080
+#define IR_PANA_VOL_DOWN     0xA1210080
+#define IR_PANA_MUTE         0xB2320080
+#define IR_PANA_POWER_TOGGLE 0xBD3D0080
+#define IR_PANA_STOP         0x4BC20980
+#define IR_PANA_PAUSE        0x48C10980
+#define IR_PANA_PLAY         0x49C00980
+#define IR_PANA_REW          0x4DC40980
+#define IR_PANA_FWD          0x4AC30980
+#define IR_PANA_REC          0x4CC50980
+#define IR_PANA_BACK         0x54D40080
+#define IR_PANA_BLUE         0xF3730080
+#define IR_PANA_RED          0xF0700080
+#define IR_PANA_GREEN        0xF1710080
+#define IR_PANA_YELLOW       0xF2720080
+#define IR_PANA_SUBTITLE     0x84050180
+#define IR_PANA_POWER_ON     0xBE3E0080
+#define IR_PANA_POWER_OFF    0xBD3D0080
+#define IR_PANA_RIGHT        0xCF4F0080
+#define IR_PANA_LEFT         0xCE4E0080
+#define IR_PANA_INFO         0xB9390080
+#define IR_PANA_PREV         0xB7370080
+#define IR_PANA_REPLAY       0x55DC0980
+#define IR_PANA_SKIP         0x54DD0980
+#define IR_PANA_ASPECT       0x5ADE0480
+#define IR_PANA_GUIDE        0xE870980
+#define IR_PANA_MENU         0xD2520080
+#define IR_PANA_EXIT         0x139A0980
+#define IR_PANA_HOME         0x1C950980
+#define IR_PANA_OK           0xC9490080
+#define IR_PANA_UP           0xCA4A0080
+#define IR_PANA_DOWN         0xCB4B0080
+
+// Standard Logitech 880 buttons
+#define REMOTE_MUTE         IR_PANA_MUTE
+#define REMOTE_VOL_UP       IR_PANA_VOL_UP
+#define REMOTE_VOL_DOWN     IR_PANA_VOL_DOWN
+#define REMOTE_PG_DOWN      0
+#define REMOTE_PG_UP        0
+#define REMOTE_CH_DOWN      IR_PANA_CH_DOWN
+#define REMOTE_CH_UP        IR_PANA_CH_UP
+#define REMOTE_PREV         IR_PANA_PREV
+#define REMOTE_UP           IR_PANA_UP
+#define REMOTE_DOWN         IR_PANA_DOWN
+#define REMOTE_LEFT         IR_PANA_LEFT
+#define REMOTE_RIGHT        IR_PANA_RIGHT
+#define REMOTE_OK           IR_PANA_OK
+#define REMOTE_MENU         IR_PANA_MENU
+#define REMOTE_EXIT         IR_PANA_EXIT
+#define REMOTE_GUIDE        IR_PANA_GUIDE
+#define REMOTE_INFO         IR_PANA_INFO
+#define REMOTE_STOP         IR_PANA_STOP
+#define REMOTE_REPLAY       IR_PANA_REPLAY
+#define REMOTE_SKIP         IR_PANA_SKIP
+#define REMOTE_PLAY         IR_PANA_PLAY
+#define REMOTE_REC          IR_PANA_REC
+#define REMOTE_REW          IR_PANA_REW
+#define REMOTE_FWD          IR_PANA_FWD
+#define REMOTE_PAUSE        IR_PANA_PAUSE
+#define REMOTE_1            IR_PANA_1
+#define REMOTE_2            IR_PANA_2
+#define REMOTE_3            IR_PANA_3
+#define REMOTE_4            IR_PANA_4
+#define REMOTE_5            IR_PANA_5
+#define REMOTE_6            IR_PANA_6
+#define REMOTE_7            IR_PANA_7
+#define REMOTE_8            IR_PANA_8
+#define REMOTE_9            IR_PANA_9
+#define REMOTE_PLUS         0
+#define REMOTE_0            IR_PANA_0
+#define REMOTE_ENTER        0
+
+// Additional buttons
+#define REMOTE_POWER_TOGGLE IR_PANA_POWER_TOGGLE
+#define REMOTE_POWER_ON     IR_PANA_POWER_ON
+#define REMOTE_POWER_OFF    IR_PANA_POWER_OFF
+#define REMOTE_BACK         IR_PANA_BACK
+#define REMOTE_RED          IR_PANA_RED
+#define REMOTE_GREEN        IR_PANA_GREEN
+#define REMOTE_YELLOW       IR_PANA_YELLOW
+#define REMOTE_BLUE         IR_PANA_BLUE
+#define REMOTE_SUBTITLE     IR_PANA_SUBTITLE
+#define REMOTE_ASPECT       IR_PANA_ASPECT
+
diff --git a/src/IR_USB_Keyboard/Sony.h b/src/IR_USB_Keyboard/Sony.h
new file mode 100644 (file)
index 0000000..fdae434
--- /dev/null
@@ -0,0 +1,97 @@
+const IRType irType = IR_SONY12;
+
+#define IR_SONY_1            0x0000
+#define IR_SONY_2            0x0001
+#define IR_SONY_3            0x0002
+#define IR_SONY_4            0x0003
+#define IR_SONY_5            0x0004
+#define IR_SONY_6            0x0005
+#define IR_SONY_7            0x0006
+#define IR_SONY_8            0x0007
+#define IR_SONY_9            0x0008
+#define IR_SONY_0            0x0009
+#define IR_SONY_CH_UP        0x0010
+#define IR_SONY_CH_DOWN      0x0011
+#define IR_SONY_VOL_UP       0x0012
+#define IR_SONY_VOL_DOWN     0x0013
+#define IR_SONY_MUTE         0x0014
+#define IR_SONY_POWER_TOGGLE 0x0015
+#define IR_SONY_STOP         0x0018
+#define IR_SONY_PAUSE        0x0019
+#define IR_SONY_PLAY         0x001A
+#define IR_SONY_REW          0x001B
+#define IR_SONY_FWD          0x001C
+#define IR_SONY_REC          0x0020
+#define IR_SONY_BACK         0x0023
+#define IR_SONY_BLUE         0x0024
+#define IR_SONY_RED          0x0025
+#define IR_SONY_GREEN        0x0026
+#define IR_SONY_YELLOW       0x0027
+#define IR_SONY_SUBTITLE     0x0028
+#define IR_SONY_POWER_ON     0x002E
+#define IR_SONY_POWER_OFF    0x002F
+#define IR_SONY_RIGHT        0x0033
+#define IR_SONY_LEFT         0x0034
+#define IR_SONY_INFO         0x003A
+#define IR_SONY_PREV         0x003B
+#define IR_SONY_REPLAY       0x003C
+#define IR_SONY_SKIP         0x003D
+#define IR_SONY_GUIDE        0x005B
+#define IR_SONY_SYNC_MENU    0x0058
+#define IR_SONY_MENU         0x0060
+#define IR_SONY_EXIT         0x0063
+#define IR_SONY_OK           0x0065
+#define IR_SONY_UP           0x0074
+#define IR_SONY_DOWN         0x0075
+
+// Standard Logitech 880 buttons
+#define REMOTE_MUTE         IR_SONY_MUTE
+#define REMOTE_VOL_UP       IR_SONY_VOL_UP
+#define REMOTE_VOL_DOWN     IR_SONY_VOL_DOWN
+#define REMOTE_PG_DOWN      0
+#define REMOTE_PG_UP        0
+#define REMOTE_CH_DOWN      IR_SONY_CH_DOWN
+#define REMOTE_CH_UP        IR_SONY_CH_UP
+#define REMOTE_PREV         IR_SONY_PREV
+#define REMOTE_UP           IR_SONY_UP
+#define REMOTE_DOWN         IR_SONY_DOWN
+#define REMOTE_LEFT         IR_SONY_LEFT
+#define REMOTE_RIGHT        IR_SONY_RIGHT
+#define REMOTE_OK           IR_SONY_OK
+#define REMOTE_MENU         IR_SONY_MENU
+#define REMOTE_EXIT         IR_SONY_EXIT
+#define REMOTE_GUIDE        IR_SONY_GUIDE
+#define REMOTE_INFO         IR_SONY_INFO
+#define REMOTE_STOP         IR_SONY_STOP
+#define REMOTE_REPLAY       IR_SONY_REPLAY
+#define REMOTE_SKIP         IR_SONY_SKIP
+#define REMOTE_PLAY         IR_SONY_PLAY
+#define REMOTE_REC          IR_SONY_REC
+#define REMOTE_REW          IR_SONY_REW
+#define REMOTE_FWD          IR_SONY_FWD
+#define REMOTE_PAUSE        IR_SONY_PAUSE
+#define REMOTE_1            IR_SONY_1
+#define REMOTE_2            IR_SONY_2
+#define REMOTE_3            IR_SONY_3
+#define REMOTE_4            IR_SONY_4
+#define REMOTE_5            IR_SONY_5
+#define REMOTE_6            IR_SONY_6
+#define REMOTE_7            IR_SONY_7
+#define REMOTE_8            IR_SONY_8
+#define REMOTE_9            IR_SONY_9
+#define REMOTE_PLUS         0
+#define REMOTE_0            IR_SONY_0
+#define REMOTE_ENTER        IR_SONY_SYNC_MENU
+
+// Additional buttons
+#define REMOTE_POWER_TOGGLE IR_SONY_POWER_TOGGLE
+#define REMOTE_POWER_ON     IR_SONY_POWER_ON
+#define REMOTE_POWER_OFF    IR_SONY_POWER_OFF
+#define REMOTE_BACK         IR_SONY_BACK
+#define REMOTE_RED          IR_SONY_RED
+#define REMOTE_GREEN        IR_SONY_GREEN
+#define REMOTE_YELLOW       IR_SONY_YELLOW
+#define REMOTE_BLUE         IR_SONY_BLUE
+#define REMOTE_SUBTITLE     IR_SONY_SUBTITLE
+#define REMOTE_ASPECT       0
+