/* * sekvencer.c * * Created: 18.4.2016 21:10:57 * Author: OK2MDK */ #define F_CPU 11059200UL //definice frekvence procesoru #include #include #include #include #include #define TRX_ALC_BLOCK() PORTC&=~(1<<2) //postav do 0 #define LNA_OFF() PORTC&=~(1<<1) #define PA_OFF() PORTC&=~(1<<0) #define TRX_ALC_UNBLOCK() PORTC|=(1<<2) #define LNA_ON() PORTC|=(1<<1) #define PA_ON() PORTC|=(1<<0) #define SW_LNA() ((PIND&16)==0) #define TL_PTT() ((PIND&8)==0) #define J1_TIME() ((PINC&16)==0) #define DC_OK() ((PINC&32)==0) #define LED_TX_OFF() PORTD|=(1<<2) #define LED_TX_ON() PORTD&=~(1<<2) #define LED_RX_OFF() PORTD|=(1<<0) #define LED_RX_ON() PORTD&=~(1<<0) #define LED_LNA_OFF() PORTD|=(1<<1) #define LED_LNA_ON() PORTD&=~(1<<1) #define DELAY_RELAY_ON 100 #define DELAY_RELAY_OFF 100 #define DELAY_PTT_PA_TRX 90 #define DELAY_PTT_OK_BURST 30 #define BURST_TIME 100 typedef enum { GO_RX = 0, RX, GO_TX, TX, } stav_ptt_t; stav_ptt_t ptt_state = GO_RX; int fault; /*Timer measure 1ms and handle burst protection*/ ISR(TIMER1_COMPA_vect) { static int delay = 0, flash = 0, divider = 0; static stav_ptt_t btn_ptt = RX; switch (btn_ptt) { case RX: if (ptt_state != RX) { ptt_state = GO_RX; } if (TL_PTT()) { btn_ptt = GO_TX; delay = 0; } break; case GO_TX: if (delay == BURST_TIME / 2) { } if (delay == BURST_TIME) { if (TL_PTT()) { btn_ptt = TX;// stisk potvrzen jdem vysílat fault = 0; if (ptt_state != TX && !fault) { ptt_state = GO_TX; } } else btn_ptt = RX;// stisk nepotvrzen navrat } break; case TX: if (!TL_PTT()) { btn_ptt = GO_RX; delay = 0; } break; case GO_RX: if (delay == BURST_TIME) { if (!TL_PTT()) btn_ptt = RX;// uvolneni potvrzeno else btn_ptt = TX; } break; } delay++; divider++; if (!(divider % 20)) { if (fault) { if (flash) { flash = 0; LED_TX_ON(); } else { flash = 1; LED_TX_OFF(); } } } } int main(void) { DDRD = 0x07; // in PORTD = 0xFF; //pull up DDRC = 0x0F; // out PORTC = 0xF0; // out log 0; OCR1A = 0x2B32; TCCR1B = (1 << CS10) | (1 << WGM12); TIMSK = (1 << OCIE1A); sei(); while (1) { /*Main loop handle change RX/TX sequence*/ switch (ptt_state) { case GO_TX: LNA_OFF(); if (!J1_TIME()) { fault = 1; if (DC_OK()) { _delay_ms(DELAY_PTT_OK_BURST); if (DC_OK()) { PA_ON(); _delay_ms(DELAY_PTT_PA_TRX); TRX_ALC_UNBLOCK(); ptt_state = TX; /*NEXT STATE = TX*/ LED_TX_ON(); fault = 0; } } } else { _delay_ms(DELAY_RELAY_OFF); PA_ON(); _delay_ms(DELAY_PTT_PA_TRX); TRX_ALC_UNBLOCK(); ptt_state = TX; /*NEXT STATE = TX*/ LED_TX_ON(); } LED_LNA_OFF(); LED_RX_OFF(); break; case TX: /*Wait, TX in progress*/ if (!J1_TIME() && !DC_OK()) { /*DC fault*/ ptt_state = GO_RX; /*ERROR = GO_RX*/ fault = 1; } break; case GO_RX: TRX_ALC_BLOCK(); _delay_ms(DELAY_PTT_PA_TRX); PA_OFF(); if (SW_LNA() && !fault) { _delay_ms(DELAY_RELAY_ON); LNA_ON(); } LED_TX_OFF(); LED_RX_ON(); ptt_state = RX; break; case RX: if (SW_LNA() && !fault) { // ON or OFF LNA LNA_ON(); LED_LNA_ON(); } else { LNA_OFF(); LED_LNA_OFF(); } break; default: ptt_state = GO_RX; // If any error go RX! break; } } }