* Makefile.am (avrdude_SOURCES): Add avr910.[ch], serial.h and
ser_posix.c files. * avr910.c: New file (stubs for avr910 serial programmer). * avr910.h: New file. * ser_posix.c: New file. * ser_win32.c: New file (just stubs for now). * serial.h: New file. * stk500.c: Move all the code for accessing the posix serial ports into ser_posix. This will make a native win32 port easier and allows the avr910 programmer to share the serial code. git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@289 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
95bc42484d
commit
746f6f4421
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
||||||
|
2003-03-12 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
|
* Makefile.am (avrdude_SOURCES): Add avr910.[ch], serial.h and
|
||||||
|
ser_posix.c files.
|
||||||
|
* avr910.c: New file (stubs for avr910 serial programmer).
|
||||||
|
* avr910.h: New file.
|
||||||
|
* ser_posix.c: New file.
|
||||||
|
* ser_win32.c: New file (just stubs for now).
|
||||||
|
* serial.h: New file.
|
||||||
|
* stk500.c: Move all the code for accessing the posix serial ports
|
||||||
|
into ser_posix. This will make a native win32 port easier and allows
|
||||||
|
the avr910 programmer to share the serial code.
|
||||||
|
|
||||||
2003-03-12 Theodore A. Roth <troth@openavr.org>
|
2003-03-12 Theodore A. Roth <troth@openavr.org>
|
||||||
|
|
||||||
* configure.ac (AC_INIT): Set version to 4.0.0cvs since we're done
|
* configure.ac (AC_INIT): Set version to 4.0.0cvs since we're done
|
||||||
|
|
|
@ -48,6 +48,8 @@ avrdude_SOURCES = \
|
||||||
lexer.l \
|
lexer.l \
|
||||||
avr.c \
|
avr.c \
|
||||||
avr.h \
|
avr.h \
|
||||||
|
avr910.c \
|
||||||
|
avr910.h \
|
||||||
avrpart.h \
|
avrpart.h \
|
||||||
config.c \
|
config.c \
|
||||||
config.h \
|
config.h \
|
||||||
|
@ -67,6 +69,9 @@ avrdude_SOURCES = \
|
||||||
ppi.c \
|
ppi.c \
|
||||||
ppi.h \
|
ppi.h \
|
||||||
ppiwin.c \
|
ppiwin.c \
|
||||||
|
serial.h \
|
||||||
|
ser_posix.c \
|
||||||
|
ser_win32.c \
|
||||||
stk500.c \
|
stk500.c \
|
||||||
stk500.h \
|
stk500.h \
|
||||||
stk500_private.h \
|
stk500_private.h \
|
||||||
|
|
|
@ -0,0 +1,216 @@
|
||||||
|
/*
|
||||||
|
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||||
|
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* avrdude interface for Atmel Low Cost Serial programmers which adher to the
|
||||||
|
* protocol described in application note avr910.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ac_cfg.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "avr.h"
|
||||||
|
#include "pgm.h"
|
||||||
|
#include "avr910.h"
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
|
extern char * progname;
|
||||||
|
extern int do_cycles;
|
||||||
|
|
||||||
|
|
||||||
|
static int avr910_send(PROGRAMMER * pgm, char * buf, size_t len)
|
||||||
|
{
|
||||||
|
return serial_send(pgm->fd, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int avr910_recv(PROGRAMMER * pgm, char * buf, size_t len)
|
||||||
|
{
|
||||||
|
return serial_recv(pgm->fd, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int avr910_drain(PROGRAMMER * pgm, int display)
|
||||||
|
{
|
||||||
|
return serial_drain(pgm->fd, display);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int avr910_rdy_led(PROGRAMMER * pgm, int value)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int avr910_err_led(PROGRAMMER * pgm, int value)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int avr910_pgm_led(PROGRAMMER * pgm, int value)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int avr910_vfy_led(PROGRAMMER * pgm, int value)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* issue the 'chip erase' command to the AVR device
|
||||||
|
*/
|
||||||
|
static int avr910_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* issue the 'program enable' command to the AVR device
|
||||||
|
*/
|
||||||
|
static int avr910_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* apply power to the AVR processor
|
||||||
|
*/
|
||||||
|
static void avr910_powerup(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* remove power from the AVR processor
|
||||||
|
*/
|
||||||
|
static void avr910_powerdown(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* initialize the AVR device and prepare it to accept commands
|
||||||
|
*/
|
||||||
|
static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int avr910_save(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void avr910_restore(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void avr910_disable(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void avr910_enable(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* transmit an AVR device command and return the results; 'cmd' and
|
||||||
|
* 'res' must point to at least a 4 byte data buffer
|
||||||
|
*/
|
||||||
|
static int avr910_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
|
||||||
|
unsigned char res[4])
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void avr910_open(PROGRAMMER * pgm, char * port)
|
||||||
|
{
|
||||||
|
strcpy(pgm->port, port);
|
||||||
|
pgm->fd = serial_open(port, 19200);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* drain any extraneous input
|
||||||
|
*/
|
||||||
|
avr910_drain (pgm, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void avr910_close(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
serial_close(pgm->fd);
|
||||||
|
pgm->fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void avr910_display(PROGRAMMER * pgm, char * p)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void avr910_initpgm(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
strcpy(pgm->type, "avr910");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mandatory functions
|
||||||
|
*/
|
||||||
|
pgm->rdy_led = avr910_rdy_led;
|
||||||
|
pgm->err_led = avr910_err_led;
|
||||||
|
pgm->pgm_led = avr910_pgm_led;
|
||||||
|
pgm->vfy_led = avr910_vfy_led;
|
||||||
|
pgm->initialize = avr910_initialize;
|
||||||
|
pgm->display = avr910_display;
|
||||||
|
pgm->save = avr910_save;
|
||||||
|
pgm->restore = avr910_restore;
|
||||||
|
pgm->enable = avr910_enable;
|
||||||
|
pgm->disable = avr910_disable;
|
||||||
|
pgm->powerup = avr910_powerup;
|
||||||
|
pgm->powerdown = avr910_powerdown;
|
||||||
|
pgm->program_enable = avr910_program_enable;
|
||||||
|
pgm->chip_erase = avr910_chip_erase;
|
||||||
|
pgm->cmd = avr910_cmd;
|
||||||
|
pgm->open = avr910_open;
|
||||||
|
pgm->close = avr910_close;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* optional functions
|
||||||
|
*/
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||||
|
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#ifndef __avr910_h__
|
||||||
|
#define __avr910_h__
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
void avr910_initpgm (PROGRAMMER * pgm);
|
||||||
|
|
||||||
|
#endif /* __avr910_h__ */
|
|
@ -0,0 +1,298 @@
|
||||||
|
/*
|
||||||
|
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||||
|
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Posix serial interface for avrdude.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
extern char *progname;
|
||||||
|
|
||||||
|
struct baud_mapping {
|
||||||
|
int baud;
|
||||||
|
speed_t speed;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* There are a lot more baud rates we could handle, but what's the point? */
|
||||||
|
|
||||||
|
static struct baud_mapping baud_lookup_table [] = {
|
||||||
|
{ 1200, B1200 },
|
||||||
|
{ 2400, B2400 },
|
||||||
|
{ 4800, B4800 },
|
||||||
|
{ 9600, B9600 },
|
||||||
|
{ 19200, B19200 },
|
||||||
|
{ 38400, B38400 },
|
||||||
|
{ 57600, B57600 },
|
||||||
|
{ 115200, B115200 },
|
||||||
|
{ 230400, B230400 },
|
||||||
|
{ 0, 0 } /* Terminator. */
|
||||||
|
};
|
||||||
|
|
||||||
|
static speed_t serial_baud_lookup(int baud)
|
||||||
|
{
|
||||||
|
struct baud_mapping *map = baud_lookup_table;
|
||||||
|
|
||||||
|
while (map->baud) {
|
||||||
|
if (map->baud == baud)
|
||||||
|
return map->speed;
|
||||||
|
map++;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "%s: serial_baud_lookup(): unknown baud rate: %d",
|
||||||
|
progname, baud);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int serial_setattr(int fd, int baud)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
struct termios termios;
|
||||||
|
speed_t speed = serial_baud_lookup (baud);
|
||||||
|
|
||||||
|
if (!isatty(fd))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* initialize terminal modes
|
||||||
|
*/
|
||||||
|
rc = tcgetattr(fd, &termios);
|
||||||
|
if (rc < 0) {
|
||||||
|
fprintf(stderr, "%s: serial_setattr(): tcgetattr() failed, %s",
|
||||||
|
progname, strerror(errno));
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
termios.c_iflag = 0;
|
||||||
|
termios.c_oflag = 0;
|
||||||
|
termios.c_cflag = 0;
|
||||||
|
termios.c_cflag |= (CS8 | CREAD | CLOCAL);
|
||||||
|
termios.c_lflag = 0;
|
||||||
|
termios.c_cc[VMIN] = 1;
|
||||||
|
termios.c_cc[VTIME] = 0;
|
||||||
|
|
||||||
|
cfsetospeed(&termios, speed);
|
||||||
|
cfsetispeed(&termios, speed);
|
||||||
|
|
||||||
|
rc = tcsetattr(fd, TCSANOW, &termios);
|
||||||
|
if (rc < 0) {
|
||||||
|
fprintf(stderr, "%s: serial_setattr(): tcsetattr() failed, %s",
|
||||||
|
progname, strerror(errno));
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int serial_open(char * port, int baud)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* open the serial port
|
||||||
|
*/
|
||||||
|
fd = open(port, O_RDWR | O_NOCTTY /*| O_NONBLOCK*/);
|
||||||
|
if (fd < 0) {
|
||||||
|
fprintf(stderr, "%s: serial_open(): can't open device \"%s\": %s\n",
|
||||||
|
progname, port, strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set serial line attributes
|
||||||
|
*/
|
||||||
|
rc = serial_setattr(fd, baud);
|
||||||
|
if (rc) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: serial_open(): can't set attributes for device \"%s\"\n",
|
||||||
|
progname, port);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void serial_close(int fd)
|
||||||
|
{
|
||||||
|
/* FIXME: Should really restore the terminal to original state here. */
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int serial_send(int fd, char * buf, size_t buflen)
|
||||||
|
{
|
||||||
|
struct timeval timeout;
|
||||||
|
fd_set wfds;
|
||||||
|
int nfds;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (!buflen)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = 500000;
|
||||||
|
|
||||||
|
while (buflen) {
|
||||||
|
FD_ZERO(&wfds);
|
||||||
|
FD_SET(fd, &wfds);
|
||||||
|
|
||||||
|
reselect:
|
||||||
|
nfds = select(fd+1, NULL, &wfds, NULL, &timeout);
|
||||||
|
if (nfds == 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: serial_send(): programmer is not responding\n",
|
||||||
|
progname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
else if (nfds == -1) {
|
||||||
|
if (errno == EINTR) {
|
||||||
|
goto reselect;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "%s: serial_send(): select(): %s\n",
|
||||||
|
progname, strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = write(fd, buf, 1);
|
||||||
|
if (rc < 0) {
|
||||||
|
fprintf(stderr, "%s: serial_send(): write error: %s\n",
|
||||||
|
progname, strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
buf++;
|
||||||
|
buflen--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int serial_recv(int fd, char * buf, size_t buflen)
|
||||||
|
{
|
||||||
|
struct timeval timeout;
|
||||||
|
fd_set rfds;
|
||||||
|
int nfds;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
timeout.tv_sec = 5;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
|
||||||
|
while (buflen) {
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(fd, &rfds);
|
||||||
|
|
||||||
|
reselect:
|
||||||
|
nfds = select(fd+1, &rfds, NULL, NULL, &timeout);
|
||||||
|
if (nfds == 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: serial_recv(): programmer is not responding\n",
|
||||||
|
progname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
else if (nfds == -1) {
|
||||||
|
if (errno == EINTR) {
|
||||||
|
goto reselect;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "%s: serial_recv(): select(): %s\n",
|
||||||
|
progname, strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = read(fd, buf, 1);
|
||||||
|
if (rc < 0) {
|
||||||
|
fprintf(stderr, "%s: serial_recv(): read error: %s\n",
|
||||||
|
progname, strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
buf++;
|
||||||
|
buflen--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int serial_drain(int fd, int display)
|
||||||
|
{
|
||||||
|
struct timeval timeout;
|
||||||
|
fd_set rfds;
|
||||||
|
int nfds;
|
||||||
|
int rc;
|
||||||
|
unsigned char buf;
|
||||||
|
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = 250000;
|
||||||
|
|
||||||
|
if (display) {
|
||||||
|
fprintf(stderr, "drain>");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(fd, &rfds);
|
||||||
|
|
||||||
|
reselect:
|
||||||
|
nfds = select(fd+1, &rfds, NULL, NULL, &timeout);
|
||||||
|
if (nfds == 0) {
|
||||||
|
if (display) {
|
||||||
|
fprintf(stderr, "<drain\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (nfds == -1) {
|
||||||
|
if (errno == EINTR) {
|
||||||
|
goto reselect;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "%s: serial_drain(): select(): %s\n",
|
||||||
|
progname, strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = read(fd, &buf, 1);
|
||||||
|
if (rc < 0) {
|
||||||
|
fprintf(stderr, "%s: serial_drain(): read error: %s\n",
|
||||||
|
progname, strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (display) {
|
||||||
|
fprintf(stderr, "%02x ", buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||||
|
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Posix serial interface for avrdude.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern char *progname;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
int serial_open(char * port, int baud)
|
||||||
|
{
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void serial_close(int fd)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int serial_send(int fd, char * buf, size_t buflen)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int serial_recv(int fd, char * buf, size_t buflen)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int serial_drain(int fd, int display)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||||
|
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/* This is the API for the generic serial interface. The implementations are
|
||||||
|
actually provided by the target dependant files:
|
||||||
|
|
||||||
|
ser_posix.c : posix serial interface.
|
||||||
|
ser_win32.c : native win32 serial interface.
|
||||||
|
|
||||||
|
The target file will be selected at configure time. */
|
||||||
|
|
||||||
|
#ifndef __serial_h__
|
||||||
|
#define __serial_h__
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
extern int serial_open(char * port, int baud);
|
||||||
|
extern void serial_close(int fd);
|
||||||
|
|
||||||
|
extern int serial_send(int fd, char * buf, size_t buflen);
|
||||||
|
extern int serial_recv(int fd, char * buf, size_t buflen);
|
||||||
|
extern int serial_drain(int fd, int display);
|
||||||
|
|
||||||
|
#endif /* __serial_h__ */
|
213
stk500.c
213
stk500.c
|
@ -33,15 +33,12 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <termios.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
#include "avr.h"
|
#include "avr.h"
|
||||||
#include "pgm.h"
|
#include "pgm.h"
|
||||||
#include "stk500_private.h"
|
#include "stk500_private.h"
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
|
|
||||||
extern char * progname;
|
extern char * progname;
|
||||||
|
@ -51,153 +48,21 @@ extern int do_cycles;
|
||||||
static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value);
|
static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value);
|
||||||
|
|
||||||
|
|
||||||
static int stk500_send(PROGRAMMER * pgm, char * buf, int buflen)
|
static int stk500_send(PROGRAMMER * pgm, char * buf, size_t len)
|
||||||
{
|
{
|
||||||
struct timeval timeout;
|
return serial_send(pgm->fd, buf, len);
|
||||||
fd_set wfds;
|
|
||||||
int nfds;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (!buflen)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
timeout.tv_sec = 0;
|
|
||||||
timeout.tv_usec = 500000;
|
|
||||||
|
|
||||||
while (buflen) {
|
|
||||||
FD_ZERO(&wfds);
|
|
||||||
FD_SET(pgm->fd, &wfds);
|
|
||||||
|
|
||||||
reselect:
|
|
||||||
nfds = select(pgm->fd+1, NULL, &wfds, NULL, &timeout);
|
|
||||||
if (nfds == 0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"%s: stk500_send(): programmer is not responding on %s\n",
|
|
||||||
progname, pgm->port);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
else if (nfds == -1) {
|
|
||||||
if (errno == EINTR) {
|
|
||||||
goto reselect;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fprintf(stderr, "%s: stk500_send(): select(): %s\n",
|
|
||||||
progname, strerror(errno));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = write(pgm->fd, buf, 1);
|
|
||||||
if (rc < 0) {
|
|
||||||
fprintf(stderr, "%s: stk500_send(): write error: %s\n",
|
|
||||||
progname, strerror(errno));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
buf++;
|
|
||||||
buflen--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int stk500_recv(PROGRAMMER * pgm, char * buf, size_t len)
|
||||||
static int stk500_recv(PROGRAMMER * pgm, char * buf, int n)
|
|
||||||
{
|
{
|
||||||
struct timeval timeout;
|
return serial_recv(pgm->fd, buf, len);
|
||||||
fd_set rfds;
|
|
||||||
int nfds;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
timeout.tv_sec = 5;
|
|
||||||
timeout.tv_usec = 0;
|
|
||||||
|
|
||||||
while (n) {
|
|
||||||
FD_ZERO(&rfds);
|
|
||||||
FD_SET(pgm->fd, &rfds);
|
|
||||||
|
|
||||||
reselect:
|
|
||||||
nfds = select(pgm->fd+1, &rfds, NULL, NULL, &timeout);
|
|
||||||
if (nfds == 0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"%s: stk500_recv(): programmer is not responding on %s\n",
|
|
||||||
progname, pgm->port);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
else if (nfds == -1) {
|
|
||||||
if (errno == EINTR) {
|
|
||||||
goto reselect;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fprintf(stderr, "%s: stk500_recv(): select(): %s\n",
|
|
||||||
progname, strerror(errno));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = read(pgm->fd, buf, 1);
|
|
||||||
if (rc < 0) {
|
|
||||||
fprintf(stderr, "%s: stk500_recv(): read error: %s\n",
|
|
||||||
progname, strerror(errno));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
buf++;
|
|
||||||
n--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int stk500_drain(PROGRAMMER * pgm, int display)
|
static int stk500_drain(PROGRAMMER * pgm, int display)
|
||||||
{
|
{
|
||||||
struct timeval timeout;
|
return serial_drain(pgm->fd, display);
|
||||||
fd_set rfds;
|
|
||||||
int nfds;
|
|
||||||
int rc;
|
|
||||||
unsigned char buf;
|
|
||||||
|
|
||||||
timeout.tv_sec = 0;
|
|
||||||
timeout.tv_usec = 250000;
|
|
||||||
|
|
||||||
if (display) {
|
|
||||||
fprintf(stderr, "drain>");
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
FD_ZERO(&rfds);
|
|
||||||
FD_SET(pgm->fd, &rfds);
|
|
||||||
|
|
||||||
reselect:
|
|
||||||
nfds = select(pgm->fd+1, &rfds, NULL, NULL, &timeout);
|
|
||||||
if (nfds == 0) {
|
|
||||||
if (display) {
|
|
||||||
fprintf(stderr, "<drain\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (nfds == -1) {
|
|
||||||
if (errno == EINTR) {
|
|
||||||
goto reselect;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fprintf(stderr, "%s: stk500_drain(): select(): %s\n",
|
|
||||||
progname, strerror(errno));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = read(pgm->fd, &buf, 1);
|
|
||||||
if (rc < 0) {
|
|
||||||
fprintf(stderr, "%s: stk500_drain(): read error: %s\n",
|
|
||||||
progname, strerror(errno));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (display) {
|
|
||||||
fprintf(stderr, "%02x ", buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -739,72 +604,10 @@ static void stk500_enable(PROGRAMMER * pgm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int stk500_setattr(int fd)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
struct termios termios;
|
|
||||||
|
|
||||||
if (!isatty(fd))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* initialize terminal modes
|
|
||||||
*/
|
|
||||||
rc = tcgetattr(fd, &termios);
|
|
||||||
if (rc < 0) {
|
|
||||||
fprintf(stderr, "%s: stk500_setattr(): tcgetattr() failed, %s",
|
|
||||||
progname, strerror(errno));
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
termios.c_iflag = 0;
|
|
||||||
termios.c_oflag = 0;
|
|
||||||
termios.c_cflag = 0;
|
|
||||||
termios.c_cflag |= (CS8 | CREAD | CLOCAL);
|
|
||||||
termios.c_lflag = 0;
|
|
||||||
termios.c_cc[VMIN] = 1;
|
|
||||||
termios.c_cc[VTIME] = 0;
|
|
||||||
|
|
||||||
cfsetospeed(&termios, B115200);
|
|
||||||
cfsetispeed(&termios, B115200);
|
|
||||||
|
|
||||||
rc = tcsetattr(fd, TCSANOW, &termios);
|
|
||||||
if (rc < 0) {
|
|
||||||
fprintf(stderr, "%s: stk500_setattr(): tcsetattr() failed, %s",
|
|
||||||
progname, strerror(errno));
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void stk500_open(PROGRAMMER * pgm, char * port)
|
static void stk500_open(PROGRAMMER * pgm, char * port)
|
||||||
{
|
{
|
||||||
int rc;
|
|
||||||
|
|
||||||
strcpy(pgm->port, port);
|
strcpy(pgm->port, port);
|
||||||
|
pgm->fd = serial_open(port, 115200);
|
||||||
/*
|
|
||||||
* open the serial port
|
|
||||||
*/
|
|
||||||
pgm->fd = open(port, O_RDWR | O_NOCTTY /*| O_NONBLOCK*/);
|
|
||||||
if (pgm->fd < 0) {
|
|
||||||
fprintf(stderr, "%s: stk500_open(): can't open device \"%s\": %s\n",
|
|
||||||
progname, port, strerror(errno));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* set serial line attributes
|
|
||||||
*/
|
|
||||||
rc = stk500_setattr(pgm->fd);
|
|
||||||
if (rc) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"%s: stk500_open(): can't set attributes for device \"%s\"\n",
|
|
||||||
progname, port);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* drain any extraneous input
|
* drain any extraneous input
|
||||||
|
@ -819,7 +622,7 @@ static void stk500_open(PROGRAMMER * pgm, char * port)
|
||||||
|
|
||||||
static void stk500_close(PROGRAMMER * pgm)
|
static void stk500_close(PROGRAMMER * pgm)
|
||||||
{
|
{
|
||||||
close(pgm->fd);
|
serial_close(pgm->fd);
|
||||||
pgm->fd = -1;
|
pgm->fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue