


// Zaklad programu byl prevzat a upraven odsud:
//       http://www.airspayce.com/mikem/bcm2835/input_8c-example.html



#include <bcm2835.h>
#include <stdio.h>


#define PIN  RPI_GPIO_P1_15   // pin, na kterem visi infra cidlo (GPIO22 = HW pin 15)
#define LED1 RPI_GPIO_P1_24   // pin, na kterem je pripojena prvni LED  (GPIO8 = HW pin 24)
#define LED2 RPI_GPIO_P1_26   // pin, na kterem je pripojena druha LED  (GPIO7 = HW pin 26)


 



int main(int argc, char **argv)
{

// If you call this, it will not actually access the GPIO
// Use for testing
// bcm2835_set_debug(1);
if (!bcm2835_init())     // opsano - netusim, co to ma delat, ale bez toho to nefunguje
  return 1;




bcm2835_gpio_fsel(LED1, BCM2835_GPIO_FSEL_OUTP);  // GPIO pin s LED1 na vystup
bcm2835_gpio_fsel(LED2, BCM2835_GPIO_FSEL_OUTP);  // GPIO pin s LED2 na vystup
bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_INPT);   // GPIO pin s cidlem na vstup
bcm2835_gpio_set_pud(PIN, BCM2835_GPIO_PUD_UP);   //     ... a pripojit na nej vnitrni Pull-Up odpor





// definice typu promennych
int citac;           // promenna (ukazatel) do ruznych smycek
int sken[1500];      // sem se uklada 1500 rychlych vzorku z GPIO pinu pri skenovani portu.
int minulystav;      // promenna pro zjistovani, kdy doslo ke zmene v naskenovane sekvenci
int pocetvzorku;     // pocet stejnych vzorku v rade 
char kod[40];        // kod stisknuteho tlacitka - prepocitany z dlouhe sekvence jednicek a nul
int pozicevkodu;     // ukazatel na jednotlive pozice v kodu tlacitka
char tlacitko;       // oznaceni tlacitka (v tomto prikladu '1' az '5' nebo mezera)
int stav;            // aktualni stav vstupniho GPIO pinu


