Цитата(cornflyer @ Jul 6 2010, 13:37)

во время работы с флешью надо запрещать все прерывания:
__disable_interrupt();
// flash read/write
__enable_interrupt();
причем надо еще добавить в startup.s:
irqHandler:
// spurious interrupts elimination
MRS r14, SPSR ; Abort if IRQ disabled
ANDS r14, r14, #I_BIT ; (IRQ_BIT = 1)
LDMNEFD sp!, {pc}^
на __disable_interrupt(); и __enable_interrupt(); IAR ругается
Я пробовал запрещать прерывания от TWI с помощью:
AT91C_BASE_TWI->TWI_IDR = 0xFFFFFFFF; и IRQ_DisbleIT(AT91C_ID_TWI);
не помогло.
Если не инициализировать TWI - запись и чтение происходят без ошибок. Причём с включенным TWI запись конфигурационного файла до 256 байт тоже проходит без ошибок, больше 256 - виснет и после резета виснет снова, т.е. как будто повреждена основная программа.
Вот код чтения:
Код
char EPR_Rd(unsigned int adr)
{
return((char) *(pfirstPageData+adr));
}
Запись - функция реализующая запись в произвольное место произвольное кол-во байт:
Код
volatile unsigned int firstPageAddress;
volatile unsigned int *pfirstPageData; // Указатель на начало пользовательского блока во FLASH
unsigned int pFlashBuffer[AT91C_IFLASH_PAGE_SIZE / 4]; // Буфер записи страницы flash
void WriteBlokToFlash(unsigned int address_wr, char *data_array_p, unsigned char IndexStartWr, unsigned int CntByte_wr)
{
unsigned int BytesSaved, i;
unsigned char PageNoStart, AddrInPage, i_end;
unsigned char array_idx=0;
BytesSaved=0; // Пока не записали ни одного байта конфигурации
while (BytesSaved!=CntByte_wr) // Сидим в цикле до тех пор пока всё запланированное не будет записано
{
PageNoStart = address_wr/64; // Номер страницы для записи
AddrInPage = address_wr%64; // Адрес внутри страницы
for (i=0;i<64;i++)
pFlashBuffer[i] = *(pfirstPageData+(PageNoStart*64)+i); // Загоняем в буфер текущую страницу флеша
if ((AddrInPage+CntByte_wr)>64) // Если блок не умещается в текущую страницу пишем до конца страницы (64*4байт)
i_end=64;
else // Если умещается - пишем до конца блока
i_end = AddrInPage + CntByte_wr - BytesSaved;
array_idx = IndexStartWr + BytesSaved; // Ставим указатель в массиве данных
for (i=AddrInPage; i<i_end; i++)
{
pFlashBuffer[i]=*(data_array_p+(array_idx++)); // Вносим изменения в буфер записи
BytesSaved++;
}
FLASHD_Write(firstPageAddress+(PageNoStart*AT91C_IFLASH_PAGE_SIZE), pFlashBuffer, AT91C_IFLASH_PAGE_SIZE);
address_wr = address_wr + BytesSaved; // Увеличиваем адрес на кол-во записанных байт
}
}
Щас появилась мысль:
Конфигурация пишется пачками по 62 байта, обычно затык на 5 пакете, т.е. который попадает между 2х страниц, соответственно эта функция произведёт запись 2х страниц почти подряд. Возможно не хватает времени на запись первой страницы, как нужно писать уже вторую? Попробую сделать задержку. Но тогда не понятно почему с отключенным TWI запись и такой конфигурации проходит нормально