comparison spandsp-0.0.3/spandsp-0.0.3/src/async.c @ 5:f762bf195c4b

import spandsp-0.0.3
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 16:00:21 +0200
parents
children
comparison
equal deleted inserted replaced
4:26cd8f1ef0b1 5:f762bf195c4b
1 /*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * async.c - Asynchronous serial bit stream encoding and decoding
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2003 Steve Underwood
9 *
10 * All rights reserved.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2, as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * $Id: async.c,v 1.6 2006/11/19 14:07:24 steveu Exp $
26 */
27
28 /*! \file */
29
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33
34 #include <inttypes.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <assert.h>
38
39 #include "spandsp/telephony.h"
40 #include "spandsp/async.h"
41
42 void async_rx_init(async_rx_state_t *s,
43 int data_bits,
44 int parity,
45 int stop_bits,
46 int use_v14,
47 put_byte_func_t put_byte,
48 void *user_data)
49 {
50 s->data_bits = data_bits;
51 s->parity = parity;
52 s->stop_bits = stop_bits;
53 s->use_v14 = use_v14;
54
55 s->put_byte = put_byte;
56 s->user_data = user_data;
57
58 s->byte_in_progress = 0;
59 s->bitpos = 0;
60 s->parity_bit = 0;
61
62 s->parity_errors = 0;
63 s->framing_errors = 0;
64 }
65 /*- End of function --------------------------------------------------------*/
66
67 void async_rx_put_bit(void *user_data, int bit)
68 {
69 async_rx_state_t *s;
70
71 s = (async_rx_state_t *) user_data;
72 if (bit < 0)
73 {
74 /* Special conditions */
75 switch (bit)
76 {
77 case PUTBIT_CARRIER_UP:
78 case PUTBIT_CARRIER_DOWN:
79 case PUTBIT_TRAINING_SUCCEEDED:
80 case PUTBIT_TRAINING_FAILED:
81 case PUTBIT_END_OF_DATA:
82 s->put_byte(s->user_data, bit);
83 s->bitpos = 0;
84 s->byte_in_progress = 0;
85 break;
86 default:
87 //printf("Eh!\n");
88 break;
89 }
90 return;
91 }
92 if (s->bitpos == 0)
93 {
94 /* Search for the start bit */
95 s->bitpos += (bit ^ 1);
96 s->parity_bit = 0;
97 s->byte_in_progress = 0;
98 }
99 else if (s->bitpos <= s->data_bits)
100 {
101 s->byte_in_progress = (s->byte_in_progress >> 1) | (bit << 7);
102 s->parity_bit ^= bit;
103 s->bitpos++;
104 }
105 else if (s->parity && s->bitpos == s->data_bits + 1)
106 {
107 if (s->parity == ASYNC_PARITY_ODD)
108 s->parity_bit ^= 1;
109
110 if (s->parity_bit != bit)
111 s->parity_errors++;
112 s->bitpos++;
113 }
114 else
115 {
116 /* Stop bit */
117 if (bit == 1)
118 {
119 /* Align the received value */
120 if (s->data_bits < 8)
121 s->byte_in_progress >>= (8 - s->data_bits);
122 s->put_byte(s->user_data, s->byte_in_progress);
123 s->bitpos = 0;
124 }
125 else if (s->use_v14)
126 {
127 /* This is actually the start bit for the next character, and
128 the stop bit has been dropped from the stream. This is the
129 rate adaption specified in V.14 */
130 /* Align the received value */
131 if (s->data_bits < 8)
132 s->byte_in_progress >>= (8 - s->data_bits);
133 s->put_byte(s->user_data, s->byte_in_progress);
134 s->bitpos = 1;
135 s->parity_bit = 0;
136 s->byte_in_progress = 0;
137 }
138 else
139 {
140 s->framing_errors++;
141 s->bitpos = 0;
142 }
143 }
144 }
145 /*- End of function --------------------------------------------------------*/
146
147 void async_tx_init(async_tx_state_t *s,
148 int data_bits,
149 int parity,
150 int stop_bits,
151 int use_v14,
152 get_byte_func_t get_byte,
153 void *user_data)
154 {
155 /* We have a use_v14 parameter for completeness, but right now V.14 only
156 applies to the receive side. We are unlikely to have an application where
157 flow control does not exist, so V.14 stuffing is not needed. */
158 s->data_bits = data_bits;
159 s->parity = parity;
160 s->stop_bits = stop_bits;
161 if (parity != ASYNC_PARITY_NONE)
162 s->stop_bits++;
163
164 s->get_byte = get_byte;
165 s->user_data = user_data;
166
167 s->byte_in_progress = 0;
168 s->bitpos = 0;
169 s->parity_bit = 0;
170 }
171 /*- End of function --------------------------------------------------------*/
172
173 int async_tx_get_bit(void *user_data)
174 {
175 async_tx_state_t *s;
176 int bit;
177
178 s = (async_tx_state_t *) user_data;
179 if (s->bitpos == 0)
180 {
181 if ((s->byte_in_progress = s->get_byte(s->user_data)) < 0)
182 {
183 /* No more data */
184 bit = PUTBIT_END_OF_DATA;
185 }
186 else
187 {
188 /* Start bit */
189 bit = 0;
190 s->parity_bit = 0;
191 s->bitpos++;
192 }
193 }
194 else if (s->bitpos <= s->data_bits)
195 {
196 bit = s->byte_in_progress & 1;
197 s->byte_in_progress >>= 1;
198 s->parity_bit ^= bit;
199 s->bitpos++;
200 }
201 else if (s->parity && s->bitpos == s->data_bits + 1)
202 {
203 if (s->parity == ASYNC_PARITY_ODD)
204 s->parity_bit ^= 1;
205 bit = s->parity_bit;
206 s->bitpos++;
207 }
208 else
209 {
210 /* Stop bit(s) */
211 bit = 1;
212 if (++s->bitpos > s->data_bits + s->stop_bits)
213 s->bitpos = 0;
214 }
215 return bit;
216 }
217 /*- End of function --------------------------------------------------------*/
218 /*- End of file ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.