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 33struct 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 43struct 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 53static 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 58static 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 78static 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 97static 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 114static 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 131static 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 140static 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 151static const int pll_corr[2] = { -0x1000, 0x1000 }; 152 153static 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 202static 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 251static 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 261const 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 266const 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