Alexandre Lemay / Mbed 2 deprecated APP4_FunTimes

Dependencies:   mbed mbed-rtos

Receiver.cpp

Committer:
ThierryLeonard
Date:
2017-10-24
Revision:
6:ac7c0ccf9b5d
Parent:
4:a3c4a43f94f8
Child:
7:332766fb3114

File content as of revision 6:ac7c0ccf9b5d:

#include "Receiver.h"
#include "CRC.h"

InterruptIn DO(p21);

extern Serial pc;


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");
}

Receiver::EdgeData Receiver::getNext()
{
    dataReady.wait();
    EdgeData val = data[currentData];
    currentData++;
    if(currentData==size)
        currentData = 0 ;
    return val;
}


void Receiver::pushState(Edge edge)
{
    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 ManchesterReceiver::getState(Edge &edge, int &timeStamp)
{
    EdgeData data = r.getNext();
    edge = data.value;
    timeStamp = data.us_timeStamp;    
}

unsigned char ManchesterReceiver::getFirstByte(int &lastTime)
{
    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;
                }
            }               
        }        
    }
}

bool ManchesterReceiver::getByte(int& lastTime, unsigned char &val)
{
    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;
        }
    }
    return false;
}

bool ManchesterReceiver::getMessage(int lastTime,vector<unsigned char> &message )
{
    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 ManchesterReceiver::getMessages()
{
    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]);
                }
            }
        }
    }

}