pin-cir: support Sony protocol
authorNIIBE Yutaka <gniibe@fsij.org>
Mon, 27 Dec 2010 02:57:25 +0000 (11:57 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Mon, 27 Dec 2010 02:57:25 +0000 (11:57 +0900)
ChangeLog
boards/STBEE_MINI/board.c
boards/STBEE_MINI/board.h
src/gnuk.h
src/pin-cir.c

index 1e63a20..ab571a5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2010-12-27  NIIBE Yutaka  <gniibe@fsij.org>
+
+       * src/pin-cir.c (cir_timer_interrupt): Support Sony protocol.
+
 2010-12-24  NIIBE Yutaka  <gniibe@fsij.org>
 
        * src/pin-cir.c: New file.
index 9b7cd4a..82a971d 100644 (file)
@@ -24,11 +24,7 @@ hwinit1 (void)
   /* EXTI0 <= PB0 */
   AFIO->EXTICR[0] = AFIO_EXTICR1_EXTI0_PB;
   EXTI->IMR = 0;
-#if 0
-  EXTI->RTSR = EXTI_RTSR_TR0;
-#else
   EXTI->FTSR = EXTI_FTSR_TR0;
-#endif
   NVICEnableVector(EXTI0_IRQn,
                   CORTEX_PRIORITY_MASK(CORTEX_MINIMUM_PRIORITY));
 
index f778b32..ce3b501 100644 (file)
  * Please refer to the STM32 Reference Manual for details.
  */
 
+#if defined(PINPAD_SUPPORT)
 /*
  * Port A setup.
+ * PA6  - (TIM3_CH1) input with pull-up
+ * PA7  - (TIM3_CH2) input with pull-down
  * PA11 - input with pull-up (USBDM)
  * PA12 - input with pull-up (USBDP)
  * Everything input with pull-up except:
  */
 #define VAL_GPIOACRL            0x88888888      /*  PA7...PA0 */
 #define VAL_GPIOACRH            0x63688888      /* PA15...PA8 */
-#define VAL_GPIOAODR            0xFFFFFFFF
+#define VAL_GPIOAODR            0xFFFFFF7F
 
 /* Port B setup. */
-#if defined(PINPAD_SUPPORT)
 #define GPIOB_CIR              0
 #define GPIOB_BUTTON            2
 #define GPIOB_ROT_A             3
 #define VAL_GPIOBCRH            0x66666666      /* PB15...PB8 */
 #define VAL_GPIOBODR            0xFFFFFFFF
 #else
+/*
+ * Port A setup.
+ * PA11 - input with pull-up (USBDM)
+ * PA12 - input with pull-up (USBDP)
+ * Everything input with pull-up except:
+ * PA13 - Open Drain output (LED1 0:ON 1:OFF)
+ * PA14 - Push pull output  (USB ENABLE 0:DISABLE 1:ENABLE)
+ * PA15 - Open Drain output (LED2 0:ON 1:OFF)
+ */
+#define VAL_GPIOACRL            0x88888888      /*  PA7...PA0 */
+#define VAL_GPIOACRH            0x63688888      /* PA15...PA8 */
+#define VAL_GPIOAODR            0xFFFFFFFF
+
+/* Port B setup. */
 /* Everything input with pull-up */
 #define VAL_GPIOBCRL            0x88888888      /*  PB7...PB0 */
 #define VAL_GPIOBCRH            0x88888888      /* PB15...PB8 */
 #define VAL_GPIODCRH            0x88888888      /* PD15...PD8 */
 #define VAL_GPIODODR            0xFFFFFFFF
 
-#if defined(PINPAD_SUPPORT)
-extern void cir_ext_disable (void);
-extern void cir_ext_enable (void);
-#endif
-
 #endif /* _BOARD_H_ */
index 08a7f2a..d732320 100644 (file)
@@ -311,3 +311,8 @@ extern void flash_put_data_internal (const uint8_t *p, uint16_t hw);
 extern void flash_bool_write_internal (const uint8_t *p, int nr);
 extern void flash_cnt123_write_internal (const uint8_t *p, int which, int v);
 extern void flash_do_write_internal (const uint8_t *p, int nr, const uint8_t *data, int len);
+
+#if defined(PINPAD_SUPPORT)
+extern void cir_ext_disable (void);
+extern void cir_ext_enable (void);
+#endif
index e0065e5..c69e706 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * pin-cir.c -- PIN input device support (Consumer Infra Red)
+ * pin-cir.c -- PIN input device support (Consumer Infra-Red)
  *
  * Copyright (C) 2010 Free Software Initiative of Japan
  * Author: NIIBE Yutaka <gniibe@fsij.org>
 #include "board.h"
 #include "gnuk.h"
 
+#if 0
+#define DEBUG_CIR 1
+#endif
 /*
- * Controller of Sharp AQUOS: (START + 48-bit + STOP) x N
- * Controller of Toshiba REGZA: (START + 32-bit + STOP) + (START + STOP) x N
+ * NEC Protocol: (START + 32-bit + STOP) + (START + STOP) x N
+ *      32-bit: 8-bit command inverted + 8-bit command + 16-bit address
+ *     Example: Controller of Toshiba REGZA
+ *     Example: Controller of Ceiling Light by NEC
+ *
+ * Sony Protocol: (START + 12-bit)
+ *      12-bit: 5-bit address + 7-bit command
+ *     Example: Controller of Sony BRAVIA
+ *
+ * Unknown Protocol 1: (START + 48-bit + STOP) x N
+ *      Example: Controller of Sharp AQUOS
+ *      Example: Controller of Ceiling Light by Mitsubishi
+ *
+ * Unsupported:
+ *
+ * Unknown Protocol 2: (START + 112-bit + STOP)
+ *      Example: Controller of Mitsubishi air conditioner
+ *
+ * Unknown Protocol 3: (START + 128-bit + STOP)
+ *      Example: Controller of Fujitsu air conditioner
+ *
+ * Unknown Protocol 4: (START + 152-bit + STOP)
+ *      Example: Controller of Sanyo air conditioner
  */
 
 /*
@@ -124,25 +148,20 @@ static uint16_t intr_ext;
 static uint16_t intr_trg;
 static uint16_t intr_ovf;
 
-#define MAX_PININPUT_BIT 256
-static uint16_t pininput[MAX_PININPUT_BIT];
-static uint16_t *pininput_p;
+#define MAX_CIRINPUT_BIT 512
+static uint16_t cirinput[MAX_CIRINPUT_BIT];
+static uint16_t *cirinput_p;
 #endif
 
-/*
- * Currently, only NEC protocol is supported.
- */
-
-static uint16_t cir_adr;
-static uint16_t cir_cmd;
+static uint32_t cir_data;
 static uint8_t cir_seq;
-#define CIR_BIT_PERIOD 1000
+#define CIR_BIT_PERIOD 1500
+#define CIR_BIT_SIRC_PERIOD_ON 1000
 
 static void
 cir_init (void)
 {
-  cir_adr = 0;
-  cir_cmd = 0;
+  cir_data = 0;
   cir_seq = 0;
   cir_ext_enable ();
 }
@@ -158,7 +177,7 @@ pin_main (void *arg)
   pin_thread = chThdSelf ();
 
 #if defined(DEBUG_CIR)
-  pininput_p = pininput;
+  cirinput_p = cirinput;
 #endif
 
   chEvtClear (ALL_EVENTS);
@@ -181,14 +200,14 @@ pin_main (void *arg)
          DEBUG_SHORT (intr_trg);
          DEBUG_SHORT (intr_ovf);
          DEBUG_INFO ("----\r\n");
-         for (p = pininput; p < pininput_p; p++)
+         for (p = cirinput; p < cirinput_p; p++)
            DEBUG_SHORT (*p);
          DEBUG_INFO ("====\r\n");
 
-         pininput_p = pininput;
+         cirinput_p = cirinput;
 #endif
-         DEBUG_INFO ("**** CIR commdand:");
-         DEBUG_SHORT (cir_cmd);
+         DEBUG_INFO ("**** CIR data:");
+         DEBUG_WORD (cir_data);
          cir_init ();
        }
 