while (1)  // nekonecna smycka
  {
  
//===================================================
    // cekani na prvni nulu na GPIO pinu
    stav = 1;
    while (stav != 0)
     {
      stav = bcm2835_gpio_lev(PIN);
      delay(1);          // uvodni '0' je dost dlouha, tak se muze cekat delsi dobu, nez pri skenovani
     }
    
    
    
//===================================================
    // rychle naskenovani 1500 vzorku
    citac = 0;
    while (citac < 1500)
     {
      stav = bcm2835_gpio_lev(PIN);        // cteni stavu GPIO pinu s cidlem
      sken[citac] = stav;              // a ukladani do promenne s nazvem 'sken'
      citac ++ ;
      usleep(10);          // pro spicky trvajici 0,6ms se pri pauze 10us nasbira asi 8 vzorku
     }
    
    
//===================================================
    //   zobrazeni vsech naskenovanych dat
      for (citac = 0; citac < 1500 ; citac ++)
        {
           printf("%d",  sken[citac]);
        }
      printf("\n\n");
    
    
    
    
//===================================================
    // analyza naskenovanych dat - prevedeni na kod tlacitka - na znaky 'Z', 'H', '1', '0' a 'K'.

    minulystav   = 1;
    pocetvzorku  = 0;
    pozicevkodu  = 0;
    
    for (citac = 0; citac < 1500 ; citac ++)
     {
    
    
    
    
       if (sken[citac] == minulystav )   // pocitani delky pulzu (pocet stejnych vzorku v rade)
          pocetvzorku ++ ;
        
            
    
    
       if (sken[citac] == 1 && minulystav == 0)   // zmena stavu z '0' na '1'
        {
//           printf("0...[%d]\n",  pocetvzorku);       // tisk celkoveho poctu nulovych vzorku v rade
           if (pocetvzorku > 20)        // zacatek prijimanych dat (dlouha '0') - pri testu to bylo az pres 70
            {
             kod[pozicevkodu] = 'Z';
             pozicevkodu ++;
            }
           pocetvzorku = 1 ;
           minulystav = 1;
        }
    
    
    
    
       if (sken[citac] == 0 && minulystav == 1)    // zmena stavu z '1' na '0'
        {
//           printf("1...[%d]\n", pocetvzorku);        // tisk celkoveho poctu jednickovych vzorku v rade
           if (pocetvzorku > 28 && pocetvzorku < 80)  // delsi jednckovy zavadeci signal - pri testu asi 50 vzorku
            {
             kod[pozicevkodu] = 'H';
             pozicevkodu ++;
            }
    
    
           if (pocetvzorku > 2 && pocetvzorku < 10)     // nulovy bit v kodu tlacitka - obvykle mezi 5 a 7 vzorky
            {
             kod[pozicevkodu] = '0';
             pozicevkodu ++;
            }
    
          
           if (pocetvzorku > 14 && pocetvzorku < 25)    // jednickovy bit v kodu tlacitka - obvykle kolem 19 vzorku
            {
             kod[pozicevkodu] = '1';
             pozicevkodu ++;
            }
    
    
           if (pocetvzorku > 150)        // konec kodu tlacitka - velice dlouha rada jednickovych vzorku
            {
             kod[pozicevkodu] = 'K';
             pozicevkodu ++;
             break;
            }
    
    
           pocetvzorku = 1 ;
           minulystav  = 0 ;
    
    
        }
    
     }
    
//===================================================
    // testovani na spravny a kompletni format kodu tlacitka vcetne vyhodnoceni 6 tlacitek na ovladaci
    tlacitko = ' ';

    if (kod[0] == 'Z' && kod[1] == 'H' && kod[34] == 'K') // prvni 2 znaky musi byt 'ZH' a 34. znak 'K' 
      {

        if (kod[18] == '0' && kod[19] == '0' && kod[20] == '0')    // tlacitko 1
          {
           tlacitko = '1';
           bcm2835_gpio_write(LED1, HIGH);  // rozsviceni LED1
          }

        if (kod[18] == '1' && kod[19] == '0' && kod[20] == '0')    // tlacitko 2
          {
           tlacitko = '2'; 
           bcm2835_gpio_write(LED2, HIGH);   // rozsviceni LED2
          }

        if (kod[18] == '0' && kod[19] == '1' && kod[20] == '0')    // tlacitko 3
          {
           tlacitko = '3'; 
          }

        if (kod[18] == '1' && kod[19] == '1' && kod[20] == '0')    // tlacitko 4
          {
           tlacitko = '4'; 
           bcm2835_gpio_write(LED1, LOW);   // zhasnuti LED1
          }

        if (kod[18] == '0' && kod[19] == '0' && kod[20] == '1')    // tlacitko 5
          {
           tlacitko = '5'; 
           bcm2835_gpio_write(LED2, LOW);   // zhasnuti LED2
          }

//        if (kod[18] == '1' && kod[19] == '0' && kod[20] == '1')    // tlacitko 6 - konec programu
//          {
//           bcm2835_close();     // ukonceni programu
//           return 0;
//          }
    
        //  zobrazeni kodu na obrazovce a jeho nasledne vymazani z pameti po jednotlivych znacich 
      }

      for (citac = 0; citac < 35 ; citac ++)
       {
         printf("%c" , kod[citac] );
         kod[citac] = ' ';
       }

      // kdyz je vyhodnoceno preddefinovane tlacitko, tak se jeho popis jeste zobrazi za kodem
      if (tlacitko != ' ')
        printf(" = Tlacitko %c\n", tlacitko);
      else      
        printf("\n");         // odradkovani na konci sekvence, kdyz neni stisknuto preddefinovane tlacitko
    
    delay(200);    // pauza pred prijetim dalsi sekvence
  }


}