Add support for ATMega163.
Add support for reading/writing ATMega163 lock and fuse bits. Unfortunately, in looking at the specs for other ATMega parts, they use entirely different instruction formats for these commands. Thus, these routines won't work for the ATMega103, for example. Add support for sending raw command bytes via the interactive terminal interface. This allows one to execute any programming instruction on the target device, whether or not avrprog supports it explicitly or not. Thus, one can use this feature to program fuse / lock bits, or access any other feature of a current or future device that avrprog does not know how to do. Add in comments, an experimental instruction format in the configuration file. If this works out, it would allow supporting new parts and non-orthoganal instructions across existing parts without making avrprog code changes. git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@99 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
2437f3d4d0
commit
d0f7b8805c
212
avr.c
212
avr.c
|
@ -49,75 +49,6 @@ extern PROGRAMMER * pgm;
|
||||||
char * avr_version = "$Id$";
|
char * avr_version = "$Id$";
|
||||||
|
|
||||||
|
|
||||||
/* Need to add information for 2323, 2343, and 4414 */
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
struct avrpart parts[] = {
|
|
||||||
{"AT90S1200", "1200", 20000,
|
|
||||||
{{0, 64, 0, 0, 9000, 20000, {0x00, 0xff }, NULL}, /* eeprom */
|
|
||||||
{0, 1024, 0, 0, 9000, 20000, {0xff, 0 }, NULL}}}, /* flash */
|
|
||||||
|
|
||||||
{"AT90S2313", "2313", 20000,
|
|
||||||
{{0, 128, 0, 0, 9000, 20000, {0x80, 0x7f }, NULL}, /* eeprom */
|
|
||||||
{0, 2048, 0, 0, 9000, 20000, {0x7f, 0 }, NULL}}}, /* flash */
|
|
||||||
|
|
||||||
{"AT90S2333", "2333", 20000,
|
|
||||||
{{0, 128, 0, 0, 9000, 20000, {0x00, 0xff }, NULL}, /* eeprom */
|
|
||||||
{0, 2048, 0, 0, 9000, 20000, {0xff, 0 }, NULL}}}, /* flash */
|
|
||||||
|
|
||||||
{"AT90S4433", "4433", 20000,
|
|
||||||
{{0, 256, 0, 0, 9000, 20000, {0x00, 0xff }, NULL}, /* eeprom */
|
|
||||||
{0, 4096, 0, 0, 9000, 20000, {0xff, 0 }, NULL}}}, /* flash */
|
|
||||||
|
|
||||||
{"AT90S4434", "4434", 20000,
|
|
||||||
{{0, 256, 0, 0, 9000, 20000, {0x00, 0xff }, NULL}, /* eeprom */
|
|
||||||
{0, 4096, 0, 0, 9000, 20000, {0xff, 0 }, NULL}}}, /* flash */
|
|
||||||
|
|
||||||
{"AT90S8515", "8515", 20000,
|
|
||||||
{{0, 512, 0, 0, 9000, 20000, {0x80, 0x7f }, NULL}, /* eeprom */
|
|
||||||
{0, 8192, 0, 0, 9000, 20000, {0x7f, 0x00 }, NULL}}}, /* flash */
|
|
||||||
|
|
||||||
{"AT90S8535", "8535", 20000,
|
|
||||||
{{0, 512, 0, 0, 9000, 20000, {0x00, 0xff }, NULL}, /* eeprom */
|
|
||||||
{0, 8192, 0, 0, 9000, 20000, {0xff, 0x00 }, NULL}}}, /* flash */
|
|
||||||
|
|
||||||
{"ATMEGA103", "103", 56000*2,
|
|
||||||
{{0, 4096, 0, 0, 64000, 69000, {0x80, 0x7f }, NULL}, /* eeprom */
|
|
||||||
{1, 131072, 256, 512, 22000, 56000, {0xff, 0x00 }, NULL}}}, /* flash */
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#define N_AVRPARTS (sizeof(parts)/sizeof(struct avrpart))
|
|
||||||
|
|
||||||
|
|
||||||
int avr_list_parts(FILE * f, char * prefix)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0; i<N_AVRPARTS; i++) {
|
|
||||||
fprintf(f, "%s%s = %s\n",
|
|
||||||
prefix, parts[i].optiontag, parts[i].partdesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct avrpart * avr_find_part(char * p)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0; i<N_AVRPARTS; i++) {
|
|
||||||
if (strcmp(parts[i].optiontag, p)==0) {
|
|
||||||
return &parts[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
AVRPART * avr_new_part(void)
|
AVRPART * avr_new_part(void)
|
||||||
{
|
{
|
||||||
AVRPART * p;
|
AVRPART * p;
|
||||||
|
@ -228,6 +159,133 @@ int avr_cmd(int fd, unsigned char cmd[4], unsigned char res[4])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read a calibration byte
|
||||||
|
*/
|
||||||
|
unsigned char avr_read_calibration(int fd, AVRPART * p)
|
||||||
|
{
|
||||||
|
unsigned char cmd[4];
|
||||||
|
unsigned char res[4];
|
||||||
|
|
||||||
|
LED_ON(fd, pgm->pinno[PIN_LED_PGM]);
|
||||||
|
LED_OFF(fd, pgm->pinno[PIN_LED_ERR]);
|
||||||
|
|
||||||
|
cmd[0] = 0x38;
|
||||||
|
cmd[1] = 0x00; /* don't care */
|
||||||
|
cmd[2] = 0x00;
|
||||||
|
cmd[3] = 0x00; /* don't care */
|
||||||
|
|
||||||
|
avr_cmd(fd, cmd, res);
|
||||||
|
|
||||||
|
LED_OFF(fd, pgm->pinno[PIN_LED_PGM]);
|
||||||
|
|
||||||
|
return res[3]; /* calibration byte */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read a fuse byte
|
||||||
|
*/
|
||||||
|
unsigned char avr_read_fuse(int fd, AVRPART * p, int high)
|
||||||
|
{
|
||||||
|
unsigned char cmd[4];
|
||||||
|
unsigned char res[4];
|
||||||
|
static unsigned char cmdbyte1[2] = { 0x50, 0x58 };
|
||||||
|
static unsigned char cmdbyte2[2] = { 0x00, 0x08 };
|
||||||
|
|
||||||
|
LED_ON(fd, pgm->pinno[PIN_LED_PGM]);
|
||||||
|
LED_OFF(fd, pgm->pinno[PIN_LED_ERR]);
|
||||||
|
|
||||||
|
cmd[0] = cmdbyte1[high];
|
||||||
|
cmd[1] = cmdbyte2[high];
|
||||||
|
cmd[2] = 0; /* don't care */
|
||||||
|
cmd[3] = 0; /* don't care */
|
||||||
|
|
||||||
|
avr_cmd(fd, cmd, res);
|
||||||
|
|
||||||
|
LED_OFF(fd, pgm->pinno[PIN_LED_PGM]);
|
||||||
|
|
||||||
|
return res[3]; /* fuse bits */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* write a fuse byte
|
||||||
|
*/
|
||||||
|
int avr_write_fuse(int fd, AVRPART * p, int high, unsigned char b)
|
||||||
|
{
|
||||||
|
unsigned char cmd[4];
|
||||||
|
unsigned char res[4];
|
||||||
|
static unsigned char cmdbyte[2] = { 0xa0, 0xa8 };
|
||||||
|
|
||||||
|
LED_ON(fd, pgm->pinno[PIN_LED_PGM]);
|
||||||
|
LED_OFF(fd, pgm->pinno[PIN_LED_ERR]);
|
||||||
|
|
||||||
|
cmd[0] = 0xac;
|
||||||
|
cmd[1] = cmdbyte[high];
|
||||||
|
cmd[2] = 0x00; /* don't care */
|
||||||
|
cmd[3] = b; /* fuse bits */
|
||||||
|
|
||||||
|
avr_cmd(fd, cmd, res);
|
||||||
|
|
||||||
|
usleep(2000);
|
||||||
|
|
||||||
|
LED_OFF(fd, pgm->pinno[PIN_LED_PGM]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read a lock byte
|
||||||
|
*/
|
||||||
|
unsigned char avr_read_lock(int fd, AVRPART * p)
|
||||||
|
{
|
||||||
|
unsigned char cmd[4];
|
||||||
|
unsigned char res[4];
|
||||||
|
|
||||||
|
LED_ON(fd, pgm->pinno[PIN_LED_PGM]);
|
||||||
|
LED_OFF(fd, pgm->pinno[PIN_LED_ERR]);
|
||||||
|
|
||||||
|
cmd[0] = 0x58;
|
||||||
|
cmd[1] = 0x00;
|
||||||
|
cmd[2] = 0;
|
||||||
|
cmd[3] = 0; /* don't care */
|
||||||
|
|
||||||
|
avr_cmd(fd, cmd, res);
|
||||||
|
|
||||||
|
LED_OFF(fd, pgm->pinno[PIN_LED_PGM]);
|
||||||
|
|
||||||
|
return res[3]; /* lock bits */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* write a lock byte
|
||||||
|
*/
|
||||||
|
int avr_write_lock(int fd, AVRPART * p, unsigned char b)
|
||||||
|
{
|
||||||
|
unsigned char cmd[4];
|
||||||
|
unsigned char res[4];
|
||||||
|
|
||||||
|
LED_ON(fd, pgm->pinno[PIN_LED_PGM]);
|
||||||
|
LED_OFF(fd, pgm->pinno[PIN_LED_ERR]);
|
||||||
|
|
||||||
|
cmd[0] = 0x5c;
|
||||||
|
cmd[1] = 0xe0;
|
||||||
|
cmd[2] = 0; /* don't care */
|
||||||
|
cmd[3] = b; /* lock bits */
|
||||||
|
|
||||||
|
avr_cmd(fd, cmd, res);
|
||||||
|
|
||||||
|
usleep(2000);
|
||||||
|
|
||||||
|
LED_OFF(fd, pgm->pinno[PIN_LED_PGM]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* read a byte of data from the indicated memory region
|
* read a byte of data from the indicated memory region
|
||||||
*/
|
*/
|
||||||
|
@ -265,19 +323,20 @@ unsigned char avr_read_byte(int fd, AVRPART * p,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read the entirety of the specified memory type into the
|
* Read the entirety of the specified memory type into the
|
||||||
* corresponding buffer of the avrpart pointed to by 'p'.
|
* corresponding buffer of the avrpart pointed to by 'p'. If size =
|
||||||
|
* 0, read the entire contents, otherwize, read 'size' bytes.
|
||||||
*
|
*
|
||||||
* Return the number of bytes read, or -1 if an error occurs.
|
* Return the number of bytes read, or -1 if an error occurs. */
|
||||||
*/
|
int avr_read(int fd, AVRPART * p, int memtype, int size)
|
||||||
int avr_read(int fd, AVRPART * p, int memtype)
|
|
||||||
{
|
{
|
||||||
unsigned char rbyte;
|
unsigned char rbyte;
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
unsigned char * buf;
|
unsigned char * buf;
|
||||||
int size;
|
|
||||||
|
|
||||||
buf = p->mem[memtype].buf;
|
buf = p->mem[memtype].buf;
|
||||||
|
if (size == 0) {
|
||||||
size = p->mem[memtype].size;
|
size = p->mem[memtype].size;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
@ -292,6 +351,9 @@ int avr_read(int fd, AVRPART * p, int memtype)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* write a byte of data to the indicated memory region
|
* write a byte of data to the indicated memory region
|
||||||
*/
|
*/
|
||||||
|
@ -643,6 +705,8 @@ char * avr_memtstr(int memtype)
|
||||||
switch (memtype) {
|
switch (memtype) {
|
||||||
case AVR_M_EEPROM : return "eeprom"; break;
|
case AVR_M_EEPROM : return "eeprom"; break;
|
||||||
case AVR_M_FLASH : return "flash"; break;
|
case AVR_M_FLASH : return "flash"; break;
|
||||||
|
case AVR_M_FUSE : return "fuse-bit"; break;
|
||||||
|
case AVR_M_LOCK : return "fock-bit"; break;
|
||||||
default : return "unknown-memtype"; break;
|
default : return "unknown-memtype"; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
14
avr.h
14
avr.h
|
@ -42,6 +42,8 @@
|
||||||
*/
|
*/
|
||||||
#define AVR_M_EEPROM 0
|
#define AVR_M_EEPROM 0
|
||||||
#define AVR_M_FLASH 1
|
#define AVR_M_FLASH 1
|
||||||
|
#define AVR_M_FUSE 2
|
||||||
|
#define AVR_M_LOCK 3
|
||||||
|
|
||||||
#define AVR_MAXMEMTYPES 2 /* just flash and eeprom */
|
#define AVR_MAXMEMTYPES 2 /* just flash and eeprom */
|
||||||
|
|
||||||
|
@ -86,10 +88,20 @@ 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_calibration(int fd, AVRPART * p);
|
||||||
|
|
||||||
|
unsigned char avr_read_fuse(int fd, AVRPART * p, int high);
|
||||||
|
|
||||||
|
int avr_write_fuse(int fd, AVRPART * p, int high, unsigned char b);
|
||||||
|
|
||||||
|
unsigned char avr_read_lock(int fd, AVRPART * p);
|
||||||
|
|
||||||
|
int avr_write_lock(int fd, AVRPART * p, unsigned char b);
|
||||||
|
|
||||||
unsigned char avr_read_byte(int fd, AVRPART * p,
|
unsigned char avr_read_byte(int fd, AVRPART * p,
|
||||||
int memtype, unsigned long addr);
|
int memtype, unsigned long addr);
|
||||||
|
|
||||||
int avr_read(int fd, AVRPART * p, int memtype);
|
int avr_read(int fd, AVRPART * p, int memtype, int size);
|
||||||
|
|
||||||
int avr_write_bank(int fd, AVRPART * p, int memtype,
|
int avr_write_bank(int fd, AVRPART * p, int memtype,
|
||||||
unsigned short bank);
|
unsigned short bank);
|
||||||
|
|
|
@ -360,6 +360,25 @@ part
|
||||||
readback_p1 = 0xff;
|
readback_p1 = 0xff;
|
||||||
readback_p2 = 0xff;
|
readback_p2 = 0xff;
|
||||||
;
|
;
|
||||||
|
/*
|
||||||
|
instructions
|
||||||
|
instr "pe", "programming enable" [ "1010 1100", "0101 0011", "xxxx xxxx", "xxxx xxxx" ];
|
||||||
|
instr "ce", "chip erase" [ "1010 1100", "100x xxxx", "xxxx xxxx", "xxxx xxxx" ];
|
||||||
|
instr "rpm", "read program memory" [ "0010 H000", "xxxa aaaa", "bbbb bbbb", "oooo oooo" ];
|
||||||
|
instr "lpmp" "load program memory page" [ "0100 H000", "xxxx xxxx", "xxbb bbbb", "iiii iiii" ];
|
||||||
|
instr "wpmp", "write program memory page" [ "0100 1100", "xxxa aaaa", "bbxx xxxx", "xxxx xxxx" ];
|
||||||
|
instr "rep", "read eeprom memory" [ "1010 0000", "xxxx xxxa", "bbbb bbbb", "oooo oooo" ];
|
||||||
|
instr "wep", "write eeprom memory" [ "1100 0000", "xxxx xxxa", "bbbb bbbb", "iiii iiii" ];
|
||||||
|
instr "rlb", "read lock bits" [ "0101 1000", "0000 0000", "xxxx 0xxx", "xxoo oooo" ];
|
||||||
|
instr "wlb", "write lock bits" [ "1010 1100", "111x xxxx", "xxxx xxxx", "11ii iiii" ];
|
||||||
|
instr "rsb", "read signature byte" [ "0011 0000", "xxxx xxxx", "xxxx xxbb", "oooo oooo" ];
|
||||||
|
instr "wfb", "write fuse bits" [ "1010 1100", "1010 0000", "xxxx xxxx", "ii11 iiii" ];
|
||||||
|
instr "wfhb", "write fuse high bits" [ "1010 1100", "1010 1000", "xxxx xxxx", "1111 1iii" ];
|
||||||
|
instr "rfb", "read fuse bits" [ "0101 0000", "0000 0000", "xxxx xxxx", "ooxx oooo" ];
|
||||||
|
instr "rfhb", "read fuse high bits" [ "0101 1000", "0000 1000", "xxxx xxxx", "xxxx 1ooo" ];
|
||||||
|
instr "rcb", "read calibration byte" [ "0011 1000", "xxxx xxxx", "0000 0000", "oooo oooo" ];
|
||||||
|
;
|
||||||
|
*/
|
||||||
;
|
;
|
||||||
|
|
||||||
part
|
part
|
||||||
|
|
4
main.c
4
main.c
|
@ -893,7 +893,7 @@ int main(int argc, char * argv [])
|
||||||
*/
|
*/
|
||||||
fprintf(stderr, "%s: reading %s memory:\n",
|
fprintf(stderr, "%s: reading %s memory:\n",
|
||||||
progname, avr_memtstr(memtype));
|
progname, avr_memtstr(memtype));
|
||||||
rc = avr_read(fd, p, memtype);
|
rc = avr_read(fd, p, memtype, 0);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
|
fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
|
||||||
progname, avr_memtstr(memtype), rc);
|
progname, avr_memtstr(memtype), rc);
|
||||||
|
@ -969,7 +969,7 @@ int main(int argc, char * argv [])
|
||||||
progname, avr_memtstr(memtype), inputf);
|
progname, avr_memtstr(memtype), inputf);
|
||||||
fprintf(stderr, "%s: reading on-chip %s data:\n",
|
fprintf(stderr, "%s: reading on-chip %s data:\n",
|
||||||
progname, avr_memtstr(memtype));
|
progname, avr_memtstr(memtype));
|
||||||
rc = avr_read(fd, v, memtype);
|
rc = avr_read(fd, v, memtype, vsize);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
|
fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
|
||||||
progname, avr_memtstr(memtype), rc);
|
progname, avr_memtstr(memtype), rc);
|
||||||
|
|
24
ppi.c
24
ppi.c
|
@ -35,6 +35,8 @@
|
||||||
|
|
||||||
#include "ppi.h"
|
#include "ppi.h"
|
||||||
|
|
||||||
|
#define SLOW_TOGGLE 0
|
||||||
|
|
||||||
extern char * progname;
|
extern char * progname;
|
||||||
|
|
||||||
struct ppipins_t {
|
struct ppipins_t {
|
||||||
|
@ -224,8 +226,17 @@ int ppi_setall(int fd, int reg, int val)
|
||||||
int ppi_pulse(int fd, int reg, int bit)
|
int ppi_pulse(int fd, int reg, int bit)
|
||||||
{
|
{
|
||||||
ppi_toggle(fd, reg, bit);
|
ppi_toggle(fd, reg, bit);
|
||||||
|
|
||||||
|
#if SLOW_TOGGLE
|
||||||
|
usleep(1000);
|
||||||
|
#endif
|
||||||
|
|
||||||
ppi_toggle(fd, reg, bit);
|
ppi_toggle(fd, reg, bit);
|
||||||
|
|
||||||
|
#if SLOW_TOGGLE
|
||||||
|
usleep(1000);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,6 +257,10 @@ int ppi_setpin(int fd, int pin, int value)
|
||||||
else
|
else
|
||||||
ppi_clr(fd, pins[pin].reg, pins[pin].bit);
|
ppi_clr(fd, pins[pin].reg, pins[pin].bit);
|
||||||
|
|
||||||
|
#if SLOW_TOGGLE
|
||||||
|
usleep(1000);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,8 +295,17 @@ int ppi_pulsepin(int fd, int pin)
|
||||||
pin--;
|
pin--;
|
||||||
|
|
||||||
ppi_toggle(fd, pins[pin].reg, pins[pin].bit);
|
ppi_toggle(fd, pins[pin].reg, pins[pin].bit);
|
||||||
|
|
||||||
|
#if SLOW_TOGGLE
|
||||||
|
usleep(1000);
|
||||||
|
#endif
|
||||||
|
|
||||||
ppi_toggle(fd, pins[pin].reg, pins[pin].bit);
|
ppi_toggle(fd, pins[pin].reg, pins[pin].bit);
|
||||||
|
|
||||||
|
#if SLOW_TOGGLE
|
||||||
|
usleep(1000);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
142
term.c
142
term.c
|
@ -64,12 +64,16 @@ int cmd_erase (int fd, struct avrpart * p, int argc, char *argv[]);
|
||||||
|
|
||||||
int cmd_sig (int fd, struct avrpart * p, int argc, char *argv[]);
|
int cmd_sig (int fd, struct avrpart * p, int argc, char *argv[]);
|
||||||
|
|
||||||
|
int cmd_cal (int fd, struct avrpart * p, int argc, char *argv[]);
|
||||||
|
|
||||||
int cmd_part (int fd, struct avrpart * p, int argc, char *argv[]);
|
int cmd_part (int fd, struct avrpart * p, int argc, char *argv[]);
|
||||||
|
|
||||||
int cmd_help (int fd, struct avrpart * p, int argc, char *argv[]);
|
int cmd_help (int fd, struct avrpart * p, int argc, char *argv[]);
|
||||||
|
|
||||||
int cmd_quit (int fd, struct avrpart * p, int argc, char *argv[]);
|
int cmd_quit (int fd, struct avrpart * p, int argc, char *argv[]);
|
||||||
|
|
||||||
|
int cmd_send (int fd, struct avrpart * p, int argc, char *argv[]);
|
||||||
|
|
||||||
|
|
||||||
struct command cmd[] = {
|
struct command cmd[] = {
|
||||||
{ "dump", cmd_dump, "dump memory : %s [eeprom|flash] <addr> <N-Bytes>" },
|
{ "dump", cmd_dump, "dump memory : %s [eeprom|flash] <addr> <N-Bytes>" },
|
||||||
|
@ -77,7 +81,9 @@ struct command cmd[] = {
|
||||||
{ "write", cmd_write, "write memory : %s [eeprom|flash] <addr> <b1> <b2> ... <bN>" },
|
{ "write", cmd_write, "write memory : %s [eeprom|flash] <addr> <b1> <b2> ... <bN>" },
|
||||||
{ "erase", cmd_erase, "perform a chip erase" },
|
{ "erase", cmd_erase, "perform a chip erase" },
|
||||||
{ "sig", cmd_sig, "display device signature bytes" },
|
{ "sig", cmd_sig, "display device signature bytes" },
|
||||||
|
{ "cal", cmd_cal, "display device calibration byte" },
|
||||||
{ "part", cmd_part, "display the current part settings" },
|
{ "part", cmd_part, "display the current part settings" },
|
||||||
|
{ "send", cmd_send, "send a command : %s <b1> <b2> <b3> <b4>" },
|
||||||
{ "help", cmd_help, "help" },
|
{ "help", cmd_help, "help" },
|
||||||
{ "?", cmd_help, "help" },
|
{ "?", cmd_help, "help" },
|
||||||
{ "quit", cmd_quit, "quit" }
|
{ "quit", cmd_quit, "quit" }
|
||||||
|
@ -215,7 +221,7 @@ int cmd_dump(int fd, struct avrpart * p, int argc, char * argv[])
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!((argc == 2) || (argc == 4))) {
|
if (!((argc == 2) || (argc == 4))) {
|
||||||
fprintf(stderr, "Usage: dump flash|eeprom [<addr> <len>]\n");
|
fprintf(stderr, "Usage: dump flash|eeprom|fuse|lock [<addr> <len>]\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,6 +232,14 @@ int cmd_dump(int fd, struct avrpart * p, int argc, char * argv[])
|
||||||
else if (strncasecmp(argv[1],"eeprom",l)==0) {
|
else if (strncasecmp(argv[1],"eeprom",l)==0) {
|
||||||
memtype = AVR_M_EEPROM;
|
memtype = AVR_M_EEPROM;
|
||||||
}
|
}
|
||||||
|
else if ((strncasecmp(argv[1],"fuse",l)==0)||
|
||||||
|
(strncasecmp(argv[1],"fuse-bit",l)==0)) {
|
||||||
|
memtype = AVR_M_FUSE;
|
||||||
|
}
|
||||||
|
else if ((strncasecmp(argv[1],"lock",l)==0)||
|
||||||
|
(strncasecmp(argv[1],"lock-bit",l)==0)) {
|
||||||
|
memtype = AVR_M_LOCK;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "%s (dump): invalid memory type \"%s\"\n",
|
fprintf(stderr, "%s (dump): invalid memory type \"%s\"\n",
|
||||||
progname, argv[1]);
|
progname, argv[1]);
|
||||||
|
@ -249,7 +263,20 @@ int cmd_dump(int fd, struct avrpart * p, int argc, char * argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maxsize = 0;
|
||||||
|
|
||||||
|
switch (memtype) {
|
||||||
|
case AVR_M_FLASH:
|
||||||
|
case AVR_M_EEPROM:
|
||||||
maxsize = p->mem[memtype].size;
|
maxsize = p->mem[memtype].size;
|
||||||
|
break;
|
||||||
|
case AVR_M_FUSE:
|
||||||
|
maxsize = 2;
|
||||||
|
break;
|
||||||
|
case AVR_M_LOCK:
|
||||||
|
maxsize = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (argc == 2) {
|
if (argc == 2) {
|
||||||
addr = 0;
|
addr = 0;
|
||||||
|
@ -273,8 +300,20 @@ int cmd_dump(int fd, struct avrpart * p, int argc, char * argv[])
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<len; i++)
|
for (i=0; i<len; i++) {
|
||||||
|
switch (memtype) {
|
||||||
|
case AVR_M_FLASH:
|
||||||
|
case AVR_M_EEPROM:
|
||||||
buf[i] = avr_read_byte(fd, p, memtype, addr+i);
|
buf[i] = avr_read_byte(fd, p, memtype, addr+i);
|
||||||
|
break;
|
||||||
|
case AVR_M_FUSE:
|
||||||
|
buf[i] = avr_read_fuse(fd, p, addr+i);
|
||||||
|
break;
|
||||||
|
case AVR_M_LOCK:
|
||||||
|
buf[i] = avr_read_lock(fd, p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hexdump_buf(stdout, addr, buf, len);
|
hexdump_buf(stdout, addr, buf, len);
|
||||||
|
|
||||||
|
@ -298,8 +337,8 @@ int cmd_write(int fd, struct avrpart * p, int argc, char * argv[])
|
||||||
int werror;
|
int werror;
|
||||||
|
|
||||||
if (argc < 4) {
|
if (argc < 4) {
|
||||||
fprintf(stderr,
|
fprintf(stderr, "Usage: write flash|eeprom|fuse <addr> <byte1> "
|
||||||
"Usage: write flash|eeprom <addr> <byte1> <byte2> ... byteN>\n");
|
"<byte2> ... byteN>\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,19 +349,39 @@ int cmd_write(int fd, struct avrpart * p, int argc, char * argv[])
|
||||||
else if (strncasecmp(argv[1],"eeprom",l)==0) {
|
else if (strncasecmp(argv[1],"eeprom",l)==0) {
|
||||||
memtype = AVR_M_EEPROM;
|
memtype = AVR_M_EEPROM;
|
||||||
}
|
}
|
||||||
|
else if ((strncasecmp(argv[1],"fuse",l)==0)||
|
||||||
|
(strncasecmp(argv[1],"fuse-bit",l)==0)) {
|
||||||
|
memtype = AVR_M_FUSE;
|
||||||
|
}
|
||||||
|
else if ((strncasecmp(argv[1],"lock",l)==0)||
|
||||||
|
(strncasecmp(argv[1],"lock-bit",l)==0)) {
|
||||||
|
memtype = AVR_M_LOCK;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "%s (write): invalid memory type \"%s\"\n",
|
fprintf(stderr, "%s (write): invalid memory type \"%s\"\n",
|
||||||
progname, argv[1]);
|
progname, argv[1]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maxsize = 0;
|
||||||
|
|
||||||
|
switch (memtype) {
|
||||||
|
case AVR_M_FLASH:
|
||||||
|
case AVR_M_EEPROM:
|
||||||
if (p->mem[memtype].paged) {
|
if (p->mem[memtype].paged) {
|
||||||
fprintf(stderr, "%s (write): sorry, interactive write of page addressed "
|
fprintf(stderr, "%s (write): sorry, interactive write of page "
|
||||||
"memory is not supported\n", progname);
|
"addressed memory is not supported\n", progname);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
maxsize = p->mem[memtype].size;
|
maxsize = p->mem[memtype].size;
|
||||||
|
break;
|
||||||
|
case AVR_M_FUSE:
|
||||||
|
maxsize = 2;
|
||||||
|
break;
|
||||||
|
case AVR_M_LOCK:
|
||||||
|
maxsize = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
addr = strtoul(argv[2], &e, 0);
|
addr = strtoul(argv[2], &e, 0);
|
||||||
if (*e || (e == argv[2])) {
|
if (*e || (e == argv[2])) {
|
||||||
|
@ -360,13 +419,28 @@ int cmd_write(int fd, struct avrpart * p, int argc, char * argv[])
|
||||||
if (*e || (e == argv[i])) {
|
if (*e || (e == argv[i])) {
|
||||||
fprintf(stderr, "%s (write): can't parse byte \"%s\"\n",
|
fprintf(stderr, "%s (write): can't parse byte \"%s\"\n",
|
||||||
progname, argv[i]);
|
progname, argv[i]);
|
||||||
|
free(buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LED_OFF(fd, pgm->pinno[PIN_LED_ERR]);
|
LED_OFF(fd, pgm->pinno[PIN_LED_ERR]);
|
||||||
for (werror=0, i=0; i<len; i++) {
|
for (werror=0, i=0; i<len; i++) {
|
||||||
|
|
||||||
|
rc = 0;
|
||||||
|
switch (memtype) {
|
||||||
|
case AVR_M_EEPROM:
|
||||||
|
case AVR_M_FLASH:
|
||||||
rc = avr_write_byte(fd, p, memtype, addr+i, buf[i]);
|
rc = avr_write_byte(fd, p, memtype, addr+i, buf[i]);
|
||||||
|
break;
|
||||||
|
case AVR_M_FUSE:
|
||||||
|
rc = avr_write_fuse(fd, p, addr+i, buf[i]);
|
||||||
|
break;
|
||||||
|
case AVR_M_LOCK:
|
||||||
|
rc = avr_write_lock(fd, p, buf[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
fprintf(stderr, "%s (write): error writing 0x%02x at 0x%04x\n",
|
fprintf(stderr, "%s (write): error writing 0x%02x at 0x%04x\n",
|
||||||
progname, buf[i], addr+i);
|
progname, buf[i], addr+i);
|
||||||
|
@ -385,6 +459,49 @@ int cmd_write(int fd, struct avrpart * p, int argc, char * argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int cmd_send(int fd, struct avrpart * p, int argc, char * argv[])
|
||||||
|
{
|
||||||
|
unsigned char cmd[4], res[4];
|
||||||
|
char * e;
|
||||||
|
int i;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (argc != 5) {
|
||||||
|
fprintf(stderr, "Usage: send <byte1> <byte2> <byte3> <byte4>\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* number of bytes to write at the specified address */
|
||||||
|
len = argc - 1;
|
||||||
|
|
||||||
|
/* load command bytes */
|
||||||
|
for (i=1; i<argc; i++) {
|
||||||
|
cmd[i-1] = strtoul(argv[i], &e, 0);
|
||||||
|
if (*e || (e == argv[i])) {
|
||||||
|
fprintf(stderr, "%s (send): can't parse byte \"%s\"\n",
|
||||||
|
progname, argv[i]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LED_OFF(fd, pgm->pinno[PIN_LED_ERR]);
|
||||||
|
|
||||||
|
avr_cmd(fd, cmd, res);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* display results
|
||||||
|
*/
|
||||||
|
fprintf(stderr, "results:");
|
||||||
|
for (i=0; i<len; i++)
|
||||||
|
fprintf(stderr, " %02x", res[i]);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int cmd_erase(int fd, struct avrpart * p, int argc, char * argv[])
|
int cmd_erase(int fd, struct avrpart * p, int argc, char * argv[])
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: erasing chip\n", progname);
|
fprintf(stderr, "%s: erasing chip\n", progname);
|
||||||
|
@ -418,6 +535,17 @@ int cmd_sig(int fd, struct avrpart * p, int argc, char * argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int cmd_cal(int fd, struct avrpart * p, int argc, char * argv[])
|
||||||
|
{
|
||||||
|
unsigned char byte;
|
||||||
|
|
||||||
|
byte = avr_read_calibration(fd, p);
|
||||||
|
fprintf(stdout, "\nDevice calibration = 0x%02x\n\n", byte);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int cmd_quit(int fd, struct avrpart * p, int argc, char * argv[])
|
int cmd_quit(int fd, struct avrpart * p, int argc, char * argv[])
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
|
|
Loading…
Reference in New Issue