*\r
* Copyright (c) 2009-2010 Frank Meyer - frank(at)fli4l.de\r
*\r
- * $Id: irmp.c,v 1.62 2010/06/23 10:48:58 fm Exp $\r
+ * $Id: irmp.c,v 1.79 2010/08/28 22:14:56 fm Exp $\r
*\r
* ATMEGA88 @ 8 MHz\r
*\r
*\r
*---------------------------------------------------------------------------------------------------------------------------------------------------\r
*\r
+ * SIEMENS:\r
+ * --------\r
+ *\r
+ * SIEMENS frame: 1 start bit + 22 data bits + no stop bit\r
+ * SIEMENS data: 13 address bits + 1 repeat bit + 7 data bits + 1 unknown bit\r
+ *\r
+ * start bit data "0": data "1":\r
+ * -------_______ _______------- -------_______\r
+ * 250us 250us 250us 250us 250us 250us\r
+ *\r
+ *---------------------------------------------------------------------------------------------------------------------------------------------------\r
+ *\r
* PANASONIC (older protocol, yet not implemented, see also MATSUSHITA, timing very similar)\r
* -----------------------------------------------------------------------------------------\r
*\r
#define IRMP_TIMEOUT_TIME_MS 16500L // timeout after 16.5 ms darkness\r
\r
#if (F_INTERRUPTS * IRMP_TIMEOUT_TIME_MS) / 1000000 >= 254\r
-#define IRMP_TIMEOUT_LEN (uint16_t)(F_INTERRUPTS * IRMP_TIMEOUT_TIME + 0.5)\r
typedef uint16_t PAUSE_LEN;\r
#else\r
-#define IRMP_TIMEOUT_LEN (uint8_t)(F_INTERRUPTS * IRMP_TIMEOUT_TIME + 0.5)\r
typedef uint8_t PAUSE_LEN;\r
#endif\r
\r
-#define IRMP_KEY_REPETITION_LEN (uint16_t)(F_INTERRUPTS * 150.0e-3 + 0.5) // autodetect key repetition within 150 msec\r
+#define IRMP_TIMEOUT_LEN (PAUSE_LEN)(F_INTERRUPTS * IRMP_TIMEOUT_TIME + 0.5)\r
+#define IRMP_KEY_REPETITION_LEN (uint16_t)(F_INTERRUPTS * 150.0e-3 + 0.5) // autodetect key repetition within 150 msec\r
\r
#define MIN_TOLERANCE_00 1.0 // -0%\r
#define MAX_TOLERANCE_00 1.0 // +0%\r
#define NEC_1_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\r
#define NEC_0_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\r
#define NEC_0_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\r
+// autodetect nec repetition frame within 50 msec:\r
+// NEC seems to send the first repetition frame after 40ms, further repetition frames after 100 ms\r
+#if 0\r
+#define NEC_FRAME_REPEAT_PAUSE_LEN_MAX (uint16_t)(F_INTERRUPTS * NEC_FRAME_REPEAT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)\r
+#else\r
+#define NEC_FRAME_REPEAT_PAUSE_LEN_MAX (uint16_t)(F_INTERRUPTS * 100.0e-3 * MAX_TOLERANCE_20 + 0.5)\r
+#endif\r
\r
#define SAMSUNG_START_BIT_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
#define SAMSUNG_START_BIT_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
#define KASEIKYO_START_BIT_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
#define KASEIKYO_START_BIT_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
#define KASEIKYO_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * KASEIKYO_PULSE_TIME * MIN_TOLERANCE_50 + 0.5) - 1)\r
-#define KASEIKYO_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * KASEIKYO_PULSE_TIME * MAX_TOLERANCE_60 + 0.5) + 1)\r
-#define KASEIKYO_1_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * KASEIKYO_1_PAUSE_TIME * MIN_TOLERANCE_50 + 0.5) - 1)\r
-#define KASEIKYO_1_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * KASEIKYO_1_PAUSE_TIME * MAX_TOLERANCE_50 + 0.5) + 1)\r
+#define KASEIKYO_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * KASEIKYO_PULSE_TIME * MAX_TOLERANCE_50 + 0.5) + 1)\r
+#define KASEIKYO_1_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * KASEIKYO_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\r
+#define KASEIKYO_1_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * KASEIKYO_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\r
#define KASEIKYO_0_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * KASEIKYO_0_PAUSE_TIME * MIN_TOLERANCE_50 + 0.5) - 1)\r
#define KASEIKYO_0_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * KASEIKYO_0_PAUSE_TIME * MAX_TOLERANCE_50 + 0.5) + 1)\r
\r
#define BANG_OLUFSEN_START_BIT3_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
#define BANG_OLUFSEN_START_BIT3_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
#define BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
-#define BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) // 10% is too big (uint8_t)\r
+#define BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MAX ((PAUSE_LEN)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) // value must be below IRMP_TIMEOUT\r
#define BANG_OLUFSEN_START_BIT4_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT4_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
#define BANG_OLUFSEN_START_BIT4_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT4_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\r
#define BANG_OLUFSEN_START_BIT4_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT4_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
#define RCCAR_0_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RCCAR_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\r
#define RCCAR_0_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RCCAR_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\r
\r
+#define JVC_START_BIT_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * JVC_START_BIT_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\r
+#define JVC_START_BIT_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * JVC_START_BIT_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\r
+#define JVC_REPEAT_START_BIT_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * (JVC_FRAME_REPEAT_PAUSE_TIME - IRMP_TIMEOUT_TIME) * MIN_TOLERANCE_40 + 0.5) - 1) // HACK!\r
+#define JVC_REPEAT_START_BIT_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * (JVC_FRAME_REPEAT_PAUSE_TIME - IRMP_TIMEOUT_TIME) * MAX_TOLERANCE_40 + 0.5) - 1) // HACK!\r
+#define JVC_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * JVC_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\r
+#define JVC_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * JVC_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\r
+#define JVC_1_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * JVC_1_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\r
+#define JVC_1_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * JVC_1_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\r
+#define JVC_0_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * JVC_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\r
+#define JVC_0_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * JVC_0_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\r
+// autodetect JVC repetition frame within 50 msec:\r
+#define JVC_FRAME_REPEAT_PAUSE_LEN_MAX (uint16_t)(F_INTERRUPTS * JVC_FRAME_REPEAT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)\r
+\r
#define AUTO_FRAME_REPETITION_LEN (uint16_t)(F_INTERRUPTS * AUTO_FRAME_REPETITION_TIME + 0.5) // use uint16_t!\r
\r
#ifdef ANALYZE\r
UART0_UBRRL = UBRRL_VALUE;\r
\r
#if USE_2X\r
- UART0_UCSRA = (1<<U2X);\r
+ UART0_UCSRA |= (1<<U2X);\r
#else\r
- UART0_UCSRA = 0;\r
+ UART0_UCSRA &= ~(1<<U2X);\r
#endif\r
\r
UART0_UCSRC = UART0_UCSZ1_BIT_VALUE | UART0_UCSZ0_BIT_VALUE | UART0_URSEL_BIT_VALUE;\r
irmp_command &= 0xff;\r
rtc = TRUE;\r
}\r
- else if ((irmp_command & 0xFF00) == 0xD100)\r
+ else if (irmp_address == 0x87EE)\r
{\r
ANALYZE_PRINTF ("Switching to APPLE protocol\n");\r
irmp_protocol = IRMP_APPLE_PROTOCOL;\r
- irmp_command &= 0xff;\r
+ irmp_address = (irmp_command & 0xFF00) >> 8;\r
+ irmp_command &= 0x00FF;\r
rtc = TRUE;\r
}\r
break;\r
}\r
\r
// these statics must not be volatile, because they are only used by irmp_store_bit(), which is called by irmp_ISR()\r
-static uint16_t irmp_tmp_address; // ir address\r
-static uint16_t irmp_tmp_command; // ir command\r
+static uint16_t irmp_tmp_address; // ir address\r
+static uint16_t irmp_tmp_command; // ir command\r
\r
#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)\r
-static uint16_t irmp_tmp_address2; // ir address\r
-static uint16_t irmp_tmp_command2; // ir command\r
+static uint16_t irmp_tmp_address2; // ir address\r
+static uint16_t irmp_tmp_command2; // ir command\r
#endif\r
\r
#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\r
-static uint16_t irmp_tmp_id; // ir id (only SAMSUNG)\r
+static uint16_t irmp_tmp_id; // ir id (only SAMSUNG)\r
+#endif\r
+#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1\r
+static uint8_t xor_check[6]; // check kaseikyo "parity" bits\r
#endif\r
\r
-static uint8_t irmp_bit; // current bit position\r
+static uint8_t irmp_bit; // current bit position\r
\r
/*---------------------------------------------------------------------------------------------------------------------------------------------------\r
* store bit\r
static void\r
irmp_store_bit (uint8_t value)\r
{\r
+\r
if (irmp_bit >= irmp_param.address_offset && irmp_bit < irmp_param.address_end)\r
{\r
if (irmp_param.lsb_first)\r
irmp_tmp_command |= value;\r
}\r
}\r
+\r
#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\r
else if (irmp_param.protocol == IRMP_SAMSUNG_PROTOCOL && irmp_bit >= SAMSUNG_ID_OFFSET && irmp_bit < SAMSUNG_ID_OFFSET + SAMSUNG_ID_LEN)\r
{\r
irmp_tmp_id |= (((uint16_t) (value)) << (irmp_bit - SAMSUNG_ID_OFFSET)); // store with LSB first\r
}\r
#endif\r
+\r
+#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1\r
+ else if (irmp_param.protocol == IRMP_KASEIKYO_PROTOCOL && irmp_bit >= 20 && irmp_bit < 24)\r
+ {\r
+ irmp_tmp_command |= (((uint16_t) (value)) << (irmp_bit - 8)); // store 4 system bits in upper nibble with LSB first\r
+ }\r
+\r
+ if (irmp_param.protocol == IRMP_KASEIKYO_PROTOCOL && irmp_bit < KASEIKYO_COMPLETE_DATA_LEN)\r
+ {\r
+ if (value)\r
+ {\r
+ xor_check[irmp_bit / 8] |= 1 << (irmp_bit % 8);\r
+ }\r
+ else\r
+ {\r
+ xor_check[irmp_bit / 8] &= ~(1 << (irmp_bit % 8));\r
+ }\r
+ }\r
+\r
+#endif\r
+\r
irmp_bit++;\r
}\r
\r
}\r
else\r
{\r
- repetition_counter++;\r
+ if (repetition_counter < 0xFFFF) // avoid overflow of counter\r
+ {\r
+ repetition_counter++;\r
+ }\r
}\r
}\r
}\r
else\r
#endif // IRMP_SUPPORT_SIRCS_PROTOCOL == 1\r
\r
+#if IRMP_SUPPORT_JVC_PROTOCOL == 1\r
+ if (irmp_protocol == IRMP_JVC_PROTOCOL && // last protocol was JVC, awaiting repeat frame\r
+ irmp_pulse_time >= JVC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= JVC_START_BIT_PULSE_LEN_MAX &&\r
+ irmp_pause_time >= JVC_REPEAT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= JVC_REPEAT_START_BIT_PAUSE_LEN_MAX)\r
+ {\r
+ ANALYZE_PRINTF ("protocol = NEC or JVC repeat frame, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",\r
+ JVC_START_BIT_PULSE_LEN_MIN, JVC_START_BIT_PULSE_LEN_MAX,\r
+ JVC_REPEAT_START_BIT_PAUSE_LEN_MIN, JVC_REPEAT_START_BIT_PAUSE_LEN_MAX);\r
+ irmp_param_p = (IRMP_PARAMETER *) &nec_param; // tricky: use nec parameters\r
+ }\r
+ else\r
+#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1\r
+\r
#if IRMP_SUPPORT_NEC_PROTOCOL == 1\r
if (irmp_pulse_time >= NEC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= NEC_START_BIT_PULSE_LEN_MAX &&\r
irmp_pause_time >= NEC_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NEC_START_BIT_PAUSE_LEN_MAX)\r
{\r
irmp_bit++;\r
}\r
+#if IRMP_SUPPORT_JVC_PROTOCOL == 1\r
+ else if (irmp_param.protocol == IRMP_NEC_PROTOCOL && (irmp_bit == 16 || irmp_bit == 17)) // it was a JVC stop bit\r
+ {\r
+ ANALYZE_PRINTF ("Switching to JVC protocol\n");\r
+ irmp_param.stop_bit = TRUE; // set flag\r
+ irmp_param.protocol = IRMP_JVC_PROTOCOL; // switch protocol\r
+ irmp_param.complete_len = irmp_bit; // patch length: 16 or 17\r
+ irmp_tmp_command = (irmp_tmp_address >> 4); // set command: upper 12 bits are command bits\r
+ irmp_tmp_address = irmp_tmp_address & 0x000F; // lower 4 bits are address bits\r
+ irmp_start_bit_detected = 1; // tricky: don't wait for another start bit...\r
+ }\r
+#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1\r
else\r
{\r
ANALYZE_PRINTF ("error 2: pause %d after data bit %d too long\n", irmp_pause_time, irmp_bit);\r
else\r
#endif\r
\r
+#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1\r
+ // if KASEIKYO protocol and the code will be repeated within 50 ms, we will ignore 2nd repetition frame\r
+ if (irmp_param.protocol == IRMP_KASEIKYO_PROTOCOL && repetition_frame_number == 1)\r
+ {\r
+ ANALYZE_PRINTF ("code skipped: KASEIKYO auto repetition frame #%d, counter = %d, auto repetition len = %d\n",\r
+ repetition_frame_number + 1, repetition_counter, AUTO_FRAME_REPETITION_LEN);\r
+ repetition_counter = 0;\r
+ }\r
+ else\r
+#endif\r
+\r
#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\r
// if SAMSUNG32 protocol and the code will be repeated within 50 ms, we will ignore every 2nd frame\r
if (irmp_param.protocol == IRMP_SAMSUNG32_PROTOCOL && (repetition_frame_number & 0x01))\r
#if IRMP_SUPPORT_NEC_PROTOCOL == 1\r
if (irmp_param.protocol == IRMP_NEC_PROTOCOL && irmp_bit == 0) // repetition frame\r
{\r
- irmp_tmp_address = last_irmp_address; // address is last address\r
- irmp_tmp_command = last_irmp_command; // command is last command\r
- irmp_flags |= IRMP_FLAG_REPETITION;\r
+ if (repetition_counter < NEC_FRAME_REPEAT_PAUSE_LEN_MAX)\r
+ {\r
+ ANALYZE_PRINTF ("Detected NEC repetition frame, repetition_counter = %d\n", repetition_counter);\r
+ irmp_tmp_address = last_irmp_address; // address is last address\r
+ irmp_tmp_command = last_irmp_command; // command is last command\r
+ irmp_flags |= IRMP_FLAG_REPETITION;\r
+ repetition_counter = 0;\r
+ }\r
+ else\r
+ {\r
+ ANALYZE_PRINTF ("Detected NEC repetition frame, ignoring it: timeout occured, repetition_counter = %d > %d\n",\r
+ repetition_counter, NEC_FRAME_REPEAT_PAUSE_LEN_MAX);\r
+ irmp_ir_detected = FALSE;\r
+ }\r
}\r
#endif // IRMP_SUPPORT_NEC_PROTOCOL\r
+\r
+#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1\r
+ if (irmp_param.protocol == IRMP_KASEIKYO_PROTOCOL)\r
+ {\r
+ uint8_t xor;\r
+ // ANALYZE_PRINTF ("0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",\r
+ // xor_check[0], xor_check[1], xor_check[2], xor_check[3], xor_check[4], xor_check[5]);\r
+\r
+ xor = (xor_check[0] & 0x0F) ^ ((xor_check[0] & 0xF0) >> 4) ^ (xor_check[1] & 0x0F) ^ ((xor_check[1] & 0xF0) >> 4);\r
+\r
+ if (xor != (xor_check[2] & 0x0F))\r
+ {\r
+ ANALYZE_PRINTF ("error 4: wrong XOR check for customer id: 0x%1x 0x%1x\n", xor, xor_check[2] & 0x0F);\r
+ irmp_ir_detected = FALSE;\r
+ }\r
+\r
+ xor = xor_check[2] ^ xor_check[3] ^ xor_check[4];\r
+\r
+ if (xor != xor_check[5])\r
+ {\r
+ ANALYZE_PRINTF ("error 4: wrong XOR check for data bits: 0x%02x 0x%02x\n", xor, xor_check[5]);\r
+ irmp_ir_detected = FALSE;\r
+ }\r
+ }\r
+#endif // IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1\r
+\r
irmp_protocol = irmp_param.protocol;\r
\r
#if IRMP_SUPPORT_FDC_PROTOCOL == 1\r
irmp_tmp_command = 0;\r
irmp_pulse_time = 0;\r
irmp_pause_time = 0;\r
+\r
+#if IRMP_SUPPORT_JVC_PROTOCOL == 1\r
+ if (irmp_protocol == IRMP_JVC_PROTOCOL) // the stop bit of JVC frame is also start bit of next frame\r
+ { // set pulse time here!\r
+ irmp_pulse_time = ((uint8_t)(F_INTERRUPTS * JVC_START_BIT_PULSE_TIME));\r
+ }\r
+#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1\r
}\r
}\r
}\r
\r
#ifdef ANALYZE\r
\r
-// main function - for unix/linux + windows only!\r
-// AVR: see main.c!\r
-// Compile it under linux with:\r
-// cc irmp.c -o irmp\r
-//\r
-// usage: ./irmp [-v|-s|-a|-l|-p] < file\r
-// options:\r
-// -v verbose\r
-// -s silent\r
-// -a analyze\r
-// -l list pulse/pauses\r
-// -p print timings\r
+/*---------------------------------------------------------------------------------------------------------------------------------------------------\r
+ * main functions - for Unix/Linux + Windows only!\r
+ *\r
+ * AVR: see main.c!\r
+ *\r
+ * Compile it under linux with:\r
+ * cc irmp.c -o irmp\r
+ *\r
+ * usage: ./irmp [-v|-s|-a|-l|-p] < file\r
+ *\r
+ * options:\r
+ * -v verbose\r
+ * -s silent\r
+ * -a analyze\r
+ * -l list pulse/pauses\r
+ * -p print timings\r
+ *---------------------------------------------------------------------------------------------------------------------------------------------------\r
+ */\r
\r
static void\r
print_timings (void)\r
{\r
+ printf ("IRMP_TIMEOUT_LEN: %d\n", IRMP_TIMEOUT_LEN);\r
+ printf ("IRMP_KEY_REPETITION_LEN %d\n", IRMP_KEY_REPETITION_LEN);\r
+ puts ("");\r
printf ("PROTOCOL S S-PULSE S-PAUSE PULSE-0 PAUSE-0 PULSE-1 PAUSE-1\n");\r
printf ("====================================================================================\n");\r
printf ("SIRCS 1 %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d\n",\r
BANG_OLUFSEN_START_BIT1_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT1_PULSE_LEN_MAX,\r
BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MAX);\r
\r
+ printf ("BANG_OLUFSEN 2 %3d - %3d %3d - %3d\n",\r
+ BANG_OLUFSEN_START_BIT2_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT2_PULSE_LEN_MAX,\r
+ BANG_OLUFSEN_START_BIT2_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT2_PAUSE_LEN_MAX);\r
+\r
printf ("BANG_OLUFSEN 3 %3d - %3d %3d - %3d\n",\r
BANG_OLUFSEN_START_BIT3_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT3_PULSE_LEN_MAX,\r
BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MAX);\r
#define KEY_STOP 0x86 // keycode = 0x0076\r
#define KEY_MAIL 0x87 // keycode = 0x0077\r
#define KEY_FAVORITES 0x88 // keycode = 0x0078\r
-#define KEY_NEW_PAGE 0x99 // keycode = 0x0079\r
-#define KEY_SETUP 0x9A // keycode = 0x007a\r
-#define KEY_FONT 0x9B // keycode = 0x007b\r
-#define KEY_ON_OFF 0x9C // keycode = 0x007c\r
-\r
-#define KEY_INSERT 0xA0 // keycode = 0x004b\r
-#define KEY_DELETE 0xA1 // keycode = 0x004c\r
-#define KEY_LEFT 0xA2 // keycode = 0x004f\r
-#define KEY_HOME 0xA3 // keycode = 0x0050\r
-#define KEY_END 0xA4 // keycode = 0x0051\r
-#define KEY_UP 0xA5 // keycode = 0x0053\r
-#define KEY_DOWN 0xA6 // keycode = 0x0054\r
-#define KEY_PAGE_UP 0xA7 // keycode = 0x0055\r
-#define KEY_PAGE_DOWN 0xA8 // keycode = 0x0056\r
-#define KEY_RIGHT 0xA9 // keycode = 0x0059\r
+#define KEY_NEW_PAGE 0x89 // keycode = 0x0079\r
+#define KEY_SETUP 0x8A // keycode = 0x007a\r
+#define KEY_FONT 0x8B // keycode = 0x007b\r
+#define KEY_PRINT 0x8C // keycode = 0x007c\r
+#define KEY_ON_OFF 0x8E // keycode = 0x007c\r
+\r
+#define KEY_INSERT 0x90 // keycode = 0x004b\r
+#define KEY_DELETE 0x91 // keycode = 0x004c\r
+#define KEY_LEFT 0x92 // keycode = 0x004f\r
+#define KEY_HOME 0x93 // keycode = 0x0050\r
+#define KEY_END 0x94 // keycode = 0x0051\r
+#define KEY_UP 0x95 // keycode = 0x0053\r
+#define KEY_DOWN 0x96 // keycode = 0x0054\r
+#define KEY_PAGE_UP 0x97 // keycode = 0x0055\r
+#define KEY_PAGE_DOWN 0x98 // keycode = 0x0056\r
+#define KEY_RIGHT 0x99 // keycode = 0x0059\r
+#define KEY_MOUSE_1 0x9E // keycode = 0x0400\r
+#define KEY_MOUSE_2 0x9F // keycode = 0x0800\r
\r
static uint8_t\r
get_fdc_key (uint16_t cmd)\r
case 0x0055: key = KEY_PAGE_UP; break;\r
case 0x0056: key = KEY_PAGE_DOWN; break;\r
case 0x0059: key = KEY_RIGHT; break;\r
+ case 0x0400: key = KEY_MOUSE_1; break;\r
+ case 0x0800: key = KEY_MOUSE_2; break;\r
\r
default:\r
{\r
{\r
key = key_table[cmd] - 'a' + 1;\r
}\r
+ else\r
+ {\r
+ key = key_table[cmd];\r
+ }\r
}\r
else\r
{\r
\r
if (irmp_data.protocol == IRMP_FDC_PROTOCOL && (key = get_fdc_key (irmp_data.command)) != 0)\r
{\r
- if (key >= 32 && key < 0x7F)\r
+ if ((key >= 0x20 && key < 0x7F) || key >= 0xA0)\r
{\r
- printf ("p = %2d, a = 0x%04x, c = 0x%04x, f = 0x%02x, asc = 0x%02x, key = %c\n",\r
+ printf ("p = %2d, a = 0x%04x, c = 0x%04x, f = 0x%02x, asc = 0x%02x, key = '%c'\n",\r
irmp_data.protocol, irmp_data.address, irmp_data.command, irmp_data.flags, key, key);\r
}\r
+ else if (key == '\r' || key == '\t' || key == KEY_ESCAPE || (key >= 0x80 && key <= 0x9F)) // function keys\r
+ {\r
+ char * p = (char *) NULL;\r
+\r
+ switch (key)\r
+ {\r
+ case '\t' : p = "TAB"; break;\r
+ case '\r' : p = "CR"; break;\r
+ case KEY_ESCAPE : p = "ESCAPE"; break;\r
+ case KEY_MENUE : p = "MENUE"; break;\r
+ case KEY_BACK : p = "BACK"; break;\r
+ case KEY_FORWARD : p = "FORWARD"; break;\r
+ case KEY_ADDRESS : p = "ADDRESS"; break;\r
+ case KEY_WINDOW : p = "WINDOW"; break;\r
+ case KEY_1ST_PAGE : p = "1ST_PAGE"; break;\r
+ case KEY_STOP : p = "STOP"; break;\r
+ case KEY_MAIL : p = "MAIL"; break;\r
+ case KEY_FAVORITES : p = "FAVORITES"; break;\r
+ case KEY_NEW_PAGE : p = "NEW_PAGE"; break;\r
+ case KEY_SETUP : p = "SETUP"; break;\r
+ case KEY_FONT : p = "FONT"; break;\r
+ case KEY_PRINT : p = "PRINT"; break;\r
+ case KEY_ON_OFF : p = "ON_OFF"; break;\r
+\r
+ case KEY_INSERT : p = "INSERT"; break;\r
+ case KEY_DELETE : p = "DELETE"; break;\r
+ case KEY_LEFT : p = "LEFT"; break;\r
+ case KEY_HOME : p = "HOME"; break;\r
+ case KEY_END : p = "END"; break;\r
+ case KEY_UP : p = "UP"; break;\r
+ case KEY_DOWN : p = "DOWN"; break;\r
+ case KEY_PAGE_UP : p = "PAGE_UP"; break;\r
+ case KEY_PAGE_DOWN : p = "PAGE_DOWN"; break;\r
+ case KEY_RIGHT : p = "RIGHT"; break;\r
+ case KEY_MOUSE_1 : p = "KEY_MOUSE_1"; break;\r
+ case KEY_MOUSE_2 : p = "KEY_MOUSE_2"; break;\r
+ default : p = "<UNKNWON>"; break;\r
+ }\r
+\r
+ printf ("p = %2d, a = 0x%04x, c = 0x%04x, f = 0x%02x, asc = 0x%02x, key = %s\n",\r
+ irmp_data.protocol, irmp_data.address, irmp_data.command, irmp_data.flags, key, p);\r
+ }\r
else\r
{\r
printf ("p = %2d, a = 0x%04x, c = 0x%04x, f = 0x%02x, asc = 0x%02x\n",\r