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

📄 irapi1.c

📁 完整的红外线驱动程序,对电视行业的开发人员很有用
💻 C
字号:
//============================================================================
//  File Name: irapi1.c
//
//  (c) Copyright [2003] Cirrus Logic Inc. All rights reserved
//
//  This source code is Cirrus Logic, Inc. proprietary and confidential information
//
//  Description:
//		Interface driver for the io micro-controller IR function. This driver uses iomicom & UART driver to  
//  communicate with the io micro-controller chip.
//
//  Please refer to the io micom driver for detail:
//
//  Modification History:
//      $Log: irapi1.c,v $
//      Revision 1.6  2005/04/29 10:21:51  michaell
//      merge 2.6 into head
//
//      Revision 1.1.1.1  2005/03/07 08:07:02  dchien
//      Import Sonata2_2-6-3
//
//      Revision 1.6  2004/07/06 18:33:36  jackchang
//      Added io micom IR driver
//
//
//
//============================================================================

#include "chips.h"
#include "irkeys.h"
#define DEBUG_CPU   1  // 0 = RISC 0, 1 = RISC 1, 2 = DSP, 3 = EXTRA
#include "eromdbg.h"
#include "clasi_public.h"
#if defined(USE_RISC1)
#include "sysclk1.h"    // system clock routines
#include "devint1.h"
#else
#include "osapi.h"
#endif
#include "assert.h"
#include "iodriver.h"
#include "irapi1.h"     // ir api (this)


#if defined(USE_RISC1)
#define OS_TICK_GET()               tick1Get()
#else
#define OS_TICK_GET()               OS_TickGet()
#endif

#define TRACE_KEY(fmt, args...)     ERomPrintFunc(DEBUG_CPU,fmt, ## args)


#define	KEY_STATUS_CHECK_PRESS				0
#define	KEY_STATUS_CHECK_RELEASE			1

#define IR_SREC_TEST                        FALSE

static Boolean      irkey_filter (Uint8);

static Uint32		gMaxRepeatTickCount2nd, gMaxRepeatTickCount1st;
static Uint32		gMaxSkipScanTick1st, gMaxSkipScanTick2nd;
static Uint32		gMaxRepeat_UPDownTickCount1st, gMaxRepeat_UPDownTickCount2nd;
static Uint32		gMaxRepeat_Stop5Sec_TickCount1st, gMaxRepeat_Stop5Sec_TickCount2nd;
static Uint32		gMaxRepeat_DisplayKey_TickCount1st, gMaxRepeat_DisplayKey_TickCount2nd;
static Uint32		gMaxRepeat_CHUPDownTickCount1st, gMaxRepeat_CHUPDownTickCount2nd;


#if IR_SREC_TEST
void IR_Testing(void);
#endif

//-----------------------------------------------------------------------------
//  Function:
void IRInit1 (
//
//  Description:
//      Initialize the IR interface
//      
//  Parameters:
        void
)
//
//  Returns: 
//      
//
//-----------------------------------------------------------------------------
{
    int OS_NUM_TICKS_PER_100ms;
    
#if defined(USE_RISC1)
	//-------------------------------------
	// Initialize Risc1 master interrupt handler
	//-------------------------------------
	DevIntInit1();

	DevIntInstallHandler1 (INT_TIMER_1, (InterruptProc_t)sysClkInt1 , NULL);
	DevIntEnable1(INT_TIMER_1,0,LEVEL);
//    sysClkConnect1 ((ClockFuncType) IRtimerHandler1, 0);   /* connect clock ISR */
//    sysClkEnable1 ();               /* start it */

    OS_NUM_TICKS_PER_100ms = 6;
#else
    OS_NUM_TICKS_PER_100ms = OS_TickRate() / 10;
#endif    
	gMaxRepeatTickCount1st = OS_NUM_TICKS_PER_100ms * 5*2;    // 1/2 sec (OS_TickRate returns ticks_per_second.  zq change for #9018
	gMaxRepeatTickCount2nd = OS_NUM_TICKS_PER_100ms * 10/2;    // 1 Tick = 16.67ms, 200ms = 12 Tick, 350ms = 21, 500ms = 30
	gMaxSkipScanTick1st = 30;
	gMaxSkipScanTick2nd = 60;
	gMaxRepeat_UPDownTickCount1st = 30;
	gMaxRepeat_UPDownTickCount2nd = 6;
	gMaxRepeat_CHUPDownTickCount1st = 30;
	gMaxRepeat_CHUPDownTickCount2nd = 6;
	gMaxRepeat_Stop5Sec_TickCount1st = 300; //5 sec.
	gMaxRepeat_Stop5Sec_TickCount2nd = 300; //5 sec.
	gMaxRepeat_DisplayKey_TickCount1st = 300; //5 sec.
	gMaxRepeat_DisplayKey_TickCount2nd = 300; //5 sec.
}

