Files
bassofono/codice/Core/Src/bassofono.c
2021-12-31 04:22:22 +01:00

221 lines
6.0 KiB
C

/*
"THE CHINOTTO-WARE LICENSE" (Revision 42):
IZ4KLL a.k.a. cesco@ventuordici.org wrote this code.
As long as you retain this notice you can do whatever you want with this stuff.
I reserve the right to do the absolute minimum provided by law, up to and including absolutely nothing.
If we meet some day, and you think this stuff is worth it, you can buy me a chinotto in return.
*/
#include <stdint.h>
#include "bassofono.h"
#include "tx.h"
#include "rx.h"
#include "interface.h"
#include "si5351.h"
#include "main.h"
#include "FIRFilterCode.h"
#include <arm_math.h>
#include <stm32g4xx_ll_cordic.h>
/*
BASSOFONO .-.
(___________________________()6 `-,
( ______________________ /''"`
//\\ //\\
"" "" "" ""
~~~~ ricetrasmettitore basso ~~~~
Ricetrasmettittore multimodo per
onde lunghe e lunghissime.
*/
// state
uint8_t receive, transmit;
uint32_t frequency;
int32_t rit;
uint16_t pwm_tx_period;
int32_t modulation;
int32_t gain;
int32_t peak, oldpeak, peakset;
int32_t volume;
int32_t squelch;
int32_t mic_gain;
int32_t scan;
q31_t nco1_increment;
uint32_t audio_filter_freq, audio_filter_bw, audio_filter_beta;
char tabstring[15];
uint8_t s_meter;
// maschera, ogni bit uno stato
uint16_t state_changed;
// uart rx
char uart_rx_buf[2], rx_cmd_rb[RX_CMD_RB_SIZE];
uint8_t rx_cmd_rb_in_idx, rx_cmd_rb_out_idx;
// uart tx
char uart_tx_buf[UART_TX_BUFFER_SIZE];
uint16_t uart_tx_buf_in_idx;
// bufffah
uint16_t adc_buffer[ADC_BUFFER_SIZE];
q31_t if_I[LF_BUFFER_SIZE];
q31_t if_Q[LF_BUFFER_SIZE];
// RX
uint8_t lf_buffer_toggle;
q31_t prefilter_lf_buffer[LF_BUFFER_SIZE];
q31_t lf_buffer[2][LF_BUFFER_SIZE];
// q31_t lf_buffer_test[2][LF_BUFFER_SIZE];
// TX
// volatile uint8_t half_tx_dac_buffer_empty, tx_dac_buffer_toggle;
q31_t tx_dac_buffer[2][TX_DAC_BUFFER_SIZE];
// ============
int32_t set_nco1_freq(int32_t freq){
int64_t tmp_increment;
if(modulation == MOD_USB) freq += (NCO2_FREQUENCY);
else if(modulation == MOD_LSB) freq -= (NCO2_FREQUENCY);
tmp_increment = ((int64_t)freq * 0x100000000LL)/ADC_SAMPLE_RATE;
return (int32_t)tmp_increment;
}
inline uint16_t ringbuf_increment(uint8_t *index, uint8_t buff_size_mask) {
(*index)++;
*index &= buff_size_mask;
return *index;
}
q31_t sat_mult_q31(q31_t a, q31_t b){
q31_t out;
out = ((q63_t) a * b) >> 32;
out = __SSAT(out, 31);
return out << 1U;
}
// uart
void enqueue_cmd(char in){
rx_cmd_rb[rx_cmd_rb_in_idx] = in;
ringbuf_increment(&rx_cmd_rb_in_idx, RX_CMD_RB_SIZE_MASK);
}
void dequeue_cmd(void){
decode_cmd(rx_cmd_rb[rx_cmd_rb_out_idx]);
ringbuf_increment(&rx_cmd_rb_out_idx, RX_CMD_RB_SIZE_MASK);
}
/*
void enqueue_tx(char * data, uint16_t len){
for( uint8_t index = 0; index < len; index++){
uart_tx_buf[uart_tx_buf_in_idx] = data[index];
uart_tx_buf_in_idx++;
if(uart_tx_buf_in_idx == UART_TX_BUFFER_SIZE) break;
}
}
*/
// state changes
void set_frequency(void){
rx_nco1_increment = set_nco1_freq(frequency+rit);
if(TX_TYPE == TX_TYPE_DAC){
tx_nco1_increment = set_nco1_freq(frequency);
}
else if(TX_TYPE == TX_TYPE_PWM){
pwm_tx_period = get_pwm_period(frequency);
}
else if(TX_TYPE == TX_TYPE_SI5351){
si53531_set_frequency(frequency);
}
}
void set_filter(void){
audio_filter_generate_coeffs(audio_filter_coeffs, audio_filter_freq, audio_filter_bw, audio_filter_beta);
}
void set_modulation(void){
st2_filter_init();
// cambia offset
set_frequency();
// nco1_increment = set_nco1_freq(frequency);
}
void set_dummy(void){
// non fare NULLAH
}
// cambiato stato
void set_changed(uint8_t state){
state_changed |= (1U<<state);
}
void reset_changed(uint8_t state){
state_changed &= ~(1U<<state);
}
uint8_t get_changed(uint8_t state){
return (state_changed >> state) & 1U;
}
void state_set_default(void){
modulation = MOD_USB;
frequency = 128000;
rit = 0;
set_frequency();
gain = 2;
volume = 8;
audio_filter_freq = AUDIO_FILTER_FREQ_DEF;
audio_filter_bw = AUDIO_FILTER_BW_DEF;
audio_filter_beta = AUDIO_FILTER_BETA_DEF;
audio_filter_generate_coeffs(audio_filter_coeffs, audio_filter_freq, audio_filter_bw, audio_filter_beta);
state_changed = 0xFFFF;
// strcpy(tabstring, "TX AUD MEM NO");
}
// diag
void diag(void){
uart_tx_buf_in_idx += sprintf(uart_tx_buf,"ADC sample rate: %d\nADC oversampling: %d\n", ADC_SAMPLE_RATE, OVERSAMPLING);
uart_tx_buf_in_idx += sprintf(uart_tx_buf,"ADC buffer size: %d\n1st decimation factor: %d\n", ADC_BUFFER_SIZE, MS_DECIMATION_FACTOR * 2);
uart_tx_buf_in_idx += sprintf(uart_tx_buf,"1st out sample rate: %d\n", ST1_OUT_SAMPLE_RATE);
uart_tx_buf_in_idx += sprintf(uart_tx_buf,"2st buffer size: %d\n2st decimation factor: %d\n", ST2_BUFFER_SIZE, ST2_DECIMATION_FACTOR * 2);
uart_tx_buf_in_idx += sprintf(uart_tx_buf,"2st out sample rate: %d\n", ST2_OUT_SAMPLE_RATE);
uart_tx_buf_in_idx += sprintf(uart_tx_buf,"in gain %d\n", gain);
uart_tx_buf_in_idx += sprintf(uart_tx_buf,"af gain %d\n", volume);
uart_tx_buf_in_idx += sprintf(uart_tx_buf,"rx nco1 inc %d\n", rx_nco1_increment);
uart_tx_buf_in_idx += sprintf(uart_tx_buf,"nco2 inc %d\n", NCO2_INCREMENT);
uart_tx_buf_in_idx += sprintf(uart_tx_buf,"audio filter f %d bw %d\n", audio_filter_freq, audio_filter_bw);
}
uint32_t get_pwm_freq(uint16_t pwm_period){
return CLOCK/pwm_period;
}
uint16_t get_pwm_period(uint32_t pwm_frequency){
return CLOCK/pwm_frequency;
}
uint8_t measure_log_abs_mean(q31_t *samples, uint16_t size){
int32_t measured_signal = 0;
// , old_rx_signal;
uint16_t index = 0;
uint8_t log_sig = 31;
q31_t abs, accu;
while(index < size){
abs = (samples[index] > 0) ? samples[index] : (q31_t)__QSUB(0, samples[index]);
measured_signal += (abs >> 6);
index++;
}
while (log_sig) {
if((measured_signal >> log_sig) & 1) break;
log_sig--;
}
return log_sig;
}