| 122 | } |
| 123 | |
| 124 | void fxOpenSerial(txSerialTool self) |
| 125 | { |
| 126 | speed_t speed; |
| 127 | struct termios term; |
| 128 | |
| 129 | self->serialConnection = open(self->path, O_RDWR | O_NOCTTY | O_NDELAY); |
| 130 | if (self->serialConnection < 0) { |
| 131 | if (!self->reconnecting) |
| 132 | mxThrowElse(self->serialConnection >= 0); |
| 133 | return; |
| 134 | } |
| 135 | fcntl(self->serialConnection, F_SETFL, 0); |
| 136 | switch (self->baud) { |
| 137 | case 921600: speed = B921600; break; |
| 138 | case 460800: speed = B460800; break; |
| 139 | case 230400: speed = B230400; break; |
| 140 | case 115200: speed = B115200; break; |
| 141 | case 57600: speed = B57600; break; |
| 142 | case 38400: speed = B38400; break; |
| 143 | case 19200: speed = B19200; break; |
| 144 | case 9600: speed = B9600; break; |
| 145 | default: speed = BOTHER; break; |
| 146 | } |
| 147 | // we need a raw terminal, start with zeroed termios and set all fields |
| 148 | // it's possible that using tcgetattr and then overriding everything is safer, hard to tell |
| 149 | memset(&term, 0, sizeof(term)); |
| 150 | term.c_cflag = CS8 | CLOCAL | CREAD; |
| 151 | term.c_iflag = IGNPAR; |
| 152 | term.c_oflag = 0; |
| 153 | term.c_lflag = 0; |
| 154 | term.c_cc[VTIME] = 0; |
| 155 | term.c_cc[VMIN] = 1; |
| 156 | cfsetspeed(&term, speed == BOTHER ? B115200 : speed); // adjust below in case of BOTHER |
| 157 | mxThrowElse(tcsetattr(self->serialConnection, TCSANOW, &term) == 0); |
| 158 | tcflush(self->serialConnection, TCIFLUSH); |
| 159 | |
| 160 | // prevent interference by ModemManager, et. al. |
| 161 | ioctl(self->serialConnection, TIOCEXCL, NULL); |
| 162 | |
| 163 | // handle non-standard speeds |
| 164 | if (speed == BOTHER) { |
| 165 | struct termios2 tio2; |
| 166 | ioctl(self->serialConnection, TCGETS2, &tio2); |
| 167 | tio2.c_cflag &= ~CBAUD; |
| 168 | tio2.c_cflag |= BOTHER; |
| 169 | tio2.c_ispeed = self->baud; |
| 170 | tio2.c_ospeed = self->baud; |
| 171 | ioctl(self->serialConnection, TCSETS2, &tio2); |
| 172 | } |
| 173 | usleep(5000); |
| 174 | |
| 175 | if (self->programming) { |
| 176 | if (self->traceCommands) |
| 177 | fprintf(stderr, "### programming mode\n"); |
| 178 | fxProgrammingModeSerial(self); |
| 179 | exit(0); |
| 180 | } |
| 181 |
no test coverage detected