Implementation of 1-Wire with added Alarm Search Functionality
Dependents: Max32630_One_Wire_Interface
OneWire_Bridge/DS28E17/ds28e17.cpp
- Committer:
- j3
- Date:
- 2016-02-12
- Revision:
- 7:78a8857b3810
- Parent:
- 4:ca27db159b10
- Child:
- 13:d1bdb03703de
File content as of revision 7:78a8857b3810:
/******************************************************************//** * @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), _owm_owner(false) { } //********************************************************************* Ds28e17::~Ds28e17() { if(_owm_owner) { delete _p_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; }