Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LPC2478 IAP problem
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
ar__systems
Есть проблемы с со стиранием флэш памяти.

Вызываю Prepare Block, Erase. Обе возвращают success, но память может быть иногда ВООБЩЕ не стерта. То есть, иногда она выглядит как недотертая (0xFFBFFFFF или что-то подобное в отдельных местах блока), но иногда она полностью не тронутая.

Пробовал ставить blank check и повторять стирание, до 10 раз. Это помогает в тех случаях, когда она недотерта, но иногда даже после 10 стираний она совершенно не тронута.

Если вручную стереть блок (FlashMagic) то запись всегда работает надежно.

Кто-то видел что-то подобное?
HARMHARM
Проверьте значение частоты, которое Вы передаёте в функцию IAP.
ar__systems
Цитата(HARMHARM @ Apr 3 2009, 11:04) *
Проверьте значение частоты, которое Вы передаёте в функцию IAP.

Проверил, передаю 72000 (x Khz).
HARMHARM
Цитата(ar__systems @ Apr 3 2009, 19:12) *
Проверил, передаю 72000 (x Khz).

Хм, если у вас контроллер работает на 72 МГц, даже не знаю что и посоветовать...
Разве что проверить типы данных.
Приведите код...
ar__systems
Цитата(HARMHARM @ Apr 3 2009, 11:25) *
Хм, если у вас контроллер работает на 72 МГц, даже не знаю что и посоветовать...
Разве что проверить типы данных.
Приведите код...


Код скопировал из даташит. DISABLE/ENABLE INTs добавил только что, правда. Сейчас с ними проверяю.
Код
typedef void (*IAP)(unsigned int [],unsigned int[]);
#define IAP_LOCATION 0x7ffffff1

#define MAX_ERASE_ATTEMPT 10

int WriteToFlash(void * ptr, int Size) {
    //     
    const IAP iap_entry = (IAP) IAP_LOCATION;
    unsigned long command[5];
    unsigned long result[3] = {0xFF,0xFF,0xFF};

    for ( int EraseCount = 0; EraseCount < MAX_ERASE_ATTEMPT; EraseCount++ ) {
        //========================================================
        // Prepare Sector for Write
        command[0] = 50;
        command[1] = 0x1B;
        command[2] = 0x1B;
        
        DISABLE_INTERRUPTS;        
        iap_entry(command,result);
        ENABLE_INTERRUPTS;        
        if (  result[0] != 0 )
            return result[0];
        
        //=========================================================
        // Erase
        
        uart1Puts("Erasing...\n\r");

        DISABLE_INTERRUPTS;        
        command[0] = 52;
        command[1] = 0x1B;
        command[2] = 0x1B;
        command[4] = 72000; //150000;
        iap_entry(command,result);
        ENABLE_INTERRUPTS;        
    
        if (  result[0] != 0 )
            return result[0];

        //=========================================================
        // BlankCheck
        command[0] = 53;
        command[1] = 0x1B;
        command[2] = 0x1B;
        command[4] = 72000;  // 150000;
        iap_entry(command,result);
        if (  result[0] == 0 )
            break;
        uart1Puts("Blank Check failed...\n\r");
    };    

    if (  result[0] != 0 )
        return result[0];

    //=========================================================
    // Prepare Sector for Write

    command[0] = 50;
    command[1] = 0x1B;
    command[2] = 0x1B;
    
    iap_entry(command,result);
    if (  result[0] != 0 )
        return result[0];

    //=========================================================
    // Copy RAM to FLASH
         
    command[0] = 51;
    command[1] = (unsigned long) PersistentData;
    command[2] = (unsigned long) ptr;
    command[3] = PersistBlockSize;
    command[4] = 72000;

    result[0] = result[1] = result[2] = 0xFF;
    
    iap_entry(command,result);
    return result[0];
};
HARMHARM
Цитата(ar__systems @ Apr 3 2009, 19:34) *
Код скопировал из даташит. DISABLE/ENABLE INTs добавил только что, правда. Сейчас с ними проверяю.

Прерывания принципиально могут работать из RAM. Разница в моём коде только в том, что неиспользуемые параметры command обнуляю. Ну и прерывания надо запрещать при всех вызовах IAP smile.gif Кстати, из User Mode прерывания не выключатся.
Могу только посоветовать проверить инициализацию источников тактирования PLL и т.п.
Попробуйте дать меньшее значение частоты в функцию, имхо при стирании оно используется лишь для вычисления задержки.
Померяйте время, которое занимает функция стирания - должно быть около 400 мс.
Увы, идей больше нету.
Приложил сборник идей по IAP, надерганных неизвестно откуда, посмотрите smile.gif
У меня работает железно, каждый раз, не видел ни единого сбоя.
ar__systems
Damn it! Частота процессора не в то поле была записана. Убил два дня! smile.gif
Кстати, а откуда время 400mS, из какого документа? Я смотрю UM10237 и еще один, без номера, там такого параметра нет.

Код
       // Erase
        
        uart1Puts("Erasing...\n\r");

        DISABLE_INTERRUPTS;        
        command[0] = 52;
        command[1] = 0x1B;
        command[2] = 0x1B;
        command[   4   ] = 72000; //150000;
HARMHARM
Цитата(ar__systems @ Apr 3 2009, 22:17) *
Damn it! Частота процессора не в то поле была записана. Убил два дня! smile.gif

Я тоже проглядел... Глаз замылился biggrin.gif
Цитата
Кстати, а откуда время 400mS, из какого документа? Я смотрю UM10237 и еще один, без номера, там такого параметра нет.

Каюсь, я LPC24xx не использовал. Это из мануала на LPC23xx. Уверен, что справедливо и для LPC24xx.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.