APP4 - S5 H16

Dependencies:   mbed-rtos mbed

main.cpp

Committer:
SonSenpai
Date:
2016-02-23
Revision:
3:cd69f04a084e
Parent:
2:f57df1b4a7a4
Child:
4:d773812f9f7b

File content as of revision 3:cd69f04a084e:

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

#define SIGNAL_READ 0x23

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

DigitalOut d_out(p9);
Thread* debugTH;

Serial pc(USBTX, USBRX);

const int PERIODE = 96000000;

//Variables for MEF
enum states
{
    START           = 0,
    ENTETE          = 1,
    CHARGE_UTILE    = 2,
    CONTROLE        = 3,
    END             = 4
};

int state;
int cntState = 0;
bool nextBit;
bitset<16> buffer;
bitset<640> chargeUtile;
int LENGTH_CHARGE_UTILE_BIT;
int LENGTH_CHARGE_UTILE_BYTE;
char c_chargeUtile[80];
unsigned short CRC_Calculated;
unsigned short CRC_Received;
bool messageReady;

//Variables for send
Mail<trame, 8> OutGoingMail;
bool increment_c = false;
bool done_sending = false;
bitset<696> *outGoingTrame;
int outGoingLength = 0;
int count = 0;

//Variables for receive
Thread* RegReader_Th;
struct inboundChargeMail
{
    char* charge;
    int length;
};
Mail<inboundChargeMail, 8> inboundChargeUtile;
int sync = 0;
int rcv_count = 0;
unsigned long tick_count_read;
bool state_adjust = true;
unsigned long period = 0;
unsigned long tc_periods[8] = {0};
bool rcv_buff[696];

void inputReceiver( void const *args )
{
    int c_count;
    char temp_c;
    string message = "";
    
    while( true )
    {
        temp_c = pc.getc();
        
        if( temp_c == 0xD )
        {
            if( !message.empty() )
            {
               pc.putc( 0xA );
               pc.putc( 0xD );
               pc.printf("debug : message sent to mailbox : %s", message );
               OutGoingMail.put( new trame( message ) );
               message = "";
               c_count = 0;
           }
        }
        else if( temp_c == 0x8 )
        {
            pc.putc( temp_c );
            pc.putc( 0x20 );
            pc.putc( temp_c );
            message = message.substr(0, message.length() - 1);
            c_count--;
        }
        else
        {
            if( c_count < 80 )
            {
                pc.putc( temp_c );
                message += temp_c;
                c_count++;
            }
        }
    }
}

extern "C" void TIMER1_IRQHandler( void )
{
    if( LPC_TIM1->IR & 0x01 )
    {
        if( count < outGoingLength )
        {
            if( outGoingTrame->test( count ) != outGoingTrame->test( count + 1 ) )
            {
                LPC_TIM1->MR0 = PERIODE;
                d_out = !outGoingTrame->test( count );
                count++;
            }
            else
            {
                if ( increment_c )
                {
                    count++;    
                    increment_c = false;
                    d_out = !d_out;
                }
                else
                {
                    increment_c = true; 
                    d_out = !outGoingTrame->test( count ); 
                }
                LPC_TIM2->MR0 = PERIODE/2;
            }
            LPC_TIM1->IR |= 1;
            debugTH->signal_set(0x1);
        }
        else
        {
            count = 0;
            LPC_TIM2->MR0 = 0;
            LPC_TIM1->MCR = 0;
            done_sending = true;
        }
    }
}

void debug( void const *args )
{
    while( true )
    {
        Thread::signal_wait(0x1);
        pc.printf( "debug1 sent %d\n\r", d_out );
    }
    
    
}

