app4

Dependencies:   mbed-rtos mbed CRC16

Fork of S5info_APP2 by Éric Bisson

main.cpp

Committer:
ericbisson
Date:
2017-03-07
Revision:
25:d0c348c3c85d
Parent:
24:2034362db66f
Child:
26:6ffbf3161f6f

File content as of revision 25:d0c348c3c85d:

#include "CRC16.h"
#include "mbed.h"
#include "rtos.h"

Thread ThreadLecture;
Thread ThreadWrite;
const int PREAMBULE = 0b01010101;
const int START = 0b01111110;
const int END = 0b01111110;
Serial pc(USBTX, USBRX);
DigitalOut out(p13);
DigitalOut myled1(LED1);
DigitalOut myled2(LED2);
InterruptIn interrupt_p30(p30);
CRC16 myCRC;
Timer t;
int periode = 0;
char sync = 0;

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
        trame_length;       //longueur de la trame complete
        
signed char bit_sent;       //position du bit de l'octet en cours d'envoi (du MSB au LSB) 7..0
bool bTimer1 = false;

//encodage manchester
bool codeManchester(bool bit, bool clock)
{
    return (bit == clock);
}

//Envoie de données bit par bit
void send_data()
{    
    out = codeManchester(((trame_sent[byte_sent_pos] >> bit_sent) & 0x01), bTimer1);
    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;
            LPC_TIM1->TCR = 0;  // disable Timer
        }
    }
}

char messageBuffer[80];
char messageLength = 0;
char lastpos = 0;
void show_message()
{
    while (true)
    {
        ThreadLecture.signal_wait(1);
        for (int i = lastpos; i < messageLength; i++)
        {
            pc.printf("%x",messageBuffer[i]);
            
            if ((i % 11) == 0 && i > 0)
            {
                pc.printf("\n");
            }
        }
        lastpos = messageLength;
    }
}

char byte = 0;
char shift = 0;
char totalsize = 7;
void resetMessage()
{
    byte = 0;
    shift = 0;
    totalsize = 7;
    messageLength = 0;
    lastpos = 0;
}

void read(bool bit)
{
    int time = t.read_us();
    if (sync == 1)
    {
        periode = time;
    }
    sync++;
    
    if (sync > 1 && (time*1.5 >= periode))
    {
        messageBuffer[messageLength] = (messageBuffer[messageLength] << 1) + bit;
    }
        
    shift++;
    if (shift == 8)
    {
        shift = 0;
        
        messageLength++;
        
        // debug
        ThreadLecture.signal_set(1);
        
        // Validations de base
        if (messageLength == 2 && messageBuffer[1] != START)
        {
            resetMessage();
        }
        
        if (messageLength == 4)
        {
            totalsize = 7 + messageBuffer[3];
        }
        
        // fin
        if (totalsize == messageLength)
        {
            // Calcul du CRC
            unsigned short currentCRC = messageBuffer[totalsize-2] + messageBuffer[totalsize-3]<<8;
            
            if (currentCRC == myCRC.calculateCRC16(messageBuffer+4, totalsize-7) && messageBuffer[totalsize-1] == END)
            {
                // Affiche à l'écran le message valide
                ThreadLecture.signal_set(1);
            }
            resetMessage();
        }
    }
        
    // reset le timer pour mesurer la période
    t.reset();
}

void rise()
{
    read(0);
}

void fall()
{
    read(1);
}

extern "C" void TIMER1_IRQHandler()
{
    LPC_TIM1->TC = 0;
    
    myled1 = !myled1;
    if ((LPC_TIM1->IR & 0x01) == 0x01)
    {
        send_data();
        LPC_TIM1->IR |= 1 << 0; // clear
    }
}

//création de la trame
void create_trame(char message[],unsigned char taille)
{
    unsigned short resultCRC = myCRC.calculateCRC16(message,taille); 
    
    trame_sent[0] = PREAMBULE;    //Preambule
    trame_sent[1] = START;    //Start
    trame_sent[2] = 0x00;    //Type + Flag mis a 0x00
    trame_sent[3] = taille;     //Longueur du message (Max 33 caractères)
    
    //message
    for (char 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] = END;    //End
    trame_length = taille + 7;        //Longueur de la trame
}

//obtention du texte
void get_text()
{
    while (true)
    {
        char text[4] = {'a','l','l','o'};
        unsigned char count = 4;
        
        create_trame(text,count);
        byte_sent_pos = 0;
        bit_sent = 7;
        bTimer1 = false;
        LPC_TIM1->TCR = 1; // enable and reset Timer
        
        wait_ms(5000);
    }
    /*pc.printf("\n\rYour text : ");
    unsigned char count = 0;
    char c = 0x00;
    char text[73];
    while(c != '\r' && count < 73) {
        c = pc.getc();
        text[count] = c;
        pc.putc(c);
        count++;
    }
    pc.printf("get_text();\n");*/
}

void initTimers()
{
    //Timer 1 (match)
    LPC_SC->PCLKSEL0 |= (1 << 4);           // pclk = cclk timer1
    LPC_SC->PCONP |= (1 << 2);              // timer1 power on
    LPC_TIM1->MCR = 3;                      // interrupt and reset control
    LPC_TIM1->TC = 0;                       // clear timer counter
    LPC_TIM1->PC = 0;                       // clear prescale counter
    LPC_TIM1->PR = 0;                       // clear prescale register
    LPC_TIM1->MR0 = (960000);               // 10 ms 
    LPC_TIM1->EMR = (3 << 4);               // Interrupt & reset timer on match
    NVIC_EnableIRQ(TIMER1_IRQn);            // enable timer interrupt
    LPC_TIM1->TCR = 0;                      // disable Timer
}

int main() {
    LPC_PINCON->PINSEL0 |= (3 << 8); // pin30
    LPC_PINCON->PINMODE1 |= 3;
    initTimers();
    ThreadLecture.start(show_message);
    ThreadWrite.start(get_text);
    interrupt_p30.fall(fall);
    interrupt_p30.rise(rise);
    t.start();
    
    while(true) 
    {
    }
};