import
This commit is contained in:
543
contr.c
Normal file
543
contr.c
Normal file
@@ -0,0 +1,543 @@
|
||||
/*
|
||||
* Copyright 2017 Oleg Borodin <onborodin@gmail.com>
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#include <eeprom.h>
|
||||
#include <disp.h>
|
||||
#include <tool.h>
|
||||
#include <uart.h>
|
||||
#include <timer.h>
|
||||
#include <temp.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 VCCS_SIZE 12
|
||||
|
||||
typedef struct {
|
||||
uint16_t fwd_power;
|
||||
uint16_t ref_power;
|
||||
uint16_t temp;
|
||||
uint16_t freq;
|
||||
uint16_t vcc;
|
||||
uint8_t band;
|
||||
bool key_was_pressed;
|
||||
uint16_t key_time_counter;
|
||||
uint16_t key_time_untap;
|
||||
uint16_t key_tap_counter;
|
||||
bool key_strokes_ended;
|
||||
uint16_t vccs[VCCS_SIZE];
|
||||
size_t vccs_pos;
|
||||
} contr_t;
|
||||
|
||||
contr_t contr;
|
||||
|
||||
void contr_key_init(void);
|
||||
void contr_key_handle(void);
|
||||
void contr_key_reset(void);
|
||||
|
||||
void contr_switch_band(void);
|
||||
void contr_set_band(uint8_t band);
|
||||
|
||||
void contr_txrelay_init(void);
|
||||
void contr_txrelay_on(void);
|
||||
void contr_txrelay_off(void);
|
||||
void contr_txrelay_onoff(void);
|
||||
|
||||
void contr_relay10m_init(void);
|
||||
void contr_relay10m_on(void);
|
||||
void contr_relay10m_off(void);
|
||||
|
||||
void contr_relay20m_init(void);
|
||||
void contr_relay20m_on(void);
|
||||
void contr_relay20m_off(void);
|
||||
|
||||
void contr_relay40m_init(void);
|
||||
void contr_relay40m_on(void);
|
||||
void contr_relay40m_off(void);
|
||||
|
||||
void contr_relay80m_init(void);
|
||||
void contr_relay80m_on(void);
|
||||
void contr_relay80m_off(void);
|
||||
|
||||
void contr_buzzer_init(void);
|
||||
void contr_buzzer_on(void);
|
||||
void contr_buzzer_off(void);
|
||||
void contr_buzzer_onoff(void);
|
||||
|
||||
void contr_fan_init(void);
|
||||
void contr_fan_on(void);
|
||||
void contr_fan_off(void);
|
||||
void contr_fan_onoff(void);
|
||||
bool contr_fan_is_on(void);
|
||||
|
||||
void contr_att_init(void);
|
||||
void contr_att_on(void);
|
||||
void contr_att_off(void);
|
||||
|
||||
void contr_timer_init(void);
|
||||
void contr_adc_init(void);
|
||||
float contr_vcc_read(void);
|
||||
|
||||
void contr_write_band(void);
|
||||
void contr_read_band(void);
|
||||
|
||||
void contr_timer_init(void) {
|
||||
/* Disable comparators */
|
||||
REG_SETDOWN_BIT(TCCR0A, COM0A1);
|
||||
REG_SETDOWN_BIT(TCCR0A, COM0A0);
|
||||
REG_SETDOWN_BIT(TCCR0A, COM0B1);
|
||||
REG_SETDOWN_BIT(TCCR0A, COM0B0);
|
||||
/* Set normal mode */
|
||||
REG_SETDOWN_BIT(TCCR0A, WGM01);
|
||||
REG_SETDOWN_BIT(TCCR0A, WGM00);
|
||||
/* Set clock to 1/64 */
|
||||
REG_SETDOWN_BIT(TCCR0B, CS02);
|
||||
REG_SETUP_BIT(TCCR0B, CS01);
|
||||
REG_SETUP_BIT(TCCR0B, CS00);
|
||||
/* Enable timer interrupt */
|
||||
REG_SETUP_BIT(TIMSK0, TOIE0);
|
||||
REG_SETUP(TCNT0, TIMER_INITVAL);
|
||||
}
|
||||
|
||||
ISR(TIMER0_OVF_vect) {
|
||||
contr_key_handle();
|
||||
|
||||
volatile uint8_t xchar;
|
||||
|
||||
while ((xchar = fifo_getc(&uart_outbuf)) > 0) {
|
||||
while (!REG_BIT_ISUP(UCSR0A, UDRE0));
|
||||
UDR0 = xchar;
|
||||
}
|
||||
REG_SETUP(TCNT0, TIMER_INITVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* D0 - PD0 RX
|
||||
* D1 - PD1 TX
|
||||
* D2 - PD2 IN PTT IN
|
||||
* D3 - PD3 IN KEY
|
||||
* D4 - PD4 OUT RELAY5 TX SWITCH
|
||||
* D5 - PD5 IN FREQ OSC MC74HC4060A
|
||||
* D6 - PD6 OUT 10M
|
||||
* D7 - PD7 OUT 20M
|
||||
* D8 - PB0 OUT 40M
|
||||
* D9 - PB1 OUT 80M
|
||||
* D10 - PB2 OUT BUZZER
|
||||
* D11 - PB3 IN TEMP DS18B20
|
||||
* D12 - PB4 OUT FAN
|
||||
* D13 - PB5 OUT PA ATT SWITCH
|
||||
*
|
||||
* A0 PC0 - V.REV
|
||||
* A1 PC1 - V.FWD
|
||||
* A2 PC2 - ICOM
|
||||
* A3 PC3 - V.VCC
|
||||
*/
|
||||
|
||||
void contr_init(void) {
|
||||
contr.fwd_power = 0;
|
||||
contr.ref_power = 0;
|
||||
contr.temp = 0;
|
||||
contr.freq = 0;
|
||||
contr.vcc = 0;
|
||||
contr.band = CONTR_BAND_OFF;
|
||||
|
||||
contr.vccs_pos = 0;
|
||||
for (size_t i = 0; i < VCCS_SIZE; i++) {
|
||||
contr.vccs[i] = 0.0F;
|
||||
}
|
||||
|
||||
contr.key_was_pressed = false;
|
||||
contr.key_time_counter = 0;
|
||||
contr.key_tap_counter = 0;
|
||||
contr.key_strokes_ended = false;
|
||||
}
|
||||
|
||||
void contr_setup(void) {
|
||||
contr_read_band();
|
||||
contr_txrelay_init();
|
||||
contr_txrelay_off();
|
||||
|
||||
contr_att_init();
|
||||
contr_att_off();
|
||||
|
||||
contr_relay10m_init();
|
||||
contr_relay20m_init();
|
||||
contr_relay40m_init();
|
||||
contr_relay80m_init();
|
||||
|
||||
contr_relay10m_off();
|
||||
contr_relay20m_off();
|
||||
contr_relay40m_off();
|
||||
contr_relay80m_off();
|
||||
|
||||
contr_buzzer_init();
|
||||
contr_buzzer_off();
|
||||
|
||||
contr_fan_init();
|
||||
contr_fan_off();
|
||||
|
||||
contr_key_init();
|
||||
contr_adc_init();
|
||||
contr_timer_init();
|
||||
}
|
||||
|
||||
|
||||
void contr_switch_band(void) {
|
||||
contr_txrelay_off();
|
||||
_delay_ms(100);
|
||||
contr_relay80m_off();
|
||||
contr_relay40m_off();
|
||||
contr_relay20m_off();
|
||||
contr_relay10m_off();
|
||||
_delay_ms(100);
|
||||
|
||||
switch (contr.band) {
|
||||
case CONTR_BAND_10M:
|
||||
contr_relay20m_on();
|
||||
contr.band = CONTR_BAND_20M;
|
||||
break;
|
||||
case CONTR_BAND_20M:
|
||||
contr_relay40m_on();
|
||||
contr.band = CONTR_BAND_40M;
|
||||
break;
|
||||
case CONTR_BAND_40M:
|
||||
contr_relay80m_on();
|
||||
contr.band = CONTR_BAND_80M;
|
||||
break;
|
||||
case CONTR_BAND_80M:
|
||||
contr_relay10m_on();
|
||||
contr.band = CONTR_BAND_10M;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
contr_write_band();
|
||||
_delay_ms(100);
|
||||
contr_att_on();
|
||||
_delay_ms(100);
|
||||
}
|
||||
|
||||
|
||||
void contr_logo(void) {
|
||||
char dispstr[10] = { '\0' };
|
||||
|
||||
sprintf(dispstr, "R2DFX");
|
||||
disp_string(2, 3, dispstr);
|
||||
}
|
||||
|
||||
/*******************************************************/
|
||||
void contr_main(void) {
|
||||
uint16_t counter = 0;
|
||||
char dispstr[10] = { '\0' };
|
||||
char* bandstr = NULL;
|
||||
|
||||
sprintf(dispstr, "Made by R2FDX");
|
||||
disp_string(1, 1, dispstr);
|
||||
_delay_ms(1000);
|
||||
disp_clear();
|
||||
|
||||
printf("READY>\n\r# ");
|
||||
|
||||
while (true) {
|
||||
_delay_ms(100);
|
||||
if (contr.key_strokes_ended) {
|
||||
switch (contr.key_tap_counter) {
|
||||
case 1:
|
||||
contr_key_reset();
|
||||
contr_switch_band();
|
||||
break;
|
||||
case 2:
|
||||
contr_key_reset();
|
||||
//contr_txrelay_onoff();
|
||||
break;
|
||||
case 3:
|
||||
contr_key_reset();
|
||||
contr_buzzer_onoff();
|
||||
break;
|
||||
case 5:
|
||||
contr_key_reset();
|
||||
contr_fan_onoff();
|
||||
break;
|
||||
default:
|
||||
contr_key_reset();
|
||||
break;
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
}
|
||||
disp_string(0, 12, bandstr);
|
||||
|
||||
sprintf(dispstr, "%3.2fV", contr_vcc_read());
|
||||
disp_string(0, 0, dispstr);
|
||||
|
||||
sprintf(dispstr, "%3.2fC", ds18b20_get_temp());
|
||||
disp_string(3, 0, dispstr);
|
||||
|
||||
if (contr.key_tap_counter) {
|
||||
sprintf(dispstr, "%2d", contr.key_tap_counter);
|
||||
disp_string(3, 12, dispstr);
|
||||
} else {
|
||||
sprintf(dispstr, " ");
|
||||
disp_string(3, 12, dispstr);
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* D4 PD4: Set input relay 5 output */
|
||||
void contr_txrelay_init(void) {
|
||||
REG_SETUP_BIT(DDRD, PD4);
|
||||
}
|
||||
void contr_txrelay_on(void) {
|
||||
REG_SETUP_BIT(PORTD, PD4);
|
||||
}
|
||||
void contr_txrelay_off(void) {
|
||||
REG_SETDOWN_BIT(PORTD, PD4);
|
||||
}
|
||||
void contr_txrelay_onoff(void) {
|
||||
if (REG_BIT_VALUE(PIND, PD4)) {
|
||||
contr_txrelay_off();
|
||||
} else {
|
||||
contr_txrelay_on();
|
||||
}
|
||||
}
|
||||
/* D6 PD6: Set 10M relay 1 output */
|
||||
void contr_relay10m_init(void) {
|
||||
REG_SETUP_BIT(DDRD, PD6);
|
||||
}
|
||||
void contr_relay10m_on(void) {
|
||||
REG_SETUP_BIT(PORTD, PD6);
|
||||
}
|
||||
void contr_relay10m_off(void) {
|
||||
REG_SETDOWN_BIT(PORTD, PD6);
|
||||
}
|
||||
|
||||
/* D7 PD7: Set 20M relay 2 output */
|
||||
void contr_relay20m_init(void) {
|
||||
REG_SETUP_BIT(DDRD, PD7);
|
||||
}
|
||||
void contr_relay20m_on(void) {
|
||||
REG_SETUP_BIT(PORTD, PD7);
|
||||
}
|
||||
void contr_relay20m_off(void) {
|
||||
REG_SETDOWN_BIT(PORTD, PD7);
|
||||
}
|
||||
|
||||
/* D8 PB0: Set 40M relay 3 output */
|
||||
void contr_relay40m_init(void) {
|
||||
REG_SETUP_BIT(DDRB, PB0);
|
||||
}
|
||||
void contr_relay40m_on(void) {
|
||||
REG_SETUP_BIT(PORTB, PB0);
|
||||
}
|
||||
void contr_relay40m_off(void) {
|
||||
REG_SETDOWN_BIT(PORTB, PB0);
|
||||
}
|
||||
|
||||
/* D9 PB1: Set 80M relay 4 output */
|
||||
void contr_relay80m_init(void) {
|
||||
REG_SETUP_BIT(DDRB, PB1);
|
||||
}
|
||||
void contr_relay80m_on(void) {
|
||||
REG_SETUP_BIT(PORTB, PB1);
|
||||
}
|
||||
void contr_relay80m_off(void) {
|
||||
REG_SETDOWN_BIT(PORTB, PB1);
|
||||
}
|
||||
|
||||
/* D10 PB2: Set buzzer output */
|
||||
void contr_buzzer_init(void) {
|
||||
REG_SETUP_BIT(DDRB, PB2);
|
||||
}
|
||||
void contr_buzzer_on(void) {
|
||||
REG_SETUP_BIT(PORTB, PB2);
|
||||
}
|
||||
void contr_buzzer_off(void) {
|
||||
REG_SETDOWN_BIT(PORTB, PB2);
|
||||
}
|
||||
void contr_buzzer_onoff(void) {
|
||||
if (REG_BIT_VALUE(PINB, PB2)) {
|
||||
contr_buzzer_off();
|
||||
} else {
|
||||
contr_buzzer_on();
|
||||
}
|
||||
}
|
||||
|
||||
/* D12 PB4: Set fan output */
|
||||
void contr_fan_init(void) {
|
||||
REG_SETUP_BIT(DDRB, PB4);
|
||||
}
|
||||
void contr_fan_on(void) {
|
||||
REG_SETUP_BIT(PORTB, PB4);
|
||||
}
|
||||
void contr_fan_off(void) {
|
||||
REG_SETDOWN_BIT(PORTB, PB4);
|
||||
}
|
||||
void contr_fan_onoff(void) {
|
||||
if (REG_BIT_VALUE(PINB, PB4)) {
|
||||
contr_fan_off();
|
||||
} else {
|
||||
contr_fan_on();
|
||||
}
|
||||
}
|
||||
bool contr_fan_is_on(void) {
|
||||
if (REG_BIT_VALUE(PINB, PB4)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* D13 PB5: Set attenuator relay output */
|
||||
void contr_att_init(void) {
|
||||
REG_SETUP_BIT(DDRB, PB5);
|
||||
}
|
||||
void contr_att_on(void) {
|
||||
REG_SETUP_BIT(PORTB, PB5);
|
||||
}
|
||||
void contr_att_off(void) {
|
||||
REG_SETDOWN_BIT(PORTB, PB5);
|
||||
}
|
||||
|
||||
|
||||
void contr_adc_init() {
|
||||
/* Disable ADC */
|
||||
REG_SETDOWN_BIT(ADCSRA, ADEN);
|
||||
/* Set reference*/
|
||||
REG_SETUP_BIT(ADMUX, REFS0);
|
||||
REG_SETDOWN_BIT(ADMUX, REFS1);
|
||||
/* Set result type */
|
||||
REG_SETUP_BIT(ADMUX, ADLAR);
|
||||
/* Set freq prescale */
|
||||
REG_SETUP_BIT(ADCSRA, ADPS2);
|
||||
REG_SETUP_BIT(ADCSRA, ADPS1);
|
||||
REG_SETUP_BIT(ADCSRA, ADPS0);
|
||||
/* Disable autoconversion */
|
||||
REG_SETDOWN_BIT(ADCSRA, ADATE);
|
||||
/* Disable interrupt */
|
||||
REG_SETDOWN_BIT(ADCSRA, ADIE);
|
||||
/* Enable ADC */
|
||||
REG_SETUP_BIT(ADCSRA, ADEN);
|
||||
}
|
||||
|
||||
float contr_vcc_read(void) {
|
||||
REG_SETUP_BIT(ADMUX, MUX0);
|
||||
REG_SETUP_BIT(ADMUX, MUX1);
|
||||
REG_SETDOWN_BIT(ADMUX, MUX2);
|
||||
REG_SETDOWN_BIT(ADMUX, MUX3);
|
||||
|
||||
REG_SETUP_BIT(ADCSRA, ADSC);
|
||||
while (ADCSRA & BIT(ADSC));
|
||||
uint16_t lval = (uint16_t)ADCL;
|
||||
uint16_t hval = (uint16_t)ADCH;
|
||||
hval = (hval << 8) & 0xFF00;
|
||||
lval = lval & 0x00FF;
|
||||
|
||||
if (++contr.vccs_pos > VCCS_SIZE) contr.vccs_pos = 0;
|
||||
contr.vccs[contr.vccs_pos] = (hval | lval);
|
||||
uint32_t vcc = 0;
|
||||
uint8_t n = 0;
|
||||
for (size_t i = 0; i < VCCS_SIZE; i++) {
|
||||
if (contr.vccs[i]) {
|
||||
n++;
|
||||
vcc += contr.vccs[i];
|
||||
}
|
||||
}
|
||||
return (float)vcc / (float)n / 2673.0F;
|
||||
}
|
||||
|
||||
void contr_write_band(void) {
|
||||
eeprom_write_bytes(0x00, &contr.band, sizeof(contr.band));
|
||||
}
|
||||
|
||||
void contr_read_band(void) {
|
||||
eeprom_read_bytes(0x00, &contr.band, sizeof(contr.band));
|
||||
}
|
||||
|
||||
void contr_key_init(void) {
|
||||
/* D3 PD3: Set key input */
|
||||
REG_SETDOWN_BIT(DDRD, PD3);
|
||||
REG_SETUP_BIT(PORTD, PD3);
|
||||
}
|
||||
|
||||
bool contr_key_is_pressed(void) {
|
||||
if (REG_BIT_VALUE(PIND, PD3)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void contr_key_handle(void) {
|
||||
if (!contr.key_was_pressed) {
|
||||
if (contr_key_is_pressed()) {
|
||||
contr.key_time_counter++;
|
||||
contr.key_time_untap++;
|
||||
}
|
||||
if (contr.key_time_counter > 100) {
|
||||
contr.key_time_counter = 0;
|
||||
contr.key_was_pressed = true;
|
||||
}
|
||||
} else {
|
||||
if (!contr_key_is_pressed()) {
|
||||
contr.key_time_counter++;
|
||||
}
|
||||
if (contr.key_time_counter > 100) {
|
||||
contr.key_time_counter = 0;
|
||||
contr.key_was_pressed = false;
|
||||
contr.key_tap_counter++;
|
||||
contr.key_time_untap = 0;
|
||||
}
|
||||
}
|
||||
if (contr.key_tap_counter > 0) {
|
||||
contr.key_time_untap++;
|
||||
if (contr.key_time_untap > 2000) {
|
||||
contr.key_strokes_ended = true;
|
||||
}
|
||||
if (contr.key_time_untap > 5000) {
|
||||
contr.key_was_pressed = false;
|
||||
contr.key_tap_counter = 0;
|
||||
contr.key_time_untap = 0;
|
||||
contr.key_strokes_ended = false;
|
||||
}
|
||||
} else {
|
||||
contr.key_time_untap = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void contr_key_reset(void) {
|
||||
contr.key_was_pressed = false;
|
||||
contr.key_tap_counter = 0;
|
||||
contr.key_time_untap = 0;
|
||||
contr.key_strokes_ended = false;
|
||||
}
|
||||
Reference in New Issue
Block a user