]> cloudbase.mooo.com Git - irmp.git/blobdiff - irsnd.c
Version 2.8.1: added PENTAX protocol
[irmp.git] / irsnd.c
diff --git a/irsnd.c b/irsnd.c
index 80d262e426038477001e06601a1e44135257491d..af089083375426ac1a44d32de0d5072afeb2ba12 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.83 2015/01/26 13:09:28 fm Exp $\r
+ * $Id: irsnd.c,v 1.85 2015/04/23 12:46:13 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
@@ -43,6 +43,7 @@
 #  else\r
 #    error Wrong value for IRSND_OCx, choose IRSND_OC0A or IRSND_OC0B in irsndconfig.h\r
 #  endif // IRSND_OCx\r
+\r
 #elif defined (__AVR_ATtiny45__) || defined (__AVR_ATtiny85__)      // ATtiny45/85 uses OC0A = PB0 or OC0B = PB1\r
 #  if IRSND_OCx == IRSND_OC0A                                       // OC0A\r
 #    define IRSND_PORT_LETTER                       B\r
@@ -53,6 +54,7 @@
 #  else\r
 #    error Wrong value for IRSND_OCx, choose IRSND_OC0A or IRSND_OC0B in irsndconfig.h\r
 #  endif // IRSND_OCx\r
+\r
 #elif defined (__AVR_ATtiny87__) || defined (__AVR_ATtiny167__)     // ATtiny87/167 uses OC0A = PA2\r
 #  if IRSND_OCx == IRSND_OC0A                                       // OC0A\r
 #    define IRSND_PORT_LETTER                       A\r
@@ -60,6 +62,7 @@
 #  else\r
 #    error Wrong value for IRSND_OCx, choose IRSND_OC0A in irsndconfig.h\r
 #  endif // IRSND_OCx\r
+\r
 #elif defined (__AVR_ATmega8__)                                     // ATmega8 uses only OC2 = PB3\r
 #  if IRSND_OCx == IRSND_OC2                                        // OC0A\r
 #    define IRSND_PORT_LETTER                       B\r
@@ -74,6 +77,7 @@
 #  else\r
 #    error Wrong value for IRSND_OCx, choose IRSND_OC2 in irsndconfig.h\r
 #  endif // IRSND_OCx\r
+\r
 #elif defined (__AVR_ATmega162__)                                   // ATmega162 uses OC2 = PB1 or OC0 = PB0\r
 #  if IRSND_OCx == IRSND_OC2                                        // OC2\r
 #    define IRSND_PORT_LETTER                       B\r
@@ -84,6 +88,7 @@
 #  else\r
 #    error Wrong value for IRSND_OCx, choose IRSND_OC2 or IRSND_OC0 in irsndconfig.h\r
 #  endif // IRSND_OCx\r
+\r
 #elif defined (__AVR_ATmega164__)   \\r
    || defined (__AVR_ATmega324__)   \\r
    || defined (__AVR_ATmega644__)   \\r
 #  else\r
 #    error Wrong value for IRSND_OCx, choose IRSND_OC2A, IRSND_OC2B, IRSND_OC0A, or IRSND_OC0B in irsndconfig.h\r
 #  endif // IRSND_OCx\r
+\r
 #elif defined (__AVR_ATmega48__)    \\r
    || defined (__AVR_ATmega88__)    \\r
    || defined (__AVR_ATmega88P__)   \\r
 #  else\r
 #    error Wrong value for IRSND_OCx, choose IRSND_OC2A, IRSND_OC2B, IRSND_OC0A, or IRSND_OC0B in irsndconfig.h\r
 #  endif // IRSND_OCx\r
+\r
 #elif defined (__AVR_ATmega8515__)                                  // ATmega8515 uses OC0 = PB0 or OC1A = PD5 or OC1B = PE2\r
 #  if IRSND_OCx == IRSND_OC0   \r
 #    define IRSND_PORT_LETTER                       B\r
 #  elif IRSND_OCx == IRSND_OC1B \r
 #    define IRSND_PORT_LETTER                       E\r
 #    define IRSND_BIT_NUMBER                        2\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 IRSND_BIT_NUMBER                        1\r
