//**********************************************************************
//            program pro rizeni TRXu - HLAVICKOVY SOUBOR
//**********************************************************************
// (c) OK1XGL 2005


#include <16F877.h>
#device ADC=8;
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,NOLVP,NOCPD
#use delay (clock=4000000,restart_wdt)


// LCD display
#define LCD_RS          PIN_D2        /* rizeni registru LCD displeje */
#define LCD_E           PIN_D3        /* enable LCD displeje */
#define LCD_DATA_LSB    PIN_D4        /* pripojeni LSB bitu datoveho portu LCD displeje (celkem 4 bity vzestupne za sebou) */
#define LCD_LED1        PIN_B5
#define LCD_LED2        PIN_B4

#define LCD_CHAR_a_FILL  "\x80\x80\x0E\x01\x0F\x1F\x0F\x80"      /* male a s s vyplnenym briskem */
#define LCD_CHAR_b_FILL  "\x10\x10\x16\x1F\x1F\x1F\x1E\x80"      /* male b s vyplnenym briskem */
#define LCD_CHAR_9_FILL  "\x0E\x1F\x1F\x0F\x01\x02\x0C\x80"      /* 9 s vyplnenym briskem */

// smimac polohy - ladeni
#define ENCODER_CLK     PIN_B0        /* musi zde byt ,je od nej preruseni */
#define ENCODER_DIR     PIN_B1

// tlacitka
#define KEY_ATN_KEY     PIN_C7
#define KEY_SPLIT_MNU   PIN_C4
#define KEY_A_B         PIN_C5
#define KEY_RIT_STEP    PIN_C6
#define KEYPORT         PORTC
// masky pro jednotlive funkce na tlacitkach
#define KEY_MASK        0b11110000    /* maska pouzitych tlacitek */
#define KEY_LONG        100           /* doba, po, ktere je povazuje stisk tlacitka za dlouhy v jednotkach zakladniho tiku  */

#define KEY_RIT         0b01000000    /* funkce RIT/STEP */
#define KEY_SPLIT       0b00010000    /* funkce SPLIT/MNU */
#define KEY_CHNGVFO     0b00100000    /* prepni VFO/srovnej VFO */
#define KEY_ATTN        0b10000000    /* nastav utlum/rychlost elbugu */


// tlg. klic
#define KEY_DASH        PIN_B6
#define KEY_DOT         PIN_B7

// ridici signaly TRXu
#define RXTX            PIN_B2      /* prepinac prijem vysilani 1= vysilani*/
#define KEYING          PIN_B3      /* klicovaci signal */
#define MUTE            PIN_C3      /* uzavira NF cestu pri vysilani */
#define TONE            PIN_C2      /* generovani tonu odposlechu NEMENIT!!! PWM1 je jen zde */
#define PWR_CTRL        PIN_C1      /* vystup PWM2 pro rizeni vystupniho vykonu PA NEMENIT !!!*/


// DDS signaly
#define  DDS_FSYNC      PIN_D0      /* enable prenosu dat aktivni v log0 */
#define  DDS_SCK        PIN_D5      /* musi zde byt, hodiny sestupna hrana */
#define  DDS_SDATA      PIN_D4      /* musi zde byt, seriova data */
#define  DDS_FSEL       PIN_D1      /* prepnuti frekvencnich registru */

// rizeni attenuatoru
#define  ATN1           PIN_E0
#define  ATN2           PIN_C0
#define  ATNC           PIN_E1
#define RELE_PULSE      10          /* delka prepinaciho pulzu pro rele v ms jednotkach */


// analogove vsupni signaly
#define  REF            PIN_A1
#define  FWD            PIN_A0
#define  MTR12V         PIN_A2
#define  SMTR           PIN_A3
#define  BAND           PIN_A5
// cisla pouzitych kanalu
#define  REF_CH         0
#define  FWD_CH         1
#define  MTR12V_CH      2
#define  SMTR_CH        3
#define  BND_CH         4


// konstanty verze programu
#define  NAME           "VERSION "
#define  VERSION        " V1.6   "

// konstanty timeru0
#define  TICK_TIME       0xFFFF-(5000/128)+1       /* zakladni tik TMR0 bude 5ms */
#define  UPDATE_TIME     10                        /* doba, po ktere se muze updatovat kde co v jedntkach tick_time */