//extern volatile Uint8 gCurrentChannel;
//extern volatile Uint8 gSearchedChNum;
extern Uint8 gInputSource_TV;
extern void io_key_send(Uint8 key);
extern Uint8 upDown_ChannelKey;
//-----------------------------------------------------------------------------
//  Function:
Boolean IR_GetKey (
//
//  Description:
//
//  Parameters:
        Uint16 *keyPtr
)
//
//  Returns:
//
//
//-----------------------------------------------------------------------------
{
    static Uint8    preKey = kNULL_KEY;
	static volatile unsigned char	keyStatus = KEY_STATUS_CHECK_PRESS;
	static volatile unsigned char 	is1stRepeat = FALSE;
	static Uint32	oldTick;
	static Uint8	LongKeyActive = FALSE;	//zq add for #9018
	static Uint8	inputSourceActive = FALSE;

    Uint8           inputKey;
    Boolean         status = FALSE, bGlobalKeyReady;
	Uint32  		newTick, MaxTickWait = 6000;
	static Uint32	diffTick = 0;

    soft_assert((NULL != keyPtr));

	bGlobalKeyReady = io_key_get(&inputKey);

	if ( !bGlobalKeyReady )
		return FALSE;

	switch ( keyStatus )
	{
		case KEY_STATUS_CHECK_PRESS:
			if ( inputKey == kNULL_KEY )
			{
				LongKeyActive = FALSE;     //zq add for #9018
				status = FALSE;
				preKey = inputKey;
			}
			else
			{
				keyStatus = KEY_STATUS_CHECK_RELEASE;
				if(((inputKey == IR_UP || inputKey == IR_DOWN)) || 
					(inputKey == IR_DISPLAY) || 
					(inputKey == IR_CH_UP) || (inputKey == IR_CH_DOWN))
				{
				    *keyPtr = kNULL_KEY;				
    				status = FALSE;
				}
				else
				{
	                *keyPtr = inputKey;
    				status = TRUE;
				}
				
				preKey = inputKey;
				oldTick = OS_TICK_GET();

				is1stRepeat = TRUE;
				//TRACE_KEY("0 inputKey is 0x%x, status = %d\n", *keyPtr, status);
			}
			break;
			
		case KEY_STATUS_CHECK_RELEASE:
			if ((inputKey == kNULL_KEY) && !diffTick)
			{
				//SYS_P2("input Key is null ! at release case \n");
				keyStatus = KEY_STATUS_CHECK_PRESS;
				preKey = inputKey;
				status = FALSE;
			}
			else
			{
				if(preKey == inputKey)
				{
					if(irkey_filter(inputKey))
					{
						newTick = OS_TICK_GET();
						diffTick = (newTick >= oldTick ) ? newTick - oldTick : oldTick - newTick;
						if((inputKey == FRONT_IR_PREV) || (inputKey == FRONT_IR_NEXT))
						{
							MaxTickWait = is1stRepeat ? gMaxSkipScanTick1st : gMaxSkipScanTick2nd;
						}
						else if((inputKey == IR_CH_UP) || (inputKey == IR_CH_DOWN)) //speed up of channel up/down at Tuner mode
						{
							MaxTickWait = is1stRepeat ? gMaxRepeat_CHUPDownTickCount1st : gMaxRepeat_CHUPDownTickCount2nd;
						}
						else if(inputKey == IR_CLEAR)
						{
							MaxTickWait = is1stRepeat ? gMaxRepeat_UPDownTickCount1st : gMaxRepeat_UPDownTickCount2nd;
						}
						else if(inputKey == IR_DISPLAY)
						{
							MaxTickWait = is1stRepeat ? gMaxRepeat_DisplayKey_TickCount1st : gMaxRepeat_DisplayKey_TickCount2nd;
						}
						else if(inputKey == IR_STOP)
						{
							MaxTickWait = is1stRepeat ? gMaxRepeat_Stop5Sec_TickCount1st : gMaxRepeat_Stop5Sec_TickCount2nd;
						}
						else if((inputKey != IR_DISPLAY) && (inputKey != IR_STOP))
						{
							MaxTickWait = is1stRepeat ? gMaxRepeatTickCount1st : gMaxRepeatTickCount2nd;
						}

						if(diffTick >= MaxTickWait)
						{
							TRACE_KEY("scan diff tickTime = %d, MaxTickWait = %d\n", diffTick, MaxTickWait);
							diffTick = 0;
							//Repeatable key
							oldTick = OS_TICK_GET();
							if(((inputKey == IR_CH_UP) || (inputKey == IR_CH_DOWN))) //speed up of channel up/down at Tuner mode
							{
								if(inputKey == IR_CH_UP) 
								{
									LongKeyActive = TRUE;
									inputKey = IR_CH_UP;
								}
								else if(inputKey == IR_CH_DOWN) 
								{
									LongKeyActive = TRUE;										
									inputKey = IR_CH_DOWN;
								}
							}
							else
							{
								if(inputKey == IR_CLEAR)
								{
									LongKeyActive = TRUE;
									inputKey = IR_CLEAR;
								}
								//zq add for #9018
								else if((inputKey == IR_UP))
								{
									LongKeyActive = TRUE;
									inputKey = IR_UP;
								}
								else if((inputKey == IR_DOWN))
								{
									LongKeyActive = TRUE;										
									inputKey = IR_DOWN;
								}
								//zq add end
							}
							if(inputKey == FRONT_IR_NEXT)
							{
								LongKeyActive = TRUE;
								inputKey = IR_FF;
								TRACE_KEY("inputKey is foward scan key, 0x%x\n", inputKey); 
							}
							else if(inputKey == FRONT_IR_PREV)
							{
								LongKeyActive = TRUE;
								inputKey = IR_FR;
								TRACE_KEY("inputKey is backward scan key, 0x%x\n", inputKey); 
							}

							*keyPtr = inputKey;

							if(inputKey == IR_SOURCE && inputSourceActive) //LG_jmk temp FIXIT
							{
								keyStatus = KEY_STATUS_CHECK_PRESS;
								status = FALSE;
								preKey = kNULL_KEY;
							}
							else
							{
								status = TRUE;
							}
							is1stRepeat = FALSE;
						}
						else
						{
							status = FALSE;//No repeatable key
						}
					}
					else
					{
						//TRACE_KEY("2.1inputKey is 0x%x\n", inputKey); 
						status = FALSE;
					}
				}
				else
				{
					//TRACE_KEY("else is executed !!!!!!!!!!!\n");
					//I'm processing this as a new key input but this should not happen.
					//State to KEY_STATUS_CHECK_RELEASE should start from KEY_STATUS_CHECK_PRESS
					//preKey = kNULL_KEY;
					status = FALSE;
					keyStatus = KEY_STATUS_CHECK_PRESS;
				}
			}
			
    		if( diffTick && inputKey == kNULL_KEY )// && !inputSourceActive) //LG_jmk
    		{
				if((!LongKeyActive )) 
				{
					switch(preKey)
					{
						case FRONT_IR_NEXT:
		    			{	
		    				diffTick = 0;
		    				*keyPtr = IR_NEXT;
		    				status = TRUE;
		    				break;
						}
						case FRONT_IR_PREV:
						{
		    				diffTick = 0;
		    				*keyPtr = IR_PREV;
		    				status = TRUE;
		    				break;
		    			}
						case IR_DISPLAY:
						{
		    				diffTick = 0;
		    				*keyPtr = IR_DISPLAY;
		    				status = TRUE;
		    				break;
		    			}
						/*case IR_STOP:
						{
		    				diffTick = 0;
		    				*keyPtr = IR_STOP;
		    				status = TRUE;
		    				break;
		    			}*/
						//zq add for 9018		    			
						case IR_CH_UP: 
						{
							diffTick = 0;
		    				*keyPtr = IR_CH_UP;
		    				status = TRUE;
							break;
						}
						case IR_CH_DOWN:
		    			{	
							diffTick = 0;
	    					*keyPtr = IR_CH_DOWN;
							status = TRUE;
							break;
						}
						case IR_UP: 
						{
							diffTick = 0;
		    				*keyPtr = IR_UP;
		    				status = TRUE;
							break;
						}
						case IR_DOWN:
		    			{	
							diffTick = 0;
	    					*keyPtr = IR_DOWN;
							status = TRUE;
							break;
						}
						//zq add end						
						default:
						{
		    				status = FALSE;
							break;
						}
					}
				}

    			preKey = kNULL_KEY;
    			keyStatus = KEY_STATUS_CHECK_PRESS;
				//TRACE_KEY("1 inputKey is 0x%x, status = %d\n", *keyPtr, status);
    		}
    		else// LG_jmk temp FIXIT
    			inputSourceActive = FALSE;
    			
			//TRACE_KEY("2 inputKey is 0x%x, status = %d\n", *keyPtr, status);
			break;
			
		default:
			TRACE_KEY("*** keyStatus is invalid state\n");
			break;
	}

#if IR_SREC_TEST
	if ((status == TRUE) && (*keyPtr == 0xbd))
	{
	    IR_Testing();
	}
#endif
	//TRACE_KEY("3 inputKey is 0x%x, status = %d\n", *keyPtr, status);
    return status;
}

