26 # include <sys/select.h>
27 # include <sys/param.h>
29 typedef struct termios term_info;
38 static const unsigned long int uiTimeoutStatic = 15000;
40 static unsigned long int uiTimeoutPerByte = 0;
43 # define CCLAIMED 0x80000000
46 uart_open (
const char *pcPortName)
48 serial_port_unix *sp = malloc (
sizeof (serial_port_unix));
51 return INVALID_SERIAL_PORT;
53 sp->fd = open (pcPortName, O_RDWR | O_NOCTTY | O_NONBLOCK);
56 return INVALID_SERIAL_PORT;
59 if (tcgetattr (sp->fd, &sp->tiOld) == -1) {
61 return INVALID_SERIAL_PORT;
64 if (sp->tiOld.c_iflag & CCLAIMED) {
66 return CLAIMED_SERIAL_PORT;
69 sp->tiNew = sp->tiOld;
71 sp->tiNew.c_cflag = CS8 | CLOCAL | CREAD;
72 sp->tiNew.c_iflag = CCLAIMED | IGNPAR;
73 sp->tiNew.c_oflag = 0;
74 sp->tiNew.c_lflag = 0;
76 sp->tiNew.c_cc[VMIN] = 0;
77 sp->tiNew.c_cc[VTIME] = 0;
79 if (tcsetattr (sp->fd, TCSANOW, &sp->tiNew) == -1) {
81 return INVALID_SERIAL_PORT;
84 tcflush (sp->fd, TCIFLUSH);
99 #define UART_BAUDRATE_T0_BYTE_DURATION(X) ((1000000 * 10)/ X)
102 uart_set_speed (serial_port sp,
const uint32_t uiPortSpeed)
106 DBG (
"Serial port speed requested to be set to %d bauds (%lu µs).", uiPortSpeed, uiTimeoutPerByte);
107 const serial_port_unix *spu = (serial_port_unix *) sp;
111 speed_t stPortSpeed = B9600;
112 switch (uiPortSpeed) {
117 stPortSpeed = B19200;
120 stPortSpeed = B38400;
124 stPortSpeed = B57600;
129 stPortSpeed = B115200;
134 stPortSpeed = B230400;
139 stPortSpeed = B460800;
143 ERR (
"Unable to set serial port speed to %d bauds. Speed value must be one of those defined in termios(3).",
149 cfsetispeed ((
struct termios *) &(spu->tiNew), stPortSpeed);
150 cfsetospeed ((
struct termios *) &(spu->tiNew), stPortSpeed);
151 if (tcsetattr (spu->fd, TCSADRAIN, &(spu->tiNew)) == -1) {
152 ERR (
"%s",
"Unable to apply new speed settings.");
157 uart_get_speed (serial_port sp)
159 uint32_t uiPortSpeed = 0;
160 const serial_port_unix *spu = (serial_port_unix *) sp;
161 switch (cfgetispeed (&spu->tiNew)) {
178 uiPortSpeed = 115200;
183 uiPortSpeed = 230400;
188 uiPortSpeed = 460800;
197 uart_close (
const serial_port sp)
199 if (((serial_port_unix *) sp)->fd >= 0) {
200 tcsetattr (((serial_port_unix *) sp)->fd, TCSANOW, &((serial_port_unix *) sp)->tiOld);
201 close (((serial_port_unix *) sp)->fd);
218 int iExpectedByteCount = (int)*pszRx;
219 DBG (
"iExpectedByteCount == %d", iExpectedByteCount);
220 struct timeval tvTimeout = {
222 .tv_usec = uiTimeoutStatic + (uiTimeoutPerByte * iExpectedByteCount),
224 struct timeval tv = tvTimeout;
231 FD_SET (((serial_port_unix *) sp)->fd, &rfds);
232 res = select (((serial_port_unix *) sp)->fd + 1, &rfds, NULL, NULL, &tv);
236 DBG (
"%s",
"RX error.");
251 res = ioctl (((serial_port_unix *) sp)->fd, FIONREAD, &byteCount);
256 res = read (((serial_port_unix *) sp)->fd, pbtRx + (*pszRx), MIN(byteCount, iExpectedByteCount));
257 iExpectedByteCount -= MIN (byteCount, iExpectedByteCount);
266 tv.tv_usec = uiTimeoutPerByte * MIN( iExpectedByteCount, 16 );
268 }
while (byteCount && (iExpectedByteCount > 0));
269 DBG (
"byteCount == %d, iExpectedByteCount == %d", byteCount, iExpectedByteCount);
279 uart_send (serial_port sp,
const byte_t * pbtTx,
const size_t szTx)
284 struct timeval tvTimeout = {
286 .tv_usec = uiTimeoutStatic + (uiTimeoutPerByte * szTx),
288 struct timeval tv = tvTimeout;
290 while (szPos < szTx) {
293 FD_SET (((serial_port_unix *) sp)->fd, &rfds);
294 res = select (((serial_port_unix *) sp)->fd + 1, NULL, &rfds, NULL, &tv);
298 DBG (
"%s",
"TX error.");
303 DBG (
"%s",
"TX time-out.");
307 res = write (((serial_port_unix *) sp)->fd, pbtTx + szPos, szTx - szPos);
317 tv.tv_usec = uiTimeoutStatic + uiTimeoutPerByte * MIN( szTx - szPos, 16 );