📄 var_intr.c
字号:
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 + -