#include <string.h>
#include <termios.h>
#include <stdint.h>
-
-#define UART_SPEED B2400
+#include <sys/ioctl.h>
+#include <linux/serial.h> /* struct struct_serial */
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h> /* clock_nanosleep */
#define LIN_HDR_SIZE 2
#define LIN_PKT_MAX_SIZE 16 /* FIXME */
-struct termios term_attr;
+
+int lin_baudrate = B19200;
+int lin_break_baud = 0;
+
+struct termios tattr_orig;
+struct termios tattr;
+struct serial_struct sattr;
/* ------------------------------------------------------------------------ */
static void reset_input_mode(int tty)
{
- tcsetattr(tty, TCSANOW, &term_attr);
+ tcsetattr(tty, TCSANOW, &tattr_orig);
}
static void set_input_mode(int tty, speed_t speed)
{
int status;
- struct termios tattr;
/* Flush input and output queues. */
if (tcflush(tty, TCIOFLUSH) != 0) {
}
/* Save settings for later restoring */
- tcgetattr(tty, &term_attr);
+ tcgetattr(tty, &tattr_orig);
+ if (ioctl(tty, TIOCGSERIAL, &sattr) < 0) {
+ perror("ioctl()");
+ }
/* RAW mode */
tcgetattr(tty, &tattr);
- tattr.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
- | INLCR | IGNCR | ICRNL | IXON);
- tattr.c_oflag &= ~OPOST;
- tattr.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
- tattr.c_cflag &= ~(CSIZE | PARENB);
- tattr.c_cflag |= CS8;
-
- tattr.c_cc[VMIN] = 1;
- tattr.c_cc[VTIME] = 0;
+// tattr.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
+// | INLCR | IGNCR | ICRNL | IXON);
+// tattr.c_oflag &= ~OPOST;
+// tattr.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
+// tattr.c_cflag &= ~(CSIZE | PARENB);
+// tattr.c_cflag |= CS8;
+
+ /* Sets hardware control flags: */
+ /* 8 data bits */
+ /* Enable receiver */
+ /* Ignore CD (local connection) */
+ tattr.c_cflag = CS8 | CREAD | CLOCAL;
+ tattr.c_iflag = 0;
+ tattr.c_oflag = NL0 | CR0 | TAB0 | BS0 | VT0 | FF0;
+ tattr.c_lflag = 0;
+
+// tattr.c_cc[VMIN] = 1;
+// tattr.c_cc[VTIME] = 0;
+
+ tattr.c_cc[VINTR] = '\0';
+ tattr.c_cc[VQUIT] = '\0';
+ tattr.c_cc[VERASE] = '\0';
+ tattr.c_cc[VKILL] = '\0';
+ tattr.c_cc[VEOF] = '\0';
+ tattr.c_cc[VTIME] = '\0';
+ tattr.c_cc[VMIN] = 1;
+ tattr.c_cc[VSWTC] = '\0';
+ tattr.c_cc[VSTART] = '\0';
+ tattr.c_cc[VSTOP] = '\0';
+ tattr.c_cc[VSUSP] = '\0';
+ tattr.c_cc[VEOL] = '\0';
+ tattr.c_cc[VREPRINT] = '\0';
+ tattr.c_cc[VDISCARD] = '\0';
+ tattr.c_cc[VWERASE] = '\0';
+ tattr.c_cc[VLNEXT] = '\0';
+ tattr.c_cc[VEOL2] = '\0';
/* Set TX, RX speed */
cfsetispeed(&tattr, speed);
if (status == -1)
perror("tcsetattr()");
+ /* Baudrate for sending LIN break */
+ //lin_break_baud = ((lin_baudrate * 2) / 3);
+ lin_break_baud = 12800;
}
int send_header(int tty)
{
- struct termios tattr;
int buff[3];
buff[0] = 0x00; /* Sync byte */
buff[1] = 0x55; /* Sync byte */
buff[2] = 0xC1; /* LIN ID: 1 */
+ printf("send_header() invoked\n");
+ tcflush(tty, TCIOFLUSH);
- /* Decrease speed to send BREAK (simulated with 0x00 data frame)*/
- tcgetattr(tty, &tattr);
- cfsetospeed(&tattr, B1200);
- tcsetattr(tty, TCSADRAIN, &tattr);
+ /* Decrease speed to send BREAK
+ * (simulated with 0x00 data frame) */
+
+ /* Set "non-standard" baudrate in serial_struct struct */
+ sattr.flags &= (~ASYNC_SPD_MASK);
+ sattr.flags |= (ASYNC_SPD_CUST);
+ //sattr.custom_divisor = (115200/12800);
+ sattr.custom_divisor = ((sattr.baud_base)/12800);
+ if (ioctl(tty, TIOCSSERIAL, &sattr) < 0)
+ {
+ perror("ioctl()");
+ }
+ cfsetospeed(&tattr, B38400); /* Should be set to this fixed value */
+ cfsetispeed(&tattr, B38400);
+ if (tcsetattr(tty, TCSANOW, &tattr) == -1) {
+ perror("tcsetattr()");
+ }
- write(tty, &buff[0], 1);
- cfsetospeed(&tattr, UART_SPEED);
- tcsetattr(tty, TCSADRAIN, &tattr);
+ printf("Write break\n");
+ write(tty, &buff[0], 1); /* Write "break" */
+#if 0
+ read(tty, &buff[0], 1);
+ printf("Break read\n");
+#else
+ {
+ struct timespec sleep_time;
+ sleep_time.tv_sec = 0;
+ sleep_time.tv_nsec = ((1000000000ll * 11) / lin_break_baud);
+ clock_nanosleep(CLOCK_MONOTONIC, 0, &sleep_time, NULL);
+ }
+#endif
+
+ sattr.flags &= (~ASYNC_SPD_CUST);
+ sattr.flags |= (ASYNC_SPD_MASK);
+ if (ioctl(tty, TIOCSSERIAL, &sattr) < 0)
+ {
+ perror("ioctl()");
+ }
+
+
+ /* Save "standard" baudrate to termios struct */
+ cfsetospeed(&tattr, lin_baudrate);
+ cfsetispeed(&tattr, lin_baudrate);
+ if (tcsetattr(tty, TCSANOW, &tattr) == -1) {
+ perror("tcsetattr()");
+ }
//tcsendbreak(tty, 1); /* Break */
//usleep((useconds_t) 50); /* Break Delimiter */
return -4;
}
+ fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
+ printf("Press enter to terminate.\n\n");
+
/* Configure UART */
- set_input_mode(tty, UART_SPEED);
+ set_input_mode(tty, lin_baudrate);
while(1) {
+ char c;
+
send_header(tty);
sleep(1);
- }
+
+ if (read(fileno(stdin), &c, 1) > 0)
+ break;
+ }
reset_input_mode(tty);
close(tty);