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

📄 nec_ir.c

📁 NEC格式遥控接收代码:NEC IR implementation
💻 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 + -