APP3 / Mbed 2 deprecated APP4

Dependencies:   mbed mbed-rtos

Revision:
3:7b1110501ef9
Parent:
2:1665cd4c922c
Child:
4:4277898e55d8
--- a/main.cpp	Mon Mar 06 08:00:37 2017 +0000
+++ b/main.cpp	Tue Mar 07 04:29:14 2017 +0000
@@ -1,22 +1,147 @@
 #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);
 
 //Mail<char (*) [256], 16> messageBox;
 Mail<char, 92 * 4> trameBox;
 
-bool ManchesterDecodeBit(bool* data, bool* out)
+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] = 0;
+        out[0] = 1;
     }
     else if (data[0] == 1 &&  data[1] == 0)
     {
-        out[0] = 1;
+        out[0] = 0;
     }
     else
     {
@@ -25,7 +150,7 @@
     return true;
 }
 
-bool ManchesterDecodeByte(bool* data, char* out)
+bool ManchesterDecodeByte(bool* data, char* out)    // Tested
 {
     bool Valid = true;
     bool tmp = true;
@@ -33,13 +158,13 @@
     {
         Valid = ManchesterDecodeBit(data, &tmp);
         data += 2;
-        if (tmp)
+        if (!tmp)
         {
-            *out = *out | (0x1 << (7-i));
+            *out = *out & ~(0x1 << (7-i));
         }
         else
         {
-            *out = *out & ~(0x1 << (7-i));
+            *out = *out | (0x1 << (7-i));
         }
         if (!Valid)
         {
@@ -49,32 +174,237 @@
     return true;
 }
 
-void ManchesterEncode(bool data, bool* out)
+void ManchesterEncodeBit(bool data, bool* out)         // Tested
 {
     if (data == 0)
     {
-        out[0] = 0;
-        out[1] = 1;
-    }
-    else
-    {
         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]));
+    }
 }
 
-void ManchesterEncode(char data, bool* out)
+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++)
     {
-        ManchesterEncode((bool) ((data >> (7 - i)) & 1), &(out[2*i]));
+        *data = STARTENDBOOL[i];
+        data++;
     }
 }
 
-void CreateAndSendTrame()
+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)
+{
+    // Synchronize with wire
+    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;
+    }
+}
 
 extern "C" void TIMER2_IRQHandler (void)
 {
@@ -97,39 +427,95 @@
     NVIC_EnableIRQ(TIMER2_IRQn);            //enable timer2 interrupt
     LPC_TIM2->TCR = 1;                      //enable Timer2
 }
+
 void TestManchester();
