Version:0.9 StartHTML:0000000105 EndHTML:0000199800 StartFragment:0000001499 EndFragment:0000199784 mikroIDE
 /*
 rev 15/02/2015  18F26k22
 A suivre ...

  ICSP
  5  Vert   ...  RB6
  4  Jaune  ...  RB7
  3  Orange  ..   0V
  2  Rouge    isolé ( ou alim via ISCSP  )
  1  marron  ..  MCLR


  Compilateur!  MikroC Pro V6.50 version enregistree
  Controller:   PIC18F26k22 PDIP 28
  Projet :      IRC5_18F26k228.mcppi
  Source :      IRC5_18F26k22_150215.c
  Eeeprom file : IRC5_18F26k22.ihex

  Hardware:
  Config PIC    Scheme de microC :
  Macro Terminal Vbray :
  librairies utilisees : ADC,C-String,Conversions,UART,SoftI2C

  librairies utilisees :
  ADC,C-String,Conversions,UART,SoftI2C

CONFIG1H : $300001 : 0x0022
CONFIG2L : $300002 : 0x001F
CONFIG2H : $300003 : 0x003C
CONFIG3H : $300005 : 0x00BF
CONFIG4L : $300006 : 0x0081
CONFIG5L : $300008 : 0x000F
CONFIG5H : $300009 : 0x00C0
CONFIG6L : $30000A : 0x000F
CONFIG6H : $30000B : 0x00E0
CONFIG7L : $30000C : 0x000F
CONFIG7H : $30000D : 0x0040


PortB
B0  21   Input IR from TSOP1736
B1  22   Led blanche  via 1K    +5V
B2  23
B3  24
B4  25
B5  26
B6  27
B7  28
---------
PORTA
A0   2  Ana CH0
A1   3  Ana CH1
A2   4  Ana CH2
A3   5  Ana CH3
A4   6  Led Rouge  via 1K    +5V
A5   7  Ana CH4
---------
PORTC
C0   11
C1   12
C2   13
C3   14
C4   15
C5   16
C6   17  TX  RS232
C7   18  RX  RS232
-----------


*/

//#define Debugging

#define Quartz     10000000
#define POWER_SUPPLY_5V
#define FOSC 10  // MHz
#define BAUD 9600  // UART1
#define VDD          5.00   //  power supply

//--- COM RS232 USART ----
#define Rs_TX PORTC.F6
#define Rs_RX PORTC.F7

// timer1 init à 200mS
#define DUREE_H  0x0B       // 3035\256
#define DUREE_L  0xDB       //3035-(DUREE_H*256)
#define DUREE   3035
#define NbCycles_T1 20

//-- commandes terminal VT220
#define CLS 12     // effacement de page sur Terminal VBRAY
#define CR 13
#define VT 10
#define LF 10
#define TAB 9
#define Bell 7
#define Byte unsigned char

#define LED_Toggle_Led_Blanche()  (LATB.F1=~LATB.F1)
#define LED_Toggle_Led_Rouge()  (LATA.F4=~LATA.F4)
#define Led_Rouge    LATA.F4
#define Led_Blanche  LATB.F1

#define Beeper  LATA.F5

#define IRC5_PIN     PORTB.F0
#define IRC5_Nbits   14


const code char mesg0[]="Mikroc pro 6.50 18F26K22 Test IRC5  150215\n\r";
const code char mesg1[]="                    ";
const code char * Messages[]={mesg0,mesg1};


const char Libel0[]="Cmd ";
const char Libel1[]="Num ";
const char Libel2[]="Droite";
const char Libel3[]="Gauche";
const char Libel4[]="Vol.+ ";
const char Libel5[]="Vol.- ";
const char Libel6[]="OK";
const char Libel7[]="Menu  ";
const char Libel8[]="Mute  ";
const char Libel9[]="Osd   ";
const char Libel10[]="Haut  ";
const char Libel11[]="Bas   ";
const char Libel12[]="Clear ";
const char Libel13[]="Memo  ";
const char Libel14[]="Correct ";
const char Libel15[]="sleep ";
const char Libel16[]="Aigu +  ";
const char Libel17[]="Aigu -  ";
const char Libel18[]="point ";
const char Libel19[]="Channel >>";
const char Libel20[]="Channel <<";
const char *IRC5_Str[]={Libel0,Libel1,Libel2,Libel3,Libel4,Libel5,Libel6,Libel7,
          Libel8,Libel9,Libel10,Libel11,Libel12,Libel13,Libel14,
          Libel15,Libel16,Libel17,Libel18,Libel19,Libel20};



