155 lines
4.0 KiB
C
155 lines
4.0 KiB
C
|
|
#include "../libsample/sample.h"
|
|
#include "../libfilter/iir_filter.h"
|
|
#include "../libwave/wave.h"
|
|
#include "../libdisplay/display.h"
|
|
#include "hdlc.h"
|
|
#include "ph_socket.h"
|
|
|
|
#define TX_NUM_B 64 /* must be a multiple of 8 (one frame) */
|
|
#define TX_NUM_D 16 /* must be a multiple of 2 (one frame) */
|
|
|
|
typedef struct uk0_tx {
|
|
double phase, phase_step, phase_180;
|
|
int index;
|
|
double level, last_level;
|
|
uint64_t buffer[8]; /* 256 symbols */
|
|
int frame_length;
|
|
int frame_index;
|
|
uint8_t mms43_column;
|
|
uint32_t scramble;
|
|
uint8_t B1[TX_NUM_B], B2[TX_NUM_B], D[TX_NUM_D];
|
|
int b_count, d_count;
|
|
} uk0_tx_t;
|
|
|
|
#define RX_NUM_B 64 /* must be a multiple of 8 (one frame) */
|
|
#define RX_NUM_D 16 /* must be a multiple of 2 (one frame) */
|
|
|
|
typedef struct uk0_rx {
|
|
wave_rec_t rec;
|
|
int oversampling; /* factor to reach about 2 megasamples */
|
|
sample_t *sinc;
|
|
sample_t *window;
|
|
int window_length;
|
|
double last_level;
|
|
double phase, phase_step, phase_360; /* uncorrected phase */
|
|
double sample_phase; /* corrected phase for sample point */
|
|
iir_filter_t lp[2]; /* filters received IQ signal */
|
|
double count_ms, ms_per_sample; /* counters when to check level and phase */
|
|
double min, max;
|
|
int overdriven_count;
|
|
double zero, low, high, low_threshold, high_threshold, rx_level;
|
|
uint64_t buffer[4];
|
|
int u0_detect; /* counter to detect LOS */
|
|
int u1w_count; /* counter to detect cease of U1W */
|
|
int u1a_count, u1a_detect; /* counters to detect U1A */
|
|
int sync_count, sync_symbols;
|
|
uint64_t sync_last;
|
|
uint32_t descramble;
|
|
uint8_t B1[RX_NUM_B], B2[RX_NUM_B], D[RX_NUM_D];
|
|
int b_count, d_count;
|
|
} uk0_rx_t;
|
|
|
|
enum uk0_state {
|
|
/* interface off */
|
|
UK0_STATE_NULL = 0,
|
|
/* deactivated state, waiting for LT or NT activation */
|
|
UK0_STATE_LT_1_1,
|
|
/* got U1W, send U2W */
|
|
UK0_STATE_LT_1_2,
|
|
/* got activation from LT, send U2W */
|
|
UK0_STATE_LT_1_3,
|
|
/* wait for U1 or U3 */
|
|
UK0_STATE_LT_1_4,
|
|
/* wait for U3 */
|
|
UK0_STATE_LT_1_5,
|
|
/* send U4H */
|
|
UK0_STATE_LT_1_6,
|
|
/* send U4 */
|
|
UK0_STATE_LT_1_7,
|
|
/* wait for U0 */
|
|
UK0_STATE_LT_1_8,
|
|
/* send test signal */
|
|
UK0_STATE_TESTSIGNAL,
|
|
};
|
|
|
|
enum uk0_event {
|
|
UK0_EVENT_DISABLE = 0,
|
|
UK0_EVENT_ENABLE,
|
|
UK0_EVENT_LOOP2_ENABLE,
|
|
UK0_EVENT_LOOP_DISABLE,
|
|
UK0_EVENT_TESTSIGNAL,
|
|
UK0_EVENT_DEACTIVATE,
|
|
UK0_EVENT_ACTIVATE,
|
|
UK0_EVENT_TIMEOUT,
|
|
UK0_EVENT_U0,
|
|
UK0_EVENT_U1W,
|
|
UK0_EVENT_U1A,
|
|
UK0_EVENT_U1,
|
|
UK0_EVENT_U3,
|
|
UK0_EVENT_U5,
|
|
UK0_EVENT_SP,
|
|
UK0_EVENT_ANY,
|
|
};
|
|
|
|
struct tx_queue {
|
|
struct tx_queue *next;
|
|
int length;
|
|
uint8_t data[0];
|
|
};
|
|
|
|
typedef struct uk0 {
|
|
const char *name;
|
|
enum uk0_state state;
|
|
int loopback2, loop_timer;
|
|
int ti1, ti2, timer;
|
|
int u2w_delay;
|
|
uk0_tx_t tx;
|
|
uk0_rx_t rx;
|
|
hdlc_tx_t hdlc_tx[3];
|
|
hdlc_rx_t hdlc_rx[3];
|
|
struct tx_queue *tx_queue[3], **tx_queue_tail[3];
|
|
int tx_queue_size[3];
|
|
ph_socket_t ph_socket;
|
|
|
|
/* measurements */
|
|
int measure_interval;
|
|
int measure_index;
|
|
double measure_level_error;
|
|
dispmeas_t dispmeas; /* display measurements */
|
|
dispmeasparam_t *dmp_level;
|
|
dispmeasparam_t *dmp_level_error;
|
|
|
|
/* error reporting */
|
|
int nt_violation_interval;
|
|
int nt_violation_index;
|
|
int nt_violation_error;
|
|
int lt_violation_interval;
|
|
int lt_violation_index;
|
|
int lt_violation_error;
|
|
int loop2_frame_interval;
|
|
int loop2_frame_index;
|
|
int loop2_frame_error;
|
|
|
|
/* wave */
|
|
dispwav_t dispwav; /* display wave form */
|
|
|
|
} uk0_t;
|
|
|
|
void uk0_init(int _fast_math);
|
|
void uk0_exit(void);
|
|
uk0_t *uk0_create(const char *name, int samplerate, int buffer_size);
|
|
void uk0_start(uk0_t *uk0);
|
|
void uk0_destroy(uk0_t *uk0);
|
|
void uk0_work(uk0_t *uk0, int buffer_size);
|
|
void uk0_send(uk0_t *uk0, int ch, uint8_t *data, int length);
|
|
void uk0_receive(uk0_t *uk0, int ch, uint8_t *data, int length);
|
|
void uk0_handle_event(uk0_t *uk0, enum uk0_event event);
|
|
void uk0_encode_mms43(uk0_t *uk0, sample_t *samples, int length);
|
|
void uk0_decode_mms43(uk0_t *uk0, sample_t *samples, int length);
|
|
|
|
void uk0_tx_flush(uk0_t *uk0, int channel);
|
|
void uk0_tx_enqueue(uk0_t *uk0, int channel, uint8_t *data, int length);
|
|
int uk0_tx_dequeue(uk0_t *uk0, int channel, uint8_t *data, int size);
|
|
|