Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
com.cpp
- Committer:
- oprospero
- Date:
- 2014-04-24
- Revision:
- 9:1190db2717a8
- Parent:
- 6:662171c0e984
- Child:
- 10:ec36e1b59a39
File content as of revision 9:1190db2717a8:
/****************************** 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 && bLength > 5)
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;
}