]> rtime.felk.cvut.cz Git - linux-lin.git/commitdiff
Setting UART speed to custom value for sending break.
authorRostislav Lisovy <lisovy@gmail.com>
Wed, 23 Nov 2011 17:59:26 +0000 (18:59 +0100)
committerRostislav Lisovy <lisovy@gmail.com>
Wed, 23 Nov 2011 17:59:26 +0000 (18:59 +0100)
Used with 19200 baud rate for data TX, break generated by
sending 0x00 with 12800 baud rate.

PCAN LIN converter configured as a slave does respond.

misc/tty_lin_master/Makefile
misc/tty_lin_master/main.c

index 6bf535a90f6a7fee2cafae564423002840b1997f..06443ed3dd6894018a8be73d0479857a7fc5a8fa 100644 (file)
@@ -1,2 +1,2 @@
 all: main.c
-       gcc main.c -std=gnu99 -Wall -pedantic -o main
+       gcc main.c -lrt -std=gnu99 -Wall -pedantic -o main
index a61566ce6432449a42febc79dffaeb075b7f7690..dfad09a3c0dcfd259e9d616795291ddac38bcea4 100644 (file)
@@ -9,22 +9,30 @@
 #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) {
@@ -39,19 +47,49 @@ static void set_input_mode(int tty, speed_t speed)
        }
 
        /* 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);
@@ -61,27 +99,69 @@ static void set_input_mode(int tty, speed_t 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 */
@@ -151,13 +231,21 @@ int main(int argc, char* argv[])
                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);