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

📄 var_intr.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 2 页
字号:

externC void 
hal_ppc40x_interrupt_acknowledge(int vector)
{
    switch (vector) {
    case CYGNUM_HAL_INTERRUPT_EXT0:
    case CYGNUM_HAL_INTERRUPT_EXT1:
    case CYGNUM_HAL_INTERRUPT_EXT2:
    case CYGNUM_HAL_INTERRUPT_EXT3:
    case CYGNUM_HAL_INTERRUPT_EXT4:
        CYGARC_MTDCR(DCR_EXISR, exier_mask[vector]);
        break;
    case CYGNUM_HAL_INTERRUPT_VAR_TIMER:
        CYGARC_MTSPR(SPR_TSR, TSR_PIS);  // clear & acknowledge interrupt
        break;
    case CYGNUM_HAL_INTERRUPT_FIXED_TIMER:
        CYGARC_MTSPR(SPR_TSR, TSR_FIS);  // clear & acknowledge interrupt
        break;
    case CYGNUM_HAL_INTERRUPT_WATCHDOG_TIMER:
        CYGARC_MTSPR(SPR_TSR, TSR_WIS);  // clear & acknowledge interrupt
        break;
    case CYGNUM_HAL_INTERRUPT_CRITICAL:
    case CYGNUM_HAL_INTERRUPT_SERIAL_RCV:
    case CYGNUM_HAL_INTERRUPT_SERIAL_XMT:
    case CYGNUM_HAL_INTERRUPT_JTAG_RCV:
    case CYGNUM_HAL_INTERRUPT_JTAG_XMT:
    case CYGNUM_HAL_INTERRUPT_DMA0:
    case CYGNUM_HAL_INTERRUPT_DMA1:
    case CYGNUM_HAL_INTERRUPT_DMA2:
    case CYGNUM_HAL_INTERRUPT_DMA3:
    default:
        break;
    }
}

// Note: These functions are only [well] defined for "external" interrupts
// which can be controlled via the EXIER register.
externC void 
hal_ppc40x_interrupt_configure(int vector, int level, int dir)
{
    cyg_uint32 mask, new_state, iocr;

    if ((vector >= CYGNUM_HAL_INTERRUPT_EXT0) &&
        (vector <= CYGNUM_HAL_INTERRUPT_EXT4)) {
        mask = 0x03 << (30 - ((vector - CYGNUM_HAL_INTERRUPT_EXT0)*2));
        new_state = (dir & 0x01);  // Up/Down    
        if (level == 0) {
            // Edge triggered
            new_state = 0x02;
        }
        new_state <<= (30 - ((vector - CYGNUM_HAL_INTERRUPT_EXT0)*2));
        CYGARC_MFDCR(DCR_IOCR, iocr);
        iocr = (iocr & ~mask) | new_state;
        CYGARC_MTDCR(DCR_IOCR, iocr);
    }
}

externC void 
hal_ppc40x_interrupt_set_level(int vector, int level)
{
}
#endif // CYGHWR_HAL_POWERPC_PPC4XX_403

#if defined(CYGHWR_HAL_POWERPC_PPC4XX_405) || defined(CYGHWR_HAL_POWERPC_PPC4XX_405GP) || defined(CYGHWR_HAL_POWERPC_PPC4XX_405EP)

cyg_uint32 _hold_tcr = 0;  // Shadow of hardware register

externC void
hal_variant_IRQ_init(void)
{
#ifndef HAL_PLF_INTERRUPT_INIT
    // Ensure all interrupts masked (disabled) & cleared
    CYGARC_MTDCR(DCR_UIC0_ER, 0);
    CYGARC_MTDCR(DCR_UIC0_CR, 0);
    CYGARC_MTDCR(DCR_UIC0_PR, 0xFFFFE000);
    CYGARC_MTDCR(DCR_UIC0_TR, 0);
    CYGARC_MTDCR(DCR_UIC0_VCR, 0);  // Makes vector identification easy
    CYGARC_MTDCR(DCR_UIC0_SR, 0xFFFFFFFF);
#else
    HAL_PLF_INTERRUPT_INIT();
#endif

    // Disable timers
    CYGARC_MTSPR(SPR_TCR, 0);

    // Let the platform do any overrides
    hal_platform_IRQ_init();
}

externC void 
hal_ppc40x_interrupt_mask(int vector)
{
    cyg_uint32 exier, tcr;

    switch (vector) {
    case CYGNUM_HAL_INTERRUPT_first...CYGNUM_HAL_INTERRUPT_last:
#ifndef HAL_PLF_INTERRUPT_MASK
        CYGARC_MFDCR(DCR_UIC0_ER, exier);
        exier &= ~(1<<(31-(vector-CYGNUM_HAL_INTERRUPT_405_BASE)));
        CYGARC_MTDCR(DCR_UIC0_ER, exier);
#else
        HAL_PLF_INTERRUPT_MASK(vector);
#endif
        break;
    case CYGNUM_HAL_INTERRUPT_VAR_TIMER:
        CYGARC_MFSPR(SPR_TCR, tcr);
        tcr = _hold_tcr;
        tcr &= ~TCR_PIE;
        CYGARC_MTSPR(SPR_TCR, tcr);
        _hold_tcr = tcr;
        break;
    case CYGNUM_HAL_INTERRUPT_FIXED_TIMER:
        CYGARC_MFSPR(SPR_TCR, tcr);
        tcr = _hold_tcr;
        tcr &= ~TCR_FIE;
        CYGARC_MTSPR(SPR_TCR, tcr);
        _hold_tcr = tcr;
        break;
    case CYGNUM_HAL_INTERRUPT_WATCHDOG_TIMER:
        CYGARC_MFSPR(SPR_TCR, tcr);
        tcr = _hold_tcr;
        tcr &= ~TCR_WIE;
        CYGARC_MTSPR(SPR_TCR, tcr);
        _hold_tcr = tcr;
        break;
    default:
        break;
    }
}

