2003-03-23 Theodore A. Roth
* avr.c (avr_write): Add call to pgm->write_setup() before the write loop.
* avr910.c: Change all show_func_info() calls to no_show_func_info().
Add read/write to/from flash/eeprom memory functionality.
* pgm.c: Initialize pgm->write_setup.
* pgm.h: Add write_setup field to PROGRAMMER structure.
* ser_posix.c: Remove unneeded cast in verbosity code.
Index: avr.c
===================================================================
RCS file: /cvsroot/avrdude/avrdude/avr.c,v
retrieving revision 1.54
diff -u -r1.54 avr.c
--- avr.c 23 Mar 2003 23:22:50 -0000 1.54
+++ avr.c 24 Mar 2003 06:55:32 -0000
@@ -733,6 +733,10 @@
}
}
+ if (pgm->write_setup) {
+ pgm->write_setup(pgm, p, m);
+ }
+
for (i=0; ibuf[i];
if (verbose) {
Index: avr910.c
===================================================================
RCS file: /cvsroot/avrdude/avrdude/avr910.c,v
retrieving revision 1.3
diff -u -r1.3 avr910.c
--- avr910.c 17 Mar 2003 06:20:01 -0000 1.3
+++ avr910.c 24 Mar 2003 06:55:33 -0000
@@ -67,7 +67,7 @@
static int avr910_drain(PROGRAMMER * pgm, int display)
{
- show_func_info();
+ no_show_func_info();
return serial_drain(pgm->fd, display);
}
@@ -139,14 +139,29 @@
return 0;
}
+
+static void avr910_enter_prog_mode(PROGRAMMER * pgm)
+{
+ avr910_send(pgm, "P", 1);
+ avr910_vfy_cmd_sent(pgm, "enter prog mode");
+}
+
+
+static void avr910_leave_prog_mode(PROGRAMMER * pgm)
+{
+ avr910_send(pgm, "L", 1);
+ avr910_vfy_cmd_sent(pgm, "leave prog mode");
+}
+
+
/*
* issue the 'program enable' command to the AVR device
*/
static int avr910_program_enable(PROGRAMMER * pgm, AVRPART * p)
{
- show_func_info();
+ no_show_func_info();
- return -1;
+ return 0;
}
@@ -176,20 +191,6 @@
}
-static void avr910_enter_prog_mode(PROGRAMMER * pgm)
-{
- avr910_send(pgm, "P", 1);
- avr910_vfy_cmd_sent(pgm, "enter prog mode");
-}
-
-
-static void avr910_leave_prog_mode(PROGRAMMER * pgm)
-{
- avr910_send(pgm, "L", 1);
- avr910_vfy_cmd_sent(pgm, "leave prog mode");
-}
-
-
/*
* initialize the AVR device and prepare it to accept commands
*/
@@ -203,7 +204,7 @@
unsigned char c;
int dev_supported = 0;
- show_func_info();
+ no_show_func_info();
/* Get the programmer identifier. Programmer returns exactly 7 chars
_without_ the null.*/
@@ -316,7 +317,7 @@
{
int i;
- show_func_info();
+ no_show_func_info();
for (i=0; i<4; i++) {
fprintf(stderr, "cmd[%d] = 0x%02x\n", i, cmd[i]);
@@ -352,11 +353,137 @@
static void avr910_display(PROGRAMMER * pgm, char * p)
{
- show_func_info();
+ no_show_func_info();
return;
}
+
+static void avr910_set_addr(PROGRAMMER * pgm, unsigned long addr)
+{
+ unsigned char cmd[3];
+
+ cmd[0] = 'A';
+ cmd[1] = (addr >> 8) & 0xff;
+ cmd[2] = addr & 0xff;
+
+ avr910_send(pgm, cmd, sizeof(cmd));
+ avr910_vfy_cmd_sent(pgm, "set addr");
+}
+
+
+/*
+ * For some reason, if we don't do this when writing to flash, the first byte
+ * of flash is not programmed. I susect that the board got out of sync after
+ * the erase and sending another command gets us back in sync. -TRoth
+ */
+static void avr910_write_setup(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
+{
+ if (strcmp(m->desc, "flash") == 0) {
+ avr910_send(pgm, "y", 1);
+ avr910_vfy_cmd_sent(pgm, "clear LED");
+ }
+}
+
+
+static int avr910_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned long addr, unsigned char value)
+{
+ unsigned char cmd[2];
+
+ no_show_func_info();
+
+ if (strcmp(m->desc, "flash") == 0) {
+ if (addr & 0x01) {
+ cmd[0] = 'C'; /* Write Program Mem high byte */
+ }
+ else {
+ cmd[0] = 'c';
+ }
+
+ addr >>= 1;
+ }
+ else if (strcmp(m->desc, "eeprom") == 0) {
+ cmd[0] = 'D';
+ }
+ else {
+ return -1;
+ }
+
+ cmd[1] = value;
+
+ avr910_set_addr(pgm, addr);
+
+ avr910_send(pgm, cmd, sizeof(cmd));
+ avr910_vfy_cmd_sent(pgm, "write byte");
+
+ return 0;
+}
+
+
+static int avr910_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned long addr, unsigned char * value)
+{
+ static int cached = 0;
+ static unsigned char cvalue;
+ static unsigned long caddr;
+
+ if (cached && ((caddr + 1) == addr)) {
+ *value = cvalue;
+ cached = 0;
+ }
+ else {
+ unsigned char buf[2];
+
+ avr910_set_addr(pgm, addr >> 1);
+
+ avr910_send(pgm, "R", 1);
+
+ /* Read back the program mem word (MSB first) */
+ avr910_recv(pgm, buf, sizeof(buf));
+
+ if ((addr & 0x01) == 0) {
+ *value = buf[1];
+ cached = 1;
+ cvalue = buf[0];
+ caddr = addr;
+ }
+ else {
+ *value = buf[0];
+ }
+ }
+
+ return 0;
+}
+
+
+static int avr910_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned long addr, unsigned char * value)
+{
+ avr910_set_addr(pgm, addr);
+ avr910_send(pgm, "d", 1);
+ avr910_recv(pgm, value, 1);
+
+ return 0;
+}
+
+
+static int avr910_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned long addr, unsigned char * value)
+{
+ no_show_func_info();
+
+ if (strcmp(m->desc, "flash") == 0) {
+ return avr910_read_byte_flash(pgm, p, m, addr, value);
+ }
+
+ if (strcmp(m->desc, "eeprom") == 0) {
+ return avr910_read_byte_eeprom(pgm, p, m, addr, value);
+ }
+
+ return -1;
+}
+
/* Signature byte reads are always 3 bytes. */
static int avr910_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
@@ -406,5 +533,8 @@
* optional functions
*/
+ pgm->write_setup = avr910_write_setup;
+ pgm->write_byte = avr910_write_byte;
+ pgm->read_byte = avr910_read_byte;
pgm->read_sig_bytes = avr910_read_sig_bytes;
}
Index: pgm.c
===================================================================
RCS file: /cvsroot/avrdude/avrdude/pgm.c,v
retrieving revision 1.12
diff -u -r1.12 pgm.c
--- pgm.c 23 Mar 2003 23:22:50 -0000 1.12
+++ pgm.c 24 Mar 2003 06:55:33 -0000
@@ -89,6 +89,7 @@
*/
pgm->paged_write = NULL;
pgm->paged_load = NULL;
+ pgm->write_setup = NULL;
pgm->write_byte = NULL;
pgm->read_byte = NULL;
pgm->read_sig_bytes = NULL;
Index: pgm.h
===================================================================
RCS file: /cvsroot/avrdude/avrdude/pgm.h,v
retrieving revision 1.12
diff -u -r1.12 pgm.h
--- pgm.h 23 Mar 2003 23:22:50 -0000 1.12
+++ pgm.h 24 Mar 2003 06:55:33 -0000
@@ -66,6 +66,7 @@
int page_size, int n_bytes);
int (*paged_load) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
int page_size, int n_bytes);
+ void (*write_setup) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
int (*write_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
unsigned long addr, unsigned char value);
int (*read_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
Index: ser_posix.c
===================================================================
RCS file: /cvsroot/avrdude/avrdude/ser_posix.c,v
retrieving revision 1.5
diff -u -r1.5 ser_posix.c
--- ser_posix.c 24 Mar 2003 02:37:33 -0000 1.5
+++ ser_posix.c 24 Mar 2003 06:55:33 -0000
@@ -168,14 +168,14 @@
fprintf(stderr, "%s: Send: ", progname);
while (buflen) {
- char c = *buf;
+ unsigned char c = *buf;
if (isprint(c)) {
fprintf(stderr, "%c ", c);
}
else {
fprintf(stderr, ". ");
}
- fprintf(stderr, "[%02x] ", ((unsigned int)c) & 0xff);
+ fprintf(stderr, "[%02x] ", c);
buf++;
buflen--;
@@ -277,14 +277,14 @@
fprintf(stderr, "%s: Recv: ", progname);
while (len) {
- char c = *p;
+ unsigned char c = *p;
if (isprint(c)) {
fprintf(stderr, "%c ", c);
}
else {
fprintf(stderr, ". ");
}
- fprintf(stderr, "[%02x] ", ((unsigned int)c &0xff));
+ fprintf(stderr, "[%02x] ", c);
p++;
len--;