Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: помогите с прошивкой флеш в sam64s
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
SpiritDance
Вобщем был уже как-то этот глюк но при невыясненных обстоятельствах прошел. Асейчас опять всплыл.
Исходные данные для прошивки принимаются по усарт. потом происходит прошивка с помощью вот такого кода
Код
__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;  
}

Код
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

При этом происходит какой-то непонятный сбой - процессор то ли не выходит из этой функции то-ли остается висеть черте-где (последнее показывает отладчик но я не уверен что это правда). При этом происходит это не постоянно иногда, 50/50 процессор остается в нормальном состоянии. Проверял такое на 4-х процессорах на 2 различных по топологии платах. Флеш не залочена. Когда смотрим отладчиком содержимое флеш то все впорядке - все записывается куда надо.
При этом я помню что когда работал с этой подпрограммой через run отладчика то все было нормально всегда. Может какие-то настройки флешь? Но ини вроде не должны играть роли.
Вобщем непонятно что это wacko.gif , просьба помочь.
Andy Great
enable_interrupts() затирается?
SpiritDance
Не понял. Что значит затирается? Суть не в том что прерывания не работают больше, суть в том что процессор отказывается потом светодиодом моргать. причем не всегда. То есть процессор судя по всему отказывается из флеш работать дальше.
DASM
что у нас в FMR ? У меня были грабли с этим, в нем все дело оказалось. Вот мой кусок записи из старых мтликов
Код
#ifdef FlashRelease
__ramfunc
#endif
bool WritePage (int adr, int *pbuf)
{

        int *pflash = (int *)adr;
        int page = adr >> 7;
        int region = (adr >> 12);

        if (AT91C_BASE_MC->MC_FSR & (region << 16))
        {
                // lock set
                AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN)&(50 <<16)) | AT91C_MC_FWS_1FWS;
                AT91C_BASE_MC->MC_FCR = (0x5A << 24) | (region << 8 ) |AT91C_MC_FCMD_UNLOCK;
        }
        while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY))
               ;


        for (int i = 0; i < PAGE_SIZE; i++)
        {
                *(pflash + i ) = *(pbuf + i);
        }
         AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN)&(100 <<16)) | AT91C_MC_FWS_1FWS;
        AT91C_BASE_MC->MC_FCR = (0x5A << 24) | (page << 8 ) |AT91C_MC_FCMD_START_PROG;
        while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY))
               ;
        return true;
}

Что к чему тут уже не помню, больше года прошло, но это работает
SpiritDance
DASM
Спасибо, буду разбиратся.
SpiritDance
Заработало вроде. Вот с таким кодом. Дело было действительно в регистре FMR. Он в программе не трогался нигде ввообще то есть в нем значение по умолчанию. Интересно какое оно? У меня отлачика подрукой нет сейчас а в даташите что-то не нашел. Gодозреваю по умолчанию FWS=0.
Код
/*------------------------------------------------------------------------------------------------*/
__arm __ramfunc t_uint8  write_page_EFC(t_uint32 Adress, t_uint32 *Buffer)
{
    t_uint16 i;
    t_uint16 tempFMR = AT91C_BASE_MC->MC_FMR;

    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_FMR = ((100 <<16)&(AT91C_MC_FMCN)) | AT91C_MC_FWS_1FWS;
    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;
    }
    
    AT91C_BASE_MC->MC_FMR = tempFMR;
//    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;  
}
/*------------------------------------------------------------------------------------------------*/

Интересно а что флеш может программироватся без проблем только при FWS=1 и 100мкс FMSC и ни при каких больше? Странно.
DASM ВЫ эти значения подбирали или откуда-то взяли?
Andy Great
Цитата
Не понял. Что значит затирается?

Я имел в виду, что возможно затирается сегмент кода с функцией enable_interrupts()
DASM
Значения из даташита, причем одно из них меняли (в первой ревизии было что-то там 1 мкс, в следущей 1.5 мкс (уже не помню на что) - поглядите сами. Мои значения кажется чуть больше даташитных (главное чтобы не меньше было)
SpiritDance
Цитата(Andy Great @ Sep 19 2006, 15:29) *
Я имел в виду, что возможно затирается сегмент кода с функцией enable_interrupts()

А... То есть если я скажем ошибся в другом месте с указателем и изгадил всю RAM? Причем так что в сегмент кодов залез? Симптомы не совсем совпадают. Да и кода у меня такого нет.

Цитата
• FMCN: Flash Microsecond Cycle Number
Before writing Non Volatile Memory bits (Lock bits, General Purpose NVM bit and Security bits), this field must be set to the
number of Master Clock cycles in one microsecond.
When writing the rest of the Flash, this field defines the number of Master Clock cycles in 1.5 microseconds. This number
must be rounded up.
Warning: The value 0 is only allowed for a master clock period superior to 30 microseconds.
Warning: In order to guarantee valid operations on the flash memory, the field Flash Microsecond Cycle Number (FMCN)
must be correctly programmed.

Насколько я понимаю FWS вобщем не причем, главное задать значение FMCN не меньшее чем округленное количество тактов MCK умещающееся в интервале 1.5 сек.

Вобщем спасибо всем.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.