Implementation of 1-Wire with added Alarm Search Functionality

Dependents:   Max32630_One_Wire_Interface

Revision:
141:cf38f48a2a49
Parent:
139:f0e0a7976846
--- a/Slaves/Memory/DS2431/DS2431.cpp	Fri Feb 17 19:09:11 2017 +0000
+++ b/Slaves/Memory/DS2431/DS2431.cpp	Fri Feb 17 21:54:14 2017 +0000
@@ -36,231 +36,179 @@
 using namespace OneWire;
 using namespace OneWire::crc;
 
-enum DS2431_CMDS
+enum Command
 {
-    WRITE_SCRATCHPAD = 0x0F,
-    READ_SCRATCHPAD = 0xAA,
-    COPY_SCRATCHPAD = 0x55,
-    READ_MEMORY = 0xF0
+    WriteScratchpad = 0x0F,
+    ReadScratchpad = 0xAA,
+    CopyScratchpad = 0x55,
+    ReadMemory = 0xF0
 };
 
+static const DS2431::Address beginReservedAddress = 0x0088;
+
 //*********************************************************************
-DS2431::DS2431(RandomAccessRomIterator &selector):OneWireSlave(selector)
+DS2431::DS2431(RandomAccessRomIterator & selector) : OneWireSlave(selector)
 {
 }
 
 //*********************************************************************
-OneWireSlave::CmdResult DS2431::writeMemory(uint16_t targetAddress, const uint8_t *data, uint8_t numBytes)
-{
-    OneWireSlave::CmdResult result = OneWireSlave::OperationFailure;
-    
-    if((targetAddress + numBytes) <= 0x88)
+OneWireSlave::CmdResult DS2431::writeMemory(Address targetAddress, const Scratchpad & data)
+{    
+    if (((targetAddress & 0x7) != 0x0) || ((targetAddress + data.size()) > beginReservedAddress))
+    {
+        return OneWireSlave::OperationFailure;
+    }
+    OneWireSlave::CmdResult result = writeScratchpad(targetAddress, data);
+    if (result != OneWireSlave::Success)
     {
-        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);
-        const uint8_t *dataIdx = data;
-        
-        DS2431::Scratchpad scratchpadData;
-        uint8_t esByte;
-        
-        if(startOffset != 0)
-        {
-            result = this->readMemory(startRowAddress, scratchpadData.data(), 8);
-            if(result == OneWireSlave::Success)
-            {
-                std::memcpy((scratchpadData.data() + startOffset), data, (8 - startOffset));
-                result = this->writeScratchpad(startRowAddress, scratchpadData);
-                if(result == OneWireSlave::Success)
-                {
-                    result = this->readScratchpad(scratchpadData , esByte);
-                    if(result == OneWireSlave::Success)
-                    {
-                        result = this->copyScratchpad(startRowAddress, esByte);
-                        startRowAddress += 8;
-                        dataIdx = (data + (8 - startOffset));
-                    }
-                }
-            }
-        }
-        
-        if(result == OneWireSlave::Success)
-        {
-            for(uint16_t row = startRowAddress; row < endRowAddress; row += 8)
-            {
-                std::memcpy(scratchpadData.data(), dataIdx, 8);
-                
-                result = this->writeScratchpad(row, scratchpadData);
-                if(result != OneWireSlave::Success)
-                {
-                    break;
-                }
-                
-                result = this->readScratchpad(scratchpadData, esByte);
-                if(result != OneWireSlave::Success)
-                {
-                    break;
-                }
-                
-                result = this->copyScratchpad(row, esByte);
-                if(result != OneWireSlave::Success)
-                {
-                    break;
-                }
-                
-                dataIdx += 8;
-            }
-        }
-        
-        if(result == OneWireSlave::Success)
-        {
-            if(endOffset != 0)
-            {
-                result = this->readMemory(endRowAddress, scratchpadData.data(), 8);
-                if(result == OneWireSlave::Success)
-                {
-                    std::memcpy(scratchpadData.data(), dataIdx, endOffset);
-                    result = this->writeScratchpad(endRowAddress, scratchpadData);
-                    if(result == OneWireSlave::Success)
-                    {
-                        result = this->readScratchpad(scratchpadData, esByte);
-                        if(result == OneWireSlave::Success)
-                        {
-                            result = this->copyScratchpad(endRowAddress, esByte);
-                        }
-                    }
-                }
-            }
-        }
+        return result;
     }
-    
+    Scratchpad readData;
+    uint8_t esByte;
+    result = readScratchpad(readData, esByte);
+    if (result != OneWireSlave::Success)
+    {
+        return result;
+    }
+    result = copyScratchpad(targetAddress, esByte);    
     return result;
 }
 
 //*********************************************************************
