/*===========================================================================================
Project : IR Àû¿Ü¼±¸®¸ðÄÜ ½ÅÈ£ Á¦¾î
Version : LK-PIC16F-UK
Date    : 2017-10-16
Author  : Kyung Nam Lee
Company : LKEMBEDDED
Compiler: MPLAB+Hitech-C
Comment : IR Àû¿Ü¼±½ÅÈ£¸¦ ÀÐ¾î µé¿© ÅØ½ºÆ®LCD·Î Á¤º¸¸¦ Ãâ·ÂÇÏ°í ÀÖ´Ù.
1. Lead code : ¸®¸ðÄÜ µ¥ÀÌÅÍÀÇ ½ÃÀÛÀ» ¾Ë·ÁÁØ´Ù.
2. Custom code : 2¹ÙÀÌÆ®ÀÇ µ¥ÀÌÅÍ·Î ±¸¼ºµÇ¾î ÀÖ´Ù. (ÁÖ·Î ¸®¸ðÄÜ Á¦ÀÛ È¸»ç¿¡ µû¶ó
´Ù¸£´Ù)
3. Data code : 2¹ÙÀÌÆ®ÀÇ µ¥ÀÌÅÍ·Î ±¸¼ºµÇ¾î ÀÖ´Ù. Ã¹ ¹øÂ° ¹ÙÀÌÆ®¿¡ ¸®¸ðÄÜ ¹ö
Æ°¿¡ µû¸¥ Á¤º¸¸¦ °¡Áö°í ÀÖ´Ù. ±×¸®°í µÎ ¹øÂ° ¹ÙÀÌÆ®´Â Ã¹ ¹øÂ° ¹ÙÀÌÆ®¿¡ ´ëÇÑ µ¥ÀÌ
ÅÍ¸¦ ºñÆ® ¹ÝÀü ½ÃÅ² µ¥ÀÌÅÍÀÌ´Ù. ¿¹¸¦ µé¾î Ã¹ ¹øÂ° data code°¡ 2Áø¼ö·Î 11110011
ÀÌ¶ó¸é µÎ ¹øÂ° data code´Â 2Áø¼ö·Î 00001100ÀÌ µÈ´Ù.
=========================================================================================*/
#include <pic18f452.h>
#include <stdio.h>
#define _XTAL_FREQ 16000000
#include <htc.h>
#define LED_CLK 0X00
#define FNDDB_CLK 0X01
#define FND_BUZZER_CLK 0X02
#define LCDCON_CLK 0X03

#define DC_SERVO_MOTOR_Relay_CLK 0X05
#define DOT_LED_A_CLK 0X06
#define DOT_LED_K_CLK 0X07
#define CP_Sig 0X10  //Active Low Cp

#define Tlcd_RS 0x01
#define Tlcd_RW 0x02
#define Tlcd_EN 0x04

#define On             1
#define Off            0

#define ir_ready        0    //¸®¸ðÄÜ µ¥ÀÌÅÍ ¼ö½Å ´ë±â »óÅÂ
#define ir_lead            1 //¸®¸ðÄÜ Lead codeÀÇ Ã³À½ ¿¡Áö °ËÃâ »óÅÂ
#define ir_data            2    //¸®¸ðÄÜ Custom code, Data code ÀúÀåÇÏ´Â »óÅÂ
volatile unsigned char ir_rx_data[4] = {0};;//4byteÀÇ ¼ö½Å µ¥ÀÌÅÍ¸¦ ÀúÀåÇÏ±â À§ÇÑ º¯¼ö
volatile unsigned char Value_rx_data[4] = {0};//4byteÀÇ ¼ö½Å µ¥ÀÌÅÍ¸¦ ÀúÀåÇÏ±â À§ÇÑ »ç¿ëÀÚ º¯¼ö
volatile unsigned char ir_state =0;;        //¸®¸ðÄÜ ¼ö½Å µ¥ÀÌÅÍ¿¡ µû¸¥ ÇöÀçÀÇ »óÅÂ Ç¥½Ã
volatile unsigned int ir_timer_cnt =0;//¸®¸ðÄÜ ¼ö½Å µ¥ÀÌÅÍÀÇ ±æÀÌ¸¦ À§ÇÑ Ä«¿îÅÍ º¯¼ö
volatile unsigned char ir_bit_cnt =0;;    //¼ö½ÅµÈ ºñÆ®ÀÇ °¹¼ö¸¦ ÀúÀåÇÏ±â À§ÇÑ º¯¼ö
volatile unsigned char ir_rx_flag =0;;//¸®¸ðÄÜ µ¥ÀÌÅÍ ¼ö½Å »óÅÂ¸¦ Ç¥½Ã, 1: µ¥ÀÌÅÍ ¼ö½Å
volatile unsigned char ir_rx_temp =0;;//1byteÀÇ µ¥ÀÌÅÍ¸¦ ÀúÀåÇÏ±â À§ÇÑ ÀÓ½Ã µ¥ÀÌÅÍ º¯¼ö
volatile unsigned char disp_led =0;;

