OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [before_ORP/] [uclinux/] [uClinux-2.0.x/] [drivers/] [net/] [soundmodem/] [sm_afsk2400_7.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*****************************************************************************/
2
 
3
/*
4
 *      sm_afsk2400_7.c  -- soundcard radio modem driver, 2400 baud AFSK modem
5
 *
6
 *      Copyright (C) 1996  Thomas Sailer (sailer@ife.ee.ethz.ch)
7
 *
8
 *      This program is free software; you can redistribute it and/or modify
9
 *      it under the terms of the GNU General Public License as published by
10
 *      the Free Software Foundation; either version 2 of the License, or
11
 *      (at your option) any later version.
12
 *
13
 *      This program is distributed in the hope that it will be useful,
14
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *      GNU General Public License for more details.
17
 *
18
 *      You should have received a copy of the GNU General Public License
19
 *      along with this program; if not, write to the Free Software
20
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
 *
22
 *  Please note that the GPL allows you to use the driver, NOT the radio.
23
 *  In order to use the radio, you need a license from the communications
24
 *  authority of your country.
25
 *
26
 */
27
 
28
/*
29
 * This driver is intended to be compatible with TCM3105 modems
30
 * overclocked to 7.3728MHz. The mark and space frequencies therefore
31
 * lie at 3658 and 1996 Hz.
32
 * Note that I do _not_ recommend the building of such links, I provide
33
 * this only for the users who live in the coverage area of such
34
 * a "legacy" link.
35
 */
36
 
37
#include "sm.h"
38
#include "sm_tbl_afsk2400_7.h"
39
 
40
/* --------------------------------------------------------------------- */
41
 
42
struct demod_state_afsk24 {
43
        unsigned int shreg;
44
        unsigned int bit_pll;
45
        unsigned char last_sample;
46
        unsigned int dcd_shreg;
47
        int dcd_sum0, dcd_sum1, dcd_sum2;
48
        unsigned int dcd_time;
49
        unsigned char last_rxbit;
50
};
51
 
52
struct mod_state_afsk24 {
53
        unsigned int shreg;
54
        unsigned char tx_bit;
55
        unsigned int bit_pll;
56
        unsigned int tx_seq;
57
        unsigned int phinc;
58
};
59
 
60
/* --------------------------------------------------------------------- */
61
 
62
static const int dds_inc[2] = { AFSK24_TX_FREQ_LO*0x10000/AFSK24_SAMPLERATE,
63
                                AFSK24_TX_FREQ_HI*0x10000/AFSK24_SAMPLERATE };
64
 
65
static void modulator_2400_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
66
{
67
        struct mod_state_afsk24 *st = (struct mod_state_afsk24 *)(&sm->m);
68
 
69
        for (; buflen > 0; buflen--, buf++) {
70
                if (st->tx_seq < 0x5555) {
71
                        if (st->shreg <= 1)
72
                                st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
73
                        st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
74
                        st->shreg >>= 1;
75
                        st->phinc = dds_inc[st->tx_bit & 1];
76
                }
77
                st->tx_seq += 0x5555;
78
                st->tx_seq &= 0xffff;
79
                *buf = OFFSCOS(st->bit_pll);
80
                st->bit_pll += st->phinc;
81
        }
82
}
83
 
84
/* --------------------------------------------------------------------- */
85
 
86
static void modulator_2400_s16(struct sm_state *sm, short *buf, unsigned int buflen)
87
{
88
        struct mod_state_afsk24 *st = (struct mod_state_afsk24 *)(&sm->m);
89
 
90
        for (; buflen > 0; buflen--, buf++) {
91
                if (st->tx_seq < 0x5555) {
92
                        if (st->shreg <= 1)
93
                                st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
94
                        st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
95
                        st->shreg >>= 1;
96
                        st->phinc = dds_inc[st->tx_bit & 1];
97
                }
98
                st->tx_seq += 0x5555;
99
                st->tx_seq &= 0xffff;
100
                *buf = COS(st->bit_pll);
101
                st->bit_pll += st->phinc;
102
        }
103
}
104
 
105
/* --------------------------------------------------------------------- */
106
 
107
extern __inline__ int convolution14_u8(const unsigned char *st, const int *coeff, int csum)
108
{
109
        int sum = -0x80 * csum;
110
 
111
        sum += (st[0] * coeff[0]);
112
        sum += (st[-1] * coeff[1]);
113
        sum += (st[-2] * coeff[2]);
114
        sum += (st[-3] * coeff[3]);
115
        sum += (st[-4] * coeff[4]);
116
        sum += (st[-5] * coeff[5]);
117
        sum += (st[-6] * coeff[6]);
118
        sum += (st[-7] * coeff[7]);
119
        sum += (st[-8] * coeff[8]);
120
        sum += (st[-9] * coeff[9]);
121
        sum += (st[-10] * coeff[10]);
122
        sum += (st[-11] * coeff[11]);
123
        sum += (st[-12] * coeff[12]);
124
        sum += (st[-13] * coeff[13]);
125
 
126
        sum >>= 7;
127
        return sum * sum;
128
}
129
 
130
extern __inline__ int convolution14_s16(const short *st, const int *coeff, int csum)
131
{
132
        int sum = 0;
133
 
134
        sum += (st[0] * coeff[0]);
135
        sum += (st[-1] * coeff[1]);
136
        sum += (st[-2] * coeff[2]);
137
        sum += (st[-3] * coeff[3]);
138
        sum += (st[-4] * coeff[4]);
139
        sum += (st[-5] * coeff[5]);
140
        sum += (st[-6] * coeff[6]);
141
        sum += (st[-7] * coeff[7]);
142
        sum += (st[-8] * coeff[8]);
143
        sum += (st[-9] * coeff[9]);
144
        sum += (st[-10] * coeff[10]);
145
        sum += (st[-11] * coeff[11]);
146
        sum += (st[-12] * coeff[12]);
147
        sum += (st[-13] * coeff[13]);
148
 
149
        sum >>= 15;
150
        return sum * sum;
151
}
152
 
153
extern __inline__ int do_filter_2400_u8(const unsigned char *buf)
154
{
155
        int sum = convolution14_u8(buf, afsk24_tx_lo_i, SUM_AFSK24_TX_LO_I);
156
        sum += convolution14_u8(buf, afsk24_tx_lo_q, SUM_AFSK24_TX_LO_Q);
157
        sum -= convolution14_u8(buf, afsk24_tx_hi_i, SUM_AFSK24_TX_HI_I);
158
        sum -= convolution14_u8(buf, afsk24_tx_hi_q, SUM_AFSK24_TX_HI_Q);
159
        return sum;
160
}
161
 
162
extern __inline__ int do_filter_2400_s16(const short *buf)
163
{
164
        int sum = convolution14_s16(buf, afsk24_tx_lo_i, SUM_AFSK24_TX_LO_I);
165
        sum += convolution14_s16(buf, afsk24_tx_lo_q, SUM_AFSK24_TX_LO_Q);
166
        sum -= convolution14_s16(buf, afsk24_tx_hi_i, SUM_AFSK24_TX_HI_I);
167
        sum -= convolution14_s16(buf, afsk24_tx_hi_q, SUM_AFSK24_TX_HI_Q);
168
        return sum;
169
}
170
 
171
/* --------------------------------------------------------------------- */
172
 
173
static void demodulator_2400_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
174
{
175
        struct demod_state_afsk24 *st = (struct demod_state_afsk24 *)(&sm->d);
176
        int j;
177
        int sum;
178
        unsigned char newsample;
179
 
180
        for (; buflen > 0; buflen--, buf++) {
181
                sum = do_filter_2400_u8(buf);
182
                st->dcd_shreg <<= 1;
183
                st->bit_pll += AFSK24_BITPLL_INC;
184
                newsample = (sum > 0);
185
                if (st->last_sample ^ newsample) {
186
                        st->last_sample = newsample;
187
                        st->dcd_shreg |= 1;
188
                        if (st->bit_pll < (0x8000+AFSK24_BITPLL_INC/2))
189
                                st->bit_pll += AFSK24_BITPLL_INC/2;
190
                        else
191
                                st->bit_pll -= AFSK24_BITPLL_INC/2;
192
                        j = /* 2 * */ hweight8(st->dcd_shreg & 0x1c)
193
                                - hweight16(st->dcd_shreg & 0x1e0);
194
                        st->dcd_sum0 += j;
195
                }
196
                hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
197
                if ((--st->dcd_time) <= 0) {
198
                        hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
199
                                                   st->dcd_sum1 +
200
                                                   st->dcd_sum2) < 0);
201
                        st->dcd_sum2 = st->dcd_sum1;
202
                        st->dcd_sum1 = st->dcd_sum0;
203
                        st->dcd_sum0 = 2; /* slight bias */
204
                        st->dcd_time = 120;
205
                }
206
                if (st->bit_pll >= 0x10000) {
207
                        st->bit_pll &= 0xffff;
208
                        st->shreg >>= 1;
209
                        st->shreg |= (!(st->last_rxbit ^
210
                                        st->last_sample)) << 16;
211
                        st->last_rxbit = st->last_sample;
212
                        diag_trigger(sm);
213
                        if (st->shreg & 1) {
214
                                hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
215
                                st->shreg = 0x10000;
216
                        }
217
                }
218
                diag_add(sm, (((int)*buf)-0x80) << 8, sum);
219
        }
