Problematique

Dependencies:   mbed mbed-rtos

main.cpp

Committer:
joGenie
Date:
2014-02-12
Revision:
4:2af360b178d2
Parent:
3:65845faafbb1

File content as of revision 4:2af360b178d2:

#include "mbed.h"
#include "rtos.h"
#include "trame.hpp"

Serial pc(USBTX, USBRX);

DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);

DigitalOut out(p26);

const int tickPerPeriod = 960000;

struct message_t
{
    char msg[696];
};

Queue<string, 16> textToSend;
Mail<trame, 16> trameToSend;

Queue<message_t, 16> messagesQueue;
Mail<trame, 16> trameToDecode;
Queue<string, 16> textToPrint;

unsigned long tc_periods[8] = {0};
unsigned long period = 0;
bool type_bit = false;
int synchrone = 0;
int count = 0;
const char end[8] = {0, 1, 1, 1, 1, 1, 1, 0};

bool good = true;

char messages[696] = {0};
message_t msgs;
const unsigned long offset = 200;

void getText(void const *args)
{
    int compteur = 0;
    char c;
    string message = "";
    
    while (true)
    {
        c = pc.getc();
        
        if (c == 0xD)
        {
            if (!message.empty())
            {
                pc.putc(0xA);
                pc.putc(0xD);
                textToSend.put(new string(message));
                message = "";
                compteur = 0;
            }
        }
        else if (c == 0x8)
        {
            pc.putc(c);
            pc.putc(0x20);
            pc.putc(c);
            message = message.substr(0, message.length() - 1);
            compteur--;
        }
        else
        {
            if (compteur < 80)
            {
                pc.putc(c);
                message += c;
                compteur++;
            }
        }
    }
}

void leTrameur(void const *args)
{
    while (true)
    {
        osEvent evt = textToSend.get();

        if (evt.status == osEventMessage) {
            string *msg = (string*)evt.value.p;
            
            //pc.printf("message envoye :\n\r%s\n\r", msg->c_str());
            trameToSend.put(new trame(*msg));
            
            delete msg;
        }
    }
}

void setPwmMatch(bitset<8> bitst)
{
    for (int a = 0; a < 8; a++)
    {
        out = !out;
        if (bitst.test(a))
        {
            LPC_PWM1->MR1 = tickPerPeriod/2;
            LPC_PWM1->MR2 = 1;
        }
        else
        {
            LPC_PWM1->MR1 = 1;
            LPC_PWM1->MR2 = tickPerPeriod/2;
        }
        
        while(LPC_PWM1->IR != 0x01);
        LPC_PWM1->IR = 0xFF;
        
        out = !out;
    }
}

void sendTrame(trame *trm)
{
    LPC_TIM2->TC = 0;
    LPC_PWM1->TCR |= (1 << 0);  // Enable counter
    
    setPwmMatch(trm->preambule);
    setPwmMatch(trm->start_end);
    setPwmMatch(trm->type_flag);
    setPwmMatch(trm->charge_utile);
    
    for (int a = 0; a < trm->length; a++)
    {
        if (trm->message.test(a))
        {
            LPC_PWM1->MR1 = tickPerPeriod/2;
            LPC_PWM1->MR2 = 1;
        }
        else
        {
            LPC_PWM1->MR1 = 1;
            LPC_PWM1->MR2 = tickPerPeriod/2;
        }
        
        while(LPC_PWM1->IR != 0x01);
        LPC_PWM1->IR = 0xFF;
    }
    
    for (int a = 0; a < 16; a++)
    {
        if (trm->crc16.test(a))
        {
            LPC_PWM1->MR1 = tickPerPeriod/2;
            LPC_PWM1->MR2 = 1;
        }
        else
        {
            LPC_PWM1->MR1 = 1;
            LPC_PWM1->MR2 = tickPerPeriod/2;
        }
        
        while(LPC_PWM1->IR != 0x01);
        LPC_PWM1->IR = 0xFF;
    }
    
    setPwmMatch(trm->start_end);
    
    LPC_PWM1->TCR = 0x0;    // Disable counter
}

void sender(void const *args)
{
    while (true)
    {
        osEvent evt = trameToSend.get();

        if (evt.status == osEventMail) {
            trame *trm = (trame*)evt.value.p;

            pc.printf("trame shooter :\n\r%s", trm->trameToString().c_str());
            sendTrame(trm);
            
            trameToSend.free(trm);
        }
    }
}

void pushTrame(void const *args)
{
    while (true)
    {
        osEvent evt = messagesQueue.get();

        if (evt.status == osEventMessage) {
            message_t *msg = (message_t*)evt.value.p;
            
            bitset<696> bit(string(const_cast<const char*>(msg->msg)));
            trame *trm = new trame(bit);
            
            pc.printf("trame recu :\n\r%s\n\r", trm->trameToString().c_str());
            if (trm->checkCRC16())
            {
                trameToDecode.put(trm);
            }
            else
            {
                for (int a=0;a < 8; a++)
                {
                    pc.printf("tc_periods: %d\n\r", tc_periods[a]);
                }
                pc.printf("period: %d\n\r", period);
                pc.printf("Mauvais CRC16\n\r");
            }
        }
    }
}

