APP3 / Mbed 2 deprecated APP4

Dependencies:   mbed mbed-rtos

main.cpp

Committer:
ShaolinPoutine
Date:
2017-03-07
Revision:
4:4277898e55d8
Parent:
3:7b1110501ef9
Child:
5:25101883c27a

File content as of revision 4:4277898e55d8:

#include "mbed.h"
#include "rtos.h"
#define CLOCK_MAX 96000000
#define TRAME_MAX 1024
#define DATA_LEN 80

bool PREAMBULEBOOL[] = {0,1,0,1,0,1,0,1};
bool STARTENDBOOL[] = {0,1,1,1,1,1,1,0};
char PREAMBULE = 0b01010101;
char STARTEND = 0b01111110;

DigitalOut myled(LED1);
DigitalOut led2(LED2);
Serial pc(USBTX, USBRX);

Queue<int, 1500> envoi;
Thread* listeningThread;


void printBin(uint16_t data)
{
    uint16_t mask = 1 << 15;
    
    while (mask != 0)
    {
        if ((data & mask) > 0)
        {
            pc.printf("1");
        }
        else
        {
            pc.printf("0");
        }
        mask = mask >> 1;
    }
}

uint16_t GetBit(char *payload, int bitNumber)
{
    int index = bitNumber / 8;
    int bitNo = bitNumber % 8;
    
    return (payload[index] & (0x80 >> bitNo)) > 0;
}

void CRC16(char *payload, int length)
{
    payload[length - 1] = 0;
    payload[length - 2] = 0;
    
    uint16_t polynome = 0x8005; // Les 16 bits du polynome (17ieme bit a 1 est implicitement)
    uint16_t workingSet;
    uint16_t lastBit;
    
    int noBit;
    int nbBit = length * 8;
    
    // Initialiser les données
    lastBit = (payload[0] & 0x80) >> 7; 
    workingSet = (((payload[0] << 8) | payload[1]) << 1) | ((payload[2] & 0x80) >> 7);
    noBit = 16;
    
    // CRC
    while (noBit < (nbBit - 1))
    {   
        if (lastBit > 0)
        {
            workingSet = workingSet xor polynome;
        }
        else
        {
            workingSet = workingSet xor 0;
        }
        
        // Ajouter le prochain bit des valeurs
        lastBit = (workingSet & 0x8000) >> 15;
        workingSet = workingSet << 1;
        workingSet = workingSet | GetBit(payload, noBit);
        
        noBit++;
    }
    
    // Final XOR
    if (lastBit > 0)
    {
        workingSet = workingSet xor polynome;
    }
    else
    {
        workingSet = workingSet xor 0;
    }
    
    // Ecrire la valeur dans le payload
    payload[length - 1] = workingSet & 0x00FF;
    payload[length - 2] = workingSet >> 8;
}

bool compareBoolArray(bool* a, bool* b)
{
    int i = 0;
    while (i < 8)
    {
        if (a[i] != b[i])
        {
            return false;
        }
        i++;
    }
    return true;
}

char msbBooltoChar(bool data[8])
{
    char c = 0;
    for (int i=0; i < 8 ; i++)
        if (data[i])
            c |= 1 << (7 - i);
    return c;
}

void charToMsbBool(char data, bool out[8])
{
    for (int i=0; i < 8; ++i)
        out[i] = (data & (1<<(7 - i))) != 0;
}

void PrintBoolArray(bool* data, int len)
{
    pc.printf("[");
    for (int i = 0; i < len - 1; i++)
    {
        pc.printf("%d, ", data[i]);
    }
    pc.printf("%d]", data[len-1]);
}

bool ManchesterDecodeBit(bool* data, bool* out)     // Tested
{
    if (data[0] == 0 && data[1] == 1)
    {
        out[0] = 1;
    }
    else if (data[0] == 1 &&  data[1] == 0)
    {
        out[0] = 0;
    }
    else
    {
        return false;
    }
    return true;
}