const char chaine0[]="                  ";
const char chaine1[]="Port comm 19200 ouvert";
const char chaine2[]="PROJET MikroC : IRC5_18F26K22.mcppi\r\n";
const char chaine3[]="ESC pour sortir\r\n";
const char chaine4[]="MARANTZ RC5200SR \r\n";
const char chaine5[]="                 \r\n";
const char chaine6[]="car recu :";
const char chaine7[]="                 \r\n";
const char chaine8[]="                 \r\n";
const char chaine9[]="   \r\n";
const char chaine10[]="  \r\n";
const char chaine11[]="IR TSOP36 Capture via IT sur RB0  \r\n";
const char chaine12[]="C:\_MikroC\_MesProjets_MikroC\_IRC5\IRC5_18F26k22_150330.c \r\n";

const char *RS_Str[]={chaine0,chaine1,chaine2,chaine3,chaine4,chaine5,chaine6,chaine7,
                        chaine8,chaine9,chaine10,chaine11,chaine12};

typedef unsigned char byte ;

//-- IRC5 notes
//  Format de la trame recue:
//  - 2 bits de start (à 1)
//  - 1 bit toggle bit (change sur une Cde NON REPETITIVE)
//  - 5 bits "System" , MSB en prmier
//  - 6 Bits "Command"  MSB en premier
// Reconnaissance d'un bit par la duree entre 2 fronts descendants du signal IR
//  - une longue duree signifie un changement d'etat du bit par rapport au precedent
//  - 2 duree elementaires signifie  Bit idem que le precedent
//    Le premier bit de start est toujours à 1
//  1 bit elementaire  = 1778 uS
//    "short" time = 1/2 bittime = 889 uS, = timer value 255-200=55 => 880/16)
//    "long"  time = 1 bittime = 1778 uS,  = timer value 255-111=144 => 1776/16)
// Note : valeurs dependant du Quartz utilise

//voir PIC_calculs_datas.xls  onglet : Timers pour details de calculs
// avec Q=10MHz et prediviseur=32
//define IRC5_OK            104    //   si > (3/4 bit elementaire)
//#define IRC5_Limite_Basse  35     //  (1/4 bit elementaire)
//#define IRC5_Limite_Haute  176    //   (5/4 bit elementaire)
//#define IRC5_Elementaire   140    //

#define IRC5_OK            104    //   si > (3/4 bit elementaire)
#define IRC5_Limite_Basse  35     //  (1/4 bit elementaire)
#define IRC5_Limite_Haute  176    //   (5/4 bit elementaire)
#define IRC5_Elementaire   140    //

#define SIZE        63

char Texte[SIZE];
char CRam1[18];
char *txt=&Texte[0];

volatile char buffer1[SIZE];        // buffer de reception
volatile int  CptErr=0;
volatile unsigned char c1=0;
volatile  Flag_Buffer;
volatile unsigned int i1,Index1=0;

unsigned int Count1;
unsigned  char Flag_Timer1;


struct chbits {
   unsigned running:1;
   unsigned standby:1;
   unsigned Allume:1;
   unsigned Accumule:1;
   unsigned Blc:1;
   unsigned OneShot:1;
   unsigned Fill:1;
   unsigned Lcd:1;
  } Drapeaux;

unsigned short int i,j,k,l;
unsigned int dummy;
unsigned long M1;
float f1,f2;

unsigned long Volume;
int CptCars;

enum {
      IRC5_IDLE,
      IRC5_DECODING,
      IRC5_COMPLETED
} IRC5_state ;

unsigned char Fx[20];
unsigned int IRC5_times[32];
volatile int   IR_Index;
volatile int   IRC5_Index;
unsigned int   IRC5_bits ;               // will hold the received bits
Byte  IRC5_bitCount ;           // nb of bits processed
Byte  IRC5_prevBit ;            // the value of the previous bit
Byte  IRC5_shortPulses ;        // nr of subsequent short pulses measured

volatile struct nbbits    // chbits
{
    unsigned toggle   : 1 ;
    unsigned device   : 5 ;
    unsigned command  : 6 ;
    unsigned received : 1 ;
} IR ;

volatile unsigned int time;

int EAn0,EAn1;
int N1;
unsigned char  addr,donnee;


unsigned int Compteur;
char * valtxt;
unsigned int M;
unsigned long ML;
//unsigned int Compteur_Sec;
//unsigned int compteur_it;
unsigned int dev, cmdx ;
unsigned int repeat ;
unsigned char last_toggle ;

