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.
Fork of CROTUS_XBee by
xbee.cpp
- Committer:
- libv2001
- Date:
- 2017-04-03
- Revision:
- 3:cc699ba7a827
- Parent:
- 2:406da750f115
- Child:
- 4:6ba5b06193d1
File content as of revision 3:cc699ba7a827:
#include "mbed.h" #include "rtos.h" #include "xbee.h" /*******************************************************/ /*****************PRIVATE FUNCTIONS*********************/ /*******************************************************/ namespace { DigitalOut _xbeeConnection(LED4); Serial _xbee(p9, p10); DigitalOut _xbeeRst(p8); char _destination64bit[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; char _destination16bit[2] = {0xff, 0xfe}; const int HARDWARE_RESET_SIGNAL = 0x10; const int CONNECTED_SIGNAL = 0x20; const int TICKER_SIGNAL = 0x40; const int RESPONSE_SIGNAL = 0x80; int _responseStatus; int _panID = 0xB00B; char _frameID = 0; Thread _xbeeReceiver; Thread * _xbeeTransmitter; void(*_packetReceivedCallback)(char*, int) = 0; /*******************************************************/ /*******************XBEE UTILITIES**********************/ /*******************************************************/ inline char _GetFrameID(){ ++_frameID; if (_frameID == 0){ _frameID = 1; } return _frameID; } inline uint16_t _GetFrameLength(char * buffer){ return (((uint16_t)buffer[LENGTH_MSB_IDX]) << 8) + buffer[LENGTH_LSB_IDX]; } bool _ValidateCheckSum(char * buffer){ uint16_t length = _GetFrameLength(buffer); char sum = 0; for (int i = 0; i <= length; ++i){ sum += buffer[i + API_ID_IDX]; } return sum == 0xff; } inline uint16_t _GetAtParamLength(char * buffer){ return _GetFrameLength(buffer) - AT_MIN_SIZE; } inline uint16_t _GetAtQueueParamLength(char * buffer){ return _GetFrameLength(buffer) - AT_QUEUE_MIN_SIZE; } inline uint16_t _GetTransmitDataLength(char * buffer){ return _GetFrameLength(buffer) - TRANSMIT_MIN_SIZE; } inline uint16_t _GetAtResponseParamLength(char * buffer){ return _GetFrameLength(buffer) - AT_CMD_RSP_MIN_SIZE; } inline uint16_t _GetReceivedPacketDataLength(char * buffer){ return _GetFrameLength(buffer) - RECEIVED_PACKET_MIN_SIZE; } void _SetCheckSum(char * buffer){ uint16_t length = _GetFrameLength(buffer); char sum = 0; int max = length + 3; for(int i = 3; i < max; ++i){ sum += buffer[i]; } buffer[max] = 0xff - sum; } /*******************************************************/ /**********************XBEE SEND************************/ /*******************************************************/ void _XbeeSend(char * buffer, int count){ for ( int i = 0; i < count; ++i ){ _xbee.putc(buffer[i]); wait_us(25); } } void _XbeeSendATCommand(bool queue, char * type, char * data, int dataLength){ char buffer[64]; buffer[START_IDX] = START_BYTE; buffer[LENGTH_MSB_IDX] = (dataLength + AT_MIN_SIZE) >> 8; buffer[LENGTH_LSB_IDX] = (dataLength + AT_MIN_SIZE) & 0xff; buffer[API_ID_IDX] = queue ? API_ID_AT_CMD_QUEUE : API_ID_AT_CMD; buffer[FRAME_ID_IDX] = _GetFrameID(); memcpy(&buffer[AT_CMD_ID_IDX], type, AT_CMD_ID_SIZE); memcpy(&buffer[AT_PARAM_IDX], data, dataLength); _SetCheckSum(buffer); while(true){ _XbeeSend(buffer, dataLength + AT_MIN_SIZE + FRAME_MIN_SIZE); Thread::signal_wait(RESPONSE_SIGNAL); switch (_responseStatus){ case AT_CMD_RSP_STATUS_OK: return; case AT_CMD_RSP_STATUS_ERROR: case AT_CMD_RSP_STATUS_INVALID_CMD: case AT_CMD_RSP_STATUS_INVALID_PARAM: case AT_CMD_RSP_STATUS_TX_FAILURE: default: _xbeeConnection = 0; break; } } } inline void _XbeeSendATID(){ char idBuf[8]; for (int i = 0; i < 8; ++i){ idBuf[i] = (_panID >> (56 - 8 * i)) & 0xff; } _XbeeSendATCommand(true, "ID", idBuf, 8); } inline void _XbeeSendATWR(){ _XbeeSendATCommand(true, "WR", 0, 0); } inline void _XbeeSendATAC(){ _XbeeSendATCommand(true, "AC", 0, 0); } /*******************************************************/ /********************XBEE RECEIVE***********************/ /*******************************************************/ inline char _XbeeReadChar(){ while(!_xbee.readable()){ } return _xbee.getc(); } void _HandleXbeeReceivedPacket(char * cmd){ _packetReceivedCallback(&cmd[RECEIVED_PACKET_DATA_IDX], _GetReceivedPacketDataLength(cmd)); } void _HandleXbeeModemStatus(char * cmd){ switch(cmd[MODEM_STATUS_STATUS_IDX]){ case MODEM_STATUS_HARDWARE_RST: _xbeeTransmitter->signal_set(HARDWARE_RESET_SIGNAL); break; case MODEM_STATUS_COORDINATOR_STARTED: // For the coordinator case MODEM_STATUS_JOINED_NETWORK: // For the router _xbeeTransmitter->signal_set(CONNECTED_SIGNAL); break; default: _xbeeConnection = 0; break; } } void _HandleXbeeATCommandResponse(char * cmd){ _responseStatus = cmd[AT_CMD_RSP_STATUS_IDX]; _xbeeTransmitter->signal_set(RESPONSE_SIGNAL); } void _HandleXbeeTransmitStatus(char * cmd){ switch(cmd[TRANSMIT_STATUS_DELIVERY_STATUS_IDX]){ case TRANSMIT_STATUS_OK: _responseStatus = cmd[TRANSMIT_STATUS_DELIVERY_STATUS_IDX]; _xbeeTransmitter->signal_set(RESPONSE_SIGNAL); break; default: _xbeeConnection = 0; } } void _HandleXbeeReceivedCommand(char * cmd){ switch(cmd[API_ID_IDX]){ case API_ID_AT_CMD_RSP: _HandleXbeeATCommandResponse(cmd); break; case API_ID_MODEM_STATUS: _HandleXbeeModemStatus(cmd); break; case API_ID_RECEIVED_PACKET: _HandleXbeeReceivedPacket(cmd); break; case API_ID_TRANSMIT_STATUS: _HandleXbeeTransmitStatus(cmd); break; default: _xbeeConnection = 0; break; } } /*******************************************************/ /*********************THREAD MAIN***********************/ /*******************************************************/ void _XbeeReceiver(){ char buffer[64]; while(true){ buffer[START_IDX] = _XbeeReadChar(); if (buffer[START_IDX] != START_BYTE){ _xbeeConnection = 0; continue; } buffer[LENGTH_MSB_IDX] = _XbeeReadChar(); buffer[LENGTH_LSB_IDX] = _XbeeReadChar(); int length = _GetFrameLength(buffer); for (int i = 0; i <= length; ++i){ buffer[i + API_ID_IDX] = _XbeeReadChar(); } if (!_ValidateCheckSum(buffer)){ _xbeeConnection = 0; continue; } _HandleXbeeReceivedCommand(buffer); } } }; /*******************************************************/ /******************PUBLIC FUNCTIONS*********************/ /*******************************************************/ void XbeeSendData(char * data, int dataLength){ char buffer[64]; buffer[START_IDX] = START_BYTE; buffer[LENGTH_MSB_IDX] = (dataLength + TRANSMIT_MIN_SIZE) >> 8; buffer[LENGTH_LSB_IDX] = (dataLength + TRANSMIT_MIN_SIZE) & 0xff; buffer[API_ID_IDX] = API_ID_TRANSMIT; buffer[FRAME_ID_IDX] = _GetFrameID(); memcpy(&buffer[TRANSMIT_64BIT_MSB_IDX], _destination64bit, ADDR_64BIT_SIZE); memcpy(&buffer[TRANSMIT_16BIT_MSB_IDX], _destination16bit, ADDR_16BIT_SIZE); buffer[TRANSMIT_BROADCAST_IDX] = TRANSMIT_DEFAULT_BROADCAST; buffer[TRANSMIT_OPT_IDX] = TRANSMIT_DEFAULT_OPT; memcpy(&buffer[TRANSMIT_DATA_IDX], data, dataLength); _SetCheckSum(buffer); _XbeeSend(buffer, dataLength + TRANSMIT_MIN_SIZE + FRAME_MIN_SIZE); Thread::signal_wait(RESPONSE_SIGNAL); switch (_responseStatus){ case TRANSMIT_STATUS_OK: _xbeeConnection = 1; break; default: _xbeeConnection = 0; break; } } bool InitXbee(bool coordinator, void(*packetReceivedCallback)(char*, int), Thread * xbeeTransmitter){ _packetReceivedCallback = packetReceivedCallback; _xbeeTransmitter = xbeeTransmitter; if (coordinator) { uint8_t temp[8] = {0x00, 0x13, 0xA2, 0x00, 0x40, 0x33, 0x19, 0x8D}; memcpy(_destination64bit, temp, 8); } _xbeeReceiver.start(callback(_XbeeReceiver)); _xbeeRst.write(0); wait(0.4); _xbeeRst.write(1); Thread::signal_wait(HARDWARE_RESET_SIGNAL); _XbeeSendATID(); _XbeeSendATWR(); _XbeeSendATAC(); Thread::signal_wait(CONNECTED_SIGNAL); _xbeeConnection = 1; return true; }