pre commentaire

Dependencies:   EthernetInterface WebSocketClient mbed-rtos mbed

Fork of Code_APP3_C by Éric Bisson

xbee.cpp

Committer:
JoeyDionne
Date:
2017-02-14
Revision:
11:f0ceb634d85c
Parent:
10:565271e4d52a

File content as of revision 11:f0ceb634d85c:

#include "xbee.h"

Timeout timeOut;
AnalogOut led_error(p18);
void LED_TurnOff()
{
    led_error = 0;
}

//--------------------------------------------------------------//
// Fonction d'envoie de données pour ZigBee (Transmit request)
// Testé et fonctionnel
//--------------------------------------------------------------//
void send(Serial* COM, CArray* message)
{
    short opt_size = 0;
    COM->putc(0x7E); // Start delimiter
    COM->putc(0x00); // length MSB is always 0
    
    if (message->_FrameType == 0x08) // Les commandes AT ne reçoivent pas d'addresses
    {
        COM->putc(6);
    }
    else
    {
        COM->putc(message->size + 12 + message->opt_size);
    }

    COM->putc(message->_FrameType);
    COM->putc(0x01); // Frame ID
    
    if (message->_FrameType != 0x08) // Les commandes AT ne reçoivent pas d'addresses
    {
        COM->putc(message->_64bit.bit[0]);
        COM->putc(message->_64bit.bit[1]);
        COM->putc(message->_64bit.bit[2]);
        COM->putc(message->_64bit.bit[3]);
        COM->putc(message->_64bit.bit[4]);
        COM->putc(message->_64bit.bit[5]);
        COM->putc(message->_64bit.bit[6]);
        COM->putc(message->_64bit.bit[7]);
        COM->putc(message->_16bit.bit[0]);
        COM->putc(message->_16bit.bit[1]);
        
        for (int i = 0; i < message->opt_size; i++)
        {
            opt_size += message->options[i];
            COM->putc(message->options[i]);
        }
    }
    
    for (int j = 0; j < message->size; j++)
    {
        COM->putc(message->_ptr[j]);
    }
    COM->putc(calculate_checksum(message, 
        message->_FrameType + 
        0x01 +
        opt_size +      
        message->_16bit.bit[0] + 
        message->_16bit.bit[1] + 
        message->_64bit.bit[0] + 
        message->_64bit.bit[1] + 
        message->_64bit.bit[2] + 
        message->_64bit.bit[3] + 
        message->_64bit.bit[4] + 
        message->_64bit.bit[5] + 
        message->_64bit.bit[6] + 
        message->_64bit.bit[7]
    ));
}
//--------------------------------------------------------------//

//--------------------------------------------------------------//
// Fonction pour la réception de données (Packet Receive)
// Testé et fonctionnel
//--------------------------------------------------------------//
void read(Serial* COM, CArray* returnValue)
{
    char BYTE_ID = 0;
    char opts = 0;
    bool bIsTrame = false;
    while (true)
    if (COM->readable())
    {            
        char value = COM->getc();
        
        if (bIsTrame)
        {
            switch (BYTE_ID)
            {
            case 1:
                break;
            case 2: // on ignore le 1, car c'est toujours 0x00
                returnValue->size = value - 12;
                break;
            case 3:                  
                if (value != 0x90)
                    return;
                returnValue->_FrameType = value;
                break;
            case 4:
            case 5:
            case 6:
            case 7:
            case 8:
            case 9:
            case 10:
            case 11:
                returnValue->_64bit.bit[BYTE_ID - 4] = value;
                break;
            case 12:
            case 13: // <-- Addresse 16 bit de l'envoyeur ici
                returnValue->_16bit.bit[BYTE_ID - 12] = value;
                break;
            case 14: // je gère pas les options pour là
                opts = value;
                break;
            default:
                if (BYTE_ID < 15 + returnValue->size)
                {
                    if (returnValue->_ptr == NULL)
                        returnValue->_ptr = new char[returnValue->size];
                        
                    returnValue->_ptr[BYTE_ID - 15] = value;
                    break;
                }
                // Finalement, le checksum. On vérifie que c'est bon
                if (value != calculate_checksum(returnValue, 
                        0x90 +
                        opts + 
                        returnValue->_16bit.bit[0] + 
                        returnValue->_16bit.bit[1] + 
                        returnValue->_64bit.bit[0] + 
                        returnValue->_64bit.bit[1] + 
                        returnValue->_64bit.bit[2] + 
                        returnValue->_64bit.bit[3] + 
                        returnValue->_64bit.bit[4] + 
                        returnValue->_64bit.bit[5] + 
                        returnValue->_64bit.bit[6] + 
                        returnValue->_64bit.bit[7]
                ))
                {
                    // Gestion d'erreur ici?
                    led_error = 1;
                    timeOut.attach(LED_TurnOff, 1);
                }
                return;
            }
        }
        else if (value == 0x7E)
            bIsTrame = true;
        else
            return;

        //wait_ms(3); // petit sleep pour recevoir un nouveau byte
        BYTE_ID++;
    }
}
//--------------------------------------------------------------//

//--------------------------------------------------------------//
// Fonction de checksum pour le protocole ZigBee
// Testé et fonctionnel
//--------------------------------------------------------------//
char calculate_checksum(CArray* message, short header_size)
{
    short sum = header_size;
    if (message != NULL)
    {
        for (int i = 0; i < message->size; i++)
        {
            sum += message->_ptr[i];
        }
    }
    return 0xFF - (sum & 0x00FF);
}
//--------------------------------------------------------------//

void setPAN(Serial* COM, short pan_id)
{
    CArray DATA_TO_SEND;
    for (int j = 0; j < 8; j++) // Je force tout à 0 pour les addresses
        DATA_TO_SEND._64bit.bit[j] = 0;
    DATA_TO_SEND._16bit.bit[0] = 0;
    DATA_TO_SEND._16bit.bit[1] = 0;
    DATA_TO_SEND.opt_size = 0;
    
    DATA_TO_SEND._FrameType = 0x08; // AT Command
    DATA_TO_SEND.size = 4;
    DATA_TO_SEND._ptr = new char[4];
    DATA_TO_SEND._ptr[0] = 'I';
    DATA_TO_SEND._ptr[1] = 'D';
    DATA_TO_SEND._ptr[2] = pan_id >> 8;
    DATA_TO_SEND._ptr[3] = pan_id & 0x00FF;
    
    send(COM, &DATA_TO_SEND);
    
    delete DATA_TO_SEND._ptr;
}