Implementation of 1-Wire with added Alarm Search Functionality
Dependents: Max32630_One_Wire_Interface
Diff: Slaves/Memory/DS2431/DS2431.cpp
- Revision:
- 115:a1ca2f3bf46d
- Parent:
- 110:a3b5e2a4fdf2
- Child:
- 116:8058bb54e959
diff -r 13e2865603df -r a1ca2f3bf46d Slaves/Memory/DS2431/DS2431.cpp --- a/Slaves/Memory/DS2431/DS2431.cpp Tue Aug 09 12:35:22 2016 -0500 +++ b/Slaves/Memory/DS2431/DS2431.cpp Mon Aug 22 05:38:20 2016 +0000 @@ -30,5 +30,235 @@ * ownership rights. **********************************************************************/ +#include "wait_api.h" #include "Slaves/Memory/DS2431/DS2431.h" +using namespace OneWire; +using namespace OneWire::crc; + +enum DS2431_CMDS +{ + WRITE_SCRATCHPAD = 0x0F, + READ_SCRATCHPAD = 0xAA, + COPY_SCRATCHPAD = 0x55, + READ_MEMORY = 0xF0 +}; + +//********************************************************************* +DS2431::DS2431(RandomAccessRomIterator &selector):OneWireSlave(selector) +{ +} + +//********************************************************************* +OneWireSlave::CmdResult DS2431::writeScratchPad(uint16_t targetAddress, uint8_t *data) +{ + OneWireSlave::CmdResult result = OneWireSlave::OperationFailure; + + OneWireMaster::CmdResult owmResult = selectDevice(); + if(owmResult == OneWireMaster::Success) + { + uint8_t sendBlock[11]; + sendBlock[0] = WRITE_SCRATCHPAD; + sendBlock[1] = (targetAddress &0xFF); + sendBlock[2] = ((targetAddress >> 8) &0xFF); + std::memcpy((sendBlock + 3), data, 8); + + owmResult = master().OWWriteBlock(sendBlock, 11); + + uint16_t invCRC16; + uint8_t recvbyte; + master().OWReadByteSetLevel(recvbyte, OneWireMaster::NormalLevel); + invCRC16 = recvbyte; + master().OWReadByteSetLevel(recvbyte, OneWireMaster::NormalLevel); + invCRC16 |= (recvbyte << 8); + + //calc our own inverted CRC16 to compare with one returned + uint16_t calculatedInvCRC16 = ~calculateCrc16(sendBlock, 0, 11); + + if(invCRC16 == calculatedInvCRC16) + { + result = OneWireSlave::Success; + } + } + + return result; +} + +//********************************************************************* +OneWireSlave::CmdResult DS2431::readScratchPad(uint8_t *data) +{ + OneWireSlave::CmdResult result = OneWireSlave::OperationFailure; + + OneWireMaster::CmdResult owmResult = selectDevice(); + if(owmResult == OneWireMaster::Success) + { + owmResult = master().OWWriteByteSetLevel(READ_SCRATCHPAD, OneWireMaster::NormalLevel); + if(owmResult == OneWireMaster::Success) + { + uint8_t recvBlock[13]; + owmResult = master().OWReadBlock(recvBlock, 13); + + uint16_t invCRC16 = ((recvBlock[12] << 8) | recvBlock[11]); + + uint8_t idx = 12; + while(--idx) + { + recvBlock[idx] = recvBlock[idx - 1]; + } + recvBlock[0] = READ_SCRATCHPAD; + + //calc our own inverted CRC16 to compare with one returned + uint16_t calculatedInvCRC16 = ~calculateCrc16(recvBlock, 0, 12); + + if(invCRC16 == calculatedInvCRC16) + { + std::memcpy(data, (recvBlock + 1), 11); + result = OneWireSlave::Success; + } + } + } + + return result; +} + +//********************************************************************* +OneWireSlave::CmdResult DS2431::copyScratchPad(uint16_t targetAddress, uint8_t esByte) +{ + OneWireSlave::CmdResult result = OneWireSlave::OperationFailure; + + OneWireMaster::CmdResult owmResult = selectDevice(); + if(owmResult == OneWireMaster::Success) + { + uint8_t sendBlock[] = {COPY_SCRATCHPAD, (targetAddress & 0xFF), ((targetAddress >> 8) & 0xFF), esByte}; + owmResult = master().OWWriteBlock(sendBlock, 4); + + master().OWSetLevel(OneWireMaster::StrongLevel); + wait_ms(10); + master().OWSetLevel(OneWireMaster::NormalLevel); + + uint8_t check; + master().OWReadByteSetLevel(check, OneWireMaster::NormalLevel); + if(check == 0xAA) + { + result = OneWireSlave::Success; + } + } + + return result; +} + +//********************************************************************* +OneWireSlave::CmdResult DS2431::writeBlock(uint16_t targetAddress, uint8_t *data, uint8_t numBytes) +{ + OneWireSlave::CmdResult result = OneWireSlave::OperationFailure; + + if((targetAddress + numBytes) <= 0x88) + { + result = OneWireSlave::Success; + + uint8_t startOffset = (targetAddress & 0x0007); + uint16_t startRowAddress = (targetAddress & 0xFFF8); + uint8_t endOffset = ((targetAddress + numBytes) & 0x0007); + uint16_t endRowAddress = ((targetAddress + numBytes) & 0xFFF8); + uint8_t *dataIdx = data; + + uint8_t localData[12]; + + if(startOffset != 0) + { + result = this->readBlock(startRowAddress, localData, 8); + if(result == OneWireSlave::Success) + { + std::memcpy((localData + startOffset), data, (8 - startOffset)); + result = this->writeScratchPad(startRowAddress, localData); + if(result == OneWireSlave::Success) + { + result = this->readScratchPad(localData); + if(result == OneWireSlave::Success) + { + result = this->copyScratchPad(startRowAddress, localData[2]); + startRowAddress += 8; + dataIdx = (data + (8 - startOffset)); + } + } + } + } + + if(result == OneWireSlave::Success) + { + for(uint16_t row = startRowAddress; row < endRowAddress; row += 8) + { + std::memcpy(localData, dataIdx, 8); + + result = this->writeScratchPad(row, localData); + if(result != OneWireSlave::Success) + { + break; + } + + result = this->readScratchPad(localData); + if(result != OneWireSlave::Success) + { + break; + } + + result = this->copyScratchPad(row, localData[2]); + if(result != OneWireSlave::Success) + { + break; + } + + dataIdx += 8; + } + } + + if(result == OneWireSlave::Success) + { + if(endOffset != 0) + { + result = this->readBlock(endRowAddress, localData, 8); + if(result == OneWireSlave::Success) + { + std::memcpy(localData, dataIdx, endOffset); + result = this->writeScratchPad(endRowAddress, localData); + if(result == OneWireSlave::Success) + { + result = this->readScratchPad(localData); + if(result == OneWireSlave::Success) + { + result = this->copyScratchPad(endRowAddress, localData[2]); + } + } + } + } + } + } + + return result; +} + +//********************************************************************* +OneWireSlave::CmdResult DS2431::readBlock(uint16_t targetAddress, uint8_t *data, uint8_t numBytes) +{ + OneWireSlave::CmdResult result = OneWireSlave::OperationFailure; + + if((targetAddress + numBytes) <= 0x88) + { + OneWireMaster::CmdResult owmResult = selectDevice(); + if(owmResult == OneWireMaster::Success) + { + uint8_t sendBlock[] = {READ_MEMORY, (targetAddress & 0xFF), ((targetAddress >> 8) & 0xFF)}; + owmResult = master().OWWriteBlock(sendBlock, 3); + if(owmResult == OneWireMaster::Success) + { + owmResult = master().OWReadBlock(data, numBytes); + if(owmResult == OneWireMaster::Success) + { + result = OneWireSlave::Success; + } + } + } + } + + return result; +}