Class containing functions usefull to communication between PC and Xbee device

Dependents:   Coordinator_node Router_node

xbee.cpp

Committer:
ShaolinPoutine
Date:
2017-02-14
Revision:
2:0000443a78fe
Parent:
1:9fb7acdb31dd
Child:
3:4c1dec78117b

File content as of revision 2:0000443a78fe:

#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;
            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");
    
    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");
    }
}