merged in changes to allow native Win32 build with no cygwin DLL dependancy

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@419 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
kiwi64ajs 2004-06-24 11:05:07 +00:00
parent 91d893eb52
commit be4f46c49e
14 changed files with 472 additions and 91 deletions

View File

@ -30,6 +30,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <sys/time.h>
#include <unistd.h>
#include "avr.h" #include "avr.h"
#include "pgm.h" #include "pgm.h"
@ -259,6 +261,8 @@ static int avr910_open(PROGRAMMER * pgm, char * port)
* drain any extraneous input * drain any extraneous input
*/ */
avr910_drain (pgm, 0); avr910_drain (pgm, 0);
return 0;
} }
static void avr910_close(PROGRAMMER * pgm) static void avr910_close(PROGRAMMER * pgm)

View File

@ -93,6 +93,46 @@ static void butterfly_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
} }
static int butterfly_rdy_led(PROGRAMMER * pgm, int value)
{
no_show_func_info();
/* Do nothing. */
return 0;
}
static int butterfly_err_led(PROGRAMMER * pgm, int value)
{
no_show_func_info();
/* Do nothing. */
return 0;
}
static int butterfly_pgm_led(PROGRAMMER * pgm, int value)
{
no_show_func_info();
/* Do nothing. */
return 0;
}
static int butterfly_vfy_led(PROGRAMMER * pgm, int value)
{
no_show_func_info();
/* Do nothing. */
return 0;
}
/* /*
* issue the 'chip erase' command to the butterfly board * issue the 'chip erase' command to the butterfly board
*/ */
@ -132,6 +172,31 @@ static int butterfly_program_enable(PROGRAMMER * pgm, AVRPART * p)
} }
/*
* apply power to the AVR processor
*/
static void butterfly_powerup(PROGRAMMER * pgm)
{
no_show_func_info();
/* Do nothing. */
return;
}
/*
* remove power from the AVR processor
*/
static void butterfly_powerdown(PROGRAMMER * pgm)
{
no_show_func_info();
/* Do nothing. */
return;
}
/* /*
* initialize the AVR device and prepare it to accept commands * initialize the AVR device and prepare it to accept commands
@ -246,6 +311,7 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
} }
static void butterfly_disable(PROGRAMMER * pgm) static void butterfly_disable(PROGRAMMER * pgm)
{ {
no_show_func_info(); no_show_func_info();
@ -288,6 +354,9 @@ static void butterfly_close(PROGRAMMER * pgm)
butterfly_leave_prog_mode(pgm); butterfly_leave_prog_mode(pgm);
/* "exit programmer" added by Martin Thomas 2/2004 */
butterfly_send(pgm, "E", 1);
serial_close(pgm->fd); serial_close(pgm->fd);
pgm->fd = -1; pgm->fd = -1;
} }
@ -526,10 +595,16 @@ void butterfly_initpgm(PROGRAMMER * pgm)
/* /*
* mandatory functions * mandatory functions
*/ */
pgm->rdy_led = butterfly_rdy_led;
pgm->err_led = butterfly_err_led;
pgm->pgm_led = butterfly_pgm_led;
pgm->vfy_led = butterfly_vfy_led;
pgm->initialize = butterfly_initialize; pgm->initialize = butterfly_initialize;
pgm->display = butterfly_display; pgm->display = butterfly_display;
pgm->enable = butterfly_enable; pgm->enable = butterfly_enable;
pgm->disable = butterfly_disable; pgm->disable = butterfly_disable;
pgm->powerup = butterfly_powerup;
pgm->powerdown = butterfly_powerdown;
pgm->program_enable = butterfly_program_enable; pgm->program_enable = butterfly_program_enable;
pgm->chip_erase = butterfly_chip_erase; pgm->chip_erase = butterfly_chip_erase;
/* pgm->cmd not supported, use default error message */ /* pgm->cmd not supported, use default error message */

View File

@ -37,6 +37,11 @@
#include "butterfly.h" #include "butterfly.h"
#include "avr.h" #include "avr.h"
#if defined(WIN32NATIVE)
#define strtok_r( _s, _sep, _lasts ) \
( *(_lasts) = strtok( (_s), (_sep) ) )
#endif
extern char * progname; extern char * progname;
int yylex(void); int yylex(void);

View File

