Цитата(Pat @ Sep 24 2005, 22:13)
Вообще, что то странное присходит. Для того что бы заработали сами прерывания иногда приходится загрузить бинарник вначале в FLASH а потом в RAM. Иногда все работает без этого шаманства.
Может кто сталкивался с этой проблемой.
Отвечу сам себе.
В EWARM IAR4.30 для загрузки RAM и FLASH в AT91SAM7xxx используются макросы SAM.mac и SAM_RAM.mac.
В них производятся некоторые процедуры инициализации перед загрузкой кристалла.
Одна из них сброс AIC (контроллер прерываний). Вот она собственно
//-------------------------------
// Normally, the code is executed only if a reset has been actually performed.
// So, the AIC initialization resumes at setting up the default vectors.
//-----------------------------------------------------------------------------
AIC()
{
// Mask All interrupt pAic->AIC_IDCR = 0xFFFFFFFF;
__writeMemory32(0xffffffff,0xFFFFF124,"Memory");
__writeMemory32(0xffffffff,0xFFFFF128,"Memory");
// disable peripheral clock Peripheral Clock Disable Register
__writeMemory32(0xffffffff,0xFFFFFC14,"Memory");
// #define AT91C_TC0_SR ((AT91_REG *) 0xFFFA0020) // (TC0) Status Register
// #define AT91C_TC1_SR ((AT91_REG *) 0xFFFA0060) // (TC1) Status Register
// #define AT91C_TC2_SR ((AT91_REG *) 0xFFFA00A0) // (TC2) Status Register
__readMemory32(0xFFFA0020,"Memory");
__readMemory32(0xFFFA0060,"Memory");
__readMemory32(0xFFFA00A0,"Memory");
// Ниже по тексту собственно основная проблема и живет,
// в AIC есть регистр AIC_EOICR который WRITE-ONLY и служит он для(цитирую):
// The End of Interrupt Command Register is used by the interrupt routine to indicate
// that the interrupt treatment is complete.
// Any value can be written because it is only necessary to make a write to this register
// location to signal the end of interrupt treatment.
for (__mac_i=0;__mac_i < 8; __mac_i++)
{
// Но в иаровских мак файлах почему то производится чтение из этого регистра
// __mac_pt = __readMemory32(0xFFFFF130,"Memory"); // __mac_pt = AIC_EOICR
// У меня аномальное поведение прерываний после загрузки, вылечилось
// нижней строкой
// теперь после загрузки с прерываниями все ОК
__writeMemory32(0xffffffff,0xFFFFF130,"Memory"); // AIC_EOICR = 0xFFFFFFFF
}
__message "------------------------------- AIC 2 INIT ---------------------------------------------";
}
Проблему так же можно решить, вставив в свой код функцию
сброса AIC
#include "include/AT91SAM7S32.h"
void reset_AIC(void)
//-----------------------------------------------------------------------------
// Сброс Interrupt Controller AIC
//-----------------------------------------------------------------------------
void reset_AIC(void)
{
unsigned int i;
// Отключаем все источники прерываний
AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF;
// Очищаем все прерывания
AT91C_BASE_AIC->AIC_ICCR = 0xFFFFFFFF;
// Отключаем периферию от системного клока
AT91C_BASE_PMC->PMC_PCDR = 0xFFFFFFFF;
// Сбрасываем флаги таймеров
i = AT91C_BASE_TC0->TC_SR;
i = AT91C_BASE_TC1->TC_SR;
i = AT91C_BASE_TC0->TC_SR;
for (i=0;i < 8;i++)
{
// Все прерывания закончены
AT91C_BASE_AIC->AIC_EOICR = 0xFFFFFFFF;
}
}
p.s. Проблемма с работой брейк поинтов в прерываниях ИАР все равно остается. Не всегда почему то останавливается программа по бряку.