Implementation of 1-Wire with added Alarm Search Functionality

Dependents:   Max32630_One_Wire_Interface

Revision:
63:422be898443a
Parent:
32:bce180b544ed
Child:
65:a28ac52ca127
diff -r 268612a10614 -r 422be898443a OneWire_Masters/DS2480B/ds2480b.cpp
--- a/OneWire_Masters/DS2480B/ds2480b.cpp	Thu Apr 14 14:38:42 2016 -0500
+++ b/OneWire_Masters/DS2480B/ds2480b.cpp	Tue Apr 19 21:52:49 2016 +0000
@@ -32,7 +32,155 @@
 
 
 #include "ds2480b.h"
-#include "RomId.hpp"
+
+#define WRITE_FUNCTION                 0
+#define READ_FUNCTION                  1
+
+// Mode Commands
+#define MODE_DATA                      0xE1
+#define MODE_COMMAND                   0xE3
+#define MODE_STOP_PULSE                0xF1
+
+// Return byte value
+#define RB_CHIPID_MASK                 0x1C
+#define RB_RESET_MASK                  0x03
+#define RB_1WIRESHORT                  0x00
+#define RB_PRESENCE                    0x01
+#define RB_ALARMPRESENCE               0x02
+#define RB_NOPRESENCE                  0x03
+
+#define RB_BIT_MASK                    0x03
+#define RB_BIT_ONE                     0x03
+#define RB_BIT_ZERO                    0x00
+
+// Masks for all bit ranges
+#define CMD_MASK                       0x80
+#define FUNCTSEL_MASK                  0x60
+#define BITPOL_MASK                    0x10
+#define SPEEDSEL_MASK                  0x0C
+#define MODSEL_MASK                    0x02
+#define PARMSEL_MASK                   0x70
+#define PARMSET_MASK                   0x0E
+
+// Command or config bit
+#define CMD_COMM                       0x81
+#define CMD_CONFIG                     0x01
+
+// Function select bits
+#define FUNCTSEL_BIT                   0x00
+#define FUNCTSEL_SEARCHON              0x30
+#define FUNCTSEL_SEARCHOFF             0x20
+#define FUNCTSEL_RESET                 0x40
+#define FUNCTSEL_CHMOD                 0x60
+
+// Bit polarity/Pulse voltage bits
+#define BITPOL_ONE                     0x10
+#define BITPOL_ZERO                    0x00
+#define BITPOL_5V                      0x00
+#define BITPOL_12V                     0x10
+
+// One Wire speed bits
+#define SPEEDSEL_STD                   0x00
+#define SPEEDSEL_FLEX                  0x04
+#define SPEEDSEL_OD                    0x08
+#define SPEEDSEL_PULSE                 0x0C
+
+// Data/Command mode select bits
+#define MODSEL_DATA                    0x00
+#define MODSEL_COMMAND                 0x02
+
+// 5V Follow Pulse select bits 
+#define PRIME5V_TRUE                   0x02
+#define PRIME5V_FALSE                  0x00
+
+// Parameter select bits
+#define PARMSEL_PARMREAD               0x00
+#define PARMSEL_SLEW                   0x10
+#define PARMSEL_12VPULSE               0x20
+#define PARMSEL_5VPULSE                0x30
+#define PARMSEL_WRITE1LOW              0x40
+#define PARMSEL_SAMPLEOFFSET           0x50
+#define PARMSEL_ACTIVEPULLUPTIME       0x60
+#define PARMSEL_BAUDRATE               0x70
+
+// Pull down slew rate.
+#define PARMSET_Slew15Vus              0x00
+#define PARMSET_Slew2p2Vus             0x02
+#define PARMSET_Slew1p65Vus            0x04
+#define PARMSET_Slew1p37Vus            0x06
+#define PARMSET_Slew1p1Vus             0x08
+#define PARMSET_Slew0p83Vus            0x0A
+#define PARMSET_Slew0p7Vus             0x0C
+#define PARMSET_Slew0p55Vus            0x0E
+
+// 12V programming pulse time table
+#define PARMSET_32us                   0x00
+#define PARMSET_64us                   0x02
+#define PARMSET_128us                  0x04
+#define PARMSET_256us                  0x06
+#define PARMSET_512us                  0x08
+#define PARMSET_1024us                 0x0A
+#define PARMSET_2048us                 0x0C
+#define PARMSET_infinite               0x0E
+
+// 5V strong pull up pulse time table
+#define PARMSET_16p4ms                 0x00
+#define PARMSET_65p5ms                 0x02
+#define PARMSET_131ms                  0x04
+#define PARMSET_262ms                  0x06
+#define PARMSET_524ms                  0x08
+#define PARMSET_1p05s                  0x0A
+#define PARMSET_dynamic                0x0C
+#define PARMSET_infinite               0x0E
+
+// Write 1 low time
+#define PARMSET_Write8us               0x00
+#define PARMSET_Write9us               0x02
+#define PARMSET_Write10us              0x04
+#define PARMSET_Write11us              0x06
+#define PARMSET_Write12us              0x08
+#define PARMSET_Write13us              0x0A
+#define PARMSET_Write14us              0x0C
+#define PARMSET_Write15us              0x0E
+
+// Data sample offset and Write 0 recovery time
+#define PARMSET_SampOff3us             0x00
+#define PARMSET_SampOff4us             0x02
+#define PARMSET_SampOff5us             0x04
+#define PARMSET_SampOff6us             0x06
+#define PARMSET_SampOff7us             0x08
+#define PARMSET_SampOff8us             0x0A
+#define PARMSET_SampOff9us             0x0C
+#define PARMSET_SampOff10us            0x0E
+
+// Active pull up on time
+#define PARMSET_PullUp0p0us            0x00
+#define PARMSET_PullUp0p5us            0x02
+#define PARMSET_PullUp1p0us            0x04
+#define PARMSET_PullUp1p5us            0x06
+#define PARMSET_PullUp2p0us            0x08
+#define PARMSET_PullUp2p5us            0x0A
+#define PARMSET_PullUp3p0us            0x0C
+#define PARMSET_PullUp3p5us            0x0E
+
+// Baud rate bits
+#define PARMSET_9600                   0x00
+#define PARMSET_19200                  0x02
+#define PARMSET_57600                  0x04
+#define PARMSET_115200                 0x06
+
+// DS2480B program voltage available
+#define DS2480BPROG_MASK                0x20
+
+// mode bit flags
+#define MODE_NORMAL                    0x00
+#define MODE_OVERDRIVE                 0x01
+#define MODE_STRONG5                   0x02
+#define MODE_PROGRAM                   0x04
+#define MODE_BREAK                     0x08
+
+#define MAX_BAUD                       PARMSET_115200
+
 
 
 //*********************************************************************
