////////////////////////////////////////////////////////////////////////////
//
//   KNIHOVNA PRO PRACI S TOUCH MEMORY FY DALLAS
//
////////////////////////////////////////////////////////////////////////////
//
// PEFI S.ICZ a.s. 2002, 2003
//
// Verze 1.0
//       1.1 - pridana podpora vypinani pullupu
//              pres pin TOUCH_PULLUP_PIN
//       1.2 - vyrazena podpora pullupu, do obecne knihovny nepatri
//           - funkce checkCRC se stala soucasti fce read_sn
//           - upraveny nazvy funkci, zpetna kompatibilita neni potreba
//       1.3 - pridana samostatna funkce pro kontrolu CRC
//
///////////////////////////////////////////////////////////////////////////
//
// funkce:
//  int8 TM_present()
//   - vraci TRUE, pokud je TM pritomna
//
//  int8 TM_read_byte()
//   - precte bajt z TM
//
//  int8 TM_write_byte(int8 data)
//   - zapise bajt do TM a vraci TRUE, pokud se to povedlo
//
//  int8 TM_read_sn(int8 *sn)
//   - precte seriove cislo z TM pomoci prikazu 0x33
//   - vraci TRUE, pokud je SN platne (spravne CRC)
//
//  definice a prepinace
//  #define TM_PIN                  /* pin, na kterem je touch memory pripojena */
//  #bit    TM_PIN_BIT              /* totez, ale definovan jako bit */
//
//
// defaultni definice
#ifndef TM_PIN
#define TM_PIN  PIN_B0
#bit    TM_PIN_BIT = PORTB.0
#endif





/****************************************************************************************************/
// Privatni sekce, cist jen v pripade, ze neco nefunguje
/****************************************************************************************************/
// precte bajt z touch memory
//
int8 TM_read_byte() {
   int8 i,data;

   for(i=0;i<8;++i) {
     output_low(TM_PIN);
     delay_us(14);
     output_float(TM_PIN);
     delay_us(5);
     shift_right(&data,1,input(TM_PIN));
     delay_us(100);
   }
   return(data);
}


// zapise bajt do touch memory
//
int8 TM_write_byte(int8 data) {
   int8 i;

   for(i=0;i<8;++i) {
     output_low(TM_PIN);
     delay_us(10);
     if(shift_right(&data,1,0)) {
       output_float(TM_PIN);
       delay_us(1);           // k vuli nabehu jednicky pres pullup
       if(!TM_PIN_BIT)   return(0);
     } else {
       output_low(TM_PIN);
       if(TM_PIN_BIT)    return(0);  // k vuli nabehu nuly
     }
     delay_us(50);
     output_float(TM_PIN);
//     delay_us(50);
   }
   return(TRUE);
}


// testuje pritomnost touch memory, pri pritomnosti vraci TRUE
//
int8 TM_present() {
    int1 present;

    output_low(TM_PIN);
    delay_us(500);
    output_float(TM_PIN);
    if(!input(TM_PIN))
      return(FALSE);
    delay_us(65);
    present=!input(TM_PIN);
    delay_us(240);
    if(present)
      return(TRUE);
    else
      return(FALSE);
}

// zkontroluje CRC zaznamu, vraci TRUE, pokud je zanam spravny
//
int8 TM_check_CRC(unsigned int8 *sn, unsigned int8 num)
{
#ifdef CRC_TAB
// tabulka pro vypocet CRC
   const  int8 TouchCRC[256]= {
      0,  94, 188, 226,  97,  63, 221, 131, 194, 156, 126,  32, 163, 253,  31,  65,
      157, 195,  33, 127, 252, 162,  64,  30,  95,   1, 227, 189,  62,  96, 130, 220,
      35, 125, 159, 193,  66,  28, 254, 160, 225, 191,  93,   3, 128, 222,  60,  98,
      190, 224,   2,  92, 223, 129,  99,  61, 124,  34, 192, 158,  29,  67, 161, 255,
      70,  24, 250, 164,  39, 121, 155, 197, 132, 218,  56, 102, 229, 187,  89,   7,
      219, 133, 103,  57, 186, 228,   6,  88,  25,  71, 165, 251, 120,  38, 196, 154,
      101,  59, 217, 135,   4,  90, 184, 230, 167, 249,  27,  69, 198, 152, 122,  36,
      248, 166,  68,  26, 153, 199,  37, 123,  58, 100, 134, 216,  91,   5, 231, 185,
      140, 210,  48, 110, 237, 179,  81,  15,  78,  16, 242, 172,  47, 113, 147, 205,
      17,  79, 173, 243, 112,  46, 204, 146, 211, 141, 111,  49, 178, 236,  14,  80,
      175, 241,  19,  77, 206, 144, 114,  44, 109,  51, 209, 143,  12,  82, 176, 238,
      50, 108, 142, 208,  83,  13, 239, 177, 240, 174,  76,  18, 145, 207,  45, 115,
      202, 148, 118,  40, 171, 245,  23,  73,   8,  86, 180, 234, 105,  55, 213, 139,
      87,   9, 235, 181,  54, 104, 138, 212, 149, 203,  41, 119, 244, 170,  72,  22,
      233, 183,  85,  11, 136, 214,  52, 106,  43, 117, 151, 201,  74,  20, 246, 168,
      116,  42, 200, 150,  21,  75, 169, 247, 182, 232,  10,  84, 215, 137, 107,  53};
#else
  int8 j,k,l;  // promenne potrebne pro algoritmicky vypocet CRC
#endif
  int8 CRC; // prubezne CRC
  int8 i;


#ifdef CRC_TAB
   // vypocet CRC tabulkou
   CRC=0;
   for(i=0;i<num;i++)  CRC=TouchCRC[CRC ^ *(sn+i)];
   if(CRC!=*(sn+7)) return(0);
     else return(1);
#else
   // vypocet CRC algoritmicky
   CRC=0;
   for(i=0 ;i<num;i++) {
     k=*(sn+i);
     #asm
              movlw  8
              movwf  j        // citac bitu
loop:
              movf   k,W      // presun bajt do W
              xorwf  CRC,W    // prixoruj CRC a uloz do w
              movwf  l
              rrf    l,F      // naxorovany bit do CY
              movf   CRC,W
              btfsc  3.0      // preskoc, je-li CY nulove
              xorlw  0x18
              movwf  CRC
              rrf    CRC,F    // rotuj CRC
              rrf    k        // na dalsi bit
              decfsz  j,F
              goto   loop
     #endasm
   }
   if(CRC!=0) return(0);
     else return(1);
#endif
}


// precte seriove cislo z touch memory, vraci TRUE je-li platne (spravne CRC)
//
int8 TM_read_sn(unsigned int8 *sn)
{
 int8 i;
   // precteni SN z touch memory
   TM_write_byte(0x33);
   for(i=0;i<8;i++) *(SN+i)=TM_read_byte(); // precti SN do buferu

   if(*sn==0) return(0);  // family kod je nulovy a to je chyba, timto nahrazujeme precteni samych nul, coz ma platne CRC, ale neexistuje
   return(TM_check_CRC(SN,8));
}
// End of FIle