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

📄 ir.c

📁 ESS 公司VCD软件关于IR的编程!
💻 C
📖 第 1 页 / 共 4 页
字号:
/* For the new style of IR handling (i.e. via 4438) */
/************************************************************************
 * Local variables.							*
 ************************************************************************/
PRIVATE	unsigned short	dataIR;		/* System/customer IR code	*/
PRIVATE	char 		cntIRbits = 0;	/* Number of IR sys/cust. bits	*/
PRIVATE volatile char	stateIR = IR_IDLE; /* IR state machine state	*/
PRIVATE char trigger_edge;
PRIVATE	unsigned int	prevIRtime = 0;	/* Last time IR intr. happens	*/

#ifdef IR_NEC
PRIVATE	unsigned int	wrongIRwidth = 0;
PRIVATE	unsigned int	intIRtime = 0;
#endif

#ifdef IR_SANYO
PRIVATE	unsigned short IR_sanyo_codebar;/* Sanyo IR only		*/
#endif /* IR_SAYNO */

#ifdef IRREP
PRIVATE unsigned char   previous_data;  /* Record the previous ID code  */
#endif

/************************************************************************
 * Local routines							*
 ************************************************************************/
PRIVATE	void		IR_core_NEC(unsigned int, int);
PRIVATE	void		IR_core_Philips(unsigned int, int);

void ir_init()
{
    CPRINTF(("EauxIR_ir_init....\n"));

    sysIRcode = IR_syscode[0];	/* Initialize IR system code	*/
  
#ifdef DANCER
    sysDANCERcode = T_DANCER_syscode[0];        /* Initialize IR system code */
#endif
    CLEAR_IRXOR;	/* Clear IR XOR (EAUX11 is active high!!	*/

#ifdef IR_SANYO
    IR_sanyo_codebar = (~sysIRcode) & 0x1fff;
#endif /* IR_SANYO */    


#ifdef NETWORK
#ifdef EAUX_ENABLE_C2PO
	if (boot_nic) {			//use ethernet
		ENABLE_EAUX3(2);   /* toggle dbg interrupt pin */
		EAUX_init_irq_ctl(1, 1, 1, 8, 0x80);
	}
#endif
#ifdef WILDCAT              /* AUX5 as PCMCIA interrupt */
    EAUX_init_irq_ctl(1, EAUX_FALLING_EDGE, 1, 4, 0x40);
#endif
#endif

    
#if defined(BD_BAHAMAS) && defined(DVD_MODEM)
    Init4210IrqCtl( 1, 1, 4 );	/*falling-edge, aux4, eaux mode enabled*/
#else
    EAUX_init_ir(1, EAUX_FALLING_EDGE, 1);	/* Start 4438 IR	*/
#endif

    EAUX_INIT_16550(1,  EAUX_RISING_EDGE); /* On, Rising edge */
    trigger_edge = 0;
    mvd[riface_clear_dbgirq] = 0;		/* Clear debug_irq	*/

#ifndef NETWORK
    enable_int(debug);
#endif

}

#if (IR_NEC || IR_SANYO)
PRIVATE void IR_core_NEC(width, overflow)
unsigned int width;
int overflow;
{
#define LEADER_MIN	ir_tbl[0]
#define LEADER_MAX	ir_tbl[1]
#define DATA_1_MIN	ir_tbl[2]
#define DATA_1_MAX	ir_tbl[3]
#define DATA_0_MIN	ir_tbl[4]
#define DATA_0_MAX	ir_tbl[5]
#ifdef IRREP
#define REPEAT_MIN	ir_tbl[6]
#define REPEAT_MAX	ir_tbl[7]
#endif /* IRREP */

#ifdef DANCER
#define LEADER_DANCER_MIN       ir_tbl[IRTBL_INDX_LAST+1]
#define LEADER_DANCER_MAX       ir_tbl[IRTBL_INDX_LAST+2]
#define DATA_1_DANCER_MIN       ir_tbl[IRTBL_INDX_LAST+3]
#define DATA_1_DANCER_MAX       ir_tbl[IRTBL_INDX_LAST+4]
#define DATA_0_DANCER_MIN       ir_tbl[IRTBL_INDX_LAST+5]
#define DATA_0_DANCER_MAX       ir_tbl[IRTBL_INDX_LAST+6]
#endif
 
    unsigned int *ir_tbl;
    unsigned char data, check;
    int reset;
 
    ir_tbl = IR_table;

    /*
     * If 4438's clock overflows, then reset. The only exception is
     * when REP is considered!!
     */
    reset = overflow; 

    if (stateIR == IR_CUSTOM) {
        dataIR <<= 1;
        if ((width >= DATA_1_MIN) && (width <= DATA_1_MAX)) {
            dataIR |= 0x1;
        } else if ((width < DATA_0_MIN) || (width > DATA_1_MAX)) {
#ifdef IR_NEC
            reset = 1;
#endif /* IR_NEC */

#ifdef IR_SANYO
            reset = 1;	/* we do not care about repeat key for Sanyo yet */
#endif /* IR_SANYO */

        }
 
        cntIRbits++;
	
#ifdef IR_NEC
        /* First 16 bits are syscode */
#if defined(_KB_VIALTA_) || defined(_KB_VIALTA_02_) 
        if (cntIRbits == 16) {
	    int k;
	    for ( k =0; k < T_IR_syscode_SZ >> 2; k ++)
		if (dataIR == IR_syscode[k]) break;
	    if (k == T_IR_syscode_SZ >> 2) reset = 1;
	    else code_set = k;
	}
#else
        if ((cntIRbits == 16) && (dataIR != sysIRcode)) reset = 1;
#endif
#if 0
        if (cntIRbits == 24) {

            data = dataIR & 0xff;
            /* reverse data bits to fit look up table */
            mvd[riface_reflect] = data;
            data = mvd[riface_reflect];

#ifdef IRREP
            previous_data = data;
#endif

            codeIR = data | 0x100;      /* Indicate a new code */
        } else if (cntIRbits == 32) reset = 1;
#else			
	if (cntIRbits == 32)		
            {
	       	data = (dataIR >> 8) & 0xff;
	      	check = (~data) & 0xff;
	     	if((dataIR & 0xff)== check)	/*do the double check */
	     	{
	      	mvd[riface_reflect] = data;
              	data = mvd[riface_reflect];
#ifdef IRREP
            previous_data = data;
#endif
              	codeIR = data | 0x100;      /* Indicate a new code */
              	}
                reset = 1;
          }
#endif	
#endif /* IR_NEC */

#ifdef IR_SANYO
        if (cntIRbits == 13) {
            dataIR &= 0x1fff;
            if (dataIR != sysIRcode) reset = 1;
            dataIR = 0;
        } else if (cntIRbits == 26) {
            unsigned short tmp = (~sysIRcode) & 0x1fff;
            if (dataIR != tmp) reset = 1;
            dataIR = 0;
        } else if (cntIRbits == 34) {
            data = dataIR;
            mvd[riface_reflect] = data;
            data = mvd[riface_reflect];
            codeIR = data;
            dataIR = 0;
        } else if (cntIRbits == 42) {
            data = dataIR;
            mvd[riface_reflect] = data;
            data = ~(mvd[riface_reflect]);
            if (data == codeIR) {
                codeIR = data | 0x100;
            } else codeIR = 0;
            reset = 1;
        }
#endif /* IR_SANYO */

    } 
#ifdef DANCER
    else if (stateIR == DANCER_CUSTOM)
    {
        dataIR <<= 1;
        if ((width >= DATA_1_DANCER_MIN) && (width <= DATA_1_DANCER_MAX)) {
            dataIR |= 0x1;
        }
        else if ((width < DATA_1_DANCER_MIN) || (width > DATA_0_DANCER_MAX)) {
            reset = 1;
        }

        cntIRbits++;
        if ((cntIRbits == 15) && ((dataIR & 0x7f) != sysDANCERcode)) reset = 1;

        if (cntIRbits == 16)
        {
            int i;
            int parity;
            int one_num = 0;
            parity = dataIR & 0x1;
            data = dataIR >> 8;
            for (i=0;i<8;i++)
            {
               if ((data & 0x1) == 1)
                   one_num ++;
               data >>= 1;
            }

            if (!(one_num & 1) && !parity)
                 reset = 1;
            else if ((one_num & 1) && parity)
                 reset = 1;
            else
            {   
                 data = dataIR >> 8;
                 codeIR = data | 0x1100;      /* Indicate a new code */
            }
        } else if (cntIRbits == 17) reset = 1;
    }
#endif
    else {
	if ((width >= LEADER_MIN) && (width <= LEADER_MAX)) {
	    stateIR = IR_CUSTOM;
	    dataIR = cntIRbits = 0;
#ifdef DANCER
        } else if ((width >= LEADER_DANCER_MIN) &&
                   (width <= LEADER_DANCER_MAX))
        {
            stateIR = DANCER_CUSTOM;
            dataIR = cntIRbits = 0;
#endif
#ifdef IRREP
        } else if ((width >= REPEAT_MIN) && (width <= REPEAT_MAX)) {
            /* if the width is 2.25 ms, it is repeat code leader */
            if (repeat_IRkey_allowed(previous_data))
	      codeIR = previous_data | 0x100; /* Indicate a new code */
#endif
        } else reset = 1;
    }
 
    if (reset) {
        /* Reset all, start from the very beginning */
#ifdef NETWORK
	if (netmode && dataIR && cntIRbits >= 32) {
		extern int stream_playing;
		fan_dataIR[nKeyEnd] = dataIR;
		nKeyEnd ++;
		if(nKeyEnd >= 100) nKeyEnd = 0;
		ir_keypressed = 1;
		if (stream_playing && dataIR==0xf807)
			stopTime = RISC_linear_time+6;
	}
#endif
	dataIR = 0;
        stateIR = IR_IDLE;
    }
}
#endif /* IR_NEC || IR_SANYO */


#ifdef IR_PHILIPS
PRIVATE unsigned int    data_half = 0;  /* Mark whether or nor have half_bit
                                           data before edge of intr. coming*/
PRIVATE void IR_core_Philips(width, overflow)
unsigned int width;
int overflow;
{
    unsigned int *ir_tbl;
    int reset;
    int is_half_bit;
    int is_full_bit;

#define HALFBIT_MIN     ir_tbl[0]
#define HALFBIT_MAX     ir_tbl[1]
#define ONEBIT_MIN      ir_tbl[2]
#define ONEBIT_MAX      ir_tbl[3]

    ir_tbl = IR_table;

    reset = overflow;	/* If 3881's clock overflows, then reset */

    is_half_bit = (width >= HALFBIT_MIN) && (width <= HALFBIT_MAX);
    is_full_bit = (width >= ONEBIT_MIN)  && (width <= ONEBIT_MAX);

    if (stateIR == IR_IDLE) {
        /* We shall get a rising edge, since the first bit is fixed */
        dataIR = 0;
        cntIRbits = 0;
        stateIR = IR_CUSTOM;

        if (is_half_bit) data_half = 0;
        else if (is_full_bit) data_half = 1;
        else {
            stateIR = IR_IDLE;
        }
    } else {
        if (data_half) {
            /*
             * We were in half bit position, so this edge shall either
             * conclude the previous cycle or go the the half position
             * of the next bit. Record the last bit.
             */
            dataIR <<= 1;
            if (!trigger_edge) dataIR |= 1;
            cntIRbits++;

            if (is_half_bit) data_half = 0;
            else if (!is_full_bit) reset = 1;
        } else {
            /*
             * We started at a sampling cycle, so we shall only get half bit,
             * otherwise, something is wrong!
             */
            if (is_half_bit) data_half = 1;
            else reset = 1;
        }

        if ((cntIRbits == 12) && trigger_edge && data_half) {
            /* This is the last rising edge, no more. So collect the bit */
            dataIR <<= 1;
            dataIR |= 1;
            cntIRbits = 13;
        }

        if (reset) {
            /*
             * Abnormal exist. Maybe we are out of sync. If this
             * is falling edge, maybe this is the sync of a new
             * input!
             */
            stateIR = IR_IDLE;
            if (trigger_edge) stateIR = IR_LEADER;
        } else if (cntIRbits == 13) {
            /* We only care the case when system code matches */
            if (((dataIR >> 6) & 0x1f) == sysIRcode) {
                unsigned int prevctlbit;
                prevctlbit = IR_ctlbit;

                IR_ctlbit = (dataIR >> 11) & 1;
                if ((unsigned int) IR_ctlbit != prevctlbit) {
                    int tmp = (dataIR >> 12) & 1;
                    if (tmp) tmp = 0x40;
                    codeIR = (dataIR & 0x3f) | tmp | 0x100;
                    IR_rep_cnt = 0;
                } else
                  IR_rep_cnt++;
                IR_int_time = (unsigned int) mvd[riface_timer2];
            }
            stateIR = IR_IDLE;
        }
    }
}
#endif /* IR_PHILIPS */


