1-Wire® library for mbed. Complete 1-Wire library that supports our silicon masters along with a bit-bang master on the MAX32600MBED platform with one common interface for mbed. Slave support has also been included and more slaves will be added as time permits.

Dependents:   MAXREFDES131_Qt_Demo MAX32630FTHR_iButton_uSD_Logger MAX32630FTHR_DS18B20_uSD_Logger MAXREFDES130_131_Demo ... more

Superseded by MaximInterface.

Revision:
2:02d228c25fd4
Parent:
1:91e52f8ab8bf
Child:
3:644fc630f958
--- a/OneWire_Masters/DS248x/ds248x.cpp	Sat Jan 30 23:00:57 2016 +0000
+++ b/OneWire_Masters/DS248x/ds248x.cpp	Sun Jan 31 06:15:24 2016 +0000
@@ -46,6 +46,62 @@
 #include "ds248x.h"
 
 
+//OW ROM Commands
+#define READ_ROM   0x33
+#define MATCH_ROM  0x55
+#define SEARCH_ROM 0xF0
+#define SKIP_ROM   0xCC
+
+// ds248x commands
+#define CMD_DRST   0xF0
+#define CMD_WCFG   0xD2
+#define CMD_A1WP   0xC3 //DS2484 only
+#define CMD_CHSL   0xC3 //DS2482-800 only
+#define CMD_SRP    0xE1
+#define CMD_1WRS   0xB4
+#define CMD_1WWB   0xA5
+#define CMD_1WRB   0x96
+#define CMD_1WSB   0x87
+#define CMD_1WT    0x78
+
+// ds248x config bits
+#define CONFIG_APU  0x01
+#define CONFIG_PDN  0x02
+#define CONFIG_SPU  0x04
+#define CONFIG_1WS  0x08
+
+// ds248x status bits 
+#define STATUS_1WB  0x01
+#define STATUS_PPD  0x02
+#define STATUS_SD   0x04
+#define STATUS_LL   0x08
+#define STATUS_RST  0x10
+#define STATUS_SBR  0x20
+#define STATUS_TSB  0x40
+#define STATUS_DIR  0x80
+
+// ds2484 adjustable parameters
+#define TRSTL     0
+#define TRSTL_OD  1
+#define TMSP      2
+#define TMSP_OD   3
+#define TW0L      4
+#define TW0L_OD   5
+#define TREC0     6 //OD NA
+#define RWPU      8 //OD NA
+
+
+// misc constants
+#define POLL_LIMIT  200
+#define TRUE    1
+#define FALSE   0
+
+// API mode bit flags
+#define MODE_STANDARD                  0x00
+#define MODE_OVERDRIVE                 0x01
+#define MODE_STRONG                    0x02
+
+
 //*********************************************************************
 Ds248x::Ds248x(I2C *p_i2c_bus, ds248x_i2c_adrs_t adrs)
 {
@@ -77,36 +133,250 @@
 
 
 //*********************************************************************
-uint8_t Ds248x::detect(void)
+bool Ds248x::detect(void)
+{
+    bool rtn_val = false;
+    
+    // reset the ds2484 ON selected address
+    if (!reset())
+    {
+        rtn_val = false;
+    }
+    else
+    {
+        // default configuration
+        _c1WS = FALSE;
+        _cSPU = FALSE;
+        _cPDN = FALSE;
+        _cAPU = FALSE;
+        
+        // write the default configuration setup
+        if (!write_config(_c1WS | _cSPU | _cPDN | _cAPU))
+        {
+            rtn_val = false;
+        }
+        else
+        {
+            rtn_val = true;
+        }
+    }
+    
+    return(rtn_val);
+}
+
+
+//*********************************************************************
+bool Ds248x::reset(void)
 {
-    uint8_t rtn_val;
+    char status;
+    char packet[] = {CMD_DRST};
+    
+    // Device Reset
+    //   S AD,0 [A] DRST [A] Sr AD,1 [A] [SS] A\ P
+    //  [] indicates from slave
+    //  SS status byte to read to verify state
+    
+    _p_i2c_bus->write(_w_adrs, packet, 1);
+    _p_i2c_bus->read(_r_adrs, &status, 1);
+    
+    return((status & 0xF7) == 0x10);   
+}
+
+
+//*********************************************************************
+bool Ds248x::write_config(uint8_t config)
+{
+    bool rtn_val = false;
+    char read_config;
+    char packet [] = {CMD_WCFG, (config | (~config << 4))};
+    
+    _p_i2c_bus->write(_w_adrs, packet, 2);
+    _p_i2c_bus->read(_r_adrs, &read_config, 1);
+    
+    // check for failure due to incorrect read back
+    if (config != read_config)
+    {
+        // handle error
+        // ...
+        reset();
+        rtn_val = false;
+    }
+    else
+    {
+        rtn_val = true;
+    }
+    
     return(rtn_val);
 }
 
 
 //*********************************************************************
-uint8_t Ds248x::reset(void)
+bool Ds248x::channel_select(uint8_t channel)
 {
-    uint8_t rtn_val;
-    return(rtn_val);   
+    
+    char ch, ch_read, check;
+    char packet [2];
+    
+    packet[0] = CMD_CHSL;
+    
+    // Channel Select (Case A)
+    //   S AD,0 [A] CHSL [A] CC [A] Sr AD,1 [A] [RR] A\ P
+    //  [] indicates from slave
+    //  CC channel value
+    //  RR channel read back
+    
+    switch (channel)
+    {
+      default: case 0: ch = 0xF0; ch_read = 0xB8; break;
+      case 1: ch = 0xE1; ch_read = 0xB1; break;
+      case 2: ch = 0xD2; ch_read = 0xAA; break;
+      case 3: ch = 0xC3; ch_read = 0xA3; break;
+      case 4: ch = 0xB4; ch_read = 0x9C; break;
+      case 5: ch = 0xA5; ch_read = 0x95; break;
+      case 6: ch = 0x96; ch_read = 0x8E; break;
+      case 7: ch = 0x87; ch_read = 0x87; break;
+    };
+    
+    packet[1] = ch;
+    
+    _p_i2c_bus->write(_w_adrs, packet, 2);
+    _p_i2c_bus->read(_r_adrs, &check, 1);
+    
+    // check for failure due to incorrect read back of channel
+    return (check == ch_read);
+}
+
+
+//*********************************************************************
+bool Ds248x::adjust_timing(uint8_t param, uint8_t val)
+{
+    bool rtn_val = false;
+    char read_port_config;
+    char control_byte;
+
+    control_byte = (((param & 0x0F) << 4) | (val & 0x0F));
+
+    char packet [] = {CMD_A1WP, control_byte};
+
+    _p_i2c_bus->write(_w_adrs, packet, 2);
+    _p_i2c_bus->read(_r_adrs, &read_port_config, 1);
+
+    // check for failure due to incorrect read back
+    if ((control_byte & 0x0F) != read_port_config) 
+    {
+        // handle error
+        // ...
+        reset();
+
+        rtn_val = false;
+    } 
+    else 
+    {
+        rtn_val = true;
+    }
+
+    return(rtn_val);
 }
 
 
 //*********************************************************************
-uint8_t Ds248x::write_config(uint8_t config)
+uint8_t Ds248x::search_triplet(uint8_t search_direction)
 {
-    uint8_t rtn_val;
-    return(rtn_val); 
+    uint8_t rtn_val = 0;
+    uint8_t poll_count = 0;
+    char status;
+    char packet [] = {CMD_1WT, search_direction ? 0x80 : 0x00};
+
+    // 1-Wire Triplet (Case B)
+    //   S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P
+    //                                         \--------/
+    //                           Repeat until 1WB bit has changed to 0
+    //  [] indicates from slave
+    //  SS indicates byte containing search direction bit value in msbit
+
+    _p_i2c_bus->write(_w_adrs, packet, 2);
+
+    // loop checking 1WB bit for completion of 1-Wire operation
+    // abort if poll limit reached
+    do 
+    {
+        _p_i2c_bus->read(_r_adrs, &status, 1);
+    } 
+    while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT));
+
+    // check for failure due to poll limit reached
+    if (poll_count >= POLL_LIMIT) 
+    {
+        // handle error
+        // ...
+        reset();
+        rtn_val = FALSE;
+    }
+    else
+    {
+        rtn_val = status;
+    }
+    
+    return(rtn_val);
 }
 
 
 //*********************************************************************
+bool Ds248x::OWReset()
+{
+    bool rtn_val = false;
+    
+    uint8_t poll_count = 0;
+    char status;
+    char packet [] = {CMD_1WRS};
 
+    // 1-Wire reset (Case B)
+    //   S AD,0 [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P
+    //                                   \--------/
+    //                       Repeat until 1WB bit has changed to 0
+    //  [] indicates from slave
+
+    _p_i2c_bus->write(_w_adrs, packet, 1);
+
+    // loop checking 1WB bit for completion of 1-Wire operation
+    // abort if poll limit reached
+    do 
+    {
+        _p_i2c_bus->read(_r_adrs, &status, 1);
+    } 
+    while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT));
 
-//*********************************************************************
-uint8_t Ds248x::OWReset()
-{
-    uint8_t rtn_val;
+    // check for failure due to poll limit reached
+    if (poll_count >= POLL_LIMIT) 
+    {
+        // handle error
+        // ...
+        reset();
+        rtn_val = false; 
+    }
+    else
+    {
+        // check for short condition
+        if (status & STATUS_SD)
+        {
+            _short_detected = TRUE;
+        }
+        else
+        {
+            _short_detected = FALSE;
+        }
+    
+        // check for presence detect
+        if (status & STATUS_PPD)
+        {
+            rtn_val = true;
+        }
+        else
+        {
+            rtn_val = false;
+        }
+    }
+
     return(rtn_val);
 }
 
