First cut at supporting the ATmega 103 which uses bank addressing and
has a 128K flash. Due to the bank addressing required, interactive update of the flash is not supported, though the eeprom can be updated interactively. Both memories can be programmed via non-interactive mode. Intel Hex Record type '04' is now generated as required for outputing memory contents that go beyond 64K. git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@78 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
ae8da8be39
commit
799081f34c
|
@ -17,7 +17,7 @@ DIRS = ${BINDIR} ${MANDIR} ${DOCDIR} ${CONFIGDIR}
|
||||||
|
|
||||||
INSTALL = /usr/bin/install -c -o root -g wheel
|
INSTALL = /usr/bin/install -c -o root -g wheel
|
||||||
|
|
||||||
CFLAGS += -g -Wall --pedantic -DCONFIG_DIR=\"${CONFIGDIR}\"
|
CFLAGS = -g -Wall --pedantic -DCONFIG_DIR=\"${CONFIGDIR}\"
|
||||||
|
|
||||||
LDFLAGS =
|
LDFLAGS =
|
||||||
|
|
||||||
|
|
|
@ -78,8 +78,8 @@ struct avrpart parts[] = {
|
||||||
{{0, 512, 0, 0, 9000, 20000, {0x00, 0xff }, NULL}, /* eeprom */
|
{{0, 512, 0, 0, 9000, 20000, {0x00, 0xff }, NULL}, /* eeprom */
|
||||||
{0, 8192, 0, 0, 9000, 20000, {0xff, 0x00 }, NULL}}}, /* flash */
|
{0, 8192, 0, 0, 9000, 20000, {0xff, 0x00 }, NULL}}}, /* flash */
|
||||||
|
|
||||||
{"ATMEGA103", "103", 20000,
|
{"ATMEGA103", "103", 56000*2,
|
||||||
{{0, 4096, 0, 0, 9000, 20000, {0x00, 0xff }, NULL}, /* eeprom */
|
{{0, 4096, 0, 0, 64000, 69000, {0x80, 0x7f }, NULL}, /* eeprom */
|
||||||
{1, 131072, 256, 512, 22000, 56000, {0xff, 0x00 }, NULL}}}, /* flash */
|
{1, 131072, 256, 512, 22000, 56000, {0xff, 0x00 }, NULL}}}, /* flash */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -181,7 +181,7 @@ int avr_cmd(int fd, unsigned char cmd[4], unsigned char res[4])
|
||||||
* read a byte of data from the indicated memory region
|
* read a byte of data from the indicated memory region
|
||||||
*/
|
*/
|
||||||
unsigned char avr_read_byte(int fd, struct avrpart * p,
|
unsigned char avr_read_byte(int fd, struct avrpart * p,
|
||||||
int memtype, unsigned short addr)
|
int memtype, unsigned long addr)
|
||||||
{
|
{
|
||||||
unsigned short offset;
|
unsigned short offset;
|
||||||
unsigned char cmd[4];
|
unsigned char cmd[4];
|
||||||
|
@ -221,7 +221,7 @@ unsigned char avr_read_byte(int fd, struct avrpart * p,
|
||||||
int avr_read(int fd, struct avrpart * p, int memtype)
|
int avr_read(int fd, struct avrpart * p, int memtype)
|
||||||
{
|
{
|
||||||
unsigned char rbyte;
|
unsigned char rbyte;
|
||||||
unsigned short i;
|
unsigned long i;
|
||||||
unsigned char * buf;
|
unsigned char * buf;
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
|
@ -230,7 +230,7 @@ int avr_read(int fd, struct avrpart * p, int memtype)
|
||||||
|
|
||||||
for (i=0; i<size; i++) {
|
for (i=0; i<size; i++) {
|
||||||
rbyte = avr_read_byte(fd, p, memtype, i);
|
rbyte = avr_read_byte(fd, p, memtype, i);
|
||||||
fprintf(stderr, " \r%4u 0x%02x", i, rbyte);
|
fprintf(stderr, " \r%4lu 0x%02x", i, rbyte);
|
||||||
buf[i] = rbyte;
|
buf[i] = rbyte;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,11 +240,41 @@ int avr_read(int fd, struct avrpart * p, int memtype)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* write a byte of data to the indicated memory region
|
||||||
|
*/
|
||||||
|
int avr_write_bank(int fd, struct avrpart * p, int memtype,
|
||||||
|
unsigned short bank)
|
||||||
|
{
|
||||||
|
unsigned char cmd[4];
|
||||||
|
unsigned char res[4];
|
||||||
|
|
||||||
|
LED_ON(fd, pinno[PIN_LED_PGM]);
|
||||||
|
LED_OFF(fd, pinno[PIN_LED_ERR]);
|
||||||
|
|
||||||
|
cmd[0] = 0x4c;
|
||||||
|
cmd[1] = bank >> 8; /* high order bits of address */
|
||||||
|
cmd[2] = bank & 0x0ff; /* low order bits of address */
|
||||||
|
cmd[3] = 0; /* these bits are ignored */
|
||||||
|
|
||||||
|
avr_cmd(fd, cmd, res);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* since we don't know what voltage the target AVR is powered by, be
|
||||||
|
* conservative and delay the max amount the spec says to wait
|
||||||
|
*/
|
||||||
|
usleep(p->mem[memtype].max_write_delay);
|
||||||
|
|
||||||
|
LED_OFF(fd, pinno[PIN_LED_PGM]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* write a byte of data to the indicated memory region
|
* write a byte of data to the indicated memory region
|
||||||
*/
|
*/
|
||||||
int avr_write_byte(int fd, struct avrpart * p, int memtype,
|
int avr_write_byte(int fd, struct avrpart * p, int memtype,
|
||||||
unsigned short addr, unsigned char data)
|
unsigned long addr, unsigned char data)
|
||||||
{
|
{
|
||||||
unsigned char cmd[4];
|
unsigned char cmd[4];
|
||||||
unsigned char res[4];
|
unsigned char res[4];
|
||||||
|
@ -257,14 +287,20 @@ int avr_write_byte(int fd, struct avrpart * p, int memtype,
|
||||||
/* order here is very important, AVR_M_EEPROM, AVR_M_FLASH, AVR_M_FLASH+1 */
|
/* order here is very important, AVR_M_EEPROM, AVR_M_FLASH, AVR_M_FLASH+1 */
|
||||||
static unsigned char cmdbyte[3] = { 0xc0, 0x40, 0x48 };
|
static unsigned char cmdbyte[3] = { 0xc0, 0x40, 0x48 };
|
||||||
|
|
||||||
|
if (!p->mem[memtype].banked) {
|
||||||
/*
|
/*
|
||||||
* check to see if the write is necessary by reading the existing
|
* check to see if the write is necessary by reading the existing
|
||||||
* value and only write if we are changing the value
|
* value and only write if we are changing the value; we can't
|
||||||
|
* use this optimization for banked addressing.
|
||||||
*/
|
*/
|
||||||
b = avr_read_byte(fd, p, memtype, addr);
|
b = avr_read_byte(fd, p, memtype, addr);
|
||||||
if (b == data) {
|
if (b == data) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addr = addr % p->mem[memtype].bank_size;
|
||||||
|
}
|
||||||
|
|
||||||
LED_ON(fd, pinno[PIN_LED_PGM]);
|
LED_ON(fd, pinno[PIN_LED_PGM]);
|
||||||
LED_OFF(fd, pinno[PIN_LED_ERR]);
|
LED_OFF(fd, pinno[PIN_LED_ERR]);
|
||||||
|
@ -284,6 +320,16 @@ int avr_write_byte(int fd, struct avrpart * p, int memtype,
|
||||||
|
|
||||||
avr_cmd(fd, cmd, res);
|
avr_cmd(fd, cmd, res);
|
||||||
|
|
||||||
|
if (p->mem[memtype].banked) {
|
||||||
|
/*
|
||||||
|
* in banked addressing, single bytes to written to the memory
|
||||||
|
* page complete immediately, we only need to delay when we commit
|
||||||
|
* the whole page via the avr_write_bank() routine.
|
||||||
|
*/
|
||||||
|
LED_OFF(fd, pinno[PIN_LED_PGM]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
tries = 0;
|
tries = 0;
|
||||||
ready = 0;
|
ready = 0;
|
||||||
while (!ready) {
|
while (!ready) {
|
||||||
|
@ -298,14 +344,15 @@ int avr_write_byte(int fd, struct avrpart * p, int memtype,
|
||||||
* specified for the chip.
|
* specified for the chip.
|
||||||
*/
|
*/
|
||||||
usleep(p->mem[memtype].max_write_delay);
|
usleep(p->mem[memtype].max_write_delay);
|
||||||
ready = 1;
|
r = avr_read_byte(fd, p, memtype, addr);
|
||||||
}
|
}
|
||||||
else if (r == data) {
|
|
||||||
|
if (r == data) {
|
||||||
ready = 1;
|
ready = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tries++;
|
tries++;
|
||||||
if (!ready && tries > 10) {
|
if (!ready && tries > 5) {
|
||||||
/*
|
/*
|
||||||
* we couldn't write the data, indicate our displeasure by
|
* we couldn't write the data, indicate our displeasure by
|
||||||
* returning an error code
|
* returning an error code
|
||||||
|
@ -335,8 +382,7 @@ int avr_write(int fd, struct avrpart * p, int memtype, int size)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
int wsize;
|
int wsize;
|
||||||
unsigned char * buf;
|
unsigned long i;
|
||||||
unsigned short i;
|
|
||||||
unsigned char data;
|
unsigned char data;
|
||||||
int werror;
|
int werror;
|
||||||
|
|
||||||
|
@ -344,7 +390,6 @@ int avr_write(int fd, struct avrpart * p, int memtype, int size)
|
||||||
|
|
||||||
werror = 0;
|
werror = 0;
|
||||||
|
|
||||||
buf = p->mem[memtype].buf;
|
|
||||||
wsize = p->mem[memtype].size;
|
wsize = p->mem[memtype].size;
|
||||||
if (size < wsize) {
|
if (size < wsize) {
|
||||||
wsize = size;
|
wsize = size;
|
||||||
|
@ -359,15 +404,32 @@ int avr_write(int fd, struct avrpart * p, int memtype, int size)
|
||||||
|
|
||||||
for (i=0; i<wsize; i++) {
|
for (i=0; i<wsize; i++) {
|
||||||
/* eeprom or low byte of flash */
|
/* eeprom or low byte of flash */
|
||||||
data = buf[i];
|
data = p->mem[memtype].buf[i];
|
||||||
rc = avr_write_byte(fd, p, memtype, i, data);
|
rc = avr_write_byte(fd, p, memtype, i, data);
|
||||||
fprintf(stderr, " \r%4u 0x%02x", i, data);
|
fprintf(stderr, " \r%4lu 0x%02x", i, data);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
fprintf(stderr, " ***failed; ");
|
fprintf(stderr, " ***failed; ");
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
LED_ON(fd, pinno[PIN_LED_ERR]);
|
LED_ON(fd, pinno[PIN_LED_ERR]);
|
||||||
werror = 1;
|
werror = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p->mem[memtype].banked) {
|
||||||
|
if (((i % p->mem[memtype].bank_size) == p->mem[memtype].bank_size-1) ||
|
||||||
|
(i == wsize-1)) {
|
||||||
|
rc = avr_write_bank(fd, p, memtype, i/p->mem[memtype].bank_size);
|
||||||
|
if (rc) {
|
||||||
|
fprintf(stderr,
|
||||||
|
" *** bank %ld (addresses 0x%04lx - 0x%04lx) failed to write\n",
|
||||||
|
i % p->mem[memtype].bank_size,
|
||||||
|
i-p->mem[memtype].bank_size+1, i);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
LED_ON(fd, pinno[PIN_LED_ERR]);
|
||||||
|
werror = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (werror) {
|
if (werror) {
|
||||||
/*
|
/*
|
||||||
* make sure the error led stay on if there was a previous write
|
* make sure the error led stay on if there was a previous write
|
||||||
|
@ -377,6 +439,7 @@ int avr_write(int fd, struct avrpart * p, int memtype, int size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
|
|
|
@ -110,12 +110,15 @@ unsigned char avr_txrx(int fd, unsigned char byte);
|
||||||
int avr_cmd(int fd, unsigned char cmd[4], unsigned char res[4]);
|
int avr_cmd(int fd, unsigned char cmd[4], unsigned char res[4]);
|
||||||
|
|
||||||
unsigned char avr_read_byte(int fd, struct avrpart * p,
|
unsigned char avr_read_byte(int fd, struct avrpart * p,
|
||||||
int memtype, unsigned short addr);
|
int memtype, unsigned long addr);
|
||||||
|
|
||||||
int avr_read(int fd, struct avrpart * p, int memtype);
|
int avr_read(int fd, struct avrpart * p, int memtype);
|
||||||
|
|
||||||
|
int avr_write_bank(int fd, struct avrpart * p, int memtype,
|
||||||
|
unsigned short bank);
|
||||||
|
|
||||||
int avr_write_byte(int fd, struct avrpart * p, int memtype,
|
int avr_write_byte(int fd, struct avrpart * p, int memtype,
|
||||||
unsigned short addr, unsigned char data);
|
unsigned long addr, unsigned char data);
|
||||||
|
|
||||||
int avr_write(int fd, struct avrpart * p, int memtype, int size);
|
int avr_write(int fd, struct avrpart * p, int memtype, int size);
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ int b2ihex(unsigned char * inbuf, int bufsize,
|
||||||
{
|
{
|
||||||
unsigned char * buf;
|
unsigned char * buf;
|
||||||
unsigned int nextaddr;
|
unsigned int nextaddr;
|
||||||
int n, nbytes;
|
int n, nbytes, n_64k;
|
||||||
int i;
|
int i;
|
||||||
unsigned char cksum;
|
unsigned char cksum;
|
||||||
|
|
||||||
|
@ -108,6 +108,7 @@ int b2ihex(unsigned char * inbuf, int bufsize,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n_64k = 0;
|
||||||
nextaddr = startaddr;
|
nextaddr = startaddr;
|
||||||
buf = inbuf;
|
buf = inbuf;
|
||||||
nbytes = 0;
|
nbytes = 0;
|
||||||
|
@ -117,6 +118,9 @@ int b2ihex(unsigned char * inbuf, int bufsize,
|
||||||
if (n > bufsize)
|
if (n > bufsize)
|
||||||
n = bufsize;
|
n = bufsize;
|
||||||
|
|
||||||
|
if ((nextaddr + n) > 0x10000)
|
||||||
|
n = 0x10000 - nextaddr;
|
||||||
|
|
||||||
if (n) {
|
if (n) {
|
||||||
cksum = 0;
|
cksum = 0;
|
||||||
fprintf(outf, ":%02X%04X00", n, nextaddr);
|
fprintf(outf, ":%02X%04X00", n, nextaddr);
|
||||||
|
@ -132,6 +136,20 @@ int b2ihex(unsigned char * inbuf, int bufsize,
|
||||||
nbytes += n;
|
nbytes += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nextaddr >= 0x10000) {
|
||||||
|
int lo, hi;
|
||||||
|
/* output an extended address record */
|
||||||
|
n_64k++;
|
||||||
|
lo = n_64k & 0xff;
|
||||||
|
hi = (n_64k >> 8) & 0xff;
|
||||||
|
cksum = 0;
|
||||||
|
fprintf(outf, ":02000004%02X%02X", hi, lo);
|
||||||
|
cksum += 2 + 0 + 4 + hi + lo;
|
||||||
|
cksum = -cksum;
|
||||||
|
fprintf(outf, "%02X\n", cksum);
|
||||||
|
nextaddr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* advance to next 'recsize' bytes */
|
/* advance to next 'recsize' bytes */
|
||||||
buf += n;
|
buf += n;
|
||||||
bufsize -= n;
|
bufsize -= n;
|
||||||
|
|
|
@ -283,6 +283,7 @@ int cmd_dump(int fd, struct avrpart * p, int argc, char * argv[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int cmd_write(int fd, struct avrpart * p, int argc, char * argv[])
|
int cmd_write(int fd, struct avrpart * p, int argc, char * argv[])
|
||||||
{
|
{
|
||||||
char * e;
|
char * e;
|
||||||
|
@ -313,6 +314,12 @@ int cmd_write(int fd, struct avrpart * p, int argc, char * argv[])
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p->mem[memtype].banked) {
|
||||||
|
fprintf(stderr, "%s (write): sorry, interactive write of bank addressed "
|
||||||
|
"memory is not supported\n", progname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
maxsize = p->mem[memtype].size;
|
maxsize = p->mem[memtype].size;
|
||||||
|
|
||||||
addr = strtoul(argv[2], &e, 0);
|
addr = strtoul(argv[2], &e, 0);
|
||||||
|
|
Loading…
Reference in New Issue