]> cloudbase.mooo.com Git - irmp.git/blobdiff - irmp.c
Version 2.6.4: changed timing tolerance of KASEIKYO
[irmp.git] / irmp.c
diff --git a/irmp.c b/irmp.c
index 0753e0d7ccb4784dc8e343577432607ce165a46d..018bb7fad36c2ad2af2738b0203102f67acdae8b 100644 (file)
--- a/irmp.c
+++ b/irmp.c
@@ -1,13 +1,11 @@
 /*---------------------------------------------------------------------------------------------------------------------------------------------------\r
  * irmp.c - infrared multi-protocol decoder, supports several remote control protocols\r
  *\r
- * Copyright (c) 2009-2013 Frank Meyer - frank(at)fli4l.de\r
+ * Copyright (c) 2009-2014 Frank Meyer - frank(at)fli4l.de\r
  *\r
- * $Id: irmp.c,v 1.155 2014/07/01 09:43:13 fm Exp $\r
+ * $Id: irmp.c,v 1.164 2014/09/15 12:36:28 fm Exp $\r
  *\r
- * ATMEGA88 @ 8 MHz\r
- *\r
- * Supported mikrocontrollers:\r
+ * Supported AVR mikrocontrollers:\r
  *\r
  * ATtiny87,  ATtiny167\r
  * ATtiny45,  ATtiny85\r
 #define MATSUSHITA_0_PAUSE_LEN_MIN              ((uint8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\r
 #define MATSUSHITA_0_PAUSE_LEN_MAX              ((uint8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\r
 \r
-#define KASEIKYO_START_BIT_PULSE_LEN_MIN        ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\r
-#define KASEIKYO_START_BIT_PULSE_LEN_MAX        ((uint8_t)(F_INTERRUPTS * KASEIKYO_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_START_BIT_PULSE_LEN_MIN        ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\r
+#define KASEIKYO_START_BIT_PULSE_LEN_MAX        ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\r
+#define KASEIKYO_START_BIT_PAUSE_LEN_MIN        ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\r
+#define KASEIKYO_START_BIT_PAUSE_LEN_MAX        ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 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_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
@@ -498,51 +496,98 @@ static void                                     (*irmp_callback_ptr) (uint8_t);
  *---------------------------------------------------------------------------------------------------------------------------------------------------\r
  */\r
 #if defined(UNIX_OR_WINDOWS) || IRMP_PROTOCOL_NAMES == 1\r
