 /**********************************************
*50MHz AMトランシーバー　PLL  VFO（DDSリファレンス）
* PIC24FJ64GA004   
* Ver 1.00 2019/5/2
* DSP AD9833 25MHz
* LCD DT018TFT 
* DSP IC KT0915
* 送受信周波数 50-51MHz MODE：AM USB LSB
* IF周波数：24MHz 
***********************************************/

#include <xc.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#define FCY 16000000UL// libpic30.hの前にFosc/2を定義　__delay関数用 32M/2
#include <libpic30.h> 
#include "font7.h"
#include "fontF30.h"

// コンフィギュレーション設定　Fosc=32MHz 内部OSC 8x4 PLL
#pragma config POSCMOD = NONE, I2C1SEL = PRI, IOL1WAY = OFF
#pragma config OSCIOFNC = ON, FCKSM = CSDCMD, FNOSC = FRCPLL
#pragma config WUTSEL = FST, IESO = OFF
#pragma config FWDTEN = OFF, ICS = PGx2, BKBUG = OFF
#pragma config GWRP = OFF, GCP = OFF, JTAGEN = OFF


#define WRT LATAbits.LATA2// Write=0 Normal=1
#define RES LATAbits.LATA1//RESET=0 Normal=1
#define RSL LATAbits.LATA0//Data=1 Command=0 Normal=1
#define TU100A  PORTAbits.RA8  //TUNE100A L:CCW H:CW  
#define TU100B  PORTAbits.RA4  //TUNE100B L:CCW H:CW
#define TU2500A  PORTAbits.RA3  //TUNE2500 A L:CCW H:CW
#define TU2500B  PORTCbits.RC2  //TUNE2500 B L:CCW H:CW INT2
#define VOLA  PORTCbits.RC1  //VOL A L:CCW H:CW  
#define VOLB  PORTCbits.RC0  //VOL B L:CCW H:CW INT1
#define MODEkey PORTBbits.RB15 // AM/USB/LSB
#define IWBkey PORTBbits.RB14 // IF Wide 4K/8K/12K
#define RITkey PORTAbits.RA7 //RIT on/off
#define CLEARkey PORTBbits.RB13 //RIT クリアー
#define SENDin PORTCbits.RC5 // SEND in H
#define SENDout LATAbitsLATA10//SEND out H
#define RLED  LATCbits.LATC9  //RED LED  ON:H
#define SPICE LATCbits.LATC6//SPI送信中L
#define BFO LATAbits.LATA9//BFO ON/OFF 1:ON
#define SENDP LATCbits.LATC3//SEND Pri out 1:ON
#define SENDOUT LATAbits.LATA10//SEND TX final out 1:ON

unsigned char lastIWB;
unsigned int Ritfreq,lastRitfreq;
char RIT,lastRIT,SEND;
char mojicolor,backcolor;
unsigned char font[40];

unsigned int V_level,lastV_level,MODE,IWB,Vmodu;
unsigned int FX,FY;//フォント表示の開始座標
unsigned int F_col,F_row;
unsigned long int DISPFREQ,lastDISPFREQ,BASEFREQ,lastFREQ,tempFREQ,IFFREQ;
unsigned long int DDSFREQ, RXDDSFREQ,TXDDSFREQ;
unsigned int FMf,MWf,SWf;
char lcd_digi[10];
unsigned int VL,lastFMfreq,lastMWfreq,lastSWfreq,last6mfreq,lastclearkey,lastritkey;