// konstanty timeru2
#define  TONE_SET        0x4d                      /* konstanta urcujici kmitocet priposlechu, zde 800Hz */

// konstanty kmitoctu pro VFO
#define  CONVERT_CONST      5.36870912             /* 2^28/50000000 , tedy 2^28/kmitocet hodin DDS*/
#define  FREQ_IF            4999600L               /* kmitocet mezifrekvence v Hz */
#define  SUB_IF_INDEX            3                 /* index pasma, od ktereho se mezifrekvencni kmitocet odecita */
// zakladni nastaveni ridiciho registru DDS
#define  CTRL_FREQ0    0b0010000000000000          /* prepni se do freq0 */
#define  CTRL_FREQ1    0b0010100000000000          /* prepni se do freq1 */
#define  CTRL_RESET    0b0010000100000000          /* pozaduj reset */
#define  CLR_PHASE0    0b1100000000000000          /* nuluj fazovy registr 0 */
#define  CLR_PHASE1    0b1110000000000000          /* nuluj fazovy registr 1 */

#define  ENC_HISTEREZE     10                      /* necitlivost kroutitka pri nastavovani parametru v impulzech */

#define  BAND_NUM          4                       /* pocet pasem */
// tabulka meznich kmitoctu v Hz pro jednotliva pasma
int32 const BAND_LIMIT[BAND_NUM][2] = {
                                       //{1800000,2000000},
                                       {3500000,3620000},
                                       {7000000,7045000},
                                       {10100000,10150000},
                                       {14000000,14120000}
                                       //{18068000,18168000}
                                       //{21000000,21450000}
                                      };


int32 const START_FREQ[BAND_NUM] = {
                                       //1810000,
                                       3560000,
                                       7030000,
                                       10116000,
                                       14060000,
                                       //18096000,
                                       //21060000
                                   };

#define  RIT_STEP    10                            /* krok RITu v Hz */
signed int16 const RIT_LIMIT[2] = {-2000,2000};    /* rozsah RITu v Hz */

int16 const FREQ_STEP[2]={20,1000};                /* tabulka ladicich kroku v Hz */

// tabulka dekodovani pasma
#define  BAND_ADC_MASK           0b11100000
int8 const BAND_ADC[BAND_NUM]= {
                                 //0x00,            /* 160m */
                                 0x20,            /* 80m  */
                                 0x40,            /* 40m  */
                                 0x60,            /* 30m  */
                                 0x80             /* 20m  */
                                 //0x82,            /* 17m  */
                                 //0x84            /* 15m  */
                               };


// hodnoty napeti z prevodniku odpovidajici prislusnym S stupnum
int8 const S_METER[9]= {
                         0xC7,      /* S2 */
                         0xBA,      /* S3 */
                         0xA8,      /* S4 */
                         0x91,      /* S5 */
                         0x82,      /* S6 */
                         0x79,      /* S7 */
                         0x73,      /* S8 */
                         0x6C,      /* S9 */
                         0x60       /* S9 + cca 10dB */
                       };



// priznaky v promenne flags
#define  _DDS_UPDATE   flags,0                     /* pozadavek zmeny kmitoctu DDS */
#define  _LCD1_UPDATE  flags,1                     /* pozadavek aktualizace udaje v 1.radku LCD */
#define  _LCD2_UPDATE  flags,2                     /* pozadavek aktualizace udaje ve 2. radku LCD */
#define  _PAR_UPDATE   flags,3                     /* pozadavek aktualizace vybraneho parametru */
#define  _RIT          flags,4                     /* misto kmitoctu zobrazuj RIT */
#define  _SPLIT        flags,5                     /* zapnut rezim SPRIT */
#define  _TRANSMIT     flags,6                     /* je prepnuto na vysilani */
#define  _LED_UPDATE   flags,7                     /* zrcadlo stavu LED */
#define  _ENC_CHNG     flags,8                     /* doslo ke zmene polohy korutitka */
#define  _TXDELAY      flags,9                     /* bezi spozdeni mezi stiskem klice a zaklicovanim vysilace */
#define  _ATTN         flags,10                    /* je zapnuty utlum */
#define  _MNU          flags,11                    /* rezim nastavovani hodnoty parametru */
#define  _MNU2         flags,12                    /* rezim vyberu parametru */
#define  _RUN_VOX      flags,13                    /* bezi  vox timer */
#define  _BATT_LOW     flags,14                    /* baterie je vybita */
#define  _KEYING       flags,15                    /* je zaklicovan vysilac */

