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

Committer:
oprospero
Date:
Fri Apr 25 06:21:19 2014 +0000
Revision:
11:d1f488302d06
Parent:
10:ec36e1b59a39
Child:
12:bf4642578682
small updates;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
oprospero 0:26a151d2c6db 1 /****************************** com.cpp **********************************/
oprospero 0:26a151d2c6db 2 /* Version: 1.0 */
oprospero 0:26a151d2c6db 3 /* Last Updated: June 1, 2013 */
oprospero 0:26a151d2c6db 4 /* */
oprospero 0:26a151d2c6db 5 /* The com class implements reliable data transfer between two nodes */
oprospero 0:26a151d2c6db 6 /*using a checksum and a sequence number for guaranteed message delivery */
oprospero 0:26a151d2c6db 7 /*over an xbee modem connected to the passed in tx and rx pins. Messages */
oprospero 0:26a151d2c6db 8 /*are received and placed in the rxBuffer to be read when convenient. */
oprospero 0:26a151d2c6db 9 /*Messages are encoded by sending a byte with the value of the command */
oprospero 0:26a151d2c6db 10 /*then and int of the command. */
oprospero 0:26a151d2c6db 11 /* */
oprospero 0:26a151d2c6db 12 /* Commands: 0 -> Ack, does not get placed in rxQueue. */
oprospero 0:26a151d2c6db 13 /* 1 -> Throttle */
oprospero 0:26a151d2c6db 14 /* 2 -> Pitch */
oprospero 0:26a151d2c6db 15 /* 3 -> Roll */
oprospero 0:26a151d2c6db 16 /* 4 -> Yaw */
oprospero 0:26a151d2c6db 17 /*************************************************************************/
oprospero 0:26a151d2c6db 18
oprospero 0:26a151d2c6db 19 #include "mbed.h"
oprospero 0:26a151d2c6db 20 #include "com.h"
oprospero 0:26a151d2c6db 21
oprospero 1:4f53de75bc96 22
oprospero 0:26a151d2c6db 23 /*********************** com( PinName, PinName ) *************************/
oprospero 0:26a151d2c6db 24 /* */
oprospero 0:26a151d2c6db 25 /*************************************************************************/
oprospero 0:26a151d2c6db 26
oprospero 2:bd1621102cad 27 com::com( PinName tx, PinName rx , PinName rssipin) : xbeeTx( tx, NC), xbeeRx( NC, rx), rssi(rssipin)
oprospero 0:26a151d2c6db 28 {
oprospero 0:26a151d2c6db 29 bLength = 0; // How many bytes are in the buffer.
oprospero 2:bd1621102cad 30 api_mode = false; // Xbee is in transparent mode.
oprospero 1:4f53de75bc96 31 xbeeTx.baud(BAUDRATE); // Setup the serial baud rate.
oprospero 0:26a151d2c6db 32 xbeeRx.baud(BAUDRATE); // Setup the serial baud rate.
oprospero 0:26a151d2c6db 33 rxBuffer = new queue(); // Point to the rxQueue.
oprospero 5:7cdf299ea7a4 34 txBuffer = new queue();
oprospero 0:26a151d2c6db 35 signalStrength = 0;
oprospero 0:26a151d2c6db 36 xbeeRx.attach( this, &com::callback ); // Set callback as the interrupt handler.
oprospero 1:4f53de75bc96 37 #ifdef DEBUG
oprospero 0:26a151d2c6db 38 xbeeTx.printf("Communication.....Done\n\r");
oprospero 1:4f53de75bc96 39 #endif
oprospero 0:26a151d2c6db 40 }
oprospero 0:26a151d2c6db 41
oprospero 0:26a151d2c6db 42 /************************* bool isData() ********************************/
oprospero 0:26a151d2c6db 43 /* */
oprospero 0:26a151d2c6db 44 /*************************************************************************/
oprospero 0:26a151d2c6db 45
oprospero 0:26a151d2c6db 46 bool com::isData()
oprospero 0:26a151d2c6db 47 {
oprospero 2:bd1621102cad 48
oprospero 1:4f53de75bc96 49 return !rxBuffer->isEmpty();
oprospero 0:26a151d2c6db 50 }
oprospero 0:26a151d2c6db 51
oprospero 0:26a151d2c6db 52 /************************ void write( char ) *****************************/
oprospero 0:26a151d2c6db 53 /* Write a packet out the xbee com port. */
oprospero 0:26a151d2c6db 54 /* */
oprospero 0:26a151d2c6db 55 /* Data format byte[] */
oprospero 0:26a151d2c6db 56 /* byte[0] = command. */
oprospero 0:26a151d2c6db 57 /* byte[1] = upper 8 bits of value. */
oprospero 0:26a151d2c6db 58 /* byte[2] = lower 8 bits of value. */
oprospero 0:26a151d2c6db 59 /* byte[3] = Checksum byte[0] + byte[2]. */
oprospero 0:26a151d2c6db 60 /* byte[4] = Sequence Number. */
oprospero 0:26a151d2c6db 61 /* byte[5] = 255 End of message. */
oprospero 0:26a151d2c6db 62 /*************************************************************************/
oprospero 0:26a151d2c6db 63
oprospero 0:26a151d2c6db 64 void com::write( short command, short value )
oprospero 0:26a151d2c6db 65 {
oprospero 2:bd1621102cad 66 if (api_mode)
oprospero 2:bd1621102cad 67 {
oprospero 2:bd1621102cad 68 short hvalue = value / 128;
oprospero 2:bd1621102cad 69 short lvalue = (value % 128);
oprospero 2:bd1621102cad 70 short sum = (2*command + hvalue + 2*lvalue + value);
oprospero 2:bd1621102cad 71 short check = sum % 256;
oprospero 2:bd1621102cad 72 xbeeTx.putc( (char) 127); //Start Delimiter
oprospero 2:bd1621102cad 73
oprospero 2:bd1621102cad 74 xbeeTx.putc( (char) 0); //Frame Data Length MSB
oprospero 2:bd1621102cad 75 xbeeTx.putc( (char) 6); //Frame Data Length LSB
oprospero 2:bd1621102cad 76 //Frame Data
oprospero 2:bd1621102cad 77 xbeeTx.putc( (char) command); // Command
oprospero 2:bd1621102cad 78 xbeeTx.putc( (char) hvalue); // First 8 bits in array.
oprospero 2:bd1621102cad 79 xbeeTx.putc( (char) lvalue); // Second 8 bits in array.
oprospero 2:bd1621102cad 80 xbeeTx.putc( command + lvalue ); // Checksum array[0] + array[1].
oprospero 2:bd1621102cad 81 xbeeTx.putc( (char) value); // Sequence number.
oprospero 2:bd1621102cad 82 xbeeTx.putc( 255 ); // End of message.
oprospero 2:bd1621102cad 83
oprospero 2:bd1621102cad 84 xbeeTx.putc( (char) 255 - check); //Checksum
oprospero 2:bd1621102cad 85
oprospero 2:bd1621102cad 86 }
oprospero 2:bd1621102cad 87 else
oprospero 2:bd1621102cad 88 {
oprospero 2:bd1621102cad 89 short lvalue = (value % 128);
oprospero 2:bd1621102cad 90 xbeeTx.putc( (char)command ); // Command
oprospero 2:bd1621102cad 91 xbeeTx.putc( (char) value / 128 ); // First 8 bits in array.
oprospero 2:bd1621102cad 92 xbeeTx.putc( (char) lvalue); // Second 8 bits in array.
oprospero 2:bd1621102cad 93 xbeeTx.putc( command + lvalue ); // Checksum array[0] + array[1].
oprospero 2:bd1621102cad 94 xbeeTx.putc( (char)value ); // Sequence number.
oprospero 2:bd1621102cad 95 xbeeTx.putc( 255 ); // End of message.
oprospero 2:bd1621102cad 96 }
oprospero 0:26a151d2c6db 97 }
oprospero 0:26a151d2c6db 98
oprospero 5:7cdf299ea7a4 99 /*************************** char ackCheck() ********************************/
oprospero 0:26a151d2c6db 100 /* */
oprospero 0:26a151d2c6db 101 /*************************************************************************/
oprospero 0:26a151d2c6db 102
oprospero 4:f8e953201251 103 void com::ackCheck()
oprospero 4:f8e953201251 104 {
oprospero 5:7cdf299ea7a4 105 if( !txBuffer->isEmpty() && xbeeTx.writeable())
oprospero 4:f8e953201251 106 {
oprospero 11:d1f488302d06 107 __disable_irq();
oprospero 5:7cdf299ea7a4 108 short * pkt = txBuffer->pop();
oprospero 5:7cdf299ea7a4 109 write(pkt[0],pkt[1]); //may need to disable interrupt
oprospero 5:7cdf299ea7a4 110 delete[] pkt;
oprospero 11:d1f488302d06 111 __enable_irq();
oprospero 4:f8e953201251 112 }
oprospero 4:f8e953201251 113 }
oprospero 4:f8e953201251 114
oprospero 5:7cdf299ea7a4 115 bool com::rdy2ack()
oprospero 5:7cdf299ea7a4 116 {
oprospero 5:7cdf299ea7a4 117 return !txBuffer->isEmpty();
oprospero 5:7cdf299ea7a4 118 }
oprospero 4:f8e953201251 119
oprospero 4:f8e953201251 120 /*************************** char read() ********************************/
oprospero 4:f8e953201251 121 /* */
oprospero 4:f8e953201251 122 /*************************************************************************/
oprospero 4:f8e953201251 123
oprospero 0:26a151d2c6db 124 short * com::read()
oprospero 0:26a151d2c6db 125 {
oprospero 0:26a151d2c6db 126 if( !rxBuffer->isEmpty())
oprospero 0:26a151d2c6db 127 return rxBuffer->pop();
oprospero 0:26a151d2c6db 128
oprospero 0:26a151d2c6db 129 return NULL;
oprospero 0:26a151d2c6db 130 }
oprospero 0:26a151d2c6db 131
oprospero 0:26a151d2c6db 132 /************************ void callback() ********************************/
oprospero 0:26a151d2c6db 133 /* */
oprospero 0:26a151d2c6db 134 /*************************************************************************/
oprospero 0:26a151d2c6db 135
oprospero 0:26a151d2c6db 136 void com::callback()
oprospero 0:26a151d2c6db 137 {
oprospero 4:f8e953201251 138 __disable_irq();
oprospero 0:26a151d2c6db 139 while( xbeeRx.readable() )
oprospero 0:26a151d2c6db 140 {
oprospero 0:26a151d2c6db 141 char data = xbeeRx.getc();
oprospero 0:26a151d2c6db 142 // xbeeTx.printf("data: %d\n\r", data);
oprospero 2:bd1621102cad 143 // xbeeTx.printf("%d %d", data,(char) 255);
oprospero 2:bd1621102cad 144 // xbeeTx.putc( data );
oprospero 0:26a151d2c6db 145 if( bLength++ < BUFFERSIZE )
oprospero 0:26a151d2c6db 146 buffer[bLength] = data;
oprospero 4:f8e953201251 147 //
oprospero 4:f8e953201251 148 // xbeeTx.putc( bLength );
oprospero 4:f8e953201251 149 // xbeeTx.putc( bLength );
oprospero 4:f8e953201251 150 // xbeeTx.putc( 255 );
oprospero 10:ec36e1b59a39 151 //2nd condition ensure that we have a full size packet before building
oprospero 10:ec36e1b59a39 152 if( data == 255 && bLength > 5)
oprospero 0:26a151d2c6db 153 packetBuilder();
oprospero 0:26a151d2c6db 154 }
oprospero 4:f8e953201251 155 __enable_irq();
oprospero 0:26a151d2c6db 156 }
oprospero 0:26a151d2c6db 157
oprospero 2:bd1621102cad 158 //void com::api_callback()
oprospero 2:bd1621102cad 159 //{
oprospero 2:bd1621102cad 160 // while( xbeeRx.readable() )
oprospero 2:bd1621102cad 161 // {
oprospero 2:bd1621102cad 162 // buffer[bLength++] = xbeeRx.getc();
oprospero 2:bd1621102cad 163 // }
oprospero 2:bd1621102cad 164 //}
oprospero 2:bd1621102cad 165
oprospero 2:bd1621102cad 166
oprospero 0:26a151d2c6db 167 /********************** void packetBuilder() *****************************/
oprospero 0:26a151d2c6db 168 /* Creates a packet from the buffered data and places it in the rxBuffer */
oprospero 0:26a151d2c6db 169 /* queue to be read whenever convenient. Max value of +/- 8063. */
oprospero 0:26a151d2c6db 170 /*************************************************************************/
oprospero 0:26a151d2c6db 171
oprospero 0:26a151d2c6db 172 void com::packetBuilder()
oprospero 0:26a151d2c6db 173 {
oprospero 0:26a151d2c6db 174 char * commandData = new char[bLength];
oprospero 0:26a151d2c6db 175 commandData[4] = buffer[--bLength]; // Sequence Number.
oprospero 0:26a151d2c6db 176 commandData[3] = buffer[--bLength]; // CheckSum value.
oprospero 0:26a151d2c6db 177 commandData[2] = buffer[--bLength]; // Second 7 bits.
oprospero 0:26a151d2c6db 178 commandData[1] = buffer[--bLength]; // Fisrt 7 bits.
oprospero 0:26a151d2c6db 179 commandData[0] = buffer[--bLength]; // Command.
oprospero 0:26a151d2c6db 180
oprospero 0:26a151d2c6db 181
oprospero 0:26a151d2c6db 182 if( commandData[0] + commandData[2] == commandData[3] ) // Validate checksum.
oprospero 0:26a151d2c6db 183 {
oprospero 0:26a151d2c6db 184 short * array = new short[2];
oprospero 0:26a151d2c6db 185
oprospero 0:26a151d2c6db 186 array[0] = (short)commandData[0];
oprospero 0:26a151d2c6db 187
oprospero 0:26a151d2c6db 188 short value = (short)(commandData[1] * 128 + commandData[2]);
oprospero 0:26a151d2c6db 189
oprospero 0:26a151d2c6db 190 if( value > 8062 )
oprospero 0:26a151d2c6db 191 value = (short)value + 57344;
oprospero 0:26a151d2c6db 192
oprospero 0:26a151d2c6db 193 array[1] = value;
oprospero 0:26a151d2c6db 194 // xbeeTx.printf("Cmd: %d,\tVal: %d\n\r,",array[0],array[1]);
oprospero 0:26a151d2c6db 195 rxBuffer->add( array ); // Add to read buffer.
oprospero 2:bd1621102cad 196 // xbeeTx.putc( 255 );
oprospero 2:bd1621102cad 197 // xbeeTx.putc( 255 );
oprospero 6:4d96c8776442 198 if ( commandData[0] != 0)
oprospero 4:f8e953201251 199 {
oprospero 4:f8e953201251 200 short * ackPacket = new short[2];
oprospero 6:4d96c8776442 201 ackPacket[0] = commandData[0];
oprospero 4:f8e953201251 202 ackPacket[1] = commandData[4];
oprospero 4:f8e953201251 203 txBuffer->add( ackPacket ); // Ack the packet with sequence nuber.
oprospero 4:f8e953201251 204 }
oprospero 0:26a151d2c6db 205 }
oprospero 0:26a151d2c6db 206 delete[] commandData;
oprospero 0:26a151d2c6db 207 bLength = 0; // Reset the buffer length.
oprospero 0:26a151d2c6db 208 }
oprospero 2:bd1621102cad 209 //
oprospero 2:bd1621102cad 210 //void com::api_packetBuilder()
oprospero 2:bd1621102cad 211 //{
oprospero 2:bd1621102cad 212 //
oprospero 2:bd1621102cad 213 //}
oprospero 0:26a151d2c6db 214
oprospero 0:26a151d2c6db 215
oprospero 0:26a151d2c6db 216 /********************** bool isSignalGood() ******************************/
oprospero 0:26a151d2c6db 217 /* For future use */
oprospero 0:26a151d2c6db 218 /*************************************************************************/
oprospero 0:26a151d2c6db 219 bool com::isSignalGood()
oprospero 0:26a151d2c6db 220 {
oprospero 0:26a151d2c6db 221 signalStrength = rssi.dutycycle();
oprospero 0:26a151d2c6db 222 if (signalStrength > RSSI_THRES) return true;
oprospero 0:26a151d2c6db 223 else return false;
oprospero 0:26a151d2c6db 224 }
oprospero 0:26a151d2c6db 225
oprospero 2:bd1621102cad 226 void com::setAPImode(bool mode)
oprospero 2:bd1621102cad 227 {
oprospero 2:bd1621102cad 228 api_mode = mode;
oprospero 2:bd1621102cad 229 }
oprospero 2:bd1621102cad 230