Code APP3

Dependencies:   mbed EthernetInterface WebSocketClient mbed-rtos BufferedSerial

Fork of APP3_Lab by Jean-Philippe Fournier

xbee.cpp

Committer:
JayMcGee
Date:
2017-09-30
Revision:
10:edcf07f33583
Parent:
8:5955af1ee445
Child:
11:ecf5776b950a

File content as of revision 10:edcf07f33583:


/***
*   xbee.cpp - en-tete de lib xbee - fouj1807 - mcgj2701
*/

#include "xbee.h"

DigitalOut xbee_transmit_led(LED1);
DigitalOut xbee_receive_led(LED2);
DigitalOut xbee_reset(p8);

Serial xbee(p13, p14); // tx, rx

char TransmitBuffer[2048] = {0};
char ReceiveBuffer[2048] = {0};

void xbee_init()
{
    xbee_receive_led = 0;
    
    wait_ms(400);
    
    xbee_reset = 1;
    
    wait_ms(5000);    
    
    xbee_receive_led = 1;    
}


bool set_pan_id(long pan_id)
{
    return false;
}

long get_pan_id()
{
    return 0L;
}


void build_api_frame_header(int frame_data_size)
{
    // Delimiter
    TransmitBuffer[FRAME_DELIMITER_POS] = ZIGBEE_DELIMITER;
    TransmitBuffer[FRAME_LEN_MSB_POS] = frame_data_size >> 8;
    TransmitBuffer[FRAME_LEN_LSB_POS] = frame_data_size & 0xFF;
}

void build_api_frame_checksum(int frame_data_size)
{
    // Calculate checksum
    char checksum = 0xFF;
    for (int i = 3; i < FRAME_CHEKSUM_POS; i++)
    {
        checksum -= TransmitBuffer[i];
    }
    
    // Insert checksum into buffer
    TransmitBuffer[FRAME_CHEKSUM_POS] = checksum;
}

void set_api_frame_type(frame_type_t frame_type)
{
    TransmitBuffer[API_FRAME_TYPE_POS] = frame_type;
}

void set_api_frame_id(int id)
{
    TransmitBuffer[API_FRAME_ID_POS] = id;
}

void set_at_command(int at_command)
{
// NOT IMPLEMENTED
}

void set_64_addr(zigbee_addr_64_t address)
{
    int i = 0;
    TransmitBuffer[TRANSMIT_REQ_ADDR64_MSB_POS + i++] = address.addr_0;
    TransmitBuffer[TRANSMIT_REQ_ADDR64_MSB_POS + i++] = address.addr_1;
    TransmitBuffer[TRANSMIT_REQ_ADDR64_MSB_POS + i++] = address.addr_2;
    TransmitBuffer[TRANSMIT_REQ_ADDR64_MSB_POS + i++] = address.addr_3;

    TransmitBuffer[TRANSMIT_REQ_ADDR64_MSB_POS + i++] = address.addr_4;
    TransmitBuffer[TRANSMIT_REQ_ADDR64_MSB_POS + i++] = address.addr_5;
    TransmitBuffer[TRANSMIT_REQ_ADDR64_MSB_POS + i++] = address.addr_6;
    TransmitBuffer[TRANSMIT_REQ_ADDR64_MSB_POS + i++] = address.addr_7;
}

void set_16_addr(zigbee_addr_16_t address)
{
    TransmitBuffer[TRANSMIT_REQ_ADDR16_MSB_POS]         = address.addr_msb;
    TransmitBuffer[TRANSMIT_REQ_ADDR16_MSB_POS + 1]     = address.addr_lsb;
}

void set_broadcast_radius(int position, char radius)
{
    TransmitBuffer[position] = radius;
}

void set_transmit_request_options(int position, char options)
{
    TransmitBuffer[position] = options;
}

void set_transmit_request_data(char* data, int data_length)
{
    for (int i = 0; i < data_length; i++)
    {
        TransmitBuffer[TRANSMIT_REQ_DATA_START + i] = data[i];
    }
}

