Implementation of 1-Wire with added Alarm Search Functionality

Dependents:   Max32630_One_Wire_Interface

OneWire_Bridge/DS28E17/ds28e17.cpp

Committer:
j3
Date:
2016-03-08
Revision:
13:d1bdb03703de
Parent:
7:78a8857b3810
Child:
17:b646b1e3970b

File content as of revision 13:d1bdb03703de:

/******************************************************************//**
* @file ds28e17.cpp
*
* @author Justin Jordan
*
* @version 0.0.0
*
* Started: 31JAN16
*
* Updated: 
*
* @brief Source file for DS28E17 1-wire to I2C bridge
***********************************************************************
* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Maxim Integrated
* Products, Inc. shall not be used except as stated in the Maxim Integrated
* Products, Inc. Branding Policy.
*
* The mere transfer of this software does not imply any licenses
* of trade secrets, proprietary technology, copyrights, patents,
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
**********************************************************************/


#include "ds28e17.h" 

const uint16_t Ds28e17::_oddparity[] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };


//*********************************************************************
Ds28e17::Ds28e17(OneWireInterface &owm)
:_p_owm(owm)
{
    
}


//*********************************************************************
bool Ds28e17::I2C_WriteDataWithStop(uint8_t I2C_addr, uint8_t length, 
                                    uint8_t *data, uint8_t &status, 
                                    uint8_t &wr_status)
{
    bool rtn_val = false;
    
    size_t send_cnt = 0;
    size_t idx = 0;
    uint32_t poll_count = 0;
    uint8_t send_block[0xff];
    
    if(_p_owm.OWMatchROM())
    {
        //seed the crc
        _crc16 = 0;
        
        // Form the 1-Wire Packet 
        
        // I2C Write Data with Stop command
        send_block[send_cnt] = CMD_I2C_WRITE_W_STOP;
        docrc16(send_block[send_cnt++]);
        
        // I2C Address
        send_block[send_cnt] = I2C_addr;
        docrc16(send_block[send_cnt++]);
        
        // Length field
        send_block[send_cnt] = length;
        docrc16(send_block[send_cnt++]);
        
        // Form the write data  
        for (idx = 0; idx < length; idx++) 
        {
            send_block[send_cnt] = data[idx];
            docrc16(send_block[send_cnt++]);
        }
        
        // Form the CRC16
        _crc16 = _crc16^0xFFFF;
        send_block[send_cnt++] = ((uint8_t)(_crc16 & 0xFF));
        send_block[send_cnt++] = ((uint8_t)((_crc16 >> 8) & 0xFF));
        
        // Send Packet
        _p_owm.OWWriteBlock(send_block, send_cnt);
        
        // Poll for Zero 1-Wire bit and return if an error occurs
        while(_p_owm.OWReadBit() && (poll_count++ < POLL_LIMIT));
        
        if(poll_count < POLL_LIMIT)
        {
            //Read Status
            status = _p_owm.OWReadByte();
            
            //Read Write Status
            wr_status = _p_owm.OWReadByte();
            
            rtn_val = true;
        }
        else
        {
            rtn_val = false;
        }
        
    }
    else
    {
        rtn_val = false;
    }
    
    return(rtn_val);
}


