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 + -
显示快捷键?