+#  elif IRSND_OCx == IRSND_XMEGA_OC0C\r
+#    define IRSND_BIT_NUMBER                        2\r
+#  elif IRSND_OCx == IRSND_XMEGA_OC0D\r
+#    define IRSND_BIT_NUMBER                        3\r
+#  elif IRSND_OCx == IRSND_XMEGA_OC1A\r
+#    define IRSND_BIT_NUMBER                        4\r
+#  elif IRSND_OCx == IRSND_XMEGA_OC1B\r
+#    define IRSND_BIT_NUMBER                        5\r
 #  else\r
 #    error Wrong value for IRSND_OCx, choose IRSND_OC0, IRSND_OC1A, or IRSND_OC1B in irsndconfig.h\r
 #  endif // IRSND_OCx\r
+\r
 #elif defined (PIC_C18)    //Microchip C18 compiler\r
     //Nothing here to do here -> See irsndconfig.h\r
 #elif defined (ARM_STM32)  //STM32\r
 #  endif // unix, WIN32\r
 #endif // __AVR...\r
 \r
-#if defined(ATMEL_AVR)\r
+#if defined(__AVR_XMEGA__)\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_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 IRSND_PORT                                CONCAT(PORT, IRSND_PORT_LETTER)\r
 #define ROOMBA_0_PAUSE_LEN                      (uint8_t)(F_INTERRUPTS * ROOMBA_0_PAUSE_TIME + 0.5)\r
 #define ROOMBA_FRAME_REPEAT_PAUSE_LEN           (uint16_t)(F_INTERRUPTS * ROOMBA_FRAME_REPEAT_PAUSE_TIME + 0.5)               // use uint16_t!\r
 \r
+#define PENTAX_START_BIT_PULSE_LEN              (uint8_t)(F_INTERRUPTS * PENTAX_START_BIT_PULSE_TIME + 0.5)\r
+#define PENTAX_START_BIT_PAUSE_LEN              (uint8_t)(F_INTERRUPTS * PENTAX_START_BIT_PAUSE_TIME + 0.5)\r
+#define PENTAX_REPEAT_START_BIT_PAUSE_LEN       (uint8_t)(F_INTERRUPTS * PENTAX_REPEAT_START_BIT_PAUSE_TIME + 0.5)\r
+#define PENTAX_PULSE_LEN                        (uint8_t)(F_INTERRUPTS * PENTAX_PULSE_TIME + 0.5)\r
+#define PENTAX_1_PAUSE_LEN                      (uint8_t)(F_INTERRUPTS * PENTAX_1_PAUSE_TIME + 0.5)\r
+#define PENTAX_0_PAUSE_LEN                      (uint8_t)(F_INTERRUPTS * PENTAX_0_PAUSE_TIME + 0.5)\r
+#define PENTAX_FRAME_REPEAT_PAUSE_LEN           (uint16_t)(F_INTERRUPTS * PENTAX_FRAME_REPEAT_PAUSE_TIME + 0.5)              // use uint16_t!\r
+\r
 static volatile uint8_t                         irsnd_busy = 0;\r
 static volatile uint8_t                         irsnd_protocol = 0;\r
 static volatile uint8_t                         irsnd_buffer[6] = {0};\r
@@ -414,10 +464,25 @@ irsnd_on (void)
 #  if defined(PIC_C18)                                  // PIC C18\r
         PWMon();\r
         // IRSND_PIN = 0; // output mode -> enable PWM outout pin (0=PWM on, 1=PWM off)\r
+\r
 #  elif defined (ARM_STM32)                             // STM32\r
         TIM_SelectOCxM(IRSND_TIMER, IRSND_TIMER_CHANNEL, TIM_OCMode_PWM1); // enable PWM as OC-mode\r
         TIM_CCxCmd(IRSND_TIMER, IRSND_TIMER_CHANNEL, TIM_CCx_Enable);      // enable OC-output (is being disabled in TIM_SelectOCxM())\r
         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
+#    else\r
+#       error wrong value of IRSND_OCx\r
+#    endif // IRSND_OCx\r
+\r
 #  else                                                 // AVR\r
 #    if   IRSND_OCx == IRSND_OC2                        // use OC2\r
         TCCR2 |= (1<<COM20)|(1<<WGM21);                 // toggle OC2 on compare match,  clear Timer 2 at compare match OCR2\r
@@ -463,11 +528,26 @@ irsnd_off (void)
 #  if defined(PIC_C18)                                  // PIC C18\r
         PWMoff();\r
         // IRSND_PIN = 1; //input mode -> disbale PWM output pin (0=PWM on, 1=PWM off)\r
