Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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");
}