368 lines
7.8 KiB
C
368 lines
7.8 KiB
C
/*
|
|
* Copyright 2017-2024 Oleg Borodin <onborodin@gmail.com>
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
|
|
#include <avr/interrupt.h>
|
|
#include <util/delay.h>
|
|
|
|
#include <tool.h>
|
|
#include <eeprom.h>
|
|
#include <disp.h>
|
|
#include <uart.h>
|
|
#include <temp.h>
|
|
#include <relay.h>
|
|
#include <timer.h>
|
|
#include <adc.h>
|
|
#include <button.h>
|
|
|
|
#include <contr.h>
|
|
|
|
#define CONTR_BAND_OFF 0x01
|
|
#define CONTR_BAND_10M 0x02
|
|
#define CONTR_BAND_20M 0x03
|
|
#define CONTR_BAND_40M 0x04
|
|
#define CONTR_BAND_80M 0x05
|
|
|
|
#define CONR_VCCARR_SIZE 4
|
|
#define CONR_PWRARR_SIZE 16
|
|
|
|
typedef struct {
|
|
uint8_t band;
|
|
uint16_t freq;
|
|
uint16_t cnt;
|
|
|
|
uint16_t vccs[CONR_VCCARR_SIZE];
|
|
size_t vccp;
|
|
float vcc;
|
|
uint16_t vccr;
|
|
|
|
uint16_t fwd1s[CONR_PWRARR_SIZE];
|
|
uint16_t fwd2s[CONR_PWRARR_SIZE];
|
|
size_t fwd1p;
|
|
size_t fwd2p;
|
|
uint16_t fwd;
|
|
|
|
uint16_t rev1s[CONR_PWRARR_SIZE];
|
|
uint16_t rev2s[CONR_PWRARR_SIZE];
|
|
size_t rev1p;
|
|
size_t rev2p;
|
|
uint16_t rev;
|
|
|
|
} contr_t;
|
|
|
|
contr_t contr;
|
|
|
|
void contr_switch_band(void);
|
|
void contr_set_band(uint8_t band);
|
|
void contr_write_band(void);
|
|
void contr_read_band(void);
|
|
|
|
void contr_init(void) {
|
|
contr.band = CONTR_BAND_OFF;
|
|
contr.vccp = 0;
|
|
for (size_t i = 0; i < CONR_VCCARR_SIZE; i++) contr.vccs[i] = 0;
|
|
|
|
contr.fwd1p = 0;
|
|
contr.fwd2p = 0;
|
|
contr.fwd2p = 0;
|
|
for (size_t i = 0; i < CONR_PWRARR_SIZE; i++) contr.fwd1s[i] = 0;
|
|
for (size_t i = 0; i < CONR_PWRARR_SIZE; i++) contr.fwd2s[i] = 0;
|
|
contr.fwd = 0;
|
|
|
|
contr.rev1p = 0;
|
|
contr.rev2p = 0;
|
|
contr.rev2p = 0;
|
|
for (size_t i = 0; i < CONR_PWRARR_SIZE; i++) contr.rev1s[i] = 0;
|
|
for (size_t i = 0; i < CONR_PWRARR_SIZE; i++) contr.rev2s[i] = 0;
|
|
contr.rev = 0;
|
|
}
|
|
void contr_setup(void) {
|
|
contr_read_band();
|
|
}
|
|
|
|
#define CONTR_VCC_SCALE 270.0F
|
|
void contr_measure_vcc(void) {
|
|
contr.vccr = adc_read(ACD_CHANELL3);
|
|
}
|
|
|
|
void contr_calc_vcc(void) {
|
|
contr.vcc = lroundf((float)contr.vccr / CONTR_VCC_SCALE) / 10.0F;
|
|
}
|
|
|
|
float contr_get_vcc(void) {
|
|
return contr.vcc;
|
|
}
|
|
|
|
#define CONTR_FWD_SCALE 370
|
|
void contr_measure_fwd(void) {
|
|
contr.fwd1s[contr.fwd1p] = adc_read(ACD_CHANELL1);
|
|
contr.fwd1p++;
|
|
if ((contr.fwd1p) > CONR_PWRARR_SIZE) {
|
|
contr.fwd1p = 0;
|
|
if ((++(contr.fwd2p)) > CONR_PWRARR_SIZE) {
|
|
contr.fwd2p = 0;
|
|
}
|
|
uint32_t summ = 0;
|
|
for (size_t i = 0; i < CONR_PWRARR_SIZE; i++) {
|
|
summ += contr.fwd1s[i];
|
|
}
|
|
contr.fwd2s[contr.fwd2p] = (uint16_t)(summ / CONR_PWRARR_SIZE);
|
|
}
|
|
}
|
|
|
|
void contr_calc_fwd(void) {
|
|
uint32_t summ = 0;
|
|
for (size_t i = 0; i < CONR_PWRARR_SIZE; i++) {
|
|
summ += contr.fwd2s[i];
|
|
}
|
|
summ /= CONR_PWRARR_SIZE;
|
|
contr.fwd = summ / CONTR_FWD_SCALE;
|
|
}
|
|
|
|
uint16_t contr_get_fwd(void) {
|
|
return contr.fwd;
|
|
}
|
|
|
|
#define CONTR_REV_SCALE 28
|
|
void contr_measure_rev(void) {
|
|
contr.rev1s[contr.rev1p] = adc_read(ACD_CHANELL0);
|
|
contr.rev1p++;
|
|
if ((contr.rev1p) > CONR_PWRARR_SIZE) {
|
|
contr.rev1p = 0;
|
|
if ((++(contr.rev2p)) > CONR_PWRARR_SIZE) {
|
|
contr.rev2p = 0;
|
|
}
|
|
uint32_t summ = 0;
|
|
for (size_t i = 0; i < CONR_PWRARR_SIZE; i++) {
|
|
summ += contr.rev1s[i];
|
|
}
|
|
contr.rev2s[contr.rev2p] = (summ / CONR_PWRARR_SIZE);
|
|
}
|
|
}
|
|
|
|
void contr_calc_rev(void) {
|
|
uint32_t summ = 0;
|
|
for (size_t i = 0; i < CONR_PWRARR_SIZE; i++) {
|
|
summ += contr.rev2s[i];
|
|
}
|
|
summ /= CONR_PWRARR_SIZE;
|
|
contr.rev = summ / CONTR_REV_SCALE;
|
|
}
|
|
|
|
uint16_t contr_get_rev(void) {
|
|
return contr.rev;
|
|
}
|
|
|
|
void contr_switch_band(void) {
|
|
switch (contr.band) {
|
|
case CONTR_BAND_10M:
|
|
contr_set_band(CONTR_BAND_20M);
|
|
break;
|
|
case CONTR_BAND_20M:
|
|
contr_set_band(CONTR_BAND_40M);
|
|
break;
|
|
case CONTR_BAND_40M:
|
|
contr_set_band(CONTR_BAND_80M);
|
|
break;
|
|
case CONTR_BAND_80M:
|
|
contr_set_band(CONTR_BAND_10M);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void contr_set_band(uint8_t band) {
|
|
ampl_off();
|
|
contr.band = band;
|
|
|
|
switch (contr.band) {
|
|
case CONTR_BAND_10M:
|
|
filter80m_off();
|
|
filter40m_off();
|
|
filter20m_off();
|
|
filter10m_on();
|
|
break;
|
|
case CONTR_BAND_20M:
|
|
filter80m_off();
|
|
filter40m_off();
|
|
filter10m_off();
|
|
filter20m_on();
|
|
break;
|
|
case CONTR_BAND_40M:
|
|
filter80m_off();
|
|
filter20m_off();
|
|
filter10m_off();
|
|
filter40m_on();
|
|
break;
|
|
case CONTR_BAND_80M:
|
|
filter40m_off();
|
|
filter20m_off();
|
|
filter10m_off();
|
|
filter80m_on();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
contr_write_band();
|
|
atten_off();
|
|
}
|
|
|
|
char* contr_get_bandname() {
|
|
char* bandstr = NULL;
|
|
switch (contr.band) {
|
|
case CONTR_BAND_10M:
|
|
bandstr = "10m";
|
|
break;
|
|
case CONTR_BAND_20M:
|
|
bandstr = "20m";
|
|
break;
|
|
case CONTR_BAND_40M:
|
|
bandstr = "40m";
|
|
break;
|
|
case CONTR_BAND_80M:
|
|
bandstr = "80m";
|
|
break;
|
|
case CONTR_BAND_OFF:
|
|
bandstr = "OFF";
|
|
break;
|
|
}
|
|
return bandstr;
|
|
}
|
|
|
|
#define CONTR_KEY_SWBAND 3
|
|
#define CONTR_KEY_BUZZER 4
|
|
#define CONTR_KEY_FUN 5
|
|
|
|
void contr_button_eval(void) {
|
|
switch (button_get()) {
|
|
case CONTR_KEY_SWBAND:
|
|
contr_switch_band();
|
|
break;
|
|
case CONTR_KEY_BUZZER:
|
|
buzzer_onoff();
|
|
break;
|
|
case CONTR_KEY_FUN:
|
|
fan_onoff();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void contr_show_logo(void) {
|
|
disp_clear();
|
|
char* dispstr = "Made by R2FDX";
|
|
disp_string(1, 1, dispstr);
|
|
_delay_ms(200);
|
|
disp_clear();
|
|
}
|
|
|
|
void contr_show_band(void) {
|
|
disp_string(0, 13, contr_get_bandname());
|
|
}
|
|
|
|
void contr_show_vcc(void) {
|
|
char buffer[12] = { '\0' };
|
|
sprintf(buffer, "%4.1fv", contr_get_vcc());
|
|
disp_string(3, 11, buffer);
|
|
}
|
|
|
|
void contr_show_ptt(void) {
|
|
if (ptt_is_pressed()) {
|
|
disp_string(3, 0, "TX");
|
|
} else {
|
|
disp_string(3, 0, " ");
|
|
}
|
|
}
|
|
|
|
ISR(TIMER0_OVF_vect) {
|
|
contr_measure_vcc();
|
|
contr_measure_fwd();
|
|
contr_measure_rev();
|
|
contr.freq = contr.cnt;
|
|
contr.cnt = 0;
|
|
button_handle();
|
|
uart_handle();
|
|
contr_calc_fwd();
|
|
contr_calc_rev();
|
|
}
|
|
|
|
ISR(TIMER1_OVF_vect) {
|
|
contr.cnt++;
|
|
REG_SETUP(TCNT1, TIMER1_PRESIZE);
|
|
}
|
|
|
|
#define CONTR_FREQ_SCALE 2
|
|
uint16_t contr_get_freq(void) {
|
|
return contr.freq / CONTR_FREQ_SCALE;
|
|
}
|
|
|
|
void contr_show_freq(void) {
|
|
char buffer[12] = { '\0' };
|
|
uint16_t freq = contr_get_freq();
|
|
|
|
sprintf(buffer, "%5uM", freq);
|
|
disp_string(0, 0, buffer);
|
|
}
|
|
|
|
void contr_show_fwd(void) {
|
|
char buffer[12] = { '\0' };
|
|
sprintf(buffer, "F %7uw", contr_get_fwd());
|
|
disp_string(1, 2, buffer);
|
|
}
|
|
|
|
void contr_show_rev(void) {
|
|
char buffer[12] = { '\0' };
|
|
sprintf(buffer, "R %7uw", contr_get_rev());
|
|
disp_string(2, 2, buffer);
|
|
}
|
|
|
|
void contr_show_swr(void) {
|
|
char buffer[12] = { '\0' };
|
|
uint16_t fwd = contr_get_fwd();
|
|
uint16_t rev = contr_get_rev();
|
|
uint16_t diff = (fwd - rev);
|
|
|
|
uint16_t swr = 0;
|
|
if (diff != 0) {
|
|
swr =((fwd + rev) * 100) / diff;
|
|
}
|
|
sprintf(buffer, " %u", swr);
|
|
disp_string(2, 2, buffer);
|
|
}
|
|
|
|
void contr_main(void) {
|
|
contr_show_logo();
|
|
uint16_t counter = 0;
|
|
while (true) {
|
|
contr_show_ptt();
|
|
contr_button_eval();
|
|
//contr_calc_vcc();
|
|
//contr_show_fwd();
|
|
//contr_show_rev();
|
|
contr_show_swr();
|
|
contr_show_vcc();
|
|
contr_show_band();
|
|
contr_show_freq();
|
|
counter++;
|
|
_delay_ms(100);
|
|
}
|
|
}
|
|
|
|
#define CONTR_BAND_EEPROM_ADDR 0x00
|
|
|
|
void contr_write_band(void) {
|
|
eeprom_write_bytes(CONTR_BAND_EEPROM_ADDR, &contr.band, sizeof(contr.band));
|
|
}
|
|
|
|
void contr_read_band(void) {
|
|
eeprom_read_bytes(CONTR_BAND_EEPROM_ADDR, &contr.band, sizeof(contr.band));
|
|
}
|
|
|