1 /*
2 * Copyright (c) 2001 Tommy Bohlin <tommy@gatespace.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26 /* litelink.c
27 */
28
29 #include <irda.h>
30
31 /**********************************************************************
32 * Constants
33 **********************************************************************/
34
35 static const char id_litelink[]="litelink";
36
37 /**********************************************************************
38 * Data structures
39 **********************************************************************/
40
41 typedef struct LiteLink {
42 SerialDevice sd;
43 SerialPort* sp;
44 bool initial;
45 int pulses;
46 int state;
47 } LiteLink;
48
49 /**********************************************************************
50 * LiteLink control
51 **********************************************************************/
52
speedTimer(void * sd)53 static void speedTimer(void* sd)
54 {
55 LiteLink* ll=(LiteLink*)sd;
56 SerialPort* sp=ll->sp;
57
58 switch(ll->state) {
59 case 1:
60 sp->setLine(sp,LINE_RTS);
61 ll->initial=FALSE;
62 ll->state=2;
63 evtSetTimer(1,speedTimer,ll); /* At least 15us */
64 break;
65 case 2:
66 sp->setLine(sp,LINE_DTR|LINE_RTS);
67 if(ll->pulses-->0) {
68 ll->state=3;
69 evtSetTimer(1,speedTimer,ll); /* At least 15us */
70 } else {
71 ll->state=0;
72 }
73 break;
74 case 3:
75 sp->setLine(sp,LINE_DTR);
76 ll->state=2;
77 evtSetTimer(1,speedTimer,ll); /* At least 15us */
78 break;
79 }
80 }
81
82 /**********************************************************************
83 * Methods
84 **********************************************************************/
85
llSetSpeed(SerialDevice * sd,int speed)86 static int llSetSpeed(SerialDevice* sd, int speed)
87 {
88 LiteLink* ll=(LiteLink*)sd;
89 SerialPort* sp=ll->sp;
90
91 sp->setSpeed(sp,speed);
92
93 switch(speed) {
94 case 57600: ll->pulses=1; break;
95 case 38400: ll->pulses=2; break;
96 case 19200: ll->pulses=3; break;
97 case 9600: ll->pulses=4; break;
98 default: /* 115200 */ ll->pulses=0; break;
99 }
100
101 if(ll->initial) {
102 ll->state=1;
103 sp->setLine(sp,LINE_DTR|LINE_RTS);
104 } else {
105 ll->state=2;
106 sp->setLine(sp,LINE_RTS);
107 }
108 evtSetTimer(1,speedTimer,ll); /* At least 15us */
109
110 /* Reasonable estimate */
111 return 40+20*ll->pulses;
112 }
113
llGetSpeedMask(SerialDevice * sd)114 static int llGetSpeedMask(SerialDevice* sd)
115 {
116 LiteLink* ll=(LiteLink*)sd;
117
118 return ll->sp->getSpeedMask(ll->sp)&
119 (SPEED_9600|SPEED_19200|SPEED_38400|SPEED_57600|SPEED_115200);
120 }
121
llGetMinTurnaroundMask(SerialDevice * sd)122 static int llGetMinTurnaroundMask(SerialDevice* sd)
123 {
124 return MIN_TA_10ms|MIN_TA_5ms|MIN_TA_1ms|MIN_TA_500us|
125 MIN_TA_100us|MIN_TA_50us|MIN_TA_10us;
126 }
127
llGetChar(SerialDevice * sd)128 static int llGetChar(SerialDevice* sd)
129 {
130 LiteLink* ll=(LiteLink*)sd;
131
132 return ll->sp->getChar(ll->sp);
133 }
134
llPutChar(SerialDevice * sd,int c)135 static void llPutChar(SerialDevice* sd, int c)
136 {
137 LiteLink* ll=(LiteLink*)sd;
138
139 if(ll->state==0) ll->sp->putChar(ll->sp,c);
140 }
141
llClose(SerialDevice * sd)142 static void llClose(SerialDevice* sd)
143 {
144 LiteLink* ll=(LiteLink*)sd;
145 SerialPort* sp=ll->sp;
146
147 evtCancelTimer(speedTimer,ll);
148 sp->setLine(sp,0);
149 sp->handle=0;
150 sp->status=0;
151 freeMem(ll);
152 }
153
llStatus(SerialPort * sp,int event)154 static void llStatus(SerialPort* sp, int event)
155 {
156 LiteLink* ll=(LiteLink*)sp->handle;
157
158 if(ll->sd.status) ll->sd.status(&ll->sd,event);
159 }
160
161 /**********************************************************************
162 * External interface
163 **********************************************************************/
164
createLiteLinkDevice(SerialPort * sp)165 SerialDevice* createLiteLinkDevice(SerialPort* sp)
166 {
167 LiteLink* ll=allocMem(id_litelink,sizeof(LiteLink));
168
169 ll->sd.close=llClose;
170 ll->sd.setSpeed=llSetSpeed;
171 ll->sd.getSpeedMask=llGetSpeedMask;
172 ll->sd.getMinTurnaroundMask=llGetMinTurnaroundMask;
173 ll->sd.getChar=llGetChar;
174 ll->sd.putChar=llPutChar;
175 ll->sd.handle=0;
176 ll->sd.status=0;
177 ll->sp=sp;
178 ll->initial=TRUE;
179 ll->state=0;
180
181 sp->handle=ll;
182 sp->status=llStatus;
183
184 return &ll->sd;
185 }
186