+\r
 #  elif defined (ARM_STM32)                             // STM32\r
         TIM_Cmd(IRSND_TIMER, DISABLE);                  // disable counter\r
         TIM_SelectOCxM(IRSND_TIMER, IRSND_TIMER_CHANNEL, TIM_ForcedAction_InActive);   // force output inactive\r
         TIM_CCxCmd(IRSND_TIMER, IRSND_TIMER_CHANNEL, TIM_CCx_Enable);      // enable OC-output (is being disabled in TIM_SelectOCxM())\r
         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
+        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
+        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
+#    else\r
+#       error wrong value of IRSND_OCx\r
+#    endif // IRSND_OCx\r
+\r
 #  else //AVR\r
 \r
 #    if   IRSND_OCx == IRSND_OC2                        // use OC2\r
@@ -568,6 +648,10 @@ irsnd_set_freq (IRSND_FREQ_TYPE freq)
          TIM_SetAutoreload(IRSND_TIMER, freq - 1);\r
          /* Set duty cycle */\r
          TIM_SetCompare1(IRSND_TIMER, (freq + 1) / 2);\r
+\r
+#  elif defined (__AVR_XMEGA__)\r
+        XMEGA_Timer.CCA = freq;\r
+\r
 #  else                                                                                     // AVR\r
 \r
 #    if IRSND_OCx == IRSND_OC2\r
@@ -1232,12 +1316,20 @@ irsnd_send_data (IRMP_DATA * irmp_data_p, uint8_t do_wait)
 #if IRSND_SUPPORT_ROOMBA_PROTOCOL == 1\r
         case IRMP_ROOMBA_PROTOCOL:\r
         {\r
-\r
             irsnd_buffer[0] = (irmp_data_p->command & 0x7F) << 1;                                               // CCCCCCC.\r
             irsnd_busy      = TRUE;\r
             break;\r
         }\r
 #endif\r
+#if IRSND_SUPPORT_PENTAX_PROTOCOL == 1\r
+        case IRMP_PENTAX_PROTOCOL:\r
+        {\r
+            irsnd_buffer[0] = (irmp_data_p->command & 0x3F) << 2;                                               // CCCCCC..\r
+            irsnd_busy      = TRUE;\r
+            break;\r
+        }\r
+#endif\r
+\r
         default:\r
         {\r
             break;\r
@@ -1993,6 +2085,24 @@ irsnd_ISR (void)
                         irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
                         break;\r
                     }\r
+#endif\r
+#if IRSND_SUPPORT_PENTAX_PROTOCOL == 1\r
+                    case IRMP_PENTAX_PROTOCOL:\r
+                    {\r
+                        startbit_pulse_len          = PENTAX_START_BIT_PULSE_LEN;\r
+                        startbit_pause_len          = PENTAX_START_BIT_PAUSE_LEN;\r
+                        complete_data_len           = PENTAX_COMPLETE_DATA_LEN;\r
+                        pulse_1_len                 = PENTAX_PULSE_LEN;\r
+                        pause_1_len                 = PENTAX_1_PAUSE_LEN - 1;\r
+                        pulse_0_len                 = PENTAX_PULSE_LEN;\r
+                        pause_0_len                 = PENTAX_0_PAUSE_LEN - 1;\r
+                        has_stop_bit                = PENTAX_STOP_BIT;\r
+                        n_auto_repetitions          = 1;                                            // 1 frame\r
+                        auto_repetition_pause_len   = 0;\r
+                        repeat_frame_pause_len      = PENTAX_FRAME_REPEAT_PAUSE_LEN;\r
+                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
+                        break;\r
+                    }\r
 #endif\r
                     default:\r
                     {\r
@@ -2079,13 +2189,16 @@ irsnd_ISR (void)
 #if IRSND_SUPPORT_ROOMBA_PROTOCOL == 1\r
                 case IRMP_ROOMBA_PROTOCOL:\r
 #endif\r
+#if IRSND_SUPPORT_PENTAX_PROTOCOL == 1\r
+                case IRMP_PENTAX_PROTOCOL:\r
+#endif\r
 \r
 #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\r
+    IRSND_SUPPORT_ROOMBA_PROTOCOL == 1 || IRSND_SUPPORT_TELEFUNKEN_PROTOCOL == 1 || IRSND_SUPPORT_PENTAX_PROTOCOL == 1\r
                 {\r
 #if IRSND_SUPPORT_DENON_PROTOCOL == 1\r
                     if (irsnd_protocol == IRMP_DENON_PROTOCOL)\r