Implementation of 1-Wire with added Alarm Search Functionality

Dependents:   Max32630_One_Wire_Interface

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;
+}