/************************************************************************/
/*  FILE        : onewire.c												*/
/*  DESCRIPTION : 1-WIRE COMMUNICATION PROTOCOL							*/
/*																		*/
/*																		*/
/************************************************************************/

#include "includes.h"


//****************************************************************************
// OW_CRC()
//****************************************************************************
tUInt OW_CRC( tUChar *iButtonData, tUChar len) 
{
    tUInt k, j;
    tUChar b, m, res;

	res = 0;

    for (k = 0; k < len; ++k)
	 {
       b = iButtonData[k];
       for (j = 0; j < 8; ++j)
		 {
           m = (res ^ b) & 0x1;
           res >>= 1;
           if (m)
            {  res ^= 0x8c; }
           b >>= 1;
        }
    }
    return res;
}


/************************************************************************/
// Function:        OW_DriveLow()
/************************************************************************/
void OW_DriveLow (void)
{
  OW_PIN_DIRECTION_OUTPUT;
  OW_PIN = LOW;
}


/************************************************************************/
// Function: OW_DriveHigh()
/************************************************************************/
void OW_DriveHigh (void)
{
   OW_PIN_DIRECTION_OUTPUT;
   OW_PIN = HIGH;        
}



/************************************************************************/
// Function:  tick_delay()
/************************************************************************/
void tick_delay(tUInt time);
__attribute__ ((section (".page0f21"))) void tick_delay(tUInt time)
{
	asm ("fclr i");					// ALL_InterruptDisable;									
    asm ("nop");
																						
	asm ("mov.w	r1,a0");			// vstupni hodnota je v R1
		
	asm ("TICK_DELAY:");			// cekaci smycka
	asm ("dec.w	a0");	
	asm ("cmp.w	#0, a0");	
	asm ("jnz TICK_DELAY");

    asm ("fset i");					// enable interrupts
	asm ("exitd");					// deallocate stack frame
}														
	
	
	
//----------------------------------------------------------------------------//
// Function:        unsigned char OW_Reset(void)
// PreCondition:    None
// Input:           None
// Output:          Return the Presense Pulse from the slave.
// Overview:        Initialization sequence start with reset pulse.
//----------------------------------------------------------------------------//
tUInt OW_Reset(void)
{
  unsigned char presence_detect;
  tUChar loop;
  tUInt retvalue;


  loop = 0;					// nastavit timer na 1 sekundu, ale jen 1x, a po tuto dobu osahavat cteci hlavu jestli je stale zkrat

	  
  /*do {
	   ClearWDT();
	   tick_delay(2500);
	   loop++;
	   if (loop == 100)
	   return (OW_SHORT);	// zkrat pretrvava, je to zkrat
	 } while (!OW_PIN);		// detekovat stav kdy nastane navrat do log.1 - tj. cip je ustalen ve cteci hlave a ceka na reset
	 
  */

  ALL_InterruptDisable;
  ALL_TimersInterruptDisable;
       
  OW_PIN_DIRECTION_OUTPUT;
  OW_DriveLow();                 // Drive the bus low
  tick_delay(1348);		         // delay 590 microsecond (us) podle EDK2
  OW_DriveHigh();	             // Release the bus
  OW_PIN_DIRECTION_INPUT;

  tick_delay(100);				 // pockat na vysilani SLAVE
  presence_detect = OW_PIN;

  tick_delay(500);               // delay 410 microsecond (us)
  OW_DriveHigh();                // Release the bus
  
  
  ALL_TimersInterruptEnable;
  ALL_InterruptEnable;
  	         
  if (!presence_detect)			// detekovan reset puls do log.0?
    retvalue = OW_RESET_OK;
  else
    retvalue = OW_NO_RESET;


  return (retvalue);
}        



/************************************************************************/
// Function:  OW_WriteBit
// Overview:  This function used to transmit a single bit to slave device.
/************************************************************************/
void OW_WriteBit (unsigned char write_bit)
{
   if (write_bit)
    {
      //writing a bit '1'
      OW_DriveLow();
      tick_delay(1);
      OW_DriveHigh(); 
      tick_delay(80);
    }
    //writing a bit '0'
    else	
     {
       OW_DriveLow();          // Drive the bus low
       tick_delay(80);         // delay 60 microsecond (us)
       OW_DriveHigh();         // Release the bus
       tick_delay(1);
     }
}        


/************************************************************************/
// Function:  OW_ReadBit
// Overview:  This function used to read a single bit from the slave device
/************************************************************************/
unsigned char OW_ReadBit (void)
{
  unsigned char read_data;   

 // LED_RED_ON;
  OW_DriveLow();    		// puls dolu
  //tick_delay(1);			// delay po pulsu dolu
  OW_DriveHigh();   		// puls nahoru
  OW_PIN_DIRECTION_INPUT;	// prepnout pin na vstup 
  tick_delay(1);			// delay pred nactenim pinu

 // LED_RED_OFF;	
  if (OW_PIN)
   {
	 read_data = 1;			// nacteni stavu pinu 
   }
  else         
   {
	 read_data = 0;
   }

// nutno pockat na uvolneni pulsu od onewire zarizeni
  do {
	  ClearWDT();
      tick_delay(10); 			
     }
  while (!OW_PIN);	 
  

  return read_data;
}


/************************************************************************/
// Function:  OW_WriteByte
// Overview:  This function used to transmit a complete byte to slave device
/************************************************************************/
void OW_WriteByte (unsigned char write_data)
{
   unsigned char i;

   ALL_InterruptDisable;
   ALL_TimersInterruptDisable;
           
   for (i = 0; i < 8; i++)
    {
      OW_WriteBit(write_data & 0x01);   // Sending LS-bit first
      write_data >>= 1;                 // shift the data byte for the next bit to send
    }        

   ALL_TimersInterruptEnable;
   ALL_InterruptEnable;
}        



/************************************************************************/
// Function:  OW_WriteInt
// Overview:  This function used to transmit a complete byte to slave device
/************************************************************************/
void OW_WriteInt (unsigned int write_data)
{
   unsigned char i;

   ALL_InterruptDisable;
   ALL_TimersInterruptDisable;
           
   for (i = 0; i < 16; i++)
    {
      OW_WriteBit(write_data & 0x01);      // Sending LS-bit first
      write_data >>= 1;                       // shift the data byte for the next bit to send
    }        

   ALL_TimersInterruptEnable;
   ALL_InterruptEnable;

}        


/************************************************************************/
// Function:  OW_ReadByte
// Overview:  This function used to read a complete byte from the slave device
/************************************************************************/
unsigned char OW_ReadByte (void)
{
   unsigned char i, result=0;

   ALL_InterruptDisable;
   ALL_TimersInterruptDisable;
           
   for (i = 0; i < 8; i++)
    {
      result >>= 1;               // shift the result to get it ready for the next bit to receive
      if (OW_ReadBit() )
       { result |= 0x80; }            // if result is one, then set MS-bit
    }

   ALL_TimersInterruptEnable;
   ALL_InterruptEnable;

   return result;                                        
}        
