blob: 4e96d449aca70feb587b1a623f39171ff9728edd [file] [log] [blame]
adamdunkels9fcf9d62003-09-04 19:46:32 +00001/*
2 * Copyright (c) 2001, Adam Dunkels.
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 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Adam Dunkels.
16 * 4. The name of the author may not be used to endorse or promote
17 * products derived from this software without specific prior
18 * written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
21 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
26 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * This file is part of the uIP TCP/IP stack.
33 *
oliverschmidtb166c4c2005-02-23 22:45:38 +000034 * $Id: rs232dev.c,v 1.2 2005/02/23 22:45:38 oliverschmidt Exp $
adamdunkels9fcf9d62003-09-04 19:46:32 +000035 *
36 */
37
38/*
39 * This is a generic implementation of the SLIP protocol over an RS232
40 * (serial) device. While initially intented for the C64, the code can
41 * easily be ported to other platforms as well.
42 *
43 * Huge thanks to Ullrich von Bassewitz <uz@cc65.org> of cc65 fame for
44 * and endless supply of bugfixes, insightsful comments and
45 * suggestions, and improvements to this code!
46 */
47
48#include "rs232.h"
49#include <string.h>
50
51 /* This will include the system specific header files as well */
52#if defined(__CBM__)
53# include <cbm.h>
54#elif defined(__ATARI__)
55# include <atari.h>
56#endif
57
58#include "uip.h"
59
60#define SLIP_END 0300
61#define SLIP_ESC 0333
62#define SLIP_ESC_END 0334
63#define SLIP_ESC_ESC 0335
64
65
66#define SIO_RECV(c) while(rs232_get(&c) == RS_ERR_NO_DATA)
67#define SIO_POLL(c) (rs232_get(&c) != RS_ERR_NO_DATA)
68#define SIO_SEND(c) rs232_put(c)
69
70#define MAX_SIZE (UIP_BUFSIZE - UIP_LLH_LEN)
71
72static u8_t slip_buf[MAX_SIZE + 2];
73
74#if MAX_SIZE > 255
75static u16_t len, tmplen;
76#else
77static u8_t len, tmplen;
78#endif /* MAX_SIZE > 255 */
79
80#if 1
81#define printf(x)
82#else
83#include <stdio.h>
84#endif
85
86
87/*-----------------------------------------------------------------------------------*/
88static void
89rs232_err(char err)
90{
91 switch(err) {
92 case RS_ERR_OK:
93 printf("RS232 OK\n");
94 break;
95 case RS_ERR_NOT_INITIALIZED:
96 printf("RS232 not initialized\n");
97 break;
98 case RS_ERR_BAUD_TOO_FAST:
99 printf("RS232 baud too fast\n");
100 break;
101 case RS_ERR_BAUD_NOT_AVAIL:
102 printf("RS232 baud rate not available\n");
103 break;
104 case RS_ERR_NO_DATA:
105 printf("RS232 nothing to read\n");
106 break;
107 case RS_ERR_OVERFLOW:
108 printf("RS232 overflow\n");
109 break;
110 }
111
112}
113/*-----------------------------------------------------------------------------------*/
114/*
115 * rs232dev_send():
116 *
117 * Sends the packet in the uip_buf and uip_appdata buffers. The first
118 * 40 bytes of the packet (the IP and TCP headers) are read from the
119 * uip_buf buffer, and the following bytes (the application data) are
120 * read from the uip_appdata buffer.
121 *
122 */
123/*-----------------------------------------------------------------------------------*/
124void
125rs232dev_send(void)
126{
127#if MAX_SIZE > 255
128 u16_t i;
129#else
130 u8_t i;
131#endif /* MAX_SIZE > 255 */
132 u8_t *ptr;
133 u8_t c;
134
135 SIO_SEND(SLIP_END);
136
137 ptr = &uip_buf[UIP_LLH_LEN];
138 for(i = 0; i < uip_len; ++i) {
oliverschmidtb166c4c2005-02-23 22:45:38 +0000139 if(i == UIP_TCPIP_HLEN) {
adamdunkels9fcf9d62003-09-04 19:46:32 +0000140 ptr = (char *)uip_appdata;
141 }
142 c = *ptr++;
143 switch(c) {
144 case SLIP_END:
145 SIO_SEND(SLIP_ESC);
146 SIO_SEND(SLIP_ESC_END);
147 break;
148 case SLIP_ESC:
149 SIO_SEND(SLIP_ESC);
150 SIO_SEND(SLIP_ESC_ESC);
151 break;
152 default:
153 SIO_SEND(c);
154 break;
155 }
156 }
157 SIO_SEND(SLIP_END);
158}
159/*-----------------------------------------------------------------------------------*/
160/*
161 * rs232dev_poll():
162 *
163 * Read all avaliable bytes from the RS232 interface into the slip_buf
164 * buffer. If no more bytes are avaliable, it returns with 0 to
165 * indicate that no packet was immediately ready. When a full packet
166 * has been read into the buffer, the packet is copied into the
167 * uip_buf buffer and the length of the packet is returned.
168 *
169 */
170/*-----------------------------------------------------------------------------------*/
171#if MAX_SIZE > 255
172u16_t
173#else
174u8_t
175#endif /* MAX_SIZE > 255 */
176rs232dev_poll(void)
177{
178 u8_t c;
179 static u8_t lastc;
180
181 while(SIO_POLL(c)) {
182 /* printf("c %x\n", c);*/
183 switch(c) {
184 case SLIP_ESC:
185 lastc = c;
186 break;
187
188 case SLIP_END:
189 lastc = c;
190 /* End marker found, we copy our input buffer to the uip_buf
191 buffer and return the size of the packet we copied. */
192 memcpy(&uip_buf[UIP_LLH_LEN], slip_buf, len);
193 tmplen = len;
194 len = 0;
195 return tmplen;
196
197 default:
198 if(lastc == SLIP_ESC) {
199 lastc = c;
200 /* Previous read byte was an escape byte, so this byte will be
201 interpreted differently from others. */
202 switch(c) {
203 case SLIP_ESC_END:
204 c = SLIP_END;
205 break;
206 case SLIP_ESC_ESC:
207 c = SLIP_ESC;
208 break;
209 }
210 } else {
211 lastc = c;
212 }
213
214
215 slip_buf[len] = c;
216 ++len;
217
218 if(len > MAX_SIZE) {
219 len = 0;
220 }
221
222 break;
223 }
224 }
225 return 0;
226}
227/*-----------------------------------------------------------------------------------*/
228/*
229 * rs232dev_init():
230 *
231 * Initializes the RS232 device and sets the parameters of the device.
232 *
233 */
234/*-----------------------------------------------------------------------------------*/
235void
236rs232dev_init(void)
237{
238 char err;
239
240 err = rs232_init(0);
241 rs232_err(err);
242 err = rs232_params(RS_BAUD_9600 | RS_BITS_8 | RS_STOP_1, RS_PAR_NONE);
243 rs232_err(err);
244
245 len = 0;
246
247 return;
248}
249/*-----------------------------------------------------------------------------------*/
250