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

📄 irapi1.c

📁 完整的红外线驱动程序,对电视行业的开发人员很有用
💻 C
📖 第 1 页 / 共 2 页
字号:
//=============================================================================
//  File Name: irapi1.c
//
//  (c)  Copyright 2001, 2002 Cirrus Logic, Inc.  All rights reserved.  
//
//  This source code is Cirrus Logic, Inc. proprietary and confidential information
//
//  Description:
//      Performs IR processing on RISC 1
//
//  Modification History:
//      25/04/01 Cirrus Logic - created
//
//=============================================================================

#include "apiconfig.h"
#include "config.h"
//#define DEBUG_MSG
#define DEBUG_CPU   3   // 0 = RISC 0, 1 = RISC 1, 2 = DSP, 3 = EXTRA
#include "eromdbg.h"

#include "chips.h"
#include "irkeys.h"
#if defined(USE_RISC1)
#include "sysclk1.h"    // system clock routines
#include "devint1.h"
#endif
#include "irapi1.h"     // ir api (this)
#include "plldriver.h"
#include "clasi_session.h"
#include "clasi_public.h"
#include "random.h"
#ifdef AUTOMATED_IR_TEST_COMBOER
#include "irtest.h"
#include "string.h"
#endif


//-----------------------------------------------------------------------------
//  Local definitions
//-----------------------------------------------------------------------------
#define TRACE(fmt, args...) 	//ERomPrintFunc(DEBUG_CPU,fmt, ## args)
#define TRACE_KEY(fmt, args...) //ERomPrintFunc(DEBUG_CPU,fmt, ## args)

#define VENDOR_OPTION		0
#define IRBUF_SIZE          300         // IR dram buffer size
#define NELEMENTS(a)        (sizeof(a) / sizeof(a[0]))

//
// IR define 
// 
#define IR_GLITCH_FILTER_ENABLE		1
#define IR_GLITCH_FILTER_MODE_NEG	0
#define IR_GLITCH_FILTER_MODE_POS	1
#define IR_TRIGGER_DISABLE			0
#define IR_TRIGGER_RISING_EDGE		1
#define IR_TRIGGER_FALLING_EDGE		2
#define IR_TRIGGER_BOTH_EDGE		3
#define IR_WRITE_COUNT_DISABLE		1
#define IR_INTERRUPT_DISABLE		1

#define IR_IN			0
#define KEY_IN			1

#define IR_TIME_COUNT (GetIRClock() / 1240)	// Based on Previous value for 98k
#define IR_GLITCH_COUNT (GetIRClock() / 10700)	// Based on previous value

//
// 	IR states
//
typedef enum {
	IRS_START,
	IRS_COMMAND,
	IRS_REPEAT
} IRStateType;


extern void sysClkInt1 (void);

//-----------------------------------------------------------------------------
//  Local variables
//-----------------------------------------------------------------------------

static Uint32       ir_buf[IRBUF_SIZE];
static Uint32       ir_rdptr            = 0;
static Uint32       ir_start_addr;
static Uint32       ir_end_addr;
static Uint8        shift_key_pressed  = 0;

static Uint16       ir_code             = IR_CUSTOMER_CODE;
static Uint16       ire_max             = 0x78;     
static Uint16       ire_repeat          = 0x78;
static Uint16       ire_cmd             = 0x11;
static Uint16       ire_cmd_adjust      = 0x01;
static Uint16       ire_data_one        = 0x02;
static Uint16       ire_data_adjust     = 0x01;
static Uint16       ir_repeat_time      = 0x05;

static Uint32       ir_data             = 0;
static Byte         ir_nbit             = 0;
static IRStateType  ir_state            = IRS_START;
static Uint8        ir_repeat_cnt       = 0;
static Uint32       ir_repeatKey;

static Uint32       CIRnFPCounter1      = 0;                

static Uint16       l_InputKey          = 0xFFFF;


//-----------------------------------------------------------------------------
//  Local Prototypes
//-----------------------------------------------------------------------------

