]> rtime.felk.cvut.cz Git - linux-lin.git/blob - misc/tty_lin_master/main.c
a61566ce6432449a42febc79dffaeb075b7f7690
[linux-lin.git] / misc / tty_lin_master / main.c
1 /*
2  * PCAN-LIN, RS-232 to CAN/LIN converter control application
3  */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <fcntl.h>
9 #include <string.h>
10 #include <termios.h>
11 #include <stdint.h>
12
13 #define UART_SPEED              B2400
14
15 #define LIN_HDR_SIZE            2
16 #define LIN_PKT_MAX_SIZE        16 /* FIXME */
17 struct termios term_attr;
18 /* ------------------------------------------------------------------------ */
19 static void reset_input_mode(int tty)
20 {
21         tcsetattr(tty, TCSANOW, &term_attr);
22 }
23
24 static void set_input_mode(int tty, speed_t speed)
25 {
26         int status;
27         struct termios tattr;
28
29         /* Flush input and output queues. */
30         if (tcflush(tty, TCIOFLUSH) != 0) {
31                 perror("tcflush");
32                 exit(EXIT_FAILURE);
33         }
34
35         /* Fetch the current terminal parameters. */
36         if(!isatty(tty)) {
37                 fprintf(stderr, "Not a terminal.\n");
38                 exit(EXIT_FAILURE);
39         }
40
41         /* Save settings for later restoring */
42         tcgetattr(tty, &term_attr);
43
44         /* RAW mode */
45         tcgetattr(tty, &tattr);
46         tattr.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
47                                 | INLCR | IGNCR | ICRNL | IXON);
48         tattr.c_oflag &= ~OPOST;
49         tattr.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
50         tattr.c_cflag &= ~(CSIZE | PARENB);
51         tattr.c_cflag |= CS8;
52
53         tattr.c_cc[VMIN] = 1;
54         tattr.c_cc[VTIME] = 0;
55
56         /* Set TX, RX speed */
57         cfsetispeed(&tattr, speed);
58         cfsetospeed(&tattr, speed);
59
60         status = tcsetattr(tty, TCSANOW, &tattr);
61         if (status == -1)
62                 perror("tcsetattr()");
63
64 }
65
66
67 int send_header(int tty)
68 {
69         struct termios tattr;
70         int buff[3];
71         buff[0] = 0x00; /* Sync byte */
72         buff[1] = 0x55; /* Sync byte */
73         buff[2] = 0xC1; /* LIN ID: 1 */
74
75
76         /* Decrease speed to send BREAK (simulated with 0x00 data frame)*/      
77         tcgetattr(tty, &tattr);
78         cfsetospeed(&tattr, B1200);
79         tcsetattr(tty, TCSADRAIN, &tattr);
80
81         write(tty, &buff[0], 1);
82
83         cfsetospeed(&tattr, UART_SPEED);
84         tcsetattr(tty, TCSADRAIN, &tattr);
85
86         //tcsendbreak(tty, 1);   /* Break */
87         //usleep((useconds_t) 50); /* Break Delimiter */
88         write(tty, &buff[1], 1); /* Sync Byte Field */
89         write(tty, &buff[2], 1); /* PID -- Protected Identifier Field */
90         return 0;
91 }
92
93 int read_header(int tty)
94 {
95         int p0, p1; /* Parity bits */
96         int par_rec; /* Parity received as a part of a packet */
97         int par_calc; /* Calculated parity */
98         int received = 0;
99         uint8_t buff[LIN_HDR_SIZE];
100         memset(buff, '\0', sizeof(buff));
101
102         while (1) {
103                 received = read(tty, &buff[0], 1);
104                 if (received == -1)
105                         perror("read()");
106                 
107                 if (buff[0] != 0x55) /* Sync byte field */
108                         continue;
109
110                 received = read(tty, &buff[1], 1);
111                 if (received == -1)
112                         perror("read()");
113                 else
114                         break;
115         }
116
117         p0 = (buff[1] ^ (buff[1] >> 1) ^ (buff[1] >> 2) ^ (buff[1] >> 4)) & 0x1;
118         p1 = ~(((buff[1] >> 1) ^ (buff[1] >> 3) ^ (buff[1] >> 4) ^ (buff[1] >> 5))) & 0x1;
119
120         printf("%02X ", buff[0]);
121         printf("%02X ", buff[1]);
122
123         par_rec = (buff[1] & 0xc0) >> 6;
124         par_calc = p0 | (p1 << 1);
125         printf("| LIN id: %02X ", buff[1] & 0x3f);
126         //printf("| par_rec: %X; par_calc: %X ", par_rec, par_calc);
127         if (par_rec == par_calc)
128                 printf("| parity OK");
129         
130         printf("\n");
131
132         return 0;
133 }
134
135
136 int main(int argc, char* argv[])
137 {
138         char dev[32];
139         int tty;
140
141         if (argc < 2) {
142                 fprintf(stderr, "Device is missing\n");
143                 fprintf(stderr, "Usage: %s DEVICE\n", argv[0]);
144                 return -3;
145         }
146
147         strncpy((char*)&dev, argv[1], 32);
148         tty = open(dev, O_RDWR);
149         if (tty < 0) {
150                 perror("open()");
151                 return -4;
152         }
153
154         /* Configure UART */
155         set_input_mode(tty, UART_SPEED);
156
157         while(1) {
158                 send_header(tty);
159                 sleep(1);
160         }       
161
162         reset_input_mode(tty);
163         close(tty);
164
165         return EXIT_SUCCESS;
166 }