Marcus Chang / AsyncSerial
Revision:
0:dfed780dc91a
Child:
1:a3f39ec7d5f2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/AsyncSerial.cpp	Mon Mar 30 15:37:07 2015 +0000
@@ -0,0 +1,165 @@
+#include "AsyncSerial/AsyncSerial.h"
+
+#include "mbed.h"
+
+template<class T>
+AsyncSerial::AsyncSerial(PinName tx, PinName rx, PinName rts, PinName cts)
+    :   SerialBase(tx, rx),
+        sendBuffer(NULL),
+        sendLength(0),
+        sendDoneHandler(NULL),
+        sendIndex(0),
+        receiveBuffer(NULL),
+        receiveMaxLength(0),
+        receiveDoneHandler(NULL),
+        receiveIndex(0),
+        conditionBuffer(NULL),
+        conditionLength(0),
+        conditionIndex(0),
+        timeout()
+{    
+    SerialBase::attach<AsyncSerial>(this, &AsyncSerial::getReady, SerialBase::RxIrq);
+    SerialBase::attach<AsyncSerial>(this, &AsyncSerial::putDone, SerialBase::TxIrq);
+}
+
+void AsyncSerial::putDone()
+{
+    if (sendLength > 0)
+    {
+        sendIndex++;
+    
+        if (sendIndex < sendLength)
+        {
+            SerialBase::_base_putc(sendBuffer[sendIndex]);
+        }
+        else
+        {
+            if (sendDoneHandler)
+            {
+                sendDoneHandler(sendBuffer, sendLength);
+                sendDoneHandler = NULL;
+                sendLength = 0;
+            }
+        }
+    }
+}
+
+void AsyncSerial::getReady()
+{
+    uint8_t input = SerialBase::_base_getc();
+    
+    if (receiveMaxLength > 0)
+    {        
+        receiveBuffer[receiveIndex] = input;
+        receiveIndex++;
+        
+        if (receiveIndex == receiveMaxLength)
+        {
+            timeout.detach();
+            getDone();
+        }
+        else if (conditionLength > 0)
+        {
+            if (receiveBuffer[receiveIndex - 1] == conditionBuffer[conditionIndex])
+            {
+                conditionIndex++;
+            
+                if (conditionIndex == conditionLength)
+                {
+                    timeout.detach();
+                    getDone();
+                }
+            }
+            else
+            {
+                conditionIndex = 0;
+            }
+        }
+    }
+}
+
+void AsyncSerial::getDone()
+{            
+    receiveMaxLength = 0;
+
+    if (receiveDoneHandler)
+    {
+        receiveDoneHandler(receiveBuffer, receiveIndex);
+        receiveDoneHandler = NULL;
+    }
+}
+
+void AsyncSerial::send(send_done_t handler, uint8_t* buffer, uint16_t length)
+{
+    if (handler && buffer && length)
+    {        
+        sendDoneHandler = handler;
+        
+        send(buffer, length);
+    }
+}
+
+template<typename T>
+void AsyncSerial::send(T *object, void (T::*member)(void), uint8_t* buffer, uint16_t length) 
+{
+    if (object && member && buffer && length)
+    {
+        sendObject = static_cast<void*>(object);
+        memcpy(sendMember, (char*)&member, sizeof(member));
+        sendMemberCaller = &AsyncSerial::sendMemberCallerTemplate<T>;
+
+        sendDoneHandler = 0;
+        
+        send(buffer, length);
+    }
+}
+
+template<typename T>
+static void AsyncSerial::sendMemberCallerTemplate(void *object, char *member, uint8_t) 
+{
+    T* o = static_cast<T*>(object);
+    void (T::*m)(void);
+    memcpy((char*)&m, member, sizeof(m));
+    (o->*m)();
+}
+
+void AsyncSerial::send(uint8_t* buffer, uint16_t length)
+{
+    sendBuffer = buffer;
+    sendLength = length;
+
+    sendIndex = 0;    
+    SerialBase::_base_putc(sendBuffer[sendIndex]);
+}
+
+
+
+void AsyncSerial::receive(receive_done_t handler, 
+                          uint8_t* buffer, uint16_t maxLength, 
+                          const uint8_t* _conditionBuffer, uint16_t _conditionLength, 
+                          uint32_t timeoutMilli)
+{
+    receiveDoneHandler = handler;
+
+    receiveBuffer = buffer;
+    receiveMaxLength = maxLength;
+    receiveIndex = 0;
+    
+    conditionBuffer = _conditionBuffer;
+    conditionLength = _conditionLength;
+    conditionIndex = 0;
+    
+    timeout.attach_us<AsyncSerial>(this, &AsyncSerial::getDone, timeoutMilli * 1000);
+}
+
+int AsyncSerial::getc() 
+{
+    return SerialBase::_base_getc();
+}
+
+int AsyncSerial::putc(int c) 
+{
+    return SerialBase::_base_putc(c);
+}
+
+