1 /*****************************************************************************/
4 * sm_fsk9600.c -- soundcard radio modem driver,
5 * 9600 baud G3RUH compatible FSK modem
7 * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Please note that the GPL allows you to use the driver, NOT the radio.
24 * In order to use the radio, you need a license from the communications
25 * authority of your country.
30 #include "sm_tbl_fsk9600.h"
32 /* --------------------------------------------------------------------- */
34 struct demod_state_fsk96
{
36 unsigned long descram
;
38 unsigned char last_sample
;
39 unsigned int dcd_shreg
;
40 int dcd_sum0
, dcd_sum1
, dcd_sum2
;
41 unsigned int dcd_time
;
44 struct mod_state_fsk96
{
50 /* --------------------------------------------------------------------- */
52 #define DESCRAM_TAP1 0x20000
53 #define DESCRAM_TAP2 0x01000
54 #define DESCRAM_TAP3 0x00001
56 #define DESCRAM_TAPSH1 17
57 #define DESCRAM_TAPSH2 12
58 #define DESCRAM_TAPSH3 0
60 #define SCRAM_TAP1 0x20000 /* X^17 */
61 #define SCRAM_TAPN 0x00021 /* X^0+X^5 */
63 /* --------------------------------------------------------------------- */
65 static void modulator_9600_4(struct sm_state
*sm
, unsigned char *buf
, int buflen
)
67 struct mod_state_fsk96
*st
= (struct mod_state_fsk96
*)(&sm
->m
);
69 const unsigned char *cp
;
71 for (; buflen
>= 4; buflen
-= 4) {
73 st
->shreg
= hdlcdrv_getbits(&sm
->hdrv
) | 0x10000;
74 st
->scram
= (st
->scram
<< 1) | (st
->scram
& 1);
75 st
->scram
^= !(st
->shreg
& 1);
77 if (st
->scram
& (SCRAM_TAP1
<< 1))
78 st
->scram
^= SCRAM_TAPN
<< 1;
79 st
->tx_bit
= (st
->tx_bit
<< 1) | (!!(st
->scram
& (SCRAM_TAP1
<< 2)));
80 cp
= fsk96_txfilt_4
+ (st
->tx_bit
& 0xff);
81 for (j
= 0; j
< 4; j
++, cp
+= 0x100)
86 /* --------------------------------------------------------------------- */
88 static void demodulator_9600_4(struct sm_state
*sm
, unsigned char *buf
, int buflen
)
90 struct demod_state_fsk96
*st
= (struct demod_state_fsk96
*)(&sm
->d
);
91 static const int pll_corr
[2] = { -0x1000, 0x1000 };
95 for (; buflen
> 0; buflen
--, buf
++) {
97 st
->bit_pll
+= 0x4000;
98 curbit
= (*buf
>= 0x80);
99 if (st
->last_sample
^ curbit
) {
101 st
->bit_pll
+= pll_corr
[st
->bit_pll
< 0xa000];
102 st
->dcd_sum0
+= 8 * hweight8(st
->dcd_shreg
& 0x0c) -
103 !!(st
->dcd_shreg
& 0x10);
105 st
->last_sample
= curbit
;
106 hdlcdrv_channelbit(&sm
->hdrv
, st
->last_sample
);
107 if ((--st
->dcd_time
) <= 0) {
108 hdlcdrv_setdcd(&sm
->hdrv
, (st
->dcd_sum0
+
111 st
->dcd_sum2
= st
->dcd_sum1
;
112 st
->dcd_sum1
= st
->dcd_sum0
;
113 st
->dcd_sum0
= 2; /* slight bias */
116 if (st
->bit_pll
>= 0x10000) {
117 st
->bit_pll
&= 0xffff;
118 st
->descram
= (st
->descram
<< 1) | curbit
;
119 descx
= st
->descram
^ (st
->descram
>> 1);
120 descx
^= ((descx
>> DESCRAM_TAPSH1
) ^
121 (descx
>> DESCRAM_TAPSH2
));
123 st
->shreg
|= (!(descx
& 1)) << 16;
125 hdlcdrv_putbits(&sm
->hdrv
, st
->shreg
>> 1);
130 diag_add_one(sm
, ((short)(*buf
- 0x80)) << 8);
134 /* --------------------------------------------------------------------- */
136 static void modulator_9600_5(struct sm_state
*sm
, unsigned char *buf
, int buflen
)
138 struct mod_state_fsk96
*st
= (struct mod_state_fsk96
*)(&sm
->m
);
140 const unsigned char *cp
;
142 for (; buflen
>= 5; buflen
-= 5) {
144 st
->shreg
= hdlcdrv_getbits(&sm
->hdrv
) | 0x10000;
145 st
->scram
= (st
->scram
<< 1) | (st
->scram
& 1);
146 st
->scram
^= !(st
->shreg
& 1);
148 if (st
->scram
& (SCRAM_TAP1
<< 1))
149 st
->scram
^= SCRAM_TAPN
<< 1;
150 st
->tx_bit
= (st
->tx_bit
<< 1) | (!!(st
->scram
& (SCRAM_TAP1
<< 2)));
151 cp
= fsk96_txfilt_5
+ (st
->tx_bit
& 0xff);
152 for (j
= 0; j
< 5; j
++, cp
+= 0x100)
157 /* --------------------------------------------------------------------- */
159 static void demodulator_9600_5(struct sm_state
*sm
, unsigned char *buf
, int buflen
)
161 struct demod_state_fsk96
*st
= (struct demod_state_fsk96
*)(&sm
->d
);
162 static const int pll_corr
[2] = { -0x1000, 0x1000 };
163 unsigned char curbit
;
166 for (; buflen
> 0; buflen
--, buf
++) {
168 st
->bit_pll
+= 0x3333;
169 curbit
= (*buf
>= 0x80);
170 if (st
->last_sample
^ curbit
) {
172 st
->bit_pll
+= pll_corr
[st
->bit_pll
< 0x9999];
173 st
->dcd_sum0
+= 16 * hweight8(st
->dcd_shreg
& 0x0c) -
174 hweight8(st
->dcd_shreg
& 0x70);
176 st
->last_sample
= curbit
;
177 hdlcdrv_channelbit(&sm
->hdrv
, st
->last_sample
);
178 if ((--st
->dcd_time
) <= 0) {
179 hdlcdrv_setdcd(&sm
->hdrv
, (st
->dcd_sum0
+
182 st
->dcd_sum2
= st
->dcd_sum1
;
183 st
->dcd_sum1
= st
->dcd_sum0
;
184 st
->dcd_sum0
= 2; /* slight bias */
187 if (st
->bit_pll
>= 0x10000) {
188 st
->bit_pll
&= 0xffff;
189 st
->descram
= (st
->descram
<< 1) | curbit
;
190 descx
= st
->descram
^ (st
->descram
>> 1);
191 descx
^= ((descx
>> DESCRAM_TAPSH1
) ^
192 (descx
>> DESCRAM_TAPSH2
));
194 st
->shreg
|= (!(descx
& 1)) << 16;
196 hdlcdrv_putbits(&sm
->hdrv
, st
->shreg
>> 1);
201 diag_add_one(sm
, ((short)(*buf
- 0x80)) << 8);
205 /* --------------------------------------------------------------------- */
207 static void demod_init_9600(struct sm_state
*sm
)
209 struct demod_state_fsk96
*st
= (struct demod_state_fsk96
*)(&sm
->d
);
215 /* --------------------------------------------------------------------- */
217 const struct modem_tx_info sm_fsk9600_4_tx
= {
218 "fsk9600", sizeof(struct mod_state_fsk96
), 38400, 9600, 4,
219 modulator_9600_4
, NULL
222 const struct modem_rx_info sm_fsk9600_4_rx
= {
223 "fsk9600", sizeof(struct demod_state_fsk96
), 38400, 9600, 4, 4,
224 demodulator_9600_4
, demod_init_9600
227 /* --------------------------------------------------------------------- */
229 const struct modem_tx_info sm_fsk9600_5_tx
= {
230 "fsk9600", sizeof(struct mod_state_fsk96
), 48000, 9600, 5,
231 modulator_9600_5
, NULL
234 const struct modem_rx_info sm_fsk9600_5_rx
= {
235 "fsk9600", sizeof(struct demod_state_fsk96
), 48000, 9600, 5, 5,
236 demodulator_9600_5
, demod_init_9600
239 /* --------------------------------------------------------------------- */