rllib
1
Main Page
Classes
Files
File List
File Members
All
Classes
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
lib
rl3964r.cpp
Go to the documentation of this file.
1
/***************************************************************************
2
rl3964r.cpp - description
3
-------------------
4
begin : Wed Jan 14 2004
5
copyright : (C) 2004 by R. Lehrig
6
email : lehrig@t-online.de
7
***************************************************************************/
8
9
/***************************************************************************
10
* *
11
* This library is free software; you can redistribute it and/or modify *
12
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
13
* published by the Free Software Foundation *
14
* *
15
***************************************************************************/
16
#include <stdio.h>
17
#include <stdarg.h>
18
#include <string.h>
19
#include "
rlcutil.h
"
20
#include "
rl3964r.h
"
21
#define STX 2
22
#define ETX 3
23
#define ENQ 5
24
#define EOT 4
25
#define ETB 23
26
#define DLE 16
27
#define NAK 21
28
#define ACK 6
29
30
enum
State
31
{
32
IDLE
= 0,
33
SENDING
= 1,
34
RECEIVING
= 2,
35
WANT_TO_SEND
= 3,
36
WANT_TO_RECEIVE
= 4
37
};
38
39
static
const
char
*
statestr
[] = {
"idle"
,
"sending"
,
"receiving"
,
"want_to_send"
,
"want_to_receive"
};
40
41
static
void
*
receiverThread
(
void
*arg)
42
{
43
THREAD_PARAM
*p = (
THREAD_PARAM
*) arg;
44
rl3964R
*d = (
rl3964R
*) p->
user
;
45
unsigned
char
c;
46
int
ret,send_retry;
47
48
send_retry = 0;
49
while
(d->
run
)
50
{
51
c = 0x0ff;
52
ret = d->
tty
.
select
(1000);
53
if
(ret == 1) c = d->
tty
.
readChar
();
54
p->
thread
->
lock
();
55
56
d->
dprintf
(
"receiverThread: c=%d state=%s\n"
,c,
statestr
[d->
state
]);
57
if
(c==
STX
&& d->
state
==
IDLE
)
58
{
59
d->
dprintf
(
"STX IDLE\n"
);
60
d->
state
=
RECEIVING
;
61
d->
dprintf
(
"write DLE\n"
);
62
d->
tty
.
writeChar
(
DLE
);
63
d->
dprintf
(
"call receive\n"
);
64
d->
receive
();
65
d->
dprintf
(
"after receive\n"
);
66
d->
state
=
IDLE
;
67
}
68
else
if
(c==
STX
&& d->
state
==
WANT_TO_SEND
&& d->
priority
==
rl3964R::lowPriority
)
69
{
70
d->
dprintf
(
"receiverThread: STX WANT_TO_SEND lowPriority\n"
);
71
d->
state
=
RECEIVING
;
72
d->
tty
.
writeChar
(
DLE
);
73
d->
receive
();
74
d->
state
=
WANT_TO_SEND
;
75
}
76
else
if
(c==
STX
&& d->
state
==
WANT_TO_SEND
&& d->
priority
==
rl3964R::highPriority
)
77
{
78
d->
dprintf
(
"receiverThread: STX WANT_TO_SEND highPriority\n"
);
79
d->
tty
.
writeChar
(
NAK
);
80
d->
tty
.
writeChar
(
STX
);
81
}
82
else
if
(c==
DLE
&& d->
state
==
WANT_TO_SEND
)
83
{
84
d->
dprintf
(
"receiverThread: DLE WANT_TO_SEND\n"
);
85
d->
send
();
86
d->
state
=
IDLE
;
87
d->
receiver
.
incrementSemaphore
();
88
}
89
else
if
(c==
NAK
)
90
{
91
d->
dprintf
(
"receiverThread: NAK\n"
);
92
}
93
else
if
(d->
state
==
WANT_TO_SEND
)
94
{
95
if
(send_retry < 1)
96
{
97
}
98
else
if
(send_retry < 3)
99
{
100
d->
tty
.
writeChar
(
STX
);
101
send_retry++;
102
d->
dprintf
(
"receiverThread: WANT_TO_SEND send=STX retry=%d\n"
,send_retry+1);
103
}
104
else
105
{
106
send_retry = 0;
107
d->
dprintf
(
"receiverThread: WANT_TO_SEND failed after 3 retries\n"
);
108
d->
state
=
IDLE
;
109
d->
receiver
.
incrementSemaphore
();
110
}
111
}
112
else
113
{
114
d->
dprintf
(
"receiverThread: IDLE\n"
);
115
d->
state
=
IDLE
;
116
}
117
118
p->
thread
->
unlock
();
119
}
120
121
return
NULL;
122
}
123
124
rl3964R::rl3964R
(
int
_priority)
125
{
126
priority
= _priority;
127
readCallback
= NULL;
128
debug
= 0;
129
isOpen
= 0;
130
state
=
IDLE
;
131
send_result
= 0;
132
tel_receive_length
=
tel_send_length
= -1;
133
}
134
135
rl3964R::~rl3964R
()
136
{
137
close
();
138
}
139
140
int
rl3964R::open
(
const
char
*devicename,
int
_baudrate)
141
{
142
int
ret;
143
144
if
(
isOpen
== 0)
145
{
146
//int openDevice(const char *devicename, int speed=B9600, int block=1, int rtscts=1, int bits=8, int stopbits=1, int parity=NONE);
147
ret =
tty
.
openDevice
(devicename,_baudrate,1,0,8,1,
rlSerial::EVEN
);
148
if
(ret >= 0)
149
{
150
isOpen
= 1;
151
run
= 1;
152
receiver
.
create
(
receiverThread
,
this
);
153
}
154
return
ret;
155
}
156
return
-1;
157
}
158
159
int
rl3964R::close
()
160
{
161
if
(
isOpen
== 1)
162
{
163
isOpen
= 0;
164
run
= 0;
165
dprintf
(
"close(): cancel\n"
);
166
receiver
.
cancel
();
167
dprintf
(
"close(): closeDevice\n"
);
168
tty
.
closeDevice
();
169
dprintf
(
"close(): return\n"
);
170
return
0;
171
}
172
isOpen
= 0;
173
return
-1;
174
}
175
176
int
rl3964R::setReadCallback
(
void
(*_readCallback)(
const
unsigned
char
*buf,
int
len))
177
{
178
readCallback
= _readCallback;
179
return
0;
180
}
181
182
int
rl3964R::write
(
const
unsigned
char
*buf,
int
len)
183
{
184
dprintf
(
"write() len=%d\n"
,len);
185
if
(len >= (
int
)
sizeof
(
tel_send
))
return
-1;
186
receiver
.
lock
();
187
tel_send_length
= len;
188
memcpy(
tel_send
,buf,len);
189
state
=
WANT_TO_SEND
;
190
dprintf
(
"write() STX\n"
);
191
tty
.
writeChar
(
STX
);
192
dprintf
(
"write() unlock\n"
);
193
receiver
.
unlock
();
194
dprintf
(
"write() waitSemaphore\n"
);
195
receiver
.
waitSemaphore
();
196
dprintf
(
"write() return len=%d\n"
,len);
197
if
(
send_result
< 0)
return
-1;
198
return
len;
199
}
200
201
int
rl3964R::send
()
202
{
203
int
i,bcc,c,ret;
204
205
dprintf
(
"send()"
);
206
//bcc = STX;
207
bcc = 0;
208
for
(i=0; i<
tel_send_length
; i++)
209
{
210
switch
(
tel_send
[i])
211
{
212
case
DLE
:
213
tty
.
writeChar
(
DLE
);
214
tty
.
writeChar
(
DLE
);
215
bcc = bcc ^
DLE
;
216
bcc = bcc ^
DLE
;
217
break
;
218
default
:
219
tty
.
writeChar
(
tel_send
[i]);
220
bcc = bcc ^
tel_send
[i];
221
break
;
222
}
223
}
224
tty
.
writeChar
(
DLE
);
225
bcc = bcc ^
DLE
;
226
tty
.
writeChar
(
ETX
);
227
bcc = bcc ^
ETX
;
228
tty
.
writeChar
(bcc);
229
ret =
tty
.
select
(1000);
230
if
(ret == 1) c =
tty
.
readChar
();
231
else
232
{
233
send_result
= -1;
234
dprintf
(
"send(): partner was sending nothing\n"
);
235
return
-1;
236
}
237
if
(c == DLE)
238
{
239
send_result
= 0;
240
dprintf
(
" success\n"
);
241
return
tel_send_length
;
242
}
243
send_result
= -1;
244
dprintf
(
" failure\n"
);
245
return
-1;
246
}
247
248
int
rl3964R::receive
()
249
{
250
int
i,c,c2,bcc,received_bcc,ret;
251
252
dprintf
(
"receive()\n"
);
253
//bcc = STX;
254
bcc = 0;
255
i = received_bcc = 0;
256
tel_receive
[i++] = c =
STX
;
257
while
(c > 0 && i < (
int
)
sizeof
(
tel_receive
))
258
{
259
ret =
tty
.
select
(1000);
260
if
(ret == 1) c =
tty
.
readChar
();
261
else
262
{
263
dprintf
(
"receive(): partner was sending nothing\n"
);
264
return
-1;
265
}
266
dprintf
(
" %x\n"
,c);
267
switch
(c)
268
{
269
case
-1:
270
case
-2:
271
return
-1;
272
case
DLE
:
273
bcc = bcc ^ c;
274
c2 =
tty
.
readChar
();
275
dprintf
(
" %x\n"
,c2);
276
bcc = bcc ^ c2;
277
if
(c2 < 0)
return
-1;
278
tel_receive
[i++] = c2;
279
if
(c2 ==
ETX
)
280
{
281
c2 =
tty
.
readChar
();
282
dprintf
(
" %x\n"
,c2);
283
if
(c2 < 0)
return
-1;
284
tel_receive
[i++] = c2;
// bcc
285
received_bcc = c2;
286
dprintf
(
" bcc=%d received_bcc=%d\n"
,bcc,received_bcc);
287
c = -1;
288
}
289
break
;
290
default
:
291
bcc = bcc ^ c;
292
tel_receive
[i++] = c;
293
break
;
294
}
295
}
296
tel_receive_length
= i;
297
298
if
(bcc == received_bcc)
299
{
300
tty
.
writeChar
(
DLE
);
301
dprintf
(
" success\n"
);
302
if
(
readCallback
!= NULL) (
readCallback
)(&
tel_receive
[1],
tel_receive_length
-3);
303
return
tel_receive_length
-3;
304
}
305
tty
.
writeChar
(
NAK
);
306
dprintf
(
" failure\n"
);
307
return
-1;
308
}
309
310
int
rl3964R::dprintf
(
const
char
*format, ...)
311
{
312
char
message[
rl_PRINTF_LENGTH
];
// should be big enough
313
int
ret;
314
315
if
(
debug
!= 1)
return
0;
316
va_list ap;
317
va_start(ap,format);
318
ret =
rlvsnprintf
(message,
rl_PRINTF_LENGTH
- 1, format, ap);
319
va_end(ap);
320
printf(
"%s"
,message);
321
return
ret;
322
}
323
Generated by
1.8.2