bool transmit_request_64(char* buffer, int data_length, char options, zigbee_addr_64_t destination)
{
    build_api_frame_header(data_length + TRANSMIT_REQ_OVERHEAD_LENGTH);

    set_api_frame_type(TransmitRequest);
    set_api_frame_id(0x01);

    set_64_addr(destination);
    DECLARE_ADDR16_UNKNOWN_OR_BCAST
    set_16_addr(USE_ADDR16_UNKNOWN_OR_BCAST);

    set_broadcast_radius(15, 0);
    set_transmit_request_options(15, 0);

    set_transmit_request_data(buffer, data_length);

    build_api_frame_checksum(data_length + TRANSMIT_REQ_OVERHEAD_LENGTH);

    transmit(data_length);
    
    return false;
}

bool transmit_request_16(char* buffer, int data_length, char options, zigbee_addr_16_t destination)
{
    build_api_frame_header(data_length + TRANSMIT_REQ_OVERHEAD_LENGTH);

    set_api_frame_type(TransmitRequest);
    set_api_frame_id(0x01);
    
    DECLARE_ADDR64_BCAST
    set_64_addr(USE_ADDR64_BCAST);
    set_16_addr(destination);

    set_broadcast_radius(15, 0);
    set_transmit_request_options(15, 0);

    set_transmit_request_data(buffer, data_length);

    build_api_frame_checksum(data_length + TRANSMIT_REQ_OVERHEAD_LENGTH);
    
    transmit(data_length);

    return false;
}

bool transmit_request(char* buffer, int data_length, char options, zigbee_addr_64_t destination64, zigbee_addr_16_t destination16)
{
    build_api_frame_header(data_length + TRANSMIT_REQ_OVERHEAD_LENGTH);
    
    set_api_frame_type(TransmitRequest);
    set_api_frame_id(0x01);

    set_64_addr(destination64);
    set_16_addr(destination16);

    set_broadcast_radius(15, 0);
    set_transmit_request_options(15, 0);

    set_transmit_request_data(buffer, data_length);

    build_api_frame_checksum(data_length + TRANSMIT_REQ_OVERHEAD_LENGTH);

    transmit(data_length);

    return false;
}

void transmit(int packet_length)
{
    for (int i = 0; i < 18 + packet_length; i++)
    {
        xbee.putc(TransmitBuffer[i]);
    }
    xbee_transmit_led = !xbee_transmit_led;
}

bool receive(frame_t* out_frame, int max_length)
{
    static int curr_length = 0;

    static frame_recv_state_t recv_state = wait_delimiter;
    static frame_t frame;
    static char checksum = 0xFF;

    bool finished_frame = false;

    while(xbee.readable() && curr_length < max_length && !finished_frame)
    {
        switch(recv_state)
        {
            case wait_delimiter:
            {
                if (xbee.getc() == ZIGBEE_DELIMITER)
                {
                    recv_state = read_length_msb;
                }                
                break;
            }
            case read_length_msb:  
            {
                frame.length = (xbee.getc() << 8);
                recv_state = read_length_lsb;
                break;
            }
            case read_length_lsb:
            {
                frame.length |= xbee.getc();
                checksum = 0xFF;
                recv_state = read_frame_specific;
                break;
            }
            case read_frame_specific:
            {
                frame.buffer[curr_length] = xbee.getc();
                checksum -= frame.buffer[curr_length++];
                if (curr_length >= frame.length)
                {
                    recv_state = read_checksum;
                }
                break;
            }
            case read_checksum:
            {
                recv_state = wait_delimiter;
                xbee_receive_led = !xbee_receive_led;
                if (checksum == xbee.getc())
                {
                    out_frame = &frame;
                    finished_frame = true;
                }
                break;
            }
        }     
    }
    
    return finished_frame;    
}


/**
 * 
 *   // Calculate checksum
    char checksum = 0xFF;
    for (int i = 3; i < FRAME_CHEKSUM_POS; i++)
    {
        checksum -= TransmitBuffer[i];
    }
    
    // Insert checksum into buffer
    TransmitBuffer[FRAME_CHEKSUM_POS] = checksum;*/