xbee communication for UWB quadcopter project

Dependencies:   PwmIn

com.cpp

Committer:
oprospero
Date:
2014-04-22
Revision:
6:662171c0e984
Parent:
5:4d96c8776442
Child:
9:1190db2717a8

File content as of revision 6:662171c0e984:

/****************************** 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 "mbed.h"
#include "com.h"


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

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

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

bool com::isData()
{
    
    return !rxBuffer->isEmpty();
}

/************************ 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  )
{
    if (api_mode)
    {
        short hvalue = value / 128;
        short lvalue = (value % 128);
        short sum = (2*command + hvalue + 2*lvalue + value);
        short check = sum % 256;
        xbeeTx.putc( (char) 127);               //Start Delimiter
        
        xbeeTx.putc( (char) 0);                 //Frame Data Length MSB
        xbeeTx.putc( (char) 6);                 //Frame Data Length LSB
        //Frame Data
        xbeeTx.putc( (char) command);           // Command
        xbeeTx.putc( (char) hvalue);            // 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.
        
        xbeeTx.putc( (char) 255 - check);       //Checksum
        
    }
    else
    {    
        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()
{
    __disable_irq();
    if( !txBuffer->isEmpty() && xbeeTx.writeable())
    {
        short * pkt = txBuffer->pop();
        write(pkt[0],pkt[1]); //may need to disable interrupt
        delete[] pkt;
    }
    __enable_irq();
}

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

/*************************** char read()  ********************************/
/*                                                                       */
/*************************************************************************/

short * com::read()
{
    if( !rxBuffer->isEmpty())
        return rxBuffer->pop();
        
    return NULL;
}

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

void com::callback()
{   
    __disable_irq();
    while( xbeeRx.readable() )
    {
        char data = xbeeRx.getc(); 
//        xbeeTx.printf("data: %d\n\r", data);
//        xbeeTx.printf("%d %d", data,(char) 255);
//        xbeeTx.putc( data );
        if( bLength++ < BUFFERSIZE )
            buffer[bLength] = data;      
     //
//        xbeeTx.putc( bLength );
//        xbeeTx.putc( bLength );
//        xbeeTx.putc( 255 );
        if( data == 255 )
            packetBuilder();
    }
    __enable_irq();
}

//void com::api_callback()
//{
//    while( xbeeRx.readable() )
//    {
//        buffer[bLength++] = xbeeRx.getc(); 
//    }
//}


/********************** 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.          */
/*************************************************************************/

void com::packetBuilder()
{
    char * commandData = new char[bLength];
    commandData[4] = buffer[--bLength];     // Sequence Number.
    commandData[3] = buffer[--bLength];     // CheckSum value.
    commandData[2] = buffer[--bLength];     // Second 7 bits.
    commandData[1] = buffer[--bLength];     // Fisrt 7 bits.
    commandData[0] = buffer[--bLength];     // Command.
    
      
    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;
//        xbeeTx.printf("Cmd: %d,\tVal: %d\n\r,",array[0],array[1]);
        rxBuffer->add( array );   // Add to read buffer.
//        xbeeTx.putc( 255 );
//        xbeeTx.putc( 255 );
        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;
    bLength = 0;    // Reset the buffer length.                                           
}
//
//void com::api_packetBuilder()
//{
//    
//}


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

void com::setAPImode(bool mode)
{
    api_mode = mode;
}