#line 1 "D:/MCCI/Firmware/mcci.c"
#line 1 "c:/program files/mikroelektronika/mikroc pro for pic/include/built_in.h"
#line 21 "D:/MCCI/Firmware/mcci.c"
unsigned char readbuff[64] absolute 0x500;
unsigned char writebuff[64] absolute 0x540;
char cnt, ren_pointer;
char remote_command;
int remote_id, tmp_out;
unsigned int ren_timer;
bit home_sw, back_sw;
bit rotery_mode, rotery_push, update_lcd;
bit disp_switch, is_advance;

sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;

void GetRotaryState()
{
 if(PORTD.B1 != rotery_mode)
 {
 Delay_us(25);
 remote_command = 1;
 if(PORTD.B0 == 0)
 remote_id = 1;
 else
 remote_id = 2;
 rotery_mode = PORTD.B1;
 }
 if(PORTD.B2 != rotery_push)
 {
 if(PORTD.B2 == 0)
 {
 remote_command = 2;
 remote_id = 0;
 }
 rotery_push = PORTD.B2;
 }
 if(PORTD.B4 != home_sw)
 {
 if(PORTD.B4 == 0)
 {
 remote_command = 2;
 remote_id = 1;
 }
 home_sw = PORTD.B4;
 }
 if(PORTD.B5 != back_sw)
 {
 if(PORTD.B5 == 0)
 {
 remote_command = 2;
 remote_id = 2;
 }
 back_sw = PORTD.B5;
 }
}

void GetSIRCValue()
{
 char pos = 0;
 char i;
 remote_command = 0;
 remote_id = 0;
 while((PORTE.B0 == 0) && (pos < 26))
 {
 Delay_us(100);
 pos++;
 }
 if(pos == 25)
 {
 for(i = 0; i < 21; i++)
 {
 tmp_out = 0;
 while((PORTE.B0 == 1) && (tmp_out < 12001))
 {
 Delay_us(1);
 tmp_out++;
 }
 if(tmp_out<12001)
 {
 pos = 0;
 while((PORTE.B0 == 0) && (pos < 20))
 {
 Delay_us(100);
 pos++;
 }
 if(pos > 10)
 {
 if(i<8)
 remote_command |= (1<<i);
 else
 remote_id |= (1<<(i-8));
 }
 }
 else
 {
 remote_command = 0;
 break;
 }
 }
 }
}

void ResetLCD()
{
 Lcd_Cmd(_LCD_CLEAR);
 Lcd_Out(1,1,"Welcome to XBMC");
}

void EchoUSBInfo()
{
 char pos_;
 is_advance = 1;
 for(pos_ = 0; pos_ < 17; pos_++)
 if(readbuff[4+ren_pointer+pos_]==0)
 {
 is_advance = 0;
 Lcd_Chr(2, pos_+1, ' ');
 }
 else
 Lcd_Chr(2, pos_+1, readbuff[4+ren_pointer+pos_]);
 ren_pointer = (is_advance==1) ? (ren_pointer+1) : 0;
}

void PrintUSBInfo()
{
 char pos_;
 if((readbuff[1]>67) || (readbuff[1]<65))
 ResetLCD();
 else
 {
 Lcd_Cmd(_LCD_CLEAR);
 switch(readbuff[1])
 {
 case 65 : Lcd_Out(1,1, "Audio"); break;
 case 66 : Lcd_Out(1,1, "Video"); break;
 case 67 : Lcd_Out(1,1, "Picture"); break;
 }
 switch(readbuff[2])
 {
 case 66 : Lcd_Out(1,9, ": Play"); break;
 case 67 : Lcd_Out(1,9, ": Pause"); break;
 }
 update_lcd = ((readbuff[1]<67) && (readbuff[2]>65));
 if(update_lcd)
 {
 ren_pointer = 0;
 EchoUSBInfo();
 ren_timer = 0;
 update_lcd = 1;
 }
 }
}

void interrupt()
{
 USB_Interrupt_Proc();
}

void main(void)
{
 ADCON1 |= 0x0F;
 CMCON |= 7;
 TRISE = 7;
 TRISA = 0;
 TRISD = 127;

 ren_pointer = 0;
 rotery_mode = 0;
 rotery_push = 0;
 update_lcd = 0;
 disp_switch = 0;
 home_sw = 0;
 back_sw = 0;

 HID_Enable(&readbuff, &writebuff);
 for(cnt=0;cnt<64;cnt++)
 writebuff[cnt]= 0;
 Lcd_Init();
 Lcd_Cmd(_LCD_CURSOR_OFF);
 ResetLCD();

mainloop:

 if(HID_Read() > 0)
 PrintUSBInfo();

 GetSIRCValue();
 if(remote_command == 0)
 GetRotaryState();

 if(remote_command != 0)
 {
 writebuff[0] = 184;
 writebuff[1] = 1;
 writebuff[2] = remote_command;
 writebuff[3] =  ((char *)&remote_id)[0] ;
 writebuff[4] =  ((char *)&remote_id)[1] ;

 while(!HID_Write(&writebuff,64));
 }

 disp_switch = !disp_switch;
 if(update_lcd && disp_switch)
 {
 ren_timer++;
 if(ren_timer >= 45000)
 {
 ren_timer = 0;
 EchoUSBInfo();
 }
 }
 goto mainloop;
}
