1 /*---------------------------------------------------------------------------*\ 2 3 FILE........: fsk.h 4 AUTHOR......: Brady O'Brien 5 DATE CREATED: 6 January 2016 6 7 C Implementation of 2FSK/4FSK modulator/demodulator, based on octave/fsk_horus.m 8 9 \*---------------------------------------------------------------------------*/ 10 11 /* 12 Copyright (C) 2016 David Rowe 13 14 All rights reserved. 15 16 This program is free software; you can redistribute it and/or modify 17 it under the terms of the GNU Lesser General Public License version 2.1, as 18 published by the Free Software Foundation. This program is 19 distributed in the hope that it will be useful, but WITHOUT ANY 20 WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 License for more details. 23 24 You should have received a copy of the GNU Lesser General Public License 25 along with this program; if not, see <http://www.gnu.org/licenses/>. 26 */ 27 28 29 #ifndef __C2FSK_H 30 #define __C2FSK_H 31 32 #include <stdint.h> 33 #include "comp.h" 34 #include "kiss_fftr.h" 35 #include "modem_stats.h" 36 37 #define MODE_2FSK 2 38 #define MODE_4FSK 4 39 40 #define MODE_M_MAX 4 41 42 #define FSK_SCALE 16383 43 44 /* default internal parameters */ 45 #define FSK_DEFAULT_P 8 /* Number of timing offsets we have to choose from, try to keep P >= 8 */ 46 #define FSK_DEFAULT_NSYM 50 /* See Nsym below */ 47 #define FSK_NONE -1 /* unused parameter */ 48 49 struct FSK { 50 /* Static parameters set up by fsk_init */ 51 int Ndft; /* freq offset est fft */ 52 int Fs; /* sample freq */ 53 int N; /* processing buffer size */ 54 int Rs; /* symbol rate */ 55 int Ts; /* samples per symbol */ 56 int Nmem; /* size of extra mem for timing adj */ 57 int P; /* oversample rate for timing est/adj */ 58 int Nsym; /* Number of symbols processed by demodulator in each call, also the timing estimator window */ 59 int Nbits; /* Number of bits spat out in a processing frame */ 60 int f1_tx; /* f1 for modulator */ 61 int tone_spacing; /* Space between TX freqs for modulator (and option mask freq estimator) */ 62 int mode; /* 2FSK or 4FSK */ 63 float tc; /* time constant for smoothing FFTs */ 64 int est_min; /* Minimum frequency for freq. estimator */ 65 int est_max; /* Maximum frequency for freq. estimator */ 66 int est_space; /* Minimum frequency spacing for freq. estimator */ 67 float* hann_table; /* Precomputed or runtime computed hann window table */ 68 69 /* Parameters used by demod */ 70 float* Sf; /* Average of magnitude spectrum */ 71 COMP phi_c[MODE_M_MAX]; /* phase of each demod local oscillator */ 72 COMP *f_dc; /* down converted samples */ 73 74 kiss_fft_cfg fft_cfg; /* Config for KISS FFT, used in freq est */ 75 float norm_rx_timing; /* Normalized RX timing */ 76 77 /* Parameters used by mod */ 78 COMP tx_phase_c; /* TX phase, but complex */ 79 80 /* Statistics generated by demod */ 81 float EbNodB; /* Estimated EbNo in dB */ 82 float f_est[MODE_M_MAX]; /* Estimated frequencies (peak method) */ 83 float f2_est[MODE_M_MAX];/* Estimated frequencies (mask method) */ 84 int freq_est_type; /* which estimator to use */ 85 float ppm; /* Estimated PPM clock offset */ 86 float SNRest; /* used for LLRs */ 87 float v_est; /* used for LLRs */ 88 float rx_sig_pow; 89 float rx_nse_pow; 90 91 /* Parameters used by mod/demod and driving code */ 92 int nin; /* Number of samples to feed the next demod cycle */ 93 int burst_mode; /* enables/disables 'burst' mode */ 94 int lock_nin; /* locks nin during testing */ 95 96 /* modem statistics struct */ 97 struct MODEM_STATS *stats; 98 int normalise_eye; /* enables/disables normalisation of eye diagram */ 99 }; 100 101 /* 102 * Create a FSK modem 103 * 104 * int Fs - Sample frequency 105 * int Rs - Symbol rate 106 * int M - 2 for 2FSK, 4 for 4FSK 107 * int f1_tx - first tone frequency 108 * int tone_spacing - frequency spacing (for modulator and optional "mask" freq estimator) 109 */ 110 struct FSK * fsk_create(int Fs, int Rs, int M, int f1_tx, int tone_spacing); 111 112 /* 113 * Create a FSK modem - advanced version 114 * 115 * int Fs - Sample frequency 116 * int Rs - Symbol rate 117 * int M - 2 for 2FSK, 4 for 4FSK 118 * int P - number of timing offsets to choose from (suggest >= 8) 119 * int Nsym - windows size for timing estimator 120 * int f1_tx - first tone frequency 121 * int tone_spacing - frequency spacing (for modulator and optional "mask" freq estimator) 122 */ 123 struct FSK * fsk_create_hbr(int Fs, int Rs, int M, int P, int Nsym, int f1_tx, int tone_spacing); 124 125 /* 126 * Set the minimum and maximum frequencies at which the freq. estimator can find tones 127 */ 128 void fsk_set_freq_est_limits(struct FSK *fsk,int fmin, int fmax); 129 130 /* 131 * Clear the estimator states 132 */ 133 void fsk_clear_estimators(struct FSK *fsk); 134 135 /* 136 * Fills MODEM_STATS struct with demod statistics 137 */ 138 void fsk_get_demod_stats(struct FSK *fsk, struct MODEM_STATS *stats); 139 140 /* 141 * Destroy an FSK state struct and free it's memory 142 * 143 * struct FSK *fsk - FSK config/state struct to be destroyed 144 */ 145 void fsk_destroy(struct FSK *fsk); 146 147 /* 148 * Modulates Nsym bits into N samples 149 * 150 * struct FSK *fsk - FSK config/state struct, set up by fsk_create 151 * float fsk_out[] - Buffer for samples of modulated FSK, fsk->Ts*(nbits/(M>>1)) in length 152 * uint8_t tx_bits[] - Buffer containing Nbits unpacked bits 153 * int nbits - number of bits to transmit 154 */ 155 void fsk_mod(struct FSK *fsk, float fsk_out[], uint8_t tx_bits[], int nbits); 156 157 /* 158 * Modulates Nsym bits into N samples 159 * 160 * struct FSK *fsk - FSK config/state struct, set up by fsk_create 161 * float fsk_out[] - Buffer for samples of "voltage" used to modulate an external VCO 162 * - fsk->Ts*(nbits/(M>>1)) in length 163 * uint8_t tx_bits[] - Buffer containing Nbits unpacked bits 164 * int nbits - number of bits to transmit 165 */ 166 void fsk_mod_ext_vco(struct FSK *fsk, float vco_out[], uint8_t tx_bits[], int nbits); 167 168 /* 169 * Modulates Nsym bits into N complex samples 170 * 171 * struct FSK *fsk - FSK config/state struct, set up by fsk_create 172 * comp fsk_out[] - Buffer for samples of modulated FSK, fsk->Ts*(nbits/(M>>1)) in length 173 * uint8_t tx_bits[] - Buffer containing Nbits unpacked bits 174 * int nbits - number of bits to transmit 175 */ 176 void fsk_mod_c(struct FSK *fsk, COMP fsk_out[], uint8_t tx_bits[], int nbits); 177 178 /* 179 * Returns the number of samples needed for the next fsk_demod() cycle 180 * 181 * struct FSK *fsk - FSK config/state struct, set up by fsk_create 182 * returns - number of samples to be fed into fsk_demod next cycle 183 */ 184 uint32_t fsk_nin(struct FSK *fsk); 185 186 187 /* 188 * Demodulate some number of FSK samples. The number of samples to be 189 * demodulated can be found by calling fsk_nin(). 190 * 191 * struct FSK *fsk - FSK config/state struct, set up by fsk_create 192 * uint8_t rx_bits[] - Buffer for fsk->Nbits unpacked bits to be written 193 * float fsk_in[] - nin samples of modulated FSK 194 */ 195 void fsk_demod(struct FSK *fsk, uint8_t rx_bits[], COMP fsk_in[]); 196 197 /* 198 * Soft decision demodulation 199 * 200 * struct FSK *fsk - FSK config/state struct, set up by fsk_create 201 * float rx_flit[] - M x Nsym array of filtermagnitude outputs 202 * float fsk_in[] - nin samples of modualted FSK 203 */ 204 void fsk_demod_sd(struct FSK *fsk, float rx_filt[], COMP fsk_in[]); 205 206 /* enables/disables normalisation of eye diagram samples */ 207 208 void fsk_stats_normalise_eye(struct FSK *fsk, int normalise_enable); 209 210 /* Set the FSK modem into burst demod mode */ 211 212 void fsk_enable_burst_mode(struct FSK *fsk); 213 214 /* Set freq est algorithm 0: peak 1:mask */ 215 void fsk_set_freq_est_alg(struct FSK *fsk, int est_type); 216 217 #endif 218