// DS1822OD.c
// Open Drain IO Port specific
// 09/02/2005

#include <p18f452.h> // For port definition
#include "Wait.h" // For wait macros
#include "DS1822OD.h"

// Wait macros that have to be defined
// Wait_7us() 
// Wait_70us()  
// Wait_500us()

// Port/pin usage
#define DSOD_PIN PORTAbits.RA4
#define DSOD_DIR TRISAbits.TRISA4

// DS1822 Commands
#define DS_SKIP_ROM      0xCC
#define DS_START_CONV    0x44
#define DS_READ_SCRATCH  0xBE
#define DS_WRITE_SCRATCH 0x4E

// Internals
UInt8 OneWireResetOD();
UInt8 OneWireReadByteOD();
void OneWireWriteByteOD(UInt8 data);


//
// ONE WIRE specific
//

// Return value :
// 0 : No sensor or error
// 1 : Sensor detected
UInt8 OneWireResetOD() {
	if (!DSOD_PIN) return 0; // Bus is stucked at 0. Error
  DSOD_PIN = 0; 
  DSOD_DIR = 0; // Output. Initiate the time slot 
  Wait_500us();
  DSOD_DIR = 1; // Input. Release the bus
  Wait_70us();
  
  if (!DSOD_PIN) { // 0 => Get the answer from the sensor
    Wait_500us();
    return 1; // Sensor present
  }
  
  Wait_500us();
  return 0;
}

UInt8 OneWireReadByteOD() {
  UInt8 data = 0;
  UInt8 i;
  for (i=0;i<8;i++) {
    // Initiate time slot.
    DSOD_DIR = 0; // Output. Initiate the time slot 
    Wait_7us();

    // Release the bus
    DSOD_DIR = 1; // Input. Release the bus
    Wait_7us();
    data >>=1;

    // Sample
    if (DSOD_PIN) data |= 0x80;
    else data &= 0x7f;

    Wait_70us(); // Wait the end of the time slot
   }
  return data;
}

void OneWireWriteByteOD(UInt8 data) {
  UInt8 i;
  for (i=0;i<8;i++) {
    DSOD_DIR = 0; // Output : Initiate the time slot
    if (data & 0x01) { // Send 1
      Wait_7us();        
      DSOD_DIR = 1; // Input : Release the bus
      Wait_70us();
    }
    else { // Send 0
      Wait_70us();         // Send 0
      DSOD_DIR = 1; // Input : Release the bus
      Wait_7us();
    }
    data>>=1;
  }
}

//
// DS1822 specific
//

// Return value :
// 0 : Failed
// 1 : Conversion started
UInt8 DS1822OD_StartConversion () {
  if (!OneWireResetOD()) return 0;

  OneWireWriteByteOD(DS_SKIP_ROM);
  OneWireWriteByteOD(DS_START_CONV);
  return 1;
}

// Return value :
// 0 : Failed
// 1 : OK
UInt8 DS1822OD_ReadTemperature(UInt8 *lsb, UInt8 *msb) {
  *lsb = 0x00;
  *msb = 0x00;
  if (!OneWireResetOD()) return 0; // Error	
  
  OneWireWriteByteOD(DS_SKIP_ROM);
  OneWireWriteByteOD(DS_READ_SCRATCH);
  //*lsb = 0x91;
  *lsb = OneWireReadByteOD();
  //*msb = 0x01;
  *msb = OneWireReadByteOD();
  
  OneWireResetOD(); // Abort transfert
  
  return 1; // Valid
}

// Return value :
// 0 : Failed
// 1 : Conversion started
UInt8 DS1822OD_Init (UInt8 mode) {
  DSOD_DIR = 1; // Input
  DSOD_PIN = 0; // Ready to pull down
  if (!OneWireResetOD()) return 0;

  OneWireWriteByteOD(DS_SKIP_ROM);
  OneWireWriteByteOD(DS_WRITE_SCRATCH);
  OneWireWriteByteOD(0); // Dummy Th
  OneWireWriteByteOD(0); // Dummy Tl
  OneWireWriteByteOD(mode);
  return 1;
}


// End of file