// priznaky promenne keys_flags
#define  _KEYS_LONG    keys_flags,0                /* tlacitko stisknuto po dlouhou dobu */
#define  _KEYS_VALID   keys_flags,1                /* tlacitka jsou platna */
#define  _KEYS_RELEASE keys_flags,2                /* cekej na uvolneni tlacitka = ukonceni reakce na tlacitko */

// priznaky promenne adc_flags
#define   _ADC_START   adc_flags,0                 /* spust_prevod */

// priznaky promenne elbug_flags
#define  _ELBUG_ON     elbug_flags,0               /* klicovani bude rizeno elbugem */
#define  _ELBUG_BSY    elbug_flags,1               /* probiha generovani signalu _ELBUG */
#define  _ELBUG_OUT    elbug_flags,2               /* vystup z elbugu */
#define  _ELBUG_SP     elbug_flags,3               /* priste vysilej mezeru */
#define  _ELBUG_DOT    elbug_flags,4               /* byla stisknuta paka tecek */
#define  _ELBUG_DASH   elbug_flags,5               /* byla stisknuta paka carek */
#define  _ELBUG_LAST   elbug_flags,6               /* minula stisknuta paka 0=dot 1=dash */
#define  _ELBUG_REV    elbug_flags,7               /* reverzni chapani pak */
#define  _ELBUG_REAL   elbug_flags,8               /* zapnuto realne klicovani */
#define  _ELBUG_ON_TMP elbug_flags,9               /* pro zapamatovani stavu _ELBUG_ON pri nastavovani vykonu */

// konstanta pro odmereni nejmensiho elementu elbugu (tecka nebo tez mezera)
#define  ELBUG_CONST    ((60*1000)/(5*5*2))*125    /* 60 - prevod na vteriny */
                                                   /* 1000 - prevod na ms    */
                                                   /* 5 - prevod WPM na LPM  */
                                                   /* 5 - pocet tecek v 1sec pro 200WPM */
                                                   /* 2 - zajima nas sirka tecky */
                                                   /* 125 - prevodni konstanta pro timer */

#define  PAR_NUM       7                           /* pocet parametru TRXu */
// cisla (indexy) parametru TRXu
// poradi urcuje poradi ve vyberovem menu
// parametry za volnym radkem v menu nejsou, vybiraji se na funkcnich tlacitkach
#define  PAR_POWER           0                     /* vykon vysilace */
#define  PAR_VOX             1                     /* doba prepnuti zpet na prijem */
#define  INF_BATT            2                     /* napeti baterie */
#define  PAR_KEYER_REV       3                     /* zap/vyp reverzni chapani pak */
#define  PAR_KEYER_MODE      4                     /* doplnkove nebo realne klicovani */

#define  PAR_KEYER           5                     /* rychlost elbugu */
#define  PAR_ATTN            6                     /* attenuator */



// tabulka mezi pro jednotlive parametry
int8 const  PAR_LIMIT[PAR_NUM][2] = {
                                      {0,16},      /* vykon ve  0.5w jednotkach */
                                      {0,40},      /* meze pro vox  v 50ms jednotkach */
                                      {0,0},       /* hodnota napeti baterie */
                                      {0,1},       /* meze pro zap/vyp reverzi pak */
                                      {0,1},       /* mod klicovani */
                                      {5,40},      /* meze pro elbug  ve WPM */
                                      {0,3}        /* meze pro attenuator  0,-6,-12 a -18dB */
                                    };

// adresy jednotlivych parametru ulozenych v eeprom
#define  EE_ADR_POWER         0                    /* BAND_NUM bajtu - pro kazde pasmo jeden bajt */
#define  EE_ADR_VOX           BAND_NUM
#define  EE_ADR_BATT          EE_ADR_VOX+1
#define  EE_ADR_KEYER_REV     EE_ADR_BATT+1
#define  EE_ADR_KEYER_MODE    EE_ADR_KEYER_REV+1
#define  EE_ADR_KEYER         EE_ADR_KEYER_MODE+1
#define  EE_ADR_ATTN          EE_ADR_KEYER+1
#define  EE_ADR_CRC           EE_ADR_ATTN+1        /* kontrolni soucet eeprom */