220
}
221
 
222
/* --------------------------------------------------------------------- */
223
 
224
static void demodulator_2400_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
225
{
226
        struct demod_state_afsk24 *st = (struct demod_state_afsk24 *)(&sm->d);
227
        int j;
228
        int sum;
229
        unsigned char newsample;
230
 
231
        for (; buflen > 0; buflen--, buf++) {
232
                sum = do_filter_2400_s16(buf);
233
                st->dcd_shreg <<= 1;
234
                st->bit_pll += AFSK24_BITPLL_INC;
235
                newsample = (sum > 0);
236
                if (st->last_sample ^ newsample) {
237
                        st->last_sample = newsample;
238
                        st->dcd_shreg |= 1;
239
                        if (st->bit_pll < (0x8000+AFSK24_BITPLL_INC/2))
240
                                st->bit_pll += AFSK24_BITPLL_INC/2;
241
                        else
242
                                st->bit_pll -= AFSK24_BITPLL_INC/2;
243
                        j = /* 2 * */ hweight8(st->dcd_shreg & 0x1c)
244
                                - hweight16(st->dcd_shreg & 0x1e0);
245
                        st->dcd_sum0 += j;
246
                }
247
                hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
248
                if ((--st->dcd_time) <= 0) {
249
                        hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
250
                                                   st->dcd_sum1 +
251
                                                   st->dcd_sum2) < 0);
252
                        st->dcd_sum2 = st->dcd_sum1;
253
                        st->dcd_sum1 = st->dcd_sum0;
254
                        st->dcd_sum0 = 2; /* slight bias */
255
                        st->dcd_time = 120;
256
                }