-char *\r
-irmp_protocol_names[IRMP_N_PROTOCOLS + 1] =\r
+static const char proto_unknown[]       PROGMEM = "UNKNOWN";\r
+static const char proto_sircs[]         PROGMEM = "SIRCS";\r
+static const char proto_nec[]           PROGMEM = "NEC";\r
+static const char proto_samsung[]       PROGMEM = "SAMSUNG";\r
+static const char proto_matsushita[]    PROGMEM = "MATSUSH";\r
+static const char proto_kaseikyo[]      PROGMEM = "KASEIKYO";\r
+static const char proto_recs80[]        PROGMEM = "RECS80";\r
+static const char proto_rc5[]           PROGMEM = "RC5";\r
+static const char proto_denon[]         PROGMEM = "DENON";\r
+static const char proto_rc6[]           PROGMEM = "RC6";\r
+static const char proto_samsung32[]     PROGMEM = "SAMSG32";\r
+static const char proto_apple[]         PROGMEM = "APPLE";\r
+static const char proto_recs80ext[]     PROGMEM = "RECS80EX";\r
+static const char proto_nubert[]        PROGMEM = "NUBERT";\r
+static const char proto_bang_olufsen[]  PROGMEM = "BANG OLU";\r
+static const char proto_grundig[]       PROGMEM = "GRUNDIG";\r
+static const char proto_nokia[]         PROGMEM = "NOKIA";\r
+static const char proto_siemens[]       PROGMEM = "SIEMENS";\r
+static const char proto_fdc[]           PROGMEM = "FDC";\r
+static const char proto_rccar[]         PROGMEM = "RCCAR";\r
+static const char proto_jvc[]           PROGMEM = "JVC";\r
+static const char proto_rc6a[]          PROGMEM = "RC6A";\r
+static const char proto_nikon[]         PROGMEM = "NIKON";\r
+static const char proto_ruwido[]        PROGMEM = "RUWIDO";\r
+static const char proto_ir60[]          PROGMEM = "IR60";\r
+static const char proto_kathrein[]      PROGMEM = "KATHREIN";\r
+static const char proto_netbox[]        PROGMEM = "NETBOX";\r
+static const char proto_nec16[]         PROGMEM = "NEC16";\r
+static const char proto_nec42[]         PROGMEM = "NEC42";\r
+static const char proto_lego[]          PROGMEM = "LEGO";\r
+static const char proto_thomson[]       PROGMEM = "THOMSON";\r
+static const char proto_bose[]          PROGMEM = "BOSE";\r
+static const char proto_a1tvbox[]       PROGMEM = "A1TVBOX";\r
+static const char proto_ortek[]         PROGMEM = "ORTEK";\r
+static const char proto_telefunken[]    PROGMEM = "TELEFUNKEN";\r
+static const char proto_roomba[]        PROGMEM = "ROOMBA";\r
+static const char proto_rcmm32[]        PROGMEM = "RCMM32";\r
+static const char proto_rcmm24[]        PROGMEM = "RCMM24";\r
+static const char proto_rcmm12[]        PROGMEM = "RCMM12";\r
+static const char proto_speaker[]       PROGMEM = "SPEAKER";\r
+static const char proto_lgair[]         PROGMEM = "LGAIR";\r
+static const char proto_samsung48[]     PROGMEM = "SAMSG48";\r
+\r
+static const char proto_radio1[]        PROGMEM = "RADIO1";\r
+\r
+const char * const\r
+irmp_protocol_names[IRMP_N_PROTOCOLS + 1] PROGMEM =\r
 {\r
-    "UNKNOWN",\r
-    "SIRCS",\r
-    "NEC",\r
-    "SAMSUNG",\r
-    "MATSUSH",\r
-    "KASEIKYO",\r
-    "RECS80",\r
-    "RC5",\r
-    "DENON",\r
-    "RC6",\r
-    "SAMSG32",\r
-    "APPLE",\r
-    "RECS80EX",\r
-    "NUBERT",\r
-    "BANG OLU",\r
-    "GRUNDIG",\r
-    "NOKIA",\r
-    "SIEMENS",\r
-    "FDC",\r
-    "RCCAR",\r
-    "JVC",\r
-    "RC6A",\r
-    "NIKON",\r
-    "RUWIDO",\r
-    "IR60",\r
-    "KATHREIN",\r
-    "NETBOX",\r
-    "NEC16",\r
-    "NEC42",\r
-    "LEGO",\r
-    "THOMSON",\r
-    "BOSE",\r
-    "A1TVBOX",\r
-    "ORTEK",\r
-    "TELEFUNKEN",\r
-    "ROOMBA",\r
-    "RCMM32",\r
-    "RCMM24",\r
-    "RCMM12",\r
-    "SPEAKER",\r
-    "LGAIR",\r
-    "RADIO1"\r
+    proto_unknown,\r
+    proto_sircs,\r
+    proto_nec,\r
+    proto_samsung,\r
+    proto_matsushita,\r
+    proto_kaseikyo,\r
+    proto_recs80,\r
+    proto_rc5,\r
+    proto_denon,\r
+    proto_rc6,\r
+    proto_samsung32,\r
+    proto_apple,\r
+    proto_recs80ext,\r
+    proto_nubert,\r
+    proto_bang_olufsen,\r
+    proto_grundig,\r
+    proto_nokia,\r
+    proto_siemens,\r
+    proto_fdc,\r
+    proto_rccar,\r
+    proto_jvc,\r
+    proto_rc6a,\r
+    proto_nikon,\r
+    proto_ruwido,\r
+    proto_ir60,\r
+    proto_kathrein,\r
+    proto_netbox,\r
+    proto_nec16,\r
+    proto_nec42,\r
+    proto_lego,\r
+    proto_thomson,\r
+    proto_bose,\r
+    proto_a1tvbox,\r
+    proto_ortek,\r
+    proto_telefunken,\r
+    proto_roomba,\r
+    proto_rcmm32,\r
+    proto_rcmm24,\r
+    proto_rcmm12,\r
+    proto_speaker,\r
+    proto_lgair,\r
+    proto_samsung48,\r
+\r
+    proto_radio1\r
 };\r
 \r
 #endif\r