@@ -114,15 +384,14 @@
 //*********************************************************************
 void Ds248x::OWWriteBit(uint8_t sendbit)
 {
-    
+    OWTouchBit(sendbit);
 }
 
 
 //*********************************************************************
 uint8_t Ds248x::OWReadBit()
 {
-    uint8_t rtn_val;
-    return(rtn_val); 
+    return(OWTouchBit(0x01)); 
 }
 
 
@@ -130,14 +399,92 @@
 uint8_t Ds248x::OWTouchBit(uint8_t sendbit)
 {
     uint8_t rtn_val;
-    return(rtn_val);
+    uint8_t poll_count = 0;
+    char status;
+    char packet[] = {CMD_1WSB, sendbit ? 0x80 : 0x00};
+
+    // 1-Wire bit (Case B)
+    //   S AD,0 [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status] A\ P
+    //                                          \--------/
+    //                           Repeat until 1WB bit has changed to 0
+    //  [] indicates from slave
+    //  BB indicates byte containing bit value in msbit
+
+    _p_i2c_bus->write(_w_adrs, packet, 2);
+
+    // loop checking 1WB bit for completion of 1-Wire operation
+    // abort if poll limit reached
+    do 
+    {
+        _p_i2c_bus->read(_r_adrs, &status, 1);
+    } 
+    while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT));
+
+    // check for failure due to poll limit reached
+    if (poll_count >= POLL_LIMIT) 
+    {
+        // handle error
+        // ...
+        reset();
+        rtn_val = 0;
+    }
+    else
+    {
+        // return bit state
+        if (status & STATUS_SBR)
+        {
+            rtn_val = 1;
+        }
+        else
+        {
+            rtn_val = 0;
+        }
+    }
+    
+    return(rtn_val); 
 }
 
 
 //*********************************************************************
-void Ds248x::OWWRiteByte(uint8_t sendbyte)
+bool Ds248x::OWWriteByte(uint8_t sendbyte)
 {
+    bool rtn_val = false;
     
+    uint8_t poll_count = 0;
+    char status;
+    char packet [] = {CMD_1WWB, sendbyte};
+
+    // 1-Wire Write Byte (Case B)
+    //   S AD,0 [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status] A\ P
+    //                                          \--------/
+    //                             Repeat until 1WB bit has changed to 0
+    //  [] indicates from slave
+    //  DD data to write
+
+    _p_i2c_bus->write(_w_adrs, packet, 2);
+
+    // loop checking 1WB bit for completion of 1-Wire operation
+    // abort if poll limit reached
+    do 
+    {
+        _p_i2c_bus->read(_r_adrs, &status, 1);
+    } 
+    while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT));
+
+    // check for failure due to poll limit reached
+    if (poll_count >= POLL_LIMIT) 
+    {
+        // handle error
+        // ...
+        reset();
+        rtn_val = false;
+    }
+    else
+    {
+        rtn_val = true;
+    }
+
+    return(rtn_val);
 }
 
 
