/******************************************************************************/
/* Programček za dostop do DS1820 senzorja                                    */
/* By P&P 24.9.2012                                                           */
/******************************************************************************/
#include <stdio.h>
#include "LPC13xx.h"                        // LPC13xx definitions ^
#include "systick_pp.h"
#include "DS1820_pp.h"
#include "LCD.h"

/******************************************************************************/
/* DS1820 je priključen na pin:                                               */
/* PIO3.1      Pin37 -> P0.26  ->P10-Pin1                                     */
/******************************************************************************/

#define PIN_DS1820                 (1 << 1)                     // ...0000 0010
// Pin da na izhod 1 ali 0
#define DS1820_Data(x) ((x) ? (LPC_GPIO3->DATA |= PIN_DS1820)  : (LPC_GPIO3->DATA &= ~PIN_DS1820) ); 
// Pin beremo
#define DS1820_beri LPC_GPIO3->DATA & PIN_DS1820
// Pin je definiran kot izhod - 1 / 0 - vhod
#define DS1820_IO(x)   ((x) ? (LPC_GPIO3->DIR |= (PIN_DS1820))  : (LPC_GPIO3->DIR &= ~(PIN_DS1820)) ); 

int Senzor_Prisoten,Delcek_Stopinje,Izmerjena_Temperatura;
int Negativna_Temperatura;

// Tule se lahko vpiše kodo prebranega senzorja, ki jo izpiše 
// funkcija PreberiSerijsko(); v prvo vrstico LCD.
// Izpis na LCD je že v Hex obliki, pred posamezne bajte je potrebno dodlati le "0x"
int koda[8]={0x94,0x00,0x08,0x01,0xD3,0x39,0x38,0x10}; // koda senzorja
int TipSenzorja=0;
int DS1820Data[]={0,0,0,0,0,0,0,0,0};
char bufer[20];
char *napis;

//**************************************************************
//    Inicializacija senzorja 
//**************************************************************
void init1820(void){
   int vrednost;
   DS1820_IO(1);
   Delay_us(500);                // počakamo 500us
   DS1820_Data(0);               // Izhod na 0
   Delay_us(500);
   DS1820_IO(0);                 // Pin je vhod
   Delay_us(100);                // Po 100us preverimo odgovor
   vrednost=DS1820_beri;         // preberemo odgovor
   Delay_us(500);
  if (vrednost & (1<<0)) {       // je bit 0 spremenljivke vrednost 1?
   Senzor_Prisoten =0;           // Napaka, senzor se ni "oglasil"
   } else {
   Senzor_Prisoten =1;           // Vse v redu, nadaljujemo...
   } 
}

//**************************************************************
// Na izhod za DS1820 zapiše 0
//**************************************************************
void write_0(){
   DS1820_IO(1)                  // Pin DS1820 je izhod
   DS1820_Data(0);               // Izhod na 0
   Delay_us(90);
   DS1820_IO(0)                  // Pin DS1820 je vhod
   Delay_us(10);
}
//**************************************************************
// Na izhod za DS1820 zapiše 1
//**************************************************************
void write_1(){
   DS1820_IO(1)                  // Pin DS1820 je izhod
   DS1820_Data(0);               // Izhod na 0
   Delay_us(3);
   DS1820_IO(0)                  // Pin DS1820 je vhod
   Delay_us(90);                 // počakamo 90us
}

//**************************************************************
// Na izhod za DS1820 pošlje 8 bitov podatkov
//**************************************************************
void send_to_ds1820(int podatki){
   int i;
   DS1820_IO(1);                 // Pin DS1820 je Izhod
   for (i=0;i<8;i++) {           // 1 byte je sestavljen iz 8 bitov
      if (podatki & (1<<i)) {    // ali je bit podatki(i) = 1?
      write_1();                 // podatiki(i) je 1, 
      } else {
      write_0();                 //podatiki(i) je 0, 
      }
   }
}

