]> cloudbase.mooo.com Git - irmp.git/blobdiff - irsnd.c
Version 2.9.0: added MERLIN and FAN protocol
[irmp.git] / irsnd.c
diff --git a/irsnd.c b/irsnd.c
index af089083375426ac1a44d32de0d5072afeb2ba12..e477e4dfef54ab0e8bf39168e554edfc81756b79 100644 (file)
--- a/irsnd.c
+++ b/irsnd.c
@@ -13,7 +13,7 @@
  * ATmega164, ATmega324, ATmega644,  ATmega644P, ATmega1284, ATmega1284P\r
  * ATmega88,  ATmega88P, ATmega168,  ATmega168P, ATmega328P\r
  *\r
- * $Id: irsnd.c,v 1.85 2015/04/23 12:46:13 fm Exp $\r
+ * $Id: irsnd.c,v 1.88 2015/05/27 09:33:14 fm Exp $\r
  *\r
  * This program is free software; you can redistribute it and/or modify\r
  * it under the terms of the GNU General Public License as published by\r
 #  endif // IRSND_OCx\r
 \r
 #elif defined (__AVR_ATxmega128A1U__)                               // ATxmega128A1U \r
-#  if (XMEGA_Timer_NR == 1)\r
-#               define IRSND_PORT_PRE               PORTC\r
-#  elif (XMEGA_Timer_NR == 2)\r
-#               define IRSND_PORT_PRE               PORTD\r
-#  elif (XMEGA_Timer_NR == 3)\r
-#               define IRSND_PORT_PRE               PORTE\r
-#  elif (XMEGA_Timer_NR == 4)\r
-#               define IRSND_PORT_PRE               PORTF\r
-#  else\r
-#    warning wrong XMEGA_Timer_NR, choose correct value in irsndconfig.h\r
-#  endif\r
 #  if IRSND_OCx == IRSND_XMEGA_OC0A   \r
 #    define IRSND_BIT_NUMBER                        0\r
 #  elif IRSND_OCx == IRSND_XMEGA_OC0B\r
 #  define _CONCAT(a,b)                              a##b\r
 #  define CONCAT(a,b)                               _CONCAT(a,b)\r
 #  define IRSND_PORT                                IRSND_PORT_PRE.OUT\r
-#  define IRSND_DDR                                 IRSND_DDR_PRE.DIR\r
-#  define IRSND_PIN                                 IRSND_PIN_PRE.IN\r
+#  define IRSND_DDR                                 IRSND_PORT_PRE.DIR\r
+#  define IRSND_PIN                                 IRSND_PORT_PRE.IN\r
 #  define IRSND_BIT                                 IRSND_BIT_NUMBER\r
-\r
 #elif defined(ATMEL_AVR)\r
 #  define _CONCAT(a,b)                              a##b\r
 #  define CONCAT(a,b)                               _CONCAT(a,b)\r
 #define NUBERT_AUTO_REPETITION_PAUSE_LEN        (uint16_t)(F_INTERRUPTS * NUBERT_AUTO_REPETITION_PAUSE_TIME + 0.5)              // use uint16_t!\r
 #define NUBERT_FRAME_REPEAT_PAUSE_LEN           (uint16_t)(F_INTERRUPTS * NUBERT_FRAME_REPEAT_PAUSE_TIME + 0.5)                 // use uint16_t!\r
 \r
+#define FAN_START_BIT_PULSE_LEN                 (uint8_t)(F_INTERRUPTS * FAN_START_BIT_PULSE_TIME + 0.5)\r
+#define FAN_START_BIT_PAUSE_LEN                 (uint8_t)(F_INTERRUPTS * FAN_START_BIT_PAUSE_TIME + 0.5)\r
+#define FAN_1_PULSE_LEN                         (uint8_t)(F_INTERRUPTS * FAN_1_PULSE_TIME + 0.5)\r
+#define FAN_1_PAUSE_LEN                         (uint8_t)(F_INTERRUPTS * FAN_1_PAUSE_TIME + 0.5)\r
+#define FAN_0_PULSE_LEN                         (uint8_t)(F_INTERRUPTS * FAN_0_PULSE_TIME + 0.5)\r
+#define FAN_0_PAUSE_LEN                         (uint8_t)(F_INTERRUPTS * FAN_0_PAUSE_TIME + 0.5)\r
+#define FAN_AUTO_REPETITION_PAUSE_LEN           (uint16_t)(F_INTERRUPTS * FAN_AUTO_REPETITION_PAUSE_TIME + 0.5)              // use uint16_t!\r
+#define FAN_FRAME_REPEAT_PAUSE_LEN              (uint16_t)(F_INTERRUPTS * FAN_FRAME_REPEAT_PAUSE_TIME + 0.5)                 // use uint16_t!\r
+\r
 #define SPEAKER_START_BIT_PULSE_LEN             (uint8_t)(F_INTERRUPTS * SPEAKER_START_BIT_PULSE_TIME + 0.5)\r
 #define SPEAKER_START_BIT_PAUSE_LEN             (uint8_t)(F_INTERRUPTS * SPEAKER_START_BIT_PAUSE_TIME + 0.5)\r
 #define SPEAKER_1_PULSE_LEN                     (uint8_t)(F_INTERRUPTS * SPEAKER_1_PULSE_TIME + 0.5)\r