bool ManchesterDecodeByte(bool* data, char* out)    // Tested
{
    bool Valid = true;
    bool tmp = true;
    for (int i = 0; i < 8; i++)
    {
        Valid = ManchesterDecodeBit(data, &tmp);
        data += 2;
        if (!tmp)
        {
            *out = *out & ~(0x1 << (7-i));
        }
        else
        {
            *out = *out | (0x1 << (7-i));
        }
        if (!Valid)
        {
            return false;
        }
    }
    return true;
}

void ManchesterEncodeBit(bool data, bool* out)         // Tested
{
    if (data == 0)
    {
        out[0] = 1;
        out[1] = 0;
    }
    else
    {
        out[0] = 0;
        out[1] = 1;
    }
}

void ManchesterEncodeByte(char data, bool* out)         // Tested       
{
    for (int i = 0; i < 8; i++)
    {
        ManchesterEncodeBit((bool) ((data >> (7 - i)) & 1), &(out[2*i]));
    }
}

int CountData(char* data)                           // Tested
{
    int i = 0;
    while(*data != 0)
    {
        data++;
        i++;
    }
    return i;
}

void AddPreambule(bool* data)
{
    for (int i = 0; i < 8; i++)
    {
        *data = PREAMBULEBOOL[i];
        data++;
    }
}

void AddStartEnd(bool* data)
{
    for (int i = 0; i < 8; i++)
    {
        *data = STARTENDBOOL[i];
        data++;
    }
}

void AnalyseHeading(char* data, int* id, int* frame, int* frame_count, int* len)
{
    *id = data[0] >> 6;
    *frame = (data[0] >> 3) & 7;
    *frame_count = data[0] & 7;
    
    *len = data[1];
}

bool AddHeading(char* out, int id, int frame, int frame_count, char len)     // Tested
{
    char tmp = 0;
    if (frame > frame_count || frame > 7 || frame_count > 7 || len - 2 > DATA_LEN)
    {
        return false;
    }
    // Two first bits -> id
    id = id & 3;
    tmp = tmp | (id << 6);
    
    // Three next -> frame number
    frame = frame & 7;
    tmp = tmp | (frame << 3);
    
    // Three last -> number of frames
    frame_count = frame_count & 7;
    tmp = tmp | frame_count;
    *out = tmp;

    // Last char is lenght
    out++;
    *out = len;
    return true;
}

void AddCRC(char* data, int len)
{
    
}
void ReceiveBits(bool* data, int len);
void SendBits(bool* bits, int len)
{
    // Emile
    // thread.signal_set(0x1);
    // Synchronize with wire
    for (int i = 0; i < len; i++)
    {
        envoi.put((int *) bits[i]);
    }
    listeningThread->signal_set(0x1);
    
    //ReceiveBits(bits, len);
}

void SendFormated(bool* data, int len)
{
    pc.printf("SendFormated - len %d\r\n", len);
    bool tmp[len + 3 * 8];
    AddPreambule(tmp);
    AddStartEnd(tmp + 8);
    for (int i = 0; i < len; i++)
    {
        tmp[i + 2 * 8] = data[i];
    }
    AddStartEnd(tmp + (len + 3 - 1) * 8);
    SendBits(tmp, len + 3 * 8);
}

void SendManchester(char* data, int len)
{
    pc.printf("SendManchester - len %d\r\n", len);
    bool bits[2*len*8];
    for (int i = 0; i < len; i++)
    {
        ManchesterEncodeByte(data[i], bits + 2*i*8);
    }
    SendFormated(bits, 2*len*8);
}

int lastIdUsed = 0;

void SendText(char* data, int len)
{
    pc.printf("SendText - len %d\r\n", len);
    char tmp[len + 4];
    int frame, frames;
    // Gestion des ID
    if (len > DATA_LEN)
    {
        pc.printf("Plz implement multiple trames messages.\r\n");
        return;
    }
    else
    {
        frame = 1;
        frames = 1;
        // Gestion exception
        AddHeading(tmp, lastIdUsed, frame, frames, len + 2);
        for (int i = 0; i < len; i++)
        {
            tmp[i + 2] = data[i];
        }
        tmp[len + 2] = 0;
        tmp[len + 3] = 0;
        CRC16(tmp + 2, len + 2);
        SendManchester(tmp, len + 4);
    }
}

