Skip to content

Commit 5eca11d

Browse files
committed
Serial port improvements.
1 parent c9ff326 commit 5eca11d

File tree

2 files changed

+113
-39
lines changed

2 files changed

+113
-39
lines changed

src/common/file.c

Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -112,34 +112,6 @@ int dev_fstatus(int handle) {
112112
return (f->handle != -1);
113113
}
114114

115-
/**
116-
* terminal speed
117-
* select the correct system constant
118-
*/
119-
#if USE_TERM_IO
120-
int select_unix_serial_speed(int n) {
121-
switch (n) {
122-
case 300:
123-
return B300;
124-
case 600:
125-
return B600;
126-
case 1200:
127-
return B1200;
128-
case 2400:
129-
return B2400;
130-
case 4800:
131-
return B4800;
132-
case 9600:
133-
return B9600;
134-
case 19200:
135-
return B19200;
136-
case 38400:
137-
return B38400;
138-
}
139-
return B9600;
140-
}
141-
#endif
142-
143115
/**
144116
* opens a file
145117
*
@@ -183,19 +155,14 @@ int dev_fopen(int sb_handle, const char *name, int flags) {
183155
}
184156
if (strncmp(f->name, "COM", 3) == 0) {
185157
f->type = ft_serial_port;
158+
f->devspeed = 9600;
186159
f->port = f->name[3] - '0';
187160
if (f->port < 0) {
188161
f->port = 10;
189162
}
190163
if (strlen(f->name) > 5) {
191164
f->devspeed = xstrtol(f->name + 5);
192-
} else {
193-
f->devspeed = 9600;
194165
}
195-
196-
#if USE_TERM_IO
197-
f->devspeed = select_unix_serial_speed(f->devspeed);
198-
#endif
199166
} else if (strncmp(f->name, "SOCL:", 5) == 0) {
200167
f->type = ft_socket_client;
201168
} else if (strncasecmp(f->name, "HTTP:", 5) == 0) {
@@ -217,6 +184,32 @@ int dev_fopen(int sb_handle, const char *name, int flags) {
217184
strcpy(f->name, "SDIN:");
218185
f->type = ft_stream;
219186
}
187+
} else if (strncmp(f->name, "/dev/tty", 8) == 0) {
188+
f->type = ft_serial_port;
189+
f->devspeed = 9600;
190+
const char *ptrSpeed = strchr(f->name, ':');
191+
if(ptrSpeed) {
192+
if(strlen(ptrSpeed) > 1) {
193+
f->devspeed = xstrtol(ptrSpeed + 1);
194+
}
195+
f->name[ptrSpeed - f->name] = '\0';
196+
}
197+
}
198+
if (f->name[5] == ':') {
199+
for (int i = 0; i < 4; i++) {
200+
f->name[i] = to_upper(f->name[i]);
201+
}
202+
if (strncmp(f->name, "COM", 3) == 0) {
203+
f->type = ft_serial_port;
204+
f->devspeed = 9600;
205+
f->port = (f->name[3] - '0') * 10 + (f->name[4] - '0');
206+
if (f->port < 0) {
207+
f->port = 10;
208+
}
209+
if (strlen(f->name) > 6) {
210+
f->devspeed = xstrtol(f->name + 6);
211+
}
212+
}
220213
}
221214
} // device
222215

src/common/fs_serial.c

Lines changed: 86 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,75 @@
2020
#include <sys/select.h>
2121
#include <errno.h>
2222

23+
/**
24+
* terminal speed
25+
* select the correct system constant
26+
*/
27+
long select_unix_serial_speed(long n) {
28+
switch (n) {
29+
case 300:
30+
return B300;
31+
case 600:
32+
return B600;
33+
case 1200:
34+
return B1200;
35+
case 2400:
36+
return B2400;
37+
case 4800:
38+
return B4800;
39+
case 9600:
40+
return B9600;
41+
case 19200:
42+
return B19200;
43+
case 38400:
44+
return B38400;
45+
// extra baud rates (but not posix)
46+
case 57600:
47+
return B57600;
48+
case 115200:
49+
return B115200;
50+
case 230400:
51+
return B230400;
52+
case 460800:
53+
return B460800;
54+
case 500000:
55+
return B500000;
56+
case 576000:
57+
return B576000;
58+
case 921600:
59+
return B921600;
60+
case 1000000:
61+
return B1000000;
62+
case 1152000:
63+
return B1152000;
64+
case 1500000:
65+
return B1500000;
66+
case 2000000:
67+
return B2000000;
68+
case 2500000:
69+
return B2500000;
70+
case 3000000:
71+
return B3000000;
72+
case 3500000:
73+
return B3500000;
74+
case 4000000:
75+
return B4000000;
76+
}
77+
return B9600;
78+
}
79+
2380
int serial_open(dev_file_t *f) {
24-
sprintf(f->name, "/dev/ttyS%d", f->port);
81+
if (strncmp(f->name, "COM", 3) == 0) {
82+
sprintf(f->name, "/dev/ttyS%d", f->port);
83+
}
2584

2685
f->handle = open(f->name, O_RDWR | O_NOCTTY);
2786
if (f->handle < 0) {
2887
err_file((f->last_error = errno));
2988
}
89+
90+
f->devspeed = select_unix_serial_speed(f->devspeed);
91+
3092
// save current port settings
3193
tcgetattr(f->handle, &f->oldtio);
3294
bzero(&f->newtio, sizeof(f->newtio));
@@ -83,33 +145,52 @@ int serial_open(dev_file_t *f) {
83145
HANDLE hCom;
84146
DWORD dwer;
85147

86-
sprintf(f->name, "COM%d", f->port);
148+
if (strncmp(f->name, "COM", 3) != 0) {
149+
rt_raise("SERIALFS: Linux serial port was specified. Use COM instead.");
150+
}
87151

152+
// Bug when opening COM-Port > 9: https://support.microsoft.com/en-us/topic/howto-specify-serial-ports-larger-than-com9-db9078a5-b7b6-bf00-240f-f749ebfd913e
153+
sprintf(f->name, "\\\\.\\COM%d", f->port);
154+
88155
hCom = CreateFile(f->name, GENERIC_READ | GENERIC_WRITE,
89156
0, NULL, OPEN_EXISTING, 0, NULL);
90157

91158
if (hCom == INVALID_HANDLE_VALUE) {
92159
dwer = GetLastError();
93160
if (dwer != 5) {
94-
rt_raise("SERIALFS: CreateFile() failed (%d)", dwer);
161+
rt_raise("SERIALFS: CreateFile() failed (Error %d)", dwer);
95162
} else {
96163
rt_raise("SERIALFS: ACCESS DENIED");
97164
}
98165
return 0;
99166
}
100167

101168
if (!GetCommState(hCom, &dcb)) {
102-
rt_raise("SERIALFS: GetCommState() failed (%d)", GetLastError());
169+
rt_raise("SERIALFS: GetCommState() failed (Error %d)", GetLastError());
103170
return 0;
104171
}
105172

173+
// Default settings from Putty
174+
dcb.fBinary = TRUE;
175+
dcb.fDtrControl = DTR_CONTROL_ENABLE; // This is needed for Raspberry Pi PICO
176+
dcb.fDsrSensitivity = FALSE;
177+
dcb.fTXContinueOnXoff = FALSE;
178+
dcb.fOutX = FALSE;
179+
dcb.fInX = FALSE;
180+
dcb.fErrorChar = FALSE;
181+
dcb.fNull = FALSE;
182+
dcb.fRtsControl = RTS_CONTROL_ENABLE;
183+
dcb.fAbortOnError = FALSE;
184+
dcb.fOutxCtsFlow = FALSE;
185+
dcb.fOutxDsrFlow = FALSE;
186+
// Settings SmallBASIC
106187
dcb.BaudRate = f->devspeed;
107188
dcb.ByteSize = 8;
108189
dcb.Parity = NOPARITY;
109190
dcb.StopBits = ONESTOPBIT;
110191

111192
if (!SetCommState(hCom, &dcb)) {
112-
rt_raise("SERIALFS: SetCommState() failed (%d)", GetLastError());
193+
rt_raise("SERIALFS: SetCommState() failed (Error %d)", GetLastError());
113194
return 0;
114195
}
115196

0 commit comments

Comments
 (0)