Implementation of 1-Wire with added Alarm Search Functionality
Dependents: Max32630_One_Wire_Interface
Diff: OneWire_Bridge/DS28E17/ds28e17.cpp
- Revision:
- 7:78a8857b3810
- Parent:
- 4:ca27db159b10
- Child:
- 13:d1bdb03703de
--- a/OneWire_Bridge/DS28E17/ds28e17.cpp Tue Feb 09 20:08:51 2016 +0000 +++ b/OneWire_Bridge/DS28E17/ds28e17.cpp Fri Feb 12 22:56:13 2016 +0000 @@ -43,32 +43,16 @@ **********************************************************************/ -#include "ds28e17.h" - +#include "ds28e17.h" -#define OW_ENABLE_DELAY 3 -#define CMD_I2C_WRITE_W_STOP 0x4B -#define CMD_I2C_WRITE_NO_STOP 0x5A -#define CMD_I2C_WRITE_ONLY 0x69 -#define CMD_I2C_WRITE_ONLY_W_STOP 0x78 -#define CMD_I2C_READ_W_STOP 0x87 -#define CMD_I2C_WRITE_READ_W_STOP 0x2D -#define CMD_WRITE_CONFIG_REG 0xD2 -#define CMD_READ_CONFIG_REG 0xE1 -#define CMD_DISABLE_OW_MODE 0x96 -#define CMD_ENABLE_SLEEP_MODE 0x1E -#define CMD_READ_DEVICE_REV 0xC3 -#define POLL_LIMIT 10000 - - -uint16_t Ds28e17::_oddparity[] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; +const uint16_t Ds28e17::_oddparity[] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; //********************************************************************* -Ds28e17::Ds28e17(OneWireInterface *p_owm) +Ds28e17::Ds28e17(OneWireInterface &owm) +:_p_owm(&owm), _owm_owner(false) { - _p_owm = p_owm; - _owm_owner = false; + } @@ -84,15 +68,73 @@ //********************************************************************* bool Ds28e17::I2C_WriteDataWithStop(uint8_t I2C_addr, uint8_t length, - uint8_t *data, uint8_t status, - uint8_t wr_status) + uint8_t *data, uint8_t &status, + uint8_t &wr_status) { bool rtn_val = false; - /*uint8_t send_cnt = 0; - uint8_t i; - uint16_t poll_count = 0; - uint8_t send_block[0xFF];*/ + 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); } @@ -100,31 +142,209 @@ //********************************************************************* bool Ds28e17::I2C_WriteDataNoStop(uint8_t I2C_addr, uint8_t length, - uint8_t *data, uint8_t status, - uint8_t wr_status) + 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) + 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) + 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); } @@ -132,23 +352,306 @@ //********************************************************************* 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 &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) + 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; +} + +