void ReceiveText(char* data)
{
    pc.printf("Received: %s\r\n", data);
}

void ReceiveFormated(char* data, int len)
{
    pc.printf("ReceiveFormated - len %d\r\n", len);
    char tmp[len - 2];
    int id, frame, frames, predicted_len;
    AnalyseHeading(data, &id, &frame, &frames, &predicted_len);
    // Gestion des id et frames et frame number
    
    if (predicted_len != len - 2)
    {
        pc.printf("DEBUG -- Received payload with wrong lenght. %d %d\r\n", len - 2, predicted_len);
        return;
    }
    // Copy data
    for (int i = 0; i < len - 2; i++)
    {
        tmp[i] = data[i + 2];
    }
    for (int i = len - 4; i < len - 2; i++)
    {
        tmp[i] = 0;
    }
    
    //CRC calculate
    CRC16(tmp, len - 2);
    if (tmp[len - 4] == data[len - 2] && tmp[len - 3] == data[len - 1])
    {
        tmp[len - 4] = '\0';
        led2= 1;
        ReceiveText(tmp);
    }
    else
    {
        pc.printf("DEBUG -- Received payload with wrong CRC.\r\n");
        return;
    }
}

void ReceiveManchester(bool* data, int len)
{
    pc.printf("ReceiveManchester - len %d\r\n", len);
    char tmp[len / 16];
    for (int i = 0; i < len / 16; i++)
    {
        ManchesterDecodeByte(data, tmp + i);
        data += 16;
    }
    ReceiveFormated(tmp, len / 16);
}

void ReceiveBits(bool* data, int len)
{   
    if (compareBoolArray(data, PREAMBULEBOOL))
    {
        data += 8;
        len -= 8;
    }
    else
    {
        pc.printf("DEBUG -- Received payload with wrong Preambule.");PrintBoolArray(data , 8);pc.printf("\r\n");
        return;
    }
    
    // Ensure Start and end are present
    if (compareBoolArray(data, STARTENDBOOL) || compareBoolArray(data + (len - 8), STARTENDBOOL))
    {
        ReceiveManchester(data + 8, len - 2 * 8);
    }
    else
    {
        pc.printf("DEBUG -- Received payload with wrong Start or End.\r\n");
        return;
    }
}

void Listening()
{
    while (1)
    {
        Thread::signal_wait(0x1);
        osEvent evt = envoi.get();
        if (evt.status == osEventMessage){
            /*bool message = (message_t*) evt.value.p;
            //ReceiveBits((bool *) message->bits, message->len);
            envoi.free(message);*/
        }
    }
    
}

extern "C" void TIMER2_IRQHandler (void)
{
if((LPC_TIM2->IR & 0x01) == 0x01)   // if MR0 interrupt, proceed
    {
        LPC_TIM2->IR |= 1 << 0;         // Clear MR0 interrupt flag
    }
}

void init_clk()
{
    LPC_PINCON->PINSEL0 |=3<<12;            //P0.6 = MAT2.0  // p8
    LPC_SC->PCLKSEL1 |=1<<12;               //pclk timer2 = cclk 
    LPC_SC->PCONP |=1<<22;                  //timer2 power on
    LPC_TIM2->MR0 = CLOCK_MAX / 2;          // 1 sec period
    LPC_TIM2->MCR = 3;                      //interrupt and reset control
                                            //3 = Interrupt & reset timer2 on match
                                            //1 = Interrupt only, no reset of timer0
    LPC_TIM2->EMR =3<<4;                    //EMC0 = 11 (Toogle)
    NVIC_EnableIRQ(TIMER2_IRQn);            //enable timer2 interrupt
    LPC_TIM2->TCR = 1;                      //enable Timer2
}