+void TestUtility();
 void mainRaph()
 {
     init_clk();
+    TestUtility();
     TestManchester();
+    SendText("OK", 2);
+    SendText("A more complex sentence to prove our algorithm is robust!", 57);
 }
 
 void tick()
 {
-    myled = !myled;   
+    myled = !myled;
 }
 int main() {
     Ticker ticker;
     ticker.attach(&tick, 0.5);
-    wait(2);
     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()
 {
-    printf("TestManchester - Begin\r\n");
+    pc.printf("TestManchester - Begin\r\n");
 
     // ----------------------------ENCODE-----------------------------------------------//
     bool Valid = true;
     bool boolData0 = (char) 0b0;
-    bool boolExpected0[] = {0,1};
+    bool boolExpected0[] = {1,0};
     bool boolAns0[2];
     
-    ManchesterEncode(boolData0, (bool *) boolAns0);
+    ManchesterEncodeBit(boolData0, (bool *) boolAns0);
     
     int i = 0;
     Valid = true;
@@ -141,14 +527,14 @@
     
     if (!Valid)
     {
-        printf("TestManchester - encode - bool0 - Failed\r\n");
-        printf("Expected: [%d, %d]. Received: [%d, %d].\r\n\n", boolExpected0[0], boolExpected0[1], boolAns0[0], boolAns0[1]);
+        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[] = {1,0};
+    bool boolExpected1[] = {0,1};
     bool boolAns1[2];
-    ManchesterEncode(boolData1, (bool*) boolAns1);
+    ManchesterEncodeBit(boolData1, (bool*) boolAns1);
     
     i = 0;
     Valid = true;
@@ -159,14 +545,14 @@
     }
     if (!Valid)
     {
-        printf("TestManchester - encode - boo11 - Failed\r\n");
-        printf("Expected: [%d, %d]. Received: [%d, %d].\r\n\n", boolExpected1[0], boolExpected1[1], boolAns1[0], boolAns1[1]);
+        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[] = {0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0};
+    bool charExpected[] = {1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1};
     bool charAns[16];
-    ManchesterEncode(charData, (bool*) charAns);
+    ManchesterEncodeByte(charData, (bool*) charAns);
     
     i = 0;
     Valid = true;
@@ -177,8 +563,8 @@
     }
     if (!Valid)
     {
-        printf("TestManchester - encode - char - Failed\r\n");
-        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", 
+        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],
@@ -191,7 +577,7 @@
     
     // ----------------------------DECODE-----------------------------------------------//
     Valid = true;
-    bool boolDecodeData0[] = {0,1};
+    bool boolDecodeData0[] = {1,0};
     bool boolDecodeExpected0 = 0b0;
     bool boolDecodeAns0;
     bool Success = true;
@@ -199,60 +585,80 @@
     
     if (!Success)
     {
-        printf("TestManchester - decode - bool0 - Invalid format\r\n");
+        pc.printf("TestManchester - decode - bool0 - Invalid format\r\n");
     }
     
     if (boolDecodeExpected0 != boolDecodeAns0)
     {
-        printf("TestManchester - decode - bool0 - Failed\r\n");
-        printf("Expected: %d. Received: %d.\r\n\n", boolDecodeExpected0,  boolDecodeAns0);
+        pc.printf("TestManchester - decode - bool0 - Failed\r\n");
+        pc.printf("Expected: %d. Received: %d.\r\n\n", boolDecodeExpected0,  boolDecodeAns0);
     } 
    
-    bool boolDecodeData1[] = {1,0};
+    bool boolDecodeData1[] = {0,1};
     bool boolDecodeExpected1 = (char) 0b1;
     bool boolDecodeAns1;
     Success = ManchesterDecodeBit((bool *)boolDecodeData1, &boolDecodeAns1);
     
     if (!Success)
     {
-        printf("TestManchester - decode - bool1 - Invalid format\r\n");
+        pc.printf("TestManchester - decode - bool1 - Invalid format\r\n");
     }
     if (boolDecodeExpected1 != boolDecodeAns1)
     {
-        printf("TestManchester - decode - boo11 - Failed\r\n");
-        printf("Expected: %d. Received: %d\r\n\n", 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[] = {0,0};
+    bool boolDataInv1[] = {1,1};
     bool boolAnsInv;
     Success = ManchesterDecodeBit((bool *)boolDataInv0, (bool*) boolAnsInv);
     if (Success)
     {
-        printf("TestManchester - decode - boolInv0 - Invalid format not caught\r\n");
+        pc.printf("TestManchester - decode - boolInv0 - Invalid format not caught\r\n");
     }
     Success = ManchesterDecodeBit((bool *)boolDataInv1, (bool*) boolAnsInv);
     if (Success)
     {
-        printf("TestManchester - decode - boolInv1 - Invalid format not caught\r\n");
+        pc.printf("TestManchester - decode - boolInv1 - Invalid format not caught\r\n");
     }
     
     
-    bool charEncodeData[] = {0,1,0,1,1,0,0,1,1,0,0,1,1,0,0,1};
+    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)
     {
-        printf("Function detected error in format\r\n");   
+        pc.printf("Function detected error in format\r\n");
     }
     else if (charEncodeExpected != charEncodeAns)
     {
-        printf("TestManchester - decode - char - Failed\r\n");
-        printf("Expected: %d\t\tReceived: %d\r\n", 
+        pc.printf("TestManchester - decode - char - Failed\r\n");
+        pc.printf("Expected: %d\t\tReceived: %d\r\n", 
         charEncodeExpected, charEncodeAns);
     }
     
-    printf("TestManchester - End\r\n");
+    //--------------------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");
 }
\ No newline at end of file