// ************************************************************************************
// **** PROGRAM = ELEKTRONICZNY PIRAT (C) 2010 LUCIDSCIENCE.COM
// **** PLATFORMA = ATMEGA88P
// **** ZEGAR = 8 MHZ WEWNTRZNY
// ************************************************************************************
#include <mega88p.h>
#include <delay.h>

// ************************************************************************************
// **** ZMIENNE PROGRAMU
// ************************************************************************************
unsigned char RC5[750];

// ************************************************************************************
// **** FUNKCJA ZAPISU
// ***********************************************************************************
void RECORD(){
  unsigned int CTR;
  unsigned char TMR;
  unsigned char REC;
  unsigned char DIV;

  // WCZENIE DIODY STANU
  PORTD.5 = 1;
  REC = 0;

  // SKASOWANIE PAMICI
  for (CTR = 0; CTR < 750; CTR++) RC5[CTR] = 0;

  // OCZEKIWANIE NA BIT STARTU
  while (PIND.1 == 1) {}

  // ZAPIS STRUMIENIA IMPULSW RC5
  for (CTR = 0; CTR < 375; CTR++) {

    // ZAPIS MODULOWANEGO IMPULSU
    TMR = 0;
    while (PIND.1 == 0) {

      // DZIELENIE CZASU PRZEZ 10
      for (DIV = 0; DIV < 10; DIV++) { //$$$

        // OPӏNIENIE 40 KHZ
        #asm
        ldi r23,66 ;1
        DL4:
        dec r23 ;1
        brne dl4 ;1/2
        nop ;1
        nop ;1
        #endasm
      }
      TMR++;
    }

    // ZAPIS CZASU
    RC5[CTR] = TMR;

    // ZWIKSZENIE LICZNIKA
    CTR++;

    // ZAPIS NIEMODULOWANEGO IMPULSU
    TMR = 0;
    while (PIND.1 == 1) {

      // DZIELENIE CZASU PRZEZ 10
      for (DIV = 0; DIV < 10; DIV++) { //$$$

        // OPӏNIENIE 40 KHZ
        #asm
        ldi r23,66 ;1
        DL5:
        dec r23 ;1
        brne dl5 ;1/2
        nop ;1
        nop ;1
        #endasm
      }
      TMR++;
    }

    // ZAPIS CZASU
    RC5[CTR] = TMR;

    // MIGANIE DIODY STANU
    REC++;
    if (REC == 40) REC = 0;
    if (REC == 0 ) PORTD.5 = 1;
    if (REC == 20 ) PORTD.5 = 0;
  }

  // WYCZENIE DIODY STANU
  PORTD.5 = 0;

  // OCZEKIWANIE NA ZWOLNIENIE PRZYCISKU
  while (PIND.2 == 0){}
  delay_ms(500);
}

// ***********************************************************************************
// **** FUNKCJA ODTWARZANIA
// ***********************************************************************************
void PLAYBACK(){
  unsigned int CTR;
  unsigned char TMR;
  unsigned char DIV;

  // WCZENIE DIODY STANU
  PORTD.5 = 1;

  // ODTWORZENIE STRUMIENIA IMPULSW RC5
  for (CTR = 0; CTR < 375; CTR++) {

    // WYSANIE MODULACJI 40KHZ
    TMR = RC5[CTR];
    while (TMR > 0) {

      // DZIELENIE CZASU PRZEZ 10
      for (DIV = 0; DIV < 10; DIV++) {

        // CYKL MODULACJI 40 KHZ
        PORTD.0 = 1;
        #asm
        ldi r23,33 ;1
        DL1:
        dec r23 ;1
        brne dl1 ;1/2
        nop ;1
        #endasm
        PORTD.0 = 0;
        #asm
        ldi r23,33 ;1
        DL2:
        dec r23 ;1
        brne dl2 ;1/2
        nop ;1
        #endasm
      }
      TMR--;
    }

    // ZWIKSZENIE LICZNIKA
    CTR++;

    // WYSYANIE BEZ MODULACJI
    TMR = RC5[CTR];
    while (TMR > 0) {

      // DZIELENIE CZASU PRZEZ 10
      for (DIV = 0; DIV < 10; DIV++) { //$$$

        // BRAK CYKLU MODULACJI
        #asm
        ldi r23,66 ;1
        DL3:
        dec r23 ;1
        brne dl3 ;1/2
        nop ;1
        nop ;1
        #endasm
      }
      TMR--;
    }
  }

  // WYCZENIE DIODY STANU
  PORTD.5 = 0;

  // POWTRZENIE OPӏNIENIA
  delay_ms(100);
}

// ***********************************************************************************
// **** KONFIGURACJA PORTW IO
// ***********************************************************************************
void main(void)
{
  DDRD.0 = 1; // WYJCIE DLA DIODY PODCZERWONEJ LED
  DDRD.1 = 0; // WEJCIE DLA CZUJNIKA PODCZERWIENI
  DDRD.2 = 0; // WEJCIE DLA PRZYCISKU ZAPISU
  DDRD.3 = 0; // WEJCIE DLA PRZYCISKU ODTWARZANIA
  DDRD.4 = 0; // WEJCIE ZMIANY TRYBU (NIEUYWANE)
  DDRD.5 = 1; // WYJCIE DLA DIODY STANU

  // STAN WYSOKI NA WEJCIACH
  PORTD.1 = 1;
  PORTD.2 = 1;
  PORTD.3 = 1;
  PORTD.4 = 1;

  // ***********************************************************************************
  // **** GWNA PTLA PROGRAMU
  // ***********************************************************************************
  while (1)
  {

    // SPRAWDZENIE PRZYCISKW ZAPISU I ODTWARZANIA
    if (PIND.2 == 0) RECORD();
    if (PIND.3 == 0) PLAYBACK();

    // KONIEC GWNEJ PTLI
  };
}