void TestManchester();
void TestUtility();
void mainRaph()
{
    init_clk();
    //TestUtility();
   // TestManchester();
   SendText("A more complex sentence to prove our algorithm is robust!", 57);
   wait(1);
    SendText("OK", 2);
    wait(1);
    SendText("A more complex sentence to prove our algorithm is robust!", 57);
}

void tick()
{
    myled = !myled;
}
int main() {
    Ticker ticker;
    ticker.attach(&tick, 0.5);
    listeningThread = new Thread();
    listeningThread->start(Listening);
    
    mainRaph();
    while (1){}
}

//--------------------------------TEST---------------------------------------------------//

char ToByte(bool b[8])
{
    char c = 0;
    for (int i=0; i < 8; ++i)
        if (b[i])
            c |= 1 << i;
    return c;
}

void FromByte(char c, bool b[8])
{
    for (int i=0; i < 8; ++i)
        b[i] = (c & (1<<i)) != 0;
}

void TestUtility()
{
    pc.printf("TestUtility -- Begin\r\n");
    char charValue = 1;
    bool boolValue[8] = {0,0,0,0,0,0,0,1};
    bool boolAns[8] = {0,0,0,0,0,0,0,1};
    char charAns;
    
    if (!compareBoolArray(boolValue, boolAns))
    {
        pc.printf("Should be gud");
        return;
    }
    boolAns[7] = 0;
    if (compareBoolArray(boolValue, boolAns))
    {
        pc.printf("Should not be gud");
        return;
    }
    
    charAns = msbBooltoChar(boolValue);
    
    if (charValue != charAns)
    {
        pc.printf("msbBooltoChar error. %d %d\r\n", charValue, charAns);
        return;
    }
    
    charToMsbBool(charValue, boolAns);
    
    if(!compareBoolArray(boolValue, boolAns))
    {
        pc.printf("charToMsbBool error ");PrintBoolArray(boolValue,8);pc.printf(" ");PrintBoolArray(boolAns,8);pc.printf("\r\n");
        return;
    }
    pc.printf("TestUtility -- End\r\n");
}