externC void 
hal_ppc40x_interrupt_unmask(int vector)
{
    cyg_uint32 exier, tcr;

    switch (vector) {
    case CYGNUM_HAL_INTERRUPT_first...CYGNUM_HAL_INTERRUPT_last:
#ifndef HAL_PLF_INTERRUPT_UNMASK
        CYGARC_MFDCR(DCR_UIC0_ER, exier);
        exier |= (1<<(31-(vector-CYGNUM_HAL_INTERRUPT_405_BASE)));
        CYGARC_MTDCR(DCR_UIC0_ER, exier);
#else
        HAL_PLF_INTERRUPT_UNMASK(vector);
#endif
        break;
    case CYGNUM_HAL_INTERRUPT_VAR_TIMER:
        CYGARC_MFSPR(SPR_TCR, tcr);
        tcr = _hold_tcr;
        tcr |= TCR_PIE;
        CYGARC_MTSPR(SPR_TCR, tcr);
        _hold_tcr = tcr;
        break;
    case CYGNUM_HAL_INTERRUPT_FIXED_TIMER:
        CYGARC_MFSPR(SPR_TCR, tcr);
        tcr = _hold_tcr;
        tcr |= TCR_FIE;
        CYGARC_MTSPR(SPR_TCR, tcr);
        _hold_tcr = tcr;
        break;
    case CYGNUM_HAL_INTERRUPT_WATCHDOG_TIMER:
        CYGARC_MFSPR(SPR_TCR, tcr);
        tcr = _hold_tcr;
        tcr |= TCR_WIE;
        CYGARC_MTSPR(SPR_TCR, tcr);
        _hold_tcr = tcr;
        break;
    default:
        break;
    }
}

externC void 
hal_ppc40x_interrupt_acknowledge(int vector)
{
    switch (vector) {
    case CYGNUM_HAL_INTERRUPT_first...CYGNUM_HAL_INTERRUPT_last:
#ifndef HAL_PLF_INTERRUPT_ACKNOWLEDGE
        CYGARC_MTDCR(DCR_UIC0_SR, (1<<(31-(vector-CYGNUM_HAL_INTERRUPT_405_BASE))));
#else
        HAL_PLF_INTERRUPT_ACKNOWLEDGE(vector);
#endif
        break;
    case CYGNUM_HAL_INTERRUPT_VAR_TIMER:
        CYGARC_MTSPR(SPR_TSR, TSR_PIS);  // clear & acknowledge interrupt
        break;
    case CYGNUM_HAL_INTERRUPT_FIXED_TIMER:
        CYGARC_MTSPR(SPR_TSR, TSR_FIS);  // clear & acknowledge interrupt
        break;
    case CYGNUM_HAL_INTERRUPT_WATCHDOG_TIMER:
        CYGARC_MTSPR(SPR_TSR, TSR_WIS);  // clear & acknowledge interrupt
        break;
    default:
        break;
    }
}

// Note: These functions are only [well] defined for "external" interrupts
externC void 
hal_ppc40x_interrupt_configure(int vector, int level, int dir)
{
#ifndef HAL_PLF_INTERRUPT_CONFIGURE
    cyg_uint32 mask, new_state, iocr;

    if ((vector >= CYGNUM_HAL_INTERRUPT_IRQ0) &&
        (vector <= CYGNUM_HAL_INTERRUPT_IRQ6)) {
        mask = (1<<(31-(vector-CYGNUM_HAL_INTERRUPT_405_BASE)));
        // Set polarity
        if (dir) {
            // High true
            new_state = mask;
        } else {
            // Low true
            new_state = 0;
        }
        CYGARC_MFDCR(DCR_UIC0_PR, iocr);
        iocr = (iocr & ~mask) | new_state;
        CYGARC_MTDCR(DCR_UIC0_PR, iocr);
        // Set edge/level
        if (level == 0) {
            // Edge triggered
            new_state = mask;
        } else {
            // Level triggered
            new_state = 0;
        }
        CYGARC_MFDCR(DCR_UIC0_TR, iocr);
        iocr = (iocr & ~mask) | new_state;
        CYGARC_MTDCR(DCR_UIC0_TR, iocr);
    }
#else
    HAL_PLF_INTERRUPT_CONFIGURE(vector, level, dir);
#endif
}

externC void 
hal_ppc40x_interrupt_set_level(int vector, int level)
{
#ifndef HAL_PLF_INTERRUPT_SET_LEVEL
    // Nothing to do for UIC
#else
    HAL_PLF_INTERRUPT_SET_LEVEL(vector, level);
#endif
}
#endif // CYGHWR_HAL_POWERPC_PPC4XX_405

// -------------------------------------------------------------------------
// EOF var_intr.c

⌨️ 快捷键说明

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