1 /*****************************************************************************/
2
3 /*
4 * sm_afsk1200.c -- soundcard radio modem driver, 1200 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 #include "sm.h"
29 #include "sm_tbl_afsk1200.h"
30
31 /* --------------------------------------------------------------------- */
32
33 struct demod_state_afsk12 {
34 unsigned int shreg;
35 unsigned int bit_pll;
36 unsigned char last_sample;
37 unsigned int dcd_shreg;
38 int dcd_sum0, dcd_sum1, dcd_sum2;
39 unsigned int dcd_time;
40 unsigned char last_rxbit;
41 };
42
43 struct mod_state_afsk12 {
44 unsigned int shreg;
45 unsigned char tx_bit;
46 unsigned int bit_pll;
47 unsigned int dds_inc;
48 unsigned int txphase;
49 };
50
51 /* --------------------------------------------------------------------- */
52
53 static const int dds_inc[2] = {
54 AFSK12_TX_FREQ_LO*0x10000/AFSK12_SAMPLE_RATE,
55 AFSK12_TX_FREQ_HI*0x10000/AFSK12_SAMPLE_RATE
56 };
57
modulator_1200_u8(struct sm_state * sm,unsigned char * buf,unsigned int buflen)58 static void modulator_1200_u8(struct sm_state *sm, unsigned char *buf,
59 unsigned int buflen)
60 {
61 struct mod_state_afsk12 *st = (struct mod_state_afsk12 *)(&sm->m);
62
63 for (; buflen > 0; buflen--) {
64 if (!((st->txphase++) & 7)) {
65 if (st->shreg <= 1)
66 st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
67 st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
68 st->shreg >>= 1;
69 }
70 st->dds_inc = dds_inc[st->tx_bit & 1];
71 *buf++ = OFFSCOS(st->bit_pll);
72 st->bit_pll += st->dds_inc;
73 }
74 }
75
76 /* --------------------------------------------------------------------- */
77
modulator_1200_s16(struct sm_state * sm,short * buf,unsigned int buflen)78 static void modulator_1200_s16(struct sm_state *sm, short *buf, unsigned int buflen)
79 {
80 struct mod_state_afsk12 *st = (struct mod_state_afsk12 *)(&sm->m);
81
82 for (; buflen > 0; buflen--) {
83 if (!((st->txphase++) & 7)) {
84 if (st->shreg <= 1)
85 st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
86 st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
87 st->shreg >>= 1;
88 }
89 st->dds_inc = dds_inc[st->tx_bit & 1];
90 *buf++ = COS(st->bit_pll);
91 st->bit_pll += st->dds_inc;
92 }
93 }
94
95 /* --------------------------------------------------------------------- */
96
convolution8_u8(const unsigned char * st,const int * coeff,int csum)97 static inline int convolution8_u8(const unsigned char *st, const int *coeff, int csum)
98 {
99 int sum = -0x80 * csum;
100
101 sum += (st[0] * coeff[0]);
102 sum += (st[-1] * coeff[1]);
103 sum += (st[-2] * coeff[2]);
104 sum += (st[-3] * coeff[3]);
105 sum += (st[-4] * coeff[4]);
106 sum += (st[-5] * coeff[5]);
107 sum += (st[-6] * coeff[6]);
108 sum += (st[-7] * coeff[7]);
109
110 sum >>= 7;
111 return sum * sum;
112 }
113
convolution8_s16(const short * st,const int * coeff,int csum)114 static inline int convolution8_s16(const short *st, const int *coeff, int csum)
115 {
116 int sum = 0;
117
118 sum += (st[0] * coeff[0]);
119 sum += (st[-1] * coeff[1]);
120 sum += (st[-2] * coeff[2]);
121 sum += (st[-3] * coeff[3]);
122 sum += (st[-4] * coeff[4]);
123 sum += (st[-5] * coeff[5]);
124 sum += (st[-6] * coeff[6]);
125 sum += (st[-7] * coeff[7]);
126
127 sum >>= 15;
128 return sum * sum;
129 }
130
do_filter_1200_u8(const unsigned char * buf)131 static inline int do_filter_1200_u8(const unsigned char *buf)
132 {
133 int sum = convolution8_u8(buf, afsk12_tx_lo_i, SUM_AFSK12_TX_LO_I);
134 sum += convolution8_u8(buf, afsk12_tx_lo_q, SUM_AFSK12_TX_LO_Q);
135 sum -= convolution8_u8(buf, afsk12_tx_hi_i, SUM_AFSK12_TX_HI_I);
136 sum -= convolution8_u8(buf, afsk12_tx_hi_q, SUM_AFSK12_TX_HI_Q);
137 return sum;
138 }
139
do_filter_1200_s16(const short * buf)140 static inline int do_filter_1200_s16(const short *buf)
141 {
142 int sum = convolution8_s16(buf, afsk12_tx_lo_i, SUM_AFSK12_TX_LO_I);
143 sum += convolution8_s16(buf, afsk12_tx_lo_q, SUM_AFSK12_TX_LO_Q);
144 sum -= convolution8_s16(buf, afsk12_tx_hi_i, SUM_AFSK12_TX_HI_I);
145 sum -= convolution8_s16(buf, afsk12_tx_hi_q, SUM_AFSK12_TX_HI_Q);
146 return sum;
147 }
148
149 /* --------------------------------------------------------------------- */
150
151 static const int pll_corr[2] = { -0x1000, 0x1000 };
152
demodulator_1200_u8(struct sm_state * sm,const unsigned char * buf,unsigned int buflen)153 static void demodulator_1200_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
154 {
155 struct demod_state_afsk12 *st = (struct demod_state_afsk12 *)(&sm->d);
156 int j;
157 int sum;
158 unsigned char newsample;
159
160 for (; buflen > 0; buflen--, buf++) {
161 sum = do_filter_1200_u8(buf);
162 st->dcd_shreg <<= 1;
163 st->bit_pll += 0x2000;
164 newsample = (sum > 0);
165 if (st->last_sample ^ newsample) {
166 st->last_sample = newsample;
167 st->dcd_shreg |= 1;
168 st->bit_pll += pll_corr
169 [st->bit_pll < 0x9000];
170 j = 4 * hweight8(st->dcd_shreg & 0x38)
171 - hweight16(st->dcd_shreg & 0x7c0);
172 st->dcd_sum0 += j;
173 }
174 hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
175 if ((--st->dcd_time) <= 0) {
176 hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
177 st->dcd_sum1 +
178 st->dcd_sum2) < 0);
179 st->dcd_sum2 = st->dcd_sum1;
180 st->dcd_sum1 = st->dcd_sum0;
181 st->dcd_sum0 = 2; /* slight bias */
182 st->dcd_time = 120;
183 }
184 if (st->bit_pll >= 0x10000) {
185 st->bit_pll &= 0xffff;
186 st->shreg >>= 1;
187 st->shreg |= (!(st->last_rxbit ^
188 st->last_sample)) << 16;
189 st->last_rxbit = st->last_sample;
190 diag_trigger(sm);
191 if (st->shreg & 1) {
192 hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
193 st->shreg = 0x10000;
194 }
195 }
196 diag_add(sm, (((int)*buf)-0x80) << 8, sum);
197 }
198 }
199
200 /* --------------------------------------------------------------------- */
201
demodulator_1200_s16(struct sm_state * sm,const short * buf,unsigned int buflen)202 static void demodulator_1200_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
203 {
204 struct demod_state_afsk12 *st = (struct demod_state_afsk12 *)(&sm->d);
205 int j;
206 int sum;
207 unsigned char newsample;
208
209 for (; buflen > 0; buflen--, buf++) {
210 sum = do_filter_1200_s16(buf);
211 st->dcd_shreg <<= 1;
212 st->bit_pll += 0x2000;
213 newsample = (sum > 0);
214 if (st->last_sample ^ newsample) {
215 st->last_sample = newsample;
216 st->dcd_shreg |= 1;
217 st->bit_pll += pll_corr
218 [st->bit_pll < 0x9000];
219 j = 4 * hweight8(st->dcd_shreg & 0x38)
220 - hweight16(st->dcd_shreg & 0x7c0);
221 st->dcd_sum0 += j;
222 }
223 hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
224 if ((--st->dcd_time) <= 0) {
225 hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
226 st->dcd_sum1 +
227 st->dcd_sum2) < 0);
228 st->dcd_sum2 = st->dcd_sum1;
229 st->dcd_sum1 = st->dcd_sum0;
230 st->dcd_sum0 = 2; /* slight bias */
231 st->dcd_time = 120;
232 }
233 if (st->bit_pll >= 0x10000) {
234 st->bit_pll &= 0xffff;
235 st->shreg >>= 1;
236 st->shreg |= (!(st->last_rxbit ^
237 st->last_sample)) << 16;
238 st->last_rxbit = st->last_sample;
239 diag_trigger(sm);
240 if (st->shreg & 1) {
241 hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
242 st->shreg = 0x10000;
243 }
244 }
245 diag_add(sm, *buf, sum);
246 }
247 }
248
249 /* --------------------------------------------------------------------- */
250
demod_init_1200(struct sm_state * sm)251 static void demod_init_1200(struct sm_state *sm)
252 {
253 struct demod_state_afsk12 *st = (struct demod_state_afsk12 *)(&sm->d);
254
255 st->dcd_time = 120;
256 st->dcd_sum0 = 2;
257 }
258
259 /* --------------------------------------------------------------------- */
260
261 const struct modem_tx_info sm_afsk1200_tx = {
262 "afsk1200", sizeof(struct mod_state_afsk12),
263 AFSK12_SAMPLE_RATE, 1200, modulator_1200_u8, modulator_1200_s16, NULL
264 };
265
266 const struct modem_rx_info sm_afsk1200_rx = {
267 "afsk1200", sizeof(struct demod_state_afsk12),
268 AFSK12_SAMPLE_RATE, 1200, 8, AFSK12_SAMPLE_RATE/1200,
269 demodulator_1200_u8, demodulator_1200_s16, demod_init_1200
270 };
271
272 /* --------------------------------------------------------------------- */
273