//-----------------------------------------------------------------------------
//  Function:
void IRtimerHandler1(
//
//  Description:
//      
//  Parameters:
        void
)
//
//  Returns: 
//      
//
//-----------------------------------------------------------------------------
{
	Uint16 inputKey;

	if ( IR_GetKey (&inputKey) )
    {
		TRACE_KEY("IR_GetKey: 0x%x\n",inputKey);
		SendIRMessageToIPQueue(inputKey );
    }
}

//-----------------------------------------------------------------------------
//  Function:
static Boolean irkey_filter (
//
//  Description:
//      filter repeat key will take effect ??
//      
//  Parameters:
        Uint8 repeatKey
)
//
//  Returns: 
//      TRUE - this key should be repeat
//      FALSE - discard this key
//
//-----------------------------------------------------------------------------
{
    switch (repeatKey) 
    {
    case IR_STEP:
    case IR_VOL_UP:
    case IR_VOL_DOWN:
    case IR_UP:
    case IR_DOWN:
    case IR_CH_UP:
    case IR_CH_DOWN:
	case IR_CLEAR:
	case IR_DISPLAY:
	case IR_STOP:
    case FRONT_IR_NEXT:
    case FRONT_IR_PREV:
    /*
    //LG_jmk 20031119 fixed 
    case IR_SOURCE://LG_jmk FIXIT temp for DVD/input source switching
    //LG_jmk case IR_CH_UP:
    //LG_jmk case IR_CH_DOWN:*/
        return TRUE;   // This should be a fifo   
        break;
    default:
        return FALSE;
        break;
    }
}

