sm_afsk2666.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:10k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*****************************************************************************/
  2. /*
  3.  * sm_afsk2666.c  -- soundcard radio modem driver, 2666 baud AFSK modem
  4.  *
  5.  * Copyright (C) 1997  Thomas Sailer (sailer@ife.ee.ethz.ch)
  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.  *  Please note that the GPL allows you to use the driver, NOT the radio.
  22.  *  In order to use the radio, you need a license from the communications
  23.  *  authority of your country.
  24.  *
  25.  */
  26. #include "sm.h"
  27. #include "sm_tbl_afsk2666.h"
  28. /* --------------------------------------------------------------------- */
  29. struct demod_state_afsk26 {
  30. unsigned int shreg;
  31. unsigned long descram;
  32. int dem_sum[8];
  33. int dem_sum_mean;
  34. int dem_cnt;
  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. };
  41. struct mod_state_afsk26 {
  42. unsigned int shreg;
  43. unsigned long scram;
  44. unsigned int bit_pll;
  45. unsigned int phinc;
  46. unsigned int tx_seq;
  47. };
  48. /* --------------------------------------------------------------------- */
  49. #define DESCRAM_TAP1 0x20000
  50. #define DESCRAM_TAP2 0x01000
  51. #define DESCRAM_TAP3 0x00001
  52. #define DESCRAM_TAPSH1 17
  53. #define DESCRAM_TAPSH2 12
  54. #define DESCRAM_TAPSH3 0
  55. #define SCRAM_TAP1 0x20000 /* X^17 */
  56. #define SCRAM_TAPN 0x00021 /* X^0+X^5 */
  57. /* --------------------------------------------------------------------- */
  58. static void modulator_2666_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
  59. {
  60. struct mod_state_afsk26 *st = (struct mod_state_afsk26 *)(&sm->m);
  61. for (; buflen > 0; buflen--, buf++) {
  62. if (!st->tx_seq++) {
  63. if (st->shreg <= 1)
  64. st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
  65. st->scram = ((st->scram << 1) | (st->scram & 1));
  66. st->scram ^= (!(st->shreg & 1));
  67. st->shreg >>= 1;
  68. if (st->scram & (SCRAM_TAP1 << 1))
  69. st->scram ^= SCRAM_TAPN << 1;
  70. st->phinc = afsk26_carfreq[!(st->scram & (SCRAM_TAP1 << 2))];
  71. }
  72. if (st->tx_seq >= 6)
  73. st->tx_seq = 0;
  74. *buf = OFFSCOS(st->bit_pll);
  75. st->bit_pll += st->phinc;
  76. }
  77. }
  78. /* --------------------------------------------------------------------- */
  79. static void modulator_2666_s16(struct sm_state *sm, short *buf, unsigned int buflen)
  80. {
  81. struct mod_state_afsk26 *st = (struct mod_state_afsk26 *)(&sm->m);
  82. for (; buflen > 0; buflen--, buf++) {
  83. if (!st->tx_seq++) {
  84. if (st->shreg <= 1)
  85. st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
  86. st->scram = ((st->scram << 1) | (st->scram & 1));
  87. st->scram ^= (!(st->shreg & 1));
  88. st->shreg >>= 1;
  89. if (st->scram & (SCRAM_TAP1 << 1))
  90. st->scram ^= SCRAM_TAPN << 1;
  91. st->phinc = afsk26_carfreq[!(st->scram & (SCRAM_TAP1 << 2))];
  92. }
  93. if (st->tx_seq >= 6)
  94. st->tx_seq = 0;
  95. *buf = COS(st->bit_pll);
  96. st->bit_pll += st->phinc;
  97. }
  98. }
  99. /* --------------------------------------------------------------------- */
  100. static inline int convolution12_u8(const unsigned char *st, const int *coeff, int csum)
  101. {
  102. int sum = -0x80 * csum;
  103. sum += (st[0] * coeff[0]);
  104. sum += (st[-1] * coeff[1]);
  105. sum += (st[-2] * coeff[2]);
  106. sum += (st[-3] * coeff[3]);
  107. sum += (st[-4] * coeff[4]);
  108. sum += (st[-5] * coeff[5]);
  109. sum += (st[-6] * coeff[6]);
  110. sum += (st[-7] * coeff[7]);
  111. sum += (st[-8] * coeff[8]);
  112. sum += (st[-9] * coeff[9]);
  113. sum += (st[-10] * coeff[10]);
  114. sum += (st[-11] * coeff[11]);
  115. return sum;
  116. }
  117. static inline int convolution12_s16(const short *st, const int *coeff, int csum)
  118. {
  119. int sum = 0;
  120. sum += (st[0] * coeff[0]);
  121. sum += (st[-1] * coeff[1]);
  122. sum += (st[-2] * coeff[2]);
  123. sum += (st[-3] * coeff[3]);
  124. sum += (st[-4] * coeff[4]);
  125. sum += (st[-5] * coeff[5]);
  126. sum += (st[-6] * coeff[6]);
  127. sum += (st[-7] * coeff[7]);
  128. sum += (st[-8] * coeff[8]);
  129. sum += (st[-9] * coeff[9]);
  130. sum += (st[-10] * coeff[10]);
  131. sum += (st[-11] * coeff[11]);
  132. sum >>= 8;
  133. return sum;
  134. }
  135. /* ---------------------------------------------------------------------- */
  136. #if 0
  137. static int binexp(unsigned int i)
  138. {
  139. int ret = 31;
  140. if (!i)
  141. return 0;
  142. if (i < 0x10000LU) {
  143. i <<= 16;
  144. ret -= 16;
  145. }
  146. if (i < 0x1000000LU) {
  147. i <<= 8;
  148. ret -= 8;
  149. }
  150. if (i < 0x10000000LU) {
  151. i <<= 4;
  152. ret -= 4;
  153. }
  154. if (i < 0x40000000LU) {
  155. i <<= 2;
  156. ret -= 2;
  157. }
  158. if (i < 0x80000000LU)
  159. ret -= 1;
  160. return ret;
  161. }
  162. static const sqrt_tab[16] = {
  163. 00000, 16384, 23170, 28378, 32768, 36636, 40132, 43348,
  164. 46341, 49152, 51811, 54340, 56756, 59073, 61303, 63455
  165. };
  166. static unsigned int int_sqrt_approx(unsigned int i)
  167. {
  168. unsigned int j;
  169. if (i < 16)
  170. return sqrt_tab[i] >> 14;
  171. j = binexp(i) >> 1;
  172. i >>= (j * 2 - 2);
  173.        return (sqrt_tab[i & 0xf] << j) >> 15;
  174. }
  175. #endif
  176. /* --------------------------------------------------------------------- */
  177. extern unsigned int est_pwr(int i, int q)
  178. {
  179. unsigned int ui = abs(i);
  180. unsigned int uq = abs(q);
  181. if (uq > ui) {
  182. unsigned int tmp;
  183. tmp = ui;
  184. ui = uq;
  185. uq = tmp;
  186. }
  187. if (uq > (ui >> 1))
  188. return 7*(ui>>3) + 9*(uq>>4);
  189. else
  190. return ui + (uq>>2);
  191. }
  192. /* --------------------------------------------------------------------- */
  193. static void demod_one_sample(struct sm_state *sm, struct demod_state_afsk26 *st, int curval,
  194.      int loi, int loq, int hii, int hiq)
  195. {
  196. static const int pll_corr[2] = { -0xa00, 0xa00 };
  197. unsigned char curbit;
  198. unsigned int descx;
  199. int val;
  200. /* 
  201.  * estimate power
  202.  */
  203. val = est_pwr(hii, hiq) - est_pwr(loi, loq);
  204. /*
  205.  * estimate center value
  206.  */
  207. st->dem_sum[0] += val >> 8;
  208. if ((++st->dem_cnt) >= 256) {
  209. st->dem_cnt = 0;
  210. st->dem_sum_mean = (st->dem_sum[0]+st->dem_sum[1]+
  211.     st->dem_sum[2]+st->dem_sum[3]+
  212.     st->dem_sum[4]+st->dem_sum[5]+
  213.     st->dem_sum[6]+st->dem_sum[7]) >> 3;
  214. memmove(st->dem_sum+1, st->dem_sum, 
  215. sizeof(st->dem_sum)-sizeof(st->dem_sum[0]));
  216. st->dem_sum[0] = 0;
  217. }
  218. /*
  219.  * decision and bit clock regen
  220.  */
  221. val -= st->dem_sum_mean;
  222. diag_add(sm, curval, val);
  223. st->dcd_shreg <<= 1;
  224. st->bit_pll += 0x1555;
  225. curbit = (val > 0);
  226. if (st->last_sample ^ curbit) {
  227. st->dcd_shreg |= 1;
  228. st->bit_pll += pll_corr[st->bit_pll < (0x8000+0x1555)];
  229. st->dcd_sum0 += 4*hweight8(st->dcd_shreg & 0x1e) -
  230. hweight16(st->dcd_shreg & 0xfe00);
  231. }
  232. st->last_sample = curbit;
  233. hdlcdrv_channelbit(&sm->hdrv, curbit);
  234. if ((--st->dcd_time) <= 0) {
  235. hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 + st->dcd_sum1 + 
  236.    st->dcd_sum2) < 0);
  237. st->dcd_sum2 = st->dcd_sum1;
  238. st->dcd_sum1 = st->dcd_sum0;
  239. st->dcd_sum0 = 2; /* slight bias */
  240. st->dcd_time = 400;
  241. }
  242. if (st->bit_pll >= 0x10000) {
  243. st->bit_pll &= 0xffffu;
  244. st->descram = (st->descram << 1) | curbit;
  245. descx = st->descram ^ (st->descram >> 1);
  246. descx ^= ((descx >> DESCRAM_TAPSH1) ^
  247.   (descx >> DESCRAM_TAPSH2));
  248. st->shreg >>= 1;
  249. st->shreg |= (!(descx & 1)) << 16;
  250. if (st->shreg & 1) {
  251. hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
  252. st->shreg = 0x10000;
  253. }
  254. diag_trigger(sm);
  255. }
  256. }
  257. /* --------------------------------------------------------------------- */
  258. static void demodulator_2666_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
  259. {
  260. struct demod_state_afsk26 *st = (struct demod_state_afsk26 *)(&sm->d);
  261. for (; buflen > 0; buflen--, buf++) {
  262. demod_one_sample(sm, st, (*buf-0x80)<<8,
  263.  convolution12_u8(buf, afsk26_dem_tables[0][0].i, AFSK26_DEM_SUM_I_0_0),
  264.  convolution12_u8(buf, afsk26_dem_tables[0][0].q, AFSK26_DEM_SUM_Q_0_0),
  265.  convolution12_u8(buf, afsk26_dem_tables[0][1].i, AFSK26_DEM_SUM_I_0_1),
  266.  convolution12_u8(buf, afsk26_dem_tables[0][1].q, AFSK26_DEM_SUM_Q_0_1));
  267. demod_one_sample(sm, st,  (*buf-0x80)<<8,
  268.  convolution12_u8(buf, afsk26_dem_tables[1][0].i, AFSK26_DEM_SUM_I_1_0),
  269.  convolution12_u8(buf, afsk26_dem_tables[1][0].q, AFSK26_DEM_SUM_Q_1_0),
  270.  convolution12_u8(buf, afsk26_dem_tables[1][1].i, AFSK26_DEM_SUM_I_1_1),
  271.  convolution12_u8(buf, afsk26_dem_tables[1][1].q, AFSK26_DEM_SUM_Q_1_1));
  272. }
  273. }
  274. /* --------------------------------------------------------------------- */
  275. static void demodulator_2666_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
  276. {
  277. struct demod_state_afsk26 *st = (struct demod_state_afsk26 *)(&sm->d);
  278. for (; buflen > 0; buflen--, buf++) {
  279. demod_one_sample(sm, st, *buf,
  280.  convolution12_s16(buf, afsk26_dem_tables[0][0].i, AFSK26_DEM_SUM_I_0_0),
  281.  convolution12_s16(buf, afsk26_dem_tables[0][0].q, AFSK26_DEM_SUM_Q_0_0),
  282.  convolution12_s16(buf, afsk26_dem_tables[0][1].i, AFSK26_DEM_SUM_I_0_1),
  283.  convolution12_s16(buf, afsk26_dem_tables[0][1].q, AFSK26_DEM_SUM_Q_0_1));
  284. demod_one_sample(sm, st, *buf, 
  285.  convolution12_s16(buf, afsk26_dem_tables[1][0].i, AFSK26_DEM_SUM_I_1_0),
  286.  convolution12_s16(buf, afsk26_dem_tables[1][0].q, AFSK26_DEM_SUM_Q_1_0),
  287.  convolution12_s16(buf, afsk26_dem_tables[1][1].i, AFSK26_DEM_SUM_I_1_1),
  288.  convolution12_s16(buf, afsk26_dem_tables[1][1].q, AFSK26_DEM_SUM_Q_1_1));
  289. }
  290. }
  291. /* --------------------------------------------------------------------- */
  292. static void demod_init_2666(struct sm_state *sm)
  293. {
  294. struct demod_state_afsk26 *st = (struct demod_state_afsk26 *)(&sm->d);
  295. st->dcd_time = 400;
  296. st->dcd_sum0 = 2;
  297. }
  298. /* --------------------------------------------------------------------- */
  299. const struct modem_tx_info sm_afsk2666_tx = {
  300. "afsk2666", sizeof(struct mod_state_afsk26), AFSK26_SAMPLERATE, 2666, 
  301. modulator_2666_u8, modulator_2666_s16, NULL
  302. };
  303. const struct modem_rx_info sm_afsk2666_rx = {
  304. "afsk2666", sizeof(struct demod_state_afsk26), AFSK26_SAMPLERATE, 2666, 12, 6, 
  305. demodulator_2666_u8, demodulator_2666_s16, demod_init_2666
  306. };
  307. /* --------------------------------------------------------------------- */