Пытаюсь вызывать FIQ по перемене состояния пина PIO, вываливаюсь в prefetch abort
Настраиваю так:
Код
/* Configure CPLD_DATA_RDY input - clear output, configure input and enable glitch filter */
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, CPLD_DATA_RDY);
AT91F_PIO_CfgInput(AT91C_BASE_PIOA, CPLD_DATA_RDY);
AT91F_PIO_InputFilterEnable(AT91C_BASE_PIOA, CPLD_DATA_RDY);
/* Enable PIOA interrupt on CPLD_DATA_RDY change */
AT91F_PIO_InterruptEnable(AT91C_BASE_PIOA,CPLD_DATA_RDY);
/* Configure FIQ */
AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_FIQ,
0, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, (void (*)( void ))FIQ_handler);
/* enable fast forcing for PIOA interrupt */
*AT91C_AIC_FFER = (1 << AT91C_ID_PIOA);
/* Enable PIOA interrupt in AIC */
AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_PIOA);
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, CPLD_DATA_RDY);
AT91F_PIO_CfgInput(AT91C_BASE_PIOA, CPLD_DATA_RDY);
AT91F_PIO_InputFilterEnable(AT91C_BASE_PIOA, CPLD_DATA_RDY);
/* Enable PIOA interrupt on CPLD_DATA_RDY change */
AT91F_PIO_InterruptEnable(AT91C_BASE_PIOA,CPLD_DATA_RDY);
/* Configure FIQ */
AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_FIQ,
0, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, (void (*)( void ))FIQ_handler);
/* enable fast forcing for PIOA interrupt */
*AT91C_AIC_FFER = (1 << AT91C_ID_PIOA);
/* Enable PIOA interrupt in AIC */
AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_PIOA);
Обработчик вот такой:
Код
__arm __fiq void FIQ_handler(void)
{
unsigned portLONG pio;
/* Get the byte and confirm reseption */
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,CPLD_CNFRM);
pio = AT91F_PIO_GetInput(AT91C_BASE_PIOA);
/* Put data into the buffer */
CPLD_Buf[CPLD_BufHead] = pio;
CPLD_BufHead++;
CPLD_BufHead &= CPLD_BUF_LENGTH;
/* */
AT91F_PIO_SetOutput(AT91C_BASE_PIOA,CPLD_CNFRM);
FIQCounter++;
/* Clear interrupt cause */
pio = AT91C_BASE_PIOA->PIO_ISR;
pio = pio;
AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC);
}
{
unsigned portLONG pio;
/* Get the byte and confirm reseption */
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,CPLD_CNFRM);
pio = AT91F_PIO_GetInput(AT91C_BASE_PIOA);
/* Put data into the buffer */
CPLD_Buf[CPLD_BufHead] = pio;
CPLD_BufHead++;
CPLD_BufHead &= CPLD_BUF_LENGTH;
/* */
AT91F_PIO_SetOutput(AT91C_BASE_PIOA,CPLD_CNFRM);
FIQCounter++;
/* Clear interrupt cause */
pio = AT91C_BASE_PIOA->PIO_ISR;
pio = pio;
AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC);
}
В недрах FreeRTOS __disable_interrupt весь поменян на portDISABLE_INTERRUPTS:
Код
__arm __interwork static inline __disable_IRQ(void)
{
unsigned long tmp;
while (!((tmp=__get_CPSR()) & (1<<7)))
{
__set_CPSR(tmp | (1<<7));
}
}
#define portDISABLE_INTERRUPTS() __disable_IRQ()
{
unsigned long tmp;
while (!((tmp=__get_CPSR()) & (1<<7)))
{
__set_CPSR(tmp | (1<<7));
}
}
#define portDISABLE_INTERRUPTS() __disable_IRQ()
Брейкпоинт на входе в обработчик FIQ не срабатывает, если я устраняю источник прерывания, то все работает штатно, без вываливания. В
Подскажите, в какую сторону копать?
Заранее спасибо!