#if IR_SREC_TEST
// testing only
void IR_Testing(void)
{
    io_rtc_type     rtcTime;
#ifdef LG_IO_PAL	// LJC_LG 0315
    iopal_srec_type    srec;
#else
    io_srec_type    srec;
#endif
    
    io_rtc_get(&rtcTime);

    srec.type = IO_RECORD_1TIME;
    srec.speed = IO_RECORD_SQ;
    srec.month = bcd2hex(rtcTime.month);
    srec.weekDay = rtcTime.weekDay;
    srec.startDate = bcd2hex(rtcTime.date);
    srec.startHour = bcd2hex(rtcTime.hour);
    srec.startMinute = bcd2hex(rtcTime.minute);
    
    TRACE_KEY("%0d %0d, %4d, %2d:%02d:%02d, week: %d\n", srec.month, srec.startDate, rtcTime.year+2000,
              srec.startHour, srec.startMinute, bcd2hex(rtcTime.second), rtcTime.weekDay);

    srec.startMinute++;
    if (srec.startMinute > 60)
    {
        srec.startMinute -= 60;
        srec.startHour++;
        // check the hour here
    }
    srec.endMinute = srec.startMinute + 1;
    if (srec.endMinute > 60)
    {
        srec.endMinute -= 60;
        srec.endHour = srec.startHour + 1;
        // check the hour here
    }else{
        srec.endHour = srec.startHour;
    }
    srec.channelNo = 2;
    srec.inputSource = IO_INPUT_TUNER;
    
    io_record_info_set(1, &srec);
}
#endif

⌨️ 快捷键说明

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