Prosper Van / xbeeCom

Fork of com by Prosper Van

com.cpp

Committer:
oprospero
Date:
2014-05-22
Revision:
13:2fb7b19dcd70
Parent:
12:bf4642578682
Child:
14:d2acb373d81c

File content as of revision 13:2fb7b19dcd70:

/****************************** com.cpp **********************************/
/* Version: 1.0                                                          */
/* Last Updated: June 1, 2013                                            */
/*                                                                       */
/* The com class implements reliable data transfer between two nodes     */
/*using a checksum and a sequence number for guaranteed message delivery */
/*over an xbee modem connected to the passed in tx and rx pins. Messages */
/*are received and placed in the rxBuffer to be read when convenient.    */
/*Messages are encoded by sending a byte with the value of the command   */
/*then and int of the command.                                           */
/*                                                                       */
/* Commands:    0 -> Ack, does not get placed in rxQueue.                */
/*              1 -> Throttle                                            */
/*              2 -> Pitch                                               */
/*              3 -> Roll                                                */
/*              4 -> Yaw                                                 */
/*************************************************************************/

#include "com.h"
#ifdef DEBUG_COM
    Timer timerCom;
    #define NL "\n\r"
    #define PRINT(x) xbeeTx.printf(x)   //Serial.print(x)
    #define PRINTF(x, y) xbeeTx.printf( (x) ,(y) )   //Serial.print(x, y)
    #define PRINTLN(x) PRINT(x);PRINT(NL)
    #define PRINTLNF(x, y) PRINTF((x) ,(y));PRINT(NL)
    #define START timerCom.start(); 
    #define STOP timerCom.stop()
    #define RESET timerCom.reset()
    #define READ timerCom.read_us()
    #define GET(x) x = READ
#else
    #define PRINT(x)
    #define PRINTF(x, y)
    #define PRINTLN(x)
    #define PRINTLNF(x, y) 
    #define START 
    #define STOP  
    #define RESET 
    #define READ 
    #define GET(x)
#endif


/*********************** com( PinName, PinName ) *************************/
/*                                                                       */
/*************************************************************************/

com::com( PinName tx, PinName rx , PinName rssipin) : xbeeTx( tx, NC), xbeeRx( NC, rx), rssi(rssipin)
{
    index1 = 0;                             // How many bytes are in the buffer.
    index2 = 0;                             // How many bytes are in the buffer.
    pindex = 0;                             // How many bytes are in the buffer.
    rdy2build = false;                      // Xbee is in transparent mode.
    xbeeTx.baud(BAUDRATE);                  // Setup the serial baud rate.
    xbeeRx.baud(BAUDRATE);                  // Setup the serial baud rate.
    txBuffer = new queue();
    signalStrength = 0;
    xbeeRx.attach( this, &com::callback );    // Set callback as the interrupt handler. 
    #ifdef DEBUG_COM
    xbeeTx.printf("Communication.....Done\n\r");
    #endif
    START;
}

/************************* bool isData()  ********************************/
/*                                                                       */
/*************************************************************************/

bool com::isData()
{
    return rdy2build;
}

/************************ void write( char ) *****************************/
/* Write a packet out the xbee com port.                                 */
/*                                                                       */
/* Data format byte[]                                                    */
/*                byte[0] = command.                                     */
/*                byte[1] = upper 8 bits of value.                       */
/*                byte[2] = lower 8 bits of value.                       */
/*                byte[3] = Checksum byte[0] + byte[2].                  */
/*                byte[4] = Sequence Number.                             */
/*                byte[5] = 255 End of message.                          */
/*************************************************************************/

void com::write( short command, short value  )
{  
    short lvalue = (value % 128);
    xbeeTx.putc( (char)command );           // Command
    xbeeTx.putc( (char) value / 128 );      // First 8 bits in array. 
    xbeeTx.putc( (char) lvalue);            // Second 8 bits in array.
    xbeeTx.putc( command + lvalue );        // Checksum array[0] + array[1].
    xbeeTx.putc( (char)value );             // Sequence number.
    xbeeTx.putc( 255 );                     // End of message.
}

