APP 4
Dependencies: mbed CRC16 mbed-rtos
APP.cpp@27:011ad1667040, 2016-02-23 (annotated)
- Committer:
- manl2003
- Date:
- Tue Feb 23 21:15:05 2016 +0000
- Revision:
- 27:011ad1667040
- Parent:
- 26:f2b37f9dfca9
Tout beau, mef inclue.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
vinbel93 | 26:f2b37f9dfca9 | 1 | // Vincent Bélanger et Laurent Mandrile |
vinbel93 | 26:f2b37f9dfca9 | 2 | // belv1802 - manl2003 |
vinbel93 | 26:f2b37f9dfca9 | 3 | |
manl2003 | 2:1250280a511b | 4 | #include "APP.h" |
vinbel93 | 3:3ffa14e75b8a | 5 | #include "Manchester.h" |
vinbel93 | 9:b937f9c6d682 | 6 | #include "Frame.h" |
vinbel93 | 14:9505b98c6623 | 7 | #include "MEF.h" |
vinbel93 | 0:ac5e42371639 | 8 | |
vinbel93 | 26:f2b37f9dfca9 | 9 | // Interfaces d'entrée-sortie |
vinbel93 | 0:ac5e42371639 | 10 | Serial pc(USBTX, USBRX); |
vinbel93 | 13:195826b8c61b | 11 | DigitalOut out(p8); |
vinbel93 | 13:195826b8c61b | 12 | DigitalIn in(p30); |
vinbel93 | 0:ac5e42371639 | 13 | |
vinbel93 | 26:f2b37f9dfca9 | 14 | // Variables globales |
vinbel93 | 26:f2b37f9dfca9 | 15 | bitset<FRAMESIZE> frameToSend; // Contient la trame à envoyer |
vinbel93 | 26:f2b37f9dfca9 | 16 | bitset<MAX_DATA> decodedFrame; // Contient la trame reçue (seulement les données utiles) |
vinbel93 | 26:f2b37f9dfca9 | 17 | int counter = 0; // Compteur pour l'envoi de la trame |
vinbel93 | 26:f2b37f9dfca9 | 18 | int payloadSize = 0; // Taille du message reçu (en octets) |
vinbel93 | 26:f2b37f9dfca9 | 19 | bool clockTick = false; // Simule une horloge pour l'encodage Manchester |
vinbel93 | 26:f2b37f9dfca9 | 20 | bool dataReady; // Indique si un message complet à été reçu |
vinbel93 | 26:f2b37f9dfca9 | 21 | bool frameDropped; // Indique si un message a été ignoré à cause d'une erreur |
vinbel93 | 26:f2b37f9dfca9 | 22 | bool firstBit = true; // Indique s'il s'agit du premier bit reçu (pour calcul de la période) |
vinbel93 | 0:ac5e42371639 | 23 | |
vinbel93 | 26:f2b37f9dfca9 | 24 | bool periodCalculated = false; // Indique si la période a été calculée |
vinbel93 | 26:f2b37f9dfca9 | 25 | unsigned int period = 0; // Contient la période calculée |
vinbel93 | 26:f2b37f9dfca9 | 26 | unsigned int currentClocks = 0; // Contient le nombre de coups d'horloge depuis le dernier interrupt |
vinbel93 | 26:f2b37f9dfca9 | 27 | MEF mef; // Machine à états finis |
vinbel93 | 26:f2b37f9dfca9 | 28 | STATES mefSTATE; // État de la MEF |
vinbel93 | 0:ac5e42371639 | 29 | |
vinbel93 | 26:f2b37f9dfca9 | 30 | char* message = "Bonjour Domingo\r\n"; // Message à envoyer |
vinbel93 | 26:f2b37f9dfca9 | 31 | int messageLength = 17; // Longueur en octets de ce message |
vinbel93 | 26:f2b37f9dfca9 | 32 | |
vinbel93 | 26:f2b37f9dfca9 | 33 | #if DEBUG |
vinbel93 | 26:f2b37f9dfca9 | 34 | bool debugBitReady = false; |
vinbel93 | 26:f2b37f9dfca9 | 35 | bool debugBit = false; |
vinbel93 | 26:f2b37f9dfca9 | 36 | STATES debugState = NOSTATE; |
vinbel93 | 26:f2b37f9dfca9 | 37 | #endif |
vinbel93 | 26:f2b37f9dfca9 | 38 | |
vinbel93 | 26:f2b37f9dfca9 | 39 | // Fonction appelée par l'interrupt du Timer1 |
vinbel93 | 13:195826b8c61b | 40 | extern "C" void TIMER1_IRQHandler() |
vinbel93 | 0:ac5e42371639 | 41 | { |
vinbel93 | 13:195826b8c61b | 42 | if ((LPC_TIM1->IR & 0x01) == 0x01) // if MR0 interrupt, proceed |
vinbel93 | 0:ac5e42371639 | 43 | { |
vinbel93 | 6:3181f546e812 | 44 | clockTick = !clockTick; |
vinbel93 | 26:f2b37f9dfca9 | 45 | out = encode(frameToSend[counter], clockTick); // Encodage Manchester |
vinbel93 | 6:3181f546e812 | 46 | |
vinbel93 | 6:3181f546e812 | 47 | if (clockTick) |
vinbel93 | 0:ac5e42371639 | 48 | { |
vinbel93 | 6:3181f546e812 | 49 | counter++; |
vinbel93 | 0:ac5e42371639 | 50 | } |
vinbel93 | 6:3181f546e812 | 51 | |
vinbel93 | 26:f2b37f9dfca9 | 52 | if (counter >= 56+messageLength*8) // Longueur totale, incluant les headers et les données utiles |
vinbel93 | 0:ac5e42371639 | 53 | { |
manl2003 | 23:d41a23d8f2d7 | 54 | counter = 0; |
vinbel93 | 0:ac5e42371639 | 55 | } |
manl2003 | 23:d41a23d8f2d7 | 56 | |
manl2003 | 23:d41a23d8f2d7 | 57 | LPC_TIM1->IR |= 1 << 0; // Clear MR0 interrupt flag |
vinbel93 | 0:ac5e42371639 | 58 | } |
vinbel93 | 0:ac5e42371639 | 59 | } |
vinbel93 | 13:195826b8c61b | 60 | |
vinbel93 | 26:f2b37f9dfca9 | 61 | // Fonction appelée par l'interrupt du Timer2 |
vinbel93 | 13:195826b8c61b | 62 | extern "C" void TIMER2_IRQHandler() |
manl2003 | 10:51ee22e230c7 | 63 | { |
vinbel93 | 13:195826b8c61b | 64 | unsigned int clocks = LPC_TIM2->CR0; |
vinbel93 | 20:f0932bfe09ed | 65 | bool inputValue = in.read(); |
manl2003 | 10:51ee22e230c7 | 66 | |
vinbel93 | 26:f2b37f9dfca9 | 67 | // Ignorer le premier bit pour la période |
vinbel93 | 20:f0932bfe09ed | 68 | if (!periodCalculated && !firstBit) |
vinbel93 | 13:195826b8c61b | 69 | { |
vinbel93 | 20:f0932bfe09ed | 70 | period = clocks / 2; |
vinbel93 | 20:f0932bfe09ed | 71 | periodCalculated = true; |
vinbel93 | 13:195826b8c61b | 72 | } |
vinbel93 | 20:f0932bfe09ed | 73 | |
vinbel93 | 20:f0932bfe09ed | 74 | if (firstBit) |
vinbel93 | 13:195826b8c61b | 75 | { |
vinbel93 | 26:f2b37f9dfca9 | 76 | #if DEBUG |
vinbel93 | 26:f2b37f9dfca9 | 77 | debugBitReady = true; |
vinbel93 | 26:f2b37f9dfca9 | 78 | debugBit = !inputValue; |
vinbel93 | 26:f2b37f9dfca9 | 79 | #endif |
vinbel93 | 26:f2b37f9dfca9 | 80 | // Envoi à la MEF |
vinbel93 | 20:f0932bfe09ed | 81 | mef.ReceiveBit(!inputValue); |
vinbel93 | 20:f0932bfe09ed | 82 | firstBit = false; |
vinbel93 | 13:195826b8c61b | 83 | } |
manl2003 | 10:51ee22e230c7 | 84 | |
vinbel93 | 20:f0932bfe09ed | 85 | if (periodCalculated) |
vinbel93 | 20:f0932bfe09ed | 86 | { |
vinbel93 | 26:f2b37f9dfca9 | 87 | // Si une ou deux périodes se sont écoulées depuis le dernier interrupt |
vinbel93 | 20:f0932bfe09ed | 88 | if (clocks >= period*1.5 || (currentClocks + clocks) >= period*1.5) |
vinbel93 | 20:f0932bfe09ed | 89 | { |
vinbel93 | 26:f2b37f9dfca9 | 90 | #if DEBUG |
vinbel93 | 26:f2b37f9dfca9 | 91 | debugBitReady = true; |
vinbel93 | 26:f2b37f9dfca9 | 92 | debugBit = !inputValue; |
vinbel93 | 26:f2b37f9dfca9 | 93 | #endif |
vinbel93 | 26:f2b37f9dfca9 | 94 | // Envoi à la MEF |
vinbel93 | 26:f2b37f9dfca9 | 95 | mef.ReceiveBit(!inputValue); |
vinbel93 | 20:f0932bfe09ed | 96 | currentClocks = 0; |
vinbel93 | 20:f0932bfe09ed | 97 | } |
vinbel93 | 20:f0932bfe09ed | 98 | else |
vinbel93 | 20:f0932bfe09ed | 99 | { |
vinbel93 | 20:f0932bfe09ed | 100 | currentClocks += clocks; |
vinbel93 | 20:f0932bfe09ed | 101 | } |
vinbel93 | 20:f0932bfe09ed | 102 | } |
vinbel93 | 20:f0932bfe09ed | 103 | |
vinbel93 | 26:f2b37f9dfca9 | 104 | LPC_TIM2->TC = 0; // clear Timer counter |
vinbel93 | 13:195826b8c61b | 105 | LPC_TIM2->IR |= 0xFFFFFFFF; // clear Timer interrupt register |
vinbel93 | 13:195826b8c61b | 106 | } |
vinbel93 | 13:195826b8c61b | 107 | |
vinbel93 | 26:f2b37f9dfca9 | 108 | // Fonction d'initialisation des Timers |
manl2003 | 7:733d500dbe5c | 109 | void initTimers() |
vinbel93 | 0:ac5e42371639 | 110 | { |
vinbel93 | 13:195826b8c61b | 111 | //Timer 1 (match) |
vinbel93 | 13:195826b8c61b | 112 | LPC_SC->PCLKSEL0 |= (1 << 4); // pclk = cclk timer1 |
manl2003 | 10:51ee22e230c7 | 113 | LPC_SC->PCONP |= (1 << 2); // timer1 power on |
manl2003 | 23:d41a23d8f2d7 | 114 | LPC_TIM1->MR0 = CLOCKS_TO_SECOND / 100; // 100 ms |
manl2003 | 10:51ee22e230c7 | 115 | LPC_TIM1->MCR = 3; // interrupt and reset control |
vinbel93 | 13:195826b8c61b | 116 | // Interrupt & reset timer on match |
vinbel93 | 13:195826b8c61b | 117 | LPC_TIM1->EMR = (3 << 4); |
vinbel93 | 13:195826b8c61b | 118 | NVIC_EnableIRQ(TIMER1_IRQn); // enable timer interrupt |
vinbel93 | 13:195826b8c61b | 119 | LPC_TIM1->TCR = 1; // enable Timer |
vinbel93 | 13:195826b8c61b | 120 | |
vinbel93 | 13:195826b8c61b | 121 | //Timer 2 (cap) |
vinbel93 | 13:195826b8c61b | 122 | LPC_SC->PCLKSEL1 |= (1 << 12); // pclk = cclk timer2 |
vinbel93 | 13:195826b8c61b | 123 | LPC_SC->PCONP |= (1 << 22); // timer2 power on |
vinbel93 | 13:195826b8c61b | 124 | LPC_TIM2->TC = 0; // clear timer counter |
vinbel93 | 13:195826b8c61b | 125 | LPC_TIM2->PC = 0; // clear prescale counter |
vinbel93 | 13:195826b8c61b | 126 | LPC_TIM2->PR = 0; // clear prescale register |
vinbel93 | 13:195826b8c61b | 127 | LPC_TIM2->TCR |= (1 << 1); // reset timer |
vinbel93 | 13:195826b8c61b | 128 | LPC_TIM2->TCR &= ~(1 << 1); // release reset |
vinbel93 | 13:195826b8c61b | 129 | LPC_TIM2->IR = 0xFFFFFFFF; // clear interrupt register |
vinbel93 | 13:195826b8c61b | 130 | LPC_TIM2->CCR |= 0x0000007; // enable rising-edge and falling-edge capture on 2.0 |
vinbel93 | 13:195826b8c61b | 131 | NVIC_EnableIRQ(TIMER2_IRQn); // enable timer interrupt |
vinbel93 | 13:195826b8c61b | 132 | LPC_TIM2->TCR = 1; // start Timer |
vinbel93 | 0:ac5e42371639 | 133 | } |
vinbel93 | 0:ac5e42371639 | 134 | |
vinbel93 | 26:f2b37f9dfca9 | 135 | // Fonction principale |
vinbel93 | 1:f212b6676849 | 136 | int main() |
vinbel93 | 0:ac5e42371639 | 137 | { |
vinbel93 | 26:f2b37f9dfca9 | 138 | // Trame à envoyer |
vinbel93 | 26:f2b37f9dfca9 | 139 | frameToSend = buildFrame(convertToBits(message, messageLength), messageLength); |
vinbel93 | 9:b937f9c6d682 | 140 | |
vinbel93 | 26:f2b37f9dfca9 | 141 | LPC_PINCON->PINSEL0 |= (3 << 8); // P0.4 = CAP2.0, correspond à la pin30 |
manl2003 | 8:60499583959f | 142 | initTimers(); |
manl2003 | 23:d41a23d8f2d7 | 143 | |
vinbel93 | 3:3ffa14e75b8a | 144 | while (true) |
vinbel93 | 0:ac5e42371639 | 145 | { |
vinbel93 | 15:ed9511c3aac6 | 146 | if (dataReady) |
vinbel93 | 15:ed9511c3aac6 | 147 | { |
vinbel93 | 26:f2b37f9dfca9 | 148 | // Affichage en console des données reçues |
vinbel93 | 20:f0932bfe09ed | 149 | for (int i = 0; i < payloadSize * 8; i++) |
vinbel93 | 20:f0932bfe09ed | 150 | { |
vinbel93 | 20:f0932bfe09ed | 151 | if((i + 1) % 8 == 0) |
vinbel93 | 20:f0932bfe09ed | 152 | { |
vinbel93 | 26:f2b37f9dfca9 | 153 | 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); |
vinbel93 | 26:f2b37f9dfca9 | 154 | pc.printf("%c", ascii); |
vinbel93 | 20:f0932bfe09ed | 155 | } |
vinbel93 | 20:f0932bfe09ed | 156 | } |
vinbel93 | 20:f0932bfe09ed | 157 | dataReady = false; |
vinbel93 | 15:ed9511c3aac6 | 158 | } |
vinbel93 | 26:f2b37f9dfca9 | 159 | |
manl2003 | 23:d41a23d8f2d7 | 160 | #if DEBUG |
vinbel93 | 26:f2b37f9dfca9 | 161 | // Affichage des informations de debug |
manl2003 | 23:d41a23d8f2d7 | 162 | debugPrint(); |
manl2003 | 23:d41a23d8f2d7 | 163 | #endif |
vinbel93 | 0:ac5e42371639 | 164 | } |
vinbel93 | 0:ac5e42371639 | 165 | } |
manl2003 | 12:715af3660c73 | 166 | |
vinbel93 | 26:f2b37f9dfca9 | 167 | // Fonction de callback pour le décodage des messages |
vinbel93 | 20:f0932bfe09ed | 168 | void _decodeCallback(bitset<MAX_DATA> decMessage, int size) |
manl2003 | 12:715af3660c73 | 169 | { |
vinbel93 | 26:f2b37f9dfca9 | 170 | decodedFrame = decMessage; |
vinbel93 | 20:f0932bfe09ed | 171 | payloadSize = size; |
vinbel93 | 17:8d8c33bdcaf5 | 172 | dataReady = true; |
manl2003 | 12:715af3660c73 | 173 | } |
manl2003 | 12:715af3660c73 | 174 | |
vinbel93 | 26:f2b37f9dfca9 | 175 | // Fonction de callback dans le cas d'une erreur de trame |
vinbel93 | 14:9505b98c6623 | 176 | void _decodeError() |
manl2003 | 12:715af3660c73 | 177 | { |
manl2003 | 12:715af3660c73 | 178 | frameDropped = true; |
manl2003 | 23:d41a23d8f2d7 | 179 | periodCalculated = false; |
manl2003 | 23:d41a23d8f2d7 | 180 | period = 0; |
vinbel93 | 17:8d8c33bdcaf5 | 181 | } |
vinbel93 | 17:8d8c33bdcaf5 | 182 | |
vinbel93 | 26:f2b37f9dfca9 | 183 | // Fonction de mise à jour de l'état de la MEF |
manl2003 | 16:cf433716f8d6 | 184 | void _updateState(STATES state) |
manl2003 | 16:cf433716f8d6 | 185 | { |
vinbel93 | 18:493a5aa7e4ec | 186 | mefSTATE = state; |
vinbel93 | 18:493a5aa7e4ec | 187 | } |
vinbel93 | 18:493a5aa7e4ec | 188 | |
vinbel93 | 26:f2b37f9dfca9 | 189 | #if DEBUG |
manl2003 | 23:d41a23d8f2d7 | 190 | void debugPrint() |
manl2003 | 23:d41a23d8f2d7 | 191 | { |
vinbel93 | 26:f2b37f9dfca9 | 192 | if (debugState != mefSTATE) |
manl2003 | 23:d41a23d8f2d7 | 193 | { |
manl2003 | 23:d41a23d8f2d7 | 194 | pc.printf("\r\nNew state: %i \r\n", mefSTATE); |
vinbel93 | 26:f2b37f9dfca9 | 195 | debugState = mefSTATE; |
manl2003 | 23:d41a23d8f2d7 | 196 | } |
manl2003 | 23:d41a23d8f2d7 | 197 | if(frameDropped) |
manl2003 | 23:d41a23d8f2d7 | 198 | { |
manl2003 | 23:d41a23d8f2d7 | 199 | pc.printf("Frame dropped\r\n"); |
manl2003 | 23:d41a23d8f2d7 | 200 | frameDropped = false; |
manl2003 | 23:d41a23d8f2d7 | 201 | } |
manl2003 | 23:d41a23d8f2d7 | 202 | if(debugMessageReady) |
manl2003 | 23:d41a23d8f2d7 | 203 | { |
manl2003 | 23:d41a23d8f2d7 | 204 | pc.printf("%i\r\n", debugMessage); |
manl2003 | 23:d41a23d8f2d7 | 205 | debugMessageReady = false; |
manl2003 | 23:d41a23d8f2d7 | 206 | } |
manl2003 | 23:d41a23d8f2d7 | 207 | |
vinbel93 | 26:f2b37f9dfca9 | 208 | if (debugBitReady) |
manl2003 | 23:d41a23d8f2d7 | 209 | { |
vinbel93 | 26:f2b37f9dfca9 | 210 | pc.printf("%i ", debugBit); |
vinbel93 | 26:f2b37f9dfca9 | 211 | debugBitReady = false; |
manl2003 | 23:d41a23d8f2d7 | 212 | } |
manl2003 | 23:d41a23d8f2d7 | 213 | } |
vinbel93 | 26:f2b37f9dfca9 | 214 | #endif |