//I2C EEPROM読み書きプログラム
//作成者：KK

#include<p18f4620.h>
#include<delays.h>		//遅延関数ヘッダ
#include<adc.h>			//A/D変換用ライブラリヘッダ
#include<usart.h>		//USART用ライブラリヘッダ
#include<timers.h>		//タイマ用ライブラリヘッダ
#include<i2c.h>			//I2C用ライブラリヘッダ
#include<stdio.h>
#include"lcd_c18.h"		//LCD用ヘッダファイル
#include"i2c_c18.h"		//I2C用ヘッダファイル

/*=====定義文=====*/
#define	SW1	(PORTAbits.RA0)	//SW1
#define	SW2	(PORTAbits.RA1)	//SW2

#define	RSW1 ((RB & 0xF0) >> 4)		//RSW1
#define	RSW2 (RB & 0x0F)			//RSW2


/*=====コンフィグレーション設定=====*/
/*
・PLL発振モード
・パワーアップタイマON
・ブラウンアウトリセット電圧0V（BOR OFF）
・CCP2出力C1
・スタックオーバーフローリセットON
・MCLR ON
*/
#pragma config OSC=HSPLL,FCMEN=OFF,IESO=OFF,PWRT=ON
#pragma config BOREN=OFF,BORV=0,WDT=OFF,WDTPS=1
#pragma config MCLRE=ON,LPT1OSC=OFF,PBADEN=OFF
#pragma config CCP2MX=PORTC,STVREN=ON,LVP=OFF
#pragma config XINST=OFF,DEBUG=OFF
#pragma config CP0=OFF,CP1=OFF,CP2=OFF,CP3=OFF,CPB=OFF,CPD=OFF
#pragma config WRT0=OFF,WRT1=OFF,WRT2=OFF,WRT3=OFF,WRTB=OFF,WRTD=OFF
#pragma config EBTR0=OFF,EBTR1=OFF,EBTR2=OFF,EBTRB=OFF

/*=====関数定義=====*/
void main(void);
void sw1_ch(void);
void sw2_ch(void);

/*=====変数宣言=====*/
unsigned int cnt=0,i=0,eep_data=0;
signed int s1=0,s2=0,a=0,b=0;
signed int eep_flag=0;
char start1[]="EEPROM I2C       ";
char start2[]="SW1:W  SW2:R";
char writeing[]="ｶｷｺﾐﾁｭｳ      ";
char write_end[]="ｶｷｺﾐｼｭｳﾘｮｳ   ";
char reading[]="ﾖﾐｺﾐﾁｭｳ      ";
char read_end[]="ﾖﾐｺﾐｼｭｳﾘｮｳ    ";
char add_num[]="ｱﾄﾞﾚｽ：   ";
char read_num[]="      ";