//**************************************************************
// Prebere 8 bitov z DS1820 vhoda v spremenljivko prebrano
//**************************************************************
int read_from_ds1820(void){
   int i;
   int prebrano=0;
  for (i=0;i<8;i++) {            // Podatki so sestavljenih iz 8 bitov
   DS1820_IO(1)                  // pin DS1820 je izhod
   DS1820_Data(0)                // izhod na 0
   Delay_us(3);                  // Malček počakamo
   DS1820_IO(0)                  // pin DS1820 je vhod
   Delay_us(10);                 // še malček počakamo
     if ( DS1820_beri ) {        // ali je prebran bit = 1?
      prebrano |= (1<<i);        // da, postavi bit[i] v prebrano na 1
      } else {
      prebrano &= ~(1<<i);       // ne, postavi bit[i] v prebrano na 0
      }
      Delay_us(70);
   }
   return prebrano;              // funkcija vrne spremenljivko prebrano
}
//**************************************************************
// Prebere serijsko številko DS1820 hrani jo v DS1820Data[]
//**************************************************************
void PreberiSerijsko() {
   int x;
   int x1 = 0;
   char bufer[20];
   init1820();
   send_to_ds1820(0x33);         // ukaz READ ROM
   Delay_us(200);
   for (x=0;x<8;x++) {           // tule pa že beremo serijsko št. 
   DS1820Data[x]=read_from_ds1820();
   }
   for (x1=0; x1<=8; x1++) {
   sprintf(bufer, "%02x", DS1820Data[8-x1]);// številko stolpca pretvorim v char
   LCD_print (x1*2, 1, bufer);              // ter jo izpišem na LCD  
   }
 }
/**************************************************************/
//    Preberi scratchapd ob enem senzorju brez naslova
/**************************************************************/
void PreberiScratcpad() {
   int x;
   int x1 = 0;
   char bufer[20];
   init1820();
   send_to_ds1820(0xCC);         // 0xCC = Skip rom
   Delay_us(100);
   send_to_ds1820(0x44);         // 0x44 = Convert T
   Delay_us(750000);             // počakamo 750ms za pretvorbo
   init1820();
   send_to_ds1820(0xCC);         // 0xCC = Skip rom  
   Delay_us(100);  
   send_to_ds1820(0xBE);         // 0xBE = Read scratchpad
   Delay_us(100);
   
   for (x=0;x<8;x++) {           // tule pa že beremo vsebino scratcpada 
   DS1820Data[x]=read_from_ds1820();
   }
   for (x1=0; x1<=8; x1++) {
   sprintf(bufer, "%02x", DS1820Data[8-x1]);// številko stolpca pretvorim v char
   LCD_print (x1*2, 2, bufer);              // ter jo izpišem na LCD  
   }
 }

 /**************************************************************/
//    Pošlje ukaz 0x55 - Match rom skupaj s serijsko številko
/**************************************************************/
void SendMatchROM() {
   int temp;
   send_to_ds1820(0x55);
   for (temp=0; temp<8; temp++) {
      send_to_ds1820(koda[7-temp]);
   }
}
 
void PreberiIzbraniDS1820() {
   int x;
   init1820();
   SendMatchROM();
   send_to_ds1820(0x44);         // 0x44 = Convert T
   Delay_us(750000);             // počakamo 750ms za pretvorbo
   init1820();
   SendMatchROM(); 
   Delay_us(100);  
   send_to_ds1820(0xBE);         // 0xBE = Read scratchpad
   Delay_us(100);
   for (x=0;x<8;x++) {           // tule pa že beremo vsebino scratcpada 
   DS1820Data[x]=read_from_ds1820();
   }
 }

/**************************************************************/
//    Prebere vsebino scratchpada in iz nje izlušči temperaturo
//    primerno za prikaz na LCD 
/**************************************************************/ 
void PreberiTemperaturo(){
  char decimalka;
  int temperatura;
  char predznak;
  
//  PreberiScratcpad();
  PreberiIzbraniDS1820();
  
// Določitev vrednosti za decimalno piko  
  if (DS1820Data[0] & (1<<0)){   // ali je bit 0 = 1
    decimalka=5;                 // da -> decimalka = 5
  } else {
    decimalka=0;                 // ne -> decimalka = 0
  }

  temperatura = DS1820Data[0] >> 1;// Določitev temperature  

  if (DS1820Data[1] & (1<<0)){   // Je temperatura pozitivna ali negativna?  
    predznak='-';
  } else{
    predznak='+';
  }    
// Sprintf tule združi nekaj spremenljivk in besedila in shrani v niz
// buffer  
sprintf(bufer, "Temperatura = %c%d.%d", predznak, temperatura, decimalka);  
napis=&bufer[0];                 // kazalec na niz buffer
}    

