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

#define TX_TYPE_NONE		0
#define TX_TYPE_DAC		1
#define TX_TYPE_PWM		2
#define TX_TYPE_SI5351		3
// #define TX_TYPE			TX_TYPE_SI5351
#define TX_TYPE			TX_TYPE_NONE

#define	IF_TYPE_NOIF		0
#define	IF_TYPE_LOMIX		1
#define	IF_TYPE			IF_TYPE_NOIF

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

#define CLOCK			(168000000UL)

// RX ADC
#define ADC_CLOCK		(700000L) 	// (168000000/((47,5+12,5)*4)
#define OVERSAMPLING		(2)
#define ADC_SAMPLE_RATE		(ADC_CLOCK/OVERSAMPLING)
#define ADC_BUFFER_SIZE         (1024)
#define SAMPLES_BUFFER_RATE	(ADC_SAMPLE_RATE/ADC_BUFFER_SIZE)

// TX DAC
#define TX_DAC_SAMPLE_RATE	(CLOCK/480)
#define TX_DAC_BUFFER_SIZE	(1024)
#define TX_DAC_BUFFER_RATE	(TX_DAC_SAMPLE_RATE/TX_DAC_BUFFER_SIZE)

#define MOD_DC          0
#define MOD_LSB         1
#define MOD_USB         2
#define MOD_AM          3

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

// === DAC ===
#define DAC_DIVISOR		7680
#define DAC_SAMPLE_RATE		(CLOCK/DAC_DIVISOR)

// === 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 ====================

// state
extern uint8_t receive, transmit;
extern q31_t nco1_increment;
extern uint32_t frequency;
extern int32_t rit;
extern uint16_t pwm_tx_period;
extern int32_t modulation;
extern int32_t gain;
extern int32_t peak, oldpeak, peakset;
extern int32_t volume;
extern int32_t squelch;
extern int32_t mic_gain;
extern int32_t scan;
extern uint32_t audio_filter_freq, audio_filter_bw, audio_filter_beta; 
extern uint16_t state_changed;
extern char tabstring[15];
extern CORDIC_HandleTypeDef hcordic;

extern uint8_t s_meter;

// 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;

// rx adc
extern uint16_t adc_buffer[ADC_BUFFER_SIZE];

// tx dac
extern q31_t tx_dac_buffer[2][TX_DAC_BUFFER_SIZE];
extern volatile uint8_t half_tx_dac_buffer_empty, tx_dac_buffer_toggle;

extern q31_t if_I[LF_BUFFER_SIZE];
extern q31_t if_Q[LF_BUFFER_SIZE];

// RX DAC
extern uint8_t lf_buffer_toggle;
extern q31_t prefilter_lf_buffer[LF_BUFFER_SIZE];
extern q31_t lf_buffer[2][LF_BUFFER_SIZE];
// extern q31_t lf_buffer_test[2][LF_BUFFER_SIZE];

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

int32_t set_nco1_freq(int32_t freq);

void set_filter(void);
void set_frequency(void);
void set_modulation(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);

uint32_t get_pwm_freq(uint16_t pwm_period);
uint16_t get_pwm_period(uint32_t pwm_frequency);

uint8_t measure_log_abs_mean(q31_t *samples, uint16_t size);
