]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/at91/jtst/v2_0/support/jtstflash.c
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / at91 / jtst / v2_0 / support / jtstflash.c
1
2 // jtstflash.c, Andrea Michelotti amichelotti@atmel.com
3 // simple flash software.
4 // To compile it:
5 // gcc -DLINUX jtstflash.c -o jtstflash (linux)
6 // gcc jtstflash.c -o jtstflash (cygwin)
7
8
9 /*
10 Redistribution and use in source and binary forms, with or without
11 modification, are permitted provided that the following conditions are
12 met:
13
14     * Redistributions of source code must retain the above copyright
15       notice, this list of conditions and the following disclaimer.
16
17     * Redistributions in binary form must reproduce the above
18       copyright notice, this list of conditions and the following
19       disclaimer in the documentation and/or other materials provided
20       with the distribution.
21
22     * Neither the name of [original copyright holder] nor the names of
23       its contributors may be used to endorse or promote products
24       derived from this software without specific prior written
25       permission.
26
27 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 #include <termios.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <unistd.h>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <fcntl.h>
47
48 #define PRG_FLASH 0x4392014
49
50 //
51 #define BUFFER_SIZE 1024
52
53 #define FLASH_SIZE 1024*1024
54 #define PROTOK 0xc1a0c1a0
55 typedef struct {
56   unsigned cmd;
57   unsigned add;
58   unsigned len;
59 } command_t;
60
61 unsigned totry[]={
62   50,
63   75,
64   110,
65   134,
66   150,
67   200,
68   300,
69   600,
70   1200,
71   2400,
72   4800,
73   9600,
74   19200,
75   38400,
76   57600,
77   115200
78 };
79
80 void check_error(int a){
81   printf("\n\n\n\n\n");
82   switch(a){
83   case -1:
84     printf("## verify error\n");
85     break;
86   case -2:
87     printf("## flash timeout error\n");
88     break;
89   case -3:
90     printf("## product id mismatch\n");
91     break;
92   case -4:
93     printf("## device id mismatch\n");
94     break;
95   case -5:
96     printf("## flash write protected\n");
97     break;
98   default:
99     printf("## PROTOCOL ERROR check serial connection 0x%x (%d)\n",a,a);
100     break;
101   }
102
103 }
104
105 unsigned num2baud(unsigned baud_rate){
106   unsigned BAUD;
107   switch (baud_rate)
108       {
109
110       default:
111         printf("%% baud rate %d not supported\n",baud_rate);
112         exit(1);
113       case 115200:
114         BAUD = B115200;
115             break;
116       case 57600:
117         BAUD = B57600;
118             break;
119       case 38400:
120
121            BAUD = B38400;
122             break;
123          case 19200:
124             BAUD  = B19200;
125             break;
126          case 9600:
127             BAUD  = B9600;
128             break;
129          case 4800:
130             BAUD  = B4800;
131             break;
132          case 2400:
133             BAUD  = B2400;
134             break;
135          case 1800:
136             BAUD  = B1800;
137             break;
138          case 1200:
139             BAUD  = B1200;
140             break;
141          case 600:
142             BAUD  = B600;
143             break;
144          case 300:
145             BAUD  = B300;
146             break;
147          case 200:
148             BAUD  = B200;
149             break;
150          case 150:
151             BAUD  = B150;
152             break;
153          case 134:
154             BAUD  = B134;
155             break;
156          case 110:
157             BAUD  = B110;
158             break;
159          case 75:
160             BAUD  = B75;
161             break;
162          case 50:
163             BAUD  = B50;
164             break;
165       }
166   return BAUD;
167 }
168 unsigned check_ack(int fd){
169   unsigned data;
170   //usleep(80000);
171   read(fd,&data,4);
172   if((data==PROTOK)){
173     //    printf("## check ack :0x%x\n",data);
174     return 0;
175   }
176   return data;
177 }
178
179 unsigned ask(int fd,unsigned cmd, unsigned address,unsigned len){
180   command_t data;
181
182   data.len = len;
183   data.cmd = cmd;
184   data.add = address;
185   //   printf("%% sending command\n");
186   //usleep(80000);
187   write(fd,&data.cmd,sizeof(data));
188
189   //  sleep(1);
190   /*  if((res=check_ack(fd)) ==0){
191     //    printf("* command OK\n");
192     return 0;
193   } else {
194     printf("## ACK check sending command failed 0x%x\n",res);
195     }*/
196   //  sleep(1);
197   return 0;
198 }
199
200
201
202
203 main(int argc,char**argv){
204
205   struct termios uparam,uparam_old;
206   unsigned res;
207   command_t data;
208   int i,fd;
209   unsigned baud_rate=115200;
210   long BAUD;
211   unsigned STOPBITS = CSTOPB;
212   unsigned PARITY = 0;
213   unsigned DATABITS = CS8;
214   unsigned PARITYON = 0;
215   int tot=0;
216 #ifdef LINUX
217   char* s_dev="/dev/ttyS1";
218 #else
219 #warning "USING WIN32 SETTINGS"
220   char* s_dev="/dev/com2";
221 #endif
222   char* s_fname=0;
223   char* s_add=0;
224   char* s_len=0;
225   unsigned address=0x500000,len=0,tlen;
226   FILE* mybin=0;
227   struct stat info;
228   char buffer[BUFFER_SIZE];
229   unsigned ok=0xc1a0c1a0;
230   for(i=1;i<argc;i++){
231     if(!strcmp(argv[i],"-d")){
232       s_dev = argv[++i];
233       continue;
234     }
235
236
237     if(!strcmp(argv[i],"-a")){
238       s_add = argv[++i];
239       continue;
240     }
241
242     /*    if(!strcmp(argv[i],"-reset")){
243       operation = CMD_RESET;
244       continue;
245       }*/
246
247     if(!strcmp(argv[i],"-h")){
248       printf("usage is %s <bin> [-a <flash address>]\n",argv[0]);
249       exit(0);
250     }
251     s_fname = argv[i];
252     // printf("name  -> %s",s_fname);
253   }
254
255   if(s_fname){
256     mybin=fopen(s_fname,"rb");
257     if(mybin==0){
258       printf("## you must specify a valid filename\n");
259       exit(1);
260     }
261   } else {
262      printf("## you must specify a valid filename\n");
263      exit(1);
264   }
265   if(s_add){
266     address=strtoul(s_add,0,0);
267   }
268   BAUD=num2baud(baud_rate);
269   fd=open(s_dev,O_RDWR |O_NOCTTY| O_NDELAY);
270   if(fd<0){
271     printf("## cannot open serial %s\n",s_dev);
272     exit(1);
273   }
274  if(tcgetattr(fd,&uparam)<0){
275     perror("## cannot get serial paramenters \n");
276     exit(1);
277   }
278  //CS8 : 8 n 1
279  // hw flow ctrl
280   //bzero(&uparam, sizeof(uparam));
281
282   uparam.c_cflag = BAUD | CS8 |CLOCAL|CREAD;
283
284   uparam.c_iflag = 0; //raw device
285   uparam.c_oflag = 0; // raw device
286   uparam.c_lflag = 0;//ICANON;
287   //uparam.c_cc[VMIN]=1;
288   //uparam.c_cc[VEOF]=4;/*ctrld*/
289   //uparam.c_cc[VTIME]=0;
290   fcntl(fd, F_SETFL, 0);
291
292   if(tcflush(fd, TCIFLUSH)<0){
293     printf("## cannot flush serial\n");
294     exit(1);
295   }
296   if(tcsetattr(fd,TCSANOW,&uparam)<0){
297     printf("## cannot set serial paramenters\n");
298     exit(1);
299   } else {
300     printf("* using serial %s, %d, no parity, 8b, 1stop\n",s_dev,baud_rate);
301   }
302 /*
303   if(tcflush(fd, TCIFLUSH)<0){
304     printf("## cannot flush serial paramenters\n");
305     exit(1);
306   }*/
307   /*
308   printf("* press return\n");
309   {
310           char pp[80];
311           gets(pp);
312         }*/
313   lstat(s_fname,&info);
314   len = info.st_size;
315
316   printf("* binary len %d bytes..\n",len);
317   if(ask(fd,PRG_FLASH,address,len)!=0) {
318     fclose(mybin);
319     close(fd);
320     return 0;
321   }
322   // check flsh id
323   if((res=check_ack(fd))!=0){
324     printf("## flash id check failed 0x%x\n",res);
325     close(fd);
326     exit(1);
327   }
328   printf("* flash id check ok\n");
329   write(fd,&ok,4);
330   if((res=check_ack(fd))!=0){
331       printf("## flash id check failed 0x%x\n",res);
332       close(fd);
333       exit(1);
334   }
335   printf("* erasing space address 0x%x... please wait\n",address);
336   // verify erase
337   if((res=check_ack(fd))!=0){
338     printf("## verify erase failed 0x%x\n",res);
339     close(fd);
340     exit(1);
341   }
342   printf("* flash erase check ok\n");
343   printf("* start programming %d bytes.\n",len);
344   tlen=len;
345   while(len>0){
346     int ll=(len<BUFFER_SIZE)?len:BUFFER_SIZE;
347     tot+=ll;
348     fread(buffer,1,ll,mybin);
349     usleep(8000);
350     write(fd,buffer,ll);
351     printf("* downloading %.3f (rem:%d bytes)\r",(tlen-len)*100.0/tlen,tot);
352     if((res=check_ack(fd))!=0){
353       printf("## programming failed base add 0x%x\n",res);
354       //      close(fd);
355       //      exit(1);
356     }
357
358     len-=ll;
359
360   }
361   printf("\n* 100%% end programming\n");
362 }
363
364