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.
Dependents: Coordinator_node Router_node
xbee.cpp
- Committer:
- ShaolinPoutine
- Date:
- 2017-02-14
- Revision:
- 6:3b97770f30e6
- Parent:
- 4:e8f4d41c0fbc
- Child:
- 7:78985e92c1c5
File content as of revision 6:3b97770f30e6:
#include "xbee.h"
void XBee::pcPrint(char* c)
{
int i = 0;
while( (c)[i] != '\0')
{
mail->put(&(c[i]));
i++;
}
}
void XBee::printHexa(char c)
{
char *msb = mail->alloc();
*msb = c >> 4;
char *lsb = mail->alloc();
*lsb = c & 0xF;
if (*msb < 10)
*msb += 0x30;
else
*msb += 0x37;
if (*lsb < 10)
*lsb += 0x30;
else
*lsb += 0x37;
char * str = "0x";
pcPrint(str);
mail->put(msb);
mail->put(lsb);
str = " ";
pcPrint(str);
}
XBee::XBee(PinName reset, PinName transfer, PinName receive, Mail<char, 250>* m) :
rst(reset), comm(transfer, receive)
{
// Constructor
mail = m;
rst = 0;
wait(0.4);
rst = 1;
wait(3); // waiting for initiation
}
void XBee::SendATCommand(char firstChar, char secondChar, char *optionalParam, int paramLen)
{
// Frame Type 0x08
// Two char as parameters
char cmdtosend[10];
char sum = 0;
int cmdlength = 8;
int i = 0;
cmdtosend[0] = FRAMEDELIMITER;
cmdtosend[1] = 0x00;
cmdtosend[2] = 0x04 + paramLen;
cmdtosend[3] = 0x08;
cmdtosend[4] = 0x52;
cmdtosend[5] = firstChar;
cmdtosend[6] = secondChar;
// Ajouter les parametres au message
if(optionalParam != NULL)
{
i = 0;
cmdlength += paramLen;
while (i < paramLen)
{
mail->put(&(optionalParam)[i]);
cmdtosend[7 + i] = (optionalParam)[i];
i++;
}
pcPrint("\r\n\0");
}
// Calculate checksum
i = 3;
while (i < (cmdlength - 1))
{
sum += cmdtosend[i];
i++;
}
cmdtosend[cmdlength - 1] = 0xFF - sum;
// Envoyer la commande sur UART
i = 0;
while (i < cmdlength)
{
comm.putc(cmdtosend[i]);
i++;
}
wait(0.1);
}
char* XBee::InterpretMessage()
{
char *response = "\0";
if (comm.readable())
{
char start = comm.getc(); // = FRAMEDELIMITER
//assert
char len_msb = comm.getc();
char len_lsb = comm.getc();
int len = ((int) len_msb << 4) + (int) len_lsb;
char frame_data[len];
// Resolving frame type
char type = comm.getc();
len--;
switch (type){
case 0x88: ATCommandResponse(len);
break;
case 0x8A: ModemStatus(len);
break;
case 0x8B: ZigBeeTransmitStatus(len);
break;
case 0x90: ZigBeeReceivePacket(len);
break;
default: pcPrint("Please implement response of type\0");
//printsHexa(type);
pcPrint("\r\n\0");
for (int i = -1; i <len; i++) comm.getc();
}
}
return response;
}
void XBee::ATCommandResponse(int len)
{
char total = 0x88;
char id = comm.getc();
total += id;
char* command0 = mail->alloc();
char* command1 = mail->alloc();
*command0 = comm.getc();
total += *command0;
*command1 = comm.getc();
total += *command1;
char status = comm.getc();
total += status;
int i = 0;
len-= 4;
char data[len];
pcPrint("response to command \0");
mail->put(command0);
mail->put(command1);
pcPrint(" is \0");
if (len == 0)
{
switch (status)
{
case 0 : pcPrint("OK"); break;
case 1 : pcPrint("ERROR"); break;
case 2 : pcPrint("Invalid Command"); break;
case 3 : pcPrint("Invalid Parameter"); break;
case 4 : pcPrint("Tx Failure"); break;
default : pcPrint("Unknow error ..."); break;
}
}
while (i < len)
{
if (comm.readable())
{
data[i] = comm.getc();
total += data[i];
printHexa(data[i]);
i++;
}
}
char checksum = comm.getc();
total += checksum;
// Verify checksum
if (total != 0xFF)
{
pcPrint("Checksum is wrong\0");
}
pcPrint("\r\n\0");
}
void XBee::ModemStatus(int len)
{
char status = comm.getc();
switch (status){
case 0 : pcPrint("Hardware reset\r\n\0"); break;
case 1 : pcPrint("Watchdog timer reset\r\n\0"); break;
case 2 : pcPrint("Joined network (routers and end devices)\r\n\0"); break;
case 3 : pcPrint("Disassociated\r\n\0"); break;
case 6 : pcPrint("Coordinator started\r\n\0"); break;
case 7 : pcPrint("Network security key was updated\r\n\0"); break;
case 0x0D : pcPrint("Voltage supply limit exceeded\r\n\0"); break;
case 0x11 : pcPrint("Modem configuration changed while join in progress\r\n\0"); break;
default : pcPrint("stack error\r\n\0"); break;
}
char checksum = comm.getc();
checksum += 0x8A + status;
if (checksum != 0xFF)
{
pcPrint("Checksum is wrong\r\n\0");
}
}
void XBee::ZigBeeTransmitStatus(int len)
{
char id = comm.getc();
char msb = comm.getc();
char lsb = comm.getc();
char retry = comm.getc();
char status = comm.getc();
char discovery = comm.getc();
//pcPrint("Response to transmit id %d is : ", id);
pcPrint("Response to transmit id is : ");
if (status == 0)
{
pcPrint("Success\r\n");
}
else
{
switch (status){
case 0x01 : pcPrint("MAC ACK Failure\r\n"); break;
case 0x02 : pcPrint("CCA Failure\r\n"); break;
case 0x15 : pcPrint("Invalid destination endpoint\r\n"); break;
case 0x21 : pcPrint("Network ACK Failure\r\n"); break;
case 0x22 : pcPrint("Not Joined to Network\r\n"); break;
case 0x23 : pcPrint("Self-addressed\r\n"); break;
case 0x24 : pcPrint("Address Not Found\r\n"); break;
case 0x25 : pcPrint("Route Not Found\r\n"); break;
case 0x26 : pcPrint("Broadcast source failed to hear a neighbor relay the message\r\n"); break;
case 0x2B : pcPrint("Invalid binding table index\r\n"); break;
case 0x2C : pcPrint("Resource error lack of free buffers, timers, etc.\r\n"); break;
case 0x2D : pcPrint("Attempted broadcast with APS transmission\r\n"); break;
case 0x2E : pcPrint("Attempted unicast with APS transmission, but EE=0\r\n"); break;
case 0x32 : pcPrint("Resource error lack of free buffers, timers, etc.\r\n"); break;
case 0x74 : pcPrint("Data payload too large\r\n"); break;
default : pcPrint("Unknow error ...\r\n"); break;
}
}
}
void XBee::ZigBeeReceivePacket(int len)
{
int i = 0;
char adresse64bit[8];
char adresse16bit[2];
char receiveOptions;
while(i < 8)
{
adresse64bit[i] = comm.getc();
i++;
}
adresse16bit[0] = comm.getc();
adresse16bit[1] = comm.getc();
receiveOptions = comm.getc();
pcPrint("Data received : ");
i = 11;
while (i < len)
{
printHexa(comm.getc());
i++;
}
// Validate checksum TODO
}
void XBee::ZigBeeTransmit(int adresse16, int adresse64, char *data, int dataLength)
{
// Frame Type 0x10
// 0x0000000000000000 - Reserved 64-bit address for the coordinator
// 0x000000000000FFFF - Broadcast address
// The Transmit Status frame (0x8B) est la reponse
char cmdtosend[25];
char checksum = 0x00;
int cmdlength = 18;
int i = 3;
//ID command to set/read operating 64 bit PAN ID
//WR command to set operating 64 bit PAN ID across reboot
//OI command to read operating 16 bit PAN ID
//II command to set operating 16 bit PAN ID
cmdtosend[0] = FRAMEDELIMITER;
cmdtosend[1] = 0x00;
cmdtosend[2] = 0x0E + dataLength;
cmdtosend[3] = 0x10; // Frame type
cmdtosend[4] = 0x01; // Frame number
cmdtosend[5] = 0x00; // MSB adresse 64-bit
cmdtosend[6] = 0x00;
cmdtosend[7] = 0x00;
cmdtosend[8] = 0x00;
cmdtosend[9] = 0x00;
cmdtosend[10] = 0x00;
cmdtosend[11] = 0xFF;
cmdtosend[12] = 0xFF; // LSB adresse 64-bit
cmdtosend[13] = adresse16 >> 16; // MSB adresse 16-bit
cmdtosend[14] = adresse16 && 0b0000000011111111; // LSB adresse 16-bit
cmdtosend[15] = 0x00; // Broadcast Radius
cmdtosend[16] = 0x00; // Options
// Set RF DATA
if(data != NULL)
{
i = 0;
cmdlength += dataLength;
while (i < dataLength)
{
cmdtosend[17 + i] = (data)[i];
i++;
}
}
//cmdtosend[17] = 0x00; // Start RF DATA
//cmdtosend[18] = 0x00;
//cmdtosend[19] = 0x00;
//cmdtosend[20] = 0x00;
//cmdtosend[21] = 0x00;
//cmdtosend[22] = 0x00;
//cmdtosend[23] = 0x00;
//cmdtosend[24] = 0x00; // End RF DATA
// Calculate checksum
i = 3;
while (i < (cmdlength - 1))
{
checksum += cmdtosend[i];
i++;
}
cmdtosend[cmdlength - 1] = 0xFF - checksum;
// Envoyer la commande sur UART
i = 0;
while (i < cmdlength)
{
comm.putc(cmdtosend[i]);
i++;
}
wait(0.1);
}