Исходные данные для прошивки принимаются по усарт. потом происходит прошивка с помощью вот такого кода
Код
__arm __ramfunc t_uint8 write_page_EFC(t_uint32 Adress, t_uint32 *Buffer)
{
t_uint16 i;
Adress &= ~(FLASH_PAGESIZE - 1);
disable_interrupts();
for(i = 0; i < (FLASH_PAGESIZE/4); ++i)
{
*((volatile t_uint32*)Adress + i) = *(Buffer + i);
}
while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY))
{
continue;
}
AT91C_BASE_MC->MC_FCR = FLASH_KEY
|
AT91C_MC_FCMD_START_PROG
|
( ((Adress - FLASH_START) / FLASH_PAGESIZE) << 8 );
while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY))
{
continue;
}
enable_interrupts();
if (AT91C_BASE_MC->MC_FCR & AT91C_MC_PROGE)
{
return 0;
}
return 1;
}
{
t_uint16 i;
Adress &= ~(FLASH_PAGESIZE - 1);
disable_interrupts();
for(i = 0; i < (FLASH_PAGESIZE/4); ++i)
{
*((volatile t_uint32*)Adress + i) = *(Buffer + i);
}
while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY))
{
continue;
}
AT91C_BASE_MC->MC_FCR = FLASH_KEY
|
AT91C_MC_FCMD_START_PROG
|
( ((Adress - FLASH_START) / FLASH_PAGESIZE) << 8 );
while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY))
{
continue;
}
enable_interrupts();
if (AT91C_BASE_MC->MC_FCR & AT91C_MC_PROGE)
{
return 0;
}
return 1;
}
Код
INT_DISABLE_MASK EQU 0x000000C0
RSEG CODE_I:CODE:NOROOT(2)
CODE32
PUBLIC disable_interrupts
PUBLIC enable_interrupts
enable_interrupts:
;Çàïèñàòü 0 â áèòû I è F ðåãèñòðà CPSR, ÷òîáû ðàçðåøèòü ïðåðûâàíèÿ
mrs r0, cpsr ;ñ÷èòûâàåì çíà÷åíèå ðåãèñòðà ñòàòóñà
mvn r1, #INT_DISABLE_MASK ;â ñ÷èòàííîì çíà÷åíèè ñáðàñûâàåì áèòû
and r0, r0, r1 ;FIQ disable è IRQ disable
msr cpsr_c, r0 ;çàïèñûâåì íîâîå çíà÷åíèå â ðåãèñòð ñòàòóñà -
bx lr ;ïðåðûâàíèÿ FIQ è IRQ ðàçðåøåíû
disable_interrupts:
;Çàïèñàòü 1 â áèòû I è F ðåãèñòðà CPSR, ÷òîáû çàïðåòèòü ïðåðûâàíèÿ
mrs r0, cpsr ;ñ÷èòûâàåì çíà÷åíèå ðåãèñòðà ñòàòóñà
orr r0, r0, #INT_DISABLE_MASK ;â ñ÷èòàííîì çíà÷åíèè ñáðàñûâàåì áèòû
;FIQ disable è IRQ disable
msr cpsr_c, r0 ;çàïèñûâåì íîâîå çíà÷åíèå â ðåãèñòð ñòàòóñà -
bx lr ;ïðåðûâàíèÿ FIQ è IRQ çàïðåùåíû
END
RSEG CODE_I:CODE:NOROOT(2)
CODE32
PUBLIC disable_interrupts
PUBLIC enable_interrupts
enable_interrupts:
;Çàïèñàòü 0 â áèòû I è F ðåãèñòðà CPSR, ÷òîáû ðàçðåøèòü ïðåðûâàíèÿ
mrs r0, cpsr ;ñ÷èòûâàåì çíà÷åíèå ðåãèñòðà ñòàòóñà
mvn r1, #INT_DISABLE_MASK ;â ñ÷èòàííîì çíà÷åíèè ñáðàñûâàåì áèòû
and r0, r0, r1 ;FIQ disable è IRQ disable
msr cpsr_c, r0 ;çàïèñûâåì íîâîå çíà÷åíèå â ðåãèñòð ñòàòóñà -
bx lr ;ïðåðûâàíèÿ FIQ è IRQ ðàçðåøåíû
disable_interrupts:
;Çàïèñàòü 1 â áèòû I è F ðåãèñòðà CPSR, ÷òîáû çàïðåòèòü ïðåðûâàíèÿ
mrs r0, cpsr ;ñ÷èòûâàåì çíà÷åíèå ðåãèñòðà ñòàòóñà
orr r0, r0, #INT_DISABLE_MASK ;â ñ÷èòàííîì çíà÷åíèè ñáðàñûâàåì áèòû
;FIQ disable è IRQ disable
msr cpsr_c, r0 ;çàïèñûâåì íîâîå çíà÷åíèå â ðåãèñòð ñòàòóñà -
bx lr ;ïðåðûâàíèÿ FIQ è IRQ çàïðåùåíû
END
При этом происходит какой-то непонятный сбой - процессор то ли не выходит из этой функции то-ли остается висеть черте-где (последнее показывает отладчик но я не уверен что это правда). При этом происходит это не постоянно иногда, 50/50 процессор остается в нормальном состоянии. Проверял такое на 4-х процессорах на 2 различных по топологии платах. Флеш не залочена. Когда смотрим отладчиком содержимое флеш то все впорядке - все записывается куда надо.
При этом я помню что когда работал с этой подпрограммой через run отладчика то все было нормально всегда. Может какие-то настройки флешь? Но ини вроде не должны играть роли.
Вобщем непонятно что это
