Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

flash.c

00001 /*
00002  * Flash tool for Armonie.
00003  *
00004  * Memory organisation:
00005  *
00006  * 0xA0000000 -> 0xA0000000 + 10 MB: enough space for this program and data.
00007  * 0xA0000000 + 12 MB: stack
00008  * 0xA0000000 + 16 MB: space for parameter passing.
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 // contains WORD address. multiply by 2 to get BYTE address.
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; // back to Reset/Read
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         // wait until the flash is finished
00084         while ((flash[SectorAddress[sector].start] &0x80) == 0) ;
00085 
00086         flash[0] = 0xF0; // back to Reset/Read
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         // some verification.
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         // unlock bypass command sequence.
00109         
00110         // unlock cycles
00111         flash[0x555] = 0xaa;
00112         flash[0x2aa] = 0x55;
00113         flash[0x555] = 0x20;
00114         
00115         // unlock bypass programming
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         // exit unlock bypass program 
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         // simple checking...
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         // find the 1st sector concerned
00171         for (first_sect = 0; SectorAddress[first_sect].end < addr; first_sect++);
00172 
00173         // find the last sector concerned
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         // mirror data
00185         for (i=SectorAddress[first_sect].start; i<=SectorAddress[last_sect].end; ++i)
00186                 flashImage[i] = flash[i];
00187 
00188         // copy data to write into flash image
00189         for (i=0; i< nb_words; i++)
00190                 flashImage[i] = data[i];
00191 
00192         // erase sectors
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         // program data
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         // Send the Autoselect ID Read command
00225         flash[0x555] = 0xaa;
00226         flash[0x2aa] = 0x55;
00227         flash[0x555] = 0x90;
00228         val = (int) flash[1];   // read device code
00229         val2 = mem[0] >> 16;
00230         flash[0] = 0xF0; // back to Reset/Read
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 

Generated on Fri May 16 13:01:45 2003 for Jelie by doxygen1.2.15