-OneWireSlave::CmdResult DS2431::readMemory(uint16_t targetAddress, uint8_t *data, uint8_t numBytes)
-{
-    OneWireSlave::CmdResult result = OneWireSlave::OperationFailure;
-    
-    if((targetAddress + numBytes) <= 0x88)
+OneWireSlave::CmdResult DS2431::readMemory(Address targetAddress, uint8_t numBytes, uint8_t * data)
+{    
+    if ((targetAddress + numBytes) > beginReservedAddress)
+    {
+        return OneWireSlave::OperationFailure;
+    }
+    OneWireMaster::CmdResult owmResult = selectDevice();
+    if (owmResult != OneWireMaster::Success)
     {
-        OneWireMaster::CmdResult owmResult = selectDevice();
-        if(owmResult == OneWireMaster::Success)
-        {
-            uint8_t sendBlock[] = { READ_MEMORY, static_cast<uint8_t>(targetAddress), static_cast<uint8_t>(targetAddress >> 8) };
-            owmResult = master().OWWriteBlock(sendBlock, 3);
-            if(owmResult == OneWireMaster::Success)
-            {
-                owmResult = master().OWReadBlock(data, numBytes);
-                if(owmResult == OneWireMaster::Success)
-                {
-                    result = OneWireSlave::Success;
-                }
-            }
-        }
+        return OneWireSlave::CommunicationError;
+    }
+    uint8_t sendBlock[] = { ReadMemory, static_cast<uint8_t>(targetAddress), static_cast<uint8_t>(targetAddress >> 8) };
+    owmResult = master().OWWriteBlock(sendBlock, sizeof(sendBlock) / sizeof(sendBlock[0]));
+    if (owmResult != OneWireMaster::Success)
+    {
+        return OneWireSlave::CommunicationError;
     }
-    
-    return result;
+    owmResult = master().OWReadBlock(data, numBytes);
+    if (owmResult != OneWireMaster::Success)
+    {
+        return OneWireSlave::CommunicationError;
+    }
+    // else
+    return OneWireSlave::Success;
 }
 
 //*********************************************************************
-OneWireSlave::CmdResult DS2431::writeScratchpad(uint16_t targetAddress, const Scratchpad &data)
-{
-    OneWireSlave::CmdResult result = OneWireSlave::OperationFailure;
-    
+OneWireSlave::CmdResult DS2431::writeScratchpad(Address targetAddress, const Scratchpad & data)
+{    
     OneWireMaster::CmdResult owmResult = selectDevice();
-    if(owmResult == OneWireMaster::Success)
+    if(owmResult != OneWireMaster::Success)
+    {
+        return OneWireSlave::CommunicationError;
+    }
+    uint8_t sendBlock[3 + Scratchpad::csize] = { WriteScratchpad, static_cast<uint8_t>(targetAddress), static_cast<uint8_t>(targetAddress >> 8) };
+    std::memcpy((sendBlock + 3), data.data(), data.size());
+    owmResult = master().OWWriteBlock(sendBlock, sizeof(sendBlock) / sizeof(sendBlock[0]));
+    if (owmResult != OneWireMaster::Success)
+    {
+        return OneWireSlave::CommunicationError;
+    }
+    uint8_t recvbyte;
+    owmResult = master().OWReadByte(recvbyte);
+    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.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, 11);
-        
-        if(invCRC16 == calculatedInvCRC16)
-        {
-            result = OneWireSlave::Success;
-        }
+        return OneWireSlave::CommunicationError;
+    }
+    uint16_t invCRC16 = recvbyte;
+    owmResult = master().OWReadByte(recvbyte);
+    if (owmResult != OneWireMaster::Success)
+    {
+        return OneWireSlave::CommunicationError;
     }
-    
-    return result;
+    invCRC16 |= (recvbyte << 8); 
+    //calc our own inverted CRC16 to compare with one returned
+    uint16_t calculatedInvCRC16 = ~calculateCrc16(sendBlock, sizeof(sendBlock) / sizeof(sendBlock[0]));
+    if (invCRC16 != calculatedInvCRC16)
+    {
+        return OneWireSlave::CrcError;
+    }
+    // else
+    return OneWireSlave::Success;
 }
 
 //*********************************************************************
