Build options for WIN32 (using mingw)
authorJustin Mitchell <justin@discordia.org.uk>
Tue, 1 Oct 2013 09:26:13 +0000 (10:26 +0100)
committerJustin Mitchell <justin@discordia.org.uk>
Tue, 1 Oct 2013 09:26:13 +0000 (10:26 +0100)
cli/Makefile
cli/boot.c
cli/log.c
cli/protocol.c
cli/serial-win.c [new file with mode: 0644]

index 3615658..6566a12 100644 (file)
@@ -1,7 +1,20 @@
-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)
 
@@ -13,5 +26,5 @@ boot: $(OBJS)
        $(CC) $(CFLAGS) -c -o $@ $<
 
 clean:
-       rm -f $(OBJS) boot
+       rm -f $(OBJS) $(TARGET)
 
index 7a3e26e..087b47a 100644 (file)
 #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)
@@ -170,6 +187,7 @@ int main(int argc, char **argv)
 
        if (!idonly && optind >= argc) {
                loge("Error: missing hexfile");
+               keypress();
                return 1;
        }
 
@@ -179,6 +197,7 @@ int main(int argc, char **argv)
                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);
@@ -190,11 +209,15 @@ int main(int argc, char **argv)
 
        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;
        }
 
@@ -208,6 +231,7 @@ int main(int argc, char **argv)
                        logi("  Max Mem: %d", dev->memsize );
                }
 
+               keypress();
                return 0;
        }
        if (dev) logd("Device Name: %s", dev->name);
@@ -215,6 +239,7 @@ int main(int argc, char **argv)
        /* 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");
@@ -231,6 +256,7 @@ int main(int argc, char **argv)
        /* finished */
        serial_close(pt);
        logd("done.");
+       keypress();
        return 0;
 
 }
index ff27062..e32cd67 100644 (file)
--- a/cli/log.c
+++ b/cli/log.c
@@ -7,8 +7,53 @@
 
 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);
 
@@ -34,3 +79,35 @@ void logit(int type, const char * 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
index 5d6e028..c9db1e0 100644 (file)
@@ -64,7 +64,7 @@ int loader_readmem(port_t * pt, uint16_t addr, uint8_t * memory, int words)
        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;
@@ -219,7 +219,7 @@ int loader_connect(port_t * pt, uint16_t *maxmem, uint16_t *devid)
                } 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) {
diff --git a/cli/serial-win.c b/cli/serial-win.c
new file mode 100644 (file)
index 0000000..9dd5cbe
--- /dev/null
@@ -0,0 +1,115 @@
+#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;
+}
+