#include <stdint.h>
#include <stdio.h>
// #include <arm_math.h>
#include "main.h"
#include "rx.h"
#include "tx.h"

#define	IF_TYPE_NOIF		0	// la frequenza del dac o del dds e' pari alla frequenza impostata
#define	IF_TYPE_LOMIX		1
#define	IF_TYPE			IF_TYPE_LOMIX

#define LO_TYPE_FIX		0
#define LO_TYPE_SI5351		1
#define LO_TYPE			LO_TYPE_SI5351

#define LO_FREQ	125000	// frequenza di LO

#define CLOCK			(168000000UL)

#define NCO2_INCREMENT          (343597383L)

#define MOD_DC          0
#define MOD_LSB         1
#define MOD_USB         2
#define MOD_CWL         3
#define MOD_CWU         4
#define MOD_AM          5
#define MOD_FM          6

#define STATUS_RX	0
#define STATUS_TX	1
#define STATUS_SQ	2

// === UART ===
#define RX_CMD_RB_SIZE			(32)
#define RX_CMD_RB_SIZE_MASK		(RX_CMD_RB_SIZE - 1)

#define UART_TX_BUFFER_SIZE		(512)

// ====== VARS ====================

struct __attribute__((__packed__)) s_stato {
	uint8_t		volume;
	uint8_t		guadagno_rx;
	uint8_t		guadagno_mic;
	uint8_t		canale;
	uint16_t	tx_f_freq;
	uint16_t	tx_f_banda;
	uint8_t		tx_f_beta;
};

struct __attribute__((__packed__)) s_canale {
	char		nome[16];
	uint8_t		gruppo;
	uint32_t	frequenza;
	uint8_t		modulazione;
	int16_t		rit;
	uint16_t	rx_f_freq;
	uint16_t	rx_f_banda;
	uint8_t		rx_f_beta;
};

struct __attribute__((__packed__)) s_banda {
	char		nome[16];
	uint32_t	min;
	uint32_t	max;
};


// volatili
extern uint8_t ricezione, trasmissione;
extern q31_t nco1_increment;
// extern uint16_t pwm_tx_period;
extern int32_t peak, peakset;
extern int32_t scan;
extern uint8_t s_meter;
extern uint16_t state_changed;
extern uint8_t scrittura_stato_pendente;

// canale
extern struct s_canale canale;
extern int32_t rit;
extern uint32_t audio_filter_freq, audio_filter_bw, audio_filter_beta; 

// stato
extern struct s_stato stato;
extern int32_t squelch;
extern int32_t rx_gain;
extern int32_t mic_gain;

extern CORDIC_HandleTypeDef hcordic;


// uartz
extern char uart_rx_buf[2], rx_cmd_rb[RX_CMD_RB_SIZE];
extern uint8_t rx_cmd_rb_in_idx, rx_cmd_rb_out_idx;

// uart tx
extern char uart_tx_buf[UART_TX_BUFFER_SIZE];
extern uint16_t uart_tx_buf_in_idx;

extern q31_t if_I[RX_DAC_BUFFER_SIZE];
extern q31_t if_Q[RX_DAC_BUFFER_SIZE];

// ======== FUNZIONI ========

void enqueue_cmd(char in);
void state_set_default(void);

void start_trasmissione(void);
void stop_trasmissione(void);
void start_ricezione(void);
void stop_ricezione(void);

void set_rx_gain(void);

int32_t set_nco1_freq(int32_t freq);

// void set_filter(void);
void set_frequency(void);
void imposta_modulazione(void);
void set_dummy	(void);
uint8_t get_changed(uint8_t state);

// varie
uint16_t ringbuf_increment(uint8_t *index, uint8_t buff_size_mask);
q31_t sat_mult_q31(q31_t a, q31_t b);

// diag
void diag(void);

uint8_t measure_log_abs_mean(q31_t *samples, uint16_t size);