// pole adres parametru ulozenych v eeprom
int8  const EE_ADDR[PAR_NUM] = {
                           EE_ADR_POWER,
                           EE_ADR_VOX,
                           EE_ADR_BATT,           // napeti baterie se neuklada, zde je zapsana konstantni hodnota
                           EE_ADR_KEYER_REV,
                           EE_ADR_KEYER_MODE,
                           EE_ADR_KEYER,
                           EE_ADR_ATTN
                        };


#define  BATT_MIN       173               // napeti baterie, od ktere se povazuje za vybitou (hodnota z prevodniku pro 10.8V)
#define  BAD_PSV        18                // od PSV > 1.8 se omezi vykon
#define  PWR_LIM        10                // vykon pri spatnem psv je omezen na 1W
#define  PWM_MIN        27                // minimalni hodnota pro PWM2
#define  PWM_MAX        157               // maximalni hodnota pro PWM2
#define  PWR_HIST_LO    2                 // spodni povolena odchylka od pozadovaneho vykonu v nasobcich 100mW
#define  PWR_HIST_HI    1                 // horni povolena odchylka od pozadovaneho vykonu v nasobcich 100mW
#define  PWR_FWD_CONST  5600              // prevodni konstatna pro prevod napeti z ADC na vykon


int8              lcd_pos;                // poloha znaku na LCD pro specialni fce s nazvy xxx_lcd_putc
int32             freq_vfo[2];            // pozadovany kmitocet vfoA a vfoB
signed int16      freq_rit;               // rozladeni +- pri prijmu
signed int8       enc_delta;              // +-pocet impulzu zmeny kroutitka

int8              update_timer;           // periodicky casovac pro aktualizaci kde ceho
int8              key_timer;              // casovac pro rozpoznani dlouheho stisku tlacitka
int16             vox_timer;              // casovac pro automaticke prepnuti na prijem po urcite dobe bez vysilani
int16             vox_time;               // hodnota vox timeru, 0 = plny BK
int8              flash_timer;            // pro blikani ledkou pri vybite baterii

int8              keys;                   // obsahuje tlacitka, ktera byla stisknuta (0=klidovy stav)
int8              keys_work;              // pro precteni stavu tlacitek v preruseni
int8              keys_old;               // predchozi stav tlacitek, pro osetreni zakmitu
int8              keyer;                  // obsahuje stav stisknutych pak elbugu
int8              keyerb;                 // obsahuje aktualni stav pak elbugu

int1              step_index;             // index do tabulky moznych kroku ladeni
int1              vfo_index;              // index do tabulky VFO
int8              band_index;             // index do tabulky rozsahu kmitoctu

int16             flags;                  // stavove priznaky pro rizeni programu
int16             elbug_flags;            // stavove priznaky pro rizeni elbugu
int8              keys_flags;             // stavove priznaky tlacitek
int8              adc_flags;              // stavove priznaky pro rizeni ADC
int8              par[PAR_NUM];           // parametry TRXu
int8              par_index;              // cislo nastavovaneho parametru

int8              adc_ch;                 // citac kanalu ADC
int8              adc_val;                // napeti z ADC aktualniho kanalu
int8              smtr_val;               // hodnota napeti z ADC odpovidajici S-metru
int8              pwr_val;                // hodnota aktualniho vykonu v 100mW jednotkach
int8              psv_val;                // hodnota psv v desetinovych jednotkach
int8              fwd_val;                // napeti z ADC odpovidajici doprednemu vykonu
int8              rev_val;                // napeti z ADC odpovidajici odrazenemu vykonu
int8              bnd_val;                // napeti z ADC odpovidajici pasmu
int8              batt_val;               // napeti z ADC odpovidajici napeti baterie
int8              pwm_val;                // hodnota pro PWM2  - rizeni vykony PA
int8              power;                  // pozadovany vykon PA
int16             elbug_dot_sp;           // hotnota timeru 1 pro generovani tecky a mezery
int16             elbug_dash;             // hordnota timeru1 pro generovani carky


#bit _T0IF        = 0x0B.2                // priznak preteceni timeru0 - vyuziva se pri spousteni TXDELAY
                                          // (vyuziva se pro nej prave timer0) aby byla jistota, ze se TXDELAY
                                          // skutecne odmeri

#bit _TMR1IF      = 0x0C.0                // priznak preruseni od timeru 1 - pro vyprovokovani preteceni (start elbugu)
// End of File