Есть два таймера. Т0 просто отсчитывает миллисекундные интервалы. Т1 должен формировать с помощью компараторов (MATCH) довольно сложную последовательность синхроимпульсов, но в примере он просто крутится и дергает ногу. Если прерывания от обоих таймеров заведены на IRQ, то все нормально работает. Если прерывания от Т1 заводятся на FIQ, а прерывание от Т0 запрещено (других прерываний вообще нет), то тоже все работает. А вот если разрешить и IRQ и FIQ, то программа работает долю секунды и «улетает». Если отладчик остановить, то РС оказывается в районе 0х00000004 - 0х00000010.
Работаю в ИАР 4.41. Проект размещается в RAM. Стартап из какого-то ИАРовского примера без доработок, инициализация стека FIQ там вроде есть. Код инициализации VIC и обработчиков также взят из примеров.Вот куски программы:
/////////////////////////////////////
void InerruptInit(void)
{
VICIntEnClear = 0xFFFFFFFF;
VICProtection = 0;
VICVectAddr = 0;
VICProtection = 0;
//VICIntSelect &= (1<VICIntSelect |= (1<VICVectAddr0 = (unsigned int)&TIMER1_ISR;
VICVectCntl0 = 0x20 | VIC_TIMER1;
VICIntEnable |= (1<VICIntSelect &= ~(1<VICVectAddr2 = (unsigned int)&TIMER0_ISR;
VICVectCntl2 = 0x20 | VIC_TIMER0;
VICIntEnable |= (1<}
/////////////////////////////////////
#pragma vector=0x18
__irq __arm void IRQ_ISR_Handler (void)
{
void (*interrupt_function)();
unsigned int vector;
vector = VICVectAddr;
interrupt_function = (void(*)())vector;
(*interrupt_function)();
VICVectAddr = 0;
}
////////////////////////////////////
#pragma vector=0x1c
__fiq __arm void FIQ_ISR_Handler (void)
{
TIMER1_ISR();
}
///////////////////////////////////
void TIMER0_ISR()
{
T0IR = 0x0f;
IO0PIN ^= (1<<20);
Delay (100);
}
//////////////////////////////////
void TIMER1_ISR()
{
T1IR = 0x0f;
IO0PIN ^= (1<<21);
}
//////////////////////////////////
void main()
{
CLOCK_Init();
MEM_Init();
InerruptInit();
IOPinInit();
T0TCR = 0;
T0IR=0xFF;
T0MR0=SysTimerCnt;
T0MCR_bit.MR0INT=1;
T0MCR_bit.MR0RES=1;
T1TCR = 0;
T1IR=0xFF;
T1MR0=3000;
T1MCR_bit.MR0INT=1;
T1MCR_bit.MR0RES=1;
__enable_interrupt(); // Global interrupt enable
T0TCR = 1;
T1TCR = 1;
while(TRUE)
{
IO0PIN ^= (1<<19);
Delay (100);
}
}