@@ -471,14 +468,18 @@ irsnd_on (void)
         TIM_Cmd(IRSND_TIMER, ENABLE);                   // enable counter\r
 \r
 #  elif defined (__AVR_XMEGA__) \r
-#    if ( (IRSND_OCx == IRSND_XMEGA_OC0A) | (IRSND_OCx == IRSND_XMEGA_OC1A) )           // use OC0A or OC1A\r
-        XMEGA_Timer.CTRLB |= (1<<TC0_CCAEN_bp);                                         // Compare A \r
-#    elif ((IRSND_OCx == IRSND_XMEGA_OC0B) | (IRSND_OCx == IRSND_XMEGA_OC1B) )          // use OC0B or OC1B\r
-        XMEGA_Timer.CTRLB |= (1<<TC0_CCBEN_bp);                                         // Compare B \r
-#    elif IRSND_OCx == IRSND_XMEGA_OC0C                                                 // use OC0C\r
-        XMEGA_Timer.CTRLB |= (1<<TC0_CCCEN_bp);                                         // Compare C\r
-#    elif IRSND_OCx == IRSND_XMEGA_OC0D                                                 // use OC0D\r
-        XMEGA_Timer.CTRLB |= (1<<TC0_CCDEN_bp);                                         // Compare D\r
+#    if (IRSND_OCx == IRSND_XMEGA_OC0A)                                 // use OC0A\r
+                XMEGA_Timer.CTRLB |= (1<<TC0_CCAEN_bp);                 // Compare A \r
+#    elif (IRSND_OCx == IRSND_XMEGA_OC0B)                               // use OC0B\r
+                XMEGA_Timer.CTRLB |= (1<<TC0_CCBEN_bp);                 // Compare B \r
+#    elif IRSND_OCx == IRSND_XMEGA_OC0C                                 // use OC0C\r
+                XMEGA_Timer.CTRLB |= (1<<TC0_CCCEN_bp);                 // Compare C\r
+#    elif IRSND_OCx == IRSND_XMEGA_OC0D                                 // use OC0D\r
+                XMEGA_Timer.CTRLB |= (1<<TC0_CCDEN_bp);                 // Compare D\r
+#    elif IRSND_OCx == IRSND_XMEGA_OC1A                                 // use OC1A\r
+                XMEGA_Timer.CTRLB |= (1<<TC1_CCAEN_bp);                 // Compare A\r
+#    elif IRSND_OCx == IRSND_XMEGA_OC1B                                 // use OC1B\r
+                XMEGA_Timer.CTRLB |= (1<<TC1_CCBEN_bp);                 // Compare B\r
 #    else\r
 #       error wrong value of IRSND_OCx\r
 #    endif // IRSND_OCx\r
@@ -536,14 +537,18 @@ irsnd_off (void)
         TIM_SetCounter(IRSND_TIMER, 0);                 // reset counter value\r
 \r
 #  elif defined (__AVR_XMEGA__)\r
-#    if ( (IRSND_OCx == IRSND_XMEGA_OC0A) | (IRSND_OCx == IRSND_XMEGA_OC1A) )           // use OC0A or OC1A\r
+#    if (IRSND_OCx == IRSND_XMEGA_OC0A)                                                                                                 // use OC0A \r
         XMEGA_Timer.CTRLB &= ~(1<<TC0_CCAEN_bp);                                        // Compare A disconnected\r
