|
20 | 20 | #include <sys/select.h> |
21 | 21 | #include <errno.h> |
22 | 22 |
|
| 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 | + |
23 | 80 | 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 | + } |
25 | 84 |
|
26 | 85 | f->handle = open(f->name, O_RDWR | O_NOCTTY); |
27 | 86 | if (f->handle < 0) { |
28 | 87 | err_file((f->last_error = errno)); |
29 | 88 | } |
| 89 | + |
| 90 | + f->devspeed = select_unix_serial_speed(f->devspeed); |
| 91 | + |
30 | 92 | // save current port settings |
31 | 93 | tcgetattr(f->handle, &f->oldtio); |
32 | 94 | bzero(&f->newtio, sizeof(f->newtio)); |
@@ -83,33 +145,52 @@ int serial_open(dev_file_t *f) { |
83 | 145 | HANDLE hCom; |
84 | 146 | DWORD dwer; |
85 | 147 |
|
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 | + } |
87 | 151 |
|
| 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 | + |
88 | 155 | hCom = CreateFile(f->name, GENERIC_READ | GENERIC_WRITE, |
89 | 156 | 0, NULL, OPEN_EXISTING, 0, NULL); |
90 | 157 |
|
91 | 158 | if (hCom == INVALID_HANDLE_VALUE) { |
92 | 159 | dwer = GetLastError(); |
93 | 160 | if (dwer != 5) { |
94 | | - rt_raise("SERIALFS: CreateFile() failed (%d)", dwer); |
| 161 | + rt_raise("SERIALFS: CreateFile() failed (Error %d)", dwer); |
95 | 162 | } else { |
96 | 163 | rt_raise("SERIALFS: ACCESS DENIED"); |
97 | 164 | } |
98 | 165 | return 0; |
99 | 166 | } |
100 | 167 |
|
101 | 168 | if (!GetCommState(hCom, &dcb)) { |
102 | | - rt_raise("SERIALFS: GetCommState() failed (%d)", GetLastError()); |
| 169 | + rt_raise("SERIALFS: GetCommState() failed (Error %d)", GetLastError()); |
103 | 170 | return 0; |
104 | 171 | } |
105 | 172 |
|
| 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 |
106 | 187 | dcb.BaudRate = f->devspeed; |
107 | 188 | dcb.ByteSize = 8; |
108 | 189 | dcb.Parity = NOPARITY; |
109 | 190 | dcb.StopBits = ONESTOPBIT; |
110 | 191 |
|
111 | 192 | if (!SetCommState(hCom, &dcb)) { |
112 | | - rt_raise("SERIALFS: SetCommState() failed (%d)", GetLastError()); |
| 193 | + rt_raise("SERIALFS: SetCommState() failed (Error %d)", GetLastError()); |
113 | 194 | return 0; |
114 | 195 | } |
115 | 196 |
|
|
0 commit comments