⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nec_ir.c

📁 Zoran V966 DVD 解码 Soc芯片的源程序
💻 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: 17 $
 * Last Modified by $Author: Rinata $ at $Modtime: 3/11/04 5:06p $ 
 ****************************************************************************************
 * Updates:
 ****************************************************************************************
 * $Log: /I76/I76_Common/I76_Reference/Remote/nec_ir/nec_ir.c $
 * 
 * 17    3/11/04 5:45p Rinata
 * cpu check remote signal after v8 wake it up when remote signal was
 * changed
 * 
 * 16    03-08-01 11:57 Wesleyj
 * remove video_mode_detect 
 * 
 * 15    7/09/03 6:05p Mikex
 * cancel transfer cpu_soft_reset() function on second standby key
 * pressed. The cpu_soft_reset() function will be transfered by core task.
 * 
 * 14    03-07-07 16:14 Ivany
 * Added a mapping table and condition for the keys which repeat-pressed
 * message should not be sent when is pressed.
 * 
 * 13    03-06-19 17:08 Wesleyj
 * add video_mode_detect charge  (Av in stat)
 * 
 * 12    03-06-17 18:28 Admin
 * Merge for ExinoII project
 * 
 * 11    03-05-19 18:54 Kennyz
 * Clear code.
 * 
 * 10    2/02/03 6:22p Lyncolnc
 * Added LONG_REPEAT_DELAY.
 * 
 * 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 "Playcore\Coremain\coremain.h"
#include "Playcore\Coremain\coredefs.h"
#include "Playcore\Coremain\coregdef.h"
#include "Devices\Remote\ir_api.h"
#include "Devices\Remote\ir_ll.h"
#include "UI_Manager\UI_Input\ui_input_ir.h"
#ifdef D_HOLD_SKIP_2S_AS_FAST_SCAN
#include "Kernel\Timers\Timers.h"
#endif
#ifdef I96_CPU_POWER_DOWN
#include "Dec_Power.h"
#endif


#ifdef  D_HOLD_STOP_3S_AS_EJECT_KEY		
#define IRKC_NULL		0xFF   
#define STOPKEY_DELAY	0x20   
#endif


#ifdef D_HOLD_SKIP_2S_AS_FAST_SCAN
//the time of 2 seconds for hold the skip key
#define SKIPKEY_DELAY  0x10 //counter value for about 2 seconds
//the time slice between two repeated skip key
#define HOLDSKIP_TIMEOUT_TIME 120 //millisecond

//the handler of the timer
static UINT8   hHoldSkipTimer = 0;
//used to remember we pressed skipf or skipr
static BYTE	lastSkipKey = 0xFF;
#endif //D_HOLD_SKIP_2S_AS_FAST_SCAN

extern CONST WORD g_ir_system_code;
extern CONST WORD g_ir_power_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

#ifdef I96_CPU_POWER_DOWN
extern BOOL bPowerUpKeyPressed;
extern BOOL bWakeFromPowerDown;
#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
#ifdef LONG_REPEAT_DELAY
  #define REPEAT_DELAY 25
#else
  #define REPEAT_DELAY	5
#endif //LONG_REPEAT_DELAY

#ifdef	IR_NO_REPEAT_PULSE
	#define IR_INTERVAL		240/20
	BYTE	last_key = 0;
	BYTE	ir_interval = 0;
#endif
//<<<YY_ZCH 
#define	MAX_NO_REPEAT_PULSE_KEY_NUM            1
#define	IR_ENTER      0x73

CONST BYTE mkey_no_repeat_pluse[MAX_NO_REPEAT_PULSE_KEY_NUM]=
{
	IR_ENTER
};

#ifdef D_HOLD_SKIP_2S_AS_FAST_SCAN
/**********************************************************************************
 * Name			:	HoldSkipTimerIR
 * Purpose		:	The timeout function for hold skip key, when timeout happens, it will send out
 *                                the skip key user pressed.
 * Input			:   
 * Return Value	:
 * Description		:
 * Comments		:
**********************************************************************************/
#pragma argsused
static void HoldSkipTimerIR(UINT8 hTimer)
{
	send_remote_event((WORD)KEY_SOURCE_IR|lastSkipKey);
	timer_service_delete(hHoldSkipTimer);
}
#endif //D_HOLD_SKIP_2S_AS_FAST_SCAN

BOOL ir_need_no_repeat_pulse(BYTE uKey)
{
	int i;
	for(i=0;i < MAX_NO_REPEAT_PULSE_KEY_NUM;i++)
	{
		if(uKey == mkey_no_repeat_pluse[i])
			return TRUE;
	}
	//if(i == MAX_NO_REPEAT_PULSE_KEY_NUM)
	return FALSE;
}

//>>>YY_ZCH
static unsigned long time_count_old;