@@ -736,79 +781,6 @@ irmp_uart_putc (unsigned char ch)
 #define ENDBITS                        1000                                 // number of sequenced highbits to detect end\r
 #define DATALEN                         700                                 // log buffer size\r
 \r
-#if 0                                                                       // old log routine\r
-\r
-static void\r
-irmp_log (uint8_t val)\r
-{\r
-    static uint8_t  buf[DATALEN];                                           // logging buffer\r
-    static uint16_t buf_idx;                                                // number of written bits\r
-    static uint8_t  startcycles;                                            // current number of start-zeros\r
-    static uint16_t cnt;                                                    // counts sequenced highbits - to detect end\r
-\r
-    if (! val && (startcycles < STARTCYCLES) && !buf_idx)                   // prevent that single random zeros init logging\r
-    {\r
-        startcycles++;\r
-    }\r
-    else\r
-    {\r
-        startcycles = 0;\r
-\r
-        if (! val || (val && buf_idx != 0))                                 // start or continue logging on "0", "1" cannot init logging\r
-        {\r
-            if (buf_idx < DATALEN * 8)                                      // index in range?\r
-            {                                                               // yes\r
-                if (val)\r
-                {\r
-                    buf[(buf_idx / 8)] |=  (1<<(buf_idx % 8));              // set bit\r
-                }\r
-                else\r
-                {\r
-                    buf[(buf_idx / 8)] &= ~(1<<(buf_idx % 8));              // reset bit\r
-                }\r
-\r
-                buf_idx++;\r
-            }\r
-\r
-            if (val)\r
-            {                                                               // if high received then look at log-stop condition\r
-                cnt++;\r
-\r
-                if (cnt > ENDBITS)\r
-                {                                                           // if stop condition is true, output on uart\r
-                    uint16_t i;\r
-\r
-                    for (i = 0; i < STARTCYCLES; i++)\r
-                    {\r
-                        irmp_uart_putc ('0');                               // the ignored starting zeros\r
-                    }\r
-\r
-                    for (i = 0; i < (buf_idx - ENDBITS + 20) / 8; i++)      // transform bitset into uart chars\r
-                    {\r
-                        uint8_t d = buf[i];\r
-                        uint8_t j;\r
-\r
-                        for (j = 0; j < 8; j++)\r
-                        {\r
-                            irmp_uart_putc ((d & 1) + '0');\r
-                            d >>= 1;\r
-                        }\r
-                    }\r
-\r
-                    irmp_uart_putc ('\n');\r
-                    buf_idx = 0;\r
-                }\r
-            }\r
-            else\r
-            {\r
-                cnt = 0;\r
-            }\r
-        }\r
-    }\r
-}\r
-\r
-#else                                                                       // new log routine\r
-\r
 static void\r
 irmp_log (uint8_t val)\r
 {\r
@@ -897,8 +869,6 @@ irmp_log (uint8_t val)
     }\r
 }\r
 \r
-#endif\r
-\r
 #else\r
 #define irmp_log(val)\r
 #endif //IRMP_LOGGING\r
@@ -1735,7 +1705,7 @@ static IRMP_PARAMETER                       irmp_param;
 static IRMP_PARAMETER                       irmp_param2;\r
 #endif\r
 \r
-static volatile uint8_t                     irmp_ir_detected;\r
+static volatile uint8_t                     irmp_ir_detected = FALSE;\r
 static volatile uint8_t                     irmp_protocol;\r
 static volatile uint16_t                    irmp_address;\r
 static volatile uint16_t                    irmp_command;\r
@@ -1827,7 +1797,15 @@ irmp_get_data (IRMP_DATA * irmp_data_p)
                     rtc = TRUE;\r
                 }\r
                 break;\r
+\r
+#if IRMP_SUPPORT_SAMSUNG48_PROTOCOL == 1\r
+            case IRMP_SAMSUNG48_PROTOCOL:\r
+                irmp_command = (irmp_command & 0x00FF) | ((irmp_id & 0x00FF) << 8);\r
+                rtc = TRUE;\r
+                break;\r
 #endif\r
+#endif\r
+\r
 #if IRMP_SUPPORT_NEC_PROTOCOL == 1\r
             case IRMP_NEC_PROTOCOL:\r
                 if ((irmp_command >> 8) == (~irmp_command & 0x00FF))\r
@@ -2001,7 +1979,7 @@ irmp_set_callback_ptr (void (*cb)(uint8_t))
 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) || IRMP_SUPPORT_NEC42_PROTOCOL == 1\r
+#if (IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)) || IRMP_SUPPORT_NEC42_PROTOCOL == 1\r
 static uint16_t irmp_tmp_address2;                                                      // ir address\r
 static uint16_t irmp_tmp_command2;                                                      // ir command\r
 #endif\r
@@ -2097,7 +2075,16 @@ irmp_store_bit (uint8_t value)
     {\r
         if (irmp_param.lsb_first)\r
         {\r
-            irmp_tmp_command |= (((uint16_t) (value)) << (irmp_bit - irmp_param.command_offset));   // CV wants cast\r
+#if IRMP_SUPPORT_SAMSUNG48_PROTOCOL == 1\r
+            if (irmp_param.protocol == IRMP_SAMSUNG48_PROTOCOL && irmp_bit >= 32)\r
+            {\r
+                irmp_tmp_id |= (((uint16_t) (value)) << (irmp_bit - 32));   // CV wants cast\r
+            }\r
+            else\r
+#endif\r
+            {\r
+                irmp_tmp_command |= (((uint16_t) (value)) << (irmp_bit - irmp_param.command_offset));   // CV wants cast\r
+            }\r
         }\r
         else\r
         {\r
@@ -2284,6 +2271,9 @@ irmp_ISR (void)
 #if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1\r
                     genre2                  = 0;\r
 #endif\r
+#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\r
+                    irmp_tmp_id = 0;\r
+#endif\r
 \r
 #if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1) || IRMP_SUPPORT_NEC42_PROTOCOL == 1\r
                     irmp_tmp_command2       = 0;\r
@@ -2314,8 +2304,8 @@ irmp_ISR (void)
                             {\r
 #ifdef ANALYZE\r
                                 ANALYZE_PRINTF ("%8.3fms warning: did not receive inverted command repetition\n",\r
-#endif // ANALYZE\r
                                                 (double) (time_counter * 1000) / F_INTERRUPTS);\r
+#endif // ANALYZE\r
                                 last_irmp_denon_command = 0;\r
                                 denon_repetition_len = 0xFFFF;\r
                             }\r
@@ -2361,7 +2351,8 @@ irmp_ISR (void)
                 }\r
                 else\r
                 {                                                               // receiving first data pulse!\r
-                    IRMP_PARAMETER * irmp_param_p = (IRMP_PARAMETER *) 0;\r
+                    IRMP_PARAMETER * irmp_param_p;\r
+                    irmp_param_p = (IRMP_PARAMETER *) 0;\r
 \r
 #if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)\r
                     irmp_param2.protocol = 0;\r
@@ -3358,6 +3349,20 @@ irmp_ISR (void)
                             }\r
 #endif // IRMP_SUPPORT_JVC_PROTOCOL == 1\r
 #endif // IRMP_SUPPORT_NEC42_PROTOCOL == 1\r
+\r
+#if IRMP_SUPPORT_SAMSUNG48_PROTOCOL == 1\r
+                            else if (irmp_param.protocol == IRMP_SAMSUNG48_PROTOCOL && irmp_bit == 32)          // it was a SAMSUNG32 stop bit\r
+                            {\r
+#ifdef ANALYZE\r
+                                ANALYZE_PRINTF ("Switching to SAMSUNG32 protocol\n");\r
+#endif // ANALYZE\r
+                                irmp_param.protocol         = IRMP_SAMSUNG32_PROTOCOL;\r
+                                irmp_param.command_offset   = SAMSUNG32_COMMAND_OFFSET;\r
+                                irmp_param.command_end      = SAMSUNG32_COMMAND_OFFSET + SAMSUNG32_COMMAND_LEN;\r
+                                irmp_param.complete_len     = SAMSUNG32_COMPLETE_DATA_LEN;\r
+                            }\r
+#endif // IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\r
+\r
 #if IRMP_SUPPORT_RCMM_PROTOCOL == 1\r
                             else if (irmp_param.protocol == IRMP_RCMM32_PROTOCOL && (irmp_bit == 12 || irmp_bit == 24))  // it was a RCMM stop bit\r
                             {\r
@@ -3689,16 +3694,27 @@ irmp_ISR (void)
                             ANALYZE_PRINTF ("SYNC\n");\r
 #endif // ANALYZE\r
                             wait_for_space = 0;\r
-                            irmp_tmp_id = 0;\r
                             irmp_bit++;\r
                         }\r
                         else  if (irmp_pulse_time >= SAMSUNG_PULSE_LEN_MIN && irmp_pulse_time <= SAMSUNG_PULSE_LEN_MAX)\r
                         {\r
+#if IRMP_SUPPORT_SAMSUNG48_PROTOCOL == 1\r
+#ifdef ANALYZE\r
+                            ANALYZE_PRINTF ("Switching to SAMSUNG48 protocol ");\r
+#endif // ANALYZE\r
+                            irmp_param.protocol         = IRMP_SAMSUNG48_PROTOCOL;\r
+                            irmp_param.command_offset   = SAMSUNG48_COMMAND_OFFSET;\r
+                            irmp_param.command_end      = SAMSUNG48_COMMAND_OFFSET + SAMSUNG48_COMMAND_LEN;\r
+                            irmp_param.complete_len     = SAMSUNG48_COMPLETE_DATA_LEN;\r
+#else\r
+#ifdef ANALYZE\r
+                            ANALYZE_PRINTF ("Switching to SAMSUNG32 protocol ");\r
+#endif // ANALYZE\r
                             irmp_param.protocol         = IRMP_SAMSUNG32_PROTOCOL;\r
                             irmp_param.command_offset   = SAMSUNG32_COMMAND_OFFSET;\r
                             irmp_param.command_end      = SAMSUNG32_COMMAND_OFFSET + SAMSUNG32_COMMAND_LEN;\r
                             irmp_param.complete_len     = SAMSUNG32_COMPLETE_DATA_LEN;\r
-\r
+#endif\r
                             if (irmp_pause_time >= SAMSUNG_1_PAUSE_LEN_MIN && irmp_pause_time <= SAMSUNG_1_PAUSE_LEN_MAX)\r
                             {\r
 #ifdef ANALYZE\r
@@ -3717,10 +3733,6 @@ irmp_ISR (void)
                                 irmp_store_bit (0);\r
                                 wait_for_space = 0;\r
                             }\r
-\r
-#ifdef ANALYZE\r
-                            ANALYZE_PRINTF ("Switching to SAMSUNG32 protocol\n");\r
-#endif // ANALYZE\r
                         }\r
                         else\r
                         {                                                           // timing incorrect!\r
@@ -4032,11 +4044,11 @@ irmp_ISR (void)
 #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 SAMSUNG32 or SAMSUNG48 protocol and the code will be repeated within 50 ms, we will ignore every 2nd frame\r
+                if ((irmp_param.protocol == IRMP_SAMSUNG32_PROTOCOL || irmp_param.protocol == IRMP_SAMSUNG48_PROTOCOL) && (repetition_frame_number & 0x01))\r
                 {\r
 #ifdef ANALYZE\r
-                    ANALYZE_PRINTF ("code skipped: SAMSUNG32 auto repetition frame #%d, counter = %d, auto repetition len = %d\n",\r
+                    ANALYZE_PRINTF ("code skipped: SAMSUNG32/SAMSUNG48 auto repetition frame #%d, counter = %d, auto repetition len = %d\n",\r
                                     repetition_frame_number + 1, key_repetition_len, AUTO_FRAME_REPETITION_LEN);\r
 #endif // ANALYZE\r
                     key_repetition_len = 0;\r