162 lines
4.9 KiB
C
162 lines
4.9 KiB
C
|
|
/* armando modem - iz4kll */
|
||
|
|
|
||
|
|
#ifdef __XC16
|
||
|
|
#include <libq.h>
|
||
|
|
#include <dsp.h>
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#include <stdint.h>
|
||
|
|
|
||
|
|
#include "modem.h"
|
||
|
|
|
||
|
|
#include "../peripheral/gpio.h"
|
||
|
|
#include "../peripheral/adc.h"
|
||
|
|
#include "../peripheral/dac.h"
|
||
|
|
|
||
|
|
#if defined(__DEBUG) && ! defined(__MPLAB_DEBUGGER_PK3)
|
||
|
|
extern fractional debug_value1, debug_value2, debug_value3;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
// parametri della modulazione
|
||
|
|
modulation mod;
|
||
|
|
|
||
|
|
uint8_t modem_tx_state, modem_rx_state;
|
||
|
|
|
||
|
|
|
||
|
|
// predelay
|
||
|
|
uint16_t modem_predelay_mstime, modem_predelay_buffer_size, modem_predelay_buffer_index;
|
||
|
|
|
||
|
|
// non trasmettere quando stai ricevendo payload phy
|
||
|
|
uint8_t modem_avoid_overlap;
|
||
|
|
|
||
|
|
// payload
|
||
|
|
uint16_t modem_payload_max_symbols, modem_payload_symbols_index;
|
||
|
|
|
||
|
|
// solo al boot
|
||
|
|
|
||
|
|
void modem_init(void) {
|
||
|
|
FIR_init();
|
||
|
|
/// Initialize the A/D converter
|
||
|
|
adc_init();
|
||
|
|
adc_init_dma();
|
||
|
|
/// Initialize the Timer to generate sampling event for ADC
|
||
|
|
adc_init_tmr();
|
||
|
|
|
||
|
|
modem_preamble_waiting = 0;
|
||
|
|
#ifndef __DEBUG
|
||
|
|
// PENDING
|
||
|
|
InitDACDMA(); // prima di initdac!!
|
||
|
|
initDac(); // Initialize the D/A converter
|
||
|
|
#endif
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
// ad ogni cambio modulazione
|
||
|
|
|
||
|
|
void modem_set_up(void) {
|
||
|
|
/// imposta dimensione alfabeto
|
||
|
|
mod.alphabet_size = (1 << mod.bits_per_symbol);
|
||
|
|
/// calcola numero di buffer per simbolo
|
||
|
|
mod.buffers_per_symbol = BUFFER_RATE / mod.symbol_rate;
|
||
|
|
|
||
|
|
/// setup modulatore
|
||
|
|
modulator_setup();
|
||
|
|
|
||
|
|
/// setup demodulatore
|
||
|
|
demodulator_setup();
|
||
|
|
|
||
|
|
modem_set_up_predelay();
|
||
|
|
|
||
|
|
// va a valle del popolamento della costellazione di detect
|
||
|
|
modem_set_up_preamble();
|
||
|
|
}
|
||
|
|
|
||
|
|
// loopback per test
|
||
|
|
|
||
|
|
void DAC_ADC_loopback(void){
|
||
|
|
#ifdef __DSP_LIB__
|
||
|
|
/// Travaso DAC-> ADC per test
|
||
|
|
VectorCopy(SAMPLES_PER_BUFFER, ADCBuffer[dac_buffer_toggle], Q_DACBuffer[dac_buffer_toggle]);
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
void modem_process_sample_buffer(fractional *buffer) {
|
||
|
|
static detector_symbol detector_modulation_averages;
|
||
|
|
|
||
|
|
// demodula un buffer di campioni e torna le medie di freq, ph e amp
|
||
|
|
demodulator_sample_buffer_demodulate(buffer, &detector_modulation_averages);
|
||
|
|
|
||
|
|
// spia OverLoad
|
||
|
|
#ifdef USE_GPIO
|
||
|
|
if ((gpio_mode == GPIO_INFO) && (detector_modulation_averages.amplitude > ADC_MAX_AMPLITUDE)) GPIO_ADC_OL = 1;
|
||
|
|
else {
|
||
|
|
GPIO_ADC_OL = 0;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if ! defined(__DEBUG)
|
||
|
|
// viene riasserito dall'interrupt DMA2, meglio azzerare presto per non perdere eventi
|
||
|
|
process_input_sample_buffer = 0; // TEST quando in debug ci pensa chi ?
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if defined(__DEBUG) && ! defined(__MPLAB_DEBUGGER_PK3)
|
||
|
|
// stampa frequenza vista dal demodulatore
|
||
|
|
debug_value2 = detector_modulation_averages.frequency;
|
||
|
|
#endif
|
||
|
|
// aspetta un preambolo
|
||
|
|
if (modem_preamble_waiting) {
|
||
|
|
if (modem_detect_preamble(detector_modulation_averages.frequency)) {
|
||
|
|
// preambolo trovato
|
||
|
|
modem_preamble_waiting = 0;
|
||
|
|
modem_post_preamble_timer = modem_post_preamble_delay;
|
||
|
|
#ifdef USE_GPIO
|
||
|
|
if (gpio_mode == GPIO_INFO) GPIO_PHY_PAYLOAD = 1;
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
} else if (modem_post_preamble_timer > 0) {
|
||
|
|
modem_post_preamble_timer--; // aspetta
|
||
|
|
} else {
|
||
|
|
// comincia a ricevere i dati
|
||
|
|
// aspetta header o dati
|
||
|
|
if (rx_sample_buffer_index < mod.buffers_per_symbol) {
|
||
|
|
// confronta le medie con la costellazione e torna il simbolo piu vicino
|
||
|
|
rx_sample_buffers_buffer[rx_sample_buffer_index] = demodulator_find_nearest_symbol(&detector_modulation_averages, detector_constellation, &symbol_error);
|
||
|
|
|
||
|
|
#ifdef USE_GPIO
|
||
|
|
// qualita' TODO
|
||
|
|
GPIO_SYM_OK = 0;
|
||
|
|
if (symbol_error.frequency < (min_symbol_distance.frequency / 4)) GPIO_SYM_OK = 1;
|
||
|
|
else {
|
||
|
|
GPIO_SYM_OK = 0;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
// sarebbe preferibile avere uno storico dei valori, invece che dei simboli, ma sarebbe MAX_BUFFERS_PER_SYMBOL * detector_symbol
|
||
|
|
// anche accumulare una media sembra critico
|
||
|
|
}
|
||
|
|
rx_sample_buffer_index++;
|
||
|
|
|
||
|
|
#if defined(__DEBUG) && ! defined(__MPLAB_DEBUGGER_PK3)
|
||
|
|
// value3 = rx_sample_buffer_index;
|
||
|
|
debug_value3 = symbol_error.frequency;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
// numero di buffer per simbolo raggiunto
|
||
|
|
if (rx_sample_buffer_index >= mod.buffers_per_symbol) {
|
||
|
|
// valore piu ricorrente
|
||
|
|
rx_symbol_buffer[rx_symbol_buffer_index] = demodulator_most_frequent_value(&rx_sample_buffers_buffer[rx_symbol_detected_part_offset], mod.alphabet_size, rx_symbol_detected_part_length);
|
||
|
|
|
||
|
|
// deviazione TODO
|
||
|
|
// find_symbol_deviation(&rx_sample_buffers_buffer[rx_symbol_detected_part_offset], rx_symbol_buffer[rx_symbol_buffer_index], rx_symbol_detected_part_length);
|
||
|
|
|
||
|
|
// simbolo fatto, avanza al successivo
|
||
|
|
rx_symbol_buffer_index++;
|
||
|
|
rx_sample_buffer_index = 0;
|
||
|
|
// stava qua
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void modem_set_up_predelay(void) {
|
||
|
|
silence = (rotor_symbol){0, 0, 0};
|
||
|
|
modem_predelay_buffer_size = (modem_predelay_mstime * BUFFER_RATE) / 1000;
|
||
|
|
}
|