const char dec[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'} ;
char str01[]={ "IR Remote Test  "};
char str02[]={ "VALUE:"};

unsigned char TlcdCon = 0; //tlcd control º¯¼öÀÌ´Ù. PORTD·¹Áö½ºÅÍ¸¦ °ø¿ëÀ¸·Î »ç¿ëÇØ¾ß ÇÏ¹Ç·Î
// ÄÁÆ®·Ñ ½ÅÈ£ÀÇ »óÅÂ¸¦ ÀúÀåÇÏ´Â ÀÓ½Ã¹öÆÛ·Î È°¿ë µÈ´Ù.
char Number[]={'0','1','2','3','4','5','6','7','8','9'};
void flilflop_Enable(unsigned char Add, unsigned char OuputData)
{
	PORTD = OuputData;
	PORTB |= CP_Sig; //74hc574 cp sig HIGH
	PORTC = Add; //74hc574 cp sig HIGH and 74HC138 E3 HIGH
	PORTB &= ~CP_Sig; //74hc574 cp sig LOW
	PORTB |= CP_Sig; //74hc574 cp sig HIGH
}
//--Text LCD----------------------------------------------------------
void dsp_str_TLCD(unsigned char n)
{
	static unsigned char buff_con = 0;
	buff_con = (n&0xf0)|Tlcd_RS;
	flilflop_Enable(LCDCON_CLK,buff_con);
	buff_con |= Tlcd_EN;
	flilflop_Enable(LCDCON_CLK,buff_con);
	buff_con &= ~Tlcd_EN;
	flilflop_Enable(LCDCON_CLK,buff_con);
	__delay_ms(1);
	buff_con &= ~Tlcd_RS ;
	flilflop_Enable(LCDCON_CLK,buff_con);
	buff_con = ((n<<4)&0xf0)|Tlcd_RS;
	flilflop_Enable(LCDCON_CLK,buff_con);
	buff_con |= Tlcd_EN;
	flilflop_Enable(LCDCON_CLK,buff_con);
	buff_con &= ~Tlcd_EN;
	flilflop_Enable(LCDCON_CLK,buff_con);
	__delay_ms(1);
	buff_con &= ~Tlcd_RS ;
	flilflop_Enable(LCDCON_CLK,buff_con);
}
void dsp_cmd_TLCD(unsigned char n)
{
	static unsigned char buff_con = 0;
	buff_con = (n&0xf0);
	flilflop_Enable(LCDCON_CLK,buff_con);
	buff_con |= Tlcd_EN;
	flilflop_Enable(LCDCON_CLK,buff_con);
	buff_con &= ~Tlcd_EN;
	flilflop_Enable(LCDCON_CLK,buff_con);
	buff_con = ((n<<4)&0xf0);
	flilflop_Enable(LCDCON_CLK,buff_con);
	buff_con |= Tlcd_EN;
	flilflop_Enable(LCDCON_CLK,buff_con);
	buff_con &= ~Tlcd_EN;
	flilflop_Enable(LCDCON_CLK,buff_con);
	__delay_ms(1);
}
void clcd_line1()
{
	dsp_cmd_TLCD(0x80);
} //line1
void clcd_line2()
{
	dsp_cmd_TLCD(0XC0);
} //line2
void Tlcd_init() //16x2line
{
	__delay_ms(30);
	dsp_cmd_TLCD(0x30);
	__delay_ms(5);
	dsp_cmd_TLCD(0x30);
	__delay_ms(1);
	dsp_cmd_TLCD(0x30);
	dsp_cmd_TLCD(0x20); //lcd function set (16x2 line, 4bit ¼³Á¤ , 5x8 dot ¼³Á¤)
	__delay_ms(1);
	dsp_cmd_TLCD(0x0c); //Display on, Cursor off, Blank off
	dsp_cmd_TLCD(0x14); //cursor/display
	dsp_cmd_TLCD(0x06); //Entry mode set ¹®ÀÚÀÇ ÁøÇà ¹æÇâ °áÁ¤
	dsp_cmd_TLCD(0x01); // È­¸é Å¬¸®¾î
}
void string_out(char *str) //¹®ÀÚ¿­ Ãâ·Â ÇÔ¼ö
{
	unsigned int i=0;
	do{
		dsp_str_TLCD(str[i]); //-----¹®ÀÚ Ãâ·Â
	}
	while(str[++i]!='\0');
}
void int_display(int i) //ÅØ½ºÆ® LCD¿¡ Á¤¼ö¸¦ Ç¥Çö ÇÏ±â À§ÇÑ ÇÔ¼ö
{
	int j, k, l = 0;
	j = (i % 1000) / 100;
	k = (i % 100) / 10;
	l = i % 10 ;
	//if((j == 0) && (k == 0)){ lcd_putchar(0x20); } //°ø¹é Ç¥½Ã´Â »ý·« ÇÑ´Ù.
	dsp_str_TLCD(Number[j]); //100ÀÇ ÀÚ¸®
	dsp_str_TLCD(Number[k]); // 10ÀÇ ÀÚ¸®
	dsp_str_TLCD('.'); // 1ÀÇ ÀÚ¸®
	dsp_str_TLCD(Number[l]); // 1ÀÇ ÀÚ¸®
}
void textLcdDisplay(unsigned char d1, unsigned char d2, unsigned char d3, unsigned char d4) //16x2 ¶óÀÎ ÅØ½ºÆ®LCD µð½ºÇÃ·¹ÀÌ ÇÔ¼ö
{
	int i=0;
	clcd_line1(); //Ã¹¹øÂ° ¶óÀÎ
	string_out("IR Recived Test");
	clcd_line2(); //µÎ¹øÂ° ¶óÀÎ
	int_display(d1); // Custom code »óÀ§ ¹ÙÀÌÆ®
	string_out("_");
	int_display(d2); // Custom code »óÀ§ ¹ÙÀÌÆ®
	string_out("_");
	int_display(d3); // Custom code »óÀ§ ¹ÙÀÌÆ®
	string_out("_");
	int_display(d4); // Custom code »óÀ§ ¹ÙÀÌÆ®
}

unsigned int cnt_int = 0;
void interrupt HIGH_ISR(void)
{
	if(INT0IF == 1) // ¿ÜºÎÀÎÅÍ·´Æ® ÇÃ·¡±×(Æú¸µ¿§Áö)°¡ µé¾î¿À¸é?
	{
		INT0IF=0;
		TMR0IE = 0;
		switch(ir_state){
			case ir_ready :  // ÀÌ»óÅÂ´Â ÀÎÅÍ·´Æ® °É¸®±â ÀüÀÇ »óÅÂÀÌ´Ù.
			ir_state = ir_lead; // ´ë±â»óÅÂ¿¡¼­ Lead codeÀÇ ÇÏ°­ ¿¡Áö °ËÃâ»óÅÂ·Î º¯°æ
			break;
			case ir_lead :   //Lead code ÀÇ Ã³À½ ÇÏ°­ ¿¡Áö °ËÃâ »óÅÂ
			//ÇÏ°­ ¿¡Áö°£ÀÇ ½Ã°£ °£°ÝÀÌ 8.5msec~9.5msec »çÀÌ¶ó¸é
			if((ir_timer_cnt>=134) && (ir_timer_cnt<138)) //133
			{
				ir_state = ir_data;     //Lead code·Î ÀÎ½ÄÇÏ¿© µ¥ÀÌÅÍ ÀúÀå»óÅÂ·Î º¯°æ
			}
			//else ir_state = ir_lead;    //¾Æ´Ï¸é ´Ù½Ã Lead code Ã³À½ ÇÏ°­ ¿¡Áö °ËÃâ »óÅÂ·Î º¯°æ
			ir_bit_cnt = 0;   //¼ö½ÅµÈ ºñÆ®¼ö¸¦ ÃÊ±âÈ­
			ir_rx_temp = 0;
			break;

			case ir_data : // ºñÆ®¸¦ ºÐ¼®ÇÏ¿© 32°³ ºñÆ®(4¹ÙÀÌÆ®)¸¦ ÀúÀåÇÏ´Â »óÅÂ
			//0.9msec~1.3msec »çÀÌÀÇ ¹üÀ§¶ó¸é ¼ö½Å ºñÆ®ÀÇ °ªÀÌ 0ÀÌ´Ù.
			if((ir_timer_cnt>=9) && (ir_timer_cnt<25))
			{
				if((ir_timer_cnt>=9) && (ir_timer_cnt<13)){
					//ir_rx_temp = ir_rx_temp|0x00;
				}
				//1.9msec~2.5msec »çÀÌÀÇ ¹üÀ§¶ó¸é ¼ö½Å ºñÆ®ÀÇ °ªÀÌ 1ÀÌ´Ù.
				else if((ir_timer_cnt>=19) && (ir_timer_cnt<25)){
					ir_rx_temp = ir_rx_temp|0x80;
				}
				else { //¼ö½ÅµÈ ½ÅÈ£°¡ µ¥ÀÌÅÍ°¡ ¾Æ´Ï¶ó¸é
					ir_state = ir_lead;
					break;
				}
				ir_bit_cnt++;
				if((ir_bit_cnt%8)==0)
				{
					ir_rx_data[(ir_bit_cnt / 8) - 1] = ir_rx_temp; //8°³ÀÇ µ¥ÀÌÅÍ°¡ ¼ö½ÅµÇ¸é °ªÀ» ÀúÀåÇÑ´Ù.
					ir_rx_temp = 0;
					if (ir_bit_cnt >= 32)
					{
						ir_state = ir_ready; //¸ðµç µ¥ÀÌÅÍ°¡ ¼ö½ÅµÇ¸é ¸®¸ðÄÜ ½ÅÈ£ ¼ö½Å ´ë±â »óÅÂ·Î º¯°æ
						ir_bit_cnt = 0;
						ir_rx_flag = 1;
						Value_rx_data[2] = ir_rx_data[2];
						textLcdDisplay(ir_rx_data[0],ir_rx_data[1],ir_rx_data[2],ir_rx_data[3]);
					}
				}

				ir_rx_temp = ir_rx_temp>>1;
			}
			else { //¼ö½ÅµÈ ½ÅÈ£°¡ µ¥ÀÌÅÍ°¡ ¾Æ´Ï¶ó¸é
				ir_state = ir_ready;
				break;
			}

			break;
		}
		TMR0IE = 1;
		TMR0 = 156; //100uS

		ir_timer_cnt = 0;
	}
	if(TMR0IF  == 1 )//  // Å¸ÀÌ¸Ó ¿À¹öÇÃ·Î¿ì ÀÎÅÍ·´Æ® ÇÃ·¡±×(100uS¸¶´Ù)°¡ µé¾î¿À¸é?
	{
		TMR0IF = 0;
		ir_timer_cnt++;
		TMR0+=156; //100uS
	}
}
void main(void) // ÃÊ±âÈ­
{
	//-- ÀÔÃâ·Â ·¹Áö½ºÅÍ ¼³Á¤ ÃÊ±âÈ­---------------------------------
	TRISA = 0X0f;
	TRISB = 0X01;
	PORTB = 0X00;
	TRISC = 0x80;
	PORTC = 0X00;
	TRISD = 0X00;
	PORTD = 0X00;
	TRISE = 0X00;
	T0CON = 0X01;;   //--  T0PS2:T0PS0=001 4ºÐÁÖºñ PIC MCU´Â 4Å¬·°¿¡ 1»çÀÌÅ¬·°
	INTCON = 0xb0; //GIE=1, INTE=1 ¼³Á¤
	//TMR0IE: TMR0 Overflow Interrupt Enable bit
	TMR0 = 156; //100uS

	Tlcd_init();			//--  TextÇüLCD ÃÊ±âÈ­
	ir_timer_cnt = 0;
	ir_bit_cnt = 0;
	ir_rx_flag = 0;
	textLcdDisplay(ir_rx_data[0],ir_rx_data[1],ir_rx_data[2],ir_rx_data[3]);
	flilflop_Enable(LED_CLK,0);
	while(1)
	{
	}
}