00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "serial.h"
00012
00013 volatile unsigned short *flash=0;
00014 volatile unsigned int *mem = 0;
00015 unsigned short *flashImage= (unsigned short *) (0xA0000000 + (9*1024*1024));
00016
00017 typedef struct {
00018 unsigned start;
00019 unsigned end;
00020 } FlashSector;
00021
00022
00023 FlashSector SectorAddress[] = {
00024 { 0x0, 0x01FFF},
00025 { 0x2000, 0x2FFF},
00026 { 0x3000, 0x3FFF},
00027 { 0x4000, 0x7FFF},
00028 { 0x8000, 0xFFFF},
00029 { 0x10000, 0x17FFF},
00030 { 0x18000, 0x1FFFF},
00031 { 0x20000, 0x27FFF},
00032 { 0x28000, 0x2FFFF},
00033 { 0x30000, 0x37FFF},
00034 { 0x38000, 0x3FFFF},
00035 { 0x40000, 0x47FFF},
00036 { 0x48000, 0x4FFFF},
00037 { 0x50000, 0x57FFF},
00038 { 0x58000, 0x5FFFF},
00039 { 0x60000, 0x67FFF},
00040 { 0x68000, 0x6FFFF},
00041 { 0x70000, 0x77FFF},
00042 { 0x78000, 0x7FFFF}
00043 };
00044
00046 int is_sector_protected(int sector) {
00047 unsigned short r;
00048
00049 if (sector < 0) sector =0;
00050 if (sector > 18) sector = 18;
00051
00052 flash[0x555] = 0xaa;
00053 flash[0x2aa] = 0x55;
00054 flash[0x555] = 0x90;
00055
00056 r = flash[ SectorAddress[sector].start | 0x02 ];
00057 flash[0] = 0xF0;
00058 return r;
00059 }
00060
00061 void protect_sector(int sector) {
00062
00063 }
00064
00065 void unprotect_sector(int sector) {
00066
00067 }
00068
00069 void erase(int sector) {
00070
00071 if ((sector < 0) || (sector > 18)) {
00072 printf("erase(%d): invalid sector.\n\r", sector);
00073 return;
00074 }
00075
00076 flash[0x555] = 0xaa;
00077 flash[0x2aa] = 0x55;
00078 flash[0x555] = 0x80;
00079 flash[0x555] = 0xaa;
00080 flash[0x2aa] = 0x55;
00081 flash[SectorAddress[sector].start] = 0x30;
00082
00083
00084 while ((flash[SectorAddress[sector].start] &0x80) == 0) ;
00085
00086 flash[0] = 0xF0;
00087 }
00088
00089 void program(unsigned byte_address, unsigned short *data, unsigned int nb_words) {
00090 unsigned addr = byte_address >> 1;
00091 unsigned i, err_cnt;
00092
00093
00094 if (nb_words == 0) return;
00095
00096 if (addr + nb_words >= (512 * 1024)) {
00097 printf("Sorry, the flash is not big enough for data. Not programming.\n\r");
00098 return;
00099 }
00100
00101 if (((unsigned)byte_address & 0x01) || ((unsigned)data & 0x01)) {
00102 printf("data or destination address not aligned. Not programming.\n\r");
00103 return;
00104 }
00105
00106 printf("Ready to program %d bytes at 0x%x\n\r", nb_words<<1, byte_address);
00107
00108
00109
00110
00111 flash[0x555] = 0xaa;
00112 flash[0x2aa] = 0x55;
00113 flash[0x555] = 0x20;
00114
00115
00116 for (i=0; i<nb_words; ++i) {
00117 unsigned dq6;
00118
00119 flash[addr] = 0xA0;
00120 flash[addr] = data[i];
00121
00122 dq6 = flash[addr] & (1 << 6);
00123
00124 while(1) {
00125 unsigned dq6_ = flash[addr] & (1 << 6);
00126 if (dq6 == dq6_)
00127 break;
00128 dq6 = dq6_;
00129 }
00130 ++addr;
00131 }
00132
00133
00134 flash[0] = 0x90;
00135 flash[1] = 0x00;
00136 printf("done. Verifying...\n\r");
00137
00138 addr = byte_address >> 1;
00139 for (i= err_cnt=0; i<nb_words; ++i) {
00140 if (flash[addr] != data[i]) err_cnt++;
00141 addr++;
00142 }
00143
00144 printf("%d error.\n\r", err_cnt);
00145 }
00146
00147 int erase_and_program(unsigned byte_address, unsigned short *data, unsigned int nb_words) {
00148 unsigned addr = byte_address >> 1;
00149 int i, first_sect, last_sect;
00150
00151 printf("erase_and_program(0x%x, 0x%x, %d)\n\r",
00152 byte_address, data, nb_words);
00153
00154
00155 if (nb_words == 0) {
00156 printf("0 words to program...\n\r");
00157 return 0;
00158 }
00159
00160 if (addr + nb_words >= (512 * 1024)) {
00161 printf("Sorry, the flash is not big enough for data. Not programming.\n\r");
00162 return 1;
00163 }
00164
00165 if (((unsigned) byte_address & 0x1) || ((unsigned) data&0x1)) {
00166 printf("data or destination address not aligned. Not programming.\n\r");
00167 return 2;
00168 }
00169
00170
00171 for (first_sect = 0; SectorAddress[first_sect].end < addr; first_sect++);
00172
00173
00174 for (last_sect=18; SectorAddress[last_sect].start >= (addr + nb_words); last_sect--);
00175
00176 if (first_sect > last_sect) {
00177 printf("erase_and_program(): INTERNAL ERROR !\n\r");
00178 return 3;
00179 }
00180
00181 printf("reprogramming sectors %d to %d (%d sectors)\r\n", first_sect,
00182 last_sect, last_sect-first_sect + 1);
00183
00184
00185 for (i=SectorAddress[first_sect].start; i<=SectorAddress[last_sect].end; ++i)
00186 flashImage[i] = flash[i];
00187
00188
00189 for (i=0; i< nb_words; i++)
00190 flashImage[i] = data[i];
00191
00192
00193 printf("erasing sectors...\n\r");
00194 for (i=first_sect; i<=last_sect; ++i) {
00195 erase(i);
00196 printf("Sector %d erased.\n\r", i);
00197 }
00198
00199
00200 printf("Programming data...\n\r");
00201 program( SectorAddress[first_sect].start << 1,
00202 flashImage + (SectorAddress[first_sect].start << 1),
00203 SectorAddress[last_sect].end - SectorAddress[first_sect].start + 1);
00204
00205 printf("ok.\n\r");
00206 return 0;
00207 }
00208
00209 int printargs(int a, int b, int c, int d) {
00210
00211 printf("a: 0x%x\n\r", a);
00212 printf("b: 0x%x\n\r", b);
00213 printf("c: 0x%x\n\r", c);
00214 printf("d: 0x%x\n\r", d);
00215 return 0xCAFE;
00216 }
00217
00218 int main(int argc, char *argv[])
00219 {
00220 unsigned int val;
00221 unsigned int val2;
00222 unsigned int i;
00223
00224
00225 flash[0x555] = 0xaa;
00226 flash[0x2aa] = 0x55;
00227 flash[0x555] = 0x90;
00228 val = (int) flash[1];
00229 val2 = mem[0] >> 16;
00230 flash[0] = 0xF0;
00231
00232 printf("Flash device code is %x (%x)\n\r", val, val2);
00233
00234 if (val != 0x225b) {
00235 printf("Wring flash device.\n\r");
00236 } else {
00237 printf("AS29LV800 flash detected.\n\r");
00238 }
00239
00240 for (i=0; i<= 18; ++i) {
00241 printf("sector %d (0x%x - 0x%x) is %sprotected\n\r",
00242 i,
00243 SectorAddress[i].start << 1,
00244 SectorAddress[i].end << 1,
00245 is_sector_protected(i) ? "" : "not ");
00246 }
00247 }
00248