app4
Dependencies: mbed-rtos mbed CRC16
Fork of S5info_APP2 by
main.cpp
- Committer:
- ericbisson
- Date:
- 2017-03-07
- Revision:
- 16:f2661759714c
- Parent:
- 15:7c2e70c36b98
- Child:
- 17:2b4b3f3a0489
File content as of revision 16:f2661759714c:
#include "CRC16.h" #include "mbed.h" #include "rtos.h" #include <vector> using std::vector; DigitalIn in(p30); Thread ThreadLecture; const int PREAMBULE = 0b01010101; const int START = 0b01111110; const int END = 0b01111110; Serial pc(USBTX, USBRX); DigitalOut out(p8); bool transmit = false; //faux pour le debut de demi-periode d'envoie d'un bit, vrai pour la 2ème demi-periode char trame_sent[80]; //tableau de la trame à envoyer uint8_t byte_sent_pos, //position de l'octet dans le tableau d'envoi bit_sent, //position du bit de l'octet en cours d'envoi (du MSB au LSB) 7..0 trame_length; //longueur de la trame complete void initTimers() { //Timer 1 (match) LPC_SC->PCLKSEL0 |= (1 << 4); // pclk = cclk timer1 LPC_SC->PCONP |= (1 << 2); // timer1 power on LPC_TIM1->MR0 = 960000; // 100 ms LPC_TIM1->MCR = 3; // interrupt and reset control LPC_TIM1->EMR = (3 << 4); // Interrupt & reset timer on match NVIC_EnableIRQ(TIMER1_IRQn); // enable timer interrupt LPC_TIM1->TCR = 1; // enable Timer //Timer 2 (cap) LPC_SC->PCLKSEL1 |= (1 << 12); // pclk = cclk timer2 LPC_SC->PCONP |= (1 << 22); // timer2 power on LPC_TIM2->TC = 0; // clear timer counter LPC_TIM2->PC = 0; // clear prescale counter LPC_TIM2->PR = 0; // clear prescale register LPC_TIM2->TCR |= (1 << 1); // reset timer LPC_TIM2->TCR &= ~(1 << 1); // release reset LPC_TIM2->IR = 0xFFFFFFFF; // clear interrupt register LPC_TIM2->CCR |= 0x0000007; // enable rising-edge and falling-edge capture NVIC_EnableIRQ(TIMER2_IRQn); // enable timer interrupt LPC_TIM2->TCR = 1; // start Timer } bool bTimer1 = false; extern "C" void TIMER1_IRQHandler() { if ((LPC_TIM1->IR & 0x01) == 0x01) { bTimer1 = !bTimer1; LPC_TIM1->IR |= 1 << 0; // clear } } int sumClocks = 0; int PeriodLength = 0; bool bReceivedFirstBit = false; extern "C" void TIMER2_IRQHandler() { if (PeriodLength > 0) { if (LPC_TIM2->CR0 >= PeriodLength*1.5 || (sumClocks + LPC_TIM2->CR0) >= PeriodLength*1.5) { sumClocks = 0; ThreadLecture.signal_set(1); } else { sumClocks += LPC_TIM2->CR0; } } else if (bReceivedFirstBit) { PeriodLength = LPC_TIM2->CR0 / 2; ThreadLecture.signal_set(1); } else { bReceivedFirstBit = true; ThreadLecture.signal_set(1); } LPC_TIM2->TC = 0; LPC_TIM2->IR |= 0xFFFFFFFF; // clear } bool codeManchester(bool bit, bool clock) { return (bit == clock); } void send_data() { out = codeManchester(((trame_sent[byte_sent_pos] >> bit_sent) & 0x01), bTimer1); // Encodage Manchester if(bTimer1) { bit_sent--; } bTimer1 = !bTimer1; //varier entre la 1ere et 2eme partie de demi-periode if (bit_sent < 0) { //Si l'octet a ete envoye bit_sent = 7; //remettre la position initiale pour le prochain octet byte_sent_pos++; //incrementer l'octet if (byte_sent_pos >= trame_length) { //Si la trame a ete envoyee byte_sent_pos = 0; bTimer1 = false; } } } //création de la trame void create_trame(char message[],int taille) { CRC16 *myCRC = new CRC16(); unsigned short resultCRC = myCRC->calculateCRC16(message,taille); trame_sent[0] = 0x55; //Preambule trame_sent[1] = 0x7E; //Start trame_sent[2] = 0x00; //Type + Flag mis a 0x00 trame_sent[3] = (char)taille; //Longueur du message (Max 33 caractères) //message for (int i=0;i<taille;i++) { trame_sent[taille + 4] = message[i]; } //CRC16 trame_sent[taille + 4] = (resultCRC >> 8) & 0xFF; trame_sent[taille + 5] = resultCRC & 0xFF; trame_sent[taille + 6] = 0x7E; //End trame_length = taille + 7; //Longueur de la trame } //obtention du texte void get_text() { pc.printf("\n\rYour text : "); int count = 0; char c = 0x00; char text[73]; while(c != 0x0D && count < 73) { //Tant que c'est different de '\r' et pour un maximum de 73 caractères c = pc.getc(); text[count] = c; pc.putc(c); count++; } create_trame(text,count); } void write() { byte_sent_pos = 0; bit_sent = 7; bTimer1 = false; //TODO start interrupt timer 1 //LPC_RIT->MCR = 1; //Permettre les interruption du MAT //LPC_RIT->MR0 = LPC_RIT->TC + HALF_PERIOD; //Faire une interruption a la prochaine demi-periode } void read() { char byte = 0; vector<char> bytes; char shift = 0; char totalsize = 7; while (true) { ThreadLecture.signal_wait(1); byte = (byte << 1) + !in; // inversion car 2e période shift++; if (shift == 8) { shift = 0; // à partir d'ici, je travaille en byte et non bit bytes.push_back(byte); // Validations de base if ((bytes.size() == 1 && bytes[0] != PREAMBULE) || (bytes.size() == 2 && bytes[1] != START)) { bytes.clear(); } if (bytes.size() == 3) { totalsize = 7 + bytes[2]; } // fin if (totalsize == bytes.size()) { // Calcul du CRC unsigned short currentCRC = bytes[bytes.size()-2] + bytes[bytes.size()-3]<<8; vector<char> charge_utile(&bytes[4], &bytes[bytes.size()-4]); if (currentCRC == mycrc16.calculateCRC16(&charge_utile[0], charge_utile.size()) && bytes.back() == END) { // Affiche à l'écran le message valide pc.printf(&charge_utile[0], charge_utile.size()); } bytes.clear(); } } } } int main() { LPC_PINCON->PINSEL0 |= (3 << 8); // pin30 initTimers(); ThreadLecture.start(read); while(true) { } };