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:
Thu Apr 24 04:14:22 2014 +0000
Revision:
9:1190db2717a8
Parent:
7:662171c0e984
Child:
10:ec36e1b59a39
Add protection against early ending packet

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 7:662171c0e984 105 __disable_irq();
oprospero 5:7cdf299ea7a4 106 if( !txBuffer->isEmpty() && xbeeTx.writeable())
oprospero 4:f8e953201251 107 {
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 4:f8e953201251 111 }
oprospero 7:662171c0e984 112 __enable_irq();
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 9:1190db2717a8 151 if( data == 255 && bLength > 5)
oprospero 0:26a151d2c6db 152 packetBuilder();
oprospero 0:26a151d2c6db 153 }
oprospero 4:f8e953201251 154 __enable_irq();
oprospero 0:26a151d2c6db 155 }
oprospero 0:26a151d2c6db 156
oprospero 2:bd1621102cad 157 //void com::api_callback()
oprospero 2:bd1621102cad 158 //{
oprospero 2:bd1621102cad 159 // while( xbeeRx.readable() )
oprospero 2:bd1621102cad 160 // {
oprospero 2:bd1621102cad 161 // buffer[bLength++] = xbeeRx.getc();
oprospero 2:bd1621102cad 162 // }
oprospero 2:bd1621102cad 163 //}
oprospero 2:bd1621102cad 164
oprospero 2:bd1621102cad 165
oprospero 0:26a151d2c6db 166 /********************** void packetBuilder() *****************************/
oprospero 0:26a151d2c6db 167 /* Creates a packet from the buffered data and places it in the rxBuffer */
oprospero 0:26a151d2c6db 168 /* queue to be read whenever convenient. Max value of +/- 8063. */
oprospero 0:26a151d2c6db 169 /*************************************************************************/
oprospero 0:26a151d2c6db 170
oprospero 0:26a151d2c6db 171 void com::packetBuilder()
oprospero 0:26a151d2c6db 172 {
oprospero 0:26a151d2c6db 173 char * commandData = new char[bLength];
oprospero 0:26a151d2c6db 174 commandData[4] = buffer[--bLength]; // Sequence Number.
oprospero 0:26a151d2c6db 175 commandData[3] = buffer[--bLength]; // CheckSum value.
oprospero 0:26a151d2c6db 176 commandData[2] = buffer[--bLength]; // Second 7 bits.
oprospero 0:26a151d2c6db 177 commandData[1] = buffer[--bLength]; // Fisrt 7 bits.
oprospero 0:26a151d2c6db 178 commandData[0] = buffer[--bLength]; // Command.
oprospero 0:26a151d2c6db 179
oprospero 0:26a151d2c6db 180
oprospero 0:26a151d2c6db 181 if( commandData[0] + commandData[2] == commandData[3] ) // Validate checksum.
oprospero 0:26a151d2c6db 182 {
oprospero 0:26a151d2c6db 183 short * array = new short[2];
oprospero 0:26a151d2c6db 184
oprospero 0:26a151d2c6db 185 array[0] = (short)commandData[0];
oprospero 0:26a151d2c6db 186
oprospero 0:26a151d2c6db 187 short value = (short)(commandData[1] * 128 + commandData[2]);
oprospero 0:26a151d2c6db 188
oprospero 0:26a151d2c6db 189 if( value > 8062 )
oprospero 0:26a151d2c6db 190 value = (short)value + 57344;
oprospero 0:26a151d2c6db 191
oprospero 0:26a151d2c6db 192 array[1] = value;
oprospero 0:26a151d2c6db 193 // xbeeTx.printf("Cmd: %d,\tVal: %d\n\r,",array[0],array[1]);
oprospero 0:26a151d2c6db 194 rxBuffer->add( array ); // Add to read buffer.
oprospero 2:bd1621102cad 195 // xbeeTx.putc( 255 );
oprospero 2:bd1621102cad 196 // xbeeTx.putc( 255 );
oprospero 6:4d96c8776442 197 if ( commandData[0] != 0)
oprospero 4:f8e953201251 198 {
oprospero 4:f8e953201251 199 short * ackPacket = new short[2];
oprospero 6:4d96c8776442 200 ackPacket[0] = commandData[0];
oprospero 4:f8e953201251 201 ackPacket[1] = commandData[4];
oprospero 4:f8e953201251 202 txBuffer->add( ackPacket ); // Ack the packet with sequence nuber.
oprospero 4:f8e953201251 203 }
oprospero 0:26a151d2c6db 204 }
oprospero 0:26a151d2c6db 205 delete[] commandData;
oprospero 0:26a151d2c6db 206 bLength = 0; // Reset the buffer length.
oprospero 0:26a151d2c6db 207 }
oprospero 2:bd1621102cad 208 //
oprospero 2:bd1621102cad 209 //void com::api_packetBuilder()
oprospero 2:bd1621102cad 210 //{
oprospero 2:bd1621102cad 211 //
oprospero 2:bd1621102cad 212 //}
oprospero 0:26a151d2c6db 213
oprospero 0:26a151d2c6db 214
oprospero 0:26a151d2c6db 215 /********************** bool isSignalGood() ******************************/
oprospero 0:26a151d2c6db 216 /* For future use */
oprospero 0:26a151d2c6db 217 /*************************************************************************/
oprospero 0:26a151d2c6db 218 bool com::isSignalGood()
oprospero 0:26a151d2c6db 219 {
oprospero 0:26a151d2c6db 220 signalStrength = rssi.dutycycle();
oprospero 0:26a151d2c6db 221 if (signalStrength > RSSI_THRES) return true;
oprospero 0:26a151d2c6db 222 else return false;
oprospero 0:26a151d2c6db 223 }
oprospero 0:26a151d2c6db 224
oprospero 2:bd1621102cad 225 void com::setAPImode(bool mode)
oprospero 2:bd1621102cad 226 {
oprospero 2:bd1621102cad 227 api_mode = mode;
oprospero 2:bd1621102cad 228 }
oprospero 2:bd1621102cad 229