📄 flash.c
字号:
/* * Flash tool for Armonie. * * Memory organisation: * * 0xA0000000 -> 0xA0000000 + 10 MB: enough space for this program and data. * 0xA0000000 + 12 MB: stack * 0xA0000000 + 16 MB: space for parameter passing. * */#include "serial.h"volatile unsigned short *flash=0;volatile unsigned int *mem = 0;unsigned short *flashImage= (unsigned short *) (0xA0000000 + (9*1024*1024));typedef struct { unsigned start; unsigned end;} FlashSector;// contains WORD address. multiply by 2 to get BYTE address.FlashSector SectorAddress[] = { { 0x0, 0x01FFF}, { 0x2000, 0x2FFF}, { 0x3000, 0x3FFF}, { 0x4000, 0x7FFF}, { 0x8000, 0xFFFF}, { 0x10000, 0x17FFF}, { 0x18000, 0x1FFFF}, { 0x20000, 0x27FFF}, { 0x28000, 0x2FFFF}, { 0x30000, 0x37FFF}, { 0x38000, 0x3FFFF}, { 0x40000, 0x47FFF}, { 0x48000, 0x4FFFF}, { 0x50000, 0x57FFF}, { 0x58000, 0x5FFFF}, { 0x60000, 0x67FFF}, { 0x68000, 0x6FFFF}, { 0x70000, 0x77FFF}, { 0x78000, 0x7FFFF}};//! \return one if sector is protected, 0 if it's not.int is_sector_protected(int sector) { unsigned short r; if (sector < 0) sector =0; if (sector > 18) sector = 18; flash[0x555] = 0xaa; flash[0x2aa] = 0x55; flash[0x555] = 0x90; r = flash[ SectorAddress[sector].start | 0x02 ]; flash[0] = 0xF0; // back to Reset/Read return r;}void protect_sector(int sector) {}void unprotect_sector(int sector) {}void erase(int sector) { if ((sector < 0) || (sector > 18)) { printf("erase(%d): invalid sector.\n\r", sector); return; } flash[0x555] = 0xaa; flash[0x2aa] = 0x55; flash[0x555] = 0x80; flash[0x555] = 0xaa; flash[0x2aa] = 0x55; flash[SectorAddress[sector].start] = 0x30; // wait until the flash is finished while ((flash[SectorAddress[sector].start] &0x80) == 0) ; flash[0] = 0xF0; // back to Reset/Read}void program(unsigned byte_address, unsigned short *data, unsigned int nb_words) { unsigned addr = byte_address >> 1; unsigned i, err_cnt; // some verification. if (nb_words == 0) return; if (addr + nb_words >= (512 * 1024)) { printf("Sorry, the flash is not big enough for data. Not programming.\n\r"); return; } if (((unsigned)byte_address & 0x01) || ((unsigned)data & 0x01)) { printf("data or destination address not aligned. Not programming.\n\r"); return; } printf("Ready to program %d bytes at 0x%x\n\r", nb_words<<1, byte_address); // unlock bypass command sequence. // unlock cycles flash[0x555] = 0xaa; flash[0x2aa] = 0x55; flash[0x555] = 0x20; // unlock bypass programming for (i=0; i<nb_words; ++i) { unsigned dq6; flash[addr] = 0xA0; flash[addr] = data[i]; dq6 = flash[addr] & (1 << 6); while(1) { unsigned dq6_ = flash[addr] & (1 << 6); if (dq6 == dq6_) break; dq6 = dq6_; } ++addr; } // exit unlock bypass program flash[0] = 0x90; flash[1] = 0x00; printf("done. Verifying...\n\r"); addr = byte_address >> 1; for (i= err_cnt=0; i<nb_words; ++i) { if (flash[addr] != data[i]) err_cnt++; addr++; } printf("%d error.\n\r", err_cnt);}int erase_and_program(unsigned byte_address, unsigned short *data, unsigned int nb_words) { unsigned addr = byte_address >> 1; int i, first_sect, last_sect; printf("erase_and_program(0x%x, 0x%x, %d)\n\r", byte_address, data, nb_words); // simple checking... if (nb_words == 0) { printf("0 words to program...\n\r"); return 0; } if (addr + nb_words >= (512 * 1024)) { printf("Sorry, the flash is not big enough for data. Not programming.\n\r"); return 1; } if (((unsigned) byte_address & 0x1) || ((unsigned) data&0x1)) { printf("data or destination address not aligned. Not programming.\n\r"); return 2; } // find the 1st sector concerned for (first_sect = 0; SectorAddress[first_sect].end < addr; first_sect++); // find the last sector concerned for (last_sect=18; SectorAddress[last_sect].start >= (addr + nb_words); last_sect--); if (first_sect > last_sect) { printf("erase_and_program(): INTERNAL ERROR !\n\r"); return 3; } printf("reprogramming sectors %d to %d (%d sectors)\r\n", first_sect, last_sect, last_sect-first_sect + 1); // mirror data for (i=SectorAddress[first_sect].start; i<=SectorAddress[last_sect].end; ++i) flashImage[i] = flash[i]; // copy data to write into flash image for (i=0; i< nb_words; i++) flashImage[i] = data[i]; // erase sectors printf("erasing sectors...\n\r"); for (i=first_sect; i<=last_sect; ++i) { erase(i); printf("Sector %d erased.\n\r", i); } // program data printf("Programming data...\n\r"); program( SectorAddress[first_sect].start << 1, flashImage + (SectorAddress[first_sect].start << 1), SectorAddress[last_sect].end - SectorAddress[first_sect].start + 1); printf("ok.\n\r"); return 0;} int printargs(int a, int b, int c, int d) { printf("a: 0x%x\n\r", a); printf("b: 0x%x\n\r", b); printf("c: 0x%x\n\r", c); printf("d: 0x%x\n\r", d); return 0xCAFE;}int main(int argc, char *argv[]){ unsigned int val; unsigned int val2; unsigned int i; // Send the Autoselect ID Read command flash[0x555] = 0xaa; flash[0x2aa] = 0x55; flash[0x555] = 0x90; val = (int) flash[1]; // read device code val2 = mem[0] >> 16; flash[0] = 0xF0; // back to Reset/Read printf("Flash device code is %x (%x)\n\r", val, val2); if (val != 0x225b) { printf("Wring flash device.\n\r"); } else { printf("AS29LV800 flash detected.\n\r"); } for (i=0; i<= 18; ++i) { printf("sector %d (0x%x - 0x%x) is %sprotected\n\r", i, SectorAddress[i].start << 1, SectorAddress[i].end << 1, is_sector_protected(i) ? "" : "not "); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -