📄 nec_ir.c
字号:
/* **************************************************************************************
* Copyright (c) 2002 ZORAN Corporation, All Rights Reserved
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF ZORAN CORPORATION
*
* File: $Workfile: nec_ir.c $
*
* Description:
* ============
* NEC IR implementation
*
* Log:
* ====
* $Revision: 12 $
* Last Modified by $Author: Nirm $ at $Modtime: 17/07/02 20:01 $
****************************************************************************************
* Updates:
****************************************************************************************
* $Log: /I49/H49V/Remote/nec_ir/nec_ir.c $
*
* 12 17/07/02 20:25 Nirm
* - Adjustments to timer_0 in order to increase timer-measurement
* accuracy throughout the system.
*
* 11 5/28/02 18:47 Rinata
* FF and FB are not with valid repeat
*
* 10 23/04/02 9:37 Nirm
* - Added dependency in "Config.h".
*
* 9 7/03/02 17:45 Nirm
* Removed EMERGENCY_EJECT_ENABLED -> replaced by the Exceptioning
* mechanism.
*
* 8 18/02/02 11:01 Atai
* make global to static
*
* 7 2/17/02 12:21p Tomasp
* Code clean up.
*
* 6 1/28/02 19:55 Rinata
* fix gen timer values for ir
*
* 5 9/01/02 16:58 Nirm
* Corrected Include-Paths.
*
* 4 1/06/02 15:46 Rinata
*
* 3 1/01/02 19:10 Atai
* Code cleaning
*
* 2 25/12/01 12:29 Atai
* Code cleaning
**************************************************************************************** */
#include "Config.h" // Global Configuration - do not remove!
#include "Kernel\ker_api.h"
#include "Kernel\eventdef.h"
#include "CPU\cpu_api.h"
#include "CPU\Timefunc.h"
#include "Playcore\Coremain\coremain.h"
#include "Playcore\Coremain\coredefs.h"
#include "Playcore\Coremain\coregdef.h"
#include "Remote\ir_api.h"
#include "Remote\ir_ll.h"
#include "Remote\NEC_IR\nec_ir.h"
#include "ir_lut.h"
#ifdef IR_KEYCODE_TEST//TT010203
extern WORD ir_custom,ir_command;
#endif
extern BOOL g_core_task_ready;
//extern CONST WORD g_ir_system_code;
//extern CONST WORD g_ir_power_key_code;
//extern CONST WORD g_ir_eject_key_code;
#ifdef MODIFIED_FOR_T1_2002
extern const WORD g_ir_volume_up_key ;//add for t1.
extern const WORD g_ir_volume_down_key ;//
#endif
//the time increment for gen_time is 1.25us
#define IR_MARGIN ((WORD)130UL)
#define time_9000_us ((WORD)9000UL)
#define time_4500_us ((WORD)4500UL)
#define time_2250_us ((WORD)2250UL)
#define time_1125_us ((WORD)1125UL)
// 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 5
#ifdef IR_NO_REPEAT_PULSE
#define IR_INTERVAL 240/20
BYTE last_key = 0;
BYTE ir_interval = 0;
#endif
static unsigned long time_count_old;
void ir_init(void)
{
ir_interrupt_and_timer_init( FALLING_EDGE );
time_count_old = gen_timer();
}
void ir_isr( void )
{
static BYTE key; // Hold the key code
static BYTE repeat_delay = REPEAT_DELAY; // Repeat code counter
static WORD custom; // Hold the custom (remote ID) code
static BYTE state = 0; // State holder
static BYTE count; // bits counter
static BYTE data1, data2; // Temporary for holding the decoded data
static BYTE valid_repeat = 0;
unsigned long time_count = gen_timer();
unsigned long t0 = time_count - time_count_old;
switch (state) {
case IDLE:
time_count_old = time_count;
ir_interrupt_set_edge(RISING_EDGE);
state = LEADER_ON;
break;
case LEADER_ON:
time_count_old = time_count;
ir_interrupt_set_edge(FALLING_EDGE);
state = ((t0>(time_9000_us-8*IR_MARGIN)) && (t0<(time_9000_us+8*IR_MARGIN))) ? LEADER_OFF:IDLE;
break;
case LEADER_OFF:
if (t0 > time_4500_us - (4*IR_MARGIN) && t0 < time_4500_us + (4*IR_MARGIN)) {
state = CUSTOM;
custom = 0;
count = 0;
repeat_delay = REPEAT_DELAY;
}
else {
if (t0 > time_2250_us - (2*IR_MARGIN) && t0 < time_2250_us + (2*IR_MARGIN)) {
if (repeat_delay) {
// Delay before sendnig the first repeat
repeat_delay--;
}
else { // repeat last key
if (valid_repeat) {
send_remote_event( REMOTE_KEY_REPEATED|key );
}
}
}
ir_interrupt_set_edge(FALLING_EDGE);
state = IDLE;
}
time_count_old = time_count;
break;
case CUSTOM:
time_count_old = time_count;
if (t0 > time_1125_us - IR_MARGIN && t0 < time_1125_us + IR_MARGIN) {
custom <<= 1; /* a zero bit */
}
else {
if (t0 > time_2250_us - (2*IR_MARGIN) && t0 < time_2250_us + (2*IR_MARGIN)) {
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) {
#ifdef IR_KEYCODE_TEST//TT010203
ir_custom = custom;
#else
if (custom != g_ir_system_code) {
// Noise from other remote ... ignore
ir_interrupt_set_edge(FALLING_EDGE);
state = IDLE;
valid_repeat = 0;
break;
}
#endif
state = DATA1;
time_count_old = time_count;
count = 0;
data1 = 0;
}
break;
case DATA1:
time_count_old = time_count;
count++;
if (t0 > time_1125_us - IR_MARGIN && t0 < time_1125_us + IR_MARGIN) {
data1 <<= 1; /* a zero bit */
}
else {
if (t0 > time_2250_us - (2*IR_MARGIN) && t0 < time_2250_us + (2*IR_MARGIN)) {
data1 = (data1 << 1) | 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:
time_count_old = time_count;
count++;
if (t0 > time_1125_us - IR_MARGIN && t0 < time_1125_us + IR_MARGIN) {
data2 <<= 1; /* a zero bit */
}
else {
if (t0 > time_2250_us - (2*IR_MARGIN) && t0 < time_2250_us + (2*IR_MARGIN)) {
data2 = (data2 << 1) | 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 & 0xff))
{ // Check if data is valid
key = (0x00FF&data1);
#ifdef IR_KEYCODE_TEST//TT010203
ir_command = key;
#endif
/* Removed by NirM 07-Mar-02: Replaced by the Exceptioning mechanism
// Emergency eject
#ifdef EMERGENCY_EJECT_ENABLED
if((key == IRKC_EJECT)
&&((gcs.mstate == MST_LOADING)||(gcs.mstate == MST_DISC_READY)))
{
gcs.bEmergencyEject = TRUE;
}
#endif
*/
#ifdef IR_NO_REPEAT_PULSE
if (((last_key&0x00FF) == key) && (ir_interval != 0)) { /* If a key was pushed continuously. */
}
else {
#endif
#ifndef IR_KEYCODE_TEST//TT010203
if( key == (BYTE)(0x00FF&g_ir_power_key_code) )
{
switch(g_power_state)
{
case POWER_SEQUENCE_IN_ON_STATE:
if(g_core_task_ready)
{
g_power_state = POWER_SEQUENCE_OFF_REQUESTED;
gcs.mstate = MST_POWER_DOWN;
}
break;
case POWER_SEQUENCE_OFF_REQUESTED:
#ifdef FAST_POWEROFF
g_power_state = POWER_SEQUENCE_ON_REQUESTED;
#endif
cpu_soft_reset();
break;
default:
g_power_state = POWER_SEQUENCE_ON_REQUESTED;
cpu_soft_reset();
break;
}
}
//TT20021209 add for invalid repeat key process
switch( key )
{
#ifdef IRKC_VOLUME_UP
case IRKC_VOLUME_UP:
#endif
#ifdef IRKC_VOLUME_DOWN
case IRKC_VOLUME_DOWN:
#endif
#ifdef IRKC_LEFT
case IRKC_LEFT:
#endif
#ifdef IRKC_PAUSE //yxm 0307
case IRKC_PAUSE:
#endif
#ifdef IRKC_RIGHT
case IRKC_RIGHT:
#endif
#ifdef IRKC_10P//D_10P_KEY
case IRKC_10P:
#endif
valid_repeat = 1;
break;
default:
valid_repeat = 0;
break;
/*
case IRKC_POWER:
case IRKC_EJECT:
case IRKC_FASTF:
case IRKC_FASTR:
valid_repeat = 0;
break;
default:
valid_repeat = 1;
break;*/
}
#endif //IR_KEYCODE_TEST//TT010203
send_remote_event( ((WORD)key)&0x00FF );
#ifdef IR_NO_REPEAT_PULSE
last_key = key;
ir_interval = IR_INTERVAL;
}
#endif
}
}
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -