-CFLAGS= -g -fstack-protector-all -Wall -pedantic -std=gnu99 -fPIC -D_GNU_SOURCE
+CFLAGS= -g -fstack-protector-all -Wall -pedantic -std=gnu99 -D_GNU_SOURCE
LDFLAGS= $(CFLAGS)
-SRC=serial.c log.c boot.c protocol.c devices.c memory.c
+SRC=log.c boot.c protocol.c devices.c memory.c
+
+WINDOWS=0
+
+ifeq ($(WINDOWS),1)
+PREFIX=i686-w64-mingw32-
+SRC += serial-win.c
+CFLAGS += -static -mwindows -DDEFPORT="COM4:"
+else
+CFLAGS += -fPIC -DDEFPORT="/dev/ttyUSB0"
+SRC += serial.c
+endif
+
+CC=$(PREFIX)gcc
OBJS=$(SRC:%.c=%.o)
$(CC) $(CFLAGS) -c -o $@ $<
clean:
- rm -f $(OBJS) boot
+ rm -f $(OBJS) $(TARGET)
#include "memory.h"
#define BAUD_RATE 19200
+
+#define STRINGIFY(n) #n
+
+#ifdef DEFPORT
+#define PORT_NAME STRINGIFY(DEFPORT)
+#else
#define PORT_NAME "/dev/ttyUSB0"
+#endif
+
+#ifdef _WIN32
+static void keypress(void)
+{
+ printf("Press ENTER to exit\n");
+ getchar();
+}
+#else
+static void keypress(void) {}
+#endif
void usage(const char * name)
if (!idonly && optind >= argc) {
loge("Error: missing hexfile");
+ keypress();
return 1;
}
FILE * fd = NULL;
if ((fd = fopen(argv[optind], "r"))==NULL) {
loge("Error opening %s: %s", argv[optind], strerror(errno));
+ keypress();
return 1;
}
ram = load_ihex(fd);
logd("open serial port %s at %d baud", port, baud);
port_t * pt = serial_open(port, baud);
- if (pt == NULL) return 1;
+ if (pt == NULL) {
+ keypress();
+ return 1;
+ }
uint16_t maxmem;
uint16_t devid;
if (loader_connect(pt, &maxmem, &devid)) {
+ keypress();
return 1;
}
logi(" Max Mem: %d", dev->memsize );
}
+ keypress();
return 0;
}
if (dev) logd("Device Name: %s", dev->name);
/* check that the selected program will fit on this device */
if (makesafe_mem(&ram, maxmem)) {
serial_close(pt);
+ keypress();
return 1;
}
logd("After re-organisation");
/* finished */
serial_close(pt);
logd("done.");
+ keypress();
return 0;
}
int debug = 0;
+#ifdef _WIN32
+#include <windows.h>
+#include <fcntl.h>
+#include <io.h>
+
+static const WORD MAX_CONSOLE_LINES = 500;
+
void logit(int type, const char * format, ...)
{
+ static int hConHandle = 0;
+
+ if (hConHandle == 0) {
+ CONSOLE_SCREEN_BUFFER_INFO coninfo;
+ AllocConsole();
+ //AttachConsole(ATTACH_PARENT_PROCESS);
+ GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
+ coninfo.dwSize.Y = MAX_CONSOLE_LINES;
+ SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
+
+ int hConHandle;
+ long lStdHandle;
+ FILE *fp;
+
+ // redirect unbuffered STDOUT to the console
+ lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
+ hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
+ fp = _fdopen( hConHandle, "w" );
+ *stdout = *fp;
+ setvbuf( stdout, NULL, _IONBF, 0 );
+
+ // redirect unbuffered STDIN to the console
+ lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
+ hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
+ fp = _fdopen( hConHandle, "r" );
+ *stdin = *fp;
+
+ setvbuf( stdin, NULL, _IONBF, 0 );
+
+ // redirect unbuffered STDERR to the console
+ lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
+ hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
+ fp = _fdopen( hConHandle, "w" );
+ *stderr = *fp;
+
+ setvbuf( stderr, NULL, _IONBF, 0 );
+ }
+
va_list va;
va_start(va, format);
va_end(va);
}
+
+#else
+
+void logit(int type, const char * format, ...)
+{
+ va_list va;
+ va_start(va, format);
+
+ struct timeval now;
+ gettimeofday(&now, NULL);
+
+ struct tm * now_tm = localtime(&(now.tv_sec));
+
+ if (type == LOG_INFO) {
+ vfprintf(stdout, format, va);
+ fprintf(stdout, "\n");
+ } else
+ if (type == LOG_DEBUG) {
+ if (debug > 0) {
+ fprintf(stderr, "%02d:%02d:%02d.%03d ", now_tm->tm_hour, now_tm->tm_min, now_tm->tm_sec, (int)(now.tv_usec / 1000));
+ vfprintf(stderr, format, va);
+ fprintf(stderr, "\n");
+ }
+ } else {
+ vfprintf(stderr, format, va);
+ fprintf(stderr, "\n");
+ }
+
+ va_end(va);
+}
+
+#endif
int ret = serial_write(pt, buff, 4);
if (ret <= 0) return 1;
- bzero(buff, len);
+ memset(buff, 0, len);
/* read the response */
if (serial_read(pt, buff, 1)<=0) return 1;
} else {
logd("Connect: Want 'BL' got '%c%c' ret=%d", buff[1], buff[2], ret);
}
- bzero(buff,3);
+ memset(buff,0,3);
}
if (ret <= 0) {
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <windows.h>
+#include <conio.h>
+
+#include "log.h"
+#include "serial.h"
+
+struct serial_port {
+ HANDLE handle;
+};
+
+port_t * serial_open(const char *name, int speed)
+{
+ port_t *pt = NULL;
+ HANDLE port = CreateFileA(name, GENERIC_READ | GENERIC_WRITE,
+ 0, NULL, OPEN_EXISTING, 0, NULL);
+
+ if (port == INVALID_HANDLE_VALUE) return NULL;
+
+ DCB settings;
+ memset(&settings, 0, sizeof(settings));
+ settings.DCBlength = sizeof(settings);
+
+ char seta[120];
+ snprintf(seta, sizeof(seta), "baud=%d data=8 parity=N stop=1 dtr=off rts=off", speed);
+ if (!BuildCommDCBA(seta, &settings)) {
+ loge("Invalid serial port settings");
+ CloseHandle(port);
+ return NULL;
+ }
+
+ if (!SetCommState(port, &settings)) {
+ loge("Unable to configure serial port");
+ CloseHandle(port);
+ return NULL;
+ }
+
+ COMMTIMEOUTS tout;
+ tout.ReadIntervalTimeout = MAXDWORD;
+ tout.ReadTotalTimeoutMultiplier = MAXDWORD;
+ tout.ReadTotalTimeoutConstant = 30000;
+ tout.WriteTotalTimeoutMultiplier = 0;
+ tout.WriteTotalTimeoutConstant = 0;
+
+ if (!SetCommTimeouts(port, &tout)) {
+ loge("Unable to set serial timeouts");
+ CloseHandle(port);
+ return NULL;
+ }
+
+ pt = malloc(sizeof(port_t));
+ pt->handle = port;
+
+ return pt;
+
+}
+
+void serial_close(port_t * pt)
+{
+ if (pt == NULL) return;
+ if (pt->handle == INVALID_HANDLE_VALUE) return;
+
+ CloseHandle(pt->handle);
+ pt->handle = INVALID_HANDLE_VALUE;
+
+ return;
+}
+
+int serial_read(port_t * pt, unsigned char * buff, size_t len)
+{
+ if (pt == NULL || pt->handle == INVALID_HANDLE_VALUE) return -1;
+ int count = 0;
+ unsigned char * p = buff;
+ int done = 0;
+
+ /* read will block if no chars, will return whats there otherwise,
+ * and will timeout after 30 seconds */
+ while (done < len) {
+ if (!ReadFile(pt->handle, p, len-done, (LPDWORD)&count, NULL))
+ return -1;
+ p += count;
+ done += count;
+ }
+
+ return count;
+}
+
+int serial_write(port_t * pt, unsigned char * buff, size_t len)
+{
+ if (pt == NULL || pt->handle == INVALID_HANDLE_VALUE) return -1;
+
+ int n;
+
+ if (WriteFile(pt->handle, buff, len, (LPDWORD)&n, NULL))
+ return n;
+
+ return 0;
+}
+
+int serial_break(port_t * pt, int set)
+{
+ if (pt == NULL || pt->handle == INVALID_HANDLE_VALUE) return -1;
+
+ if (set) {
+ SetCommBreak(pt->handle);
+ } else {
+ ClearCommBreak(pt->handle);
+ }
+
+ return 0;
+}
+