@ -121,6 +121,8 @@ AC_SUBST(DEFAULT_SER_PORT, $DEFAULT_SER_PORT)
case $target in case $target in
*-*-mingw32* | *-*-cygwin* | *-*-windows*) *-*-mingw32* | *-*-cygwin* | *-*-windows*)
WINDOWS_DIRS="windows" WINDOWS_DIRS="windows"
CFLAGS="-mno-cygwin -DWIN32NATIVE"
LDFLAGS="-static"
;; ;;
esac esac
AC_SUBST(WINDOWS_DIRS,$WINDOWS_DIRS) AC_SUBST(WINDOWS_DIRS,$WINDOWS_DIRS)

View File

@ -19,7 +19,7 @@
#if defined(__CYGWIN__) #if defined(WIN32NATIVE)
#include <limits.h> #include <limits.h>
#include <windows.h> #include <windows.h>

View File

@ -19,7 +19,7 @@
#if defined(__CYGWIN__) #if defined(WIN32NATIVE)
#ifndef __confwin_h__ #ifndef __confwin_h__
#define __confwin_h__ #define __confwin_h__

View File

@ -910,7 +910,7 @@ int fileio(int op, char * filename, FILEFMT format,
if (rc < 0) if (rc < 0)
return -1; return -1;
#if defined(__CYGWIN__) #if defined(WIN32NATIVE)
/* Open Raw Binary format in binary mode on Windows.*/ /* Open Raw Binary format in binary mode on Windows.*/
if(format == FMT_RBIN) if(format == FMT_RBIN)
{ {

25
main.c
View File

@ -700,11 +700,17 @@ int main(int argc, char * argv [])
char * e; /* for strtol() error checking */ char * e; /* for strtol() error checking */
int quell_progress; int quell_progress;
int baudrate; /* override default programmer baud rate */ int baudrate; /* override default programmer baud rate */
#if !defined(__CYGWIN__) #if !defined(WIN32NATIVE)
char * homedir; char * homedir;
#endif #endif
progname = rindex(argv[0],'/'); progname = rindex(argv[0],'/');
#if defined (WIN32NATIVE)
/* take care of backslash as dir sep in W32 */
if (!progname) progname = rindex(argv[0],'\\');
#endif /* WIN32NATIVE */
if (progname) if (progname)
progname++; progname++;
else else
@ -742,7 +748,7 @@ int main(int argc, char * argv [])
baudrate = 0; baudrate = 0;
#if defined(__CYGWIN__) #if defined(WIN32NATIVE)
win_sys_config_set(sys_config); win_sys_config_set(sys_config);
win_usr_config_set(usr_config); win_usr_config_set(usr_config);
@ -897,8 +903,16 @@ int main(int argc, char * argv [])
if (quell_progress == 0) { if (quell_progress == 0) {
if (isatty (STDERR_FILENO)) if (isatty (STDERR_FILENO))
update_progress = update_progress_tty; update_progress = update_progress_tty;
else else {
update_progress = update_progress_no_tty; update_progress = update_progress_no_tty;
#if defined(WIN32NATIVE)
/* disable all buffering of stderr for compatibility with
software that captures and redirects output to a GUI
i.e. Programmers Notepad */
setvbuf( stderr, NULL, _IONBF, 0 );
setvbuf( stdout, NULL, _IONBF, 0 );
#endif /* WIN32NATIVE */
}
} }
if (verbose) { if (verbose) {
@ -910,6 +924,11 @@ int main(int argc, char * argv [])
"\n%s: Version %s\n" "\n%s: Version %s\n"
"%sCopyright (c) 2000-2003 Brian Dean, bsd@bsdhome.com\n\n", "%sCopyright (c) 2000-2003 Brian Dean, bsd@bsdhome.com\n\n",
progname, version, progbuf); progname, version, progbuf);
#if defined(WIN32NATIVE)
#warning "Experimental Win32 Native Build"
fprintf(stderr,"%sExperimental Windows32 native build by Martin Thomas\n\n",
progbuf);
#endif
} }
if (verbose) { if (verbose) {

28
pgm.h
View File

@ -83,4 +83,32 @@ typedef struct programmer_t {
PROGRAMMER * pgm_new(void); PROGRAMMER * pgm_new(void);
#if defined(WIN32NATIVE)
#include <windows.h>
/* usleep replacements */
/* sleep Windows in ms, Unix usleep in us
#define usleep(us) Sleep((us)<20000?20:us/1000)
#define usleep(us) Sleep(us/1000)
#define ANTIWARP 3
#define usleep(us) Sleep(us/1000*ANTIWARP)
*/
void usleep(unsigned long us);
void gettimeofday(struct timeval*, void*z);
#define rindex strrchr
#endif /* __win32native_h */
#if !defined(ppi_claim)
# define ppi_claim(pgm)
#endif
#if !defined(ppi_release)
# define ppi_release(pgm)
#endif
#endif #endif

7
ppi.h
View File

@ -34,13 +34,6 @@ enum {
}; };
#if !defined(ppi_claim)
# define ppi_claim(pgm)
#endif
#if !defined(ppi_release)
# define ppi_release(pgm)
#endif
int ppi_get (int fd, int reg, int bit); int ppi_get (int fd, int reg, int bit);

118
ppiwin.c
View File

@ -30,7 +30,7 @@ reg = register as defined in an enum in ppi.h. This must be converted
#if defined(__CYGWIN__) #if defined (WIN32NATIVE)
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
@ -40,11 +40,9 @@ reg = register as defined in an enum in ppi.h. This must be converted
#include <unistd.h> #include <unistd.h>
#include <windows.h> #include <windows.h>
#include <sys/time.h> #include <sys/time.h>
#include <w32api/windows.h> #include <windows.h>
#include "ppi.h" #include "ppi.h"
extern char *progname; extern char *progname;
@ -317,80 +315,62 @@ static void outb(unsigned char value, unsigned short port)
return; return;
} }
/* These two functions usecPerfDelay and usleep are based on code from the void gettimeofday(struct timeval*tv, void*z){
* uisp project and are a replacement for the cygwin usleep library // i've found only ms resolution, avrdude expects us
* function which seems to not delay for the correct time
*/
BOOL usecPerfDelay(long t) SYSTEMTIME st;
GetSystemTime(&st);
tv->tv_sec=(long)(st.wSecond+st.wMinute*60+st.wHour*3600);
tv->tv_usec=(long)(st.wMilliseconds*1000);
}
// #define W32USLEEPDBG
void usleep(unsigned long us)
{ {
static BOOL perf_counter_checked = FALSE; int has_highperf;
static BOOL use_perf_counter = FALSE; LARGE_INTEGER freq,start,stop,loopend;
static LARGE_INTEGER freq ; #ifdef W32USLEEPDBG
unsigned long dt;
#endif
if (! perf_counter_checked) { // workaround: although usleep is very precise if using
if (QueryPerformanceFrequency(&freq)){ // high-performance-timers there are sometimes problems with
use_perf_counter = TRUE; // verify - increasing the delay helps sometimes but not
// realiably. There must be some other problem. Maybe just
// with my test-hardware maybe in the code-base.
//// us=(unsigned long) (us*1.5);
has_highperf=QueryPerformanceFrequency(&freq);
//has_highperf=0; // debug
if (has_highperf) {
QueryPerformanceCounter(&start);
loopend.QuadPart=start.QuadPart+freq.QuadPart*us/(1000*1000);
do {
QueryPerformanceCounter(&stop);
} while (stop.QuadPart<=loopend.QuadPart);
} }
perf_counter_checked = TRUE;
}
if (! use_perf_counter)
return FALSE;
else { else {
LARGE_INTEGER now; #ifdef W32USLEEPDBG
LARGE_INTEGER finish; QueryPerformanceCounter(&start);
QueryPerformanceCounter(&now); #endif
finish.QuadPart = now.QuadPart + (t * freq.QuadPart) / 1000000; Sleep(1);
do { Sleep( (DWORD)((us+999)/1000) );
QueryPerformanceCounter(&now); #ifdef W32USLEEPDBG
} while (now.QuadPart < finish.QuadPart); QueryPerformanceCounter(&stop);
#endif
return TRUE;
}
}
/*
WARNING WARNING This function replaces the standard usleep() library function
because it doesn't appear to delay for the correct time.
*/
#ifndef MIN_SLEEP_USEC
#define MIN_SLEEP_USEC 20000
#endif
unsigned usleep( unsigned int uSeconds )
{
struct timeval t1, t2;
struct timespec nanoDelay ;
if (usecPerfDelay(uSeconds))
return(0);
gettimeofday(&t1, NULL);
if( uSeconds > MIN_SLEEP_USEC )
{
nanoDelay.tv_sec = uSeconds / 1000000UL;
nanoDelay.tv_nsec = (uSeconds / 1000000UL) * 1000 ;
nanosleep( &nanoDelay, NULL ) ;
} }
/* loop for the remaining time */ #ifdef W32USLEEPDBG
t2.tv_sec = uSeconds / 1000000UL; dt=(unsigned long)((stop.QuadPart-start.QuadPart)*1000*1000/freq.QuadPart);
t2.tv_usec = uSeconds % 1000000UL; fprintf(stderr,"hpt:%i usleep usec:%lu sleep msec:%lu timed usec:%lu\n",
has_highperf,us,((us+999)/1000),dt);
timeradd(&t1, &t2, &t1); #endif
do {
gettimeofday(&t2, NULL);
} while (timercmp(&t2, &t1, <));
return(0);
} }
#endif #endif

View File

@ -23,6 +23,9 @@
* Posix serial interface for avrdude. * Posix serial interface for avrdude.
*/ */
#if !defined(WIN32NATIVE)
#include <ctype.h> #include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -350,3 +353,5 @@ int serial_drain(int fd, int display)
return 0; return 0;
} }
#endif /* WIN32NATIVE */

View File

@ -23,38 +23,306 @@
* Native Win32 serial interface for avrdude. * Native Win32 serial interface for avrdude.
*/ */
#if defined(WIN32NATIVE)
#include <windows.h>
#include <ctype.h> /* for isprint */
#include "serial.h" #include "serial.h"
extern char *progname; extern char *progname;
extern int verbose;
#if 0 #define W32SERBUFSIZE 1024
struct baud_mapping {
long baud;
DWORD speed;
};
/* HANDLE hComPort=INVALID_HANDLE_VALUE; */
static struct baud_mapping baud_lookup_table [] = {
{ 1200, CBR_1200 },
{ 2400, CBR_2400 },
{ 4800, CBR_4800 },
{ 9600, CBR_9600 },
{ 19200, CBR_19200 },
{ 38400, CBR_38400 },
{ 57600, CBR_57600 },
{ 115200, CBR_115200 },
{ 0, 0 } /* Terminator. */
};
static DWORD serial_baud_lookup(long 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: %ld",
progname, baud);
exit(1);
}
BOOL serial_w32SetTimeOut(HANDLE hComPort, DWORD timeout) // in ms
{
COMMTIMEOUTS ctmo;
ZeroMemory (&ctmo, sizeof(COMMTIMEOUTS));
ctmo.ReadIntervalTimeout = timeout;
ctmo.ReadTotalTimeoutMultiplier = timeout;
ctmo.ReadTotalTimeoutConstant = timeout;
return SetCommTimeouts(hComPort, &ctmo);
}
int serial_open(char * port, long baud) int serial_open(char * port, long baud)
{ {
return fd; DCB dcb;
LPVOID lpMsgBuf;
HANDLE hComPort=INVALID_HANDLE_VALUE;
/* if (hComPort!=INVALID_HANDLE_VALUE)
fprintf(stderr, "%s: serial_open(): \"%s\" is already open\n",
progname, port);
*/
hComPort = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hComPort == INVALID_HANDLE_VALUE) {
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL);
fprintf(stderr, "%s: serial_open(): can't open device \"%s\": %s\n",
progname, port, (char*)lpMsgBuf);
LocalFree( lpMsgBuf );
exit(1);
}
if (!SetupComm(hComPort, W32SERBUFSIZE, W32SERBUFSIZE))
{
CloseHandle(hComPort);
fprintf(stderr, "%s: serial_open(): can't set buffers for \"%s\"\n",
progname, port);
exit(1);
}
ZeroMemory (&dcb, sizeof(DCB));
dcb.DCBlength = sizeof(DCB);
dcb.BaudRate = serial_baud_lookup (baud);
dcb.fBinary = 1;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
if (!SetCommState(hComPort, &dcb))
{
CloseHandle(hComPort);
fprintf(stderr, "%s: serial_open(): can't set com-state for \"%s\"\n",
progname, port);
exit(1);
}
if (!serial_w32SetTimeOut(hComPort,0))
{
CloseHandle(hComPort);
fprintf(stderr, "%s: serial_open(): can't set initial timeout for \"%s\"\n",
progname, port);
exit(1);
}
return (int)hComPort;
} }
void serial_close(int fd) void serial_close(int fd)
{ {
HANDLE hComPort=(HANDLE)fd;
if (hComPort != INVALID_HANDLE_VALUE)
CloseHandle (hComPort);
hComPort = INVALID_HANDLE_VALUE;
} }
int serial_send(int fd, char * buf, size_t buflen) int serial_send(int fd, char * buf, size_t buflen)
{ {
size_t len = buflen;
unsigned char c='\0';
DWORD written;
HANDLE hComPort=(HANDLE)fd;
if (hComPort == INVALID_HANDLE_VALUE) {
fprintf(stderr, "%s: serial_send(): port not open\n",
progname);
exit(1);
}
if (!len)
return 0;
if (verbose > 3)
{
fprintf(stderr, "%s: Send: ", progname);
while (buflen) {
c = *buf;
if (isprint(c)) {
fprintf(stderr, "%c ", c);
}
else {
fprintf(stderr, ". ");
}
fprintf(stderr, "[%02x] ", c);
buf++;
buflen--;
}
fprintf(stderr, "\n");
}
serial_w32SetTimeOut(hComPort,500);
if (!WriteFile (hComPort, buf, buflen, &written, NULL)) {
fprintf(stderr, "%s: serial_send(): write error: %s\n",
progname, "sorry no info avail"); // TODO
exit(1);
}
if (written != buflen) {
fprintf(stderr, "%s: serial_send(): size/send mismatch\n",
progname);
exit(1);
}
return 0; return 0;
} }
int serial_recv(int fd, char * buf, size_t buflen) int serial_recv(int fd, char * buf, size_t buflen)
{ {
unsigned char c;
char * p = buf;
size_t len = 0;
DWORD read;
HANDLE hComPort=(HANDLE)fd;
if (hComPort == INVALID_HANDLE_VALUE) {
fprintf(stderr, "%s: serial_read(): port not open\n",
progname);
exit(1);
}
serial_w32SetTimeOut(hComPort,5000);
if (!ReadFile(hComPort, buf, buflen, &read, NULL)) {
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL );
fprintf(stderr, "%s: serial_recv(): read error: %s\n",
progname, (char*)lpMsgBuf);
LocalFree( lpMsgBuf );
exit(1);
}
p = buf;
if (verbose > 3)
{
fprintf(stderr, "%s: Recv: ", progname);
while (len) {
c = *p;
if (isprint(c)) {
fprintf(stderr, "%c ", c);
}
else {
fprintf(stderr, ". ");
}
fprintf(stderr, "[%02x] ", c);
p++;
len--;
}
fprintf(stderr, "\n");
}
return 0; return 0;
} }
int serial_drain(int fd, int display) int serial_drain(int fd, int display)
{ {
// int rc;
unsigned char buf[10];
BOOL readres;
DWORD read;
HANDLE hComPort=(HANDLE)fd;
if (hComPort == INVALID_HANDLE_VALUE) {
fprintf(stderr, "%s: serial_drain(): port not open\n",
progname);
exit(1);
}
serial_w32SetTimeOut(hComPort,250);
if (display) {
fprintf(stderr, "drain>");
}
while (1) {
readres=ReadFile(hComPort, buf, 1, &read, NULL);
if (!readres) {
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL );
fprintf(stderr, "%s: serial_drain(): read error: %s\n",
progname, (char*)lpMsgBuf);
LocalFree( lpMsgBuf );
exit(1);
}
if (read) { // data avail
if (display) fprintf(stderr, "%02x ", buf[0]);
}
else { // no more data
if (display) fprintf(stderr, "<drain\n");
break;
}
} // while
return 0; return 0;
} }
#endif #endif /* WIN32NATIVE */