/*************************** char ackCheck()  ********************************/
/*                                                                       */
/*************************************************************************/

void com::ackCheck()
{
    if( !txBuffer->isEmpty())
    {
    __disable_irq();
        short * pkt = txBuffer->pop();
    __enable_irq();
        write(pkt[0],pkt[1]); //may need to disable interrupt
        #ifdef DEBUG_COM
        if(pkt[1] % 5 == 0) 
        {
            PRINTLNF("len: %d",txBuffer->queueLength());
        }
        #endif
        delete[] pkt;
    
    }
}

bool com::rdy2ack()
{
    return !txBuffer->isEmpty();
}



/************************ void callback() ********************************/
/*                                                                       */
/*************************************************************************/

void com::callback()
{   
    __disable_irq();
    while( xbeeRx.readable() )
    {
        char data = xbeeRx.getc(); 
//        xbeeRx.putc(data);
        if (isA1)
        {
            if ( data == 255 && index1 > 4 )
            {
                rdy2build = true;
                pindex = index1;
                index1 = 0;
                isA1 = false;
            }
            else if ( index1 < BUFFERSIZE )
            {
                
                buffer1[index1++] = data;
            }
        }
        else
        {
            if ( data == 255 && index2 > 4 )
            {
                rdy2build = true;
                pindex = index2;
                index2 = 0;
                isA1 = true;
            }
            else if ( index2 < BUFFERSIZE )
            {
                buffer2[index2++] = data;
            }
        }
    }
    __enable_irq();
}


/********************** void packetBuilder() *****************************/
/* Creates a packet from the buffered data and places it in the rxBuffer */
/* queue to be read whenever convenient. Max value of +/- 8063.          */
/*************************************************************************/

short * com::read()
{
    if (rdy2build)
    {
        rdy2build = false;
        char * commandData = new char[5];
        if (!isA1)
        {
            commandData[4] = buffer1[--pindex];     // Sequence Number.
            commandData[3] = buffer1[--pindex];     // CheckSum value.
            commandData[2] = buffer1[--pindex];     // Second 7 bits.
            commandData[1] = buffer1[--pindex];     // Fisrt 7 bits.
            commandData[0] = buffer1[--pindex];     // Command.
        }
        else 
        {
            commandData[4] = buffer2[--pindex];     // Sequence Number.
            commandData[3] = buffer2[--pindex];     // CheckSum value.
            commandData[2] = buffer2[--pindex];     // Second 7 bits.
            commandData[1] = buffer2[--pindex];     // Fisrt 7 bits.
            commandData[0] = buffer2[--pindex];     // Command.
        }
        
//        xbeeTx.printf("Copied: %d %d %d %d %d\n\r",commandData[0],commandData[1],commandData[2],commandData[3],commandData[4]);
          
        if( commandData[0] + commandData[2] == commandData[3] ) // Validate checksum.
        {
            short * array = new short[2];
            array[0] = (short)commandData[0];
            
            short value = (short)(commandData[1] * 128 + commandData[2]);
            
            if( value > 8062 )
                value = (short)value + 57344;
            
            array[1] = value;
            if ( commandData[0] != 0)
            {
                short * ackPacket = new short[2];
                ackPacket[0] = commandData[0];
                ackPacket[1] = commandData[4];
                txBuffer->add( ackPacket ); // Ack the packet with sequence nuber.
            }
            
            delete[] commandData;
            return array;
        } 
        delete[] commandData; 
    }        
    return NULL;                                 
}



/********************** bool isSignalGood() ******************************/
/* For future use   */
/*************************************************************************/
bool com::isSignalGood()
{
    signalStrength = rssi.dutycycle();
    if (signalStrength > RSSI_THRES) return true;
    else return false;
}