-#    elif ((IRSND_OCx == IRSND_XMEGA_OC0B) | (IRSND_OCx == IRSND_XMEGA_OC1B) )          // use OC0B or OC1B\r
+#    elif (IRSND_OCx == IRSND_XMEGA_OC0B)                                                                                               // use OC0B \r
         XMEGA_Timer.CTRLB &= ~(1<<TC0_CCBEN_bp);                                        // Compare B disconnected\r
 #    elif IRSND_OCx == IRSND_XMEGA_OC0C                                                 // use OC0C\r
         XMEGA_Timer.CTRLB &= ~(1<<TC0_CCCEN_bp);                                        // Compare C disconnected\r
 #    elif IRSND_OCx == IRSND_XMEGA_OC0D                                                 // use OC0D\r
         XMEGA_Timer.CTRLB &= ~(1<<TC0_CCDEN_bp);                                        // Compare D disconnected\r
+#    elif IRSND_OCx == IRSND_XMEGA_OC1A                                                 // use OC1A\r
+                XMEGA_Timer.CTRLB &= ~(1<<TC1_CCAEN_bp);                                        // Compare A disconnected\r
+#    elif IRSND_OCx == IRSND_XMEGA_OC1B                                                 // use OC1B\r
+                XMEGA_Timer.CTRLB &= ~(1<<TC1_CCBEN_bp);                                        // Compare B disconnected\r
 #    else\r
 #       error wrong value of IRSND_OCx\r
 #    endif // IRSND_OCx\r
@@ -746,7 +751,21 @@ irsnd_init (void)
         TIM_OC1PreloadConfig(IRSND_TIMER, TIM_OCPreload_Enable);\r
 \r
         irsnd_set_freq (IRSND_FREQ_36_KHZ);                                         // set default frequency\r
-#  else                                                                             // AVR\r
+\r
+# elif defined (__AVR_XMEGA__)\r
+        IRSND_PORT &= ~(1<<IRSND_BIT);                                              // set IRSND_BIT to low\r
+        IRSND_DDR |= (1<<IRSND_BIT);                                                // set IRSND_BIT to output\r
+\r
+        XMEGA_Timer.PER = 0xFFFF; //Topwert\r
+        XMEGA_Timer.CTRLB |= TC_WGMODE_FRQ_gc; //Modus: Frequenz entspricht CTC\r
+\r
+#    if AVR_PRESCALER == 8\r
+        XMEGA_Timer.CTRLA |= TC_CLKSEL_DIV8_gc;                                     // start Timer  prescaler = 8\r
+#    else\r
+        XMEGA_Timer.CTRLA |= TC_CLKSEL_DIV1_gc;                                     // start Timer  prescaler = 1\r
+#    endif\r
+                \r
+# else                                                                              // AVR\r
         IRSND_PORT &= ~(1<<IRSND_BIT);                                              // set IRSND_BIT to low\r
         IRSND_DDR |= (1<<IRSND_BIT);                                                // set IRSND_BIT to output\r
 \r
@@ -1145,6 +1164,15 @@ irsnd_send_data (IRMP_DATA * irmp_data_p, uint8_t do_wait)
             break;\r
         }\r
 #endif\r
+#if IRSND_SUPPORT_FAN_PROTOCOL == 1\r
+        case IRMP_FAN_PROTOCOL:\r
+        {\r
+            irsnd_buffer[0] = irmp_data_p->command >> 3;                                                        // CCCCCCCC\r
+            irsnd_buffer[1] = (irmp_data_p->command & 0x0007) << 5;                                             // CCC00000\r
+            irsnd_busy      = TRUE;\r
+            break;\r
+        }\r
+#endif\r
 #if IRSND_SUPPORT_SPEAKER_PROTOCOL == 1\r
         case IRMP_SPEAKER_PROTOCOL:\r
         {\r
@@ -1840,6 +1868,24 @@ irsnd_ISR (void)
                         break;\r
                     }\r
 #endif\r
