Implementation of 1-Wire with added Alarm Search Functionality
Dependents: Max32630_One_Wire_Interface
Diff: OneWire_Masters/OneWireMaster.cpp
- Revision:
- 17:b646b1e3970b
- Parent:
- 15:f6cb0d906fb6
- Child:
- 21:00c94aeb533e
--- a/OneWire_Masters/OneWireMaster.cpp Wed Mar 16 19:10:19 2016 +0000 +++ b/OneWire_Masters/OneWireMaster.cpp Fri Mar 18 20:21:05 2016 +0000 @@ -1,17 +1,4 @@ /******************************************************************//** -* @file OneWireMaster.cpp -* -* @author Justin Jordan -* -* @version 0.0.0 -* -* Started: 08FEB16 -* -* Updated: -* -* @brief Header file for functions shared between masters, that should -* be implemented only once. -*********************************************************************** * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -47,162 +34,121 @@ #include "OneWireMaster.h" -//********************************************************************* -void OneWireMaster::OWWriteBit(uint8_t sendbit) -{ - OWTouchBit(sendbit); -} +const uint16_t OneWireMaster::_oddparity[] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; //********************************************************************* -uint8_t OneWireMaster::OWReadBit() +OneWireInterface::CmdResult OneWireMaster::OWWriteBit(uint8_t sendbit) { - return(OWTouchBit(0x01)); + return OWTouchBit(sendbit); } //********************************************************************* -uint8_t OneWireMaster::OWTouchByte(uint8_t sendbyte) +OneWireInterface::CmdResult OneWireMaster::OWReadBit(uint8_t & recvbit) { - uint8_t rtn_val; - - if (sendbyte == 0xFF) - { - rtn_val = OWReadByte(); - } - else - { - OWWriteByte(sendbyte); - rtn_val = sendbyte; - } - - return(rtn_val); + recvbit = 0x01; + return(OWTouchBit(recvbit)); } //********************************************************************* -void OneWireMaster::OWBlock(uint8_t *tran_buf, uint8_t tran_len) +OneWireInterface::CmdResult OneWireMaster::OWTouchByte(uint8_t & sendrecvbyte) { - uint8_t i; + OneWireInterface::CmdResult result = OWWriteByte(sendrecvbyte); + + if (result == OneWireInterface::Success) + { + OWReadByte(sendrecvbyte); + } - for (i = 0; i < tran_len; i++) - { - tran_buf[i] = OWTouchByte(tran_buf[i]); - } + return result; } //********************************************************************* -void OneWireMaster::OWWriteBlock(const uint8_t *tran_buf, uint8_t tran_len) +OneWireInterface::CmdResult OneWireMaster::OWBlock(uint8_t *tran_buf, uint8_t tran_len) { - uint8_t idx; - - for(idx = 0; idx < tran_len; idx++) - { - OWWriteByte(tran_buf[idx]); - } -} + OneWireInterface::CmdResult result; + for (uint8_t i = 0; i < tran_len; i++) + { + result = OWTouchByte(tran_buf[i]); + + if (result != OneWireInterface::Success) + { + break; + } + } -//********************************************************************* -void OneWireMaster::OWReadBlock(uint8_t *recv_buf, uint8_t recv_len) + return result; +} + + +OneWireInterface::CmdResult OneWireMaster::OWFirst(RomId & romId) { - uint8_t idx; - - for(idx = 0; idx < recv_len; idx++) - { - recv_buf[idx] = OWReadByte(); - } + // reset the search state + _last_discrepancy = 0; + _last_device_flag = 0; + _last_family_discrepancy = 0; + + return OWSearch(romId); } //********************************************************************* -bool OneWireMaster::OWFirst(void) +OneWireInterface::CmdResult OneWireMaster::OWNext(RomId & romId) { - // reset the search state - _last_discrepancy = 0; - _last_device_flag = false; - _last_family_discrepancy = 0; - - return OWSearch(); + // leave the search state alone + return OWSearch(romId); } //********************************************************************* -bool OneWireMaster::OWNext(void) +OneWireInterface::CmdResult OneWireMaster::OWVerify(const RomId & romId) { - // leave the search state alone - return OWSearch(); -} - - -//********************************************************************* -bool OneWireMaster::OWVerify(void) -{ - bool rtn_val = false; - - uint8_t rom_backup[8]; - uint8_t i,rslt,ld_backup,ldf_backup,lfd_backup; + OneWireInterface::CmdResult result; + + RomId romIdCopy(romId); + + int 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; + _last_device_flag = 0; - if (OWSearch()) + result = OWSearch(romIdCopy); + if (result == OneWireInterface::Success) { // check if same device found - rslt = true; - for (i = 0; i < 8; i++) + if (romId != romIdCopy) { - if (rom_backup[i] != _rom_number[i]) - { - rslt = false; - break; - } + result = OneWireInterface::OperationFailure; } - } - else - { - rslt = false; } // 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); + return result; } //********************************************************************* -void OneWireMaster::OWTargetSetup(uint8_t family_code) +void OneWireMaster::OWTargetSetup(RomId & romId) { - uint8_t i; - // set the search state to find SearchFamily type devices - _rom_number[0] = family_code; - for (i = 1; i < 8; i++) + for (int i = 1; i < 8; i++) { - _rom_number[i] = 0; + romId[i] = 0; } _last_discrepancy = 64; @@ -216,12 +162,12 @@ { // 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) + if (_last_discrepancy == 0) { _last_device_flag = true; } @@ -229,197 +175,156 @@ //********************************************************************* -bool OneWireMaster::OWReadROM(void) +OneWireInterface::CmdResult OneWireMaster::OWReadROM(RomId & romId) { - bool rtn_val = false; + OneWireInterface::CmdResult result; - if(!OWReset()) - { - rtn_val = false; - } - else + uint8_t buf[2 + RomId::byteLen]; + + result = OWReset(); + if (result == OneWireInterface::Success) { - if(!OWWriteByte(READ_ROM)) - { - rtn_val = false; - } - else - { - OWReadBlock(_rom_number, ROMnumberLen); - rtn_val = true; - } + result = OWWriteByte(0x33); // READ ROM + } + + // read the ROM + if (result == OneWireInterface::Success) + { + result = OWReadBlock(buf, RomId::byteLen); } - return rtn_val; + // verify CRC8 + if ((result == OneWireInterface::Success) && romId.crc8Valid() && (buf[1] != 0)) + { + romId = RomId(reinterpret_cast<std::uint8_t (&)[RomId::byteLen]>(buf[0])); + } + + return result; } //********************************************************************* -bool OneWireMaster::OWSkipROM(void) +OneWireInterface::CmdResult OneWireMaster::OWSkipROM(void) { - bool rtn_val = false; + OneWireInterface::CmdResult result; - if(!OWReset()) + result = OWReset(); + if (result == OneWireInterface::Success) { - rtn_val = false; - } - else - { - if(!OWWriteByte(SKIP_ROM)) - { - rtn_val = false; - } - else - { - rtn_val = true; - } + result = OWWriteByte(0xCC); } - return rtn_val; + return result; } //********************************************************************* -bool OneWireMaster::OWMatchROM(void) +OneWireInterface::CmdResult OneWireMaster::OWMatchROM(const RomId & romId) { - bool rtn_val = false; - uint8_t idx; + OneWireInterface::CmdResult result; - if(!OWReset()) - { - rtn_val = false; - } - else + uint8_t buf[1 + RomId::byteLen]; + + // use MatchROM + result = OWReset(); + if (result == OneWireInterface::Success) { - if(!OWWriteByte(MATCH_ROM)) - { - rtn_val = false; - } - else - { - for(idx = 0; idx < ROMnumberLen; idx++) - { - OWWriteByte(_rom_number[idx]); - } - rtn_val = true; - } + buf[0] = 0x55; + std::memcpy(&buf[1], romId, RomId::byteLen); + // send command and rom + result = OWWriteBlock(buf, 1 + RomId::byteLen); } - - return rtn_val; + + return result; } //********************************************************************* -bool OneWireMaster::OWOverdriveSkipROM(void) +OneWireInterface::CmdResult OneWireMaster::OWOverdriveSkipROM(void) { - bool rtn_val = false; + OneWireInterface::CmdResult result = OWSpeed(SPEED_STANDARD); - if(!OWReset()) - { - rtn_val = false; - } - else + if (result == OneWireInterface::Success) { - if(!OWWriteByte(OVERDRIVE_SKIP)) - { - rtn_val = false; - } - else - { - //change speed for subsequent comands - OWSpeed(SPEED_OVERDRIVE); - rtn_val = true; - } + result = OWReset(); } - return rtn_val; + if (result == OneWireInterface::Success) + { + result = OWWriteByte(0x3C); + } + + if (result == OneWireInterface::Success) + { + result = OWSpeed(SPEED_OVERDRIVE); + } + + return result; } //********************************************************************* -bool OneWireMaster::OWOverdriveMatchROM(void) +OneWireInterface::CmdResult OneWireMaster::OWOverdriveMatchROM(const RomId & romId) { - bool rtn_val = false; - uint8_t idx; + OneWireInterface::CmdResult result; - if(!OWReset()) + // use overdrive MatchROM + OWSpeed(SPEED_STANDARD); + + result = OWReset(); + if (result == OneWireInterface::Success) { - rtn_val = false; - } - else - { - if(!OWWriteByte(OVERDRIVE_MATCH)) + result = OWWriteByte(0x69); + if (result == OneWireInterface::Success) { - rtn_val = false; - } - else - { - //change speed before sending ROM number OWSpeed(SPEED_OVERDRIVE); - - for(idx = 0; idx < ROMnumberLen; idx++) - { - OWWriteByte(_rom_number[idx]); - } - rtn_val = true; + // send ROM + result = OWWriteBlock(romId, RomId::byteLen); } } - - return rtn_val; + return result; } //********************************************************************* -bool OneWireMaster::OWResume(void) +OneWireInterface::CmdResult OneWireMaster::OWResume(void) { - bool rtn_val = false; + OneWireInterface::CmdResult result; - if(!OWReset()) + result = OWReset(); + if (result == OneWireInterface::Success) { - rtn_val = false; - } - else - { - if(!OWWriteByte(RESUME)) - { - rtn_val = false; - } - else - { - rtn_val = true; - } + result = OWWriteByte(0xA5); } - return rtn_val; + return result; } -//********************************************************************* -const uint8_t (&OneWireMaster::OWgetROMnumber() const)[ROMnumberLen] +//-------------------------------------------------------------------------- +// Calculate a new CRC16 from the input data shorteger. Return the current +// CRC16 and also update the global variable CRC16. +// +uint16_t OneWireMaster::calculateCRC16(uint16_t CRC16, uint16_t data) { - return _rom_number; + data = (data ^ (CRC16 & 0xff)) & 0xff; + CRC16 >>= 8; + + if (_oddparity[data & 0xf] ^ _oddparity[data >> 4]) + CRC16 ^= 0xc001; + + data <<= 6; + CRC16 ^= data; + data <<= 1; + CRC16 ^= data; + + return CRC16; } - -//********************************************************************* -uint8_t OneWireMaster::OWCalc_crc8(uint8_t data, uint8_t crc8) -{ - 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; +uint16_t OneWireMaster::calculateCRC16(const uint8_t * data, size_t data_offset, size_t data_len, uint16_t crc) +{ + for (size_t i = data_offset; i < (data_len + data_offset); i++) + crc = calculateCRC16(crc, data[i]); + return crc; }