;Program T1620_2.bas

;This program illustrates how to use the Versatech Tickit62 to make 
;continuous temperature measurements from the Dallas Semiconductor DS1620
;Digital Thermometer and Thermostat, and writes them to the EEPROM. Then
;when all the measurements are taken, all the temperatures are read from
;the EEPROM.

;Configure the status register of the DS1620.
;Start temperature conversion on the DS1620.
;Get the starting available EEPROM addresses from EEPROM address 4 and 5.
;Measures temperature from the DS1620.
;Write each temperature to the EEPROM.
;Read all temperatures in the EEPROM.

;  Data_5 (term 36) ---------------> RST (term 3)
;  Data_6 (term 37) ---------------> CLK (term 2)
;  Data_7 (term 38) <--------------> DQ  (term 1)

;copyright, Locksley Haynes, Morgan State University, Sept. 20, 1997.

DEF tic62_b
LIB fbasic.lib      ;Library for standard functions
LIB constrin.lib    ;Library for string functions

DEF CLOCK pin_D6
DEF RST   pin_D5
DEF DQ    pin_D7

;**********************DS1620 Commands*****************************
DEF WRITE_CONF 0y00001100b     ;command to configure the register  
DEF READ_TEMP 0y10101010b      ;command to read temperature
DEF START_CONVERT 0y11101110b  ;command to start converting temp.
DEF STOP_CONVERT  0y00100010b  ;command to stop converting temp.

DEF MEASUREMENTS 0d10b        ;number of temp. measurements

GLOBAL word RAW  0w
GLOBAL word ADDRESS 0w

;**Function out_bit sets the state of DATA lead to bit_value, followed
;**by a clock pulse.
FUNC none out_bit
   PARAM byte value
BEGIN
   
   pin_high( CLOCK )
   IF ==( value, 0b )    ;if value equal zero
     pin_low( DQ )    ;then write zero to DATA lead
   ELSE
     pin_high( DQ )     ;else write one.
   ENDIF
   pin_low( CLOCK )       ;provide clock pulse
  
ENDFUN

;**Function write_command writes any eight bit command via DATA output, 
;**least significant bit first.
FUNC none write_command
   PARAM byte command          ;command sent to be written
   
   LOCAL byte comm
   LOCAL byte comm2
   LOCAL byte n 0b            ;index for looping
   LOCAL byte val 0b      ;specific bit value
BEGIN
   =( comm2, command)
   WHILE <=( n, 8b )
      
      IF <>(n, 0b)         ;if not bit0 shift right once
        =(comm2, >>( comm2 )) 
      ENDIF

      =(comm, comm2)
      =( val, and( comm, 0y00000001b) )  ;assign bit to val
      
      out_bit( val )    ;send that bit to DATA lead
      ++( n )
   LOOP
ENDFUN

;**Function read_data reads a nine bit digital word via the DATA lead.
FUNC none read_data
   LOCAL byte n 
   LOCAL byte i 0b
   LOCAL word val
BEGIN   
   =( RAW, 0w )
   =( n, 0b )
   WHILE <=( n, 8b )        ;read DATA lead nine times
      =( i, n )
      
      pin_low( CLOCK )
      =( val, to_word( and( pin_in( DQ), 1b)))  ;read DQ pin
      pin_high( CLOCK )

      WHILE >( i, 0b )
         =(val, <<(val))
         --( i )
      LOOP
     
      =( RAW, or( RAW, val ))
     
      ++( n )
   LOOP
ENDFUN
;**Function finds the next available EEPROM addresses.
FUNC none get_available_eeprom_address
LOCAL byte first 0b
LOCAL word second 0w
LOCAL byte n 1b
BEGIN
    =(first, ee_read(0x0004w))   
    =(second, to_word(ee_read(0x0005w)))

    WHILE <=( n, 8b)
       =(second,<<( second ))
       ++( n )
    LOOP
    =(ADDRESS, or( second, to_word(first)))
ENDFUN

;**Function reads measured temperatures written to the eeprom.
FUNC none read_temp_from_eeprom
PARAM word addr 
LOCAL byte n 1b
BEGIN
   WHILE <=( n, MEASUREMENTS )
      con_string( "Temperature ")
      con_out( n )
      con_string( " read from EEPROM.\r\l ") 
      con_out( ee_read(addr) ) ;read and display EEPROM temperature.
      con_string( " DEGREES FAHRENHEIT.\r\l\l ") 
      ++( n )
      ++( addr )       ;increment to next available EEPROM address
   LOOP
ENDFUN

;**Function writes the temp values to the eeprom.
FUNC none write_to_eeprom
PARAM byte temp
LOCAL byte n 0b
BEGIN
   
  ee_write( ADDRESS, temp)  ;write temperature to EEPROM.

  ++( ADDRESS)  ;increment next available EEPROM address.
ENDFUN

;****************************Main function***************** 
FUNC none main
   LOCAL byte count 1b
   LOCAL byte configure 0y00000010b
   LOCAL word addr
BEGIN
   pin_low( RST )
   pin_high( CLOCK )
   pin_high( RST )              ;initiate communication
   write_command( WRITE_CONF )  
   write_command( configure )  ;configure DS1620 in CPU mode
   pin_high( CLOCK )
   pin_low( RST )               ;terminate communication
   delay(200)    ;wait for programming of configuration register.

   pin_low( RST )
   pin_high( CLOCK )
   pin_high( RST )
   write_command( START_CONVERT ) ;start converting temperature
   pin_high( CLOCK )
   pin_low( RST )
   delay(200)     ;wait for programming of DS1620

   con_string( "Measuring temperature...\r\l")
   
   get_available_eeprom_address() ;get available addresses to write data
   
   =(addr,ADDRESS)   ;keep first eeprom address

   WHILE <=( count, MEASUREMENTS)
      pin_high( CLOCK )
      pin_low( RST ) 
      pin_high( RST )
      write_command( READ_TEMP ) ;command to DS1620 for reading temp
      read_data()   ;read the raw data from device
      pin_high( CLOCK )
      pin_low( RST )
      
      =( RAW, >>( RAW ) )       ;convert to temp. fahrenheit
      
      
      ;Write temperature to EEPROM
      con_out( count )
      con_string( " temperature measurement written.\r\l\l" )
      write_to_eeprom( trunc_byte(+( 32w, /( *( RAW, 9w), 5w))) )
      
      ++( count )
      delay( 10000 )        ;wait ten seconds
   LOOP
   
   pin_low( RST )
   pin_high( CLOCK )
   pin_high( RST )
   write_command( STOP_CONVERT ) ;stop temp. conversion to save power.
   pin_high( CLOCK )
   pin_low( RST )
   pin_low( CLOCK )
   
   con_string( "End temperature measurements.\r\l\l\l" )

   con_string( "Reading temperatures stored in EEPROM. \r\l\l")
   delay( 10000 )
   read_temp_from_eeprom(addr)

   debug_on() ;return control to debugger.
ENDFUN