void TestManchester()
{
    pc.printf("TestManchester - Begin\r\n");

    // ----------------------------ENCODE-----------------------------------------------//
    bool Valid = true;
    bool boolData0 = (char) 0b0;
    bool boolExpected0[] = {1,0};
    bool boolAns0[2];
    
    ManchesterEncodeBit(boolData0, (bool *) boolAns0);
    
    int i = 0;
    Valid = true;
    while (Valid && i < 2)
    {
        Valid = !(boolExpected0[i] ^ boolAns0[i]);
        i++;
    }
    
    if (!Valid)
    {
        pc.printf("TestManchester - encode - bool0 - Failed\r\n");
        pc.printf("Expected: [%d, %d]. Received: [%d, %d].\r\n\n", boolExpected0[0], boolExpected0[1], boolAns0[0], boolAns0[1]);
    }
        
    bool boolData1 = (char) 0b1;
    bool boolExpected1[] = {0,1};
    bool boolAns1[2];
    ManchesterEncodeBit(boolData1, (bool*) boolAns1);
    
    i = 0;
    Valid = true;
    while (Valid && i < 2)
    {
        Valid = !(boolExpected1[i] ^ boolAns1[i]);
        i++;
    }
    if (!Valid)
    {
        pc.printf("TestManchester - encode - boo11 - Failed\r\n");
        pc.printf("Expected: [%d, %d]. Received: [%d, %d].\r\n\n", boolExpected1[0], boolExpected1[1], boolAns1[0], boolAns1[1]);
    }
    
    char charData = (char) 0b01010101;
    bool charExpected[] = {1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1};
    bool charAns[16];
    ManchesterEncodeByte(charData, (bool*) charAns);
    
    i = 0;
    Valid = true;
    while (Valid && i < 16)
    {
        Valid = !(charExpected[i] ^ charAns[i]);
        i++;
    }
    if (!Valid)
    {
        pc.printf("TestManchester - encode - char - Failed\r\n");
        pc.printf("Expected: [%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d]\r\nReceived: [%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d].\r\n\n", 
        charExpected[0], charExpected[1], charExpected[2], charExpected[3],
        charExpected[4], charExpected[5], charExpected[6], charExpected[7],
        charExpected[8], charExpected[9], charExpected[10], charExpected[11],
        charExpected[12], charExpected[13], charExpected[14], charExpected[15], 
        charAns[0], charAns[1], charAns[2], charAns[3],
        charAns[4], charAns[5], charAns[6], charAns[7],
        charAns[8], charAns[9], charAns[10], charAns[11],
        charAns[12], charAns[13], charAns[14], charAns[15]);
    }
    
    // ----------------------------DECODE-----------------------------------------------//
    Valid = true;
    bool boolDecodeData0[] = {1,0};
    bool boolDecodeExpected0 = 0b0;
    bool boolDecodeAns0;
    bool Success = true;
    Success = ManchesterDecodeBit((bool *)boolDecodeData0, &boolDecodeAns0);
    
    if (!Success)
    {
        pc.printf("TestManchester - decode - bool0 - Invalid format\r\n");
    }
    
    if (boolDecodeExpected0 != boolDecodeAns0)
    {
        pc.printf("TestManchester - decode - bool0 - Failed\r\n");
        pc.printf("Expected: %d. Received: %d.\r\n\n", boolDecodeExpected0,  boolDecodeAns0);
    } 
   
    bool boolDecodeData1[] = {0,1};
    bool boolDecodeExpected1 = (char) 0b1;
    bool boolDecodeAns1;
    Success = ManchesterDecodeBit((bool *)boolDecodeData1, &boolDecodeAns1);
    
    if (!Success)
    {
        pc.printf("TestManchester - decode - bool1 - Invalid format\r\n");
    }
    if (boolDecodeExpected1 != boolDecodeAns1)
    {
        pc.printf("TestManchester - decode - boo11 - Failed\r\n");
        pc.printf("Expected: %d. Received: %d\r\n\n", boolDecodeExpected1, boolDecodeAns1);
    }
    
    bool boolDataInv0[] = {0,0};
    bool boolDataInv1[] = {1,1};
    bool boolAnsInv;
    Success = ManchesterDecodeBit((bool *)boolDataInv0, (bool*) boolAnsInv);
    if (Success)
    {
        pc.printf("TestManchester - decode - boolInv0 - Invalid format not caught\r\n");
    }
    Success = ManchesterDecodeBit((bool *)boolDataInv1, (bool*) boolAnsInv);
    if (Success)
    {
        pc.printf("TestManchester - decode - boolInv1 - Invalid format not caught\r\n");
    }
    
    
    bool charEncodeData[] = {1,0,1,0,0,1,1,0,0,1,1,0,0,1,1,0};
    char charEncodeExpected = 42;
    char charEncodeAns;
    Valid = ManchesterDecodeByte(charEncodeData, &charEncodeAns);
    
    if (!Valid)
    {
        pc.printf("Function detected error in format\r\n");
    }
    else if (charEncodeExpected != charEncodeAns)
    {
        pc.printf("TestManchester - decode - char - Failed\r\n");
        pc.printf("Expected: %d\t\tReceived: %d\r\n", 
        charEncodeExpected, charEncodeAns);
    }
    
    //--------------------TEST COMPLET -------------------------------//
    
    char charComplet = 158;
    bool tmpAns[16];
    char charCompletAns;
    
    ManchesterEncodeByte(charComplet, (bool *) tmpAns);
    Valid = ManchesterDecodeByte((bool *) tmpAns, &charCompletAns);
    
    if (!Valid)
    {
        pc.printf("Function detected error in format\r\n");   
    }
    if (charComplet != charCompletAns)
    {
        pc.printf("TestManchester - decode - complete - Failed\r\n");
        pc.printf("Expected: %d\t\tReceived: %d\r\n", 
        charComplet, charCompletAns);
    }
    
    pc.printf("TestManchester - End\r\n");
}