iop310_misc.c

来自「eCos操作系统源码」· C语言 代码 · 共 1,006 行 · 第 1/3 页

C
1,006
字号
	if (i2c_sources & (1<<7)) {	    isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_I2C_RX_FULL);	    CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "I2C RX FULL Interrupt not handled");	}	if (i2c_sources & (1<<6)) {	    isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_I2C_TX_EMPTY);	    CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "I2C TX EMPTY Interrupt not handled");	}	if (i2c_sources & (1<<10)) {	    isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_I2C_BUS_ERR);	    CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "I2C BUS ERR Interrupt not handled");	}	if (i2c_sources & (1<<4)) {	    isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_I2C_STOP);	    CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "I2C STOP Interrupt not handled");	}	if (i2c_sources & (1<<5)) {	    isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_I2C_LOSS);	    CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "I2C LOSS Interrupt not handled");	}	if (i2c_sources & (1<<9)) {	    isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_I2C_ADDRESS);	    CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "I2C ADDRESS Interrupt not handled");	}	return 0;    }    if (sources & 4) {	// Messaging Unit	cyg_uint32 inb_sources = *IISR_REG;	if (inb_sources & (1<<0)) {	    isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_MESSAGE_0);	    CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "MESSAGE 0 Interrupt not handled");	}	if (inb_sources & (1<<1)) {	    isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_MESSAGE_1);	    CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "MESSAGE 1 Interrupt not handled");	}	if (inb_sources & (1<<2)) {	    isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_DOORBELL);	    CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "DOORBELL Interrupt not handled");	}	if (inb_sources & (1<<4)) {	    isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_QUEUE_POST);	    CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "QUEUE POST Interrupt not handled");	}	if (inb_sources & (1<<6)) {	    isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_INDEX_REGISTER);	    CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "INDEX REGISTER Interrupt not handled");	}	return 0;    }    if (sources & 8) {	// BIST	isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_BIST);	CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "BIST Interrupt not handled");    }    return 0;}// This routine is called to respond to a hardware interrupt (IRQ).  It// should interrogate the hardware and return the IRQ vector number.int hal_IRQ_handler(void){    int sources, masks;    asm volatile ( // read the interrupt source reg INTSRC        "mrc      p13,0,%0,c4,c0,0;"        : "=r"(sources)        :       /*:*/        );    asm volatile ( // read the interrupt control reg INTCTL        "mrc      p13,0,%0,c0,c0,0;"        : "=r"(masks)        :       /*:*/        );    // is a source both unmasked and active?    if ( (0 != (1 & masks)) && (0 != ((8 << 28) & sources)) )        return CYGNUM_HAL_INTERRUPT_NFIQ;    if ( (0 != (2 & masks)) && (0 != ((4 << 28) & sources)) )        return CYGNUM_HAL_INTERRUPT_NIRQ;    if ( (0 != (8 & masks)) && (0 != ((2 << 28) & sources)) )        return CYGNUM_HAL_INTERRUPT_BCU_INTERRUPT;    if ( (0 != (4 & masks)) && (0 != ((1 << 28) & sources)) ) {        // more complicated; it's the PMU.        asm volatile ( // read the PMNC perfmon control reg            "mrc      p14,0,%0,c0,c0,0;"            : "=r"(sources)            :             /*:*/            );        // sources is now the PMNC performance monitor control register        // enable bits are 4..6, status bits are 8..10        sources = (sources >> 4) & (sources >> 8);        if ( 1 & sources )            return CYGNUM_HAL_INTERRUPT_PMU_PMN0_OVFL;        if ( 2 & sources )            return CYGNUM_HAL_INTERRUPT_PMU_PMN1_OVFL;        if ( 4 & sources )            return CYGNUM_HAL_INTERRUPT_PMU_CCNT_OVFL;    }    return CYGNUM_HAL_INTERRUPT_NONE; // This shouldn't happen!}//// Interrupt control//void hal_interrupt_mask(int vector){    int mask = 0;    int submask = 0;    switch ( vector ) {    case CYGNUM_HAL_INTERRUPT_PMU_PMN0_OVFL:    case CYGNUM_HAL_INTERRUPT_PMU_PMN1_OVFL:    case CYGNUM_HAL_INTERRUPT_PMU_CCNT_OVFL:        submask = vector - CYGNUM_HAL_INTERRUPT_PMU_PMN0_OVFL; // 0 to 2        // select interrupt enable bit and also enable the perfmon per se        submask = (1 << (submask + 4)); // bits 4-6 are masks        asm volatile (            "mrc      p14,0,r1,c0,c0,0;"            "bic      r1, r1, #0x700;" // clear the overflow/interrupt flags            "bic      r1, r1, #0x006;" // clear the reset bits            "bic      %0, r1, %0;"     // preserve r1; better for debugging            "tsts     %0, #0x070;"     // are all 3 sources now off?            "biceq    %0, %0, #1;"     // if so, disable entirely.            "mcr      p14,0,%0,c0,c0,0;"            :            : "r"(submask)            : "r1"            );        mask = 4;        break;    case CYGNUM_HAL_INTERRUPT_BCU_INTERRUPT:        // Nothing specific to do here        mask = 8;        break;    case CYGNUM_HAL_INTERRUPT_NIRQ         :        mask = 2;        break;    case CYGNUM_HAL_INTERRUPT_NFIQ         :        mask = 1;        break;    case CYGNUM_HAL_INTERRUPT_GTSC:        *GTMR_REG &= ~1;        return;    case CYGNUM_HAL_INTERRUPT_PEC:        *ESR_REG &= ~(1<<16);        return;    case CYGNUM_HAL_INTERRUPT_AAIP:        *ADCR_REG &= ~1;        return;    case CYGNUM_HAL_INTERRUPT_I2C_TX_EMPTY ... CYGNUM_HAL_INTERRUPT_I2C_ADDRESS:        *ICR_REG &= ~(1<<(vector - CYGNUM_HAL_INTERRUPT_I2C_TX_EMPTY));	return;    case CYGNUM_HAL_INTERRUPT_MESSAGE_0 ... CYGNUM_HAL_INTERRUPT_INDEX_REGISTER:        *IIMR_REG &= ~(1<<(vector - CYGNUM_HAL_INTERRUPT_MESSAGE_0));	return;    case CYGNUM_HAL_INTERRUPT_BIST:        *ATUCR_REG &= ~(1<<3);	return;    case CYGNUM_HAL_INTERRUPT_P_SERR:  // FIQ        *ATUCR_REG &= ~(1<<9);	return;    case CYGNUM_HAL_INTERRUPT_S_SERR:  // FIQ        *ATUCR_REG &= ~(1<<10);	return;    case CYGNUM_HAL_INTERRUPT_XINT3_BIT0 ... CYGNUM_HAL_INTERRUPT_XINT3_BIT4:        *X3MASK_REG |= (1<<(vector - CYGNUM_HAL_INTERRUPT_XINT3_BIT0));	return;#ifdef CYGNUM_HAL_INTERRUPT_PCI_S_INTC	    // The hardware doesn't (yet?) provide masking or status for these    // even though they can trigger cpu interrupts. ISRs will need to    // poll the device to see if the device actually triggered the    // interrupt.    case CYGNUM_HAL_INTERRUPT_PCI_S_INTC:    case CYGNUM_HAL_INTERRUPT_PCI_S_INTB:    case CYGNUM_HAL_INTERRUPT_PCI_S_INTA:    default:        /* do nothing */        return;#endif    }    asm volatile (        "mrc      p13,0,r1,c0,c0,0;"        "bic      r1, r1, %0;"        "mcr      p13,0,r1,c0,c0,0;"        :        : "r"(mask)        : "r1"        );}void hal_interrupt_unmask(int vector){    int mask = 0;    int submask = 0;    switch ( vector ) {    case CYGNUM_HAL_INTERRUPT_PMU_PMN0_OVFL:    case CYGNUM_HAL_INTERRUPT_PMU_PMN1_OVFL:    case CYGNUM_HAL_INTERRUPT_PMU_CCNT_OVFL:        submask = vector - CYGNUM_HAL_INTERRUPT_PMU_PMN0_OVFL; // 0 to 2        // select interrupt enable bit and also enable the perfmon per se        submask = 1 + (1 << (submask + 4)); // bits 4-6 are masks        asm volatile (            "mrc      p14,0,r1,c0,c0,0;"            "bic      r1, r1, #0x700;"   // clear the overflow/interrupt flags            "bic      r1, r1, #0x006;"   // clear the reset bits            "orr      %0, r1, %0;"       // preserve r1; better for debugging            "mcr      p14,0,%0,c0,c0,0;"            "mrc      p13,0,r2,c8,c0,0;" // steer PMU interrupt to IRQ            "and      r2, r2, #2;"       // preserve the other bit (BCU steer)            "mcr      p13,0,r2,c8,c0,0;"            :            : "r"(submask)            : "r1","r2"            );        mask = 4;        break;    case CYGNUM_HAL_INTERRUPT_BCU_INTERRUPT:         asm volatile (            "mrc      p13,0,r2,c8,c0,0;" // steer BCU interrupt to IRQ            "and      r2, r2, #1;"       // preserve the other bit (PMU steer)            "mcr      p13,0,r2,c8,c0,0;"            :            :             : "r2"            );        mask = 8;        break;    case CYGNUM_HAL_INTERRUPT_NIRQ         :        mask = 2;        break;    case CYGNUM_HAL_INTERRUPT_NFIQ         :        mask = 1;        break;    case CYGNUM_HAL_INTERRUPT_GTSC:        *GTMR_REG |= 1;        return;    case CYGNUM_HAL_INTERRUPT_PEC:        *ESR_REG |= (1<<16);        return;    case CYGNUM_HAL_INTERRUPT_AAIP:        *ADCR_REG |= 1;        return;    case CYGNUM_HAL_INTERRUPT_I2C_TX_EMPTY ... CYGNUM_HAL_INTERRUPT_I2C_ADDRESS:        *ICR_REG |= (1<<(vector - CYGNUM_HAL_INTERRUPT_I2C_TX_EMPTY));	return;    case CYGNUM_HAL_INTERRUPT_MESSAGE_0 ... CYGNUM_HAL_INTERRUPT_INDEX_REGISTER:        *IIMR_REG |= (1<<(vector - CYGNUM_HAL_INTERRUPT_MESSAGE_0));	return;    case CYGNUM_HAL_INTERRUPT_BIST:        *ATUCR_REG |= (1<<3);	return;    case CYGNUM_HAL_INTERRUPT_P_SERR:  // FIQ        *ATUCR_REG |= (1<<9);	return;    case CYGNUM_HAL_INTERRUPT_S_SERR:  // FIQ        *ATUCR_REG |= (1<<10);	return;    case CYGNUM_HAL_INTERRUPT_XINT3_BIT0 ... CYGNUM_HAL_INTERRUPT_XINT3_BIT4:        *X3MASK_REG &= ~(1<<(vector - CYGNUM_HAL_INTERRUPT_XINT3_BIT0));	return;#ifdef CYGNUM_HAL_INTERRUPT_PCI_S_INTC	    // The hardware doesn't (yet?) provide masking or status for these    // even though they can trigger cpu interrupts. ISRs will need to    // poll the device to see if the device actually triggered the    // interrupt.    case CYGNUM_HAL_INTERRUPT_PCI_S_INTC:    case CYGNUM_HAL_INTERRUPT_PCI_S_INTB:    case CYGNUM_HAL_INTERRUPT_PCI_S_INTA:    default:        /* do nothing */        return;#endif    }    asm volatile (        "mrc      p13,0,r1,c0,c0,0;"        "orr      %0, r1, %0;"        "mcr      p13,0,%0,c0,c0,0;"        :        : "r"(mask)        : "r1"        );}void hal_interrupt_acknowledge(int vector){    int submask = 0;    switch ( vector ) {    case CYGNUM_HAL_INTERRUPT_PMU_PMN0_OVFL:    case CYGNUM_HAL_INTERRUPT_PMU_PMN1_OVFL:    case CYGNUM_HAL_INTERRUPT_PMU_CCNT_OVFL:        submask = vector - CYGNUM_HAL_INTERRUPT_PMU_PMN0_OVFL; // 0 to 2        // select interrupt enable bit and also enable the perfmon per se        submask = (1 << (submask + 8)); // bits 8-10 are status; write 1 clr        // Careful not to ack other interrupts or zero any counters:        asm volatile (            "mrc      p14,0,r1,c0,c0,0;"            "bic      r1, r1, #0x700;" // clear the overflow/interrupt flags            "bic      r1, r1, #0x006;" // clear the reset bits            "orr      %0, r1, %0;"     // preserve r1; better for debugging            "mcr      p14,0,%0,c0,c0,0;"            :            : "r"(submask)            : "r1"            );        break;    case CYGNUM_HAL_INTERRUPT_BCU_INTERRUPT:    case CYGNUM_HAL_INTERRUPT_NIRQ         :    case CYGNUM_HAL_INTERRUPT_NFIQ         :    default:        /* do nothing */        return;    }}void hal_interrupt_configure(int vector, int level, int up){}void hal_interrupt_set_level(int vector, int level){}/*------------------------------------------------------------------------*/// EOF iop310_misc.c

⌨️ 快捷键说明

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