📄 nec_ir.c
字号:
/***********************************************************************/
/* File: */
/* Copyright (c) 2000 ZORAN Corporation, All Rights Reserved */
/* THIS IS PROPRIETARY SOURCE CODE OF ZORAN CORPORATION */
/* */
/* =========== */
#include "iom163.h"
#define ir_rising() TCCR1B |= 0x40
#define ir_falling() TCCR1B &= 0xBF
//the time increment for gen_time is 1.00us
#define IR_MARGIN 300 //150
#define time_9000_us 9000/75
#define time_9000_ush 9900/75
#define time_9000_usl 8100/75
#define time_4500_us 4500/75
#define time_4500_ush 5100/75
#define time_4500_usl 3900/75
#define time_2250_us 2250/75
#define time_2250_ush 2550/75
#define time_2250_usl 1950/75
#define time_1125_us 1125/75
#define time_1125_ush 1275/75
#define time_1125_usl 975/75
#define G_IR_SYSTEM_CODE 0x00ff
// State of the remote key decoder
#define IDLE 0
#define LEADER_ON 1
#define LEADER_OFF 2
#define CUSTOM 3
#define DATA1 4
#define DATA2 5
// Hoe many repeat message will ignire before send it to the FSM's
#define REPEAT_DELAY 3
extern unsigned int key_buff,dvd_key;
/* TP0713, timer optimization */
unsigned char ir_get_timer(void)
{
static unsigned int old_ir_timer;
unsigned int t1,t2;
t1 = ICR1L;
t1 |= (unsigned int)ICR1H<<8;
if(t1>old_ir_timer)
t2 = t1-old_ir_timer;
else
t2 =(65535-old_ir_timer)+t1+1;
old_ir_timer = t1;
return (unsigned char)(t2/75);
}
#pragma interrupt_handler timer1_capt_isr:6
void timer1_capt_isr(void) //IR_IST
{
static unsigned char key; // Hold the key code
static unsigned char repeat_delay = REPEAT_DELAY; // Repeat code counter
static unsigned int custom; // Hold the custom (remote ID) code
static unsigned char state = 0; // State holder
static unsigned char count; // bits counter
static unsigned char data1, data2; // Temporary for holding the decoded data
static unsigned char valid_repeat = 0;
unsigned char t0; // Hold the last timer value
t0 = ir_get_timer();
switch (state) {
case IDLE:
ir_rising(); //ir_interrupt_set_edge(RISING_EDGE);
state = LEADER_ON;
break;
case LEADER_ON:
/* TP0713, timer optimization */
ir_falling();//ir_interrupt_set_edge(FALLING_EDGE);
state = ((t0>time_9000_usl) &&( t0<time_9000_ush)) ? LEADER_OFF:IDLE;
break;
case LEADER_OFF:
if (t0 > time_4500_usl && t0 < time_4500_ush) {
state = CUSTOM;
custom = 0;
count = 0;
repeat_delay = REPEAT_DELAY;
}
else
{
if (t0 > time_2250_usl && t0 < time_2250_ush)
{
if (repeat_delay)
{
// Delay before sendnig the first repeat
repeat_delay--;
}
else
{ // repeat last key
if (valid_repeat)
{
if(is_repeat_ui_key(key))
{
//dvd_key = key;//|0X8000
key_buff = key;
repeat_delay = REPEAT_DELAY;
}
}
}
}
//else
// valid_repeat = 0;
//set_falling();//ir_interrupt_set_edge(FALLING_EDGE);
state = IDLE;
}
break;
case CUSTOM:
/* TP0713, timer optimization */
if (t0 > time_1125_usl && t0 < time_1125_ush) {
custom <<= 1; /* a zero bit */
}
else
{
if (t0 > time_2250_usl && t0 < time_2250_ush) {
custom = (custom << 1) | 1; /* a one bit */
}
else {
// Garbage ... ignored
//ir_interrupt_set_edge(FALLING_EDGE);
state = IDLE;
valid_repeat = 0;
break;
}
}
/* count 16 'custom' bits */
if (++count == 16) {
if (custom != G_IR_SYSTEM_CODE)
{
// Noise from other remote ... ignore
//#ifdef TEST_IR_CODE //CT add for test ir key code in release version 1-3-6 10:18
//printf("custom code = ");
//debug_out_dwx(custom);
//printf("\n");
//#endif
//key_buff = custom;
//ir_interrupt_set_edge(FALLING_EDGE);
state = IDLE;
valid_repeat = 0;
break;
}
state = DATA1;
/* TP0713, timer optimization */
count = 0;
data1 = 0;
}
break;
case DATA1:
/* TP0713, timer optimization */
count++;
if (t0 > time_1125_usl&& t0 < time_1125_ush)
{
data1 <<= 1; /* a zero bit */
}
else
{
if (t0 > time_2250_usl && t0 < time_2250_ush)
{
data1 = (data1 << 1) ;
data1++; //| 1; /* a one bit */
}
else
{
//ir_interrupt_set_edge(FALLING_EDGE);
state = IDLE;
valid_repeat = 0;
break;
}
}
if (count == 8) {
state = DATA2;
count = 0;
data2 = 0;
}
break;
case DATA2:
/* TP0713, timer optimization */
count++;
if (t0 > time_1125_usl && t0 < time_1125_ush)
{
data2 <<= 1; /* a zero bit */
}
else
{
if (t0 > time_2250_usl && t0 < time_2250_ush)
{
data2 = (data2 << 1);
data2++;// | 1; /* a one bit */
}
else
{
//ir_interrupt_set_edge(FALLING_EDGE);
state = IDLE;
valid_repeat = 0;
break;
}
}
if (count == 8)
{
//ir_interrupt_set_edge(FALLING_EDGE);
state = IDLE;
if (data1 == (~data2 ))
{ // Check if data is valid
key = data1;
//dvd_key = data1;
key_buff = data1;
valid_repeat = 1;
}
}
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -