#include #include // debug #ifdef __XC16 #include #endif #ifdef __XC16 #include #include #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; }