135 lines
4.0 KiB
C
135 lines
4.0 KiB
C
|
|
#include <stdint.h>
|
||
|
|
#include <string.h>
|
||
|
|
|
||
|
|
// debug
|
||
|
|
#ifdef __XC16
|
||
|
|
#include <xc.h>
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifdef __XC16
|
||
|
|
#include <libq.h>
|
||
|
|
#include <dsp.h>
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#include "../ringbuf.h"
|
||
|
|
#include "modem_types.h"
|
||
|
|
|
||
|
|
#include "preamble.h"
|
||
|
|
|
||
|
|
#include "../peripheral/gpio.h" //debug
|
||
|
|
#include "../mini-printf.h"
|
||
|
|
|
||
|
|
|
||
|
|
#if defined(__DEBUG) && ! defined(__MPLAB_DEBUGGER_PK3)
|
||
|
|
#include "../peripheral/uarts.h"
|
||
|
|
extern fractional debug_value3;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
// preambolo
|
||
|
|
uint8_t modem_preamble_waiting, modem_post_preamble_delay, modem_post_preamble_timer;
|
||
|
|
// uint8_t modem_preamble_pending, modem_preamble_done;
|
||
|
|
uint16_t BuffersPerPreamble;
|
||
|
|
|
||
|
|
fractional sync_values_sequence[(MODEM_PREAMBLE_LENGTH * MAX_BUFFERS_PER_SYMBOL)];
|
||
|
|
_Q15_16 preamble_squelch_distance;
|
||
|
|
|
||
|
|
void modem_set_up_preamble(void) {
|
||
|
|
uint8_t sync_symbols[MODEM_PREAMBLE_LENGTH];
|
||
|
|
modem_generate_preamble(sync_symbols);
|
||
|
|
modem_generate_preamble_fingerprint(sync_symbols, sync_values_sequence, mod.buffers_per_symbol);
|
||
|
|
BuffersPerPreamble = MODEM_PREAMBLE_LENGTH * mod.buffers_per_symbol;
|
||
|
|
|
||
|
|
preamble_squelch_distance = _Q16mpy(modem_get_preamble_max_correlation_index(sync_symbols), _Q16ftoi(MODEM_PREAMBLE_SQUELCH));
|
||
|
|
|
||
|
|
modem_post_preamble_delay = BUFFER_RATE / mod.symbol_rate; // un simbolo
|
||
|
|
}
|
||
|
|
|
||
|
|
uint8_t modem_generate_preamble(uint8_t *ModulationSymbolsBuffer) {
|
||
|
|
uint8_t i;
|
||
|
|
// barker code con N=13
|
||
|
|
uint8_t sync_sequence[13] = {1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1};
|
||
|
|
|
||
|
|
for (i = 0; i < MODEM_PREAMBLE_LENGTH; i++) {
|
||
|
|
if (sync_sequence[i]) {
|
||
|
|
ModulationSymbolsBuffer[i] = (mod.alphabet_size - 1);
|
||
|
|
} else {
|
||
|
|
ModulationSymbolsBuffer[i] = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return MODEM_PREAMBLE_LENGTH;
|
||
|
|
}
|
||
|
|
|
||
|
|
// trasforma la sequenza di simboli nella sua rappresentazione in sottosimboli
|
||
|
|
|
||
|
|
void modem_generate_preamble_fingerprint(uint8_t *ModulationSymbolsBuffer, fractional *symbols_values_sequence, uint8_t values_per_symbol) {
|
||
|
|
uint8_t i, l, m = 0;
|
||
|
|
for (i = 0; i < MODEM_PREAMBLE_LENGTH; i++) {
|
||
|
|
for (l = 0; l < values_per_symbol; l++) {
|
||
|
|
symbols_values_sequence[m] = detector_constellation[ModulationSymbolsBuffer[i]].frequency;
|
||
|
|
m++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// trova indice di correlazione massimo per la data modulationz
|
||
|
|
|
||
|
|
_Q15_16 modem_get_preamble_max_correlation_index(uint8_t *ModulationSymbolsBuffer) {
|
||
|
|
uint8_t i;
|
||
|
|
_Q15_16 symbol_mass = 0;
|
||
|
|
_Q15_16 mass = 0;
|
||
|
|
for (i = 0; i < MODEM_PREAMBLE_LENGTH; i++) {
|
||
|
|
symbol_mass = __builtin_mulss(
|
||
|
|
detector_constellation[ModulationSymbolsBuffer[i]].frequency,
|
||
|
|
detector_constellation[ModulationSymbolsBuffer[i]].frequency);
|
||
|
|
mass += symbol_mass;
|
||
|
|
}
|
||
|
|
return mass * mod.buffers_per_symbol;
|
||
|
|
}
|
||
|
|
/// riconosce preambolo
|
||
|
|
|
||
|
|
uint8_t modem_detect_preamble(fractional insymbol) {
|
||
|
|
static _Q15_16 somigl_hist;
|
||
|
|
static fractional in_sym_ringbuf[MODEM_PREAMBLE_SEARCH_BUFF_SIZE];
|
||
|
|
static uint16_t in_sym_ringbuf_index;
|
||
|
|
|
||
|
|
uint8_t found = 0;
|
||
|
|
uint16_t i;
|
||
|
|
_Q15_16 distance_accu = 0;
|
||
|
|
|
||
|
|
// mette nel ringbuffer
|
||
|
|
in_sym_ringbuf[in_sym_ringbuf_index] = insymbol;
|
||
|
|
|
||
|
|
// correla
|
||
|
|
for (i = 0; i < BuffersPerPreamble; i++) {
|
||
|
|
// product
|
||
|
|
|
||
|
|
distance_accu += __builtin_mulss(
|
||
|
|
in_sym_ringbuf[ringbuf_idx_from_end(&in_sym_ringbuf_index, MODEM_PREAMBLE_SEARCH_BUFF_SIZE_MASK, (BuffersPerPreamble - i))],
|
||
|
|
sync_values_sequence[i]);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
#if defined(__DEBUG) && ! defined(__MPLAB_DEBUGGER_PK3)
|
||
|
|
debug_value3 = _Q16shr(distance_accu, 16);
|
||
|
|
#endif
|
||
|
|
/*
|
||
|
|
if (distance_accu > preamble_squelch_distance) LATBbits.LATB3 = 1;
|
||
|
|
else {
|
||
|
|
LATBbits.LATB3 = 0;
|
||
|
|
}
|
||
|
|
*/
|
||
|
|
if ((distance_accu > preamble_squelch_distance) && (somigl_hist > distance_accu)) {
|
||
|
|
// trovato !
|
||
|
|
|
||
|
|
//resetta il riconoscimento di preambolo
|
||
|
|
somigl_hist = 0;
|
||
|
|
memset(in_sym_ringbuf, 0, MODEM_PREAMBLE_SEARCH_BUFF_SIZE * sizeof (in_sym_ringbuf));
|
||
|
|
in_sym_ringbuf_index = 0;
|
||
|
|
|
||
|
|
found = 1;
|
||
|
|
} else {
|
||
|
|
somigl_hist = distance_accu;
|
||
|
|
ringbuf_increment(&in_sym_ringbuf_index, MODEM_PREAMBLE_SEARCH_BUFF_SIZE_MASK);
|
||
|
|
}
|
||
|
|
return found;
|
||
|
|
}
|