+#if IRSND_SUPPORT_FAN_PROTOCOL == 1\r
+                    case IRMP_FAN_PROTOCOL:\r
+                    {\r
+                        startbit_pulse_len          = FAN_START_BIT_PULSE_LEN;\r
+                        startbit_pause_len          = FAN_START_BIT_PAUSE_LEN - 1;\r
+                        pulse_1_len                 = FAN_1_PULSE_LEN;\r
+                        pause_1_len                 = FAN_1_PAUSE_LEN - 1;\r
+                        pulse_0_len                 = FAN_0_PULSE_LEN;\r
+                        pause_0_len                 = FAN_0_PAUSE_LEN - 1;\r
+                        has_stop_bit                = FAN_STOP_BIT;\r
+                        complete_data_len           = FAN_COMPLETE_DATA_LEN;\r
+                        n_auto_repetitions          = FAN_FRAMES;                                   // only 1 frame\r
+                        auto_repetition_pause_len   = FAN_AUTO_REPETITION_PAUSE_LEN;                // 35 ms pause\r
+                        repeat_frame_pause_len      = FAN_FRAME_REPEAT_PAUSE_LEN;\r
+                        irsnd_set_freq (IRSND_FREQ_36_KHZ);\r
+                        break;\r
+                    }\r
+#endif\r
 #if IRSND_SUPPORT_SPEAKER_PROTOCOL == 1\r
                     case IRMP_SPEAKER_PROTOCOL:\r
                     {\r
@@ -2162,6 +2208,9 @@ irsnd_ISR (void)
 #if IRSND_SUPPORT_NUBERT_PROTOCOL == 1\r
                 case IRMP_NUBERT_PROTOCOL:\r
 #endif\r
+#if IRSND_SUPPORT_FAN_PROTOCOL == 1\r
+                case IRMP_FAN_PROTOCOL:\r
+#endif\r
 #if IRSND_SUPPORT_SPEAKER_PROTOCOL == 1\r
                 case IRMP_SPEAKER_PROTOCOL:\r
 #endif\r
@@ -2196,9 +2245,10 @@ irsnd_ISR (void)
 #if IRSND_SUPPORT_SIRCS_PROTOCOL == 1  || IRSND_SUPPORT_NEC_PROTOCOL == 1 || IRSND_SUPPORT_NEC16_PROTOCOL == 1 || IRSND_SUPPORT_NEC42_PROTOCOL == 1 || \\r
     IRSND_SUPPORT_LGAIR_PROTOCOL == 1 || IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1 || IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1 ||   \\r
     IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1 || IRSND_SUPPORT_RECS80_PROTOCOL == 1 || IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1 || IRSND_SUPPORT_DENON_PROTOCOL == 1 || \\r
-    IRSND_SUPPORT_NUBERT_PROTOCOL == 1 || IRSND_SUPPORT_SPEAKER_PROTOCOL == 1 || IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1 || IRSND_SUPPORT_FDC_PROTOCOL == 1 || IRSND_SUPPORT_RCCAR_PROTOCOL == 1 ||   \\r
-    IRSND_SUPPORT_JVC_PROTOCOL == 1 || IRSND_SUPPORT_NIKON_PROTOCOL == 1 || IRSND_SUPPORT_LEGO_PROTOCOL == 1 || IRSND_SUPPORT_THOMSON_PROTOCOL == 1 || \\r
-    IRSND_SUPPORT_ROOMBA_PROTOCOL == 1 || IRSND_SUPPORT_TELEFUNKEN_PROTOCOL == 1 || IRSND_SUPPORT_PENTAX_PROTOCOL == 1\r
+    IRSND_SUPPORT_NUBERT_PROTOCOL == 1 || IRSND_SUPPORT_FAN_PROTOCOL == 1 || IRSND_SUPPORT_SPEAKER_PROTOCOL == 1 || IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1 || \\r
+    IRSND_SUPPORT_FDC_PROTOCOL == 1 || IRSND_SUPPORT_RCCAR_PROTOCOL == 1 || IRSND_SUPPORT_JVC_PROTOCOL == 1 || IRSND_SUPPORT_NIKON_PROTOCOL == 1 || \\r
+    IRSND_SUPPORT_LEGO_PROTOCOL == 1 || IRSND_SUPPORT_THOMSON_PROTOCOL == 1 || IRSND_SUPPORT_ROOMBA_PROTOCOL == 1 || IRSND_SUPPORT_TELEFUNKEN_PROTOCOL == 1 || \\r
+    IRSND_SUPPORT_PENTAX_PROTOCOL == 1\r
                 {\r
 #if IRSND_SUPPORT_DENON_PROTOCOL == 1\r
                     if (irsnd_protocol == IRMP_DENON_PROTOCOL)\r