1 /*
2 * demod_afsk24.c -- 2400 baud AFSK demodulator
3 *
4 * Copyright (C) 1996
5 * Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 /* ---------------------------------------------------------------------- */
23
24 #include "multimon.h"
25 #include "filter.h"
26 #include <math.h>
27 #include <string.h>
28
29 /* ---------------------------------------------------------------------- */
30
31 /*
32 * Standard TCM3105 clock frequency: 4.4336MHz
33 * Xtal used: 7.3728 MHz
34 * Ratio: 1.6629
35 * Mark frequency: 3658 Hz
36 * Space frequency: 1996 Hz
37 */
38
39 #define FREQ_MARK 3658
40 #define FREQ_SPACE 1996
41 #define FREQ_SAMP 22050
42 #define BAUD 2400
43
44 /* ---------------------------------------------------------------------- */
45
46 #define CORRLEN ((int)(2*FREQ_SAMP/BAUD))
47 #define SPHASEINC (0x10000u*BAUD/FREQ_SAMP)
48
49 static float corr_mark_i[CORRLEN];
50 static float corr_mark_q[CORRLEN];
51 static float corr_space_i[CORRLEN];
52 static float corr_space_q[CORRLEN];
53
54 /* ---------------------------------------------------------------------- */
55
afsk24_2_init(struct demod_state * s)56 static void afsk24_2_init(struct demod_state *s)
57 {
58 float f;
59 int i;
60
61 hdlc_init(s);
62 memset(&s->l1.afsk24, 0, sizeof(s->l1.afsk24));
63 for (f = 0, i = 0; i < CORRLEN; i++) {
64 corr_mark_i[i] = cos(f);
65 corr_mark_q[i] = sin(f);
66 f += 2.0*M_PI*FREQ_MARK/FREQ_SAMP;
67 }
68 for (f = 0, i = 0; i < CORRLEN; i++) {
69 corr_space_i[i] = cos(f);
70 corr_space_q[i] = sin(f);
71 f += 2.0*M_PI*FREQ_SPACE/FREQ_SAMP;
72 }
73 for (i = 0; i < CORRLEN; i++) {
74 f = 0.54 - 0.46*cos(2*M_PI*i/(float)(CORRLEN-1));
75 corr_mark_i[i] *= f;
76 corr_mark_q[i] *= f;
77 corr_space_i[i] *= f;
78 corr_space_q[i] *= f;
79 }
80 }
81
82 /* ---------------------------------------------------------------------- */
83
afsk24_2_demod(struct demod_state * s,buffer_t buffer,int length)84 static void afsk24_2_demod(struct demod_state *s, buffer_t buffer, int length)
85 {
86 float f;
87 unsigned char curbit;
88
89 for (; length > 0; length--, buffer.fbuffer++) {
90 f = fsqr(mac(buffer.fbuffer, corr_mark_i, CORRLEN)) +
91 fsqr(mac(buffer.fbuffer, corr_mark_q, CORRLEN)) -
92 fsqr(mac(buffer.fbuffer, corr_space_i, CORRLEN)) -
93 fsqr(mac(buffer.fbuffer, corr_space_q, CORRLEN));
94 s->l1.afsk24.dcd_shreg <<= 1;
95 s->l1.afsk24.dcd_shreg |= (f > 0);
96 verbprintf(10, "%c", '0'+(s->l1.afsk24.dcd_shreg & 1));
97 /*
98 * check if transition
99 */
100 if ((s->l1.afsk24.dcd_shreg ^ (s->l1.afsk24.dcd_shreg >> 1)) & 1) {
101 if (s->l1.afsk24.sphase < (0x8000u-(SPHASEINC/2)))
102 s->l1.afsk24.sphase += SPHASEINC/8;
103 else
104 s->l1.afsk24.sphase -= SPHASEINC/8;
105 }
106 s->l1.afsk24.sphase += SPHASEINC;
107 if (s->l1.afsk24.sphase >= 0x10000u) {
108 s->l1.afsk24.sphase &= 0xffffu;
109 s->l1.afsk24.lasts <<= 1;
110 s->l1.afsk24.lasts |= s->l1.afsk24.dcd_shreg & 1;
111 curbit = (s->l1.afsk24.lasts ^
112 (s->l1.afsk24.lasts >> 1) ^ 1) & 1;
113 verbprintf(9, " %c ", '0'+curbit);
114 hdlc_rxbit(s, curbit);
115 }
116 }
117 }
118
119 /* ---------------------------------------------------------------------- */
120
121 const struct demod_param demod_afsk2400_2 = {
122 "AFSK2400_2", true, FREQ_SAMP, CORRLEN, afsk24_2_init, afsk24_2_demod, NULL
123 };
124
125 /* ---------------------------------------------------------------------- */
126