Здравствуйте!
Пытаюсь перелезть на FreeScale 56F83хх. Сейчас мучаю 56F8357, не пожалел денег купил евалюшн боард, довольно резво запустил проц, наладил с ним связь по UART (даже нашёл и исправил косяк в MC56F35x.h из поставки CodeWarrior).
В общем, процесс освоения проходил легко, пока я не перешёл к теме "хранение данных в Program Flash (pROM)". Для начала решил просто стереть страницу pROM, принялся курить мануалы и писать код. Используется Small Data Model т.к. в перспективе будут использоваться более скромные процессоры (и без Data flash)
Но мне ни как поддаётся стирание стирание флэша. Скачал исходники бутлоадера, оказывается делаю в точности тоже самое, но ... досада флэшка не трётся.
Привожу код и всё что к нему относится, вдруг кто пальцем ткнёт "вот ошибка!", наверняка дело в какой нибудь мелкой "заковыке".
1)Кусок командного файла для линкераMEMORY { .p_interrupts_ROM (RX) : ORIGIN = 0x0000, LENGTH = 0x00A4 #interrupts #small data model used not above 64K flash .p_flash_ROM (RX) : ORIGIN = 0x00A4, LENGTH = 0x0EF5B # 60K words for program ################################################################### # p_DEVICE_CID резервирует сектор идентификатора и калибровочных параметров .p_DEVICE_CID (RX) : ORIGIN = 0x0F000, LENGTH = 0x003FF # 1Kb for identification ################################# SECURE BLOCK ################### # p_SECURE Flash Memory Configuration Fail .p_SECURE (RX) : ORIGIN = 0x1FFF7, LENGTH = 0x00009 ################################################################### .............................................. } .................................. SECTIONS { .............................. .DEVICE_CID : { * (DEVICE_CID.text) } > .p_DEVICE_CID .............................. .SECURE :# обратите внимание флэшка полностью разблокирована { . = 0x1FFF7; # Security Word Lower WRITEH(0x0FFFF); # (SECL_VALUE) . = 0x1FFF8; # Security Word Upper WRITEH(0x0FFFF); # (SECH_VALUE) . = 0x1FFF9; # BOOT Protection Bytes WRITEH(0x0FFFF); # (PROTB_VALUE) . = 0x1FFFA; # PROGRAM Protection Bytes WRITEH(0x0FFFF); # (PROT_BANK0_VALUE) . = 0x1FFFB; # DATA Protection Bytes WRITEH(0x0FFFF); # (PROT_BANK1_VALUE) . = 0x1FFFC; # Backdoor Comparsion Key0 WRITEH(0x0FFFF); # (BACK_KEY_0_VALUE) . = 0x1FFFD; # Backdoor Comparsion Key1 WRITEH(0x0FFFF); # (BACK_KEY_1_VALUE) . = 0x1FFFE; # Backdoor Comparsion Key2 WRITEH(0x0FFFF); # (BACK_KEY_2_VALUE) . = 0x1FFFF; # Backdoor Comparsion Key3 WRITEH(0x0FFFF); # (BACK_KEY_3_VALUE) } > .p_SECURE
2) а это FConstData.asm собственно содержимое подопытного сектора ;*************************************************** SECTION DEVICE_CID org p: GLOBAL FHellow FHellow: DCBR 5,"1234",0 DCBR "help me please",0 помогите мне ENDSECEND ;***************************************************
3) main.c по возможности только то что относится к делу#include "MC56F835x.h"
extern word Hellow;
//************* MAIN ****************** int main(void) { *(word*) FMCLKD = 0x53;// Инициализация Flash. Инициализировать генератор! FlashWrite ( (dword) &Hellow, j, 100); asm (bfclr #$0300,sr); //enable all interrupts while (1){} }
typedef word TBuff512KWords [512]; typedef byte TBuff1KBYTES [1024];
static TBuff512KWords FlashTmpBuff;
typedef struct { //описание флеш-памяти содержимое которой требуется изменить uint FlashPageSize; //размер страницы words uint FlashPageNumber; //номер страницы uint FlashPageOffset; //смещение ADDR относительно начала страницы (ADDR - FlashPageBeginAddr) dword FlashPageBeginAddr; //начальный адрес страницы dword FlashModifAddr; //начальный адрес данных требующий модификации //описание буфера данные которого нужно скопировать во флеш-память TBuff512KWords * SourceBufAddr;//Адрес буфера "источника", адресует байт uint SourceBufCounter;//Количество байт копируемых из буфера "источника" //описание промежуточного буфера TBuff512KWords * TmpBufAddr;//адрес промежуточного буфера, адресует слово word TmpBuffMaxSize;//размер буфера words } TFlashInfo;
static TFlashInfo FlashInfo;
void GetFlashInfo (dword FLASH_ADDR) { FlashInfo.TmpBuffMaxSize = 512;//words FlashInfo.TmpBufAddr = &FlashTmpBuff; FlashInfo.FlashModifAddr = FLASH_ADDR; FlashInfo.FlashPageNumber = (FLASH_ADDR >> 9); FlashInfo.FlashPageBeginAddr = FlashInfo.FlashPageNumber << 9; FlashInfo.FlashPageOffset = FLASH_ADDR - FlashInfo.FlashPageBeginAddr; FlashInfo.FlashPageSize = 512;//words return; }
uint FlashPageErase (void) { //4.3) Инициализация Flash. Инициализировать генератор! if ((*(word*) FMCLKD & DIVLD) == 0) {//Срочно Инициализировать! *(word*) FMCLKD = 0x53; //Ждём появления пока CBEIF не станет 1 while (!(*(word*) FMUSTAT & CBEIF)) {}; }; //4.3) Очистить регистр FMCR *(word*) FMCR = 0; //4.1) Выбрать банк регистров FMCR.BKSEL 2->Program *(word*) FMCR = 2; //4.4) Снять защиту *(word*) FMPROT = 0; *(word*) FMPROTB = 0; //4.5) Проверка готовности к выполнению команд стирания страницы, если не готов подождать // Ждём появления пока CBEIF не станет 1 while (!(*(word*) FMUSTAT & CBEIF)) {}; // *(word*)FMUSTAT |= ACCERR; //4.6) Устанавливаем Адрес стираемой страницы и данные для "записи" asm(bfset #0x0300,SR); /* dis isrs!!! */ asm( move.l FlashInfo.FlashPageBeginAddr , R1 );//и в R1 попадает F000 asm( clr.w Y1); asm( move.w Y1, P:(R1)+);//т.к. интерласинг, то пишем два раза asm( move.w Y1, P:(R1)+);//ну в мануале так написано //4.7) Подаём команду "Стереть страницу = PageErase = $40" *(word*)FMCMD = PageErase;/* page erase command */ *(word*)FMUSTAT |= CBEIF; /* clear CBEIF flag для подготовки регистра команд к новой команде*/ asm(bfclr #0x0300,SR); //4.8) Проверяем исполнение команды //4.8.1) Был ли защищён от записи стираемый блок? if (*(word*)FMUSTAT & PVIOL) {//операция не удалась т.к. страница защищена от записи //очистить бит ошибки перед выходом *(word*)FMUSTAT &= ~PVIOL; return PVIOL; }; //4.8.2) Были ошибки доступа? if (*(word*)FMUSTAT & ACCERR) {//операция не удалась т.к. в доступе отказано (например не правильно указан адрес) //очистить бит ошибки перед выходом *(word*)FMUSTAT &= ~ACCERR; return ACCERR; }; //4.8.3) Операция прошла успешно, нужно подождать пока всё устаканится (CCIF должен стать 1) while (!(*(word*)FMUSTAT & CCIF)) {}; return 0; }
void ReadFlashToTmpBuffer(void) { word count = FlashInfo.TmpBuffMaxSize; word * Buffer = (word*)FlashInfo.TmpBufAddr; dword FlashSourceAddr = FlashInfo.FlashPageBeginAddr; while (count-- != 0) { *Buffer++ = readflash(FlashSourceAddr++); } }
uint FlashWrite(dword FLASH_ADDR, char* Buffer, uint Count) { //1)Получение данных о Flash GetFlashInfo (FLASH_ADDR); (char*) FlashInfo.SourceBufAddr = Buffer; FlashInfo.SourceBufCounter = Count;
//2)скопировать страницу флеша во временный буфер //ReadFlashToTmpBuffer(); //3)стереть страницу флеша if (FlashPageErase() != 0) {return -1;};
//4)внести изменения во временный буфер //5)теперь на подготовленную флешку можно писать //WriteBuffToFlash (); return 0; }
4) стартап я приводить не стал, т.к. ничего относящегося к флэшу там нет, смотрел 10^6 раз.Надеюсь на помощь клуба.
С уважением, Герасимов.
;-)