unsigned int AMSYSCFGB;
unsigned char lastmodekey = 1;
unsigned char lastIWBkey = 1;
unsigned char rbw[4]={4,4,8,12};
static char RE_table[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
static char lastRE = 0; 
//DSP レジスター定数
unsigned int SEEK= 0b0000000000000111;//0x02 FM 100KHz span R-mut/L-mut off
unsigned int TUNE= 0x8702;//0x03 FM normal Op FM low freq=89700KHz/50=1794+0x8000
unsigned int VOLUME= 0b1110000010000000;//0x04 FM/AM soft mute off Bass off pop mute full
unsigned int DSPCFGA= 0b1001000000000000;//0x05 FM mono 75uS 
unsigned int LOCFGA= 0b0000000000000000;//0x0A FM AFC on
unsigned int LOCFGC= 0b0000000000100100;//0x0C FM 64-110MHz
unsigned int RXCFG= 0b1000100000000000;//0x0F Stanby off Volume=0 bit4-0) 
unsigned int AMSYSCFG= 0b0000100101000011;//0x16 FM user Band 38KHz AF_gain 6dB AFC OFF
unsigned int AMCHAN= 0x0546;//0x17 AM1350KHz
unsigned int AMDSP= 0b0101010011000000;//0x22 BW (6-7) 2KHz:01 4KHz:10 6KHz:11
unsigned int AMCFG= 0b0001010000000001;//0x33 AM span (15-14) 1KHz:00 9KHz:01
unsigned int SOFTMUTE=0b1101111011110100;//0x2E 

double kd = 10.73741824; //kd = 1Hz x 2^28/25MHz  DDSへの周波数指定はHz単位

const unsigned char color[16][3]= {
	{0,0,0},//0 黒
	{255,0,0},//1　赤
	{0,255,0},//2　緑
	{0,100,255},//3　青
	{255,255,0},//4　黄
	{0,255,255},//5　シアン
	{255,0,255},//6　紫
	{255,255,255},//7　白
	{0,0,120},//8　紺
	{120,0,0},//9　茶
	{0,50,0},//10　深緑
	{120,120,0},//11　
	{0,30,50},//12
	{120,0,120},//13
	{60,60,60},//14
	{255,70,0}//15
};

//void mojidisp0( unsigned char* fc);
//void mojiretsudisp( char* str);
void mojiretsudisp7( char* str,char spn);

void initMain() {
 CLKDIV = 0x0000;
 AD1PCFG = 0b0000111111111111;//AN12有効
 AD1CON1 = 0b1010000000000010;
 AD1CON3 = 0b0000000100000000;
 I2C1CON = 0b1000000000000000; //I2Cイネーブル
 PORTB  = 0b0000000000000000; //全てL設定
 TRISB  = 0b1111111100000000;  //ポートB　0:出力　1:RB8-15input
 PORTA  = 0b0000000000000111; //RA0,1,2 Normal H
 TRISA   =0b0000000110111000; //ポートA　入力RA3,4,5,7,8
 PORTC  = 0b0000000000000000; //全てL出力
 TRISC  = 0b0000010000100111; //ポートC　入力RA0,1,2,5,10
 LATC   = 0b0000000011000000; //RC6,7 L active

 RPINR0bits.INT1R = 16;//INT1をRC0に割り当て VOL
 RPINR1bits.INT2R = 18;//UNT2をRC2に割り当てる TU2500
// RPOR11bits.RP22R = 9;//SDCE
 RPOR11bits.RP23R = 8;//SCK1 clock
 RPOR12bits.RP24R = 7;//SDO1 data
 RPOR10bits.RP20R = 18;//RP20にOC1を設定
	
 INTCON1 = 0b0000000000000000;//割込みネスト（多重割り込み）
 INTCON2 = 0b0000000000000110;//INT1,INT2立下りで割り込み	
 
 IPC5bits.INT1IP = 3;IPC7bits.INT2IP = 3;//外部割込み優先順位3
 IFS1bits.INT1IF = 0;IFS1bits.INT2IF = 0;//割込みフラグクリアー
 IEC1bits.INT1IE = 1;IEC1bits.INT2IE = 1;//外部割込み許可
	
 SPI1CON1 = 0b0000011101110010;//マスターモード プライマリ1/4、セカンダリ1/4、クロックactive_L
 SPI1CON2 = 0b0000000000000000;//
 SPI1STATbits.SPIROV = 0;
 SPI1STATbits.SPIEN = 1;//SPI1有効化
    
 I2C1BRG = 157; //100KHz fosc/2=16MHz
 I2C1MSK = 0;
 T1CON = 0b0000000000100000;//Timer1：プリスケーラー1/64 クロック：fosc/2  
    PR1 = 1000;//T1 カウントmax 1msごとに割り込み発生
    TMR1 = 0;//T1レジスタクリア
    IPC0bits.T1IP = 3;//t1 割込み優先度　3
    IFS0bits.T1IF = 0;//t1 割込みフラグクリア
    IEC0bits.T1IE = 1;//t1 割込み許可
    T1CONbits.TON = 1;// ti タイマースタート

 AD1PCFG = 0b1110111111111111;//AN12 ON
 AD1CON1 = 0b1000000011100000;//AD ON
 AD1CON2 = 0b0000010000000000;//FIFO使用　入力12chをスキャン　MUX-Aのみ使う
 AD1CON3 = 0b0001111100000111;//31TAD 7Tcy
 AD1CSSL = 0b0001000000000000;//AN12 SCAN有効
 AD1CHS = 0b000000000001100;//スキャン開始AN0　負側入力Vss
 AD1CON1bits.ADON =1;
  T2CON = 0x000;
	PR2 = 799;//DA変換周期0.05m秒
	OC1CON = 0x0006;// timer2 periscale 1:1 内部クロック
	OC1RS = 700;//PWM Lになるカウンター値　変するとDC出力が変化する
    OC1R = 0;
	//T2CONbits.TON = 1;//timer2 スタート PWM中止

}


void lcd_CMD(unsigned char CM) {//1-byteコマンド
	RSL = 0;//LCD RS
	WRT = 0;
	LATB =CM;
	WRT = 1;
	RSL = 1;
}
void lcd_DATA(unsigned char DA) {
	WRT = 0;
	LATB = DA;
	WRT = 1;
}
void init_LCD() {
	lcd_CMD(0x01);//ソフトリセット
	__delay_ms(120) ;
	lcd_CMD(0x11);//Sleep Out
	__delay_ms(120) ;
	lcd_CMD(0x36);
	lcd_DATA(0xC8);
	lcd_CMD(0x2A);
	lcd_DATA(0x00);
	lcd_DATA(0x00);
	lcd_DATA(0x00);
	lcd_DATA(0x9F);
	lcd_CMD(0x2B);
	lcd_DATA(0x00);
	lcd_DATA(0x00);
	lcd_DATA(0x00);
	lcd_DATA(0x7F);
	lcd_CMD(0x36);
//	lcd_DATA(0xAC);
    lcd_DATA(0x7C);//LCD方向反転
//	lcd_CMD(0x29);//Display ON
	lcd_CMD(0x2C);
	__delay_ms(200) ;
	
}

void set_col_range(unsigned int start, unsigned int end) {//行範囲の指定
	lcd_CMD(0x2A);  
	lcd_DATA(start >> 8);
	lcd_DATA(start);
	lcd_DATA(end >> 8);
	lcd_DATA(end);
	}
void set_row_range(unsigned int start, unsigned int end) {//列範囲の指定
	lcd_CMD(0x2B);  
	lcd_DATA(start >> 8);
	lcd_DATA(start);
	lcd_DATA(end >> 8);
	lcd_DATA(end);
	}


void write_color(unsigned char C) {
	lcd_DATA(color[C][0]);
	lcd_DATA(color[C][1]);
	lcd_DATA(color[C][2]);
	
}
void itostring(unsigned char digit, unsigned long int data,  char *buffer) {
	unsigned char i;
    char j=digit;
	buffer +=j;
	*buffer =0;					// 最後の数字位置
	for(i=digit; i>0; i--) {			// 変換は下位から上位へ
            buffer--;					// ポインター１
            *buffer = (data % 10) + '0';	// ASCIIへ
            data = data / 10;				// 次の桁へ
	}
}
void mojidisp0( void *fp) {
    const unsigned char *fc = (const unsigned char*)fp;
	unsigned int k;
	unsigned int x,y,m;
 	set_col_range(FX,FX+F_col);
 	set_row_range(FY,FY+F_row);
 	lcd_CMD(0x2C);//色データ書き込み
        m=0;
 	for (y=0;y<=F_row;y++) {
 		for (x=0;x<=F_col;x++) {
 			k=(*fc) & (1<<(7-m));
 				if (k>0) {
                    write_color(mojicolor);//文字色
 				} else {
                    write_color(backcolor);//背景色
 				}
                        m++;
                        if (m>7) {
                            m=0;
                            if (x < F_col) {fc++;}
                        }
 			}
                m=0;fc++;
 	}
}

void mojidisp1(unsigned char ch) {
	unsigned char k;
    const unsigned char *fc;
	int x,y;
 	set_col_range(FX,FX+F_col);
 	set_row_range(FY,FY+F_row);
 	lcd_CMD(0x2C);//色データ書き込み
	fc = Font1_table[ch];
 	for (y=0;y<=F_row;y++) {
 		for (x=0;x<=F_col;x++) {
 			k=(*fc) & (1<<(F_col-x));
 				if (k>0) {
                    write_color(mojicolor);//文字色
 
 				} else {
                    write_color(backcolor);//背景色

 				}
 			}
 		fc++;
 	}
	FX=FX+F_col+2;
}

void mojidisp7(unsigned char ch,char spn) {
	unsigned char k;
    const unsigned char *fc;
	int x,y;
 	set_col_range(FX,FX+F_col);
 	set_row_range(FY,FY+F_row);
 	lcd_CMD(0x2C);//色データ書き込み
	fc = Font7_table[ch];
 	for (y=0;y<=F_row;y++) {
 		for (x=0;x<=F_col;x++) {
 			k=(*fc) & (1<<(F_col-x));
 				if (k>0) {
                    write_color(mojicolor);//文字色
 				} else {
 					write_color(backcolor);//背景色
 				
 				}
 			}
 		fc++;
 	}
	FX=FX+F_col+spn;
}
void mojiretsudisp1( char *str) {
    unsigned char i;
    char len;
	len = strlen(str);
	for (i=0;i<len;i++) {
		mojidisp1(str[i]);
	}
}

void mojiretsudisp7( char *str,char spn) {
    unsigned char i;
    char len;
	len = strlen(str);
	for (i=0;i<len;i++) {
		mojidisp7(str[i],spn);
	}
}
void write_line(unsigned char xs,unsigned char ys,unsigned char xe,unsigned char ye,unsigned char c) {
    unsigned char i,j;
    set_col_range(xs,xe);
    set_row_range(ys,ye);
    lcd_CMD(0x2C);//色データ書き込み
    for (i=ys;i<=ye;i++) {
        for (j=xs;j<=xe;j++) {
            write_color(c);
        }
    }
}


void write_dots(int x,int y,int d,char c) {//x:ｘ座標　y:y座標　d:線幅　c:色番号
	int i,j;
	set_col_range(x,x+d);
 	set_row_range(y,y+d);
	lcd_CMD(0x2C);//色データ書き込み
	for (i=x;i<x+d;i++) {
 		for (j=y;j<=y+d;j++) {
 			write_color(c);//文字色
 		}
	}
}
void select_font(unsigned int F) {
    switch (F) {
        case 1:F_col=4;F_row=7;break;//実際のXYドット数からマイナス１した数値
        case 2:F_col=6;F_row=12;break;
        case 3:F_col=11;F_row=11;break;
        case 4:F_col=41;F_row=11;break;
        case 5:F_col=14;F_row=4;break;//FontKHz MHz
        case 6:F_col=3;F_row=6;break;
        case 7:F_col=5;F_row=9;break;
        case 10:F_col=11;F_row=21;break;//FREQ
        default:F_col=4;F_row=7;break;
    }
}
void mojidispF(unsigned char ch) {
	int k;
        const unsigned char *fc;
	int x,y,m;
 	set_col_range(FX,FX+F_col);
 	set_row_range(FY,FY+F_row);
 	lcd_CMD(0x2C);//色データ書き込み
	fc = FontF30_table[ch];
        m=0;
 	for (y=0;y<=F_row;y++) {
 		for (x=0;x<=F_col;x++) {
 			k=(*fc) & (1<<(7-m));
 				if (k>0) {
                    write_color(mojicolor);
 					//lcd_DATA(color[mojicolor]);//文字色
 				} else {
                    write_color(backcolor);
 					//lcd_DATA(color[backcolor]);//背景色
 				}
                        m++;
                        if (m>7) {m=0;if (x<F_col) {fc++;}}
 			}
                m=0;
 		fc++;
 	}
	FX=FX+F_col+5;
}
void Freqdisp(unsigned char dg,unsigned long int su) {
  unsigned long int k,s,sd;
    unsigned char m,n,z,w;
      unsigned char i,j;
      n=dg;s=su;k=1;z=1;sd=su;
      for (j=dg;j>0;j--) {
	for (i=n;i>1;i--) { k=10*k; }
        m=s/k;w=m;
        if (m>0) { z=2;}
        if (z==1) {w=10;}
        mojidispF(w);
        s=s-m*k;
        n--;
        k=1;
      }
}
void setdispfreq() {

 select_font(10);//FontF
 mojicolor=5;

    FX=5;FY=5;
    Freqdisp(6,DISPFREQ/10);// LCD 表示は1/10とし、最下位は100Hz
    write_dots(34,27,2,5);
    write_dots(82,27,2,5);
    
    select_font(5);//Font MHz KHzを選択
    mojicolor=5;
    backcolor = 0;
    FX=28;FY=32;
    mojidisp0(&Font5_MHz);
    FX=76;FY=32;
    mojidisp0(&Font5_KHz);
 	
}

void makefreq() {
	unsigned long int Fdisp,RFq;
    RFq = Ritfreq;
    lastDISPFREQ = DISPFREQ;
    if (RIT == 1) {DISPFREQ = BASEFREQ + RFq - 1000;} else {DISPFREQ = BASEFREQ;}
    if (SEND == 1) {DISPFREQ = BASEFREQ;}
	RXDDSFREQ = DISPFREQ - IFFREQ;
    TXDDSFREQ = DISPFREQ / 2;
}

void integerdisp7(unsigned int x, unsigned int y,unsigned char degi, unsigned long int num,unsigned char spn) {
    FX=x;FY=y;
    itostring(degi,num,lcd_digi);//ASCIIに変換
    mojiretsudisp7(lcd_digi,spn);
}



//***************************************************************
//I2C関数
//***************************************************************

void i2c_start() {
    I2C1CONbits.SEN = 1; //スタート条件開始
    while (I2C1CONbits.SEN) {
        //スタート終了待ち
    }
}

void i2c_restart() {
    I2C1CONbits.RSEN = 1; //リスタート条件開始
    while (I2C1CONbits.RSEN) {
        //リスタート終了待ち
    }
}

void i2c_stop() {
    I2C1CONbits.PEN = 1; //ストップ条件開始
    while (I2C1CONbits.PEN) {
        //ストップコンディション終了待ち
    }
}

void i2c_send(unsigned char data) {

    I2C1TRN = data;//dataをレジスタにセット。送信開始
    while (I2C1STATbits.TRSTAT) {
        //データの送信終了待ち
    }
}

// DDS 書き込み
void DDSwrite(unsigned int data) {
//	IFS0bits.SPI1IF = 0;
    SPICE = 0; //DDS FSYNC 0(CEをL)  
    __delay_us(1);
	SPI1BUF = data;

//	while(!IFS0bits.SPI1IF);
    __delay_us(20);
	SPICE = 1; // CEをH
}

void DDSFREQwrite(unsigned long int FQ, unsigned char ML) {
	//return;
	unsigned long int Freg;
	unsigned int MLset,MFreg,LFreg;
	double DFreg;
	if (ML == 0) {MLset = 0x4000;} else {MLset = 0x8000;}
    DFreg = FQ;
	Freg = (double) (DFreg * kd); //Freg = DFreg;
	MFreg = (Freg >> 14) + MLset;
	LFreg = (Freg & 0x00003FFF) + MLset;
	DDSwrite(LFreg);
    __delay_us(10);
	DDSwrite(MFreg);
}

void initDDS(unsigned long int F) {
	DDSwrite(0x2100);//DDS reset
	DDSwrite(0xC000);//PHASE0 0
	DDSwrite(0xE000);//PHASE1 0
	DDSwrite(0x2000);//16bit連続2回送信にて周波数確定
	DDSFREQwrite(F,0);//reg0に1MHz書き込み
	DDSFREQwrite(F,1);//reg1に1MHz書き込み
}	





//DSP書き込み

void writeDSP(unsigned char address, unsigned int data) {
    unsigned char wca, dataL,dataH;
    wca = 0x6A;
	dataL = data;//dataの下位8bit
	dataH = data >> 8;//dataの上位8bit
  
    //書き込み開始
    i2c_start();
    i2c_send(wca); //DSP書き込み用チップアドレス
    i2c_send(address); //レジスタアドレス
    i2c_send(dataH); //上位データ
    i2c_send(dataL); //下位データ
    i2c_stop();
    
}

//DSP読み出し（返り値：int読み出し値）

unsigned int readDSP(unsigned char address) {
    unsigned char rca,wca;
	unsigned int data;
    rca = 0x6B;wca = 0x6A;

    //読み出し開始
    i2c_start();
    i2c_send(wca); //DSP書き込みチップアドレス
    i2c_send(address); //レジスタアドレス
    i2c_start();
    i2c_send(rca); //DSP読み出し用チップアドレス
    
    I2C1CONbits.RCEN = 1; //データ受信
    while (I2C1CONbits.RCEN) {}  //受信終了待ち
	data = I2C1RCV; data = data << 8;
	I2C1CONbits.RCEN = 1; //データ受信
    while (I2C1CONbits.RCEN) {}  //受信終了待ち
	data = data | I2C1RCV;
    i2c_stop();
    return data; //DSP読み出し値を返り値にセット
}
void DSPinit() {
    unsigned int Rdata;

	writeDSP(0x04,VOLUME);
	writeDSP(0x05,DSPCFGA);

	writeDSP(0x0F,RXCFG);

    writeDSP (0x2E,SOFTMUTE);
    Rdata=readDSP(0x22);

    writeDSP(0x22,(Rdata & 0xF0FF) | 0x0200);
    Rdata=readDSP(0x0A);
    writeDSP(0x0A,Rdata & 0x0400);
    Rdata=readDSP(0x22);

    writeDSP(0x22,Rdata & 0xF0DF | 0x0240);

    Rdata=readDSP(0x3F);
    writeDSP(0x3F,(Rdata & 0xFF88) | 0x0013);
}

void DSPIFBWset(unsigned char bw) {
    unsigned int b,Rdata;
    b=bw<<6;
    Rdata=readDSP(0x22);
    writeDSP(0x22,(Rdata & 0xFF1F) | b); 
}



void DSPIFset(unsigned char md) {
	unsigned int ifq,AMf;
	ifq=IFFREQ/100-2;
	 switch (md) {
	 	case 0: DSPIFBWset(IWB);BFO=0;break;
        case 1: ifq=ifq + 2;DSPIFBWset(1);BFO=1;break;
	 	case 2: ifq=ifq - 2;DSPIFBWset(1);BFO=1;break;
	 	default: DSPIFBWset(IWB);BFO=0;break;
    	}

        AMSYSCFGB = AMSYSCFG | 0x8000;
        AMf=0x8000+ifq;
        writeDSP(0x16,AMSYSCFGB);
    	writeDSP(0x17,AMf);
}

char getCLEARkeySw(){
 	char sw,last,cnt;
 	cnt=0;
 	last= CLEARkey; //CLEAR スイッチの接続ポート
	while(cnt < 80){
		__delay_us(500);
 		sw=CLEARkey;
 		if(last == sw){ // 前回の状態と比較
			cnt++; //安定状態
 			}else{
			cnt=0; //チャタリング発生中
 			}
 		last=sw; // 今の状態を前回の状態とする
 		}
	return sw;
 	}

char getRITkeySw(){
 	char sw,last,cnt;
 	cnt=0;
 	last= RITkey; //RIT スイッチの接続ポート
	while(cnt < 80){
		__delay_us(500);
 		sw=RITkey;
 		if(last == sw){ // 前回の状態と比較
			cnt++; //安定状態
 			}else{
			cnt=0; //チャタリング発生中
 			}
 		last=sw; // 今の状態を前回の状態とする
 		}
	return sw;
 	}

char getMODEkeySw(){
 	char sw,last,cnt;
 	cnt=0;
 	last= MODEkey; //MODE スイッチの接続ポート
	while(cnt < 80){
		__delay_us(500);
 		sw=MODEkey;
 		if(last == sw){ // 前回の状態と比較
			cnt++; //安定状態
 			}else{
			cnt=0; //チャタリング発生中
 			}
 		last=sw; // 今の状態を前回の状態とする
 		}
	return sw;
 	}
char getIWBkeySw(){
 	char sw,last,cnt;
 	cnt=0;
 	last= IWBkey; //BAND幅 スイッチの接続ポート
	while(cnt < 60){
		__delay_us(500);
 		sw=IWBkey;
 		if(last == sw){ // 前回の状態と比較
			cnt++; //安定状態
 			}else{
			cnt=0; //チャタリング発生中
 			}
 		last=sw; // 今の状態を前回の状態とする
 		}
	return sw;
 	}
 	
void CLEARcheck() {
	char sw;
	if (CLEARkey == 1) {lastclearkey = 1; return;}
	if (CLEARkey == lastclearkey) { return; }
	
	sw=getCLEARkeySw(); // チャタリング除去済のスイッチ状態
    lastclearkey=sw;
    if( (0 ==sw) && (CLEARkey==0) ){ // スイッチが押されて、かつ現在ON
		
        Ritfreq = 1000;
		}
	}
 
 void RITcheck() {
	char sw;
	if (RITkey == 1) {lastritkey = 1; return;}
	if (RITkey == lastritkey) { return; }
	
	sw=getRITkeySw(); // チャタリング除去済のスイッチ状態
    lastritkey=sw;
    if( (0 ==sw) && (RITkey==0) ){ // スイッチが押されて、かつ現在ON
		
        if (RIT == 0) {RIT = 1;} else {RIT = 0;}// 0:Rit off 1:Rit on
		}
	}
 
void MODEcheck() {
	char sw;
	if (MODEkey == 1) {lastmodekey = 1; return;}
	if (MODEkey == lastmodekey) { return; }
	
	sw=getMODEkeySw(); // チャタリング除去済のスイッチ状態
    lastmodekey=sw;
    if( (0 ==sw) && (MODEkey==0) ){ // スイッチが押されて、かつ現在ON
		MODE++;
        if (MODE > 2) {MODE=0;}// 0:AM 1:USB 2:LSB
		}
	}
void IWBcheck() {
	char sw;
	if (IWBkey == 1) {lastIWBkey = 1; return;}
	if (IWBkey == lastIWBkey) { return; }
	
	sw=getIWBkeySw(); // チャタリング除去済のスイッチ状態
    lastIWBkey=sw;
	if( (0 ==sw) && (IWBkey==0) ){ // スイッチが押されて、かつ現在ON
		IWB++;
        if (IWB > 3) {IWB=1;}// 1:4KHz 2:8KHz 3:12KHz
        }
    //lastIWB = IWB;
   
	}


unsigned int takeADdata() {
  	unsigned int adv;
    AD1CON1bits.SAMP = 1;//AD Start
    while (!AD1CON1bits.DONE);
//    __delay_us(100);
    adv =  ADC1BUF0;//選択したのがAN12のみなので、AN12のデータはBUF0に格納される
	adv = adv/4;
	return adv;
}



void ritdisplay(char e) {//e:0 Rit表示消去　1:Rit表示
	if (e == 1) {
    	write_line(110,5,150,17,1);
    	write_line(110,5,110,39,1);
    	write_line(150,5,150,39,1);
    	write_line(110,39,150,39,1);
    	select_font(1);//Font1を選択
    	backcolor = 1;
    	FX=123;FY=7;
    	mojiretsudisp1("RIT");
    	backcolor = 0;
    	select_font(5);//Font5を選択
     	FX=125;FY=32;
    	mojidisp0(&Font5_KHz);
		} else {
		write_line(110,5,150,39,0);
        write_line(110,5,150,5,14);
        write_line(110,5,110,39,14);
    	write_line(150,5,150,39,14);
    	write_line(110,39,150,39,14);
        mojicolor = 14;backcolor = 0;
        select_font(1);
    	FX=123;FY=8;
    	mojiretsudisp1("OFF");
	}
}

void actritfreq(unsigned int df) {
	unsigned char d;
   // d = df/10;
    select_font(7);//Font7を選択
    backcolor = 0;
        
    FX=115;FY=20;
    if (df < 1000) {
        mojiretsudisp7("-",2); d=(1000-df)/10;} else {
        if (df > 1000) {mojiretsudisp7("+",2);d=(df-1000)/10;} else {
        mojiretsudisp7(" ",2);d=df/10;}
        }
        select_font(7);//Font7を選択
        mojicolor=5;
    integerdisp7(125,20,2,d,7); 
    write_dots(133,29,1,5);
}
void dispModMeter() {
	write_line(24,61,158,72,0);
    select_font(7);//Font7を選択
    mojicolor=7;
    FX=10;FY=58;mojiretsudisp7("M",2);
    write_line(25,72,87,72,7);
    write_line(88,72,149,72,3);
    write_line(27,69,27,72,7);
    write_line(39,69,39,72,7);
    write_line(51,69,51,72,7);
    write_line(63,69,63,72,7);
    write_line(75,69,75,72,7);
    write_line(87,69,87,72,7);
    write_line(99,69,99,72,7);
    write_line(111,69,111,72,7);
    write_line(123,69,123,72,7);
    write_line(135,69,135,72,7);
    write_line(147,69,147,72,7);
    select_font(1);//Font1を選択
    mojicolor=7;
    FX=24;FY=61;mojiretsudisp1("0");
    FX=45;FY=61;mojiretsudisp1("20");
    FX=70;FY=61;mojiretsudisp1("40");
    FX=94;FY=61;mojiretsudisp1("60");
    FX=118;FY=61;mojiretsudisp1("80");
    mojicolor=1;
    FX=140;FY=61;mojiretsudisp1("100");

    
}
void actModMeter(unsigned char s) {
    unsigned char sm;
    //mojicolor=4;
    if (s >124) {sm=124;} else {sm=s;}
   write_line(25,50,25+sm,58,15); 
   write_line(26+sm,50,149,58,0);
}
void dispSmeter() {
	write_line(24,61,158,72,0);
    select_font(7);//Font7を選択
    mojicolor=5;
    FX=10;FY=58;mojiretsudisp7("S",2);
    write_line(25,72,87,72,7);
    write_line(88,72,149,72,3);
    write_line(27,69,27,72,7);
    write_line(42,69,42,72,7);
    write_line(57,69,57,72,7);
    write_line(72,69,72,72,7);
    write_line(87,69,87,72,7);
    write_line(107,69,107,72,3);
    write_line(127,69,127,72,3);
    write_line(147,69,147,72,3);
    select_font(1);//Font1を選択
    mojicolor=5;
    FX=24;FY=61;mojiretsudisp1("1");
    FX=39;FY=61;mojiretsudisp1("3");
    FX=55;FY=61;mojiretsudisp1("5");
    FX=69;FY=61;mojiretsudisp1("7");
    FX=84;FY=61;mojiretsudisp1("9");
    mojicolor=3;
    FX=101;FY=61;mojiretsudisp1("20");
    FX=121;FY=61;mojiretsudisp1("40");
    FX=141;FY=61;mojiretsudisp1("60");
    
}
void actSMeter(unsigned char s) {
    unsigned char sm;
    //mojicolor=4;
    if (s >124) {sm=124;} else {sm=s;}
   write_line(25,50,25+sm,58,4); 
   write_line(26+sm,50,149,58,0);
}
void disppannel(){
   write_line(0,43,159,43,8);
   write_line(0,43,0,127,8);
   write_line(159,43,159,127,8);
   write_line(0,127,159,127,8);
	
	write_line(110,105,154,124,12);//MODE表示エリア
	select_font(1);//Font1を選択
	mojicolor=7;backcolor = 0;
   	FX=121;FY=94;
   	mojiretsudisp1("MODE");
	
	write_line(60,105,100,124,10);//IF-WB表示エリア
	select_font(1);//Font1を選択
   mojicolor=7;backcolor = 0;
   
   FX=65;FY=94;
   mojiretsudisp1("IF-BW");
   backcolor = 10;
    select_font(5);//Font5を選択
     FX=82;FY=115;
    mojidisp0(&Font5_KHz);
}
void dispvolume() {
   select_font(1);//Font7を選択
   mojicolor=3;backcolor=0;
   FX=134;FY=81;
   mojiretsudisp1("MAX"); 
   select_font(7);//Font7を選択
   mojicolor=3;
   FX=5;FY=79;
   mojiretsudisp7("VOL",3);
}
void actVolume(unsigned char vr) {
   write_line(35,79,35+(vr*3),87,8); 
   write_line(36+(vr*3),79,131,87,0);
   
}
void dispsend(unsigned char s) {
	if (s == 1) {
   		write_line(10,105,50,124,1);
   		select_font(7);//Font7を選択
   		mojicolor=7;backcolor = 1;
   		FX=15;FY=110;
   		mojiretsudisp7("SEND",3);
   		backcolor = 0;
	} else {
		write_line(10,105,50,124,0);
	}
}
void dispIBW(unsigned char b) {

   mojicolor=7;backcolor = 10;

   select_font(7);//Font7を選択
    integerdisp7(67,110,2,rbw[b],3);//b=1:4KHz 2:8KHz 3:12KHz
    
    backcolor = 0;
}
void dispmode(unsigned char m) {
    write_line(110,105,154,124,8);
	mojicolor = 7;backcolor = 8;
   	select_font(7);//Font7を選択
	switch (m) {
		case 1:FX=122;FY=110;mojiretsudisp7("USB",3);break;//USB表示
		case 2:FX=122;FY=110;mojiretsudisp7("LSB",3);break;//LSB表示
        default:FX=125;FY=110;mojiretsudisp7("AM",3);break;//AM表示
    }
    backcolor = 0;
}
void __attribute__((__interrupt__,__no_auto_psv__)) _INT2Interrupt(void){
 //   lastFREQ=BASEFREQ;
 IFS1bits.INT2IF = 0;
 IEC1bits.INT2IE = 0;

       if (TU2500A == 1) {
            if (BASEFREQ < 5100000) {BASEFREQ = 4*BASEFREQ +1000;BASEFREQ = BASEFREQ / 1000;BASEFREQ = BASEFREQ * 250;}}
		
 		if (TU2500A ==0) {
			if (BASEFREQ > 5000000) {
                BASEFREQ = 4*BASEFREQ;
                tempFREQ = BASEFREQ /1000; tempFREQ =  tempFREQ * 1000;
                if ((BASEFREQ - tempFREQ) != 0) {BASEFREQ = BASEFREQ + 1000;} 
                BASEFREQ = BASEFREQ - 1000;BASEFREQ = BASEFREQ / 1000;BASEFREQ = BASEFREQ * 250;
                }
       		}
		
	__delay_ms(1);  
 
 IEC1bits.INT2IE = 1;
}
void __attribute__((__interrupt__,__no_auto_psv__)) _INT1Interrupt(void){
    lastV_level=V_level;
 IFS1bits.INT1IF = 0;
 IEC1bits.INT1IE = 0;
        if (VOLA == 1) {
			if (V_level < 31) {V_level = V_level+1;}
		}
		if (VOLA == 0) {
			if (V_level > 0) {V_level = V_level-1;}
		}
	__delay_ms(1); 
 IEC1bits.INT1IE = 1;
}

void __attribute__((__interrupt__,__no_auto_psv__)) _T1Interrupt(void){
        unsigned char k;          
    	char curRE;
 IFS0bits.T1IF = 0;
 IEC0bits.T1IE = 0;
  T1CONbits.TON = 0;// ti タイマー1 Stop
	curRE = TU100B * 2 + TU100A;    
    lastRE <<= 2;                      
    lastRE |= ( curRE & 0x03 ); 
    k = (RE_table[(lastRE & 0x0F)]);
    if (RIT == 0) {
        if ((k == 1) && (BASEFREQ < 5100000) ){BASEFREQ = BASEFREQ + 1;} 
        if ((k == 255) && (BASEFREQ > 5000000)){BASEFREQ = BASEFREQ - 1;}
    } else {
        if ((k == 1) && (Ritfreq < 1999) ){lastRitfreq =Ritfreq;Ritfreq = Ritfreq + 1;} 
        if ((k == 255) && (Ritfreq > 2)){lastRitfreq =Ritfreq;Ritfreq = Ritfreq - 1;}
    }
 TMR1 = 0;
  T1CONbits.TON = 1;// ti タイマー1スタート

 IEC0bits.T1IE = 1;
 
}


int main()  {




 unsigned char i,j,lastMODE,lastSEND;
 unsigned int Sdata;
 	
 initMain();//メインイニシャライズ
 RLED =0;RIT = 0;
//__delay_ms(100) ;
 RES = 0; //LCD H/Wリセット
 __delay_ms(120) ;
 RES = 1;
 __delay_ms(100) ;
 init_LCD();//LCD初期設定


 //***********************************画面クリアー（backcolorで全面塗りつぶし）
	backcolor = 0;	
	lcd_CMD(0x2C);//色データ書き込み
 	for (i=0;i<160;i++) {
 		for (j=0;j<128;j++) {
 			write_color(backcolor);//背景色
 		}
 	}
 	lcd_CMD(0x29);//Display ON
    dispSmeter();
    
    DISPFREQ = 5050000;BASEFREQ = DISPFREQ;//最小桁10Hz
	IFFREQ = 2400000;//最小桁10Hz
    RXDDSFREQ = DISPFREQ - IFFREQ;TXDDSFREQ = DISPFREQ / 2;
    Ritfreq = 1000;//オフセット周波数　1000にてRIT　0Hz
    lastRitfreq = Ritfreq;
    V_level=10;lastV_level = V_level;// VOLレベル初期設定10
    RIT =0;lastRIT = RIT;
    IWB = 2;lastIWB = IWB;// IFバンド幅　初期設定8KHz

    initDDS(1000000);//DDS初期設定　1MHzを仮設定
    MODE = 0;lastMODE=MODE;//0:AM 1:USB 2:LSB
    SEND =0;lastSEND = SEND;

	__delay_ms(100);
     writeDSP(0x10,0x6000);
    DSPinit();
	DSPIFset(0);//DSP 24MHz AMに設定
	
	
     VL = RXCFG | V_level;
	DSPIFBWset(IWB);// IFバンド幅　DSP書き込み
    writeDSP(0x0F,VL);// VOLレベルDSP書き込み
    disppannel();
	dispvolume();actVolume(V_level);
    dispmode(MODE);
    dispIBW(IWB);
    ritdisplay(RIT);

	lastDISPFREQ = DISPFREQ;
    setdispfreq();
	DDSFREQwrite(RXDDSFREQ,0);//reg0にDDSFREQを書き込み
    RLED = 1;
while(1) {
	makefreq();//受信時のRit周波数シフト、DDS周波数計算、基本はBASEFREQ


	if (SEND == 0) {
    	MODEcheck();
    	IWBcheck();

    	Sdata=readDSP(0x24);Sdata=Sdata>>6;
        actSMeter(Sdata * 2);

        if (lastV_level != V_level) {actVolume(V_level);
 
            VL = RXCFG | V_level;
            writeDSP(0x0F,VL);
            lastV_level = V_level;}
        if (MODE != 0) {IWB = 1;}
    	if (lastMODE != MODE) {dispmode(MODE);DSPIFset(MODE);lastMODE = MODE;}
    	if (lastIWB != IWB) {DSPIFBWset(IWB);dispIBW(IWB);lastIWB = IWB;}
        if (lastSEND != SEND) {
        	SENDOUT = 0;SENDP = 0;
        	DSPinit();DSPIFset(MODE);
            DDSFREQ = RXDDSFREQ;
            DDSFREQwrite(DDSFREQ,0);
        	dispmode(MODE);dispSmeter();dispsend(SEND);lastSEND = SEND;
        	}
    	
		} else {
		if (lastSEND != SEND) {
			DDSFREQ = TXDDSFREQ;
            DDSFREQwrite(DDSFREQ,0);
            dispModMeter();dispsend(SEND);lastSEND = SEND;
            dispmode(0);
//			BFO=1;
			SENDP = 1;
			__delay_ms(200);
			SENDOUT = 1;
            }
        
            Vmodu = takeADdata();
            actModMeter(Vmodu);
        }




	if (lastDISPFREQ != DISPFREQ) {
		setdispfreq();
		if (SEND == 0) {DDSFREQ = RXDDSFREQ;} else {DDSFREQ = TXDDSFREQ;}
		DDSFREQwrite(DDSFREQ,0);
		lastDISPFREQ = DISPFREQ;
		}
	CLEARcheck();
    RITcheck();

   if (lastRIT != RIT ) {ritdisplay(RIT);lastRIT = RIT;actritfreq(Ritfreq);
        setdispfreq();}
    if (lastRitfreq != Ritfreq) {
        actritfreq(Ritfreq);
        setdispfreq();lastRitfreq = Ritfreq;
   }

    if (SENDin == 1){SEND = 1;} else {SEND = 0;}


   }

	
}