6
term.c
View File

@ -28,9 +28,11 @@
#include <limits.h> #include <limits.h>
#if defined(HAVE_LIBREADLINE) #if defined(HAVE_LIBREADLINE)
#if !defined(WIN32NATIVE)
# include <readline/readline.h> # include <readline/readline.h>
# include <readline/history.h> # include <readline/history.h>
#endif #endif
#endif
#include "avr.h" #include "avr.h"
#include "config.h" #include "config.h"
@ -754,7 +756,7 @@ int do_cmd(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
char * terminal_get_input(const char *prompt) char * terminal_get_input(const char *prompt)
{ {
#if defined(HAVE_LIBREADLINE) #if defined(HAVE_LIBREADLINE) && !defined(WIN32NATIVE)
char *input; char *input;
input = readline(prompt); input = readline(prompt);
if ((input != NULL) && (strlen(input) >= 1)) if ((input != NULL) && (strlen(input) >= 1))
@ -767,7 +769,7 @@ char * terminal_get_input(const char *prompt)
if (fgets(input, sizeof(input), stdin)) if (fgets(input, sizeof(input), stdin))
{ {
/* FIXME: readline strips the '\n', should this too? */ /* FIXME: readline strips the '\n', should this too? */
strdup(input); return strdup(input);
} }
else else
return NULL; return NULL;