APP 4
Dependencies: mbed CRC16 mbed-rtos
APP.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 "APP.h" #include "Manchester.h" #include "Frame.h" #include "MEF.h" // Interfaces d'entrée-sortie Serial pc(USBTX, USBRX); DigitalOut out(p8); DigitalIn in(p30); // Variables globales bitset<FRAMESIZE> frameToSend; // Contient la trame à envoyer bitset<MAX_DATA> decodedFrame; // Contient la trame reçue (seulement les données utiles) int counter = 0; // Compteur pour l'envoi de la trame int payloadSize = 0; // Taille du message reçu (en octets) bool clockTick = false; // Simule une horloge pour l'encodage Manchester bool dataReady; // Indique si un message complet à été reçu bool frameDropped; // Indique si un message a été ignoré à cause d'une erreur bool firstBit = true; // Indique s'il s'agit du premier bit reçu (pour calcul de la période) bool periodCalculated = false; // Indique si la période a été calculée unsigned int period = 0; // Contient la période calculée unsigned int currentClocks = 0; // Contient le nombre de coups d'horloge depuis le dernier interrupt MEF mef; // Machine à états finis STATES mefSTATE; // État de la MEF char* message = "Bonjour Domingo\r\n"; // Message à envoyer int messageLength = 17; // Longueur en octets de ce message #if DEBUG bool debugBitReady = false; bool debugBit = false; STATES debugState = NOSTATE; #endif // Fonction appelée par l'interrupt du Timer1 extern "C" void TIMER1_IRQHandler() { if ((LPC_TIM1->IR & 0x01) == 0x01) // if MR0 interrupt, proceed { clockTick = !clockTick; out = encode(frameToSend[counter], clockTick); // Encodage Manchester if (clockTick) { counter++; } if (counter >= 56+messageLength*8) // Longueur totale, incluant les headers et les données utiles { counter = 0; } LPC_TIM1->IR |= 1 << 0; // Clear MR0 interrupt flag } } // Fonction appelée par l'interrupt du Timer2 extern "C" void TIMER2_IRQHandler() { unsigned int clocks = LPC_TIM2->CR0; bool inputValue = in.read(); // Ignorer le premier bit pour la période if (!periodCalculated && !firstBit) { period = clocks / 2; periodCalculated = true; } if (firstBit) { #if DEBUG debugBitReady = true; debugBit = !inputValue; #endif // Envoi à la MEF mef.ReceiveBit(!inputValue); firstBit = false; } if (periodCalculated) { // Si une ou deux périodes se sont écoulées depuis le dernier interrupt if (clocks >= period*1.5 || (currentClocks + clocks) >= period*1.5) { #if DEBUG debugBitReady = true; debugBit = !inputValue; #endif // Envoi à la MEF mef.ReceiveBit(!inputValue); currentClocks = 0; } else { currentClocks += clocks; } } LPC_TIM2->TC = 0; // clear Timer counter LPC_TIM2->IR |= 0xFFFFFFFF; // clear Timer interrupt register } // Fonction d'initialisation des Timers void initTimers() { //Timer 1 (match) LPC_SC->PCLKSEL0 |= (1 << 4); // pclk = cclk timer1 LPC_SC->PCONP |= (1 << 2); // timer1 power on LPC_TIM1->MR0 = CLOCKS_TO_SECOND / 100; // 100 ms LPC_TIM1->MCR = 3; // interrupt and reset control // Interrupt & reset timer on match LPC_TIM1->EMR = (3 << 4); 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 on 2.0 NVIC_EnableIRQ(TIMER2_IRQn); // enable timer interrupt LPC_TIM2->TCR = 1; // start Timer } // Fonction principale int main() { // Trame à envoyer frameToSend = buildFrame(convertToBits(message, messageLength), messageLength); LPC_PINCON->PINSEL0 |= (3 << 8); // P0.4 = CAP2.0, correspond à la pin30 initTimers(); while (true) { if (dataReady) { // Affichage en console des données reçues for (int i = 0; i < payloadSize * 8; i++) { if((i + 1) % 8 == 0) { char ascii = (decodedFrame[i] << 0) | (decodedFrame[i - 1] << 1) | (decodedFrame[i - 2] << 2) | (decodedFrame[i - 3] << 3) | (decodedFrame[i - 4] << 4) | (decodedFrame[i - 5] << 5) | (decodedFrame[i - 6] << 6) | (decodedFrame[i - 7] << 7); pc.printf("%c", ascii); } } dataReady = false; } #if DEBUG // Affichage des informations de debug debugPrint(); #endif } } // Fonction de callback pour le décodage des messages void _decodeCallback(bitset<MAX_DATA> decMessage, int size) { decodedFrame = decMessage; payloadSize = size; dataReady = true; } // Fonction de callback dans le cas d'une erreur de trame void _decodeError() { frameDropped = true; periodCalculated = false; period = 0; } // Fonction de mise à jour de l'état de la MEF void _updateState(STATES state) { mefSTATE = state; } #if DEBUG void debugPrint() { if (debugState != mefSTATE) { pc.printf("\r\nNew state: %i \r\n", mefSTATE); debugState = mefSTATE; } if(frameDropped) { pc.printf("Frame dropped\r\n"); frameDropped = false; } if(debugMessageReady) { pc.printf("%i\r\n", debugMessage); debugMessageReady = false; } if (debugBitReady) { pc.printf("%i ", debugBit); debugBitReady = false; } } #endif