changeset 1802:fab3d892d9ad

* support/jtstflash.{c|cpp}: Host tools for programming the flash on the jtst boards. See the redboot documentation.
author asl
date Fri, 08 Oct 2004 10:29:05 +0000
parents 73eed70a0752
children 4028c3fff75e
files packages/hal/arm/at91/jtst/current/ChangeLog packages/hal/arm/at91/jtst/current/support/jtstflash.c packages/hal/arm/at91/jtst/current/support/jtstflash.cpp
diffstat 3 files changed, 622 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/packages/hal/arm/at91/jtst/current/ChangeLog
+++ b/packages/hal/arm/at91/jtst/current/ChangeLog
@@ -1,3 +1,8 @@
+2004-10-8  Andrew Lunn	<andrew.lunn@ascom.ch>
+
+	* support/jtstflash.{c|cpp}: Host tools for programming the
+	flash on the jtst boards. See the redboot documentation.
+	
 2004-10-6  Andrea Michelotti  <amichelotti@atmel.com>
 
 	* include/plf_io.h: removed SPI definitions. They are defined in
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/at91/jtst/current/support/jtstflash.c
@@ -0,0 +1,364 @@
+
+// jtstflash.c, Andrea Michelotti amichelotti@atmel.com
+// simple flash software.
+// To compile it:
+// gcc -DLINUX jtstflash.c -o jtstflash (linux)
+// gcc jtstflash.c -o jtstflash (cygwin)
+
+
+/*
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of [original copyright holder] nor the names of
+      its contributors may be used to endorse or promote products
+      derived from this software without specific prior written
+      permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <termios.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define PRG_FLASH 0x4392014
+
+//
+#define BUFFER_SIZE 1024
+
+#define FLASH_SIZE 1024*1024
+#define PROTOK 0xc1a0c1a0
+typedef struct {
+  unsigned cmd;
+  unsigned add;
+  unsigned len;
+} command_t;
+
+unsigned totry[]={
+  50,
+  75,
+  110,
+  134,
+  150,
+  200,
+  300,
+  600,
+  1200,
+  2400,
+  4800,
+  9600,
+  19200,
+  38400,
+  57600,
+  115200
+};
+
+void check_error(int a){
+  printf("\n\n\n\n\n");
+  switch(a){
+  case -1:
+    printf("## verify error\n");
+    break;
+  case -2:
+    printf("## flash timeout error\n");
+    break;
+  case -3:
+    printf("## product id mismatch\n");
+    break;
+  case -4:
+    printf("## device id mismatch\n");
+    break;
+  case -5:
+    printf("## flash write protected\n");
+    break;
+  default:
+    printf("## PROTOCOL ERROR check serial connection 0x%x (%d)\n",a,a);
+    break;
+  }
+
+}
+
+unsigned num2baud(unsigned baud_rate){
+  unsigned BAUD;
+  switch (baud_rate)
+      {
+
+      default:
+	printf("%% baud rate %d not supported\n",baud_rate);
+	exit(1);
+      case 115200:
+	BAUD = B115200;
+            break;
+      case 57600:
+	BAUD = B57600;
+            break;
+      case 38400:
+
+	   BAUD = B38400;
+            break;
+         case 19200:
+            BAUD  = B19200;
+            break;
+         case 9600:
+            BAUD  = B9600;
+            break;
+         case 4800:
+            BAUD  = B4800;
+            break;
+         case 2400:
+            BAUD  = B2400;
+            break;
+         case 1800:
+            BAUD  = B1800;
+            break;
+         case 1200:
+            BAUD  = B1200;
+            break;
+         case 600:
+            BAUD  = B600;
+            break;
+         case 300:
+            BAUD  = B300;
+            break;
+         case 200:
+            BAUD  = B200;
+            break;
+         case 150:
+            BAUD  = B150;
+            break;
+         case 134:
+            BAUD  = B134;
+            break;
+         case 110:
+            BAUD  = B110;
+            break;
+         case 75:
+            BAUD  = B75;
+            break;
+         case 50:
+            BAUD  = B50;
+            break;
+      }
+  return BAUD;
+}
+unsigned check_ack(int fd){
+  unsigned data;
+  //usleep(80000);
+  read(fd,&data,4);
+  if((data==PROTOK)){
+    //    printf("## check ack :0x%x\n",data);
+    return 0;
+  }
+  return data;
+}
+
+unsigned ask(int fd,unsigned cmd, unsigned address,unsigned len){
+  command_t data;
+
+  data.len = len;
+  data.cmd = cmd;
+  data.add = address;
+  //   printf("%% sending command\n");
+  //usleep(80000);
+  write(fd,&data.cmd,sizeof(data));
+
+  //  sleep(1);
+  /*  if((res=check_ack(fd)) ==0){
+    //    printf("* command OK\n");
+    return 0;
+  } else {
+    printf("## ACK check sending command failed 0x%x\n",res);
+    }*/
+  //  sleep(1);
+  return 0;
+}
+
+
+
+
+main(int argc,char**argv){
+
+  struct termios uparam,uparam_old;
+  unsigned res;
+  command_t data;
+  int i,fd;
+  unsigned baud_rate=115200;
+  long BAUD;
+  unsigned STOPBITS = CSTOPB;
+  unsigned PARITY = 0;
+  unsigned DATABITS = CS8;
+  unsigned PARITYON = 0;
+  int tot=0;
+#ifdef LINUX
+  char* s_dev="/dev/ttyS1";
+#else
+#warning "USING WIN32 SETTINGS"
+  char* s_dev="/dev/com2";
+#endif
+  char* s_fname=0;
+  char* s_add=0;
+  char* s_len=0;
+  unsigned address=0x500000,len=0,tlen;
+  FILE* mybin=0;
+  struct stat info;
+  char buffer[BUFFER_SIZE];
+  unsigned ok=0xc1a0c1a0;
+  for(i=1;i<argc;i++){
+    if(!strcmp(argv[i],"-d")){
+      s_dev = argv[++i];
+      continue;
+    }
+
+
+    if(!strcmp(argv[i],"-a")){
+      s_add = argv[++i];
+      continue;
+    }
+
+    /*    if(!strcmp(argv[i],"-reset")){
+      operation = CMD_RESET;
+      continue;
+      }*/
+
+    if(!strcmp(argv[i],"-h")){
+      printf("usage is %s <bin> [-a <flash address>]\n",argv[0]);
+      exit(0);
+    }
+    s_fname = argv[i];
+    // printf("name  -> %s",s_fname);
+  }
+
+  if(s_fname){
+    mybin=fopen(s_fname,"rb");
+    if(mybin==0){
+      printf("## you must specify a valid filename\n");
+      exit(1);
+    }
+  } else {
+     printf("## you must specify a valid filename\n");
+     exit(1);
+  }
+  if(s_add){
+    address=strtoul(s_add,0,0);
+  }
+  BAUD=num2baud(baud_rate);
+  fd=open(s_dev,O_RDWR |O_NOCTTY| O_NDELAY);
+  if(fd<0){
+    printf("## cannot open serial %s\n",s_dev);
+    exit(1);
+  }
+ if(tcgetattr(fd,&uparam)<0){
+    perror("## cannot get serial paramenters \n");
+    exit(1);
+  }
+ //CS8 : 8 n 1
+ // hw flow ctrl
+  //bzero(&uparam, sizeof(uparam));
+
+  uparam.c_cflag = BAUD | CS8 |CLOCAL|CREAD;
+
+  uparam.c_iflag = 0; //raw device
+  uparam.c_oflag = 0; // raw device
+  uparam.c_lflag = 0;//ICANON;
+  //uparam.c_cc[VMIN]=1;
+  //uparam.c_cc[VEOF]=4;/*ctrld*/
+  //uparam.c_cc[VTIME]=0;
+  fcntl(fd, F_SETFL, 0);
+
+  if(tcflush(fd, TCIFLUSH)<0){
+    printf("## cannot flush serial\n");
+    exit(1);
+  }
+  if(tcsetattr(fd,TCSANOW,&uparam)<0){
+    printf("## cannot set serial paramenters\n");
+    exit(1);
+  } else {
+    printf("* using serial %s, %d, no parity, 8b, 1stop\n",s_dev,baud_rate);
+  }
+/*
+  if(tcflush(fd, TCIFLUSH)<0){
+    printf("## cannot flush serial paramenters\n");
+    exit(1);
+  }*/
+  /*
+  printf("* press return\n");
+  {
+	  char pp[80];
+	  gets(pp);
+	}*/
+  lstat(s_fname,&info);
+  len = info.st_size;
+
+  printf("* binary len %d bytes..\n",len);
+  if(ask(fd,PRG_FLASH,address,len)!=0) {
+    fclose(mybin);
+    close(fd);
+    return 0;
+  }
+  // check flsh id
+  if((res=check_ack(fd))!=0){
+    printf("## flash id check failed 0x%x\n",res);
+    close(fd);
+    exit(1);
+  }
+  printf("* flash id check ok\n");
+  write(fd,&ok,4);
+  if((res=check_ack(fd))!=0){
+      printf("## flash id check failed 0x%x\n",res);
+      close(fd);
+      exit(1);
+  }
+  printf("* erasing space address 0x%x... please wait\n",address);
+  // verify erase
+  if((res=check_ack(fd))!=0){
+    printf("## verify erase failed 0x%x\n",res);
+    close(fd);
+    exit(1);
+  }
+  printf("* flash erase check ok\n");
+  printf("* start programming %d bytes.\n",len);
+  tlen=len;
+  while(len>0){
+    int ll=(len<BUFFER_SIZE)?len:BUFFER_SIZE;
+    tot+=ll;
+    fread(buffer,1,ll,mybin);
+    usleep(8000);
+    write(fd,buffer,ll);
+    printf("* downloading %.3f (rem:%d bytes)\r",(tlen-len)*100.0/tlen,tot);
+    if((res=check_ack(fd))!=0){
+      printf("## programming failed base add 0x%x\n",res);
+      //      close(fd);
+      //      exit(1);
+    }
+
+    len-=ll;
+
+  }
+  printf("\n* 100%% end programming\n");
+}
+
+
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/at91/jtst/current/support/jtstflash.cpp
@@ -0,0 +1,253 @@
+// jtstflash.cpp Andrea Michelotti amichelotti@atmel.com
+// simple flash software. Compiled with MS Visual Studio 6
+
+/*
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of [original copyright holder] nor the names of
+      its contributors may be used to endorse or promote products
+      derived from this software without specific prior written
+      permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include "stdafx.h"
+#include "windows.h"
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <io.h>
+
+static HANDLE hComm;
+
+#define PRG_FLASH 0x4392014
+
+//
+#define BUFFER_SIZE 1024
+
+#define FLASH_SIZE 1024*1024
+#define PROTOK 0xc1a0c1a0
+typedef struct {
+  unsigned cmd;
+  unsigned add;
+  unsigned len;
+} command_t;
+
+
+unsigned check_ack(){
+  unsigned data;
+  unsigned long len;
+  //usleep(80000);
+  //read(fd,&data,4);
+  ReadFile(hComm,&data,4,&len,NULL);
+  if(len!=4){
+	  printf("## (check_ack) protocol error byte read %d, expected 4\n",len);
+	  exit(1);
+  }
+  if((data==PROTOK)){
+    //    printf("## check ack :0x%x\n",data);
+    return 0;
+  }
+  return data;
+}
+
+unsigned ask(unsigned cmd, unsigned address,unsigned len){
+  unsigned long rlen;
+  command_t data;
+
+  data.len = len;
+  data.cmd = cmd;
+  data.add = address;
+  //   printf("%% sending command\n");
+  //usleep(80000);
+  WriteFile(hComm,&data.cmd,sizeof(data),&rlen,NULL);
+
+  //  sleep(1);
+  /*  if((res=check_ack(fd)) ==0){
+    //    printf("* command OK\n");
+    return 0;
+  } else {
+    printf("## ACK check sending command failed 0x%x\n",res);
+    }*/
+  //  sleep(1);
+  return 0;
+}
+
+void initCom(char* com){
+	DCB dcb;
+	hComm = CreateFile (
+		com,
+	GENERIC_READ|GENERIC_WRITE,
+	0,
+	NULL,
+	OPEN_EXISTING,
+	0,
+	0
+	);
+
+	if(hComm==INVALID_HANDLE_VALUE){
+		printf("##  cannot open serial port %s\n",com);
+		exit(1);
+	}
+
+	if(GetCommState(hComm,&dcb)==0){
+		printf("## cannot get serial status\n");
+		exit(1);
+	}
+
+	dcb.BaudRate= CBR_115200;
+	dcb.ByteSize = 8;
+	dcb.Parity = NOPARITY;
+	dcb.StopBits = ONESTOPBIT;
+	dcb.fDtrControl= DTR_CONTROL_DISABLE;
+	dcb.fRtsControl = RTS_CONTROL_DISABLE;
+	dcb.DCBlength = sizeof(dcb);
+	if(SetCommState(hComm, &dcb)==0){
+		printf("## cannot set serial status\n");
+		exit(1);
+	}
+
+}
+
+
+
+int main(int argc, char* argv[])
+{
+ int res,i,tot=0;
+  char* s_dev="COM2";
+
+  char* s_fname=0;
+  char* s_add=0;
+  char* s_len=0;
+  unsigned address=0x500000,len=0,tlen;
+  FILE* mybin=0;
+  struct stat info;
+  char buffer[BUFFER_SIZE];
+  unsigned ok=0xc1a0c1a0;
+  unsigned long lenw;
+  for(i=1;i<argc;i++){
+    if(!strcmp(argv[i],"-d")){
+      s_dev = argv[++i];
+      continue;
+    }
+
+
+    if(!strcmp(argv[i],"-a")){
+      s_add = argv[++i];
+      continue;
+    }
+
+    /*    if(!strcmp(argv[i],"-reset")){
+      operation = CMD_RESET;
+      continue;
+      }*/
+
+    if(!strcmp(argv[i],"-h")){
+      printf("usage is %s <bin> [-a <flash address>]\n",argv[0]);
+      exit(0);
+    }
+    s_fname = argv[i];
+    // printf("name  -> %s",s_fname);
+  }
+
+  if(s_fname){
+    mybin=fopen(s_fname,"rb");
+    if(mybin==0){
+      printf("## you must specify a valid filename\n");
+      exit(1);
+    }
+  } else {
+     printf("## you must specify a valid filename\n");
+     exit(1);
+  }
+  if(s_add){
+    address=strtoul(s_add,0,0);
+  }
+
+	initCom(s_dev);
+
+	{
+		int fdf=fseek(mybin,0,SEEK_END );
+		fdf = ftell(mybin);
+		fseek(mybin,0,SEEK_SET );
+		len = fdf- ftell(mybin);
+	}
+  printf("* binary len %d bytes flash add 0x%x..\n",len,address);
+  if(ask(PRG_FLASH,address,len)!=0) {
+    fclose(mybin);
+    CloseHandle(hComm);
+    return 0;
+  }
+  // check flsh id
+  if((res=check_ack())!=0){
+    printf("## flash id check failed 0x%x\n",res);
+    CloseHandle(hComm);
+    exit(1);
+  }
+  printf("* flash id check ok\n");
+
+  WriteFile(hComm,&ok,4,&lenw,NULL);
+  if((res=check_ack())!=0){
+      printf("## flash id check failed 0x%x\n",res);
+       CloseHandle(hComm);
+      exit(1);
+  }
+  printf("* erasing space address 0x%x... please wait\n",address);
+  // verify erase
+  if((res=check_ack())!=0){
+    printf("## verify erase failed 0x%x\n",res);
+    CloseHandle(hComm);
+    exit(1);
+  }
+  printf("* flash erase check ok\n");
+  printf("* start programming %d bytes.\n",len);
+  tlen=len;
+  while(len>0){
+
+    unsigned long ll=(len<BUFFER_SIZE)?len:BUFFER_SIZE;
+    tot+=ll;
+    fread(buffer,1,ll,mybin);
+    //usleep(8000);
+    //write(fd,buffer,ll);
+	WriteFile(hComm,buffer,ll,&lenw,NULL);
+	if(ll!=lenw){
+		printf("## error writing byte write %d != byte to write %d\n",lenw,ll);
+		exit(1);
+	}
+    printf("* downloading %.3f (rem:%d bytes)\r",(tlen-len)*100.0/tlen,tot);
+    if((res=check_ack())!=0){
+      printf("## programming failed base add 0x%x\n",res);
+      //      close(fd);
+      //      exit(1);
+    }
+
+    len-=ll;
+
+  }
+	printf("\n* 100%% end programming\n");
+	return 0;
+}
+