ispdown/isp_down.c

440 lines
11 KiB
C
Raw Normal View History

2006-05-21 19:42:31 +02:00
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <string.h>
2006-05-21 19:43:19 +02:00
#define BAUDRATE B115200
2006-05-21 19:42:31 +02:00
2006-05-21 19:43:19 +02:00
struct chip_ {
char shortname[8];
char longname[16];
char signatur[3];
int flash_size;
int eeprom_size;
};
2006-05-21 19:42:31 +02:00
2006-05-21 19:43:19 +02:00
typedef struct chip_ CHIP;
2006-05-21 19:43:07 +02:00
2006-05-21 19:43:19 +02:00
CHIP chips[] = {
{ "1200", "AT90S1200", { 0x00, 0x90, 0x1E }, 0x200, 0x40 },
{ "2313", "AT90S2313", { 0x01, 0x91, 0x1E }, 0x400, 0x80 },
{ "8515", "AT90S8515", { 0x01, 0x93, 0x1E }, 0x1000, 0x200 },
{ "\0", "\0", {0, 0, 0}, 0, 0 }
};
2006-05-21 19:42:31 +02:00
void show_usage();
2006-05-21 19:43:19 +02:00
int main(int argc, char *argv[])
2006-05-21 19:42:31 +02:00
{
2006-05-21 19:43:19 +02:00
char arg;
printf("\nISP for Atmel-AVRs:\n");
if (argc <= 1) {
show_usage();
exit(-1);
}
for (arg= 1; arg<argc; arg++) {
if (!strcmp (argv[arg], "-avr")) {
/* check AVR-device */
if (++arg == argc) {
printf("ERROR: No AVR-Device\n\n");
exit(-1);
}
if (!strcmp (argv[arg], "1200"))
avr_device=0;
else if (!strcmp (argv[arg], "2313"))
avr_device=1;
else if (!strcmp (argv[arg], "2323"))
avr_device=2;
else if (!strcmp (argv[arg], "2343"))
avr_device=3;
else if (!strcmp (argv[arg], "4414"))
avr_device=4;
else if (!strcmp (argv[arg], "8515"))
avr_device=5;
else {
printf("ERROR: Unknown AVR-Device\n");
exit(-1);
}
} else if (!strcmp (argv[arg], "-dev")) {
/* check RS232 device */
if (++arg == argc) {
printf(" ERROR: No RS232-device\n");
exit(-1);
}
strcpy (ser_device, argv[arg]);
} else if (!strcmp (argv[arg], "-flash")) {
/* check flash */
flash= 1;
} else if (!strcmp (argv[arg], "-eeprom")) {
/* check eeprom */
eeprom= 1;
} else if (!strcmp (argv[arg], "-verify")) {
/* check verify */
verify= 1;
} else if (!strcmp (argv[arg], "-reset")) {
/* check reset */
reset= 1;
} else if (flash == 1) {
/* get flash-file */
strcpy (flash_file, argv[arg]);
flash= 2;
} else if (eeprom == 1) {
/* get eeprom-file */
strcpy (eeprom_file, argv[arg]);
eeprom= 2;
} else {
/* wrong parameter */
printf(" ERROR: Unknown parameter\n");
exit(-1);
}
}
if (flash == 1) {
2006-05-21 19:42:31 +02:00
/* check flash-file */
2006-05-21 19:43:19 +02:00
printf (" ERROR: No FLASH-file\n");
exit(-1);
}
2006-05-21 19:42:31 +02:00
2006-05-21 19:43:19 +02:00
if (eeprom == 1) {
2006-05-21 19:42:31 +02:00
/* check eeprom-file */
2006-05-21 19:43:19 +02:00
printf (" ERROR: No EEPROM-file\n");
exit(-1);
}
init_ser(ser_device);
/* open rs232-device */
2006-05-21 19:42:31 +02:00
printf(" Opening %s -----> ", ser_device);
ser = open(ser_device, O_RDWR | O_NOCTTY );
if (ser <0)
{
printf("ERROR: Wrong (?) RS232-device\n");
end_prg(0);
}
printf("OK\n");
/* save rs232 settings */
tcgetattr(ser,&oldtio); /* save current port settings */
bzero(&newtio, sizeof(newtio));
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
newtio.c_lflag = 0; /* set input mode (non-canonical, no echo,...) */
newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
newtio.c_cc[VMIN] = 1; /* blocking read until 5 chars received */
tcflush(ser, TCIFLUSH);
tcsetattr(ser,TCSANOW,&newtio);
/* detecting avr-isp adapter */
printf(" Detecting ISP ----------> ");
write (ser,"S",1);
2006-05-21 19:43:07 +02:00
usleep(10000);
2006-05-21 19:42:31 +02:00
read (ser,inbuf,7);
inbuf[7]=0x00;
if (!strcmp(inbuf, "AVR ISP"))
printf ("OK\n");
else
{
printf("ERROR: No response\n");
end_prg(1);
}
/* set avr-device in avr-isp adapter */
switch (avr_device)
{
case 0: printf(" Set device AT90S1200 ---> ");
outbuf[1]=0x12;
break;
case 1: printf(" Set device AT90S2313 ---> ");
2006-05-21 19:43:07 +02:00
outbuf[1]=0x12;
2006-05-21 19:42:31 +02:00
break;
case 2: printf(" Set device AT90S2323 ---> ");
outbuf[1]=0x00;
break;
case 3: printf(" Set device AT90S2343 ---> ");
outbuf[1]=0x00;
break;
case 4: printf(" Set device AT90S4414 ---> ");
outbuf[1]=0x00;
break;
case 5: printf(" Set device AT90S8515 ---> ");
outbuf[1]=0x38;
break;
}
outbuf[0]=0x54;
write (ser,outbuf,2);
2006-05-21 19:43:07 +02:00
usleep(10000);
2006-05-21 19:42:31 +02:00
read (ser,inbuf,1);
if (inbuf[0]==0x0D)
printf("OK\n");
else
{
printf("ERROR: No response\n");
end_prg(1);
}
2006-05-21 19:43:07 +02:00
/* switch on red LED */
write (ser,"x",1);
usleep(10000);
read (ser,inbuf,1);
2006-05-21 19:42:31 +02:00
/* enter programming mode */
printf(" Set Prg Mode -----------> ");
write (ser,"P",1);
2006-05-21 19:43:07 +02:00
usleep(10000);
2006-05-21 19:42:31 +02:00
read (ser,inbuf,1);
if (inbuf[0]==0x0D)
printf("OK\n");
else
{
2006-05-21 19:43:07 +02:00
printf("ERROR: No response\n");
2006-05-21 19:42:31 +02:00
end_prg(1);
}
/* check the signature */
printf(" Checking Signature -----> ");
write (ser,"s",1);
2006-05-21 19:43:07 +02:00
usleep(10000);
2006-05-21 19:42:31 +02:00
read (ser,inbuf,3);
if (sign[avr_device][0] == inbuf[0] && sign[avr_device][1] == inbuf[1] && sign[avr_device][2] == inbuf[2])
printf ("OK\n");
else
{
2006-05-21 19:43:07 +02:00
printf("ERROR: Wrong signature: ");
printf ("%2.2X %2.2X %2.2X <-> ",inbuf[0], inbuf[1], inbuf[2]);
printf ("%2.2X %2.2X %2.2X\n",sign[avr_device][0], sign[avr_device][1], sign[avr_device][2]);
2006-05-21 19:42:31 +02:00
end_prg(2);
}
2006-05-21 19:43:07 +02:00
if (!reset)
2006-05-21 19:42:31 +02:00
{
2006-05-21 19:43:07 +02:00
/* clear the chip */
printf(" Erase FLASH & EEPROM ---> ");
write (ser,"e",1);
usleep(10000);
read (ser,inbuf,1);
if (inbuf[0]==0x0D)
printf("OK\n");
else
{
printf("ERROR: No response\n");
2006-05-21 19:42:31 +02:00
end_prg(2);
2006-05-21 19:43:07 +02:00
}
2006-05-21 19:42:31 +02:00
}
2006-05-21 19:43:07 +02:00
/* reset the chip after clear */
2006-05-21 19:42:31 +02:00
printf(" Reseting AVR-Device ----> ");
write (ser,"L",1);
2006-05-21 19:43:07 +02:00
usleep(10000);
2006-05-21 19:42:31 +02:00
read (ser,inbuf,1);
2006-05-21 19:43:07 +02:00
if (inbuf[0]!=0x0D)
{
printf("ERROR: No response\n");
end_prg(2);
2006-05-21 19:42:31 +02:00
}
2006-05-21 19:43:07 +02:00
if (reset)
{
printf("OK\n");
end_prg(2);
}
/* enter programming mode */
2006-05-21 19:42:31 +02:00
write (ser,"P",1);
2006-05-21 19:43:07 +02:00
usleep(10000);
2006-05-21 19:42:31 +02:00
read (ser,inbuf,1);
if (inbuf[0]==0x0D)
printf("OK\n");
else
{
2006-05-21 19:43:07 +02:00
printf("ERROR: No response\n");
2006-05-21 19:42:31 +02:00
end_prg(2);
}
2006-05-21 19:43:07 +02:00
/* writing flash */
if (flash == 2)
2006-05-21 19:42:31 +02:00
{
printf(" Writing FLASH DATA -----> ");
fdat = open(flash_file, O_RDWR);
if (fdat <0)
{
2006-05-21 19:43:07 +02:00
printf("ERROR: <%s> not found\n", flash_file);
2006-05-21 19:42:31 +02:00
}
else
{
t=0;
2006-05-21 19:43:07 +02:00
while (read (fdat,databuf,2) == 2 && t < (mem_size[avr_device][0]/2))
2006-05-21 19:42:31 +02:00
{
outbuf[0]=0x41;
outbuf[1]=(unsigned char)(t>>8) & 0xFF;
outbuf[2]=(unsigned char)t & 0xFF;
write (ser,outbuf,3);
read (ser,inbuf,1);
outbuf[0]=0x63; //Lowbyte
outbuf[1]=databuf[0];
write (ser,outbuf,2);
read (ser,inbuf,1);
outbuf[0]=0x43; //Highbyte
outbuf[1]=databuf[1];
write (ser,outbuf,2);
read (ser,inbuf,1);
t++;
}
close (fdat);
2006-05-21 19:43:07 +02:00
printf("%4.4Xh bytes\n",t*2);
2006-05-21 19:42:31 +02:00
}
}
2006-05-21 19:43:07 +02:00
/* verify flash */
if (verify == 1 && flash == 2)
2006-05-21 19:42:31 +02:00
{
printf(" Verify FLASH DATA ------> ");
fdat = open(flash_file, O_RDWR);
if (fdat <0)
{
2006-05-21 19:43:07 +02:00
printf("ERROR: <%s> not found\n", flash_file);
2006-05-21 19:42:31 +02:00
}
else
{
t=0;
2006-05-21 19:43:07 +02:00
while (read (fdat,databuf,2) == 2 && t < (mem_size[avr_device][0]/2))
2006-05-21 19:42:31 +02:00
{
outbuf[0]=0x41;
outbuf[1]=(unsigned char)(t>>8) & 0xFF;
outbuf[2]=(unsigned char)t & 0xFF;
write (ser,outbuf,3);
read (ser,inbuf,1);
write (ser,"R",1);
read (ser,inbuf,2);
if (inbuf[0]!=databuf[1] || inbuf[1]!=databuf[0])
printf("Verify Error %4.4X: %2.2X.%2.2X - %2.2X.%2.2X\n", t, databuf[1], databuf[0], inbuf[0], inbuf[1]);
t++;
}
close (fdat);
2006-05-21 19:43:07 +02:00
printf("%4.4Xh bytes\n",t*2);
2006-05-21 19:42:31 +02:00
}
}
2006-05-21 19:43:07 +02:00
/* writing eeprom */
if (eeprom == 2)
2006-05-21 19:42:31 +02:00
{
printf(" Writing EEPROM DATA ----> ");
eedat = open(eeprom_file, O_RDWR);
if (eedat <0)
{
2006-05-21 19:43:07 +02:00
printf("ERROR: <%s> not found\n", eeprom_file);
2006-05-21 19:42:31 +02:00
}
else
{
t=0;
2006-05-21 19:43:07 +02:00
while (read (eedat,databuf,1) == 1 && t < (mem_size[avr_device][1]/2))
2006-05-21 19:42:31 +02:00
{
outbuf[0]=0x41;
outbuf[1]=(unsigned char)(t>>8) & 0xFF;
outbuf[2]=(unsigned char)t & 0xFF;
write (ser,outbuf,3);
read (ser,inbuf,1);
outbuf[0]=0x44;
outbuf[1]=databuf[0];
write (ser,outbuf,2);
read (ser,inbuf,1);
t++;
}
close (eedat);
2006-05-21 19:43:07 +02:00
printf("%4.4Xh bytes\n",t);
2006-05-21 19:42:31 +02:00
}
}
2006-05-21 19:43:07 +02:00
/* verify eeprom */
if (verify == 1 && eeprom == 2)
2006-05-21 19:42:31 +02:00
{
printf(" Verify EEPROM DATA -----> ");
eedat = open(eeprom_file, O_RDWR);
if (eedat <0)
{
2006-05-21 19:43:07 +02:00
printf("ERROR: <%s> not found\n", eeprom_file);
2006-05-21 19:42:31 +02:00
}
else
{
t=0;
2006-05-21 19:43:07 +02:00
while (read (eedat,databuf,1) == 1 && t < (mem_size[avr_device][1]/2))
2006-05-21 19:42:31 +02:00
{
outbuf[0]=0x41;
outbuf[1]=(unsigned char)(t>>8) & 0xFF;
outbuf[2]=(unsigned char)t & 0xFF;
write (ser,outbuf,3);
read (ser,inbuf,1);
outbuf[0]=0x64;
write (ser,outbuf,1);
read (ser,inbuf,1);
if (inbuf[0]!=databuf[0])
printf("Verify Error %4.4X: %2.2X - %2.2X\n", t, databuf[0], inbuf[0]);
t++;
}
close (eedat);
printf("%4.4Xh Bytes\n",t);
}
}
2006-05-21 19:43:07 +02:00
/* release chip */
2006-05-21 19:42:31 +02:00
printf(" Leave Prg Mode ---------> ");
write (ser,"L",1);
read (ser,inbuf,1);
if (inbuf[0]==0x0D)
printf("OK\n");
else
{
2006-05-21 19:43:07 +02:00
printf("ERROR: No response\n");
2006-05-21 19:42:31 +02:00
end_prg(2);
}
end_prg(2);
}
void end_prg(char level)
{
switch (level)
{
case 2: write (ser,"y",1);
read (ser,0,1);
case 1: tcsetattr(ser,TCSANOW,&oldtio);
case 0: printf("\n***************************************\n\n");
}
2006-05-21 19:43:07 +02:00
exit (0);
2006-05-21 19:42:31 +02:00
}
2006-05-21 19:43:19 +02:00
void show_usage() {
printf("USAGE:\n");
printf(" isp_down [OPTIONS] <flash-file> <eeprom-file>\n\n");
printf("OPTIONS:\n");
printf(" -avr <num> selects AVR-device\n");
printf(" 1200 -> AT90S1200 1kB FLASH / 64 bytes EEPROM\n");
printf(" 2313 -> AT90S2313 2kB FLASH / 128 bytes EEPROM\n");
printf(" 2323 -> AT90S2323 2kB FLASH / 128 bytes EEPROM\n");
printf(" 2343 -> AT90S2343 2kB FLASH / 128 bytes EEPROM\n");
printf(" 4414 -> AT90S4414 4kB FLASH / 256 bytes EEPROM\n");
printf(" 8515 -> AT90S8515 8kB FLASH / 512 bytes EEPROM (default)\n\n");
printf(" -dev <dev> selects RS232-device (default: /dev/ttyS0)\n");
printf(" -flash Write (1st) file to FLASH\n");
printf(" -eeprom Write (2nd) file to EEPROM\n");
printf(" -verify Verify writing\n");
printf(" -reset Only resets AVR\n");
2006-05-21 19:42:31 +02:00
}