void readTrame()
{
    if (synchrone < 8)
    {
        tc_periods[synchrone] = LPC_TIM2->CR1;
        synchrone++;
        
        if (synchrone == 8)
        {
            for (int i = 0; i < 8; i++)
            {
               period += tc_periods[i]; 
            }
            
            period = period/8;
        }
    }
    else
    {   
        unsigned long tc_count = LPC_TIM2->CR1;
        if (tc_count > (period*2 - offset) && tc_count < (period*2 + offset))
        {
            type_bit = !type_bit;
            good = true;
            
            if (type_bit)
            {
                messages[count] = '1';
                led1 = 1;
                led2 = 0;
            }
            else
            {
                messages[count] = '0';
                led1 = 0;
                led2 = 1;
            }
                
            count++;
        }
        
        good = !good;
        if (good)
        {
            if (type_bit)
            {
                messages[count] = '1';
                led1 = 1;
                led2 = 0;
            }
            else
            {
                messages[count] = '0';
                led1 = 0;
                led2 = 1;
            }
                
            count++;
        }
    }
    
    if (count >= 48)
    {
        char temp[8] = {0};
        for (int a = 0; a < 8; a++)
        {
            temp[a] = messages[count-a];
        }
        
        if (strcmp(temp, end) == 0)
        {
            count = 0;
            synchrone = 0;
            good = true;
            strcpy(msgs.msg, messages);
            fill(messages, messages+696, 0);
            messagesQueue.put(&msgs);
            led3 = 1;
        }
    }

    LPC_TIM2->TC = 0;
    LPC_TIM2->IR = 0xFF;
    led4 = 1;
}

void decoder(void const *args)
{
    while(true)
    {
        osEvent evt = trameToDecode.get();

        if (evt.status == osEventMail) {
            trame *trm = (trame*)evt.value.p;

            textToPrint.put(new string(trm->text));
            
            trameToDecode.free(trm);
        }
    }
}

void printer(void const *args)
{
    while (true)
    {
        osEvent evt = textToPrint.get();

        if (evt.status == osEventMessage) {
            string *msg = (string*)evt.value.p;
            
            pc.printf("Sender says :\n\r%s\n\r", msg->c_str());
            
            delete msg;
        }
    }
}

void initialize()
{
    // Set system control
    LPC_SC->PCONP |= (1 << 22) | (1 << 6); // Enable Timer2 et PWM
    LPC_SC->PCLKSEL0 |= (1 << 12); // PClk PWM = CCLK
    LPC_SC->PCLKSEL1 |= (1 << 12); // PClk Timer2 = CCLK

    // Set pin connection
    LPC_PINCON->PINSEL0 |= (3 << 10); // Pin 29 Capture
    LPC_PINCON->PINSEL4 |= (1 << 2);  // Pin 25 PWM

    //Initialize Timer2 for capture
    NVIC_SetVector(TIMER2_IRQn, (uint32_t)&readTrame);
    NVIC_EnableIRQ(TIMER2_IRQn);

    LPC_TIM2->TC = 0;           // Initialize Time Counter
    LPC_TIM2->PC = 0;           // Initialize Prescale Counter
    LPC_TIM2->PR = 0;           // Initialize Prescale Register
    LPC_TIM2->TCR |= (1 << 1);  // Reset Timer Control Register
    LPC_TIM2->IR = 0xFF;        // Reset Interrupt Register
    LPC_TIM2->CCR |=  (1 << 5) | (1 << 4) | (1 << 3);   // Initialize Capture Control Register
    LPC_TIM2->CTCR = 0x0;

    LPC_TIM2->TCR = 0x01;       // Start Timer Control Register
    
    //Initialize PWM
    LPC_PWM1->MCR |= (1 << 1) | (1 << 0);   // Initialize Match Control Register Interrupt/Reset
    LPC_PWM1->PCR |= (1 << 10) | (1 << 2);  // Initialize PWM Control Register Output/Double-edge
    
    LPC_PWM1->MR0 = tickPerPeriod;        // Period
    LPC_PWM1->LER |= (1 << 2) | (1 << 1);   // Initialize Latch Enable Register
    
    LPC_PWM1->IR = 0xFF; // Reset Interrupt Registe
}

int main()
{
    out = 0; // Pour analyse de performance
    
    initialize();
    
    // Permet de concevoir le message a envoyer
    // Ajoute le message dans le queue du trameur
    Thread thread1(getText);
    
    // Vide la queue du trameur
    // Creer un message a binaire
    // Ajoute se message dans le mail box du sender
    Thread thread2(leTrameur);
    thread2.set_priority(osPriorityAboveNormal);
    
    // Vide la mailbox du sender
    // Creer le signal du modulateur a l'aide du LPC_PM1
    Thread thread3(sender);
    thread3.set_priority(osPriorityHigh);
    
    // Creer un message en binaire et check pour le CRC16
    // Ajoute ce message dans la mailbox du decoder
    Thread thread(pushTrame);
    thread.set_priority(osPriorityRealtime);
    
    // Vide la mailbox du decoder
    // Creer un message en lettre
    // Ajoute ce message dans la queue du printer
    Thread thread4(decoder);
    thread4.set_priority(osPriorityHigh);
    
    // Vide la queue du printer
    // Affiche le message a l'ecran
    Thread thread5(printer);
    thread5.set_priority(osPriorityAboveNormal);
    
    while(true);
}