#if defined(IR_NEC) || defined(IR_SANYO)
#define CLK_LEADER_MIN  (cpuclk * 1300)  /* Leader minimum */
#define CLK_LEADER_MAX  (cpuclk * 1390)  /* Leader maximum */
#define CLK_DATA_1_MIN  (cpuclk * 195)   /* Data 1 minimum  */
#define CLK_DATA_1_MAX  (cpuclk * 255)   /* Data 1 maximum */
#define CLK_DATA_0_MIN  (cpuclk * 82)    /* Data 0 minimum */
#define CLK_DATA_0_MAX  (cpuclk * 142)   /* Data 0 maximum  */
#ifdef IRREP
#define CLK_REP_MIN  (cpuclk * 1000)	 /* Data 0 minimum */
#define CLK_REP_MAX  (cpuclk * 1150)	 /* Data 0 maximum  */
#endif /* IRREP */

/* The width for IR_NEC */
#define IR_LEADER  IR_table[1]
#define IR_DATA_1  IR_table[3]
#define IR_DATA_0  IR_table[5]
#ifdef IRREP
#define IR_REPEAT  IR_table[7]
#endif /* IRREP */
#endif

#ifdef IR_PHILIPS
#define CLK_HALFBIT_MIN   (cpuclk*50)     /* minimum length of half bit */
#define CLK_HALFBIT_MAX   (cpuclk*130)    /* maximum length of half bit */
#define CLK_ONEBIT_MIN    (cpuclk*140)    /* minimum length of one bit */
#define CLK_ONEBIT_MAX    (cpuclk*240)    /* maximum length of one bit */
#define IR_HALFBIT	    IR_table[1]
#define IR_ONEBIT	    IR_table[3]
#endif

/* Interrupt via 4438 */
void IR_recv_interrupt_service(status)
unsigned int status;
{
    unsigned int width;
    unsigned int *ir_tbl;
    int overflow = 0;
       
    if (status & 0x80) {
	overflow = 1;			/* 4438's clock overflowed	*/

    }

#if defined(BD_BAHAMAS) && defined(DVD_MODEM)
    width = 0; wrongIRwidth = 0;
#else
    width = mvd[eaux_ir_diff] & 0xff;	/* Get the counter	*/
#endif
#ifdef IR_NEC
    if(!IS_POWER_DOWN) {		/* only active when power on */
	/* avoid the width is 0 for the noise, we use timer2 instead */
	if((width == 0) || (wrongIRwidth == 1)) {		
	    unsigned int currIRtime;
	    currIRtime = mvd[riface_timer2];
	    width = currIRtime - intIRtime;
	    if (currIRtime < intIRtime) {  /* Wrap around case		*/
		width += -timer2_period;
	    }
	    if ((width >= CLK_LEADER_MIN) && (width <= CLK_LEADER_MAX)) {
		width = IR_LEADER; 
	    } else if ((width >= CLK_DATA_1_MIN) && (width <= CLK_DATA_1_MAX)) {
		width = IR_DATA_1;
	    } else if ((width >= CLK_DATA_0_MIN) && (width <= CLK_DATA_0_MAX)) {
		width = IR_DATA_0;
	    } else
		{
#ifdef IRREP	  
		  if ((width >= CLK_REP_MIN) && (width <= CLK_REP_MAX)) {
			width = IR_REPEAT;
			}
		  else
#endif /*IRREP	*/

⌨️ 快捷键说明

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