@@ -145,6 +492,49 @@
 uint8_t Ds248x::OWReadByte(void)
 {
     uint8_t rtn_val;
+    
+    uint8_t poll_count = 0;
+    char data, status;
+    char packet[2] = {CMD_1WRB, 0};
+
+    // 1-Wire Read Bytes (Case C)
+    //   S AD,0 [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A\
+    //                                   \--------/
+    //                     Repeat until 1WB bit has changed to 0
+    //   Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P
+    //
+    //  [] indicates from slave
+    //  DD data read
+
+    _p_i2c_bus->write(_w_adrs, packet, 1);
+
+    // loop checking 1WB bit for completion of 1-Wire operation
+    // abort if poll limit reached
+    do 
+    {
+        _p_i2c_bus->read(_r_adrs, &status, 1);
+    } 
+    while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT));
+
+    // check for failure due to poll limit reached
+    if (poll_count >= POLL_LIMIT) 
+    {
+        // handle error
+        // ...
+        reset();
+        rtn_val = 0;
+    }
+    else
+    {
+        packet[0] = CMD_SRP;
+        packet[1] = 0xE1;
+    
+        _p_i2c_bus->write(_w_adrs, packet, 2);
+        _p_i2c_bus->read(_r_adrs, &data, 1);
+    
+        rtn_val = data;
+    }
+    
     return(rtn_val);
 }
 
@@ -153,6 +543,17 @@
 uint8_t Ds248x::OWTouchByte(uint8_t sendbyte)
 {
     uint8_t rtn_val;
+
+    if (sendbyte == 0xFF) 
+    {
+        rtn_val = OWReadByte();
+    } 
+    else 
+    {
+        OWWriteByte(sendbyte);
+        rtn_val = sendbyte;
+    }
+    
     return(rtn_val);
 }
 
@@ -160,29 +561,88 @@
 //*********************************************************************
 void Ds248x::OWBlock(uint8_t *tran_buf, uint8_t tran_len)
 {
-
+    uint8_t i;
+    
+    for (i = 0; i < tran_len; i++)
+    {
+        tran_buf[i] = OWTouchByte(tran_buf[i]);
+    }
 }
 
 
 //*********************************************************************
-void Ds248x::OWFirst(void)
+bool Ds248x::OWFirst(void)
 {
-    
+    // reset the search state
+    _last_discrepancy = 0;
+    _last_device_flag = FALSE;
+    _last_family_discrepancy = 0;
+
+   return OWSearch();  
+}
+
+
+//*********************************************************************
+bool Ds248x::OWNext(void)
+{
+    // leave the search state alone
+    return OWSearch();
 }
 
 
 //*********************************************************************
-uint8_t Ds248x::OWNext(void)
+bool Ds248x::OWVerify(void)
 {
-    uint8_t rtn_val;
-    return(rtn_val);
-}
+    bool rtn_val = false;
+
+    uint8_t rom_backup[8];
+    uint8_t i,rslt,ld_backup,ldf_backup,lfd_backup;
+
+    // keep a backup copy of the current state
+    for (i = 0; i < 8; i++)
+    {
+        rom_backup[i] = _rom_number[i];
+    }
+    
+    ld_backup = _last_discrepancy;
+    ldf_backup = _last_device_flag;
+    lfd_backup = _last_family_discrepancy;
+
+    // set search to find the same device
+    _last_discrepancy = 64;
+    _last_device_flag = FALSE;
 
+    if (OWSearch()) 
+    {
+        // check if same device found
+        rslt = TRUE;
+        for (i = 0; i < 8; i++) 
+        {
+            if (rom_backup[i] != _rom_number[i]) 
+            {
+                rslt = FALSE;
+                break;
+            }
+        }
+    } 
+    else
+    {
+        rslt = FALSE;
+    }
 
-//*********************************************************************
-uint8_t Ds248x::OWVerify(void)
-{
-    uint8_t rtn_val;
+    // restore the search state
+    for (i = 0; i < 8; i++)
+    {
+        _rom_number[i] = rom_backup[i];
+    }
+    
+    _last_discrepancy = ld_backup;
+    _last_device_flag = ldf_backup;
+    _last_family_discrepancy = lfd_backup;
+    
+    // return the result of the verify
+    rtn_val = rslt;
+    
     return(rtn_val);
 }
 
@@ -190,30 +650,180 @@
 //*********************************************************************
 void Ds248x::OWTargetSetup(uint8_t family_code)
 {
+    uint8_t i;
+
+    // set the search state to find SearchFamily type devices
+    _rom_number[0] = family_code;
+    for (i = 1; i < 8; i++)
+    {
+        _rom_number[i] = 0;
+    }
     
+    _last_discrepancy = 64;
+    _last_family_discrepancy = 0;
+    _last_device_flag = FALSE;
 }
 
 
 //*********************************************************************
 void Ds248x::OWFamilySkipSetup(void)
 {
+    // set the Last discrepancy to last family discrepancy
+    _last_discrepancy = _last_family_discrepancy;
     
+    // clear the last family discrpepancy
+    _last_family_discrepancy = 0;
+    
+    // check for end of list
+    if (_last_discrepancy == 0) 
+    {
+        _last_device_flag = TRUE;
+    }
 }
 
 
 //*********************************************************************
-uint8_t Ds248x::OWSearch(void)
+bool Ds248x::OWSearch(void)
 {
-    uint8_t rtn_val;
-    return(rtn_val);
+    uint8_t id_bit_number;
+    uint8_t last_zero, rom_byte_number, search_result;
+    uint8_t id_bit, cmp_id_bit;
+    uint8_t rom_byte_mask, search_direction, status;
+
+    // initialize for search
+    id_bit_number = 1;
+    last_zero = 0;
+    rom_byte_number = 0;
+    rom_byte_mask = 1;
+    search_result = FALSE;
+    _crc8 = 0;
+
+    // if the last call was not the last one
+    if (!_last_device_flag) 
+    {
+        // 1-Wire reset
+        if (!OWReset()) 
+        {
+            // reset the search
+            _last_discrepancy = 0;
+            _last_device_flag = FALSE;
+            _last_family_discrepancy = 0;
+            return FALSE;
+        }
+
+        // issue the search command
+        OWWriteByte(SEARCH_ROM);
+
+        // loop to do the search
+        do 
+        {
+            // if this discrepancy if before the Last Discrepancy
+            // on a previous next then pick the same as last time
+            if (id_bit_number < _last_discrepancy) 
+            {
+                if ((_rom_number[rom_byte_number] & rom_byte_mask) > 0)
+                    search_direction = 1;
+                else
+                    search_direction = 0;
+            } 
+            else 
+            {
+                // if equal to last pick 1, if not then pick 0
+                if (id_bit_number == _last_discrepancy)
+                    search_direction = 1;
+                else
+                    search_direction = 0;
+            }
+
+            // Perform a triple operation on the ds2484 which will perform 2 read bits and 1 write bit
+            status = search_triplet(search_direction);
+
+            // check bit results in status byte
+            id_bit = ((status & STATUS_SBR) == STATUS_SBR);
+            cmp_id_bit = ((status & STATUS_TSB) == STATUS_TSB);
+            search_direction = ((status & STATUS_DIR) == STATUS_DIR) ? (unsigned char)1 : (unsigned char)0;
+
+            // check for no devices on 1-Wire
+            if ((id_bit) && (cmp_id_bit))
+                break;
+            else 
+            {
+                if ((!id_bit) && (!cmp_id_bit) && (search_direction == 0)) 
+                {
+                    last_zero = id_bit_number;
+
+                    // check for Last discrepancy in family
+                    if (last_zero < 9)
+                        _last_family_discrepancy = last_zero;
+                }
+
+                // set or clear the bit in the ROM byte rom_byte_number
+                // with mask rom_byte_mask
+                if (search_direction == 1)
+                    _rom_number[rom_byte_number] |= rom_byte_mask;
+                else
+                    _rom_number[rom_byte_number] &= (unsigned char)~rom_byte_mask;
+
+                // increment the byte counter id_bit_number
+                // and shift the mask rom_byte_mask
+                id_bit_number++;
+                rom_byte_mask <<= 1;
+
+                // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
+                if (rom_byte_mask == 0) 
+                {
+                    calc_crc8(_rom_number[rom_byte_number]);  // accumulate the CRC
+                    rom_byte_number++;
+                    rom_byte_mask = 1;
+                }
+            }
+        } 
+        while(rom_byte_number < 8); // loop until through all ROM bytes 0-7
+
+        // if the search was successful then
+        if (!((id_bit_number < 65) || (_crc8 != 0))) 
+        {
+            // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
+            _last_discrepancy = last_zero;
+
+            // check for last device
+            if (_last_discrepancy == 0)
+                _last_device_flag = TRUE;
+
+            search_result = TRUE;
+        }
+    }
+
+    // if no device found then reset counters so next 'search' will be like a first
+    if (!search_result || (_rom_number[0] == 0)) 
+    {
+        _last_discrepancy = 0;
+        _last_device_flag = FALSE;
+        _last_family_discrepancy = 0;
+        search_result = FALSE;
+    }
+
+    return search_result;
 }
 
 
 //*********************************************************************
 uint8_t Ds248x::OWSpeed(uint8_t new_speed)
 {
-    uint8_t rtn_val;
-    return(rtn_val);
+    // set the speed
+    if (new_speed == MODE_OVERDRIVE)
+    {
+        _c1WS = CONFIG_1WS;
+    }
+    else
+    {
+        _c1WS = FALSE;
+    }
+
+    // write the new config
+    write_config(_c1WS | _cSPU | _cPDN | _cAPU);
+
+    return(new_speed);
 }
 
 
@@ -221,22 +831,79 @@
 uint8_t Ds248x::OWLevel(uint8_t new_level)
 {
     uint8_t rtn_val;
+    
+    // function only will turn back to non-strong pull-up
+    if (new_level != MODE_STANDARD)
+    {
+        rtn_val = MODE_STRONG;
+    }
+    else
+    {
+        // clear the strong pull-up bit in the global config state
+        _cSPU = FALSE;
+        // write the new config
+        write_config(_c1WS | _cSPU | _cPDN | _cAPU);
+        rtn_val = MODE_STANDARD;
+    }
+
     return(rtn_val);
 }
 
 
 //*********************************************************************
-uint8_t Ds248x::OWWriteBytePower(uint8_t sendbyte)
+bool Ds248x::OWWriteBytePower(uint8_t sendbyte)
 {
-    uint8_t rtn_val;
+    bool rtn_val = false;
+    
+    // set strong pull-up enable
+    _cSPU = CONFIG_SPU;
+    
+    // write the new config
+    if (!write_config(_c1WS | _cSPU | _cPDN | _cAPU))
+    {
+        rtn_val = false;
+    }
+    else
+    {
+        // perform write byte
+        OWWriteByte(sendbyte);
+        rtn_val = true;
+    }
+    
     return(rtn_val);
 }
 
 
 //*********************************************************************
-uint8_t Ds248x::OWReadBitPower(uint8_t applyPowerResponse)
+bool Ds248x::OWReadBitPower(uint8_t applyPowerResponse)
 {
-    uint8_t rtn_val;
+    bool rtn_val = false;
+
+    uint8_t rdbit;
+
+    // set strong pull-up enable
+    _cSPU = CONFIG_SPU;
+
+    // write the new config
+    if (!write_config(_c1WS | _cSPU | _cPDN | _cAPU))
+    {
+        rtn_val = false; 
+    }
+    else
+    {
+        // perform read bit
+        rdbit = OWReadBit();
+
+        // check if response was correct, if not then turn off strong pull-up
+        if (rdbit != applyPowerResponse) 
+        {
+            OWLevel(MODE_STANDARD);
+            rtn_val = false; 
+        }
+
+        rtn_val = true;
+    }
+
     return(rtn_val);
 }
 
@@ -244,6 +911,31 @@
 //*********************************************************************
 uint8_t Ds248x::calc_crc8(uint8_t data)
 {
-    uint8_t rtn_val;
-    return(rtn_val);
+    unsigned char i;
+
+    // See Application Note 27
+    _crc8 = _crc8 ^ data;
+    for (i = 0; i < 8; ++i) 
+    {
+        if (_crc8 & 1)
+        {
+            _crc8 = (_crc8 >> 1) ^ 0x8c;
+        }
+        else
+        {
+            _crc8 = (_crc8 >> 1);
+        }
+    }
+
+    return _crc8;
+}
+
+
+//*********************************************************************
+void Ds248x::get_rom_number(uint8_t *p_rom_buff)
+{
+    for(uint8_t idx = 0; idx < 8; idx++)
+    {
+        *(p_rom_buff + idx) = _rom_number[idx];
+    }
 }
\ No newline at end of file