Files
armod/preamble.c

135 lines
4.0 KiB
C
Raw Normal View History

2022-10-24 19:41:38 +02:00
#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;
}