Support for Arduino auto-reset:

* serial.h, ser_avrdoper.c, ser_posix.c, ser_win32.c: Added 
	  serial_device.set_dtr_rts implementations.
	* arduino.c, stk500.c, stk500.h: Call serial_set_dtr_rts()
	  to reset Arduino board before program upload.
	Inspired by patch #6866, resolves bug #26703



git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@845 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
Michal Ludvig 2009-10-10 01:41:40 +00:00
parent b7766d1400
commit 819bb7dfeb
8 changed files with 103 additions and 4 deletions

View File

@ -1,3 +1,12 @@
2009-10-10 Michal Ludvig <mludvig@logix.net.nz>
Support for Arduino auto-reset:
* serial.h, ser_avrdoper.c, ser_posix.c, ser_win32.c: Added
serial_device.set_dtr_rts implementations.
* arduino.c, stk500.c, stk500.h: Call serial_set_dtr_rts()
to reset Arduino board before program upload.
Inspired by patch #6866, resolves bug #26703
2009-10-08 Michal Ludvig <mludvig@logix.net.nz>
* buspirate.c: Optimised buspirate_cmd() - reading 1kB EEPROM now

View File

@ -82,13 +82,40 @@ static int arduino_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
return 3;
}
static int arduino_open(PROGRAMMER * pgm, char * port)
{
strcpy(pgm->port, port);
serial_open(port, pgm->baudrate? pgm->baudrate: 115200, &pgm->fd);
/* Clear DTR and RTS to unload the RESET capacitor
* (for example in Arduino) */
serial_set_dtr_rts(&pgm->fd, 0);
usleep(50*1000);
/* Set DTR and RTS back to high */
serial_set_dtr_rts(&pgm->fd, 1);
usleep(50*1000);
/*
* drain any extraneous input
*/
stk500_drain(pgm, 0);
if (stk500_getsync(pgm) < 0)
return -1;
return 0;
}
void arduino_initpgm(PROGRAMMER * pgm)
{
/* This is mostly a STK500; just the signature is read
differently than on real STK500v1 */
differently than on real STK500v1
and the DTR signal is set when opening the serial port
for the Auto-Reset feature */
stk500_initpgm(pgm);
strcpy(pgm->type, "Arduino");
pgm->read_sig_bytes = arduino_read_sig_bytes;
pgm->open = arduino_open;
}

View File

@ -634,6 +634,14 @@ static int avrdoper_drain(union filedescriptor *fdp, int display)
/* ------------------------------------------------------------------------- */
static int avrdoper_set_dtr_rts(union filedescriptor *fdp, int is_on)
{
fprintf(stderr, "%s: AVR-Doper doesn't support DTR/RTS setting\n", progname);
return -1;
}
/* ------------------------------------------------------------------------- */
struct serial_device avrdoper_serdev =
{
.open = avrdoper_open,
@ -641,6 +649,7 @@ struct serial_device avrdoper_serdev =
.send = avrdoper_send,
.recv = avrdoper_recv,
.drain = avrdoper_drain,
.set_dtr_rts = avrdoper_set_dtr_rts,
.flags = SERDEV_FL_NONE,
};

View File

@ -32,6 +32,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
@ -210,6 +211,36 @@ net_open(const char *port, union filedescriptor *fdp)
fdp->ifd = fd;
}
static int ser_set_dtr_rts(union filedescriptor *fdp, int is_on)
{
unsigned int ctl;
int r;
r = ioctl(fdp->ifd, TIOCMGET, &ctl);
if (r < 0) {
perror("ioctl(\"TIOCMGET\")");
return -1;
}
if (is_on) {
/* Clear DTR and RTS */
ctl &= ~(TIOCM_DTR | TIOCM_RTS);
}
else {
/* Set DTR and RTS */
ctl |= (TIOCM_DTR | TIOCM_RTS);
}
r = ioctl(fdp->ifd, TIOCMSET, &ctl);
if (r < 0) {
perror("ioctl(\"TIOCMSET\")");
return -1;
}
return 0;
}
static void ser_open(char * port, long baud, union filedescriptor *fdp)
{
int rc;
@ -455,6 +486,7 @@ struct serial_device serial_serdev =
.send = ser_send,
.recv = ser_recv,
.drain = ser_drain,
.set_dtr_rts = ser_set_dtr_rts,
.flags = SERDEV_FL_CANSETSPEED,
};

View File

@ -203,6 +203,20 @@ static void ser_close(union filedescriptor *fd)
hComPort = INVALID_HANDLE_VALUE;
}
static int ser_set_dtr_rts(union filedescriptor *fdp, int is_on)
{
HANDLE hComPort=(HANDLE)fd->pfd;
if (is_on) {
EscapeCommFunction(hComPort, SETDTR);
EscapeCommFunction(hComPort, SETRTS);
} else {
EscapeCommFunction(hComPort, CLRDTR);
EscapeCommFunction(hComPort, CLRRTS);
}
return 0;
}
static int ser_send(union filedescriptor *fd, unsigned char * buf, size_t buflen)
{
@ -378,6 +392,7 @@ struct serial_device serial_serdev =
.send = ser_send,
.recv = ser_recv,
.drain = ser_drain,
.set_dtr_rts = ser_set_dtr_rts,
.flags = SERDEV_FL_CANSETSPEED,
};

View File

@ -52,6 +52,8 @@ struct serial_device
int (*recv)(union filedescriptor *fd, unsigned char * buf, size_t buflen);
int (*drain)(union filedescriptor *fd, int display);
int (*set_dtr_rts)(union filedescriptor *fd, int is_on);
int flags;
#define SERDEV_FL_NONE 0x0000 /* no flags */
#define SERDEV_FL_CANSETSPEED 0x0001 /* device can change speed */
@ -69,5 +71,6 @@ extern struct serial_device avrdoper_serdev;
#define serial_send (serdev->send)
#define serial_recv (serdev->recv)
#define serial_drain (serdev->drain)
#define serial_set_dtr_rts (serdev->set_dtr_rts)
#endif /* serial_h */

View File

@ -73,13 +73,13 @@ static int stk500_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
}
static int stk500_drain(PROGRAMMER * pgm, int display)
int stk500_drain(PROGRAMMER * pgm, int display)
{
return serial_drain(&pgm->fd, display);
}
static int stk500_getsync(PROGRAMMER * pgm)
int stk500_getsync(PROGRAMMER * pgm)
{
unsigned char buf[32], resp[32];

View File

@ -28,6 +28,10 @@ extern "C" {
void stk500_initpgm (PROGRAMMER * pgm);
/* used by arduino.c to avoid duplicate code */
int stk500_getsync(PROGRAMMER * pgm);
int stk500_drain(PROGRAMMER * pgm, int display);
#ifdef __cplusplus
}
#endif