@@ -225,10 +244,10 @@ cir_ext_interrupt (void)
 
 #if defined(DEBUG_CIR)
   intr_ext++;
-  if (pininput_p - pininput < MAX_PININPUT_BIT)
+  if (cirinput_p - cirinput < MAX_CIRINPUT_BIT)
     {
-      *pininput_p++ = 0x0000;
-      *pininput_p++ = (uint16_t)chTimeNow ();
+      *cirinput_p++ = 0x0000;
+      *cirinput_p++ = (uint16_t)chTimeNow ();
     }
 #endif
 
@@ -245,31 +264,27 @@ cir_ext_interrupt (void)
 void
 cir_timer_interrupt (void)
 {
-  if ((TIM3->SR & TIM_SR_TIF))
-    {
-      uint16_t period, on, off;
+  uint16_t period, on, off;
 
-      period = TIM3->CCR1;
-      on = TIM3->CCR2;
-      off = period - on;
+  period = TIM3->CCR1;
+  on = TIM3->CCR2;
+  off = period - on;
 
-      if (cir_seq >= 2)
+  if ((TIM3->SR & TIM_SR_TIF))
+    {
+      if (cir_seq >= 1)
        {
-         uint8_t bit = (on >= CIR_BIT_PERIOD) ? 1 : 0;
-
-         if (cir_seq < 2 + 16)
-           cir_adr |= (bit << (cir_seq - 2));
-         else
-           cir_cmd |= (bit << (cir_seq - 2 - 16));
+         cir_data >>= 1;
+         cir_data |= (period >= CIR_BIT_PERIOD) ? 0x80000000 : 0;
        }
-      
+
       cir_seq++;
 
 #if defined(DEBUG_CIR)
-      if (pininput_p - pininput < MAX_PININPUT_BIT)
+      if (cirinput_p - cirinput < MAX_CIRINPUT_BIT)
        {
-         *pininput_p++ = on;
-         *pininput_p++ = off;
+         *cirinput_p++ = on;
+         *cirinput_p++ = off;
        }
       intr_trg++;
 #endif
@@ -282,28 +297,50 @@ cir_timer_interrupt (void)
     {
       TIM3->SR &= ~TIM_SR_UIF;
 
-      if (palReadPad (IOPORT2, GPIOB_CIR))
+      if (on > 0)
        {
-         /* disable Timer */
+         /* Disable the timer */
          TIM3->CR1 &= ~TIM_CR1_CEN;
          TIM3->DIER = 0;
 
-         if (cir_seq == 2 + 16 + 16
-             && (cir_cmd >> 8) == (cir_cmd & 0xff) ^ 0xff)
+         if (cir_seq == 12)
+           {
+#if defined(DEBUG_CIR)
+             if (cirinput_p - cirinput < MAX_CIRINPUT_BIT)
+               {
+                 *cirinput_p++ = on;
+                 *cirinput_p++ = 0xffff;
+               }
+#endif
+             cir_data >>= 21;
+             cir_data |= (on >= CIR_BIT_SIRC_PERIOD_ON) ? 0x800: 0;
+             cir_seq++;
+           }
+         else
+           /* It must be the stop bit, just ignore */
+           {
+             ;
+           }
+
+         if (cir_seq == 1 + 12
+#if defined(DEBUG_CIR)
+             || cir_seq > 12
+#endif
+             || cir_seq == 1 + 32
+             || cir_seq == 1 + 48)
            {
              /* Notify thread */
              chEvtSignal (pin_thread, (eventmask_t)1);
-             cir_cmd &= 0xff;
            }
          else
            /* Ignore data received and enable CIR again */
            cir_init ();
 
 #if defined(DEBUG_CIR)
-         if (pininput_p - pininput < MAX_PININPUT_BIT)
+         if (cirinput_p - cirinput < MAX_CIRINPUT_BIT)
            {
-             *pininput_p++ = 0xffff;
-             *pininput_p++ = (uint16_t)chTimeNow ();
+             *cirinput_p++ = 0xffff;
+             *cirinput_p++ = (uint16_t)chTimeNow ();
            }
          intr_ovf++;
 #endif