Misile_Inc 0 4 июля, 2012 Опубликовано 4 июля, 2012 (изменено) · Жалоба Доброго времени суток. Есть проект, в котором не работает запись данных во флеш. Процедура записи такая: #define PSEE 1 // PSEE: Program Store Erase Enable #define PSWE 0 // PSWE: Program Store Write Enable #define FLASH_UNLOCK_CODE_1 0xA5 #define FLASH_UNLOCK_CODE_2 0xF1 void flash_write_byte(uint16 ptr, uint8 byte) { bit EA_save=1; uint8 xdata * data pwrite; volatile uint8 i; volatile uint8 j; { EA_save = EA; DISABLE_INTERRUPT(); VDM0CN = (1<<VDMEN); // enable VDD monitor RSTSRC = (1<<PORSF); // enable VDD monitor as a reset source // Unlock flash for modify // PSCTL |= (1<<PSWE); // бит PSWE=1; PSCTL &=~ (1<<PSEE); // бит PSEE=0; FLKEY = FLASH_UNLOCK_CODE_1; FLKEY = FLASH_UNLOCK_CODE_2; VDM0CN = (1<<VDMEN); // enable VDD monitor RSTSRC = (1<<PORSF); // enable VDD monitor as a reset source pwrite = (uint8 xdata*) ptr; *pwrite = byte; // Lock flash for modify PSCTL &= (~ (1<<PSWE)); //бит PSWE=0; for (i = 0; i < 0xff; i++) { for (j = 0; j < 10; j++) { } } //возвращаем состояние контроллера прерываний на момент до запрещения прерываний EA = EA_save; } } Используется так: #define SKEY_ADRESS (0x0C00)// Указатель на серийный номер S-KEY #define SKEY_LENGTH_BYTE 32 // длина серийного номера в байтах uint8 xdata skey_buffer[sET_SKEY_PACKET_LENGTH_BYTE + 1]; uint8 i; // Перезапись из временного буфера в ПЗУ for (i = 0; i < SKEY_LENGTH_BYTE + 1; i++) { flash_write_byte(SKEY_ADRESS + i, skey_buffer[i]); } Среда разработки Keil. Что программист делает не так? Сравнил с документацией, вроде все удовлетворяет требованиям. Спасибо. Изменено 4 июля, 2012 пользователем Misile_Inc Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Edit2007 3 4 июля, 2012 Опубликовано 4 июля, 2012 · Жалоба В примере от SiLabs (an201) сперва прописываются ключи, затем устанавливается значение PSWE. может и не принципиально но факт. Второй момент. Перед записью необходимо стереть страницу. В коде этого не видно, но надеюсь что выполняется. В конце функции записи есть пустой вложенный цикл. Он не нужен.На время записи работа ядра приостанавливается (на 040 и 582 это так, не думаю что в этом семействе иначе) an201.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Misile_Inc 0 4 июля, 2012 Опубликовано 4 июля, 2012 · Жалоба редактор, спасибо, этот файл у меня есть. Пустой цикл уже я добавлял, пытаясь разобраться. Стирание производится на всякий случай (уже я добавил) . Но не знаю, насколько успешно- там пустая область. Порядок следования ключей и установки бит тоже менял. В даташите порядок такой: 11.1.3. FLASH Write Procedure FLASH bytes are programmed by software with the following sequence: Step 1. Disable interrupts (recommended). Step 2. Erase the 512-byte FLASH page containing the target location, as described in Section 11.1.2. Step 3. Set the PSWE bit (register PSCTL). Step 4. Clear the PSEE bit (register PSCTL). Step 5. Write the first key code to FLKEY: 0xA5. Step 6. Write the second key code to FLKEY: 0xF1. Step 7. Using the MOVX instruction, write a single data byte to the desired location within the 512-byte sector. Step 8. Clear the PSWE bit. Так что, видимо, не важен порядок. Пока что не пишется.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Edit2007 3 4 июля, 2012 Опубликовано 4 июля, 2012 · Жалоба Может попробовать пример производителя один в один без масок, сдвигов, дефайнов ?? Как определяете что не пишется??? Если смотреть поле Memory в кейле, то оно отобразит изменения только после перезагрузки (отключить отладчик, подключить отладчик) Если код выполняется целиком, то последовательность операций неверная. Был еще такой прецедент: при записи во флешь происходил сброс МК. Похоже не хватало тока. Вылечили тем что на время записи отключили все перефирийные модули для снижения потребления. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Misile_Inc 0 4 июля, 2012 Опубликовано 4 июля, 2012 · Жалоба Нашел "закладку" в стартап- коде STARTUP1: ; при записи некорректных значений в регистр FLKEY блокируется ; запись и стирание флеш, чего и добиваемся MOV FLKEY, #1 MOV FLKEY, #1 Потому и не работало. Спасибо за внимание! Может быть подскажете, как из программы на языке Си получить адрес метки "STARTUP1" (как в приведенном выше коде)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Misile_Inc 0 4 июля, 2012 Опубликовано 4 июля, 2012 · Жалоба Решено: В ассемблере добавляем определение публичной функции с именем метки: PUBLIC STARTUP1 В Си подключаем как функцию: extern void STARTUP1(); тогда адрес команды равен указателю на функцию: (uint16) STARTUP1; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Misile_Inc 0 4 июля, 2012 Опубликовано 4 июля, 2012 · Жалоба Решено: В ассемблере добавляем определение публичной функции с именем метки: PUBLIC STARTUP1 В Си подключаем как функцию: extern void STARTUP1(); тогда адрес команды равен указателю на функцию: (uint16) STARTUP1; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться