Alexandre Lemay / Mbed 2 deprecated APP4_FunTimes

Dependencies:   mbed mbed-rtos

Revision:
6:ac7c0ccf9b5d
Parent:
4:a3c4a43f94f8
Child:
7:332766fb3114
--- a/Receiver.cpp	Mon Oct 23 21:20:08 2017 +0000
+++ b/Receiver.cpp	Tue Oct 24 02:33:50 2017 +0000
@@ -1,107 +1,224 @@
-#include <Receiver.h>
-
+#include "Receiver.h"
+#include "CRC.h"
 
 InterruptIn DO(p21);
 
-const int us_period = 10000;
+extern Serial pc;
+
 
-void ReceiverData::setTime()
-{
-    lastTime = time.read_us();
+Receiver::Receiver():currentData(0),endData(0)
+{   
+    time.start();
+    pc.printf("receive");
+    DO.rise(this,&Receiver::rise);
+    DO.fall(this,&Receiver::fall);
+    pc.printf("contructor\n");
 }
 
-void ReceiverData::addBit(unsigned char bit)
+Receiver::EdgeData Receiver::getNext()
 {
-    setTime();
-    if(bit != 0)
-    {
-        // MSB First
-        temp = temp | 1 << (7-currentBit);
-    }
-    
-    currentBit++;
-
-    // If filled  a whole byte, send it to the data
-    if(currentBit == 8) {
-        data.push_back(temp);        
-        temp = 0;
-        currentBit = 0;
-    }
+    dataReady.wait();
+    EdgeData val = data[currentData];
+    currentData++;
+    if(currentData==size)
+        currentData = 0 ;
+    return val;
 }
 
-void ReceiverData::clear()
+
+void Receiver::pushState(Edge edge)
 {
-    currentBit =0;
-    lastTime =0;
-    temp =0;
-    data.clear();
-    time.stop();    
+    EdgeData point(time.read_us(),edge);
+    data[endData] = point;
+    endData++;
+    if(endData==size)
+        endData = 0;    
+    dataReady.release();
+}
+
+
+void Receiver::rise()
+{
+    pushState(rising);
+}
+void Receiver::fall()
+{
+    pushState(falling);
 }
 
 
-void ReceiverData::fall()
+void ManchesterReceiver::getState(Edge &edge, int &timeStamp)
+{
+    EdgeData data = r.getNext();
+    edge = data.value;
+    timeStamp = data.us_timeStamp;    
+}
+
+unsigned char ManchesterReceiver::getFirstByte(int &lastTime)
 {
-    if(!ready){
-        return;
-    }
-    
-    if(waiting()) {
-        //First data is a 0 (rising edge)
-        return;
-    }
-    if(time.read_us() - lastTime < us_period/2) {
-        // This transition is not real data.
-        return;
-    } else {
-        addBit(1);
+    while(true)
+    {
+        Edge edge;
+        int us;
+        int lastData;
+        getState(edge,lastData);
+        if(edge == rising)
+        {   
+            // start first byte
+            unsigned char val = 0;
+            for(int i =0; i < 7; i++ )
+            {
+                getState(edge,us);
+                pc.printf("timeout : %i\n", us-lastData);
+                // timed out
+                if(us - lastData > us_period*5/4)
+                {
+                //a potential new preamble byte
+                    if( edge == rising ){
+                        i = 0; continue;
+                    }
+                    else break;
+                }
+                // Closer to data transition than 
+                else if(us - lastData > us_period*3/4)
+                {
+                    lastData = us;
+                    if(edge == falling)
+                    {
+                        val = val | 1 << 6-i;
+                    }
+                    if(i==6)
+                    {
+                        lastTime = lastData;
+                        return val;
+                    }
+                }
+                // skip it, because it is just before a meaningful transition
+                else if(us - lastData < us_period*3/4)
+                {
+                    i--; 
+                    continue;
+                }
+            }               
+        }        
     }
 }
 
-void ReceiverData::rise()
+bool ManchesterReceiver::getByte(int& lastTime, unsigned char &val)
 {
-    if(!ready){
-        return;
+    val = 0;
+    int us = 0;
+    for(int i = 0 ; i <8; i++) 
+    {
+        Edge edge;
+        getState(edge,us);
+        
+                pc.printf("\ntimeout : %i\n", us-lastTime);
+        // timed out
+        if(us - lastTime > us_period*5/4)
+        {   pc.printf ("\n\n\n TIMEOUT GETBYTE");
+            return false;
+        }
+        // Close to data transition time
+        else if(us - lastTime > us_period*3/4) 
+        {
+            lastTime = us;
+            if(edge == falling) 
+            {
+                val = val | 1 << 7-i;
+            }
+            if(i==7)
+                return true;
+        }// between meaningful transitions, skip it
+        else if(us - lastTime < us_period*3/4)
+        {
+            i--; 
+            continue;
+        }
     }
-    
-    if(waiting()) {
-        // Should be the first 0 in the first byte
-        receiving = true;
-        addBit(0);
-        return;
-    }
-
-    if(time.read_us() - lastTime < us_period/2) {
-        // This transition is not real data.
-        return;
-    } else {
-        addBit(0);
-    }
+    return false;
 }
 
-void ReceiverData::waitData()
+bool ManchesterReceiver::getMessage(int lastTime,vector<unsigned char> &message )
 {
-    dataSemaphore.wait();
+    message.push_back(preamble_byte);
+    
+    unsigned char byte;
+    if(!getByte(lastTime, byte))
+    {   pc.printf("1");// timed out 
+        return false;
+    }
+    
+    
+    pc.printf("%i\n",byte);
+    
+    if(byte!=STARTBYTE)
+        return false;
+    message.push_back(byte);
+    //flags
+    if(!getByte(lastTime, byte))
+        return false;
+    message.push_back(byte);
+    
+    if(!getByte(lastTime, byte))
+        return false;
+    message.push_back(byte);
+    
+    int length = byte;
+    //data
+    for(int i = 0; i < length-3; i++)
+    {
+        if(!getByte(lastTime, byte))
+        return false;
+        message.push_back(byte);
+        
+        
+        pc.printf("%i",message.size());
+    }
+    
+    int crc = crc16Remainder(message);
+    
+    // crc byte1
+    if(!getByte(lastTime, byte))
+        return false;
+    message.push_back(byte);
+    
+    int readCrc = byte << 8;
+    // crc byte2
+    if(!getByte(lastTime, byte))
+        return false;
+    message.push_back(byte);
+    readCrc = readCrc | byte;
+    
+    // endbyte
+    if(!getByte(lastTime, byte))
+        return false;
+    message.push_back(byte);
+    
+    if( byte != ENDBYTE )
+        return false;
+    return true;
 }
 
-void ReceiverData::timeout()
+void ManchesterReceiver::getMessages()
 {
-    if(!receiving){
-        return;
+    while(true)
+    {
+        int lastTime;
+        unsigned char byte = getFirstByte(lastTime);
+        pc.printf("%i",byte);
+        if(byte == preamble_byte)
+        {
+            vector<unsigned char> message;
+            if(getMessage(lastTime, message)==true)
+            {
+                for(int i = 0 ; i < message.size(); i++)
+                {
+                    pc.printf("%c", message[i]);
+                }
+            }
+        }
     }
-    if(time.read_us() - lastTime > 3/2 * us_period )
-    {   // Finished
-        dataSemaphore.release();
-        
-        watchDog.detach();
-        ready = false;
-    }
+
 }
 
-void ReceiverData::start()
-{
-    clear();
-    DO.fall(this,&ReceiverData::fall);
-    DO.rise(this, &ReceiverData::rise);
-    watchDog.attach(this, &ReceiverData::timeout,us_period);
-    ready = true;
-}
\ No newline at end of file