unsigned int clk;
volatile char FLAG  ;
volatile unsigned int cmd;

int nbit=0;

void Init_Hardware(void) ;
void Read_Msg_Eeprom( int depuis);
void Write_Msg_Eeprom( int Adr,const char * d1) ;
void Init_Timer0(void);
void Init_Timer1 (void);    //125mS
void Init_Timer2 (void);    //125mS
void CRLF(void) ;
void UART1_Write_CText(const char *txt);


  /*

void Interrupts_() iv 0x0018 ics ICS_AUTO
{
 if ((INTCON.INT0IE) && (INTCON.INT0IF))
{
cmd=0;
delay_us(10668); //sauter 6bits
delay_us(444);  // attente 1/4 de bit pour etre sur d'etre sur le palier etat haut
if(PORTB.F0==1)
cmd=cmd+0b00100000;
delay_us(1778);
if(PORTB.F0==1)
cmd=cmd+0b00100000;
delay_us(1778);
if(PORTB.F0==1)
cmd=cmd+0b00010000;
delay_us(1778);
if(PORTB.F0==1)
cmd=cmd+0b00001000;
delay_us(1778);
if(PORTB.F0==1)
cmd=cmd+0b00000100;
delay_us(1778);
if(PORTB.F0==1)
cmd=cmd+0b00000010;
delay_us(1778);
if(PORTB.F0==1)
cmd=cmd+0b00000001;
delay_us(1778);
FLAG=1;
INTCON.INT0IF=0;
}
}
   */