@@ -43,10 +191,9 @@
 
 
 //*********************************************************************
-Ds2480b::Ds2480b(PinName tx, PinName rx, uint32_t baud)
+Ds2480b::Ds2480b(PinName tx, PinName rx)
 :_p_serial(new Serial(tx, rx)), _serial_owner(true)
 {
-    _p_serial->baud(baud);
 }
 
 
@@ -61,33 +208,162 @@
 
 
 //*********************************************************************
+void Ds2480b::rx_callback(void)
+{
+    rx_buffer.buff[rx_buffer.w_idx++] = _p_serial->getc();
+    
+    if(rx_buffer.w_idx == rx_buffer.r_idx)
+    {
+        rx_buffer.wrap_error = true;
+    }
+}
+
+
+//*********************************************************************
+void Ds2480b::tx_callback(void)
+{
+}
+
+
+//*********************************************************************
 OneWireMaster::CmdResult Ds2480b::OWInitMaster(void)
 {
-    OneWireMaster::CmdResult result = OneWireMaster::OperationFailure;
+    _p_serial->attach(this, &Ds2480b::rx_callback, Serial::RxIrq);
+    _p_serial->attach(this, &Ds2480b::tx_callback, Serial::TxIrq);
+    
+    rx_buffer.w_idx = 0;
+    rx_buffer.r_idx = 0;
+    rx_buffer.wrap_error = false;
     
-    //TODO
+    _ULevel = OneWireMaster::LEVEL_NORMAL;
+    _UBaud = BPS_9600;
+    _UMode = MODSEL_COMMAND;
+    _USpeed = OneWireMaster::SPEED_STANDARD;
     
-    return result;
+    return DS2480B_Detect();
 }
 
 
 //*********************************************************************
 OneWireMaster::CmdResult Ds2480b::OWReset(void)
 {
-    OneWireMaster::CmdResult result = OneWireMaster::OperationFailure;
-    
-    //TODO
-    
+    OneWireMaster::CmdResult result;
+
+    uint8_t readbuffer[10],sendpacket[10];
+    uint8_t sendlen=0;
+
+    // make sure normal level
+    result = OWSetLevel(OneWireMaster::LEVEL_NORMAL);
+    if(result == OneWireMaster::Success) 
+    {
+        // check for correct mode
+        if(_UMode != MODSEL_COMMAND) 
+        {
+            _UMode = MODSEL_COMMAND;
+            sendpacket[sendlen++] = MODE_COMMAND;
+        }
+
+        // construct the command
+        sendpacket[sendlen++] = (uint8_t)(CMD_COMM | FUNCTSEL_RESET | _USpeed);
+        
+        FlushCOM();
+
+        // send the packet
+        result = WriteCOM(sendlen,sendpacket);
+        if(result == OneWireMaster::Success) 
+        {
+            // read back the 1 byte response
+            result = ReadCOM(1,readbuffer);
+            if(result == OneWireMaster::Success) 
+            {
+                // make sure this byte looks like a reset byte
+                if(((readbuffer[0] & RB_RESET_MASK) == RB_PRESENCE) || ((readbuffer[0] & RB_RESET_MASK) == RB_ALARMPRESENCE))
+                {
+                    result = OneWireMaster::Success;
+                }
+                else
+                {
+                    result = OneWireMaster::OperationFailure;
+                }
+            }
+        }
+        
+        if(result != OneWireMaster::Success)
+        {
+            // an error occured so re-sync with DS2480B
+            DS2480B_Detect();
+        }
+    }
+
     return result;
 }
 
 
+//*********************************************************************
 OneWireMaster::CmdResult Ds2480b::OWTouchBit(uint8_t & sendrecvbit, OWLevel after_level)
 {
     OneWireMaster::CmdResult result = OneWireMaster::OperationFailure;
-    
-    //TODO
-    
+
+    uint8_t readbuffer[10],sendpacket[10];
+    uint8_t sendlen=0;
+
+    // make sure normal level
+    OWSetLevel(OneWireMaster::LEVEL_NORMAL);
+
+    // check for correct mode
+    if(_UMode != MODSEL_COMMAND) 
+    {
+        _UMode = MODSEL_COMMAND;
+        sendpacket[sendlen++] = MODE_COMMAND;
+    }
+
+    // construct the command
+    sendpacket[sendlen] = (sendrecvbit != 0) ? BITPOL_ONE : BITPOL_ZERO;
+    sendpacket[sendlen++] |= CMD_COMM | FUNCTSEL_BIT | _USpeed;
+
+    // flush the buffers
+    FlushCOM();
+
+    // send the packet
+    result = WriteCOM(sendlen,sendpacket);
+    if(result == OneWireMaster::Success) 
+    {
+        // read back the response
+        result = ReadCOM(1,readbuffer);
+        if(result == OneWireMaster::Success) 
+        {
+            // interpret the response
+            if (((readbuffer[0] & 0xE0) == 0x80) && ((readbuffer[0] & RB_BIT_MASK) == RB_BIT_ONE))
+            {
+                sendrecvbit = 1;
+                result = OneWireMaster::Success;
+            }
+            else
+            {
+                sendrecvbit = 0;
+                result = OneWireMaster::Success;
+            }
+        }
+        else
+        {
+            result = OneWireMaster::CommunicationReadError;
+        }
+    }
+    else
+    {
+        result = OneWireMaster::CommunicationWriteError;
+    }
+
+    // an error occured so re-sync with DS2480B
+    if(result != OneWireMaster::Success)
+    {
+        DS2480B_Detect();
+    }
+    else
+    {
+       result = OWSetLevel(after_level);
+    }
+
     return result;
 }
 
@@ -96,9 +372,62 @@
 OneWireMaster::CmdResult Ds2480b::OWWriteByte(uint8_t sendbyte, OWLevel after_level)
 {
     OneWireMaster::CmdResult result = OneWireMaster::OperationFailure;
-    
-    //TODO
-    
+
+    uint8_t readbuffer[10],sendpacket[10];
+    uint8_t sendlen=0;
+
+    // make sure normal level
+    OWSetLevel(OneWireMaster::LEVEL_NORMAL);
+
+    // check for correct mode
+    if (_UMode != MODSEL_DATA) 
+    {
+        _UMode = MODSEL_DATA;
+        sendpacket[sendlen++] = MODE_DATA;
+    }
+
+    // add the byte to send
+    sendpacket[sendlen++] = sendbyte;
+
+    // check for duplication of data that looks like COMMAND mode
+    if(sendbyte == MODE_COMMAND)
+    {
+        sendpacket[sendlen++] = sendbyte;
+    }
+
+    // flush the buffers
+    FlushCOM();
+
+    // send the packet
+    result = WriteCOM(sendlen,sendpacket);
+    if(result == OneWireMaster::Success) 
+    {
+        // read back the 1 byte response
+        result = ReadCOM(1,readbuffer);
+        if((result == OneWireMaster::Success) && (readbuffer[0] == sendbyte)) 
+        {
+            result = OneWireMaster::Success;
+        }
+        else
+        {
+            result = OneWireMaster::CommunicationReadError;
+        }
+    }
+    else
+    {
+        result = OneWireMaster::CommunicationWriteError;
+    }
+
+    // an error occured so re-sync with DS2480B
+    if(result != OneWireMaster::Success)
+    {
+        DS2480B_Detect();
+    }
+    else
+    {
+       result = OWSetLevel(after_level);
+    }
+
     return result;
 }
 
@@ -107,9 +436,57 @@
 OneWireMaster::CmdResult Ds2480b::OWReadByte(uint8_t & recvbyte, OWLevel after_level)
 {
     OneWireMaster::CmdResult result = OneWireMaster::OperationFailure;
-    
-    //TODO
-    
+
+    uint8_t readbuffer[10],sendpacket[10];
+    uint8_t sendlen=0;
+
+    // make sure normal level
+    OWSetLevel(OneWireMaster::LEVEL_NORMAL);
+
+    // check for correct mode
+    if (_UMode != MODSEL_DATA) 
+    {
+        _UMode = MODSEL_DATA;
+        sendpacket[sendlen++] = MODE_DATA;
+    }
+
+    // add the byte to send
+    sendpacket[sendlen++] = 0xFF;
+
+    // flush the buffers
+    FlushCOM();
+
+    // send the packet
+    result = WriteCOM(sendlen,sendpacket);
+    if(result == OneWireMaster::Success) 
+    {
+        // read back the 1 byte response
+        result = ReadCOM(1,readbuffer);
+        if(result == OneWireMaster::Success) 
+        {
+            recvbyte = readbuffer[0];
+            result = OneWireMaster::Success;
+        }
+        else
+        {
+            result = OneWireMaster::CommunicationReadError;
+        }
+    }
+    else
+    {
+        result = OneWireMaster::CommunicationWriteError;
+    }
+
+    // an error occured so re-sync with DS2480B
+    if(result != OneWireMaster::Success)
+    {
+        DS2480B_Detect();
+    }
+    else
+    {
+       result = OWSetLevel(after_level);
+    }
+
     return result;
 }
 
@@ -117,10 +494,15 @@
 //*********************************************************************
 OneWireMaster::CmdResult Ds2480b::OWWriteBlock(const uint8_t *tran_buf, uint8_t tran_len)
 {
-    OneWireMaster::CmdResult result = OneWireMaster::OperationFailure;
-    
-    //TODO
-    
+    OneWireMaster::CmdResult result;
+    uint8_t idx = 0;
+
+    do
+    {
+        result = OWWriteByte(tran_buf[idx++], OneWireMaster::LEVEL_NORMAL);
+    }
+    while((result == OneWireMaster::Success) && (idx < tran_len));
+
     return result;
 }
 
@@ -128,21 +510,15 @@
 //*********************************************************************
 OneWireMaster::CmdResult Ds2480b::OWReadBlock(uint8_t *rx_buf, uint8_t rx_len)
 {
-    OneWireMaster::CmdResult result = OneWireMaster::OperationFailure;
-    
-    //TODO
-    
-    return result;
-}
-
+    OneWireMaster::CmdResult result;
+    uint8_t idx = 0;
 
