CROTUS / CROTUS_XBee

Dependents:   ProjetCasque

Fork of CROTUS_XBee by Valentin Libioulle

Committer:
libv2001
Date:
Mon Apr 03 18:21:05 2017 +0000
Revision:
3:cc699ba7a827
Parent:
2:406da750f115
Child:
4:6ba5b06193d1
Xbee transmission moins bloquante

Who changed what in which revision?

UserRevisionLine numberNew contents of line
libv2001 0:2a59dd59ee5e 1 #include "mbed.h"
libv2001 0:2a59dd59ee5e 2 #include "rtos.h"
libv2001 0:2a59dd59ee5e 3 #include "xbee.h"
libv2001 0:2a59dd59ee5e 4
libv2001 1:13c7d6237a53 5 /*******************************************************/
libv2001 1:13c7d6237a53 6 /*****************PRIVATE FUNCTIONS*********************/
libv2001 1:13c7d6237a53 7 /*******************************************************/
libv2001 1:13c7d6237a53 8 namespace {
libv2001 1:13c7d6237a53 9 DigitalOut _xbeeConnection(LED4);
libv2001 0:2a59dd59ee5e 10
libv2001 1:13c7d6237a53 11 Serial _xbee(p9, p10);
libv2001 1:13c7d6237a53 12 DigitalOut _xbeeRst(p8);
libv2001 1:13c7d6237a53 13
libv2001 1:13c7d6237a53 14 char _destination64bit[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
libv2001 1:13c7d6237a53 15 char _destination16bit[2] = {0xff, 0xfe};
libv2001 0:2a59dd59ee5e 16
libv2001 0:2a59dd59ee5e 17 const int HARDWARE_RESET_SIGNAL = 0x10;
libv2001 0:2a59dd59ee5e 18 const int CONNECTED_SIGNAL = 0x20;
libv2001 0:2a59dd59ee5e 19 const int TICKER_SIGNAL = 0x40;
libv2001 0:2a59dd59ee5e 20 const int RESPONSE_SIGNAL = 0x80;
libv2001 0:2a59dd59ee5e 21
libv2001 1:13c7d6237a53 22 int _responseStatus;
libv2001 0:2a59dd59ee5e 23
libv2001 1:13c7d6237a53 24 int _panID = 0xB00B;
libv2001 1:13c7d6237a53 25 char _frameID = 0;
libv2001 0:2a59dd59ee5e 26
libv2001 0:2a59dd59ee5e 27 Thread _xbeeReceiver;
libv2001 0:2a59dd59ee5e 28 Thread * _xbeeTransmitter;
libv2001 0:2a59dd59ee5e 29
libv2001 1:13c7d6237a53 30 void(*_packetReceivedCallback)(char*, int) = 0;
libv2001 1:13c7d6237a53 31
libv2001 1:13c7d6237a53 32 /*******************************************************/
libv2001 1:13c7d6237a53 33 /*******************XBEE UTILITIES**********************/
libv2001 1:13c7d6237a53 34 /*******************************************************/
libv2001 1:13c7d6237a53 35 inline char _GetFrameID(){
libv2001 1:13c7d6237a53 36 ++_frameID;
libv2001 1:13c7d6237a53 37 if (_frameID == 0){
libv2001 1:13c7d6237a53 38 _frameID = 1;
libv2001 0:2a59dd59ee5e 39 }
libv2001 1:13c7d6237a53 40 return _frameID;
libv2001 0:2a59dd59ee5e 41 }
libv2001 0:2a59dd59ee5e 42
libv2001 1:13c7d6237a53 43 inline uint16_t _GetFrameLength(char * buffer){
libv2001 0:2a59dd59ee5e 44 return (((uint16_t)buffer[LENGTH_MSB_IDX]) << 8) + buffer[LENGTH_LSB_IDX];
libv2001 0:2a59dd59ee5e 45 }
libv2001 0:2a59dd59ee5e 46
libv2001 1:13c7d6237a53 47 bool _ValidateCheckSum(char * buffer){
libv2001 1:13c7d6237a53 48 uint16_t length = _GetFrameLength(buffer);
libv2001 0:2a59dd59ee5e 49
libv2001 0:2a59dd59ee5e 50 char sum = 0;
libv2001 0:2a59dd59ee5e 51 for (int i = 0; i <= length; ++i){
libv2001 0:2a59dd59ee5e 52 sum += buffer[i + API_ID_IDX];
libv2001 0:2a59dd59ee5e 53 }
libv2001 0:2a59dd59ee5e 54
libv2001 0:2a59dd59ee5e 55 return sum == 0xff;
libv2001 0:2a59dd59ee5e 56 }
libv2001 0:2a59dd59ee5e 57
libv2001 1:13c7d6237a53 58 inline uint16_t _GetAtParamLength(char * buffer){
libv2001 1:13c7d6237a53 59 return _GetFrameLength(buffer) - AT_MIN_SIZE;
libv2001 0:2a59dd59ee5e 60 }
libv2001 0:2a59dd59ee5e 61
libv2001 1:13c7d6237a53 62 inline uint16_t _GetAtQueueParamLength(char * buffer){
libv2001 1:13c7d6237a53 63 return _GetFrameLength(buffer) - AT_QUEUE_MIN_SIZE;
libv2001 0:2a59dd59ee5e 64 }
libv2001 0:2a59dd59ee5e 65
libv2001 1:13c7d6237a53 66 inline uint16_t _GetTransmitDataLength(char * buffer){
libv2001 1:13c7d6237a53 67 return _GetFrameLength(buffer) - TRANSMIT_MIN_SIZE;
libv2001 0:2a59dd59ee5e 68 }
libv2001 0:2a59dd59ee5e 69
libv2001 1:13c7d6237a53 70 inline uint16_t _GetAtResponseParamLength(char * buffer){
libv2001 1:13c7d6237a53 71 return _GetFrameLength(buffer) - AT_CMD_RSP_MIN_SIZE;
libv2001 0:2a59dd59ee5e 72 }
libv2001 0:2a59dd59ee5e 73
libv2001 1:13c7d6237a53 74 inline uint16_t _GetReceivedPacketDataLength(char * buffer){
libv2001 1:13c7d6237a53 75 return _GetFrameLength(buffer) - RECEIVED_PACKET_MIN_SIZE;
libv2001 0:2a59dd59ee5e 76 }
libv2001 0:2a59dd59ee5e 77
libv2001 1:13c7d6237a53 78 void _SetCheckSum(char * buffer){
libv2001 1:13c7d6237a53 79 uint16_t length = _GetFrameLength(buffer);
libv2001 0:2a59dd59ee5e 80
libv2001 0:2a59dd59ee5e 81 char sum = 0;
libv2001 0:2a59dd59ee5e 82
libv2001 0:2a59dd59ee5e 83 int max = length + 3;
libv2001 0:2a59dd59ee5e 84
libv2001 0:2a59dd59ee5e 85 for(int i = 3; i < max; ++i){
libv2001 0:2a59dd59ee5e 86 sum += buffer[i];
libv2001 0:2a59dd59ee5e 87 }
libv2001 0:2a59dd59ee5e 88
libv2001 0:2a59dd59ee5e 89 buffer[max] = 0xff - sum;
libv2001 0:2a59dd59ee5e 90 }
libv2001 0:2a59dd59ee5e 91
libv2001 1:13c7d6237a53 92 /*******************************************************/
libv2001 1:13c7d6237a53 93 /**********************XBEE SEND************************/
libv2001 1:13c7d6237a53 94 /*******************************************************/
libv2001 1:13c7d6237a53 95 void _XbeeSend(char * buffer, int count){
libv2001 0:2a59dd59ee5e 96 for ( int i = 0; i < count; ++i ){
libv2001 0:2a59dd59ee5e 97 _xbee.putc(buffer[i]);
libv2001 0:2a59dd59ee5e 98 wait_us(25);
libv2001 0:2a59dd59ee5e 99 }
libv2001 0:2a59dd59ee5e 100 }
libv2001 0:2a59dd59ee5e 101
libv2001 1:13c7d6237a53 102 void _XbeeSendATCommand(bool queue, char * type, char * data, int dataLength){
libv2001 0:2a59dd59ee5e 103 char buffer[64];
libv2001 2:406da750f115 104 buffer[START_IDX] = START_BYTE;
libv2001 0:2a59dd59ee5e 105 buffer[LENGTH_MSB_IDX] = (dataLength + AT_MIN_SIZE) >> 8;
libv2001 0:2a59dd59ee5e 106 buffer[LENGTH_LSB_IDX] = (dataLength + AT_MIN_SIZE) & 0xff;
libv2001 0:2a59dd59ee5e 107 buffer[API_ID_IDX] = queue ? API_ID_AT_CMD_QUEUE : API_ID_AT_CMD;
libv2001 1:13c7d6237a53 108 buffer[FRAME_ID_IDX] = _GetFrameID();
libv2001 0:2a59dd59ee5e 109 memcpy(&buffer[AT_CMD_ID_IDX], type, AT_CMD_ID_SIZE);
libv2001 0:2a59dd59ee5e 110 memcpy(&buffer[AT_PARAM_IDX], data, dataLength);
libv2001 0:2a59dd59ee5e 111
libv2001 1:13c7d6237a53 112 _SetCheckSum(buffer);
libv2001 0:2a59dd59ee5e 113
libv2001 0:2a59dd59ee5e 114 while(true){
libv2001 1:13c7d6237a53 115 _XbeeSend(buffer, dataLength + AT_MIN_SIZE + FRAME_MIN_SIZE);
libv2001 0:2a59dd59ee5e 116
libv2001 0:2a59dd59ee5e 117 Thread::signal_wait(RESPONSE_SIGNAL);
libv2001 0:2a59dd59ee5e 118
libv2001 1:13c7d6237a53 119 switch (_responseStatus){
libv2001 0:2a59dd59ee5e 120 case AT_CMD_RSP_STATUS_OK:
libv2001 0:2a59dd59ee5e 121 return;
libv2001 0:2a59dd59ee5e 122 case AT_CMD_RSP_STATUS_ERROR:
libv2001 0:2a59dd59ee5e 123 case AT_CMD_RSP_STATUS_INVALID_CMD:
libv2001 0:2a59dd59ee5e 124 case AT_CMD_RSP_STATUS_INVALID_PARAM:
libv2001 0:2a59dd59ee5e 125 case AT_CMD_RSP_STATUS_TX_FAILURE:
libv2001 0:2a59dd59ee5e 126 default:
libv2001 0:2a59dd59ee5e 127 _xbeeConnection = 0;
libv2001 0:2a59dd59ee5e 128 break;
libv2001 0:2a59dd59ee5e 129 }
libv2001 0:2a59dd59ee5e 130 }
libv2001 0:2a59dd59ee5e 131 }
libv2001 0:2a59dd59ee5e 132
libv2001 1:13c7d6237a53 133 inline void _XbeeSendATID(){
libv2001 0:2a59dd59ee5e 134 char idBuf[8];
libv2001 0:2a59dd59ee5e 135 for (int i = 0; i < 8; ++i){
libv2001 1:13c7d6237a53 136 idBuf[i] = (_panID >> (56 - 8 * i)) & 0xff;
libv2001 0:2a59dd59ee5e 137 }
libv2001 1:13c7d6237a53 138 _XbeeSendATCommand(true, "ID", idBuf, 8);
libv2001 0:2a59dd59ee5e 139 }
libv2001 0:2a59dd59ee5e 140
libv2001 1:13c7d6237a53 141 inline void _XbeeSendATWR(){
libv2001 1:13c7d6237a53 142 _XbeeSendATCommand(true, "WR", 0, 0);
libv2001 0:2a59dd59ee5e 143 }
libv2001 0:2a59dd59ee5e 144
libv2001 1:13c7d6237a53 145 inline void _XbeeSendATAC(){
libv2001 1:13c7d6237a53 146 _XbeeSendATCommand(true, "AC", 0, 0);
libv2001 0:2a59dd59ee5e 147 }
libv2001 0:2a59dd59ee5e 148
libv2001 1:13c7d6237a53 149 /*******************************************************/
libv2001 1:13c7d6237a53 150 /********************XBEE RECEIVE***********************/
libv2001 1:13c7d6237a53 151 /*******************************************************/
libv2001 1:13c7d6237a53 152 inline char _XbeeReadChar(){
libv2001 0:2a59dd59ee5e 153 while(!_xbee.readable()){
libv2001 0:2a59dd59ee5e 154 }
libv2001 0:2a59dd59ee5e 155 return _xbee.getc();
libv2001 0:2a59dd59ee5e 156 }
libv2001 0:2a59dd59ee5e 157
libv2001 1:13c7d6237a53 158 void _HandleXbeeReceivedPacket(char * cmd){
libv2001 1:13c7d6237a53 159 _packetReceivedCallback(&cmd[RECEIVED_PACKET_DATA_IDX], _GetReceivedPacketDataLength(cmd));
libv2001 0:2a59dd59ee5e 160 }
libv2001 0:2a59dd59ee5e 161
libv2001 1:13c7d6237a53 162 void _HandleXbeeModemStatus(char * cmd){
libv2001 0:2a59dd59ee5e 163 switch(cmd[MODEM_STATUS_STATUS_IDX]){
libv2001 0:2a59dd59ee5e 164 case MODEM_STATUS_HARDWARE_RST:
libv2001 0:2a59dd59ee5e 165 _xbeeTransmitter->signal_set(HARDWARE_RESET_SIGNAL);
libv2001 0:2a59dd59ee5e 166 break;
libv2001 0:2a59dd59ee5e 167 case MODEM_STATUS_COORDINATOR_STARTED: // For the coordinator
libv2001 2:406da750f115 168 case MODEM_STATUS_JOINED_NETWORK: // For the router
libv2001 0:2a59dd59ee5e 169 _xbeeTransmitter->signal_set(CONNECTED_SIGNAL);
libv2001 0:2a59dd59ee5e 170 break;
libv2001 0:2a59dd59ee5e 171 default:
libv2001 0:2a59dd59ee5e 172 _xbeeConnection = 0;
libv2001 0:2a59dd59ee5e 173 break;
libv2001 0:2a59dd59ee5e 174 }
libv2001 0:2a59dd59ee5e 175 }
libv2001 0:2a59dd59ee5e 176
libv2001 1:13c7d6237a53 177 void _HandleXbeeATCommandResponse(char * cmd){
libv2001 1:13c7d6237a53 178 _responseStatus = cmd[AT_CMD_RSP_STATUS_IDX];
libv2001 0:2a59dd59ee5e 179 _xbeeTransmitter->signal_set(RESPONSE_SIGNAL);
libv2001 0:2a59dd59ee5e 180 }
libv2001 0:2a59dd59ee5e 181
libv2001 1:13c7d6237a53 182 void _HandleXbeeTransmitStatus(char * cmd){
libv2001 0:2a59dd59ee5e 183 switch(cmd[TRANSMIT_STATUS_DELIVERY_STATUS_IDX]){
libv2001 0:2a59dd59ee5e 184 case TRANSMIT_STATUS_OK:
libv2001 1:13c7d6237a53 185 _responseStatus = cmd[TRANSMIT_STATUS_DELIVERY_STATUS_IDX];
libv2001 0:2a59dd59ee5e 186 _xbeeTransmitter->signal_set(RESPONSE_SIGNAL);
libv2001 0:2a59dd59ee5e 187 break;
libv2001 0:2a59dd59ee5e 188 default:
libv2001 0:2a59dd59ee5e 189 _xbeeConnection = 0;
libv2001 0:2a59dd59ee5e 190 }
libv2001 0:2a59dd59ee5e 191 }
libv2001 0:2a59dd59ee5e 192
libv2001 1:13c7d6237a53 193 void _HandleXbeeReceivedCommand(char * cmd){
libv2001 0:2a59dd59ee5e 194 switch(cmd[API_ID_IDX]){
libv2001 0:2a59dd59ee5e 195 case API_ID_AT_CMD_RSP:
libv2001 1:13c7d6237a53 196 _HandleXbeeATCommandResponse(cmd);
libv2001 0:2a59dd59ee5e 197 break;
libv2001 0:2a59dd59ee5e 198 case API_ID_MODEM_STATUS:
libv2001 1:13c7d6237a53 199 _HandleXbeeModemStatus(cmd);
libv2001 0:2a59dd59ee5e 200 break;
libv2001 0:2a59dd59ee5e 201 case API_ID_RECEIVED_PACKET:
libv2001 1:13c7d6237a53 202 _HandleXbeeReceivedPacket(cmd);
libv2001 0:2a59dd59ee5e 203 break;
libv2001 0:2a59dd59ee5e 204 case API_ID_TRANSMIT_STATUS:
libv2001 1:13c7d6237a53 205 _HandleXbeeTransmitStatus(cmd);
libv2001 0:2a59dd59ee5e 206 break;
libv2001 0:2a59dd59ee5e 207 default:
libv2001 0:2a59dd59ee5e 208 _xbeeConnection = 0;
libv2001 0:2a59dd59ee5e 209 break;
libv2001 0:2a59dd59ee5e 210 }
libv2001 0:2a59dd59ee5e 211 }
libv2001 0:2a59dd59ee5e 212
libv2001 1:13c7d6237a53 213 /*******************************************************/
libv2001 1:13c7d6237a53 214 /*********************THREAD MAIN***********************/
libv2001 1:13c7d6237a53 215 /*******************************************************/
libv2001 0:2a59dd59ee5e 216 void _XbeeReceiver(){
libv2001 0:2a59dd59ee5e 217 char buffer[64];
libv2001 0:2a59dd59ee5e 218 while(true){
libv2001 1:13c7d6237a53 219 buffer[START_IDX] = _XbeeReadChar();
libv2001 2:406da750f115 220 if (buffer[START_IDX] != START_BYTE){
libv2001 0:2a59dd59ee5e 221 _xbeeConnection = 0;
libv2001 0:2a59dd59ee5e 222 continue;
libv2001 0:2a59dd59ee5e 223 }
libv2001 1:13c7d6237a53 224 buffer[LENGTH_MSB_IDX] = _XbeeReadChar();
libv2001 1:13c7d6237a53 225 buffer[LENGTH_LSB_IDX] = _XbeeReadChar();
libv2001 1:13c7d6237a53 226 int length = _GetFrameLength(buffer);
libv2001 0:2a59dd59ee5e 227
libv2001 0:2a59dd59ee5e 228 for (int i = 0; i <= length; ++i){
libv2001 1:13c7d6237a53 229 buffer[i + API_ID_IDX] = _XbeeReadChar();
libv2001 0:2a59dd59ee5e 230 }
libv2001 1:13c7d6237a53 231 if (!_ValidateCheckSum(buffer)){
libv2001 0:2a59dd59ee5e 232 _xbeeConnection = 0;
libv2001 0:2a59dd59ee5e 233 continue;
libv2001 0:2a59dd59ee5e 234 }
libv2001 0:2a59dd59ee5e 235
libv2001 1:13c7d6237a53 236 _HandleXbeeReceivedCommand(buffer);
libv2001 0:2a59dd59ee5e 237 }
libv2001 0:2a59dd59ee5e 238 }
libv2001 0:2a59dd59ee5e 239
libv2001 0:2a59dd59ee5e 240 };
libv2001 0:2a59dd59ee5e 241
libv2001 0:2a59dd59ee5e 242 /*******************************************************/
libv2001 1:13c7d6237a53 243 /******************PUBLIC FUNCTIONS*********************/
libv2001 0:2a59dd59ee5e 244 /*******************************************************/
libv2001 1:13c7d6237a53 245 void XbeeSendData(char * data, int dataLength){
libv2001 0:2a59dd59ee5e 246 char buffer[64];
libv2001 2:406da750f115 247 buffer[START_IDX] = START_BYTE;
libv2001 0:2a59dd59ee5e 248 buffer[LENGTH_MSB_IDX] = (dataLength + TRANSMIT_MIN_SIZE) >> 8;
libv2001 0:2a59dd59ee5e 249 buffer[LENGTH_LSB_IDX] = (dataLength + TRANSMIT_MIN_SIZE) & 0xff;
libv2001 0:2a59dd59ee5e 250 buffer[API_ID_IDX] = API_ID_TRANSMIT;
libv2001 1:13c7d6237a53 251 buffer[FRAME_ID_IDX] = _GetFrameID();
libv2001 1:13c7d6237a53 252 memcpy(&buffer[TRANSMIT_64BIT_MSB_IDX], _destination64bit, ADDR_64BIT_SIZE);
libv2001 1:13c7d6237a53 253 memcpy(&buffer[TRANSMIT_16BIT_MSB_IDX], _destination16bit, ADDR_16BIT_SIZE);
libv2001 0:2a59dd59ee5e 254 buffer[TRANSMIT_BROADCAST_IDX] = TRANSMIT_DEFAULT_BROADCAST;
libv2001 0:2a59dd59ee5e 255 buffer[TRANSMIT_OPT_IDX] = TRANSMIT_DEFAULT_OPT;
libv2001 0:2a59dd59ee5e 256 memcpy(&buffer[TRANSMIT_DATA_IDX], data, dataLength);
libv2001 0:2a59dd59ee5e 257
libv2001 1:13c7d6237a53 258 _SetCheckSum(buffer);
libv2001 0:2a59dd59ee5e 259
libv2001 3:cc699ba7a827 260 _XbeeSend(buffer, dataLength + TRANSMIT_MIN_SIZE + FRAME_MIN_SIZE);
libv2001 3:cc699ba7a827 261
libv2001 3:cc699ba7a827 262 Thread::signal_wait(RESPONSE_SIGNAL);
libv2001 0:2a59dd59ee5e 263
libv2001 3:cc699ba7a827 264 switch (_responseStatus){
libv2001 3:cc699ba7a827 265 case TRANSMIT_STATUS_OK:
libv2001 3:cc699ba7a827 266 _xbeeConnection = 1;
libv2001 3:cc699ba7a827 267 break;
libv2001 3:cc699ba7a827 268 default:
libv2001 3:cc699ba7a827 269 _xbeeConnection = 0;
libv2001 3:cc699ba7a827 270 break;
libv2001 0:2a59dd59ee5e 271 }
libv2001 0:2a59dd59ee5e 272 }
libv2001 0:2a59dd59ee5e 273
libv2001 1:13c7d6237a53 274 bool InitXbee(bool coordinator, void(*packetReceivedCallback)(char*, int), Thread * xbeeTransmitter){
libv2001 1:13c7d6237a53 275 _packetReceivedCallback = packetReceivedCallback;
libv2001 0:2a59dd59ee5e 276 _xbeeTransmitter = xbeeTransmitter;
libv2001 0:2a59dd59ee5e 277
libv2001 0:2a59dd59ee5e 278 if (coordinator)
libv2001 0:2a59dd59ee5e 279 {
libv2001 0:2a59dd59ee5e 280 uint8_t temp[8] = {0x00, 0x13, 0xA2, 0x00, 0x40, 0x33, 0x19, 0x8D};
libv2001 1:13c7d6237a53 281 memcpy(_destination64bit, temp, 8);
libv2001 0:2a59dd59ee5e 282 }
libv2001 0:2a59dd59ee5e 283
libv2001 0:2a59dd59ee5e 284 _xbeeReceiver.start(callback(_XbeeReceiver));
libv2001 0:2a59dd59ee5e 285
libv2001 0:2a59dd59ee5e 286 _xbeeRst.write(0);
libv2001 0:2a59dd59ee5e 287 wait(0.4);
libv2001 0:2a59dd59ee5e 288 _xbeeRst.write(1);
libv2001 0:2a59dd59ee5e 289
libv2001 0:2a59dd59ee5e 290 Thread::signal_wait(HARDWARE_RESET_SIGNAL);
libv2001 0:2a59dd59ee5e 291
libv2001 1:13c7d6237a53 292 _XbeeSendATID();
libv2001 1:13c7d6237a53 293 _XbeeSendATWR();
libv2001 1:13c7d6237a53 294 _XbeeSendATAC();
libv2001 0:2a59dd59ee5e 295
libv2001 0:2a59dd59ee5e 296 Thread::signal_wait(CONNECTED_SIGNAL);
libv2001 0:2a59dd59ee5e 297
libv2001 0:2a59dd59ee5e 298 _xbeeConnection = 1;
libv2001 0:2a59dd59ee5e 299
libv2001 0:2a59dd59ee5e 300 return true;
libv2001 0:2a59dd59ee5e 301 }