static int chk_data_range (Uint32, Uint32, Uint32);
static int chk_range (Uint32, Uint32, Uint32);
static void irkey_filter (Uint32);
static Uint32 IRCheckState (void);
static void IR_SetEdgeMode (Uint32 edge_mode);
static void IR_SetTimeCount (Uint32 count);
static void IR_SetGlitch (Uint32 mode, Uint32 count);
#ifdef AUTOMATED_IR_TEST_COMBOER
static void IR_TraceKey(Uint16 key,Uint16 time,int i, Uint32 totaltime);
#define IR_STARTTEST_KEYNUM  4
static Uint16 startTestTmrCn = 0;
static Uint16 startTestArr[IR_STARTTEST_KEYNUM] = 
{
	IR_NUM1,
	IR_NUM3,
	IR_NUM5,
	IR_NUM7,
};
static Uint16 startTestFlag = 0;
static IRTimerTest_t*	testcase = NULL;
static Uint16 *			allkeyarr = NULL;
static Uint16			allkeyNum = 0;
static Uint16			intervalMin = 0;
static Uint16 			intervalMax = 0;
static Uint16			testKeyArrNum = 0;
#endif
#define AUTOMATED_IR_TEST 0
#define POWER_EJECT_TEST 0

#if AUTOMATED_IR_TEST
typedef enum
{
	AUTO_IR_EJECT_TEST = 1,
	AUTO_IR_EJECT_POWER_TEST = 2,
	AUTO_IR_TRICKMODE_TEST = 3,
	AUTO_IR_TRICKMODE_PASSTHRU_TEST = 4
} AUTO_IR_TEST_SUBCMD;

