Mercurial > templog
diff ds18x20.c @ 315:7d409dded901
Import ds18x20 code
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 18 May 2012 23:57:08 +0800 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ds18x20.c Fri May 18 23:57:08 2012 +0800 @@ -0,0 +1,760 @@ +/********************************************************************************* +Title: DS18X20-Functions via One-Wire-Bus +Author: Martin Thomas <[email protected]> + http://www.siwawi.arubi.uni-kl.de/avr-projects +Software: avr-gcc 4.3.3 / avr-libc 1.6.7 (WinAVR 3/2010) +Hardware: any AVR - tested with ATmega16/ATmega32/ATmega324P and 3 DS18B20 + +Partly based on code from Peter Dannegger and others. + +changelog: +20041124 - Extended measurements for DS18(S)20 contributed by Carsten Foss (CFO) +200502xx - function DS18X20_read_meas_single +20050310 - DS18x20 EEPROM functions (can be disabled to save flash-memory) + (DS18X20_EEPROMSUPPORT in ds18x20.h) +20100625 - removed inner returns, added static function for read scratchpad + . replaced full-celcius and fractbit method with decicelsius + and maxres (degreeCelsius*10e-4) functions, renamed eeprom-functions, + delay in recall_e2 replaced by timeout-handling +20100714 - ow_command_skip_last_recovery used for parasite-powerd devices so the + strong pull-up can be enabled in time even with longer OW recovery times +20110209 - fix in DS18X20_format_from_maxres() by Marian Kulesza +**********************************************************************************/ + +#include <stdlib.h> +#include <stdint.h> + +#include <avr/io.h> +#include <avr/pgmspace.h> + +#include "ds18x20.h" +#include "onewire.h" +#include "crc8.h" + +#if DS18X20_EEPROMSUPPORT +// for 10ms delay in copy scratchpad +#include <util/delay.h> +#endif /* DS18X20_EEPROMSUPPORT */ + +/*----------- start of "debug-functions" ---------------*/ + +#if DS18X20_VERBOSE +#if (!DS18X20_DECICELSIUS) +#error "DS18X20_DECICELSIUS must be enabled for verbose-mode" +#endif + +/* functions for debugging-output - undef DS18X20_VERBOSE in .h + if you run out of program-memory */ +#include <string.h> +#include "uart.h" +#include "uart_addon.h" + +static int16_t DS18X20_raw_to_decicelsius( uint8_t fc, uint8_t sp[] ); + +void DS18X20_show_id_uart( uint8_t *id, size_t n ) +{ + size_t i; + + for( i = 0; i < n; i++ ) { + if ( i == 0 ) { uart_puts_P( "FC:" ); } + else if ( i == n-1 ) { uart_puts_P( "CRC:" ); } + if ( i == 1 ) { uart_puts_P( "SN: " ); } + uart_puthex_byte(id[i]); + uart_puts_P(" "); + if ( i == 0 ) { + if ( id[0] == DS18S20_FAMILY_CODE ) { uart_puts_P ("(18S)"); } + else if ( id[0] == DS18B20_FAMILY_CODE ) { uart_puts_P ("(18B)"); } + else if ( id[0] == DS1822_FAMILY_CODE ) { uart_puts_P ("(22)"); } + else { uart_puts_P ("( ? )"); } + } + } + if ( crc8( id, OW_ROMCODE_SIZE) ) + uart_puts_P( " CRC FAIL " ); + else + uart_puts_P( " CRC O.K. " ); +} + +static void show_sp_uart( uint8_t *sp, size_t n ) +{ + size_t i; + + uart_puts_P( "SP:" ); + for( i = 0; i < n; i++ ) { + if ( i == n-1 ) { uart_puts_P( "CRC:" ); } + uart_puthex_byte(sp[i]); + uart_puts_P(" "); + } +} + +/* + convert raw value from DS18x20 to Celsius + input is: + - familycode fc (0x10/0x28 see header) + - scratchpad-buffer + output is: + - cel full celsius + - fractions of celsius in millicelsius*(10^-1)/625 (the 4 LS-Bits) + - subzero =0 positiv / 1 negativ + always returns DS18X20_OK +*/ +static uint8_t DS18X20_meas_to_cel( uint8_t fc, uint8_t *sp, + uint8_t* subzero, uint8_t* cel, uint8_t* cel_frac_bits) +{ + uint16_t meas; + uint8_t i; + + meas = sp[0]; // LSB + meas |= ( (uint16_t)sp[1] ) << 8; // MSB + + // only work on 12bit-base + if( fc == DS18S20_FAMILY_CODE ) { // 9 -> 12 bit if 18S20 + /* Extended res. measurements for DS18S20 contributed by Carsten Foss */ + meas &= (uint16_t) 0xfffe; // Discard LSB, needed for later extended precicion calc + meas <<= 3; // Convert to 12-bit, now degrees are in 1/16 degrees units + meas += ( 16 - sp[6] ) - 4; // Add the compensation and remember to subtract 0.25 degree (4/16) + } + + // check for negative + if ( meas & 0x8000 ) { + *subzero=1; // mark negative + meas ^= 0xffff; // convert to positive => (twos complement)++ + meas++; + } + else { + *subzero=0; + } + + // clear undefined bits for B != 12bit + if ( fc == DS18B20_FAMILY_CODE || fc == DS1822_FAMILY_CODE ) { + i = sp[DS18B20_CONF_REG]; + if ( (i & DS18B20_12_BIT) == DS18B20_12_BIT ) { ; } + else if ( (i & DS18B20_11_BIT) == DS18B20_11_BIT ) { + meas &= ~(DS18B20_11_BIT_UNDF); + } else if ( (i & DS18B20_10_BIT) == DS18B20_10_BIT ) { + meas &= ~(DS18B20_10_BIT_UNDF); + } else { // if ( (i & DS18B20_9_BIT) == DS18B20_9_BIT ) { + meas &= ~(DS18B20_9_BIT_UNDF); + } + } + + *cel = (uint8_t)(meas >> 4); + *cel_frac_bits = (uint8_t)(meas & 0x000F); + + return DS18X20_OK; +} + +static void DS18X20_uart_put_temp(const uint8_t subzero, + const uint8_t cel, const uint8_t cel_frac_bits) +{ + char buffer[sizeof(int)*8+1]; + size_t i; + + uart_putc((subzero)?'-':'+'); + uart_put_int((int)cel); + uart_puts_P("."); + itoa(cel_frac_bits*DS18X20_FRACCONV,buffer,10); + for ( i = 0; i < 4-strlen(buffer); i++ ) { + uart_puts_P("0"); + } + uart_puts(buffer); + uart_puts_P("�C"); +} + +/* verbose output rom-search follows read-scratchpad in one loop */ +uint8_t DS18X20_read_meas_all_verbose( void ) +{ + uint8_t id[OW_ROMCODE_SIZE], sp[DS18X20_SP_SIZE], diff; + uint8_t i; + uint16_t meas; + int16_t decicelsius; + char s[10]; + uint8_t subzero, cel, cel_frac_bits; + + for( diff = OW_SEARCH_FIRST; diff != OW_LAST_DEVICE; ) + { + diff = ow_rom_search( diff, &id[0] ); + + if( diff == OW_PRESENCE_ERR ) { + uart_puts_P( "No Sensor found\r" ); + return OW_PRESENCE_ERR; // <--- early exit! + } + + if( diff == OW_DATA_ERR ) { + uart_puts_P( "Bus Error\r" ); + return OW_DATA_ERR; // <--- early exit! + } + + DS18X20_show_id_uart( id, OW_ROMCODE_SIZE ); + + if( id[0] == DS18B20_FAMILY_CODE || id[0] == DS18S20_FAMILY_CODE || + id[0] == DS1822_FAMILY_CODE ) { + // temperature sensor + + uart_putc ('\r'); + + ow_byte_wr( DS18X20_READ ); // read command + + for ( i=0 ; i< DS18X20_SP_SIZE; i++ ) { + sp[i]=ow_byte_rd(); + } + + show_sp_uart( sp, DS18X20_SP_SIZE ); + + if ( crc8( &sp[0], DS18X20_SP_SIZE ) ) { + uart_puts_P( " CRC FAIL " ); + } else { + uart_puts_P( " CRC O.K. " ); + } + uart_putc ('\r'); + + meas = sp[0]; // LSB Temp. from Scrachpad-Data + meas |= (uint16_t) (sp[1] << 8); // MSB + + uart_puts_P( " T_raw="); + uart_puthex_byte( (uint8_t)(meas >> 8) ); + uart_puthex_byte( (uint8_t)meas ); + uart_puts_P( " " ); + + if( id[0] == DS18S20_FAMILY_CODE ) { // 18S20 + uart_puts_P( "S20/09" ); + } + else if ( id[0] == DS18B20_FAMILY_CODE || + id[0] == DS1822_FAMILY_CODE ) { // 18B20 or 1822 + i=sp[DS18B20_CONF_REG]; + if ( (i & DS18B20_12_BIT) == DS18B20_12_BIT ) { + uart_puts_P( "B20/12" ); + } + else if ( (i & DS18B20_11_BIT) == DS18B20_11_BIT ) { + uart_puts_P( "B20/11" ); + } + else if ( (i & DS18B20_10_BIT) == DS18B20_10_BIT ) { + uart_puts_P( " B20/10 " ); + } + else { // if ( (i & DS18B20_9_BIT) == DS18B20_9_BIT ) { + uart_puts_P( "B20/09" ); + } + } + uart_puts_P(" "); + + DS18X20_meas_to_cel( id[0], sp, &subzero, &cel, &cel_frac_bits ); + DS18X20_uart_put_temp( subzero, cel, cel_frac_bits ); + + decicelsius = DS18X20_raw_to_decicelsius( id[0], sp ); + if ( decicelsius == DS18X20_INVALID_DECICELSIUS ) { + uart_puts_P("* INVALID *"); + } else { + uart_puts_P(" conv: "); + uart_put_int(decicelsius); + uart_puts_P(" deci�C "); + DS18X20_format_from_decicelsius( decicelsius, s, 10 ); + uart_puts_P(" fmt: "); + uart_puts(s); + uart_puts_P(" �C "); + } + + uart_puts("\r"); + + } // if meas-sensor + + } // loop all sensors + + uart_puts_P( "\r" ); + + return DS18X20_OK; +} + +#endif /* DS18X20_VERBOSE */ + +#if DS18X20_VERBOSE +#define uart_puts_P_verbose(s__) uart_puts_P(s__) +#else +#define uart_puts_P_verbose(s__) +#endif + + +/*----------- end of "debug-functions" ---------------*/ + + +/* find DS18X20 Sensors on 1-Wire-Bus + input/ouput: diff is the result of the last rom-search + *diff = OW_SEARCH_FIRST for first call + output: id is the rom-code of the sensor found */ +uint8_t DS18X20_find_sensor( uint8_t *diff, uint8_t id[] ) +{ + uint8_t go; + uint8_t ret; + + ret = DS18X20_OK; + go = 1; + do { + *diff = ow_rom_search( *diff, &id[0] ); + if ( *diff == OW_PRESENCE_ERR || *diff == OW_DATA_ERR || + *diff == OW_LAST_DEVICE ) { + go = 0; + ret = DS18X20_ERROR; + } else { + if ( id[0] == DS18B20_FAMILY_CODE || id[0] == DS18S20_FAMILY_CODE || + id[0] == DS1822_FAMILY_CODE ) { + go = 0; + } + } + } while (go); + + return ret; +} + +/* get power status of DS18x20 + input: id = rom_code + returns: DS18X20_POWER_EXTERN or DS18X20_POWER_PARASITE */ +uint8_t DS18X20_get_power_status( uint8_t id[] ) +{ + uint8_t pstat; + + ow_reset(); + ow_command( DS18X20_READ_POWER_SUPPLY, id ); + pstat = ow_bit_io( 1 ); + ow_reset(); + return ( pstat ) ? DS18X20_POWER_EXTERN : DS18X20_POWER_PARASITE; +} + +/* start measurement (CONVERT_T) for all sensors if input id==NULL + or for single sensor where id is the rom-code */ +uint8_t DS18X20_start_meas( uint8_t with_power_extern, uint8_t id[]) +{ + uint8_t ret; + + ow_reset(); + if( ow_input_pin_state() ) { // only send if bus is "idle" = high + if ( with_power_extern != DS18X20_POWER_EXTERN ) { + ow_command_with_parasite_enable( DS18X20_CONVERT_T, id ); + /* not longer needed: ow_parasite_enable(); */ + } else { + ow_command( DS18X20_CONVERT_T, id ); + } + ret = DS18X20_OK; + } + else { + uart_puts_P_verbose( "DS18X20_start_meas: Short Circuit!\r" ); + ret = DS18X20_START_FAIL; + } + + return ret; +} + +// returns 1 if conversion is in progress, 0 if finished +// not available when parasite powered. +uint8_t DS18X20_conversion_in_progress(void) +{ + return ow_bit_io( 1 ) ? DS18X20_CONVERSION_DONE : DS18X20_CONVERTING; +} + +static uint8_t read_scratchpad( uint8_t id[], uint8_t sp[], uint8_t n ) +{ + uint8_t i; + uint8_t ret; + + ow_command( DS18X20_READ, id ); + for ( i = 0; i < n; i++ ) { + sp[i] = ow_byte_rd(); + } + if ( crc8( &sp[0], DS18X20_SP_SIZE ) ) { + ret = DS18X20_ERROR_CRC; + } else { + ret = DS18X20_OK; + } + + return ret; +} + + +#if DS18X20_DECICELSIUS + +/* convert scratchpad data to physical value in unit decicelsius */ +static int16_t DS18X20_raw_to_decicelsius( uint8_t familycode, uint8_t sp[] ) +{ + uint16_t measure; + uint8_t negative; + int16_t decicelsius; + uint16_t fract; + + measure = sp[0] | (sp[1] << 8); + //measure = 0xFF5E; // test -10.125 + //measure = 0xFE6F; // test -25.0625 + + if( familycode == DS18S20_FAMILY_CODE ) { // 9 -> 12 bit if 18S20 + /* Extended measurements for DS18S20 contributed by Carsten Foss */ + measure &= (uint16_t)0xfffe; // Discard LSB, needed for later extended precicion calc + measure <<= 3; // Convert to 12-bit, now degrees are in 1/16 degrees units + measure += (16 - sp[6]) - 4; // Add the compensation and remember to subtract 0.25 degree (4/16) + } + + // check for negative + if ( measure & 0x8000 ) { + negative = 1; // mark negative + measure ^= 0xffff; // convert to positive => (twos complement)++ + measure++; + } + else { + negative = 0; + } + + // clear undefined bits for DS18B20 != 12bit resolution + if ( familycode == DS18B20_FAMILY_CODE || familycode == DS1822_FAMILY_CODE ) { + switch( sp[DS18B20_CONF_REG] & DS18B20_RES_MASK ) { + case DS18B20_9_BIT: + measure &= ~(DS18B20_9_BIT_UNDF); + break; + case DS18B20_10_BIT: + measure &= ~(DS18B20_10_BIT_UNDF); + break; + case DS18B20_11_BIT: + measure &= ~(DS18B20_11_BIT_UNDF); + break; + default: + // 12 bit - all bits valid + break; + } + } + + decicelsius = (measure >> 4); + decicelsius *= 10; + + // decicelsius += ((measure & 0x000F) * 640 + 512) / 1024; + // 625/1000 = 640/1024 + fract = ( measure & 0x000F ) * 640; + if ( !negative ) { + fract += 512; + } + fract /= 1024; + decicelsius += fract; + + if ( negative ) { + decicelsius = -decicelsius; + } + + if ( /* decicelsius == 850 || */ decicelsius < -550 || decicelsius > 1250 ) { + return DS18X20_INVALID_DECICELSIUS; + } else { + return decicelsius; + } +} + +/* format decicelsius-value into string, itoa method inspired + by code from Chris Takahashi for the MSP430 libc, BSD-license + modifications mthomas: variable-types, fixed radix 10, use div(), + insert decimal-point */ +uint8_t DS18X20_format_from_decicelsius( int16_t decicelsius, char str[], uint8_t n) +{ + uint8_t sign = 0; + char temp[7]; + int8_t temp_loc = 0; + uint8_t str_loc = 0; + div_t dt; + uint8_t ret; + + // range from -550:-55.0�C to 1250:+125.0�C -> min. 6+1 chars + if ( n >= (6+1) && decicelsius > -1000 && decicelsius < 10000 ) { + + if ( decicelsius < 0) { + sign = 1; + decicelsius = -decicelsius; + } + + // construct a backward string of the number. + do { + dt = div(decicelsius,10); + temp[temp_loc++] = dt.rem + '0'; + decicelsius = dt.quot; + } while ( decicelsius > 0 ); + + if ( sign ) { + temp[temp_loc] = '-'; + } else { + ///temp_loc--; + temp[temp_loc] = '+'; + } + + // reverse the string.into the output + while ( temp_loc >=0 ) { + str[str_loc++] = temp[(uint8_t)temp_loc--]; + if ( temp_loc == 0 ) { + str[str_loc++] = DS18X20_DECIMAL_CHAR; + } + } + str[str_loc] = '\0'; + + ret = DS18X20_OK; + } else { + ret = DS18X20_ERROR; + } + + return ret; +} + +/* reads temperature (scratchpad) of sensor with rom-code id + output: decicelsius + returns DS18X20_OK on success */ +uint8_t DS18X20_read_decicelsius( uint8_t id[], int16_t *decicelsius ) +{ + uint8_t sp[DS18X20_SP_SIZE]; + uint8_t ret; + + ow_reset(); + ret = read_scratchpad( id, sp, DS18X20_SP_SIZE ); + if ( ret == DS18X20_OK ) { + *decicelsius = DS18X20_raw_to_decicelsius( id[0], sp ); + } + return ret; +} + +/* reads temperature (scratchpad) of sensor without id (single sensor) + output: decicelsius + returns DS18X20_OK on success */ +uint8_t DS18X20_read_decicelsius_single( uint8_t familycode, int16_t *decicelsius ) +{ + uint8_t sp[DS18X20_SP_SIZE]; + uint8_t ret; + + ret = read_scratchpad( NULL, sp, DS18X20_SP_SIZE ); + if ( ret == DS18X20_OK ) { + *decicelsius = DS18X20_raw_to_decicelsius( familycode, sp ); + } + return ret; +} + +#endif /* DS18X20_DECICELSIUS */ + + +#if DS18X20_MAX_RESOLUTION + +static int32_t DS18X20_raw_to_maxres( uint8_t familycode, uint8_t sp[] ) +{ + uint16_t measure; + uint8_t negative; + int32_t temperaturevalue; + + measure = sp[0] | (sp[1] << 8); + //measure = 0xFF5E; // test -10.125 + //measure = 0xFE6F; // test -25.0625 + + if( familycode == DS18S20_FAMILY_CODE ) { // 9 -> 12 bit if 18S20 + /* Extended measurements for DS18S20 contributed by Carsten Foss */ + measure &= (uint16_t)0xfffe; // Discard LSB, needed for later extended precicion calc + measure <<= 3; // Convert to 12-bit, now degrees are in 1/16 degrees units + measure += ( 16 - sp[6] ) - 4; // Add the compensation and remember to subtract 0.25 degree (4/16) + } + + // check for negative + if ( measure & 0x8000 ) { + negative = 1; // mark negative + measure ^= 0xffff; // convert to positive => (twos complement)++ + measure++; + } + else { + negative = 0; + } + + // clear undefined bits for DS18B20 != 12bit resolution + if ( familycode == DS18B20_FAMILY_CODE || familycode == DS1822_FAMILY_CODE ) { + switch( sp[DS18B20_CONF_REG] & DS18B20_RES_MASK ) { + case DS18B20_9_BIT: + measure &= ~(DS18B20_9_BIT_UNDF); + break; + case DS18B20_10_BIT: + measure &= ~(DS18B20_10_BIT_UNDF); + break; + case DS18B20_11_BIT: + measure &= ~(DS18B20_11_BIT_UNDF); + break; + default: + // 12 bit - all bits valid + break; + } + } + + temperaturevalue = (measure >> 4); + temperaturevalue *= 10000; + temperaturevalue +=( measure & 0x000F ) * DS18X20_FRACCONV; + + if ( negative ) { + temperaturevalue = -temperaturevalue; + } + + return temperaturevalue; +} + +uint8_t DS18X20_read_maxres( uint8_t id[], int32_t *temperaturevalue ) +{ + uint8_t sp[DS18X20_SP_SIZE]; + uint8_t ret; + + ow_reset(); + ret = read_scratchpad( id, sp, DS18X20_SP_SIZE ); + if ( ret == DS18X20_OK ) { + *temperaturevalue = DS18X20_raw_to_maxres( id[0], sp ); + } + return ret; +} + +uint8_t DS18X20_read_maxres_single( uint8_t familycode, int32_t *temperaturevalue ) +{ + uint8_t sp[DS18X20_SP_SIZE]; + uint8_t ret; + + ret = read_scratchpad( NULL, sp, DS18X20_SP_SIZE ); + if ( ret == DS18X20_OK ) { + *temperaturevalue = DS18X20_raw_to_maxres( familycode, sp ); + } + return ret; + +} + +uint8_t DS18X20_format_from_maxres( int32_t temperaturevalue, char str[], uint8_t n) +{ + uint8_t sign = 0; + char temp[10]; + int8_t temp_loc = 0; + uint8_t str_loc = 0; + ldiv_t ldt; + uint8_t ret; + + // range from -550000:-55.0000�C to 1250000:+125.0000�C -> min. 9+1 chars + if ( n >= (9+1) && temperaturevalue > -1000000L && temperaturevalue < 10000000L ) { + + if ( temperaturevalue < 0) { + sign = 1; + temperaturevalue = -temperaturevalue; + } + + do { + ldt = ldiv( temperaturevalue, 10 ); + temp[temp_loc++] = ldt.rem + '0'; + temperaturevalue = ldt.quot; + } while ( temperaturevalue > 0 ); + + // mk 20110209 + if ((temp_loc < 4)&&(temp_loc > 1)) { + temp[temp_loc++] = '0'; + } // mk end + + if ( sign ) { + temp[temp_loc] = '-'; + } else { + temp[temp_loc] = '+'; + } + + while ( temp_loc >= 0 ) { + str[str_loc++] = temp[(uint8_t)temp_loc--]; + if ( temp_loc == 3 ) { + str[str_loc++] = DS18X20_DECIMAL_CHAR; + } + } + str[str_loc] = '\0'; + + ret = DS18X20_OK; + } else { + ret = DS18X20_ERROR; + } + + return ret; +} + +#endif /* DS18X20_MAX_RESOLUTION */ + + +#if DS18X20_EEPROMSUPPORT + +uint8_t DS18X20_write_scratchpad( uint8_t id[], + uint8_t th, uint8_t tl, uint8_t conf) +{ + uint8_t ret; + + ow_reset(); + if( ow_input_pin_state() ) { // only send if bus is "idle" = high + ow_command( DS18X20_WRITE_SCRATCHPAD, id ); + ow_byte_wr( th ); + ow_byte_wr( tl ); + if ( id[0] == DS18B20_FAMILY_CODE || id[0] == DS1822_FAMILY_CODE ) { + ow_byte_wr( conf ); // config only available on DS18B20 and DS1822 + } + ret = DS18X20_OK; + } + else { + uart_puts_P_verbose( "DS18X20_write_scratchpad: Short Circuit!\r" ); + ret = DS18X20_ERROR; + } + + return ret; +} + +uint8_t DS18X20_read_scratchpad( uint8_t id[], uint8_t sp[], uint8_t n ) +{ + uint8_t ret; + + ow_reset(); + if( ow_input_pin_state() ) { // only send if bus is "idle" = high + ret = read_scratchpad( id, sp, n ); + } + else { + uart_puts_P_verbose( "DS18X20_read_scratchpad: Short Circuit!\r" ); + ret = DS18X20_ERROR; + } + + return ret; +} + +uint8_t DS18X20_scratchpad_to_eeprom( uint8_t with_power_extern, + uint8_t id[] ) +{ + uint8_t ret; + + ow_reset(); + if( ow_input_pin_state() ) { // only send if bus is "idle" = high + if ( with_power_extern != DS18X20_POWER_EXTERN ) { + ow_command_with_parasite_enable( DS18X20_COPY_SCRATCHPAD, id ); + /* not longer needed: ow_parasite_enable(); */ + } else { + ow_command( DS18X20_COPY_SCRATCHPAD, id ); + } + _delay_ms(DS18X20_COPYSP_DELAY); // wait for 10 ms + if ( with_power_extern != DS18X20_POWER_EXTERN ) { + ow_parasite_disable(); + } + ret = DS18X20_OK; + } + else { + uart_puts_P_verbose( "DS18X20_copy_scratchpad: Short Circuit!\r" ); + ret = DS18X20_START_FAIL; + } + + return ret; +} + +uint8_t DS18X20_eeprom_to_scratchpad( uint8_t id[] ) +{ + uint8_t ret; + uint8_t retry_count=255; + + ow_reset(); + if( ow_input_pin_state() ) { // only send if bus is "idle" = high + ow_command( DS18X20_RECALL_E2, id ); + while( retry_count-- && !( ow_bit_io( 1 ) ) ) { + ; + } + if ( retry_count ) { + ret = DS18X20_OK; + } else { + uart_puts_P_verbose( "DS18X20_recall_E2: timeout!\r" ); + ret = DS18X20_ERROR; + } + } + else { + uart_puts_P_verbose( "DS18X20_recall_E2: Short Circuit!\r" ); + ret = DS18X20_ERROR; + } + + return ret; +} + +#endif /* DS18X20_EEPROMSUPPORT */ +