-
Notifications
You must be signed in to change notification settings - Fork 19
/
os_serial.cpp
145 lines (135 loc) · 3.04 KB
/
os_serial.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
* os_serial.cpp
*
* (C) Copyright 2014 Ulrich Hecht
*
* This file is part of CASCADE. CASCADE is almost free software; you can
* redistribute it and/or modify it under the terms of the Cascade Public
* License 1.0. Read the file "LICENSE" for details.
*/
#include "os.h"
#include "debug.h"
#include <stdlib.h>
#ifndef DRYDOCK
/** Convert carriage return to line feed.
@param buf data to be converted
@param size size of buf
*/
static void crtolf(char *buf, size_t size)
{
size_t i;
for (i = 0; i < size; i++) {
if (buf[i] == '\r')
buf[i] = '\n';
}
}
#endif
/** Get response from serial port .
@param fd serial port file descriptor
@param buf buffer the input data will be written to
@param size size of buf
@param timeout timeout (seconds) before aborting read
@param expect character signaling end of transmission
@return number of bytes read or -1 on error
*/
char *os_serial_read(int fd, int timeout, int expect)
{
int size = 9000;
char *buf = (char *)calloc(1, size);
#ifdef DRYDOCK
gets(buf);
return buf;
#else
int rc;
char *obuf = buf;
timeout *= 1000;
while (size > 0) {
/* check if there is data to read */
int bytes;
for (; timeout > 0;) {
bytes = os_serial_bytes_received(fd);
if (bytes > 0) break;
os_msleep(1); timeout--;
}
if (timeout <= 0) {
/* read timeout */
ERROR("OS timeout reading from serial port\n");
free(obuf);
return NULL;
}
rc = os_serial_read_to_buffer(fd, buf, bytes > size ? size : bytes);
if (rc < 0) {
ERROR("OS I/O error reading from serial port\n");
free(obuf);
return NULL;
}
crtolf(buf, rc);
size -= rc;
buf += rc;
/* check for end-of-transmission character */
if (expect && rc >= 1 && buf[-1] == expect) {
DEBUG(OS, "OS serial read: %s\n", obuf);
return obuf;
}
}
DEBUG(OS, "OS serial read: %s\n", obuf);
return obuf;
#endif /* DRYDOCK */
}
int os_serial_expect(int fd, int prompt, int timeout)
{
char *x;
if (!(x = os_serial_read(fd, timeout, prompt)))
return 1;
else {
free(x);
return 0;
}
}
static void breakbit(int fd, int bit)
{
if (bit)
os_serial_clear_break(fd);
else
os_serial_set_break(fd);
}
int os_serial_send_byte_5baud(int fd, char byte)
{
int flags;
DEBUG(OS, "OS serial flush before 5 baud send\n");
if (os_serial_flush(fd) < 0)
return -1;
#if 1
/* turn off CAN on K+CAN */
os_serial_clear_dtr(fd);
os_serial_clear_rts(fd);
os_msleep(500);
#endif
breakbit(fd, 1);
os_msleep(500);
breakbit(fd, 0); // start bit
#if 0
os_serial_clear_rts(fd);
#endif
os_msleep(200);
for (int i = 0; i < 8; i++) {
DEBUG(WARN, "bit %d\n", !!(byte & (1 << i)));
breakbit(fd, byte & (1 << i));
#if 0
if (byte & (1 << i)) {
os_serial_set_rts(fd);
}
else {
os_serial_clear_rts(fd);
}
#endif
os_msleep(200);
DEBUG(WARN, "time %d\n", os_mtime());
}
#if 0
os_serial_set_rts(fd);
#endif
breakbit(fd, 1);
//os_serial_flush(fd);
return 0;
}