Add CRC16 library

Dependencies:   CRC16 mbed-rtos mbed

Fork of S5info_APP4 by Éric Bisson

Committer:
JoeyDionne
Date:
Tue Mar 07 00:31:52 2017 +0000
Revision:
9:edf45585032a
Parent:
8:177b2370528b
Write code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ericbisson 7:5501dbea5650 1 #include "mbed.h"
ericbisson 0:c637467eeb8f 2 #include "rtos.h"
ericbisson 7:5501dbea5650 3 #include <string>
ericbisson 7:5501dbea5650 4 #include "bit.h"
JoeyDionne 8:177b2370528b 5 #include "CRC16.h"
ericbisson 7:5501dbea5650 6 using std::string;
ericbisson 1:b3ae0d9f02ad 7
ericbisson 7:5501dbea5650 8 #define PREAMBULE 0b01010101
ericbisson 7:5501dbea5650 9 const char START = 0b01111110;
ericbisson 7:5501dbea5650 10 const char END = 0b01111110;
ericbisson 7:5501dbea5650 11 const char FLAGS = 0x00;
ericbisson 7:5501dbea5650 12 const char MAX_LENGTH = 80;
ericbisson 7:5501dbea5650 13 const float HALF_PERIOD = 0.0005; // secondes
ericbisson 2:c6465d4e82d2 14
ericbisson 7:5501dbea5650 15 Serial pc(USBTX, USBRX, 9600);
ericbisson 7:5501dbea5650 16 Serial uart(p13, p14, 9600);
ericbisson 7:5501dbea5650 17 DigitalOut myled1(LED1);
ericbisson 7:5501dbea5650 18 DigitalOut myled2(LED2);
ericbisson 7:5501dbea5650 19 InterruptIn read_pin(p14);
ericbisson 7:5501dbea5650 20 Thread* thread;
ericbisson 2:c6465d4e82d2 21
JoeyDionne 9:edf45585032a 22 bool transmit = false; //faux pour le debut de demi-periode d'envoie d'un bit, vrai pour la 2ème demi-periode
JoeyDionne 9:edf45585032a 23 char trame_sent[80]; //tableau de la trame à envoyer
JoeyDionne 9:edf45585032a 24 uint8_t byte_sent_pos, //position de l'octet dans le tableau d'envoi
JoeyDionne 9:edf45585032a 25 bit_sent, //position du bit de l'octet en cours d'envoi (du MSB au LSB) 7..0
JoeyDionne 9:edf45585032a 26 trame_length; //longueur de la trame complete
JoeyDionne 9:edf45585032a 27
ericbisson 7:5501dbea5650 28 bool bIsHalfPeriod = false;
JoeyDionne 9:edf45585032a 29
JoeyDionne 9:edf45585032a 30 //TODO (Erase when not usefull anymore, timer handling read and write)
JoeyDionne 9:edf45585032a 31 /*extern "C" void TIMER2_IRQHandler (void)
JoeyDionne 9:edf45585032a 32 {
JoeyDionne 9:edf45585032a 33 if((LPC_TIM2->IR & 0x01) == 0x01) { //Si il y a interruption par le MAT
JoeyDionne 9:edf45585032a 34 LPC_TIM2->IR &= ~(1 << 0); //Nettoyer le drapeau de l'interruption du MR0
JoeyDionne 9:edf45585032a 35 send_data();
JoeyDionne 9:edf45585032a 36 }
JoeyDionne 9:edf45585032a 37 else if (((LPC_TIM2->IR >> 4) & 0x01) == 0x01) { //Si il y a interruption du CAP
JoeyDionne 9:edf45585032a 38 LPC_TIM2->IR &= ~(1 << 4); //Nettoyer le drapeau de l'interruption du CR0
JoeyDionne 9:edf45585032a 39 receive_data();
JoeyDionne 9:edf45585032a 40 }
JoeyDionne 9:edf45585032a 41 }*/
ericbisson 1:b3ae0d9f02ad 42
ericbisson 7:5501dbea5650 43 void p14_interrupt()
ericbisson 7:5501dbea5650 44 {
ericbisson 7:5501dbea5650 45 // On envoie le signal au thread de lecture
ericbisson 7:5501dbea5650 46 thread->signal_set(1);
ericbisson 2:c6465d4e82d2 47
ericbisson 7:5501dbea5650 48 // On turn off les interrupts de lecture une fois qu'on a détecter un message
ericbisson 7:5501dbea5650 49 read_pin.disable_irq();
ericbisson 7:5501dbea5650 50 };
ericbisson 1:b3ae0d9f02ad 51
ericbisson 7:5501dbea5650 52 void read()
ericbisson 7:5501dbea5650 53 {
ericbisson 7:5501dbea5650 54 while(true)
ericbisson 7:5501dbea5650 55 {
ericbisson 7:5501dbea5650 56 thread->signal_wait(1);
ericbisson 2:c6465d4e82d2 57
ericbisson 7:5501dbea5650 58 // TODO: mettre ici le code pour la lecture de trame
ericbisson 7:5501dbea5650 59 myled2 = !myled2;
ericbisson 2:c6465d4e82d2 60
ericbisson 7:5501dbea5650 61 // Une fois fini, on réactive l'interrupt de lecture
ericbisson 7:5501dbea5650 62 read_pin.enable_irq();
ericbisson 1:b3ae0d9f02ad 63 }
ericbisson 7:5501dbea5650 64 };
ericbisson 3:3ecbcc05bc85 65
ericbisson 7:5501dbea5650 66 void rit_init()
ericbisson 4:87e9b434bb4d 67 {
ericbisson 7:5501dbea5650 68 LPC_SC->PCONP |= bit16; //Power Control for Peripherals register: power up RIT clock
ericbisson 7:5501dbea5650 69 LPC_SC->PCLKSEL1 |= (bit26 && bit27); //Peripheral clock selection: divide clock by 8 (run RIT clock by 12.5MHz)
ericbisson 7:5501dbea5650 70 LPC_RIT->RICOUNTER = 0; //set counter to zero
ericbisson 7:5501dbea5650 71 LPC_RIT->RICOMPVAL = 1000000000 * HALF_PERIOD; //interrupt tick every HALF_PERIOD
ericbisson 7:5501dbea5650 72 LPC_RIT->RICTRL |= bit1; // clear timer when counter reaches value
ericbisson 7:5501dbea5650 73 LPC_RIT->RICTRL |= bit3; // enable timer
ericbisson 7:5501dbea5650 74
ericbisson 7:5501dbea5650 75 //enable interrupt
ericbisson 7:5501dbea5650 76 NVIC_SetPriority(RIT_IRQn, 31);
ericbisson 7:5501dbea5650 77 NVIC_EnableIRQ(RIT_IRQn);
ericbisson 7:5501dbea5650 78 };
ericbisson 4:87e9b434bb4d 79
JoeyDionne 9:edf45585032a 80 /*TODO Initialisation des paramettres du TIMER 2*/
JoeyDionne 9:edf45585032a 81 /*
JoeyDionne 9:edf45585032a 82 void timer2_init(void)
JoeyDionne 9:edf45585032a 83 {
JoeyDionne 9:edf45585032a 84 LPC_SC->PCLKSEL1 |=1<<12; //pclk = cclk timer2
JoeyDionne 9:edf45585032a 85 LPC_SC->PCONP |=1<<22; //timer2 power on
JoeyDionne 9:edf45585032a 86 //LPC_TIM2->MR0 = PERIOD;
JoeyDionne 9:edf45585032a 87 //LPC_TIM2->MCR = 0; //interrupt and reset control
JoeyDionne 9:edf45585032a 88 //3 = Interrupt & reset timer2 on match
JoeyDionne 9:edf45585032a 89 //1 = Interrupt only, no reset of timer0
JoeyDionne 9:edf45585032a 90 LPC_TIM2->CCR = 5; //5 = Interrupt on rising edge
JoeyDionne 9:edf45585032a 91 //6 = Interrupt on falling edge
JoeyDionne 9:edf45585032a 92 //7 = Interrupt rising or falling edge
JoeyDionne 9:edf45585032a 93
JoeyDionne 9:edf45585032a 94 NVIC_EnableIRQ(TIMER2_IRQn); //enable timer2 interrupt
JoeyDionne 9:edf45585032a 95 LPC_TIM2->TCR = 1; //enable Timer2
JoeyDionne 9:edf45585032a 96 //pc.printf("\n\rTimer set");
JoeyDionne 9:edf45585032a 97 }*/
JoeyDionne 9:edf45585032a 98
JoeyDionne 9:edf45585032a 99 void send_data()
JoeyDionne 9:edf45585032a 100 {
JoeyDionne 9:edf45585032a 101 if (!transmit) { //Si on est dans la premiere demi-periode d'envoie
JoeyDionne 9:edf45585032a 102 if (((trame_sent[byte_sent_pos] >> bit_sent) & 0x01) == 1) { //Verifier le bit à envoyer et preparer la prochaine interruption pour prendre sa valeur
JoeyDionne 9:edf45585032a 103 LPC_RIT->EMR |= 1 << 5;
JoeyDionne 9:edf45585032a 104 LPC_RIT->EMR &= ~(1 << 4);
JoeyDionne 9:edf45585032a 105 } else {
JoeyDionne 9:edf45585032a 106 LPC_RIT->EMR |= 1 << 4;
JoeyDionne 9:edf45585032a 107 LPC_RIT->EMR &= ~(1 << 5);
JoeyDionne 9:edf45585032a 108 }
JoeyDionne 9:edf45585032a 109 } else { //Si on est dans la 2eme demi-periode d'envoie, toggle a la prochaine interruption
JoeyDionne 9:edf45585032a 110 LPC_RIT->EMR |= 3 << 4;
JoeyDionne 9:edf45585032a 111 bit_sent--;
JoeyDionne 9:edf45585032a 112 }
JoeyDionne 9:edf45585032a 113 transmit = !transmit; //varier entre la 1ere et 2eme partie de demi-periode
JoeyDionne 9:edf45585032a 114 LPC_RIT->MR0 += HALF_PERIOD; //preparer la prochaine interruption a une demi-periode plus loin
JoeyDionne 9:edf45585032a 115 if (bit_sent < 0) { //Si l'octet a ete envoye
JoeyDionne 9:edf45585032a 116 bit_sent = 7; //remettre la position initiale pour le prochain octet
JoeyDionne 9:edf45585032a 117 byte_sent_pos++; //incrementer l'octet
JoeyDionne 9:edf45585032a 118 if (byte_sent_pos > trame_length) { //Si la trame a ete envoyee
JoeyDionne 9:edf45585032a 119 LPC_RIT->MCR &= 0; //desactiver les interruptions du MAT
JoeyDionne 9:edf45585032a 120 LPC_RIT->EMR &= ~(3 << 4); //remettre a zero le registre EMR (00 pour rien faire, 01 pour mettre a 1, 10 pour mettre a 0 et 11 pour toggle)
JoeyDionne 9:edf45585032a 121 byte_sent_pos = 0;
JoeyDionne 9:edf45585032a 122 transmit = false;
JoeyDionne 9:edf45585032a 123 }
JoeyDionne 9:edf45585032a 124 }
JoeyDionne 9:edf45585032a 125 }
JoeyDionne 9:edf45585032a 126
JoeyDionne 9:edf45585032a 127 void get_text()
JoeyDionne 9:edf45585032a 128 {
JoeyDionne 9:edf45585032a 129 CRC16 *myCRC = new CRC16();
JoeyDionne 9:edf45585032a 130
JoeyDionne 9:edf45585032a 131 trame_sent[0] = 0x55; //Preambule
JoeyDionne 9:edf45585032a 132 trame_sent[1] = 0x7E; //Start
JoeyDionne 9:edf45585032a 133 trame_sent[2] = 0x00; //Type + Flag mis a 0x00
JoeyDionne 9:edf45585032a 134
JoeyDionne 9:edf45585032a 135 pc.printf("\n\rYour text : ");
JoeyDionne 9:edf45585032a 136 int count = 0;
JoeyDionne 9:edf45585032a 137 char c = 0x00;
JoeyDionne 9:edf45585032a 138 char text[73];
JoeyDionne 9:edf45585032a 139 while(c != 0x0D && count < 73) { //Tant que c'est different de '\r' et un maximum de 33 caractères
JoeyDionne 9:edf45585032a 140 c = pc.getc();
JoeyDionne 9:edf45585032a 141 trame_sent[count + 4] = c; //Ajouter les caractères tapés au clavier dans le message
JoeyDionne 9:edf45585032a 142 text[count] = c;
JoeyDionne 9:edf45585032a 143 pc.putc(c);
JoeyDionne 9:edf45585032a 144 count++;
JoeyDionne 9:edf45585032a 145 }
JoeyDionne 9:edf45585032a 146 trame_sent[3] = (char)count; //Longueur du message (Max 33 caractères)
JoeyDionne 9:edf45585032a 147
JoeyDionne 9:edf45585032a 148 unsigned short resultCRC = myCRC->calculateCRC16(text,count);
JoeyDionne 9:edf45585032a 149 trame_sent[count + 4] = (resultCRC >> 8) & 0xFF;
JoeyDionne 9:edf45585032a 150 trame_sent[count + 5] = resultCRC & 0xFF;
JoeyDionne 9:edf45585032a 151
JoeyDionne 9:edf45585032a 152 trame_sent[count + 6] = 0x7E; //End
JoeyDionne 9:edf45585032a 153 trame_length = count + 6; //Longueur de la trame
JoeyDionne 9:edf45585032a 154
JoeyDionne 9:edf45585032a 155 }
JoeyDionne 9:edf45585032a 156
JoeyDionne 9:edf45585032a 157 void write()
JoeyDionne 9:edf45585032a 158 {
JoeyDionne 9:edf45585032a 159 byte_sent_pos = 0;
JoeyDionne 9:edf45585032a 160 bit_sent = 7;
JoeyDionne 9:edf45585032a 161 LPC_RIT->MCR = 1; //Permettre les interruption du MAT
JoeyDionne 9:edf45585032a 162 LPC_RIT->MR0 = LPC_RIT->TC + HALF_PERIOD; //Faire une interruption a la prochaine demi-periode
JoeyDionne 9:edf45585032a 163 }
JoeyDionne 9:edf45585032a 164
JoeyDionne 9:edf45585032a 165 extern "C" void RIT_IRQHandler(void) {
JoeyDionne 9:edf45585032a 166 //clear flag
JoeyDionne 9:edf45585032a 167 LPC_RIT->RICTRL |= bit0; //write 1 to clear bit
JoeyDionne 9:edf45585032a 168
JoeyDionne 9:edf45585032a 169 //Write
JoeyDionne 9:edf45585032a 170 if((LPC_TIM2->IR & 0x01) == 0x01) { //Si il y a interruption par le MAT
JoeyDionne 9:edf45585032a 171 LPC_TIM2->IR &= ~(1 << 0); //Nettoyer le drapeau de l'interruption du MR0
JoeyDionne 9:edf45585032a 172 send_data();
JoeyDionne 9:edf45585032a 173 }
JoeyDionne 9:edf45585032a 174
JoeyDionne 9:edf45585032a 175 //TODO Read
JoeyDionne 9:edf45585032a 176
JoeyDionne 9:edf45585032a 177 myled1 = !myled1;
JoeyDionne 9:edf45585032a 178 bIsHalfPeriod = !bIsHalfPeriod;
JoeyDionne 9:edf45585032a 179 }
JoeyDionne 9:edf45585032a 180
ericbisson 2:c6465d4e82d2 181 int main() {
ericbisson 7:5501dbea5650 182 rit_init();
ericbisson 7:5501dbea5650 183 read_pin.fall(p14_interrupt);
ericbisson 7:5501dbea5650 184 read_pin.enable_irq();
ericbisson 0:c637467eeb8f 185
ericbisson 7:5501dbea5650 186 Thread ThreadLecture; // Thread pour pas avoir à rien faire dans l'interrupt
ericbisson 7:5501dbea5650 187 thread = &ThreadLecture;
ericbisson 7:5501dbea5650 188 thread->start(read);
ericbisson 0:c637467eeb8f 189
ericbisson 3:3ecbcc05bc85 190 while(true) {
JoeyDionne 9:edf45585032a 191 get_text();
JoeyDionne 9:edf45585032a 192 write();
ericbisson 7:5501dbea5650 193 uart.putc(0);
ericbisson 7:5501dbea5650 194 wait_ms(100);
ericbisson 0:c637467eeb8f 195 }
ericbisson 7:5501dbea5650 196 };