void Interrupt() iv 0x0008 ics ICS_AUTO
{
      unsigned int time;

  /* ------  timer 1  ----------------
  if  ( (TMR1IE_bit==1) && ( TMR1IF_bit==1))
   {  // Test "Peripheral Interrupt Request Register 1" for Timer1 Flag

     Count1++;
     if (Count1>=NbCycles_T1)   // 8x125 ms= 1 seconde   et init timer1 à 3035  et prescaler=1/8
       {
        Count1=0;
        Flag_Timer1=1;
        TMR1IE_bit=0;
      }
      TMR1H= 0x0B; // Hi (3035);
      TMR1L= 0xDB; // Lo (3035);
      PIR1.TMR1IF=0;
   }
   */
   /*
   ------  timer 2 ----------------
  if( ((TMR2IE_bit==1)&& TMR2IF_bit==1))
  {  // Test "Peripheral Interrupt Request Register 1" for Timer1 Flag

     Count2++;
     if (Count2>=NbCycles_T2)   // 8x125 ms= 1 seconde   et init timer1 à 3035  et prescaler=1/8
       {
        Count2=0;
        Flag_Timer2=1;
      }
      TMR2= 60;
      PIR1.TMR2IF=0;
   }
   */
   //  ====   RB0 interrupt ======
 // test si interrupt Rb0
 if (INTCON.INT0IF==1)
 {

    // inverse le sens de detection front d'interruption INTEDG (interrupt edge)
    INTCON2.INTEDG0 = ~INTCON2.INTEDG0 ;
    INTCON.INT0IF =0;
    time =TMR0L ; // ReadTimer0();     // lecture timer0
    TMR0L=0;     // relance le timer
    switch (IRC5_state)
       {
       // temps mort , encore rien recu
        case IRC5_IDLE :
                 IRC5_bits        = 1; // already 1 bit (with value "1") received
                IRC5_bitCount    = 1;
                IRC5_shortPulses = 0;
                IRC5_prevBit     = 1;
                IRC5_state       = IRC5_DECODING;
                INTCON.TMR0IF = 0;    // reset Timer0 overflow flag
                INTCON.TMR0IE = 1;    //enable timer0 interrupt
                break ;

       // Modification detectee. On demarre la sequence de Test des bits
        case IRC5_DECODING :  //temps d'  Execution ~52 uS a 4 Mhz
                if ((time > IRC5_Limite_Basse) && (time < IRC5_Limite_Haute))
                {
                     if (time < IRC5_OK)                    // impulsion courte detectee
                     {
                        IRC5_shortPulses ++ ;
                        if (IRC5_shortPulses == 2)          // c'est un bit
                        {
                           IRC5_bits <<= 1;                 // memorise le bit recu
                           IRC5_bits |= IRC5_prevBit;
                           IRC5_bitCount ++ ;
                           IRC5_shortPulses = 0;
                        }
                     } else {    // impulsion longue detectee
                        IRC5_prevBit = 1- IRC5_prevBit;     // inverse le bit
                        IRC5_bits <<= 1;                    // memorise le bit recu
                        IRC5_bits |= IRC5_prevBit;
                        IRC5_bitCount ++ ;
                        IRC5_shortPulses = 0;
                     }

                     if (IRC5_bitCount == IRC5_Nbits) // tous les 14 bits recu ?
                     {
                        IRC5_state = IRC5_COMPLETED;
                        INTCON2.INTEDG0 = 0; // le prochain front d'interruption IRC5 sera negatif
                        INTCON.TMR0IE = 0;   // desarme interrupt timer0
                       TMR0L=0;     // relance le timer
                       // T0CON=0b110000100;
                     }
                } else { // probleme de timming
                     IRC5_state = IRC5_IDLE;  // on recommence
                     INTCON2.INTEDG0 = 0; //le prochain front d'interruption IRC5 sera negatif
                  //   INTCONbits.TMR0IE  = 0;  // desarme interrupt timer0
                    // T0CON=0b110000100;
                }
                break ;

        // Tous les bits ont été correctement recu. Memorise la donne
         case IRC5_COMPLETED :
                INTCON2.INTEDG0 = 0; // next RC5 interrupt is negative going
                IR.toggle = ((IRC5_bits>>11) & 0x01) ? 0 : 1 ;
                IR.device =  (IRC5_bits>>6) & 0b00011111 ;
                IR.command=  (IRC5_bits & 0b00111111) ;
                IR.received = 1 ;
                IRC5_state = IRC5_IDLE ;
                break ;

    }  // fin du switch
  }    // fin IT RB0
   // UART1 interrupt
   if ( (RCIE_bit) && ( RCIF_bit))
   {
   // traitement separe des erreurs de COM
      if (RCSTA.OERR==1)    // voir parag 16.1.26 p273
      {
       RCSTA.CREN = 0 ;
       c1 = RCREG;
       RCSTA.CREN = 1 ;
        CptErr++;
       }
      if(RCSTA.FERR==1 )
      {
      RCSTA.SPEN = 0 ;
      RCSTA.SPEN= 1 ;
      CptErr++;
       c1 = RCREG;
      }
      c1 = RCREG;
     if (c1==CR)
      {
      Flag_Buffer=1;
      //PIE1.RCIE=0 ; //interdit IT Reception UART
      buffer1[i1]=0;
      Index1=i1;
      i1=0;
      c1=0;
     }
     else
     {
        buffer1[i1]=c1;
        Index1=i1;
        i1++;
      }
     PIR1.RCIF=0   ;
   }
  // --- Timer0 interrupt -------------
  if (INTCON.TMR0IF==1)  // depassement timer0
 {
   if (IRC5_state == IRC5_DECODING) // Probleme de decodage
   {
     IRC5_state = IRC5_IDLE;    // on recommence
     INTCON2.INTEDG0 = 0;   //le prochain front d'interruption IRC5 sera negatif
     INTCON.TMR0IE = 0;     // desactive interrupt timer0
    }
    INTCON.TMR0IF = 0;
 }


} // end interrupt routine


 // --- Copie le texte depuis FLASH ROM vers RAM
void strConstRamCpy(unsigned char *dest, const code char *source)
 {
  while (*source)*dest++ = *source++ ;
  *dest = 0 ;    // terminateur
}

void CRLF()
{
 UART1_Write(CR);
 UART1_Write(LF);
}

void UART1_Write_CText(const char *txt)
 {
   while (*txt)
      UART1_Write(*txt++);
}

void Write_Msg_Eeprom(int Adr,const char * d1)
{ int i1 ,i;
  char c1;
  i1=Adr;
  do
  {
  c1=*d1;
  EEPROM_Write(Adr,c1);
  if ( c1==0) break;
  if ( i1>1023) break;
  Delay_ms(5);
  i1++;
  }
  while (i!=0) ;
 }


void Read_Msg_Eeprom( int debut)
{   int i1 ,i;
  i1=debut;
  do
  {
  i = EEPROM_Read(i1);
  if (( i==0) || (i==0xFF)) break;
  if ( i1>1023) break;
  UART1_Write(i);
 // Tampon[i1-debut]=i;
  Delay_ms(5);
  i1++;
   }
  while (i!=0) ;
 }


 void Decompile_byte(Byte un) {
char masque;
  masque = 128;
  while (masque > 0 ) {
    if (un & masque)
      UART1_Write(49);  //  '1'
    else
      UART1_Write(48);  //  '0'
    masque >>= 1;
    }
 // Usart_Write(10);
}