//*********************************************************************
bool Ds28e17::I2C_WriteDataNoStop(uint8_t I2C_addr, uint8_t length, 
                                  uint8_t *data, uint8_t &status, 
                                  uint8_t &wr_status)
{
    bool rtn_val = false;
    
    size_t send_cnt = 0;
    size_t idx = 0;
    uint32_t poll_count = 0;
    uint8_t send_block[0xff];
    
    if(_p_owm.OWMatchROM())
    {
        // seed the crc
        _crc16 = 0;
        
        // I2C Write Data with Stop command
        send_block[send_cnt] = CMD_I2C_WRITE_NO_STOP;
        docrc16(send_block[send_cnt++]);
        
        // I2C Address
        send_block[send_cnt] = I2C_addr;
        docrc16(send_block[send_cnt++]);
        
        // Length field
        send_block[send_cnt] = length;
        docrc16(send_block[send_cnt++]);
        
        // Form the write data
        for(idx = 0; idx < length; idx++)
        {
            send_block[send_cnt] = data[idx];
            docrc16(send_block[send_cnt++]);
        }
        
        // Form the CRC16
        _crc16 = _crc16^0xFFFF;
        send_block[send_cnt++] = ((uint8_t)(_crc16 & 0xFF));
        send_block[send_cnt++] = ((uint8_t)((_crc16 >> 8) & 0xFF));
        
        // Send Packet
        _p_owm.OWBlock(send_block, send_cnt);
        
        // Poll for Zero 1-Wire bit and return if an error occurs
        while(_p_owm.OWReadBit() && (poll_count++ < POLL_LIMIT)); 
        
        if(poll_count < POLL_LIMIT)
        {
            //Read Status
            status = _p_owm.OWReadByte();
            
            //Read Write Status
            wr_status = _p_owm.OWReadByte();
            
            rtn_val = true;
        }
        else
        {
            rtn_val = false;
        }
    }
    else
    {
        rtn_val = false;
    }
    
    return(rtn_val);
}


//*********************************************************************
bool Ds28e17::I2C_WriteDataOnly(uint8_t length, uint8_t *data, 
                                uint8_t &status, uint8_t &wr_status)
{
    bool rtn_val = false;
    
    size_t send_cnt = 0;
    size_t idx = 0;
    uint32_t poll_count = 0;
    uint8_t send_block[0xff];
    
    if(_p_owm.OWMatchROM())
    {
        // seed the crc
        _crc16 = 0;
        
        // Form the 1-Wire Packet
        
        // I2C Write Data with Stop command
        send_block[send_cnt] = CMD_I2C_WRITE_ONLY;
        docrc16(send_block[send_cnt++]);
        
        // Length field
        send_block[send_cnt] = length;
        docrc16(send_block[send_cnt++]);
        
        // Form the write data
        for (idx = 0; idx < length; idx++) 
        {
            send_block[send_cnt] = data[idx];
            docrc16(send_block[send_cnt++]);
        }
        
        // Form the CRC16\
        _crc16 = _crc16^0xFFFF;
        send_block[send_cnt++] = (_crc16 & 0xFF);
        send_block[send_cnt++] = ((_crc16 >> 8) & 0xFF);
        
        // Send Packet
        _p_owm.OWBlock(send_block, send_cnt);
        
        // Poll for Zero 1-Wire bit and return if an error occurs
        while(_p_owm.OWReadBit() && (poll_count++ < POLL_LIMIT));
        
        
        if(poll_count < POLL_LIMIT)
        {
            // Read Status
            status = _p_owm.OWReadByte();
            
            // Read Write Status
            wr_status = _p_owm.OWReadByte();
            
            rtn_val = true; 
        }
        else
        {
            rtn_val = false;
        }
    }
    else
    {
        rtn_val = false;
    }
    
    
    return(rtn_val);
}


//*********************************************************************
bool Ds28e17::I2C_WriteDataOnlyWithStop(uint8_t length, uint8_t *data, 
                                        uint8_t &status, uint8_t &wr_status)
{
    bool rtn_val = false;
    
    size_t send_cnt = 0;
    size_t idx = 0;
    uint32_t poll_count = 0;
    uint8_t send_block[0xff];
    
    if(_p_owm.OWMatchROM())
    {
        //seed the crc
        _crc16 = 0;
    
        // Form the 1-Wire Packet
    
        // I2C Write Data with Stop command
        send_block[send_cnt] = CMD_I2C_WRITE_ONLY_W_STOP;
        docrc16(send_block[send_cnt++]);
    
        // Length field
        send_block[send_cnt] = length;
        docrc16(send_block[send_cnt++]);
    
        // Form the write data
        for (idx = 0; idx < length; idx++) 
        {
            send_block[send_cnt] = data[idx];
            docrc16(send_block[send_cnt++]);
        }
    
        // Form the CRC16
        _crc16 = _crc16^0xFFFF;
        send_block[send_cnt++] = (_crc16 & 0xFF);
        send_block[send_cnt++] = ((_crc16 >> 8) & 0xFF);
    
        // Send Packet
        _p_owm.OWBlock(send_block, send_cnt);
    
        // Poll for Zero 1-Wire bit and return if an error occurs
        while(_p_owm.OWReadBit() && (poll_count++ < POLL_LIMIT));
    
        if(poll_count < POLL_LIMIT)
        {
            // Read Status
            status = _p_owm.OWReadByte();
            
            // Read Write Status
            wr_status = _p_owm.OWReadByte();
            
            rtn_val = true; 
        }
        else
        {
            rtn_val = false;
        }
    }
    else
    {
        rtn_val = false;
    }
    
    return(rtn_val);
}


//*********************************************************************
bool Ds28e17::I2C_WriteReadDataWithStop(uint8_t I2C_addr, uint8_t length, 
                                        uint8_t *data, uint8_t nu_bytes_read, 
                                        uint8_t &status, uint8_t &wr_status, 
                                        uint8_t *read_data)
{
    bool rtn_val = false;
    
    size_t send_cnt = 0;
    size_t idx = 0;
    uint32_t poll_count = 0;
    uint8_t send_block[0xff];
    
    if(_p_owm.OWMatchROM())
    {
        //seed the crc
        _crc16 = 0;
    
        // Form the 1-Wire Packet
    
        // I2C Write Data with Stop command
        send_block[send_cnt] = CMD_I2C_WRITE_READ_W_STOP;
        docrc16(send_block[send_cnt++]);
    
        // I2C Address
        send_block[send_cnt] = I2C_addr;
        docrc16(send_block[send_cnt++]);
    
        // Length field
        send_block[send_cnt] = length;
        docrc16(send_block[send_cnt++]);
    
        // Form the write data
        for (idx = 0; idx < length; idx++) 
        {
            send_block[send_cnt] = data[idx];
            docrc16(send_block[send_cnt++]);
        }
    
        // # of bytes to Read field
        send_block[send_cnt] = nu_bytes_read;
        docrc16(send_block[send_cnt++]);
    
        // Form the CRC16
        _crc16 = _crc16^0xFFFF;
        send_block[send_cnt++] = (_crc16 & 0xFF);
        send_block[send_cnt++] = ((_crc16 >> 8) & 0xFF);
    
        // Send Packet
        _p_owm.OWBlock(send_block, send_cnt);
    
        // Poll for Zero 1-Wire bit and return if an error occurs
        while(_p_owm.OWReadBit() && (poll_count++ < POLL_LIMIT));
        
        if(poll_count < POLL_LIMIT)
        {
            // Read Status
            status = _p_owm.OWReadByte();
            
            // Read Write Status
            wr_status = _p_owm.OWReadByte();
            
            //seed the crc for read bytes
            _crc16 = 0;
        
            // Read Data
            for(idx = 0; idx < nu_bytes_read; idx++)
            {
                read_data[idx] = _p_owm.OWReadByte();
                docrc16(read_data[idx]);
            }
            
            /********** TODO **********/
            // need to check datasheet, below was left commented for a reason.  
            // need to see why
        
            // Read the CRC16
            //docrc16(OWReadByte());  //Receive first crc16 byte
            //docrc16(OWReadByte());    //Receive second crc16 byte
        
            // check CRC16
            //if (CRC16 != 0xB001)
            //  return false;
            
            rtn_val = true; 
        }
        else
        {
            rtn_val = false;
        }
    }
    else
    {
        rtn_val = false;
    }
    
    return(rtn_val);
}


//*********************************************************************
bool Ds28e17::I2C_ReadDataWithStop(uint8_t I2C_addr, uint8_t nu_bytes_read, 
                                   uint8_t &status, uint8_t *read_data)
{
    bool rtn_val = false;
    
    size_t send_cnt = 0;
    size_t idx = 0;
    uint32_t poll_count = 0;
    uint8_t send_block[0xff];
    
    if(_p_owm.OWMatchROM())
    {
        //seed the crc for transmit bytes
        _crc16 = 0;
    
        // Form the 1-Wire Packet to send
    
        // I2C Write Data with Stop command
        send_block[send_cnt] = CMD_I2C_READ_W_STOP;
        docrc16(send_block[send_cnt++]);
    
        // I2C Address
        send_block[send_cnt] = I2C_addr;
        docrc16(send_block[send_cnt++]);
    
        // # of bytes to Read field
        send_block[send_cnt] = nu_bytes_read;
        docrc16(send_block[send_cnt++]);
    
        // Form the CRC16
        _crc16 = _crc16^0xFFFF;
        send_block[send_cnt++] = (_crc16 & 0xFF);
        send_block[send_cnt++] = ((_crc16 >> 8) & 0xFF);
    
        // Send Packet
        _p_owm.OWBlock(send_block, send_cnt);
    
        // Poll for Zero 1-Wire bit and return if an error occurs
        while(_p_owm.OWReadBit() && (poll_count++ < POLL_LIMIT));
        
        if(poll_count < POLL_LIMIT)
        {
            // Read Status
            status = _p_owm.OWReadByte();
            
            //seed the crc for read bytes
            _crc16 = 0;
        
            // Read Data
            for(idx = 0; idx < nu_bytes_read; idx++)
            {
                read_data[idx] = _p_owm.OWReadByte();
                docrc16(read_data[idx]);
            }
            
            /********** TODO **********/
            // need to check datasheet, below was left commented for a reason.  
            // need to see why
        
            // Read the CRC16
            //docrc16(OWReadByte());  //Receive first crc16 byte
            //docrc16(OWReadByte());    //Receive second crc16 byte
        
            // check CRC16
            //if (CRC16 != 0xB001)
            //  return false;
            
            rtn_val = true; 
        }
        else
        {
            rtn_val = false;
        }
    }
    else
    {
        rtn_val = false;
    }
    
    return(rtn_val);
}


//*********************************************************************
bool Ds28e17::WriteConfigReg(uint8_t data)
{
    bool rtn_val = false;
    
    if(_p_owm.OWMatchROM())
    {
        // Send CMD and Data
        _p_owm.OWWriteByte(CMD_WRITE_CONFIG_REG);
        _p_owm.OWWriteByte(data);
        _i2c_speed = data & 0x03; // Save off _i2c_speed setting to be used by other functions
        rtn_val = true;
    }
    else
    {
        rtn_val = false;
    }
    
    return(rtn_val);
}


//*********************************************************************
uint8_t Ds28e17::ReadConfigReg(void)
{
    uint8_t rtn_val = false;
    
    if(_p_owm.OWMatchROM())
    {
        // Send CMD and receive Data
        _p_owm.OWWriteByte(CMD_READ_CONFIG_REG);
        rtn_val = _p_owm.OWReadByte();
    }
    else
    {
        rtn_val = false;
    }
    
    return(rtn_val);
}


//*********************************************************************
bool Ds28e17::DisableOWMode()
{
    bool rtn_val = false;
    
    if(_p_owm.OWMatchROM())
    {
        // Send CMD
        _p_owm.OWWriteByte(CMD_DISABLE_OW_MODE);
        rtn_val = true;
    }
    else
    {
        rtn_val = false;
    }
    
    return(rtn_val);
}


//*********************************************************************
bool Ds28e17::EnableSleepMode()
{
    bool rtn_val = false;
    
    if(_p_owm.OWMatchROM())
    {
        // Send CMD
        _p_owm.OWWriteByte(CMD_ENABLE_SLEEP_MODE);
        rtn_val = true;
    }
    else
    {
        rtn_val = false;
    }
    
    return(rtn_val);
}


//*********************************************************************
uint8_t Ds28e17::ReadDeviceRevision(void)
{
    uint8_t rtn_val;
    
    if(_p_owm.OWMatchROM())
    {
        // Send CMD and receive Data
        _p_owm.OWWriteByte(CMD_READ_DEVICE_REV);
        rtn_val = _p_owm.OWReadByte();
    }
    else
    {
        rtn_val = false;
    }
    
    return(rtn_val);
}


//*********************************************************************
uint16_t Ds28e17::docrc16(uint16_t data)
{
    data = ((data ^ (_crc16 & 0xff)) & 0xff);
    _crc16 >>= 8;

    if (Ds28e17::_oddparity[data & 0xf] ^ Ds28e17::_oddparity[data >> 4])
    {
        _crc16 ^= 0xc001;
    }

    data <<= 6;
    _crc16  ^= data;
    data <<= 1;
    _crc16   ^= data;

    return _crc16;
}