/*=====メイン関数=====*/
void main(void){
	ADCON1=0x0F;	//全ポートデジタルとして利用
	//ポート入出力設定
	TRISA = 0x03;
	TRISB = 0xFF;
	TRISC = 0x00;
	TRISD = 0x00;
	TRISE = 0x00;
	//初期化
	LATA = 0x00;
	LATB = 0x00;
	LATC = 0x00;
	LATD = 0x00;
	LATE = 0x00;
	
	//TIMER0設定
	//1ms割り込み
	//16ビットタイマ・内部クロック・プリスケーラ1:1
	OpenTimer0(TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_EDGE_FALL & T0_PS_1_1);
	WriteTimer0(55536);		//タイマ０設定

	//USART設定
	//9600bps
	OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_BRGH_HIGH,255);
	
	//I2C設定
	//伝送速度・400Kbps
	OpenI2C(MASTER,SLEW_ON);
	SSPADD=24;
	//(40MHz/400Kbps)/4-1 = 24
	
	INTCONbits.TMR0IE=1;	//タイマ０割り込み許可
	INTCONbits.GIE=1;		//グローバル割り込み許可
	
	lcd_init();		//LCD初期化
	lcd_cmd(0x0c);	//カーソルOFF
	lcd_clear();
	
	lcd_cmd(0x80);
	lcd_str(start1);
	lcd_cmd(0xc0);
	lcd_str(start2);
	
	while(1){
		//アドレス0〜255までRSWの値書き込み
		if(a){
			eep_data=PORTB&0xff;
			lcd_cmd(0x80);				//１行目へ
			lcd_str(writeing);			//カキコミチュウ　表示
			lcd_cmd(0xc0);				//２行目へ
			lcd_put_num(3,i,add_num+6);	//アドレス文字列変換
			lcd_str(add_num);			//アドレス表示 
			lcd_put_num(3,eep_data,read_num+1);//データ文字列変換
			lcd_str(read_num);			//データ表示
			
			if(i>=0xFF || eep_flag!=0){				//アドレス255まで書き込んだら終了
				a=0;
				lcd_cmd(0x80);			//１行目へ
				lcd_str(write_end);		//カキコミシュウリョウ　表示
				//1s待機
				cnt=0;
				while(cnt<=1000);
				lcd_clear();
				lcd_cmd(0x80);
				lcd_str(start1);
				lcd_cmd(0xc0);
				lcd_str(start2);
			}
			
			//100ms毎のデータ書き込み
			if(cnt>=100){
				//EEPROM書き込み
				eep_flag = i2c_write(0xA0,i,PORTB&0xFF);
				cnt=0;
				i++;
			}
		}
		
		if(b){
			lcd_cmd(0x80);				//１行目へ
			lcd_str(reading);			//ヨミコミチュウ　表示
			lcd_cmd(0xc0);				//２行目へ
			lcd_put_num(3,i,add_num+6);	//アドレス文字列変換
			lcd_str(add_num);			//アドレス表示
			lcd_put_num(3,eep_data,read_num+1);//データ文字列変換
			lcd_str(read_num);			//データ表示
			
			if(i>=0xFF || eep_data <0){				//アドレス255まで書き込んだら終了
				b=0;
				lcd_cmd(0x80);			//１行目へ
				lcd_str(read_end);		//ヨミコミシュウリョウ　表示
				//1s待機
				cnt=0;
				while(cnt<=1000);
				lcd_cmd(0x80);
				lcd_str(start1);
			}
			
			//100ms毎のデータ書き込み
			if(cnt>=100){
				//EEPROM読み込み
				eep_data = i2c_read(0xA1,i);
				cnt=0;
				i++;
			}
		}
		sw1_ch();
		sw2_ch();
	}
}

/*=====割り込み定義=====*/
#pragma interrupt timer
//割り込みベクタセット
#pragma code timercode=0x08	//開始番地指定
void tim_dir(void){			//割り込み関数へジャンプ
	_asm goto timer _endasm
}

/*=====TIMER割り込み処理=====*/
#pragma code
void timer(void){
	/*タイマ0割り込み処理*/
	if(INTCONbits.TMR0IF){
		INTCONbits.TMR0IF=0;	//割り込みフラグクリア
		WriteTimer0(55536);		//タイマ０再設定	
		
		cnt++;
	}
}

/*=====SW状態検出=====*/
void sw1_ch(void){
	switch(s1){
		case 0:
			if(SW1){
				s1=1;
				if(!b){
					if(!a){
						lcd_clear();
						i=0;
						cnt=0;
					}	
					a=1;	//書き込み開始
				}
			}
			break;
		
		case 1:
			if(!SW1){
				s1=0;
			}
			break;
	}
}	

void sw2_ch(void){
	switch(s2){
		case 0:
			if(SW2){
				s2=1;
				if(!a){
					if(!b){
						lcd_clear();
						i=0;
						cnt=0;
					}
					b=1;	//読み込み開始
				}	

			}
			break;
		
		case 1:
			if(!SW2){
				s2=0;
			}
			break;
	}
}