void Octet2Hex(char number)
{
char high,low;
  // high nibble
  high = ((number & 0xF0) >> 4) + 48; // + '0'
  if (high > '9')
    high =high + 7;
 // low nibble
  low = (number & 0x0F) + 48;          // +'0' low nibble
  if (low > '9')                       // '9'= 57u
    low += 7;                         // > '9'
  UART1_Write(high);
  UART1_Write(low);
  UART1_Write('h');
 }
 

void Write_Word(unsigned int M,char Sign)
{
// Sign 1 pour entier signé +32767 -32768
// Sign 0 pour entier non signé 0 a 65535
unsigned int i,k,l;
unsigned long L1;
unsigned char valtxt[8];
    // init ponteur sur zone rangement caracteres
 if (Sign>1) return;   // argument signe doit etre 0 ou 1
 if (Sign==0)
  {       L1=(long)M;
        LongWordToStr(L1,valtxt);
  }
  else WordToStr(M,valtxt);
 if (Drapeaux.Fill==1)
 {
  k=strlen(valtxt);
  for (i=0;i<k;i++)valtxt[4+Sign-i]=valtxt[k-i-1];
  for (i=0;i<(5+Sign-k);i++)
  {if (Drapeaux.Blc==1) valtxt[i]='0'; else valtxt[i]=' ';}
 }
 valtxt[5+Sign]=0;
 UART1_Write_Text(valtxt);
}

 void Tempo(long val)
{
while(val>0)
{
val--;
}
}


void Float2Ascii (float x, unsigned char *str,char precision)
{
 /* converts a floating point number to an ascii string */
 /* x is stored into str, which should be at least 30 chars long */
 int ie, i, k, ndig;
 double y;
 ndig = ( precision<=0) ? 7 : (precision > 22 ? 23 : precision+1);
 ie = 0;
 /* if x negative, write minus and reverse */
 if ( x < 0)
 {
   *str++ = '-';
   x = -x;
 }
 /* put x in range 1 <= x < 10 */
 if (x > 0.0) while (x < 1.0)
 {
   x *= 10.0;                // a la place de =*
   ie--;
 }
 while (x >= 10.0)
 {
   x = x/10.0;
   ie++;
 }
 // in f format, number of digits is related to size
 ndig += ie;                                // a la place de =+
 //round. x is between 1 and 10 and ndig will be printed to
 // right of decimal point so rounding is ...
 for (y = i = 1; i < ndig; i++)
 y = y/10.;
 x += y/2.;
 if (x >= 10.0) {x = 1.0; ie++;}
 if (ie<0)
 {
   *str++ = '0'; *str++ = '.';
   if (ndig < 0) ie = ie-ndig;
   for (i = -1; i > ie; i--)  *str++ = '0';
 }
 for (i=0; i < ndig; i++)
 {
   k = x;
   *str++ = k + '0';
   if (i ==  ie ) *str++ = '.';
   x -= (y=k);
   x *= 10.0;
  }
 *str = '\0';
}

void PrintHandler(char c)
 {
  UART1_Write(c);
}


 void Init_Timer0(void)
 {
  T0CON=0;
  T0CON.T08BIT=1; // mode 8 bits
  T0CON.PSA=0; // assigne prescaler
  T0CON.T0PS2=1; // Prescaler=32
  T0CON.T0PS1=0;
  T0CON.T0PS0=0;
  TMR0H= 0x00;
  TMR0L= 0x00;
  T0CON.TMR0ON=0;
  INTCON.TMR0IF=0;
  TMR0IP_bit=1;
  INTCON.TMR0IE=0;    // disable interrupt Timer0
 }

void Init_Timer1(void)
 {
  T1CON=0;
 // T1CON=0b00110000;
  T1CON.TMR1CS0=0;   // FOSC internal / 4
  T1CON.TMR1CS1=0;
  T1CKPS1_bit=1;  //prescal select=11 => 1/8
  T1CKPS0_bit=1;
  T1GCON=0;
  TMR1H= 0x0B; // Hi (3035);
  TMR1L= 0xDB; // Lo (3035);
 // TMR1H= NbCycles_T1>>8;
 // TMR1L= NbCycles_T1 & 0x00FF;
   Count1=0;
  Flag_Timer1=0;
  PIR1.TMR1IF=0;     // Reset Timer1 Flag
  PIE1.TMR1IE=0;  //Disable interrupt TMR1
  TMR1ON_bit=0;
}


