Add CRC16 library

Dependencies:   CRC16 mbed-rtos mbed

Fork of S5info_APP4 by Éric Bisson

main.cpp

Committer:
JoeyDionne
Date:
2017-03-07
Revision:
9:edf45585032a
Parent:
8:177b2370528b

File content as of revision 9:edf45585032a:

#include "mbed.h"
#include "rtos.h"
#include <string>
#include "bit.h"
#include "CRC16.h"
using std::string;

#define PREAMBULE 0b01010101
const char START =      0b01111110;
const char END =        0b01111110;
const char FLAGS =      0x00;
const char MAX_LENGTH = 80;
const float HALF_PERIOD = 0.0005; // secondes

Serial pc(USBTX, USBRX, 9600);
Serial uart(p13, p14, 9600);
DigitalOut myled1(LED1);
DigitalOut myled2(LED2);
InterruptIn read_pin(p14);
Thread* thread;

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

bool bIsHalfPeriod = false;

//TODO (Erase when not usefull anymore, timer handling read and write)
/*extern "C" void TIMER2_IRQHandler (void)
{
    if((LPC_TIM2->IR & 0x01) == 0x01) { //Si il y a interruption par le MAT
        LPC_TIM2->IR &= ~(1 << 0);      //Nettoyer le drapeau de l'interruption du MR0
        send_data();
    }
    else if (((LPC_TIM2->IR >> 4) & 0x01) == 0x01) {    //Si il y a interruption du CAP
        LPC_TIM2->IR &= ~(1 << 4);                      //Nettoyer le drapeau de l'interruption du CR0
        receive_data();
    }
}*/

void p14_interrupt()
{    
    // On envoie le signal au thread de lecture
    thread->signal_set(1);
    
    // On turn off les interrupts de lecture une fois qu'on a détecter un message
    read_pin.disable_irq();
};

void read()
{
    while(true) 
    {
        thread->signal_wait(1);
        
        // TODO: mettre ici le code pour la lecture de trame
        myled2 = !myled2;
        
        // Une fois fini, on réactive l'interrupt de lecture
        read_pin.enable_irq();
    }
};

void rit_init()
{
    LPC_SC->PCONP |= bit16;                             //Power Control for Peripherals register: power up RIT clock
    LPC_SC->PCLKSEL1 |= (bit26 && bit27);               //Peripheral clock selection: divide clock by 8 (run RIT clock by 12.5MHz)
    LPC_RIT->RICOUNTER = 0;                             //set counter to zero
    LPC_RIT->RICOMPVAL = 1000000000 * HALF_PERIOD;       //interrupt tick every HALF_PERIOD
    LPC_RIT->RICTRL |= bit1;                            // clear timer when counter reaches value
    LPC_RIT->RICTRL |= bit3;                            // enable timer
     
    //enable interrupt
    NVIC_SetPriority(RIT_IRQn, 31);
    NVIC_EnableIRQ(RIT_IRQn);
};

/*TODO Initialisation des paramettres du TIMER 2*/
/*
void timer2_init(void)
{
    LPC_SC->PCLKSEL1 |=1<<12;       //pclk = cclk timer2
    LPC_SC->PCONP |=1<<22;          //timer2 power on
    //LPC_TIM2->MR0 = PERIOD;
    //LPC_TIM2->MCR = 0;            //interrupt and reset control
                                    //3 = Interrupt & reset timer2 on match
                                    //1 = Interrupt only, no reset of timer0
    LPC_TIM2->CCR = 5;              //5 = Interrupt on rising edge
                                    //6 = Interrupt on falling edge
                                    //7 = Interrupt rising or falling edge
                                    
    NVIC_EnableIRQ(TIMER2_IRQn);    //enable timer2 interrupt
    LPC_TIM2->TCR = 1;              //enable Timer2
    //pc.printf("\n\rTimer set");
}*/

void send_data()
{
    if (!transmit) { //Si on est dans la premiere demi-periode d'envoie
        if (((trame_sent[byte_sent_pos] >> bit_sent) & 0x01) == 1) { //Verifier le bit à envoyer et preparer la prochaine interruption pour prendre sa valeur
            LPC_RIT->EMR |= 1 << 5;
            LPC_RIT->EMR &= ~(1 << 4);
        } else {
            LPC_RIT->EMR |= 1 << 4;
            LPC_RIT->EMR &= ~(1 << 5);
        }
    } else {        //Si on est dans la 2eme demi-periode d'envoie, toggle a la prochaine interruption
        LPC_RIT->EMR |= 3 << 4;
        bit_sent--;
    }
    transmit = !transmit;       //varier entre la 1ere et 2eme partie de demi-periode
    LPC_RIT->MR0 += HALF_PERIOD;    //preparer la prochaine interruption a une demi-periode plus loin
    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
            LPC_RIT->MCR &= 0;             //desactiver les interruptions du MAT
            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)
            byte_sent_pos = 0;
            transmit = false;
        }
    }
}

void get_text()
{
    CRC16 *myCRC = new CRC16();
    
    trame_sent[0] = 0x55;    //Preambule
    trame_sent[1] = 0x7E;    //Start
    trame_sent[2] = 0x00;    //Type + Flag mis a 0x00
    
    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 un maximum de 33 caractères 
        c = pc.getc();
        trame_sent[count + 4] = c;   //Ajouter les caractères tapés au clavier dans le message
        text[count] = c;
        pc.putc(c);
        count++;
    }
    trame_sent[3] = (char)count;     //Longueur du message (Max 33 caractères)
    
    unsigned short resultCRC = myCRC->calculateCRC16(text,count);     
    trame_sent[count + 4] = (resultCRC >> 8) & 0xFF;
    trame_sent[count + 5] = resultCRC & 0xFF;
    
    trame_sent[count + 6] = 0x7E;    //End
    trame_length = count + 6;        //Longueur de la trame
    
}

void write()
{
    byte_sent_pos = 0;
    bit_sent = 7;
    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
}

extern "C" void RIT_IRQHandler(void) {
    //clear flag
    LPC_RIT->RICTRL |= bit0; //write 1 to clear bit
    
    //Write
    if((LPC_TIM2->IR & 0x01) == 0x01) { //Si il y a interruption par le MAT
        LPC_TIM2->IR &= ~(1 << 0);      //Nettoyer le drapeau de l'interruption du MR0
        send_data();
    }
    
    //TODO Read
    
    myled1 = !myled1;
    bIsHalfPeriod = !bIsHalfPeriod;
}

int main() {
    rit_init();
    read_pin.fall(p14_interrupt);
    read_pin.enable_irq();
    
    Thread ThreadLecture; // Thread pour pas avoir à rien faire dans l'interrupt
    thread = &ThreadLecture;
    thread->start(read);
    
    while(true) {
        get_text();
        write();
        uart.putc(0);
        wait_ms(100);
    }
};