Подключил отладчик и стал смотреть прерывания. При первом же срабатывание программа обработки зацикливается и нет возможности выйти.
Доку устал штудировать. Понял только одно, что надо в р-р AIC_IVR писать (хотя по той же доке он только для чтения), но это не помогает.
Стартуп взял из премеров Кейла (board_cstartup_keil.s), так же как и board_lowlevel.c, board_memories.c, sram.sct и sram.ini.
PIT инициализирую так
Код
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (uint)System_Interrupt; // Save the interrupt handler routine pointer
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | (AT91C_AIC_PRIOR_HIGHEST - 2);
AT91C_BASE_AIC->AIC_ICCR = (0x01 << AT91C_ID_SYS); // Clear interrupt
AT91C_BASE_AIC->AIC_IECR = (0x01 << AT91C_ID_SYS); // Enable the interrupt on the interrupt controller
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | (AT91C_AIC_PRIOR_HIGHEST - 2);
AT91C_BASE_AIC->AIC_ICCR = (0x01 << AT91C_ID_SYS); // Clear interrupt
AT91C_BASE_AIC->AIC_IECR = (0x01 << AT91C_ID_SYS); // Enable the interrupt on the interrupt controller
Обработчик:
Код
static void System_Interrupt(void) __irq {
if ( AT91C_BASE_PITC->PITC_PISR & AT91C_PITC_PITS ){ // Read PITC status reg.
// AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_PITC->PITC_PIVR; // Read the PIVR (to clear PISR)
AT91C_BASE_PITC->PITC_PIVR; // Read the PIVR (to clear PISR)
}
AT91C_BASE_AIC->AIC_EOICR = 0x00;
}
if ( AT91C_BASE_PITC->PITC_PISR & AT91C_PITC_PITS ){ // Read PITC status reg.
// AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_PITC->PITC_PIVR; // Read the PIVR (to clear PISR)
AT91C_BASE_PITC->PITC_PIVR; // Read the PIVR (to clear PISR)
}
AT91C_BASE_AIC->AIC_EOICR = 0x00;
}
Где то далеко в памяти сидит инфа, что в обработчике надо работать с контекстом AIC, но как - не знаю.
В board_cstartup_keil.s есть irqHandler
Код
irqHandler
; Save interrupt context on the stack to allow nesting */
SUB lr, lr, #4
STMFD sp!, {lr}
MRS lr, SPSR
STMFD sp!, {r0,r1,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_SVC
STMFD sp!, {r1-r4, r12, lr}
MOV lr, pc
BX r0
; Run fun
LDMIA sp!, {r1-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,r1,lr}
MSR SPSR_cxsf, lr
LDMIA sp!, {pc}^
Здесь, вроде, всё есть для работы с отладчиком, но этот irqHandler почему то не вызывается, вернее работает до ; Run fun, а по выходу из подпрограммы обработки обратно не возвращается - выполняет другой код.
; Save interrupt context on the stack to allow nesting */
SUB lr, lr, #4
STMFD sp!, {lr}
MRS lr, SPSR
STMFD sp!, {r0,r1,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_SVC
STMFD sp!, {r1-r4, r12, lr}
MOV lr, pc
BX r0
; Run fun
LDMIA sp!, {r1-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,r1,lr}
MSR SPSR_cxsf, lr
LDMIA sp!, {pc}^