Доброго времени суток!
Не работают прерывания на AT91SAM9XE512 - ни по таймеру, ни по USART.
Инициализация проходит нормально. Программа выходит в главный цикл. Можно управлять портами - включать/выключать светодиоды. Таймер работает.
Программирую микроконтроллер через H-Jtag. Программа хранится во внутренней flash памяти.
flash.lds, board_cstartup.S, board_lowlevel.c, board_memories.c взяты из примеров ATMEL. В board_lowlevel.c отменен Remap. board_memories.c скорректирован с учетом размера используемой памяти.
------------------------------------------------------------------------------- обработка прерываний в board_cstartup.S
//------------------------------------------------------------------------------ /// 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, [lr, #AIC_IVR] str lr, [lr, #AIC_IVR]
/* Branch to interrupt handler in Supervisor mode */ msr CPSR_c, #ARM_MODE_SVC stmfd sp!, {r1-r3, r4, r12, lr} blx r0 /* Restore scratch/used registers and LR from User Stack */ /* Disable Interrupt and switch back in IRQ mode */ ldmia sp!, {r1-r3, r4, r12, lr} msr CPSR_c, #ARM_MODE_IRQ | I_BIT
/* Acknowledge interrupt */ ldr lr, =AT91C_BASE_AIC str lr, [lr, #AIC_EOICR]
/* Restore interrupt context and branch back to calling code */ ldmia sp!, {r0, lr} msr SPSR_cxsf, lr ldmia sp!, {pc}^ ------------------------------------------------------------- Инициализация прерываний в board_lowlevel.c
/* Initialize AIC ****************/ AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF; AT91C_BASE_AIC->AIC_SVR[0] = (unsigned int) defaultFiqHandler; for (i = 1; i < 31; i++) {
AT91C_BASE_AIC->AIC_SVR[i] = (unsigned int) defaultIrqHandler; } AT91C_BASE_AIC->AIC_SPU = (unsigned int) defaultSpuriousHandler;
// Unstack nested interrupts for (i = 0; i < 8 ; i++) {
AT91C_BASE_AIC->AIC_EOICR = 0; }
-------------------------------------------- Конфигурация таймера в main.c: --------------------------------------------
//------------------------------------------------------------------------------ /// Configures Timer Counter 2 (TC2) to generate an interrupt every 1s. //------------------------------------------------------------------------------ void ConfigureTc2(void) { unsigned int divv, tcclks;
// Enable TC2 peripheral clock PMC_EnablePeripheral(AT91C_ID_TC2);
/// 1s (= 1Hz) TC_FindMckDivisor(1, BOARD_MCK, &divv, &tcclks); TC_Configure(AT91C_BASE_TC2, tcclks | AT91C_TC_CPCTRG); AT91C_BASE_TC2->TC_RC = (BOARD_MCK / divv)/1; // timerFreq / desiredFreq
// Configure interrupt on RC compare AIC_ConfigureIT(AT91C_ID_TC2, 0, ISR_Tc2); AT91C_BASE_TC2->TC_IER = AT91C_TC_CPCS; AIC_EnableIT(AT91C_ID_TC2); }
Обработка прерывания ------------------------------ void ISR_Tc2(void) { TC_Stop(AT91C_BASE_TC2); // таймер стоп
// Clear status bit to acknowledge interrupt AT91C_BASE_TC2->TC_SR;
PIO_Set(&LED_PWR); // светодиод "Питание ВЫКЛ."
TC_Start(AT91C_BASE_TC2); // таймер старт }
Плата содержит внешнюю память SDRAM и NANDFLASH, но пока они не инициализируются, не используются.
Буду благодарен за любую помощь.
|