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

📄 irstate.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
字号:
#include "fip_private.h"#include "fip.h"#include "irstate.h"// define DEBUG_REMOTE to be the scan code we want to check//#define DEBUG_REMOTE	0x00ffb847#ifndef FIP_NO_INTERRUPT/* for debugging */#ifdef DEBUG_REMOTEunsigned long tt[32];#endifstatic IR_STATE ir_state;int ir_pio(){	return ir_state_machine(&ir_state);}// 9281 is the default/original timer scale, so that TS(x) = x in the default case#define TS(x) (x*ir_state->timer_scale/9281)int ir_state_machine (IR_STATE *ir_state){	int t1, t;#ifdef VERBOSE	DPRINTF("in ir_state_machine state=%d\n", ir_state->state);#endifnext_state:	switch (ir_state->state)	{	// PIO 1 is high, we can proceed to state 2 only when PIO 1 goes low	case IR_STATE_WAIT_FOR_COMMAND_START:		// since the falling edge interrupt was signalled, we must be		// already at state 2, so just fall through!			// PIO 1 is low, save the time (t0) at this moment and go to state 3	case IR_STATE_COMMAND_START:		ir_state->t0 = *(TIMER0_VAL_REG);		ir_state->state = IR_STATE_COMMAND;		// fall through!	// PIO 1 is low, we can proceed to state 4 only when PIO 1 goes high	case IR_STATE_COMMAND:		// setup the PIO 1 interrupt to trigger on the next rising edge		// and set the state to be the next state - the next time we		// come here we will be at the next state		*(PIO_0_POL_REG) = (0x00010000 << 1);		ir_state->state = IR_STATE_COMMAND_END;		break; 	// PIO 1 is high, current time = t1, if (t1-t0) < 8ms go back to	// state 1, else proceed to state 5	case IR_STATE_COMMAND_END:		t1 = *(TIMER0_VAL_REG);		t = ir_state->t0 - t1;		if (t < 0)			t = ir_state->t0 + (ir_state->timer_load - t1);				if (t > TS(30000))		{			ir_state->state = IR_STATE_LEADER_PULSE_START;			// fall through!		}						else 		{			ir_state->state = IR_STATE_WAIT_FOR_COMMAND_START;			// setup PIO 1 interrupt to signal on the falling edge			*(PIO_0_POL_REG) = 0x00010001 << IR_PIO;			break;		}			// PIO 1 is high, save the time (t0) at this moment and go to state 6	case IR_STATE_LEADER_PULSE_START:		ir_state->t0 = *(TIMER0_VAL_REG);		ir_state->state = IR_STATE_LEADER_PULSE;		// fall through!	// PIO 1 is high, we can only proceed to state 7 when PIO 5 goes low	case IR_STATE_LEADER_PULSE:		// program PIO 1 to signal on the next falling edge		*(PIO_0_POL_REG) = 0x00010001 << IR_PIO;		// and set the state to be the next state		ir_state->state = IR_STATE_LEADER_PULSE_END;		break;	// PIO 1 is low, current time = t1, if (t1-t0) < 3.5ms, then the last	// key was kept pressed down, go to state 8, else go to state 12	case IR_STATE_LEADER_PULSE_END:		t1 = *(TIMER0_VAL_REG);		t = ir_state->t0 - t1;		if (t < 0)			t = ir_state->t0 + (ir_state->timer_load - t1);		if (t > TS(15000))		{			ir_state->state = IR_STATE_READ_SCAN_CODE;			goto next_state;		}		else		{			ir_state->state = IR_STATE_REPEAT_PULSE_START;			// fall through!		}	// PIO 1 is low, we can proceed to state 1 only when PIO 1 goes high	case IR_STATE_REPEAT_PULSE_START:		// program PIO 1 to signal on the next *falling* edge		*(PIO_0_POL_REG) = 0x00010001 << IR_PIO;		// and set the state to be the next state		ir_state->state = IR_STATE_WAIT_FOR_COMMAND_START;		// XXX key repeated		ir_state->repeat++;		ir_state->release_timeout = 0;		if(ir_state->repeat >= IR_REPEAT && ir_state->scan_code) {			ir_state->repeat = 0;// XXX vincent: perhaps we should send a special "repeat" scancode//			fip_receive_scancode(ir_state->scan_code);		}		break;	// PIO 1 is low, set bit_position to 31, set scan_code to 0,	// save current time as t0, go to state 13	case IR_STATE_READ_SCAN_CODE:		ir_state->t0 = *(TIMER0_VAL_REG);		ir_state->scan_code = 0;		ir_state->repeat = 0;		ir_state->release_timeout = 0;		ir_state->bit_position = 31;		ir_state->state = IR_SUBSTATE_READ_BIT_START;		// fall through!	// PIO 1 is low, we can only proceed to state 14 when PIO 1 goes high	case IR_SUBSTATE_READ_BIT_START:		// program PIO 1 to signal on the next *falling* edge		*(PIO_0_POL_REG) = 0x00010001 << IR_PIO;		// the next time we get an interrupt will be when the signal		// has gone low again, so we actually skip state 14		ir_state->state = IR_SUBSTATE_READ_BIT_LOW;		break;	// PIO 1 is high, we can only go to state 15 when PIO 1 goes low	case IR_SUBSTATE_READ_BIT_HIGH:		if ((*(PIO_0_DATA_REG) & 2) == 0)		{			ir_state->state = IR_SUBSTATE_READ_BIT_LOW;			// fall through!		}		else			break;	// PIO 1 is low, current time = t1, if (t1-t0) > 1.75ms 	// scan_code |= (1 << bit_position)	// decrement bit position, if bit_posiion < 0, go to state 1,	// else go to state 13	case IR_SUBSTATE_READ_BIT_LOW:		t1 = *(TIMER0_VAL_REG);		t = ir_state->t0 - t1;		if (t < 0)			t = ir_state->t0 + (ir_state->timer_load - t1);// XXX why this hack? we have to try to ignore spurious interrupts?//// if ((t < TS(10000)) && (t > TS(6000)))//			break; 		if (t < TS(4500)) 			break; 			// XXX		if (t > TS(10000))			ir_state->scan_code |= (1 << ir_state->bit_position);#ifdef DEBUG_REMOTE		/* for debugging */		tt[ir_state->bit_position] = t;#endif		ir_state->bit_position--;		if (ir_state->bit_position < 0)		{			ir_state->state = IR_STATE_WAIT_FOR_COMMAND_START;			// program PIO 1 to signal on the next *falling* edge			*(PIO_0_POL_REG) = 0x00010001 << IR_PIO;			fip_receive_scancode(ir_state->scan_code);#ifdef DEBUG_REMOTE			/* for debugging */			if (ir_state->scan_code != DEBUG_REMOTE)			{				for (t1=0; t1<32; t1++)					DPRINTF ("(%02d: %d)\r\n", (int)t1, (int)tt[t1]);				DPRINTF ("scancode = 0x%08lx\n", (unsigned long)ir_state->scan_code);			}#endif						return 1; // scancode has been received		}		else		{			ir_state->t0 = *(TIMER0_VAL_REG);			// program PIO 1 to signal on the next *falling* edge			*(PIO_0_POL_REG) = 0x00010001 << IR_PIO;			// set the next state to be IR_SUBSTATE_READ_BIT_LOW			// and *not* IR_SUBSTATE_READ_BIT_START because the			// next time an interrupt will come is when PIO 1 is			// low again			ir_state->state = IR_SUBSTATE_READ_BIT_LOW;		}		break;	case IR_STATE_ERROR_RECOVERY:		ir_state->error_recovery--;		if (ir_state->error_recovery <= 0)			ir_state->state = IR_STATE_WAIT_FOR_COMMAND_START;		break;	default:		// error!!!		break;	}		return 0;}void ir_init(){	unsigned long dw;	unsigned long unit;	unsigned long pll_reg;	unsigned long pll_mult, pll_div, pll_D;	unsigned long clock;		ir_state.state = 1;	ir_state.timer_load = *(TIMER0_LOAD_REG);	dw = (*TIMER0_CNTL_REG) & 0x0F;	unit = 1000*2*1<<dw;	pll_reg = *QUASAR_DRAM_PLLCONTROL_REG;	pll_mult = (pll_reg & 0xFF) >> 2;	pll_div = (pll_reg >> 8 ) & 0x3;	pll_D = (pll_reg & 0x2);	clock = ((JASPER_EXT_CLOCK / unit) * (pll_mult+2))/(pll_div + 2);	if(pll_D)		clock = clock / 2;	// here we got sysclock in kHz	ir_state.timer_scale = clock;	DPRINTF("ir_init: scale = %d\n",ir_state.timer_scale);		// program PIO_0, bit IR_PIO, as input	*(PIO_0_DIR_REG) = 0x00010000 << IR_PIO;	// program PIO_0, bit IR_PIO, interrupt to signal on falling edge	*(PIO_0_POL_REG) = 0x00010001 << IR_PIO ;	// enable PIO_0, bit IR_PIO, interrupt	*(PIO_0_INT_ENABLE_REG) = 0x00010001 << IR_PIO;}#endif /* !FIP_NO_INTERRUPT */

⌨️ 快捷键说明

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