void Init_ADC()
 {
       //config lecture ADC 10 bits
 ADCON0.ADON=1;      // ADC enabled chanel 0
 ADCON1.TRIGSEL=0 ; // trigger from CCP5
 ADCON2.ADFM=1;     // right justified
 ADCON2.ACQT2=1;
 ADCON2.ACQT1=1;
 ADCON2.ACQT0=0;    // 16 TAD
 ADCON2.ADCS1=1;    // select RA0 = analog input
 ADCON2.ADCS2=0;    // RA1 = Analog input
 ADCON2.ADCS0=0;    // Fosc/32
 // +Vref = +5V AVdd
 ADCON1.PVCFG1=0;
 ADCON1.PVCFG0=0;
 // +Vref = AN3
 // ADCON1.PVCFG1=0;
 // ADCON1.PVCFG0=1;
 // +Vref = FVR BUF2
 // ADCON1.PVCFG1=1;
 //ADCON1.PVCFG0=0;
 ADCON1.NVCFG1=0;   // -Vref = Gnd AVss
 ADCON1.NVCFG0=0;
 }

 void Init_Hardware()
{
  PORTB = 0x00;
  TRISB = 0xFF;    //  B0,B1 as input   ATTENTION B7 B6 for ICSP Pickit3
  ANSELB=0;

  PORTA = 0b00001111;
  ANSELA=0;
 // ANSELA.ANSA0=1;    //  analog input on Port A   voir page 154
 // ANSELA.ANSA1=1;
  TRISA = 0b00001111 ;   // PORTA is RA0,1= analog input  RA2=sortie DAC RA3 input, RA4,5=Digital output
  PORTA=0;

  PORTC = 0x00;          // RC0..RC5,RC7 = input RC6=Output
  ANSELC=0;
  TRISC = 0xFF;    //
  TRISC.TRISC3 = 1;  // SCL I2C
  TRISC.TRISC4 = 1;  // SDA I2C
  TRISC.TRISC7 = 1;  // RX - UART1
  TRISC.TRISC6 = 0;  // TX - UART1

  SLRCON=0; // standard rate for PORTA,B,C,D,E
 }



unsigned int lecture_trame_rc5()
{   unsigned int i,val;
        if (IRC5_PIN==1)      // Récepteur Infrarouge
        {
        while (IRC5_PIN== 1){};            // Ligne au repos
       //Delay_us(1778/8);               // Après passage à l'état bas on attend 1/4 d'un bit
       Delay_us(220);
         for (i=0;i<14;i++)            // On lit les 14 bits
        {
           buffer1[i] = !IRC5_PIN;
         //   Delay_us(1778/2);// 1778µS Q=20Mhz
          Delay_us(875);// 1778µS Q=20Mhz
        }
      // On récupère les 6 derniers bits de Commande
        val=buffer1[13]+2*buffer1[12]+4*buffer1[11]+8*buffer1[10]+16*buffer1[9]+32*buffer1[8];
        }
 return (val);
 }
 
void Beep(long ton)
{
// ton=120 => 262Hz
// ton=60  => 520Hz
int i=0;
  while(i<100)
  {
      Beeper=0;
      Tempo(ton);
      Beeper=1;
      Tempo(ton);
      i++;
  }
}

// *****************************************

