APP 4

Dependencies:   mbed CRC16 mbed-rtos

MEF.cpp

Committer:
manl2003
Date:
2016-02-23
Revision:
27:011ad1667040
Parent:
26:f2b37f9dfca9

File content as of revision 27:011ad1667040:

// Vincent Bélanger et Laurent Mandrile
// belv1802 - manl2003

#include "MEF.h"
#include "CRC16.h"

void MEF::init()
{
    m_InputBuffer.reset();
    m_BSPayload.reset();
    memset(m_CPayload, 0, 80);
    m_Counter = 0;
    m_DataSize = 0;
    m_CRC = 0;
}

void MEF::ReceiveBit(bool bit)
{
    switch (state)
    {
        case PREAMBLE :
        default :
                {
                    //On vérifie si dans les 8 derniers bits se trouve le préambule
                    m_InputBuffer[0] = m_InputBuffer[1];
                    m_InputBuffer[1] = m_InputBuffer[2];
                    m_InputBuffer[2] = m_InputBuffer[3];
                    m_InputBuffer[3] = m_InputBuffer[4];
                    m_InputBuffer[4] = m_InputBuffer[5];
                    m_InputBuffer[5] = m_InputBuffer[6];
                    m_InputBuffer[6] = m_InputBuffer[7];
                    m_InputBuffer[7] = bit;
                    
                    if(preambleChecker())
                    {
                        state = START;
                    }

                }break;
        case START :
                {
                    //Verification du start byte
                    m_InputBuffer[m_Counter] = bit;
                    m_Counter++;
                    if(m_Counter >= 8)
                    {
                        if(startChecker())
                        {
                            state = TYPE;
                            m_Counter = 0;
                        }
                        else
                        {
                            //Frame drop
                            _decodeError();
                            state = PREAMBLE;
                            init();                            
                        }
                    }                    
                }break;
        case TYPE :
                {
                    //8 bits de type
                    m_Counter ++;
                    if(m_Counter >= 8)
                    {
                        state = LENGTH;
                        m_Counter = 0;
                    }
                    
                }break;
        case LENGTH :
                {
                    //Longueur du data
                    m_InputBuffer[m_Counter] = bit;
                    m_Counter++;
                    if(m_Counter >= 8)
                    {
                        state = DATA;
                        m_DataSize = calculateSize();
                        m_Counter = 0;
                    }
                    
                }break;
        case DATA :
                {
                    //Interprétation du data
                    m_BSPayload[m_Counter] = bit;
                    if (((m_Counter + 1) % 8) == 0 && m_Counter != 0)
                    {
                        m_CPayload[(m_Counter + 1)/ 8 - 1] = (m_BSPayload[m_Counter] << 0) | (m_BSPayload[m_Counter - 1] << 1) | (m_BSPayload[m_Counter - 2] << 2) | (m_BSPayload[m_Counter - 3] << 3) | (m_BSPayload[m_Counter - 4] << 4) | (m_BSPayload[m_Counter - 5] << 5) | (m_BSPayload[m_Counter - 6] << 6) | (m_BSPayload[m_Counter - 7] << 7);
                    }
                    m_Counter++;
                    if(m_Counter >= m_DataSize*8)
                    {
                        state = CRC16STATE;
                        m_CRC = CRC16::calculateCRC16(m_CPayload, m_DataSize);
                        m_Counter = 0;
                    }
                }break;
        case CRC16STATE :
                {
                    //Réception du checksum et calcul
                    m_InputBuffer[m_Counter] = bit;
                    m_Counter++;
                    if(m_Counter >= 16)
                    {
                        if(!compareCRC())
                        {
                            //Frame drop
                            _decodeError();
                            state = PREAMBLE;
                            init();    
                        }
                        else
                        {
                           state = END;                               
                        }
                        m_Counter = 0;
                    }
                    
                }break;
        case END :
                {
                    //Calcul du byte de fin
                    m_InputBuffer[m_Counter] = bit;
                    m_Counter++;
                    if(m_Counter >= 8)
                    {
                        if(startChecker())
                        {
                            state = PREAMBLE;
                            m_Counter = 0;
                            //Message complet, appel du callback
                            _decodeCallback(m_BSPayload, m_DataSize);   
                        }
                        else
                        {
                            _decodeError();
                            state = PREAMBLE;
                            init();
                        }
                    }

                }break;           
    }
    //Callback pour avertir le main d'un changement d'état
    _updateState(state);
}

bool MEF::preambleChecker()
{
    bool temp = false;
    bool resultTest1 = true, resultTest2 = true;
    for(int i = 0; i < 8; i++)
    {
        if(m_InputBuffer[i] != temp)
        {
            resultTest1 = false;
        }
        if(m_InputBuffer[i] == temp)
        {
            resultTest2 = false;
        }
        temp = !temp;
    }
    return resultTest1 || resultTest2;    
}

bool MEF::startChecker()
{
    if(m_InputBuffer[0] == 0 && m_InputBuffer[1] == 1 && m_InputBuffer[2] == 1 && m_InputBuffer[3] == 1 && m_InputBuffer[4] == 1 && m_InputBuffer[5] == 1 && m_InputBuffer[6] == 1 && m_InputBuffer[7] == 0)
    {
        return true;
    }
    return false;
}

int MEF::calculateSize()
{
    return (m_InputBuffer[0] << 7) | (m_InputBuffer[1] << 6) | (m_InputBuffer[2] << 5) | (m_InputBuffer[3] << 4) | (m_InputBuffer[4] << 3) | (m_InputBuffer[5] << 2) | (m_InputBuffer[6] << 1) | (m_InputBuffer[7] << 0);
}

bool MEF::compareCRC()
{
    unsigned short incommingCRC = (m_InputBuffer[0] << 15) | 
    (m_InputBuffer[1] << 14) | 
    (m_InputBuffer[2] << 13) | 
    (m_InputBuffer[3] << 12) | 
    (m_InputBuffer[4] << 11) | 
    (m_InputBuffer[5] << 10) | 
    (m_InputBuffer[6] << 9) | 
    (m_InputBuffer[7] << 8) | 
    (m_InputBuffer[8] << 7) |
    (m_InputBuffer[9] << 6) |
    (m_InputBuffer[10] << 5) |
    (m_InputBuffer[11] << 4) |
    (m_InputBuffer[12] << 3) |
    (m_InputBuffer[13] << 2) |
    (m_InputBuffer[14] << 1) |
    (m_InputBuffer[15] << 0);

    return m_CRC == incommingCRC;
}