Marcus Chang / AsyncSerial
Revision:
1:a3f39ec7d5f2
Parent:
0:dfed780dc91a
Child:
2:efec63739aa3
--- a/source/AsyncSerial.cpp	Mon Mar 30 15:37:07 2015 +0000
+++ b/source/AsyncSerial.cpp	Mon Mar 30 17:12:30 2015 +0100
@@ -5,19 +5,30 @@
 template<class T>
 AsyncSerial::AsyncSerial(PinName tx, PinName rx, PinName rts, PinName cts)
     :   SerialBase(tx, rx),
+
         sendBuffer(NULL),
         sendLength(0),
+        sendIndex(0),
+
         sendDoneHandler(NULL),
-        sendIndex(0),
+        sendObject(NULL),
+        sendMember(),
+        sendDoneObject(NULL),
+
         receiveBuffer(NULL),
         receiveMaxLength(0),
+        receiveIndex(0),
+
         receiveDoneHandler(NULL),
-        receiveIndex(0),
+        receiveObject(NULL),
+        receiveMember(),
+        receiveDoneObject(NULL),
+
         conditionBuffer(NULL),
         conditionLength(0),
         conditionIndex(0),
         timeout()
-{    
+{
     SerialBase::attach<AsyncSerial>(this, &AsyncSerial::getReady, SerialBase::RxIrq);
     SerialBase::attach<AsyncSerial>(this, &AsyncSerial::putDone, SerialBase::TxIrq);
 }
@@ -27,18 +38,24 @@
     if (sendLength > 0)
     {
         sendIndex++;
-    
+
         if (sendIndex < sendLength)
         {
             SerialBase::_base_putc(sendBuffer[sendIndex]);
         }
         else
         {
+            sendLength = 0;
+
             if (sendDoneHandler)
             {
                 sendDoneHandler(sendBuffer, sendLength);
                 sendDoneHandler = NULL;
-                sendLength = 0;
+            }
+            else if (sendObject)
+            {
+                sendDoneObject(sendObject, sendMember, sendBuffer, sendLength);
+                sendObject = NULL;
             }
         }
     }
@@ -47,12 +64,12 @@
 void AsyncSerial::getReady()
 {
     uint8_t input = SerialBase::_base_getc();
-    
+
     if (receiveMaxLength > 0)
-    {        
+    {
         receiveBuffer[receiveIndex] = input;
         receiveIndex++;
-        
+
         if (receiveIndex == receiveMaxLength)
         {
             timeout.detach();
@@ -63,7 +80,7 @@
             if (receiveBuffer[receiveIndex - 1] == conditionBuffer[conditionIndex])
             {
                 conditionIndex++;
-            
+
                 if (conditionIndex == conditionLength)
                 {
                     timeout.detach();
@@ -79,7 +96,7 @@
 }
 
 void AsyncSerial::getDone()
-{            
+{
     receiveMaxLength = 0;
 
     if (receiveDoneHandler)
@@ -87,77 +104,115 @@
         receiveDoneHandler(receiveBuffer, receiveIndex);
         receiveDoneHandler = NULL;
     }
+    else if (receiveObject)
+    {
+        receiveDoneObject(receiveObject, receiveMember, receiveBuffer, receiveIndex);
+        receiveObject = NULL;
+    }
 }
 
 void AsyncSerial::send(send_done_t handler, uint8_t* buffer, uint16_t length)
 {
     if (handler && buffer && length)
-    {        
+    {
         sendDoneHandler = handler;
-        
+
+        sendObject = NULL;
+        sendMember = 0;
+
         send(buffer, length);
     }
 }
 
 template<typename T>
-void AsyncSerial::send(T *object, void (T::*member)(void), uint8_t* buffer, uint16_t length) 
+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>;
+        memcpy(sendMember, &member, sizeof(member));
+        sendDoneObject = &AsyncSerial::membercaller<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;    
+    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, 
+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;
+    if (handler)
+    {
+        receiveDoneHandler = handler;
+
+        receiveObject = NULL;
+
+        receive(buffer, maxLength, conditionBuffer, conditionLength, timeoutMilli);
+    }
+}
 
+template<typename T>
+void AsyncSerial::receive(T *object, void (T::*member)(uint8_t*, uint16_t),
+                          uint8_t* buffer, uint16_t maxLength,
+                          const uint8_t* conditionBuffer, uint16_t conditionLength,
+                          uint32_t timeoutMilli)
+{
+    if (object && member && receiveBuffer && maxLength)
+    {
+        receiveObject = static_cast<void*>(object);
+        memcpy(receiveMember, (uint8_t*) &member, sizeof(member));
+        receiveDoneObject = &AsyncSerial::membercaller<T>;
+
+        receiveDoneHandler = NULL;
+
+        receive(buffer, maxLength, conditionBuffer, conditionLength, timeoutMilli);
+    }
+}
+
+void AsyncSerial::receive(uint8_t* receiveBuffer, uint16_t maxLength,
+                          const uint8_t* conditionBuffer, uint16_t conditionLength,
+                          uint32_t timeoutMilli)
+{
     receiveBuffer = buffer;
     receiveMaxLength = maxLength;
     receiveIndex = 0;
-    
+
     conditionBuffer = _conditionBuffer;
     conditionLength = _conditionLength;
     conditionIndex = 0;
-    
+
     timeout.attach_us<AsyncSerial>(this, &AsyncSerial::getDone, timeoutMilli * 1000);
 }
 
-int AsyncSerial::getc() 
+template<typename T>
+static void AsyncSerial::membercaller(void* object, uint8_t* member, uint8_t* buffer, uint16_t length)
+{
+    T* o = static_cast<T*>(object);
+    void (T::*m)(uint8_t*, uint16_t);
+    memcpy(&m, member, sizeof(m));
+    (o->*m)(buffer, length);
+}
+
+int AsyncSerial::getc()
 {
     return SerialBase::_base_getc();
 }
 
-int AsyncSerial::putc(int c) 
+int AsyncSerial::putc(int c)
 {
     return SerialBase::_base_putc(c);
 }