-OneWireSlave::CmdResult DS2431::readScratchpad(Scratchpad &data, uint8_t &esByte)
-{
-    OneWireSlave::CmdResult result = OneWireSlave::OperationFailure;
-    
+OneWireSlave::CmdResult DS2431::readScratchpad(Scratchpad & data, uint8_t & esByte)
+{    
     OneWireMaster::CmdResult owmResult = selectDevice();
-    if(owmResult == OneWireMaster::Success)
+    if (owmResult != OneWireMaster::Success)
+    {
+        return OneWireSlave::CommunicationError;
+    }
+    owmResult = master().OWWriteByte(ReadScratchpad);
+    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, 12);
-            
-            if(invCRC16 == calculatedInvCRC16)
-            {
-                esByte = recvBlock[3];
-                std::memcpy(data.data(), (recvBlock + 4), 8);
-                result = OneWireSlave::Success;
-            }
-        }
+        return OneWireSlave::CommunicationError;
+    }
+    uint8_t recvBlock[13];
+    const size_t recvBlockSize = sizeof(recvBlock) / sizeof(recvBlock[0]);
+    owmResult = master().OWReadBlock(recvBlock, recvBlockSize);
+    if (owmResult != OneWireMaster::Success)
+    {
+        return OneWireSlave::CommunicationError;
     }
-    
-    return result;
+    uint16_t invCRC16 = ((recvBlock[recvBlockSize - 1] << 8) | recvBlock[recvBlockSize - 2]);
+    // Shift contents down
+    std::memmove(recvBlock + 1, recvBlock, recvBlockSize - 1);
+    recvBlock[0] = ReadScratchpad;
+    //calc our own inverted CRC16 to compare with one returned
+    uint16_t calculatedInvCRC16 = ~calculateCrc16(recvBlock, recvBlockSize - 1);
+    if (invCRC16 != calculatedInvCRC16)
+    {
+        return OneWireSlave::CrcError;
+    }
+    esByte = recvBlock[3];
+    std::memcpy(data.data(), (recvBlock + 4), data.size());
+    return OneWireSlave::Success;
 }
 
 //*********************************************************************
-OneWireSlave::CmdResult DS2431::copyScratchpad(uint16_t targetAddress, uint8_t esByte)
-{
-    OneWireSlave::CmdResult result = OneWireSlave::OperationFailure;
-    
+OneWireSlave::CmdResult DS2431::copyScratchpad(Address targetAddress, uint8_t esByte)
+{    
     OneWireMaster::CmdResult owmResult = selectDevice();
-    if(owmResult == OneWireMaster::Success)
+    if(owmResult != OneWireMaster::Success)
+    {
+        return OneWireSlave::CommunicationError;
+    }
+    uint8_t sendBlock[] = { CopyScratchpad, static_cast<uint8_t>(targetAddress), static_cast<uint8_t>(targetAddress >> 8) };
+    owmResult = master().OWWriteBlock(sendBlock, sizeof(sendBlock) / sizeof(sendBlock[0]));
+    if (owmResult != OneWireMaster::Success)
+    {
+        return OneWireSlave::CommunicationError;
+    }
+    owmResult = master().OWWriteByteSetLevel(esByte, OneWireMaster::StrongLevel);
+    if (owmResult != OneWireMaster::Success)
     {
-        uint8_t sendBlock[] = { COPY_SCRATCHPAD, static_cast<uint8_t>(targetAddress), static_cast<uint8_t>(targetAddress >> 8), 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 OneWireSlave::CommunicationError;
+    }
+    wait_ms(10);
+    owmResult = master().OWSetLevel(OneWireMaster::NormalLevel);
+    if (owmResult != OneWireMaster::Success)
+    {
+        return OneWireSlave::CommunicationError;
     }
-    
-    return result;
+    uint8_t check;
+    owmResult = master().OWReadByte(check);
+    if (owmResult != OneWireMaster::Success)
+    {
+        return OneWireSlave::CommunicationError;
+    }
+    if (check != 0xAA)
+    {
+        return OneWireSlave::OperationFailure;
+    }
+    // else
+    return OneWireSlave::Success;
 }