void ir_init(void)
{
	ir_interrupt_init( FALLING_EDGE );
	time_count_old = cpu_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;

#ifdef  D_HOLD_STOP_3S_AS_EJECT_KEY		
	static BYTE		lastkey = IRKC_NULL;
	static BYTE		stopkey_repeatDelay = REPEAT_DELAY;
#endif

#ifdef D_HOLD_SKIP_2S_AS_FAST_SCAN
	// 2 seconds timeout counter
	static BYTE		skipkey_repeatDealy = REPEAT_DELAY;
#endif

	unsigned long time_count, t0;	

#ifdef I96_CPU_POWER_DOWN
    if (bWakeFromPowerDown == TRUE)
    {
        DEC_PowerCpu(TRUE);       
    }
#endif

	time_count = cpu_gen_timer();	
	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)) {
#ifdef   D_HOLD_STOP_3S_AS_EJECT_KEY
				if(key == IRKC_STOP)
				{
					if(stopkey_repeatDelay)
						stopkey_repeatDelay--;
					else
					{
						if(lastkey != IRKC_EJECT)
						{
							send_remote_event((WORD)IRKC_EJECT&0x00FF);
							lastkey = IRKC_EJECT;         // Eject only once
							//lastkey = IRKC_STOP;      // Eject at STOPKEY_DELAY interval
							stopkey_repeatDelay = STOPKEY_DELAY;
						}     
					}
				}
				else
#endif //D_HOLD_STOP_3S_AS_EJECT_KEY
#ifdef D_HOLD_SKIP_2S_AS_FAST_SCAN
				if(IRKC_SKIPB == key || IRKC_SKIPF == key)
				{
					//reset the timer
					timer_service_enable(hHoldSkipTimer, TRUE);
					if(skipkey_repeatDealy)
					{
						skipkey_repeatDealy--;
					}
					else
					{
						//clear the timer
						timer_service_delete(hHoldSkipTimer);
						//translate the skip key to "hold" scan key
						if(IRKC_SKIPF == key)
						{
							send_remote_event((WORD)KEY_STATUS_HOLD|KEY_SOURCE_IR|IRKC_FASTF);
						}
						else
						{
							send_remote_event((WORD)KEY_STATUS_HOLD|KEY_SOURCE_IR|IRKC_FASTR);
						}							
					}
				}
				else
#endif //D_HOLD_SKIP_2S_AS_FAST_SCAN
				if (repeat_delay) {
					// Delay before sendnig the first repeat
					repeat_delay--;
				}
				else { // repeat last key
					if (valid_repeat) {//<<<YY_ZCH
						if(!ir_need_no_repeat_pulse(key))//>>>YY_ZCH 
						send_remote_event( (KEY_STATUS_HOLD|KEY_SOURCE_IR)|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) {
			if (custom != g_ir_system_code) {
				// Noise from other remote ... ignore
				ir_interrupt_set_edge(FALLING_EDGE);
				state = IDLE;
				valid_repeat = 0;
				break;
			}
			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);

/* 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

					valid_repeat = 1;  //allow key repeat  
#ifdef D_HOLD_STOP_3S_AS_EJECT_KEY
					if(key == IRKC_STOP)
					{
						stopkey_repeatDelay = STOPKEY_DELAY;
						lastkey = IRKC_NULL;
					}       
#endif //D_HOLD_STOP_3S_AS_EJECT_KEY

#ifdef D_HOLD_SKIP_2S_AS_FAST_SCAN
					if(IRKC_SKIPF == key || IRKC_SKIPB == key)
					{
						lastSkipKey = key;
						skipkey_repeatDealy = SKIPKEY_DELAY;
						hHoldSkipTimer = timer_service_create(HoldSkipTimerIR, HOLDSKIP_TIMEOUT_TIME, TIMER_ONCE |TIMER_DISABLED);
						timer_service_enable(hHoldSkipTimer, TRUE);	
						//when press the skip key or press down the skip key first,
						//we just ignore it here. It will be sent out when "holdkey" timeout happens.
						break;
					}

#endif //D_HOLD_SKIP_2S_AS_FAST_SCAN

					if (key == (BYTE)(0x00FF&g_ir_power_key_code))	
					{ 
						switch(g_power_state)
						{
							case POWER_SEQUENCE_IN_ON_STATE:
								g_power_state = POWER_SEQUENCE_OFF_REQUESTED;
								break;

							case POWER_SEQUENCE_IN_OFF_STATE:
								g_power_state = POWER_SEQUENCE_ON_REQUESTED;
								break;

							case POWER_SEQUENCE_OFF_REQUESTED:
								g_power_state = POWER_SEQUENCE_ON_REQUESTED;
							//03-07-09	cpu_soft_reset();
						}
					}
#ifdef I96_CPU_POWER_DOWN
					if(	key == (BYTE)g_ir_power_key_code )
					{
						bPowerUpKeyPressed = TRUE;
					}
#endif
					send_remote_event(KEY_SOURCE_IR|key);



#ifdef	IR_NO_REPEAT_PULSE
					last_key = key;
					ir_interval = IR_INTERVAL;
				}
#endif
			}
		}
		break;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -