Implementation of 1-Wire with added Alarm Search Functionality
Dependents: Max32630_One_Wire_Interface
OneWire_Bridge/DS28E17/ds28e17.cpp
- Committer:
- j3
- Date:
- 2016-03-18
- Revision:
- 17:b646b1e3970b
- Parent:
- 13:d1bdb03703de
- Child:
- 22:686273e55cdc
File content as of revision 17:b646b1e3970b:
/******************************************************************//** * 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) :_owm(owm) { } //********************************************************************* void Ds28e17::set_rom_id(const RomId &romId) { _romId = romId; } //********************************************************************* RomId Ds28e17::get_rom_id(void) { return _romId; } //********************************************************************* Ds28e17::CmdResult Ds28e17::I2C_WriteDataWithStop(uint8_t I2C_addr, uint8_t length, uint8_t *data, uint8_t &status, uint8_t &wr_status) { Ds28e17::CmdResult bridge_result = Ds28e17::OperationFailure; size_t send_cnt = 0; uint8_t send_block[0xff]; OneWireInterface::CmdResult ow_result = _owm.OWMatchROM(_romId); if(ow_result == OneWireInterface::Success) { //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 (size_t 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 bridge_result = send_packet(send_block, send_cnt, status, wr_status); } return bridge_result; } //********************************************************************* Ds28e17::CmdResult Ds28e17::I2C_WriteDataNoStop(uint8_t I2C_addr, uint8_t length, uint8_t *data, uint8_t &status, uint8_t &wr_status) { Ds28e17::CmdResult bridge_result = Ds28e17::OperationFailure; size_t send_cnt = 0; uint8_t send_block[0xff]; OneWireInterface::CmdResult ow_result = _owm.OWMatchROM(_romId); if(ow_result == OneWireInterface::Success) { // 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(size_t 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 bridge_result = send_packet(send_block, send_cnt, status, wr_status); } return bridge_result; } //********************************************************************* Ds28e17::CmdResult Ds28e17::I2C_WriteDataOnly(uint8_t length, uint8_t *data, uint8_t &status, uint8_t &wr_status) { Ds28e17::CmdResult bridge_result = Ds28e17::OperationFailure; size_t send_cnt = 0; uint8_t send_block[0xff]; OneWireInterface::CmdResult ow_result = _owm.OWMatchROM(_romId); if(ow_result == OneWireInterface::Success) { // 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 (size_t 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 bridge_result = send_packet(send_block, send_cnt, status, wr_status); } return bridge_result; } //********************************************************************* Ds28e17::CmdResult Ds28e17::I2C_WriteDataOnlyWithStop(uint8_t length, uint8_t *data, uint8_t &status, uint8_t &wr_status) { Ds28e17::CmdResult bridge_result = Ds28e17::OperationFailure; size_t send_cnt = 0; uint8_t send_block[0xff]; OneWireInterface::CmdResult ow_result = _owm.OWMatchROM(_romId); if(ow_result == OneWireInterface::Success) { //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 (size_t 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 bridge_result = send_packet(send_block, send_cnt, status, wr_status); } return bridge_result; } //********************************************************************* Ds28e17::CmdResult 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) { Ds28e17::CmdResult bridge_result = Ds28e17::OperationFailure; size_t send_cnt = 0; size_t idx = 0; uint8_t send_block[0xff]; OneWireInterface::CmdResult ow_result = _owm.OWMatchROM(_romId); if(ow_result == OneWireInterface::Success) { //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 bridge_result = send_packet(send_block, send_cnt, status, wr_status); if(bridge_result == Ds28e17::Success) { ow_result = _owm.OWReadBlock(read_data, nu_bytes_read); if(ow_result == OneWireInterface::Success) { bridge_result = Ds28e17::Success; } else { bridge_result = Ds28e17::CommsReadBlockError; } } } return bridge_result; } //********************************************************************* Ds28e17::CmdResult Ds28e17::I2C_ReadDataWithStop(uint8_t I2C_addr, uint8_t nu_bytes_read, uint8_t &status, uint8_t *read_data) { Ds28e17::CmdResult bridge_result = Ds28e17::OperationFailure; size_t send_cnt = 0; uint8_t send_block[0xff]; OneWireInterface::CmdResult ow_result = _owm.OWMatchROM(_romId); if(ow_result == OneWireInterface::Success) { //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 bridge_result = send_packet(send_block, send_cnt, status); if(bridge_result == Ds28e17::Success) { ow_result = _owm.OWReadBlock(read_data, nu_bytes_read); if(ow_result == OneWireInterface::Success) { bridge_result = Ds28e17::Success; } else { bridge_result = Ds28e17::CommsReadBlockError; } } } return bridge_result; } //********************************************************************* Ds28e17::CmdResult Ds28e17::WriteConfigReg(uint8_t data) { Ds28e17::CmdResult bridge_result = Ds28e17::OperationFailure; OneWireInterface::CmdResult ow_result = _owm.OWMatchROM(_romId); if(ow_result == OneWireInterface::Success) { // Send CMD and Data uint8_t send_block[] = {CMD_WRITE_CONFIG_REG, data}; ow_result = _owm.OWWriteBlock(send_block, 2); if(ow_result == OneWireInterface::Success) { _i2c_speed = data & 0x03; // Save off _i2c_speed setting to be used by other functions bridge_result = Ds28e17::Success; } else { bridge_result = Ds28e17::CommsWriteBlockError; } } return bridge_result; } //********************************************************************* Ds28e17::CmdResult Ds28e17::ReadConfigReg(uint8_t & config) { Ds28e17::CmdResult bridge_result = Ds28e17::OperationFailure; OneWireInterface::CmdResult ow_result = _owm.OWMatchROM(_romId); if(ow_result == OneWireInterface::Success) { // Send CMD and receive Data ow_result = _owm.OWWriteByte(CMD_READ_CONFIG_REG); if(ow_result == OneWireInterface::Success) { ow_result = _owm.OWReadByte(config); if(ow_result == OneWireInterface::Success) { bridge_result = Ds28e17::Success; } else { bridge_result = Ds28e17::CommsReadByteError; } } else { bridge_result = Ds28e17::CommsWriteByteError; } } return bridge_result; } //********************************************************************* Ds28e17::CmdResult Ds28e17::DisableOWMode() { Ds28e17::CmdResult bridge_result = Ds28e17::OperationFailure; OneWireInterface::CmdResult ow_result = _owm.OWMatchROM(_romId); if(ow_result == OneWireInterface::Success) { // Send CMD ow_result = _owm.OWWriteByte(CMD_DISABLE_OW_MODE); if(ow_result == OneWireInterface::Success) { bridge_result = Ds28e17::Success; } else { bridge_result = Ds28e17::CommsWriteByteError; } } return bridge_result; } //********************************************************************* Ds28e17::CmdResult Ds28e17::EnableSleepMode() { Ds28e17::CmdResult bridge_result = Ds28e17::OperationFailure; OneWireInterface::CmdResult ow_result = _owm.OWMatchROM(_romId); if(ow_result == OneWireInterface::Success) { // Send CMD ow_result = _owm.OWWriteByte(CMD_ENABLE_SLEEP_MODE); if(ow_result == OneWireInterface::Success) { bridge_result = Ds28e17::Success; } else { bridge_result = Ds28e17::CommsWriteByteError; } } return bridge_result; } //********************************************************************* Ds28e17::CmdResult Ds28e17::ReadDeviceRevision(uint8_t & rev) { Ds28e17::CmdResult bridge_result = Ds28e17::OperationFailure; OneWireInterface::CmdResult ow_result = _owm.OWMatchROM(_romId); if(ow_result == OneWireInterface::Success) { // Send CMD and receive Data ow_result = _owm.OWWriteByte(CMD_READ_DEVICE_REV); if(ow_result == OneWireInterface::Success) { ow_result = _owm.OWReadByte(rev); if(ow_result == OneWireInterface::Success) { bridge_result = Ds28e17::Success; } else { bridge_result = Ds28e17::CommsReadByteError; } } else { bridge_result = Ds28e17::CommsWriteByteError; } } return bridge_result; } //********************************************************************* 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; } //********************************************************************* Ds28e17::CmdResult Ds28e17::send_packet(const uint8_t * data, uint8_t data_length, uint8_t & status, uint8_t & wr_status) { Ds28e17::CmdResult bridge_result = Ds28e17::CommsWriteBlockError; uint32_t poll_count = 0; OneWireInterface::CmdResult ow_result = _owm.OWWriteBlock(data, data_length); if(ow_result == OneWireInterface::Success) { // Poll for Zero 1-Wire bit and return if an error occurs uint8_t recvbit = 0x01; do { ow_result = _owm.OWReadBit(recvbit); } while(recvbit && (poll_count++ < POLL_LIMIT) && (ow_result == OneWireInterface::Success)); if(ow_result == OneWireInterface::Success) { if(poll_count < POLL_LIMIT) { //Read Status and write status uint8_t read_block[2]; ow_result = _owm.OWReadBlock(read_block, 2); if(ow_result == OneWireInterface::Success) { status = read_block[0]; wr_status = read_block[1]; bridge_result = Ds28e17::Success; } else { bridge_result = Ds28e17::CommsReadBlockError; } } else { bridge_result = Ds28e17::TimeoutError; } } else { bridge_result = Ds28e17::CommsReadBitError; } } return bridge_result; } //********************************************************************* Ds28e17::CmdResult Ds28e17::send_packet(const uint8_t * data, uint8_t data_length, uint8_t & status) { Ds28e17::CmdResult bridge_result = Ds28e17::CommsWriteBlockError; uint32_t poll_count = 0; OneWireInterface::CmdResult ow_result = _owm.OWWriteBlock(data, data_length); if(ow_result == OneWireInterface::Success) { // Poll for Zero 1-Wire bit and return if an error occurs uint8_t recvbit = 0x01; do { ow_result = _owm.OWReadBit(recvbit); } while(recvbit && (poll_count++ < POLL_LIMIT) && (ow_result == OneWireInterface::Success)); if(ow_result == OneWireInterface::Success) { if(poll_count < POLL_LIMIT) { //Read Status ow_result = _owm.OWReadByte(status); if(ow_result == OneWireInterface::Success) { bridge_result = Ds28e17::Success; } else { bridge_result = Ds28e17::CommsReadByteError; } } else { bridge_result = Ds28e17::TimeoutError; } } else { bridge_result = Ds28e17::CommsReadBitError; } } return bridge_result; }