pin-cir: support Sony protocol

This commit is contained in:
NIIBE Yutaka
2010-12-27 11:57:25 +09:00
parent c67a30aba1
commit 315565ace0
5 changed files with 112 additions and 59 deletions

View File

@@ -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.

View 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));

View File

@@ -84,8 +84,11 @@
* 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:
@@ -95,10 +98,9 @@
*/
#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
@@ -117,6 +119,20 @@
#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 */
@@ -144,9 +160,4 @@
#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_ */

View 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

View 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>
@@ -27,9 +27,33 @@
#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;
period = TIM3->CCR1;
on = TIM3->CCR2;
off = period - on;
if (cir_seq >= 2)
if ((TIM3->SR & TIM_SR_TIF))
{
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));
if (cir_seq >= 1)
{
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