Newer
Older
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
*
* Bernd-Christian Renner, and
* Hamburg University of Technology (TUHH).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FREQSETUP_H
#define FREQSETUP_H
#include "fixpoint.h"
#include <stdint.h>
#include <stdbool.h>
#ifdef WIDEBAND
# define FREQ_BAND_NUM_MAX 6 // max. number of frequency bands
#else
# define FREQ_BAND_NUM_MAX 4 // max. number of frequency bands
#endif
#define FREQ_CARRIER_NUM_MAX 3 // max. number of carriers (hops) per band
// NOTE if these ever become "variables", FREQ_SYNC_SEQ_LEN must become varible as well
#define FREQ_SYNC_NUM_MAX 2 // max. number of sync frequencies
#define FREQ_SYNC_CARRIER_MAX 2
#define FREQ_SYNC_SEQ_LEN (FREQ_SYNC_NUM_MAX * FREQ_SYNC_CARRIER_MAX)
#define FREQ_SFD_LEN 4
#define FREQ_SFD_SEQUENCE {1,0,0,1} // NOTE/TODO only "save" due to carrier changing? -> convert to data freqs
// sampling frequency when receiving
#ifndef SAMPLING_FREQ
# define SAMPLING_FREQ 200000 /* hertz */
#endif
#define SAMPLING_CLK_DIV (PBA_SPEED / (2 * SAMPLING_FREQ))
#if SAMPLING_CLK_DIV * 2 * SAMPLING_FREQ != PBA_SPEED
# error "cpu speed is not a multiple of sampling frequency"
#endif
// tx sending/sampling speed-up (vs. receiving sampling frequency)
// TODO better define a frequency here?
#ifndef TX_FACTOR
# define TX_FACTOR 1 // scaling for sending
#endif
// sampling frequency when sending
#define TX_SAMPLING_CLK_DIV ((SAMPLING_CLK_DIV) / (TX_FACTOR))
#if TX_SAMPLING_CLK_DIV * TX_FACTOR != SAMPLING_CLK_DIV
# error "tx sampling frequency not a multiple of rx sampling frequency"
#endif
#define SYNC_MOD_INDEX 1 // TODO only implemented for sending (do not change atm)
#if SAMPLING_FREQ == 200000UL
# ifdef HIGHSPEED
# define SAMPLES_PER_SYMBOL 256 // must be power of 2
# define FREQ_MSG "*** 200kHz, HIGHSPEED, LOWFREQ ***"
# define FREQ_RX_LUT_FILE "lut/freq-rx_25000-62500Hz_48x_256tap_200kHz.c"
# else
# define FREQ_MSG "*** 200kHz, HIGHSPEED ***"
# define FREQ_RX_LUT_FILE "lut/freq-rx_50000-87500Hz_48x_256tap_200kHz.c"
# endif
# else
# define SAMPLES_PER_SYMBOL 512 // must be power of 2
# define FREQ_MSG "*** 200kHz, LOWFREQ ***"
# define FREQ_RX_LUT_FILE "lut/freq-rx_25000-62500Hz_48x_512tap_200kHz.c"
# else
# define FREQ_MSG "*** 200kHz ***"
# define FREQ_RX_LUT_FILE "lut/freq-rx_50000-87500Hz_48x_512tap_200kHz.c"
# endif
# endif
#else
# error "RX sampling frequency not supported"
#endif
#if TX_FACTOR * SAMPLING_FREQ == 200000UL
# ifdef HIGHSPEED
# define FREQ_TX_LUT_FILE "lut/freq-tx_25000-62500Hz_48x_256tap_200kHz.c"
# else
# define FREQ_TX_LUT_FILE "lut/freq-tx_50000-87500Hz_48x_256tap_200kHz.c"
# endif
# else
# define FREQ_TX_LUT_FILE "lut/freq-tx_25000-62500Hz_48x_512tap_200kHz.c"
# else
# define FREQ_TX_LUT_FILE "lut/freq-tx_50000-87500Hz_48x_512tap_200kHz.c"
# endif
# endif
# else
# error "TX sampling frequency not supported"
# endif
// transducer options
enum {
TRANSDUCER_AS1,
TRANSDUCER_FRAUNHOFER,
TRANSDUCER_BUDDY,
TRANSDUCER_AS1_ORIG,
TRANSDUCER_FRAUNHOFER_ORIG,
TRANSDUCER_NUM
};
#define TRANSDUCER_DFLT TRANSDUCER_AS1
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
# define GAIN_LUT_FILE "lut/gain-25000-62500kHz_48x.c"
#else
# define GAIN_LUT_FILE "lut/gain-50000-87500kHz_48x.c"
#endif
// list all frequencies (NOTE these MUST match the actual
// implementation in the C-file)
#define FREQ_IDX(n) (n)
#define FREQ_LIST_NUM 49
#define SAMPLES_PER_SYMBOL_MASK (SAMPLES_PER_SYMBOL-1)
const fp16_t * const FREQ_LIST[FREQ_LIST_NUM];
const fp16_t * const FREQ_TXLIST[FREQ_LIST_NUM];
// sync/preamble length setup
#define SYNC_SEQ_NUM_MIN 2
#define SYNC_SEQ_NUM_MAX 8
#ifndef SYNC_SEQ_NUM_TX_DFLT
# define SYNC_SEQ_NUM_TX_DFLT 4
#endif
#ifndef SYNC_SEQ_NUM_RX_DFLT
# define SYNC_SEQ_NUM_RX_DFLT 3
#endif
#define SFD_SEQ_NUM_MAX (1 + (SYNC_SEQ_NUM_MAX - SYNC_SEQ_NUM_MIN))
// sanity check
#if SYNC_SEQ_NUM_RX_DFLT > SYNC_SEQ_NUM_TX_DFLT
# error "*** default sync rx sequence cannot be longer than tx sequence ***"
#endif
// number of leading/trailing sync symbols to ignore
// lead: should be 0 or 1 and MUST be less than SYNC_SYMBOLS_NUM_MIN-1
#define SYNC_SYMBOLS_NUM_RX_LEAD_IGNORE 0
// trail: should be 1 and MUST be less than FREQ_SFD_LEN
#define SYNC_SYMBOLS_NUM_RX_TRAIL_IGNORE 1
// macros for sync lengths
#define SYNC_SYMBOLS_NUM_TX(sn) ((sn) * FREQ_SYNC_SEQ_LEN)
#define SYNC_SYMBOLS_NUM_RX(sn) ((sn) * FREQ_SYNC_SEQ_LEN - SYNC_SYMBOLS_NUM_RX_TRAIL_IGNORE)
#define SYNC_SEQ_NUM_TX(sn) ((sn) / FREQ_SYNC_SEQ_LEN)
#define SYNC_SEQ_NUM_RX(sn) (((sn) + SYNC_SYMBOLS_NUM_RX_TRAIL_IGNORE) / FREQ_SYNC_SEQ_LEN)
// maximum number of symbols
#define SYNC_SYMBOLS_NUM_MAX (SYNC_SEQ_NUM_MAX * FREQ_SYNC_SEQ_LEN)
// rx signal threshold setup
#define SIGNAL_THRESHOLD_MAX (FP32_FROM_UINT(SAMPLES_PER_SYMBOL) / 2)
#define SIGNAL_THRESHOLD_DFLT (SIGNAL_THRESHOLD_MAX / 10) // 10%
//#define SIGNAL_THRESHOLD_DFLT (SIGNAL_THRESHOLD_MAX / 20) // 5%
//#define SIGNAL_THRESHOLD_DFLT (SIGNAL_THRESHOLD_MAX / 4) // 25%
// binary coding: symbols are space ("0") and mark ("1")
enum {
SYMBOL_SPACE = 0,
SYMBOL_MARK = 1,
NUM_SYMBOLS
};
// minimum window size for peak detection during sync
//#define SIGNAL_WINDOW_SIZE (SAMPLES_PER_SYMBOL / 2)
#define SIGNAL_WINDOW_SIZE_MAX (SAMPLES_PER_SYMBOL / 4)
#define SIGNAL_WINDOW_SIZE_DFLT (SAMPLES_PER_SYMBOL / 8)
// NOTE should be at least SIGNAL_WINDOW_SIZE_MAX
#define SIGNAL_WINDOW_MAX_DELAY (SAMPLES_PER_SYMBOL / 4)
// turn-around times for mode switching
//#define TXRX_TURNAROUND_TICKS 250 // num samples needed for tx -> rx
//#define RXTX_TURNAROUND_TICKS 250 // num samples needed for rx -> tx
// time in milli seconds
#define MS_TO_TICKS(t) (((t) * SAMPLING_FREQ) / 1000UL)
#define US_TO_TICKS(t) (((t) * SAMPLING_FREQ) / 1000000UL)
#define TICKS_TO_MS(t) (((t) * 1000UL) / SAMPLING_FREQ)
#define TICKS_TO_US(t) (((t) * 1000000ULL) / SAMPLING_FREQ)
#define TXRX_TURNAROUND_TICKS MS_TO_TICKS(12) // num samples needed for tx -> rx
#define RXTX_TURNAROUND_TICKS MS_TO_TICKS(12) // num samples needed for rx -> tx
// FIXME move these to tx amp implementation?
// problem 1: above should be constant! ALWAYS, platform indep, or modems will not work with each other!
// problem 2: below depend on the actual hardware!
//#define SAMPLES_TXSWITCH_WAIT US_TO_TICKS(500)
//#define SAMPLES_TX_STABILIZE MS_TO_TICKS(4)
// timings for TX enable
#define TXON_SUPPLY_STABILIZE_NS MS_TO_TICKS(4) // time for supply to come up
// timings for TX disable
#define TXOFF_OUTPUT_SETTLE_NS US_TO_TICKS(500) // time for amp output to settle after transmission
#define TXOFF_SWITCH_DELAY_NS US_TO_TICKS(500) // time to delay after switching hydrophone
/*
* multiplication of wave forms with sampled signal
* incoherent receiver requires a sine and cosine value
*/
typedef struct {
fp16_t sin;
fp16_t cos;
} freq_product_t;
/*
* integral for coherent reception
* requires a sine and cosine value (see freq_product_t)
*/
typedef struct {
fp32_t sin;
fp32_t cos;
} freq_integral_t;
typedef fp32_t freq_magnitude_t; // FIXME 64-bit value, as square of Integral values?
// init
bool
freq_init(void);
// get preamble/sync length
uint8_t
freq_getNumSyncTxSymbols(void);
// set preamble/sync length
// input is sequence length (not num symbols)
bool
freq_setNumSyncTxSymbols(uint8_t numsymb);
// get preamble symbols to be received for sync
uint8_t
freq_getNumSyncRxSymbols(void);
// set preamble symbols to be received for sync
// input is sequence length (not num symbols)
bool
freq_setNumSyncRxSymbols(uint8_t numsymb);
// get number of SFD tries (max) needed after sync
uint8_t
freq_getNumSfdTries(void);
// frequency look-up tables for preamble / sync
// contains 2*SAMPLES_PER_SYMBOL values, where
// - even indices are sine values
// - odd indices are cosine values
//extern const fp16_t * const FREQ_SYNC_SPACE[FREQ_SYNC_NUM_MAX];
//extern const fp16_t * const FREQ_SYNC_MARK[FREQ_SYNC_NUM_MAX];
//typedef const fp16_t * (*getSyncFreq_t)(uint8_t num, uint8_t hop);
const fp16_t *
freq_getSyncFreq(uint8_t symbol, uint8_t num, uint8_t hop);
const fp16_t *
freq_getSyncTxFreq(uint8_t symbol, uint8_t num, uint8_t hop);
fp16_t
freq_getSyncTxGain(uint8_t symbol, uint8_t num, uint8_t hop);
// return pointer to first value of space signal for given band and carrier
const fp16_t *
freq_getFreq(uint8_t symbol, uint8_t band, uint8_t hop);
// return pointer to first value of symbol signal for given band and carrier
const fp16_t *
freq_getTxFreq(uint8_t symbol, uint8_t band, uint8_t hop);
// return relative gain of symbol frequency for transmissions
fp16_t
freq_getTxGain(uint8_t symbol, uint8_t band, uint8_t hop);
// return pointer to first element of rx filter
// const fp16_t *
// freq_getRxWin(void);
// return attenuation due to rx window
// uint8_t
// freq_getRxWinLossSq(void);
// get number of currently used bands
uint8_t
freq_getNumBands(void);
// set number of currently used bands
// @return true, if 0 < num <= MAX; false else
bool
freq_setNumBands(uint8_t num);
// get pointer to band sequence of bits
// (the result is an array of [FREQ_BAND_NUM_MAX][FREQ_CARRIER_NUM_MAX])
size_t
freq_getBandSequence(uint8_t * seq);
// set the hopping sequence for band
// (seq must always contain FREQ_CARRIER_NUM_MAX entries)
size_t
freq_setBandSequence(const uint8_t * seq);
// get number of currently used carriers (per band)
uint8_t
freq_getNumCarriers(void);
// set number of currently used carriers (for all bands)
// @return true, if 0 < num <= MAX; false else
bool
freq_setNumCarriers(uint8_t num);
// get pointer to hopping sequence of band
// (the result is an array of [FREQ_BAND_NUM_MAX][FREQ_CARRIER_NUM_MAX])
size_t
freq_getHoppingSequence(uint8_t * seq);
// set the hopping sequence for band
// (seq must always contain FREQ_CARRIER_NUM_MAX entries)
bool
freq_setHoppingSequence(const uint8_t * seq);
// get max threshold for a single frequency/bit per symbol
freq_magnitude_t
freq_getMaxSignalThreshold(void);
// get threshold that indicates a proper signal (rather than noise)
// as square valued
freq_magnitude_t
freq_getRxThreshold(void);
// get max threshold for a single frequency/bit per symbol
freq_magnitude_t
freq_getMaxSignalThresholdSq(void);
// get threshold that indicates a proper signal (rather than noise)
// as square valued
freq_magnitude_t
freq_getRxThresholdSq(void);
// set threshold that indicates a proper signal (rather than noise)
bool
freq_setRxThreshold(freq_magnitude_t thresh);
// get threshold that indicates a proper signal (rather than noise)
// as percentile of maximum value
uint8_t
freq_getRxThresholdPerc(void);
// set threshold that indicates a proper signal (rather than noise)
// in percent of maximum signal
bool
freq_setRxThresholdPerc(uint8_t perc);
// set txgain values from array v, the array *must* contain
// FREQ_LIST_NUM values (FREQ_LIST_NUM == num)
// return TRUE, if operation succeeded, FALSE else
//bool
//freq_setTxGainArray(fp16_t * v, uint8_t num);
// get txgain values by writing them into array v, the array *must* contain
// at least FREQ_LIST_NUM values (num > FREQ_LIST_NUM)
// return the number of values in the array (either 0 or FREQ_LIST_NUM)
//uint8_t
//freq_getTxGainArray(fp16_t * v, uint8_t num);
fp16_t
freq_getTxGainByIndex(uint8_t i);
uint16_t
freq_getSignalWindowSize(void);
void
freq_setSignalWindowSize(uint16_t newSize);
// change transducer gain table; index h must be from TRANSDUCER_*
bool
freq_setTransducer(uint8_t h);
// get transducer gain table index (from TRANSDUCER_*)
uint8_t
freq_getTransducer(void);
// get transducer description (of currently selected one)
const char *
freq_getTransducerDescr(void);
#endif /* FREQSETUP_H */