257
                if (st->bit_pll >= 0x10000) {
258
                        st->bit_pll &= 0xffff;
259
                        st->shreg >>= 1;
260
                        st->shreg |= (!(st->last_rxbit ^
261
                                        st->last_sample)) << 16;
262
                        st->last_rxbit = st->last_sample;
263
                        diag_trigger(sm);
264
                        if (st->shreg & 1) {
265
                                hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
266
                                st->shreg = 0x10000;
267
                        }
268
                }
269
                diag_add(sm, *buf, sum);
270
        }
271
}
272
 
273
/* --------------------------------------------------------------------- */
274
 
275
static void demod_init_2400(struct sm_state *sm)
276
{
277
        struct demod_state_afsk24 *st = (struct demod_state_afsk24 *)(&sm->d);
278
 
279
        st->dcd_time = 120;
280
        st->dcd_sum0 = 2;
281
}
282
 
283
/* --------------------------------------------------------------------- */
284
 
285
const struct modem_tx_info sm_afsk2400_7_tx = {
286
        "afsk2400_7", sizeof(struct mod_state_afsk24), AFSK24_SAMPLERATE, 2400,
287
        modulator_2400_u8, modulator_2400_s16, NULL
288
};
289
 
290
const struct modem_rx_info sm_afsk2400_7_rx = {
291
        "afsk2400_7", sizeof(struct demod_state_afsk24),
292
        AFSK24_SAMPLERATE, 2400, 14, AFSK24_SAMPLERATE/2400,
293
        demodulator_2400_u8, demodulator_2400_s16, demod_init_2400
294
};
295
 
296
/* --------------------------------------------------------------------- */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.