void main() 
{
   Delay_ms(1000);
   Init_Hardware();
   Delay_ms(1000);

   txt=&Texte[0];    // init pointeur

 // Compteur_Sec=0;
 // compteur_it=0;
   // --- Init RS232 ------
  UART1_Init(9600);
  Delay_ms(100);
 // UART1_Write(CLS);
 // Delay_ms(1000);
  CRLF();
 // Read_Msg_Eeprom(0x0000)  ;
 
 // Presentation
  UART1_Write_CText(chaine2);
    UART1_Write_CText(chaine12);
      UART1_Write_CText(chaine11);
        UART1_Write_CText(chaine4);
          UART1_Write_CText(chaine1);
  CRLF();
  Delay_ms(1000);
  Read_Msg_Eeprom(0x0010)  ;
  clk = Clock_kHz(); 
  WordToStr(clk , txt);
  UART1_Write_Text(txt);
  UART1_Write_CText(" Khz \r\n");

  CRLF();
  Read_Msg_Eeprom(0x0020)  ;
  UART1_Write('#');
  CRLF();
  delay_us(2000000);   // Mesure duree reelle via time Terminal VBray
  CRLF();
  UART1_Write ('*');
  CRLF();

   IRC5_state = IRC5_IDLE ;
   for (i=0; i< sizeof (IRC5_times); i ++) IRC5_times[i] = 0 ;
 
   Init_Timer0() ;
 
  INTCON3=0;
  PIE1=0;
  PIE2=0;
  INTCON3=0;
  RCON.IPEN=1;
  IR_Index=0;
  
  // Enable RB0 external interrupt
  INTCON.T0IE = 0;      // disable timer 0 interrupt for now
  INTCON2.INTEDG0    = 0;            // start with downgoing edge
  INTCON.INT0IF      = 0;            // Clear interrupt

  Volume=0;
  CptCars=0; 
  Drapeaux.Accumule=0;
  Fx[0]=0;
  f1=0.0;
  IR.received = 0 ;
  last_toggle = 2 ; // Impossible
  
   Read_Msg_Eeprom(0x0030)  ;
   CRLF();
  
  T0CON.TMR0ON=1;
  INTCON.PEIE = 1;
  INTCON.TMR0IE  = 1;  // Enable Timer0 interrupt
  INTCON.INT0IE      = 1;       // Enable RB0 interrupt
  INTCON.GIE         = 1;      // bit7 global interrupt enable
  
  //compteur=0;
   
  // ------ boucle Principale -------------
 do
 {

//------- IR capture
  if (IR.received==1)
  {
   Led_Rouge=0;
   INTCON.INT0IE=0 ; // disable RB0 interrupt
   INTCON.GIE     = 0;
   dev = IR.device ;
   cmd = IR.command;
   IR.received = 0 ;  // Processed the command
     if (last_toggle == IR.toggle)
   {
      repeat ++ ;
      } else
     {
      repeat = 0 ;
      last_toggle = IR.toggle;
  }
  #ifdef DEBUG_IR
   UART1_Write_CText("Dev=");
   Write_Word(dev,0);
   UART1_Write(TAB);
   strcpypgm2ram(txt,IRC5_Str[0]);  // cmd
   UART1_Write_Text(txt);
   Write_Word(cmd,0);
   UART1_Write(TAB);
  #endif

   switch (cmd)
   {

     case 0:
     case 1:
     case 2:
     case 3:
     case 4:
     case 5:
     case 6:
     case 7:
     case 8:
     case 9:
            // cmd
            UART1_Write_CText(IRC5_Str[1]);
            UART1_Write(TAB);UART1_Write(cmd+48);
            UART1_Write(TAB);
            if (CptCars==0)Drapeaux.Accumule=1;
            if (Drapeaux.Accumule)
            {
                  Fx[CptCars]=cmd+48;
                  if (CptCars<16)CptCars++;
                  Fx[CptCars]=0;
                   UART1_Write_Text(Fx);
             }
            break;
     case 13:// mute
             UART1_Write_CText(IRC5_Str[8]);

             break ;
     case 15:   //OSD
           UART1_Write_CText(IRC5_Str[9]);
            break ;
    case 16:   //Volume up
            Texte[0]=0;txt=&Texte[0];
             UART1_Write_CText(IRC5_Str[4]);  // ON
            UART1_Write(TAB);
            //UART1_Write_CText("Volume =");
            if(Volume<2000000000)  // 2^32
            {
                Volume++;
                Texte[0]=0;txt=&Texte[0];
               LongWordToStr(Volume,txt); // <-----------------  OK
               //sprintf(txt, "% 9lu",Volume);// <------ PB
               UART1_Write_Text(txt);
            }
            break ;
     case 17:  //Volume down
            Texte[0]=0;txt=&Texte[0];
             UART1_Write_CText(IRC5_Str[5]);  // OFF
            UART1_Write(TAB);
            //UART1_Write_CText("Volume= ");
            if(Volume>0)
            {
                Volume--;
                Texte[0]=0;txt=&Texte[0];
               LongWordToStr(Volume,txt);  // <---------------------- OK
               //sprintf(txt,"% 9lu",Volume);  // <-- probleme si %lu
               UART1_Write_Text(txt);
            }
            break ;
     case 23:   // ok   VALIDATION saisie
            if(dev==0)
            {
             UART1_Write_CText(IRC5_Str[6]);  // OFF
            UART1_Write(TAB);
             if ((CptCars>0) && (Drapeaux.Accumule==1))
            {
             f1=atof(Fx);
              UART1_Write_Text(Fx);
             Drapeaux.Accumule=0;
             CptCars=0;
              }
             }
            break ;
    case 24:   //Aigu UP
             UART1_Write_CText(IRC5_Str[16]);  // OFF
            break ;
    case 25:   //Aigu DOWN
            UART1_Write_CText(IRC5_Str[17]);
            break ;
     case 28:   //Haut
          UART1_Write_CText(IRC5_Str[10]);
           break ;
     case 29:  //bas
          UART1_Write_CText(IRC5_Str[11]);
           break ;
     case 32:   //channel >>
          UART1_Write_CText(IRC5_Str[19]);
           break ;
     case 33:   // channel <<
          UART1_Write_CText(IRC5_Str[20]);
          break ;
     case 34:   //S-direct = correction
          UART1_Write_CText(IRC5_Str[14]);
          if (CptCars>0)
            {
             CptCars--;
             Fx[CptCars]=0;
              UART1_Write_Text(Fx);
            }
            break ;
      case 38:   //sleep
            UART1_Write_CText(IRC5_Str[15]);
            break ;
     case 41:  //PTV   POINT CARRE decima
            UART1_Write_CText(IRC5_Str[18]);
            // gestion point decimal
           if ((CptCars>1)&& (Drapeaux.Accumule==1))
            {
             Fx[CptCars]='.';
             if (CptCars<16)CptCars++;
             Fx[CptCars]=0;
              UART1_Write_Text(Fx);
           }
            break ;
     case 43:   // droite
            UART1_Write_CText(IRC5_Str[2]);
            break ;
     case 44:   // gauche
          UART1_Write_CText(IRC5_Str[3]);
           break ;
      case 46:   // menu
          UART1_Write_CText(IRC5_Str[7]);
          break ;
       case 49: //clear
            UART1_Write_CText(IRC5_Str[12]);
            CptCars=0; Drapeaux.Accumule=0;Fx[0]=0;f1=0;
            break ;
      case 60: //memo
            UART1_Write_CText(IRC5_Str[13]);
            UART1_Write(TAB);
           //  if ((CptCars>0) && (Drapeaux.Accumule==1))
           // {
           //  f1=atof(Fx);
           //  UART1_Write(Fx);
             Float2Ascii (f1,txt,3);
             UART1_Write_Text(txt);  UART1_Write(TAB);
             M1=(long)(ceil(f1)) ;
              UART1_Write_CText(" M1= ");
             txt=&Texte[0];
             LongWordToStr(M1, txt);
             UART1_Write_Text(txt); UART1_Write('L');
           //   }
            break ;
     default:
       break;
    } // fin du switch

    // if (IR.toggle)
    //{
    // Put_RS(TAB); Put_RS('T');Put_RS(' ');
    // Write_Word(repeat,0);
    // }
     CRLF();
     INTCON.INT0IE=0 ; // disable RB0 interrupt
    if (cmd<10)Beep(60); else Beep(120);
     // Delay10KTCYx(10); //  =144mS= > 1 trame + salve
     INTCON.INT0IF = 0;  // Clear flag interrupt
     INTCON.INT0IE=1 ; // disable RB0 interrupt
     Led_Rouge=0;
    INTCON.GIE     = 1;
   } //IF IR.received
  }while(1);
}

/*

PROJET MikroC : IRC5_18F26K22.mcppi
C:_MikroC_MesProjets_MikroC_IRC5IRC5_18F26k22_150330.c
IR TSOP36 Capture via IT sur RB0
MARANTZ RC5200SR
Port comm 19200 ouvert
FOSC  =         10000 Khz

Test Delay 2s
#

*
Start detect IRC5 detection

Haut
Bas
Droite
Gauche
OK
Vol.+            1
Vol.+            2
Vol.-            1
Vol.-            0
Osd
Menu
Channel >>
Channel <<
Aigu +
Aigu -
sleep
Mute
Vol.+            1
Vol.+            2
Vol.+            3
Vol.+            4
Vol.+            5
Vol.+            6
Vol.-            5
Vol.-            4
Vol.-            3
Num     1       1
Num     2       12
Num     3       123
Num     4       1234
Num     5       12345
point 12345.
Num     4       12345.4
Num     5       12345.45
Num     8       12345.458
Num     9       12345.4589
Memo    k     12346
Clear
Num     1       1
Num     2       12
point 12.
Num     8       12.8
Num     6       12.86
Num     2       12.862
Num     1       12.8621
Memo    k        13

*/