Цитата(aaarrr @ Mar 25 2010, 18:41)

Очень похоже, что упускаете правильное оформление процедуры прерывания. Что живет на векторе IRQ?
Или, как вариант, где-то включен еще один источник SYS.
Распишу по частям как у меня инициализируется прерывание
Сразу после настройки PLL инициализирую AIC дефолтными значениеями
CODE
void defaultSpuriousHandler( void )
{
while (1);
}
void defaultFiqHandler( void )
{
while (1);
}
void defaultIrqHandler( void )
{
while (1);
}
// Initialize AIC
AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF; //запрет всех прерываний
AT91C_BASE_AIC->AIC_SVR[0] = (unsigned int) defaultFiqHandler; //инициализация вектора FIQ
for (i = 1; i < 31; i++) {
AT91C_BASE_AIC->AIC_SVR[i] = (unsigned int) defaultIrqHandler; //инициализация вектора IRQ
}
AT91C_BASE_AIC->AIC_SPU = (unsigned int) defaultSpuriousHandler;
// Unstack nested interrupts
for (i = 0; i < 8 ; i++) {
AT91C_BASE_AIC->AIC_EOICR = 0;
}
Далее настройка прерывания PIT
CODE
void ConfigurePit(void)
{
/настройка PIT на 1мС
PIT_Init(PIT_PERIOD, BOARD_MCK / 1000000); /
//Настройка прерывния PIT
AT91C_BASE_AIC->AIC_IDCR = 1 << AT91C_ID_SYS; //запрет прерывания от SYS (PIT)
// Configure mode and handler
AT91C_BASE_AIC->AIC_SMR[source] = AT91C_AIC_PRIOR_LOWEST; //наинизший приоритет (0)
AT91C_BASE_AIC->AIC_SVR[source] = (unsigned int) ISR_Pit; //вектор прерывания - ISR_Pit()
// Очистка прерывания
AT91C_BASE_AIC->AIC_ICCR = 1 << AT91C_ID_SYS;
//разрешаем прерывание от SYS (PIT)
AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_SYS;
//разрешение прерывания PIT
AT91C_BASE_PITC->PITC_PIMR |= AT91C_PITC_PITIEN;
//разрешаем PIT
AT91C_BASE_PITC->PITC_PIMR |= AT91C_PITC_PITEN;
}
Собственно сам обработчика прерывания
Код
void ISR_Pit(void)
{
unsigned int status;
// Read the PIT status register
status = AT91C_BASE_PITC->PITC_PISR & AT91C_PITC_PITS;
if (status != 0) {
// 1 = The Periodic Interval timer has reached PIV since the last read of PIT_PIVR.
// Read the PIVR to acknowledge interrupt and get number of ticks
//Returns the number of occurrences of periodic intervals since the last read of PIT_PIVR.
timestamp += (PIT_GetPIVR() >> 20);
}
}
кроме того в стартапе есть такой код
Код
/*
Handles incoming interrupt requests by branching to the corresponding
handler, as defined in the AIC. Supports interrupt nesting.
*/
irqHandler:
/* Save interrupt context on the stack to allow nesting */
SUB lr, lr, #4
STMFD sp!, {lr}
MRS lr, SPSR
STMFD sp!, {r0, lr}
/* Write in the IVR to support Protect Mode */
LDR lr, =AT91C_BASE_AIC
LDR r0, [r14, #AIC_IVR]
STR lr, [r14, #AIC_IVR]
/* Branch to interrupt handler in Supervisor mode */
MSR CPSR_c, #ARM_MODE_SYS
STMFD sp!, {r1-r3, r4, r12, lr}
MOV lr, pc
BX r0
LDMIA sp!, {r1-r3, r4, r12, lr}
MSR CPSR_c, #ARM_MODE_IRQ | I_BIT
/* Acknowledge interrupt */
LDR lr, =AT91C_BASE_AIC
STR lr, [r14, #AIC_EOICR]
/* Restore interrupt context and branch back to calling code */
LDMIA sp!, {r0, lr}
MSR SPSR_cxsf, lr
LDMIA sp!, {pc}^
Я запутался в логике работы AIC. При возникновении прерывания IRQ процессор начинает исполнять код irqHandler. Вектор прерывания берётся из AIC_IVR. Идёт исполнение по этому вектору (в моём случае должна выполниться функция ISR_Pit()). После исполнения идёт возврат в irqHandler. Далее процедура выхода из прерывания. Как я предполагаю собственно всё.... Далее ждём следующего прерывания.