Build options for WIN32 (using mingw)
[bootloader] / cli / serial-win.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include <windows.h>
6 #include <conio.h>
7
8 #include "log.h"
9 #include "serial.h"
10
11 struct serial_port {
12         HANDLE handle;
13 };
14
15 port_t * serial_open(const char *name, int speed)
16 {
17         port_t *pt = NULL;
18         HANDLE port = CreateFileA(name, GENERIC_READ | GENERIC_WRITE, 
19                         0, NULL, OPEN_EXISTING, 0, NULL);
20
21         if (port == INVALID_HANDLE_VALUE) return NULL;
22
23         DCB settings;
24         memset(&settings, 0, sizeof(settings));
25         settings.DCBlength = sizeof(settings);
26
27         char seta[120];
28         snprintf(seta, sizeof(seta), "baud=%d data=8 parity=N stop=1 dtr=off rts=off", speed);
29         if (!BuildCommDCBA(seta, &settings)) {
30                 loge("Invalid serial port settings");
31                 CloseHandle(port);
32                 return NULL;
33         }
34
35         if (!SetCommState(port, &settings)) {
36                 loge("Unable to configure serial port");
37                 CloseHandle(port);
38                 return NULL;
39         }
40
41         COMMTIMEOUTS tout;
42         tout.ReadIntervalTimeout = MAXDWORD;
43         tout.ReadTotalTimeoutMultiplier  = MAXDWORD;
44         tout.ReadTotalTimeoutConstant    = 30000;
45         tout.WriteTotalTimeoutMultiplier = 0;
46         tout.WriteTotalTimeoutConstant   = 0;
47
48         if (!SetCommTimeouts(port, &tout)) {
49                 loge("Unable to set serial timeouts");
50                 CloseHandle(port);
51                 return NULL;
52         }
53
54         pt = malloc(sizeof(port_t));
55         pt->handle = port;
56
57         return pt;
58
59 }
60
61 void serial_close(port_t * pt)
62 {
63         if (pt == NULL) return;
64         if (pt->handle == INVALID_HANDLE_VALUE) return;
65
66         CloseHandle(pt->handle);
67         pt->handle = INVALID_HANDLE_VALUE;
68
69         return;
70 }
71
72 int serial_read(port_t * pt, unsigned char * buff, size_t len)
73 {
74         if (pt == NULL || pt->handle == INVALID_HANDLE_VALUE) return -1;
75         int count = 0;
76         unsigned char * p = buff;
77         int done = 0;
78
79         /* read will block if no chars, will return whats there otherwise,
80          * and will timeout after 30 seconds */
81         while (done < len) {
82                 if (!ReadFile(pt->handle, p, len-done, (LPDWORD)&count, NULL))
83                         return -1;
84                 p += count;
85                 done += count;
86         }
87
88         return count;
89 }
90
91 int serial_write(port_t * pt, unsigned char * buff, size_t len)
92 {
93         if (pt == NULL || pt->handle == INVALID_HANDLE_VALUE) return -1;
94
95         int n;
96
97         if (WriteFile(pt->handle, buff, len,  (LPDWORD)&n, NULL))
98                 return n;
99
100         return 0;
101 }
102
103 int serial_break(port_t * pt, int set)
104 {
105         if (pt == NULL || pt->handle == INVALID_HANDLE_VALUE) return -1;
106
107         if (set) {
108                 SetCommBreak(pt->handle);
109         } else {
110                 ClearCommBreak(pt->handle);
111         }
112
113         return 0;
114 }
115