-//*********************************************************************
-OneWireMaster::CmdResult Ds2480b::OWSearch(RomId & romId)
-{
-    OneWireMaster::CmdResult result = OneWireMaster::OperationFailure;
-    
-    //TODO
-    
+    do
+    {
+        result = OWReadByte(rx_buf[idx++], OneWireMaster::LEVEL_NORMAL);
+    }
+    while((result == OneWireMaster::Success) && (idx < rx_len));
+
     return result;
 }
 
@@ -161,9 +537,437 @@
 //*********************************************************************
 OneWireMaster::CmdResult Ds2480b::OWSetLevel(OWLevel new_level)
 {
+    OneWireMaster::CmdResult result = OneWireMaster::Success;
+
+    uint8_t sendpacket[10],readbuffer[10];
+    uint8_t sendlen=0;
+
+    // check if need to change level
+    if(new_level != _ULevel) 
+    {
+        // check for correct mode
+        if(_UMode != MODSEL_COMMAND) 
+        {
+            _UMode = MODSEL_COMMAND;
+            sendpacket[sendlen++] = MODE_COMMAND;
+        }
+        
+        // check if just putting back to normal
+        if(new_level == OneWireMaster::LEVEL_NORMAL) 
+        {
+            // stop pulse command
+            sendpacket[sendlen++] = MODE_STOP_PULSE;
+
+            // add the command to begin the pulse WITHOUT prime
+            sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_5V | PRIME5V_FALSE;
+
+            // stop pulse command
+            sendpacket[sendlen++] = MODE_STOP_PULSE;
+            
+            FlushCOM();
+
+            // send the packet
+            result = WriteCOM(sendlen,sendpacket);
+            if(result == OneWireMaster::Success) 
+            {
+                // read back the 1 byte response
+                result = ReadCOM(2,readbuffer);
+                if(result == OneWireMaster::Success) 
+                {
+                    // check response byte
+                    if (((readbuffer[0] & 0xE0) == 0xE0) && ((readbuffer[1] & 0xE0) == 0xE0)) 
+                    {
+                        _ULevel = OneWireMaster::LEVEL_NORMAL;
+                    }
+                    else
+                    {
+                        result = OneWireMaster::OperationFailure;
+                    }
+                }
+            }
+        }
+        // set new level
+        else 
+        {
+            // set the SPUD time value
+            sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_5VPULSE | PARMSET_infinite;
+            // add the command to begin the pulse
+            sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_5V;
+            
+            FlushCOM();
+
+            // send the packet
+            result = WriteCOM(sendlen,sendpacket);
+            if(result == OneWireMaster::Success) 
+            {
+                // read back the 1 byte response from setting time limit
+                result = ReadCOM(1,readbuffer);
+                if(result == OneWireMaster::Success) 
+                {
+                    // check response byte
+                    if ((readbuffer[0] & 0x81) == 0) 
+                    {
+                        _ULevel = new_level;
+                    }
+                    else
+                    {
+                        result = OneWireMaster::OperationFailure;
+                    }
+                }
+            }
+        }
+
+        // if lost communication with DS2480B then reset
+        if(result != OneWireMaster::Success)
+        {
+            DS2480B_Detect();
+        }
+            
+    }
+
+    return result;
+}
+
+
+//*********************************************************************
+OneWireMaster::CmdResult Ds2480b::DS2480B_Detect(void)
+{
+    OneWireMaster::CmdResult result;
+
+    uint8_t sendpacket[10],readbuffer[10];
+    uint8_t sendlen=0;
+
+    // reset modes
+    _UMode = MODSEL_COMMAND;
+    _UBaud = BPS_9600;
+    _USpeed = SPEEDSEL_FLEX;
+
+    // set the baud rate to 9600
+    SetBaudCOM(_UBaud);
+
+    // send a break to reset the DS2480B
+    BreakCOM();
+
+    // delay to let line settle
+    wait_ms(2);
+    
+    FlushCOM();
+
+    // send the timing byte
+    sendpacket[0] = 0xC1;
+    result = WriteCOM(1,sendpacket);
+    if(result == OneWireMaster::Success) 
+    {
+        // delay to let line settle
+        wait_ms(2);
+
+        // set the FLEX configuration parameters
+        // default PDSRC = 1.37Vus
+        sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_SLEW | PARMSET_Slew1p37Vus;
+        // default W1LT = 10us
+        sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_WRITE1LOW | PARMSET_Write10us;
+        // default DSO/WORT = 8us
+        sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_SAMPLEOFFSET | PARMSET_SampOff8us;
+
+        // construct the command to read the baud rate (to test command block)
+        sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_PARMREAD | (PARMSEL_BAUDRATE >> 3);
+
+        // also do 1 bit operation (to test 1-Wire block)
+        sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_BIT | _UBaud | BITPOL_ONE;
+        
+        FlushCOM();
+
+        // send the packet
+        result = WriteCOM(sendlen,sendpacket);
+        if(result == OneWireMaster::Success) 
+        {
+            // read back the response
+            result = ReadCOM(5,readbuffer);
+            if(result == OneWireMaster::Success) 
+            {
+                // look at the baud rate and bit operation
+                // to see if the response makes sense
+                if (((readbuffer[3] & 0xF1) == 0x00) && ((readbuffer[3] & 0x0E) == _UBaud) &&  ((readbuffer[4] & 0xF0) == 0x90) && ((readbuffer[4] & 0x0C) == _UBaud)) 
+                {
+                    result = OneWireMaster::Success;
+                }
+                else
+                {
+                    result = OneWireMaster::OperationFailure;
+                }
+            }
+        }
+    }
+    
+    return result;
+}
+
+
+//*********************************************************************
+OneWireMaster::CmdResult Ds2480b::DS2480B_ChangeBaud(DS2480B_BPS newbaud)
+{
+   OneWireMaster::CmdResult result = OneWireMaster::OperationFailure;
+   
+   uint8_t rt=0;
+   uint8_t readbuffer[5],sendpacket[5],sendpacket2[5];
+   uint8_t sendlen=0,sendlen2=0;
+
+   // see if diffenent then current baud rate
+   if (_UBaud == newbaud)
+   {
+      //return _UBaud;
+   }
+   else
+   {
+      // build the command packet
+      // check for correct mode
+      if (_UMode != MODSEL_COMMAND)
+      {
+         _UMode = MODSEL_COMMAND;
+         sendpacket[sendlen++] = MODE_COMMAND;
+      }
+      // build the command
+      sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_BAUDRATE | newbaud;
+
+      // flush the buffers
+      FlushCOM();
+
+      // send the packet
+      if (!WriteCOM(sendlen,sendpacket))
+         rt = 0;
+      else
+      {
+         // make sure buffer is flushed
+         wait_ms(5);
+
+         // change our baud rate
+         SetBaudCOM(newbaud);
+         _UBaud = newbaud;
+
+         // wait for things to settle
+         wait_ms(5);
+
+         // build a command packet to read back baud rate
+         sendpacket2[sendlen2++] = CMD_CONFIG | PARMSEL_PARMREAD | (PARMSEL_BAUDRATE >> 3);
+
+         // flush the buffers
+         FlushCOM();
+
+         // send the packet
+         if(WriteCOM(sendlen2,sendpacket2))
+         {
+            // read back the 1 byte response
+            if (ReadCOM(1,readbuffer) == 1)
+            {
+               // verify correct baud
+               if (((readbuffer[0] & 0x0E) == (sendpacket[sendlen-1] & 0x0E)))
+                  rt = 1;
+            }
+         }
+      }
+   }
+
+   // if lost communication with DS2480B then reset
+   if (rt != 1)
+      DS2480B_Detect();
+
+   return result;
+}
+
+
+//*********************************************************************
+OneWireMaster::CmdResult Ds2480b::WriteCOM(uint32_t outlen, uint8_t *outbuf)
+{
     OneWireMaster::CmdResult result = OneWireMaster::OperationFailure;
     
-    //TODO
+    Timer t;
+    uint32_t t_val;
+    uint32_t timeout;
+    uint8_t idx = 0;
+    
+    //calculate timeout, the time needed to tx 1 byte
+    switch(_UBaud) 
+    {
+        case BPS_115200:
+            timeout = ((1000000/115200)*10);
+            break;
+            
+        case BPS_57600:
+            timeout = ((1000000/57600)*10);
+            break;
+            
+        case BPS_19200:
+            timeout = ((1000000/19200)*10);
+            break;
+            
+        case BPS_9600:
+        default:
+            timeout = ((1000000/9600)*10);
+            break;
+    }
+    
+    t.start();
+    do
+    {
+        t.reset();
+        do
+        {
+            t_val = t.read_us();
+        }
+        while(!_p_serial->writeable() && (t_val < timeout));
+        
+        if(t_val < timeout)
+        {
+            _p_serial->putc(outbuf[idx++]);
+            result = OneWireMaster::Success;
+        }
+        else
+        {
+            result = OneWireMaster::TimeoutError;
+        }
+    }
+    while((idx < outlen) && (result == OneWireMaster::Success));
     
     return result;
+}
+
+
+//*********************************************************************
+OneWireMaster::CmdResult Ds2480b::ReadCOM(uint32_t inlen, uint8_t *inbuf)
+{
+    OneWireMaster::CmdResult result;
+    uint32_t num_bytes_read= 0;
+    uint32_t timeout;
+    
+    //calculate timeout, 5x the time needed to recieve inlen bytes 
+    switch(_UBaud) 
+    {
+        case BPS_115200:
+            timeout = ((1000000/115200)*50)*inlen;
+            break;
+            
+        case BPS_57600:
+            timeout = ((1000000/57600)*50)*inlen;
+            break;
+            
+        case BPS_19200:
+            timeout = ((1000000/19200)*50)*inlen;
+            break;
+            
+        case BPS_9600:
+        default:
+            timeout = ((1000000/9600)*50)*inlen;
+            break;
+    }
+    
+    wait_us(timeout);
+    
+    if(rx_buffer.wrap_error)
+    {
+        //reset rx buffer, error, and return failure
+        rx_buffer.w_idx = 0;
+        rx_buffer.r_idx = 0;
+        rx_buffer.wrap_error = false;
+        
+        result = OneWireMaster::OperationFailure;
+    }
+    else
+    {
+        if(rx_buffer.w_idx != rx_buffer.r_idx)
+        {
+            do
+            {
+                inbuf[num_bytes_read++] = rx_buffer.buff[rx_buffer.r_idx++];
+            }
+            while((num_bytes_read < inlen) && (rx_buffer.w_idx != rx_buffer.r_idx));
+            
+            if(num_bytes_read == inlen)
+            {
+                result = OneWireMaster::Success;
+            }
+            else
+            {
+                result = OneWireMaster::CommunicationReadError;
+            }
+        }
+        else
+        {
+            //buffer empty
+            result = OneWireMaster::OperationFailure;
+        }
+    }
+    
+    return result;
+}
+
+
+//*********************************************************************
+void Ds2480b::BreakCOM(void)
+{
+    while(!_p_serial->writeable()); 
+    //for some reason send_break wouldn't work unless first sending char
+    _p_serial->putc(0);
+    _p_serial->send_break();
+}
+
+
+void Ds2480b::FlushCOM(void)
+{
+    //reset soft rx_buffer
+    rx_buffer.w_idx = 0;
+    rx_buffer.r_idx = 0;
+    rx_buffer.wrap_error = false;
+    
+    //make sure hardware rx buffer is empty
+    while(_p_serial->readable())
+    {
+        _p_serial->getc();
+    }
+}
+
+
+//*********************************************************************
+void Ds2480b::SetBaudCOM(uint8_t new_baud)
+{
+    switch(new_baud) 
+    {
+        case BPS_115200:
+            _p_serial->baud(115200);
+            break;
+            
+        case BPS_57600:
+            _p_serial->baud(57600);
+            break;
+            
+        case BPS_19200:
+            _p_serial->baud(19200);
+            break;
+            
+        case BPS_9600:
+        default:
+            _p_serial->baud(9600);
+            break;
+    }
+}
+
+
+//*********************************************************************
+int32_t Ds2480b::bitacc(uint32_t op, uint32_t state, uint32_t loc, uint8_t *buf)
+{
+   int nbyt,nbit;
+
+   nbyt = (loc / 8);
+   nbit = loc - (nbyt * 8);
+
+   if (op == WRITE_FUNCTION)
+   {
+      if (state)
+         buf[nbyt] |= (0x01 << nbit);
+      else
+         buf[nbyt] &= ~(0x01 << nbit);
+
+      return 1;
+   }
+   else
+      return ((buf[nbyt] >> nbit) & 0x01);
 }
\ No newline at end of file