xbee communication for UWB quadcopter project Originally by Greg Abdo Forking to reduce impact of interrupt by moving packetbuilder out of the interrupt and letting be handled in the main loop

Fork of com by Prosper Van

com.cpp

Committer:
oprospero
Date:
2014-04-22
Revision:
4:f8e953201251
Parent:
2:bd1621102cad
Child:
5:7cdf299ea7a4

File content as of revision 4:f8e953201251:

/****************************** 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.
    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 read()  ********************************/
/*                                                                       */
/*************************************************************************/

void com::ackCheck()
{
    if( !txBuffer->isEmpty())
    {
        short * pkt = rxBuffer->pop();
        write(pkt[0],pkt[1]);
    }
        
}


/*************************** 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[1] = 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;
}