#endif
//-----------------------------------------------------------------------------
//  Function:
Boolean IR_GetKey (
//
//  Description:
//      
//  Parameters:
        Uint16 *keyPtr
)
//
//  Returns: 
//      
//
//-----------------------------------------------------------------------------
{
    if (0xFFFF != l_InputKey)
    {
		TRACE_KEY("IR_GetKey: l_InputKey = 0x%x\n",l_InputKey);
        if (NULL != keyPtr)
            *keyPtr = l_InputKey;
        l_InputKey = 0xFFFF;
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}


//-----------------------------------------------------------------------------
//  Function:
void IR_SetEdgeMode (
//
//  Description:
//      Set edge mode to rising, falling or both
//      
//  Parameters:
        Uint32 edge_mode
)
//
//  Returns: 
//      
//
//-----------------------------------------------------------------------------
{
    ls500reg(IR_CONTROL_REG) |= (edge_mode<<28) |
                                (IR_WRITE_COUNT_DISABLE<<30) |  
                                (IR_INTERRUPT_DISABLE << 31);
}


//-----------------------------------------------------------------------------
//  Function:
void IR_SetTimeCount (
//
//  Description:
//      Set time count, base counting uint for IR  
//      
//  Parameters:
        Uint32 count
)
//
//  Returns: 
//      
//
//-----------------------------------------------------------------------------
{
    ls500reg(IR_CONTROL_REG) |= count;
}


//-----------------------------------------------------------------------------
//  Function:
void IR_SetGlitch (
//
//  Description:
//      Enable filter, set giltch mode and count 
//      
//  Parameters:
        Uint32 mode, 
        Uint32 count
)
//
//  Returns: 
//      
//
//-----------------------------------------------------------------------------
{
    ls500reg(IR_GLITCH_MAX_REG) = (IR_GLITCH_FILTER_ENABLE << 20) | 
                                  (mode << 21) |    
                                  count;
}

unsigned dbg_timeout = 0;
extern Uint32 isaRomulator;
#ifdef AUTOMATED_IR_TEST_COMBOER
extern void IRTestSetDefault(void);
#endif
//-----------------------------------------------------------------------------
//  Function:
void IRInit1 (
//
//  Description:
//      Initialize the IR interface
//      
//  Parameters:
        void
)
//
//  Returns: 
//      
//
//-----------------------------------------------------------------------------
{
    Uint32 *ir_buf_ptr;

    TRACE("IR1 init\n");         

    l_InputKey = 0xFFFF;   // This should be a fifo 
    ir_buf_ptr = ir_buf;

    // IR reg init 
    ls500reg(IR_CONTROL_REG) = 0x0;                                 // disable IR 
    ls500reg(IR_DRAM_START_ADDRESS_REG) = (Uint32)ir_buf_ptr;       // Dram starting address
    ls500reg(IR_DRAM_END_ADDRESS_REG) = ((Uint32)ir_buf_ptr+(IRBUF_SIZE<<2))-4; // Dram ending address
    ir_rdptr = (Uint32)ir_buf_ptr;                                  // make read ptr = write ptr
    ir_rdptr &= 0x7FFFFFFF;
    ir_start_addr= ir_rdptr;
    ir_end_addr = (Uint32)ir_buf_ptr+(IRBUF_SIZE<<2); 
    ir_end_addr &= 0x7FFFFFFF; 

    IR_SetGlitch(IR_GLITCH_FILTER_MODE_NEG, IR_GLITCH_COUNT);
    IR_SetEdgeMode( IR_TRIGGER_FALLING_EDGE );
    IR_SetTimeCount(IR_TIME_COUNT);

#ifdef AUTOMATED_IR_TEST_COMBOER
	IRTestSetDefault();
	allkeyNum = IRTestGetTotalKeyNum();
	testKeyArrNum = IRTestGetTestKeyArrNum();
	intervalMin = IRTestGetIntervalMin();
	intervalMax = IRTestGetIntervalMax();
	allkeyarr = IRTestGetAllKeyArray();
	testcase = IRTestGetCase();
	srand(((Uint32)IRtimerHandler1 + tickGet()) );
	dbg_timeout  = 400/9;
#else
#if AUTOMATED_IR_TEST

	srand(((Uint32)IRtimerHandler1 + tickGet()) );
#if POWER_EJECT_TEST
	*(unsigned *)0xb0000028 = 0xdeadbeef;
	*(unsigned *)0xb000002c = AUTO_IR_EJECT_POWER_TEST ;

	isaRomulator = 1; // without this you won't get prints if you use rmlvio.
	dbg_timeout  = 400/9;
#endif

#endif

#endif
#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 */
#endif    
    
}




#ifdef AUTOMATED_IR_TEST_COMBOER

void IRtimerHandler1(
//
//  Description:
//      
//  Parameters:
        void
)
//
//  Returns: 
//      
//
//-----------------------------------------------------------------------------
{

	int i=-1;
	Uint32	rand_val;
	Uint16	startpoint=0;

    CIRnFPCounter1++;

    if (CIRnFPCounter1 >= 9)
    {
        CIRnFPCounter1 = 0;
		if (ls500reg(0x28) == 0xdeadbeef)
		{
			// automated testing mode
			if (dbg_timeout)
				dbg_timeout--;
			if (!dbg_timeout)
			{
				if (testcase == NULL)
				{
					ERomPrintFunc(0,"Get the wrong testcase and allkeyarr pointer,testcase=0x%x\n",testcase);
					*(unsigned *)0xb0000028 = 0x0;
					return;
				}
		
				ERomPrintFunc(0,"lastexecutekey=%d \n",testcase->lastexecutekey);
				if (testcase->lastexecutekey == testKeyArrNum)
				{
					ERomPrintFunc(0,"run to %d line\n",__LINE__);
					startpoint = 0;
					
				}
				else
				{
					ERomPrintFunc(0,"run to %d line\n",__LINE__);
					startpoint = testcase->nextkeyitem[testcase->lastexecutekey];
				}
				i = startpoint;
				if (i==0 || i==17)
					ERomPrintFunc(0,"nextkeyitem[17]=%d\n", testcase->nextkeyitem[17]);
					
				ERomPrintFunc(0,"i=%d\n",i);
				switch (testcase->keymode)
				{
					case IR_Auto_Mode:
						if (allkeyarr == NULL)
						{
							ERomPrintFunc(0,"Get the wrong key array, allkeyarr=%x\n",allkeyarr);
							*(unsigned *)0xb0000028 = 0x0;
							break;
						}
						rand_val = rand();
						rand_val = (rand_val & 0x00ffff00) >> 8;
						testcase->keyArray[i] = allkeyarr[rand_val%allkeyNum];//gennerate a key
						l_InputKey = testcase->keyArray[i];
						break;
					case IR_Fix_Mode:
						if ((testcase->keyArray[i] == 0)||(testcase->keyRepeatTimes[i] == 0))
						{
	
							testcase->runtimes--;
							if (testcase->runtimes>0)
							{
								ERomPrintFunc(0,"RefCreatCase\n");
								testcase->RefCreatCase();

							}
							else
							{
								
								ERomPrintFunc(0, "***Test finished.** \n");
								l_InputKey = 0xFFFF;
								*(unsigned *)0xb0000028 = 0x0;
							}
							l_InputKey=0xffff;
							ERomPrintFunc(0,"run to %d line\n",__LINE__);
							break;
						}
						l_InputKey = testcase->keyArray[i];
						ERomPrintFunc(0,"run to %d line\n",__LINE__);
						if ((testcase->nextkeyitem[i] <= i) && (testcase->keyRepeatTimes[i] ==1))
						{
							testcase->nextkeyitem [i] = (i+1)%testKeyArrNum;
							ERomPrintFunc(0,"run to %d line\n",__LINE__);
						}
						break;
					case IR_FixAuto_Mode:
						l_InputKey = testcase->keyArray[i];
						if ((testcase->nextkeyitem[i] <= i) && (testcase->keyRepeatTimes[i] ==1))
						{
							testcase->nextkeyitem [i] = i+1;
						}
						if(testcase->keyArray[testcase->nextkeyitem[i]]==0)
						{
							testcase->keymode = IR_Auto_Mode;
						}
						break;
					default:
						break;
				}//switch(IRTestCase.intervalmode)
				if (l_InputKey != 0xFFFF)
				{
					ERomPrintFunc(0,"run to %d line\n",__LINE__);
					if (testcase->lastexecutekey == testKeyArrNum)
					{
						testcase->testTotalTime = 0;
					}
					else 
					{
						testcase->testTotalTime += testcase->keyInterval[testcase->lastexecutekey];
					}

					testcase->lastexecutekey = i;
					ERomPrintFunc(0,"run to %d line\n",__LINE__);
					switch (testcase->intervalmode)
					{
						case IR_Auto_Mode:
							rand_val = rand();
							rand_val = (rand_val & 0xffffff00) >> 8;
							testcase->keyInterval[i] = intervalMin+(rand_val%(intervalMax-intervalMin)); 
							dbg_timeout = testcase->keyInterval[i]*7;
							break;
						case IR_Fix_Mode:
							dbg_timeout = testcase->keyInterval[i]*7;
							break;
						case IR_FixAuto_Mode:
							if(testcase->keyInterval[i] < 0)
							{
								rand_val = rand();
								testcase->keyInterval[i] = intervalMin+(rand_val%(intervalMax-intervalMin)); 
								dbg_timeout = testcase->keyInterval[i]*7;
								testcase->intervalmode = IR_Auto_Mode;
							}
							else
							{
								dbg_timeout = testcase->keyInterval[i]*7;
							}
							break;
						default:
							break;
					}//end of switch 
					ERomPrintFunc(0,"run to %d line\n",__LINE__);

				}//end of if
			}
			else
			{
				l_InputKey = 0xFFFF;
			}
		}
		else
		{
			while (ir_rdptr != ls500reg(IR_DRAM_WRITE_ADDRESS_REG)) 
		       {
		       	IRCheckState ();
				ir_rdptr += 4;
			      	if (ir_rdptr >= ir_end_addr) 
			      	{
			      		ir_rdptr = ir_start_addr ;
			      	}
			}	
			if (0xFFFF != l_InputKey)
		       {
		       	if (l_InputKey == startTestArr[startTestFlag])
				{
					startTestFlag ++;
					if(startTestFlag == IR_STARTTEST_KEYNUM)
					{
						*(unsigned *)0xb0000028 = 0xdeadbeef;//start to auto test
						ERomPrintFunc(0, "***Start the test*** \n");
					}
				}
			}
			else
			{
				if (++startTestTmrCn > 7)
				{
					startTestTmrCn = 0;
					startTestFlag = 0;
				}
			}
    	}

		if (0xFFFF != l_InputKey)
		{
			TRACE_KEY("IR_GetKey: l_InputKey = 0x%x\n",l_InputKey);
			if (testcase!= NULL)
			{
				IR_TraceKey(l_InputKey, testcase->keyInterval[i],  i, testcase->testTotalTime);
			}
			SendIRMessageToIPQueue(l_InputKey );
			testcase->keyRepeatTimes[i]--;
			
			l_InputKey = 0xFFFF;
		}
		
    }  
    return;
}

#else 
#if AUTOMATED_IR_TEST

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

    CIRnFPCounter1++;
    if (CIRnFPCounter1 >= 9)
    {
        CIRnFPCounter1 = 0;
		if (ls500reg(0x28) == 0xdeadbeef)
		{
			// automated testing mode
			if (dbg_timeout)
				dbg_timeout--;
			if (!dbg_timeout)
			{
				Uint32 rand_val = rand();
				Uint16 key_gen  = (rand_val & 0xffff0000) >> 16;
				switch(ls500reg(0x2c))
				{
				case AUTO_IR_EJECT_TEST:
					// eject testing..
					l_InputKey = IR_EJECT;
					break;
				case AUTO_IR_EJECT_POWER_TEST: 
					// eject and powerdown testing
					if (key_gen % 2)
					{

⌨️ 快捷键说明

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