bool analyze_state(bool bit)
{
    switch(state)
    {
        case START:
        
            pc.printf("START\t");
            
            if(cntState == 0 && bit == 0)
            {
                nextBit = 1;
                cntState++;
            }
            else if (cntState < 6 && bit == nextBit)
            {
                cntState++;
            }
            else if (cntState == 6 && bit == nextBit)
            {
                nextBit = 0;
                cntState++;
            }
            else if (cntState == 7 && bit == nextBit)
            {
                state = ENTETE;
                cntState = 0;
                nextBit = 0;
            }
            else
            {
                state = START;
                return 0;
            }
            
            break;
           
        case ENTETE:
        
            if(cntState < 7 && nextBit == 0)
            {
                pc.printf("TEST1: %i \t", cntState);
                cntState++;
                
            }
            else if (cntState == 7 && nextBit == 0)
            {
                pc.printf("TEST2: %i \t", cntState);
                nextBit = 1;
            }
            else if (nextBit == 1 && cntState > 0)
            {
                pc.printf("TEST3: %i \t", cntState);
                buffer.set(cntState, bit);
                cntState--;
            }
            else if (nextBit == 1 && cntState == 0)
            { 
                buffer.set(cntState, bit);
                state = CHARGE_UTILE;
                LENGTH_CHARGE_UTILE_BIT = (int)(buffer.to_ulong());
                
                cntState = LENGTH_CHARGE_UTILE_BIT - 1;
            }
            else
            {
                state = START;
                return 0;
            }
            
            break;
           
        case CHARGE_UTILE:
            
            pc.printf("CHARGE UTILE\t");
            
            if (cntState > 0)
            {
               chargeUtile.set(cntState, bit); 
               cntState--;
            }
            else if (cntState == 0)
            {
                chargeUtile.set(cntState, bit); 
                cntState = 0;
                state = CONTROLE;
                nextBit = 0;
            }
            else
            {
                state = START;
                return 0;
            }
            
            break;
           
        case CONTROLE:
            
            if(nextBit == 0)
            {
                LENGTH_CHARGE_UTILE_BYTE = LENGTH_CHARGE_UTILE_BIT / 8;
                
                for (int i = LENGTH_CHARGE_UTILE_BIT-1; i >= 0; i--)
                {
                    pc.printf("%i", (chargeUtile[i] & 0x1));
                    if (i % 8 == 0)
                        c_chargeUtile[ ( ( LENGTH_CHARGE_UTILE_BIT - 1 ) - i ) / 8] = (chargeUtile[i] << 7) | (chargeUtile[i + 1] << 6) | (chargeUtile[i + 2] << 5) | (chargeUtile[i + 3] << 4) | (chargeUtile[i + 4] << 3) | (chargeUtile[i + 5] << 2) | (chargeUtile[i + 6] << 1) | (chargeUtile[i + 7] << 0);
                }
                
                CRC_Calculated = CRC16::calculateCRC16(c_chargeUtile, LENGTH_CHARGE_UTILE_BYTE);
                
                pc.printf("CRC Calculated: %hu\t", CRC_Calculated);
                
                nextBit = 1;
                cntState = 14;
                buffer.reset();
                buffer.set(15, bit);
            }
            else if (nextBit == 1 && cntState > 0)
            {
                buffer.set(cntState, bit);
                cntState--;
            }
            else if (nextBit == 1 && cntState == 0)
            {
                buffer.set(cntState, bit);
                CRC_Received = (unsigned short)buffer.to_ulong();
                
                pc.printf("CRC Received: %hu\t", CRC_Received);
                
                if (CRC_Received == CRC_Calculated)
                {
                    state = END;
                    nextBit = 0;
                    cntState = 0;
                }
                else
                {
                    state = START;
                    return 0;
                }
            }
            else
            {
                state = START;
                return 0;
            }
            
            break;
           
        case END:
        
            if (nextBit == 0 && nextBit == bit && cntState == 0)
            {
                nextBit = 1;
                cntState++;
            }
            else if (nextBit == 1 && nextBit == bit && cntState < 6)
            {
                cntState++;
            }
            else if (nextBit == 1 && nextBit == bit && cntState == 6)
            {
                nextBit = 0;
                cntState++;
            }
            else if (nextBit == 0 && nextBit == bit && cntState == 7)
            {
                messageReady = true;
                state = START;
            }
            else
            {
                state = START;
                messageReady = false;
                return 0;
            }
        
            break;
    }
    
    return 1;
}

extern "C" void TIMER2_IRQHandler( void )
{
    if( LPC_TIM2->IR & 0x01 )
    {
        tick_count_read = LPC_TIM2->CR1;
        RegReader_Th->signal_set(SIGNAL_READ);
    }
}

void regReader( void const *args )
{
    bool bitValueOk = 1;
    while(true)
    {
        Thread::signal_wait(SIGNAL_READ);
        if( sync < 8 )
        {
            tc_periods[sync] = tick_count_read;
            sync++;
            
            if (sync == 8)
            {
                for (int i = 0; i < sync; i++)
                {
                   period += tc_periods[i]; 
                }
                period = period/8;
            }
        }
        else
        {
            if( tick_count_read > ( period * 0.8 ) && tick_count_read < ( period * 1.2 ) )
            {
                if( rcv_count == 0 )
                {
                    rcv_buff[0] = 0;
                    bitValueOk = analyze_state(0);
                }
                else if( rcv_buff[ rcv_count - 1 ] == 0 )
                {
                    rcv_buff[ rcv_count ] = 1;
                    bitValueOk = analyze_state(1);
                }
                else
                {
                    rcv_buff[ rcv_count ] = 0;
                    bitValueOk = analyze_state(0);
                }
                rcv_count++;
            }
            else if( tick_count_read < ( period * 0.7 ) )
            {
                if( state_adjust )
                {
                    state_adjust = !state_adjust;
                }
                else
                {
                    state_adjust = !state_adjust;
                    rcv_buff[ rcv_count ] = rcv_buff[ rcv_count - 1 ];
                    bitValueOk = analyze_state( rcv_buff[ rcv_count ] );
                    rcv_count++;
                }
            }
            
        }
        LPC_TIM2->TC = 0;
        if( messageReady )
        {
            inboundChargeMail *mail_t = new inboundChargeMail;
            char ctemp[ 80 ];
            strcpy( ctemp, c_chargeUtile );
            mail_t->charge = ctemp;
            mail_t->length = LENGTH_CHARGE_UTILE_BYTE;
            inboundChargeUtile.put( mail_t );
            
            rcv_count = 0;
            state_adjust = true;
            sync = 0;
            messageReady = false;
            cntState = 0;
        }
        if( !bitValueOk )
        {
            rcv_count = 0;
            state_adjust = true;
            sync = 0;
            cntState = 0;
        }
    }
}

void send( trame *trm )
{
    outGoingTrame = trm->getBitset();
    outGoingLength = trm->length;
    d_out = 0;
    LPC_TIM1->MCR |= 3; //Interrupt on MR0 and Reset TC on MR0
    LPC_TIM1->MR0 = PERIODE/2; // set periode
    while( !done_sending )
    {
        Thread::wait(5);
    }
    done_sending = false;
}

void frame_sender( void const *args )
{
    while( true )
    {
        osEvent evt = OutGoingMail.get();
 
        if( evt.status == osEventMail ) 
        {
            trame *trm = ( trame* )evt.value.p;
 
            //pc.printf( "outgoing frame :\n\r%s", trm->ToString().c_str() );
            send( trm );
            OutGoingMail.free( trm );
        }
    }
}

void frame_printer( void const *args )
{
    while( true )
    {
        osEvent evt = inboundChargeUtile.get();
        
        if( evt.status == osEventMail )
        {
            inboundChargeMail* mailed_charge = ( inboundChargeMail* )evt.value.p;
            pc.printf( "Received frame :\n\r%s", mailed_charge->charge );
            inboundChargeUtile.free( mailed_charge );
        }
    }
}

void init_timer1()
{
    LPC_SC->PCONP |= ( 1 << 2 ); //Power-Up Timer 1
    LPC_SC->PCLKSEL0 |= ( 1 << 4 ); //Select Timer 1 = CCLK
    LPC_PINCON->PINSEL0 |= ( 3 << 18 ); //Select match register 1
    
    NVIC_EnableIRQ(TIMER1_IRQn); //Bind timer 1 to custom funk
}

void init_timer2()
{
    NVIC_EnableIRQ(TIMER2_IRQn);
    LPC_SC->PCONP |= ( 1 << 22 ); //Power-Up Timer 2
    LPC_SC->PCLKSEL1 |= ( 1 << 12 ); //Select Timer 2 = CCLK
    LPC_PINCON->PINSEL0 |= ( 3 << 10 ); //Select Capture register 1
    LPC_TIM2->TC = 0;
    LPC_TIM2->TCR |= ( 1 << 1 );
    LPC_TIM2->CCR |= ( 7 << 3 );
}


int main() {
    state = START;
    messageReady = false;
    
    init_timer1();
    init_timer2();
    
    debugTH = new Thread(debug);
    
    Thread fp( frame_printer );
    Thread fs( frame_sender );
    Thread ir( inputReceiver );
    RegReader_Th = new Thread( regReader );
    
    while( true )
    {
        wait(50000);
    }
}