Code APP3

Dependencies:   mbed EthernetInterface WebSocketClient mbed-rtos BufferedSerial

Fork of APP3_Lab by Jean-Philippe Fournier

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers xbee.cpp Source File

xbee.cpp

00001 
00002 /***
00003 *   xbee.cpp - en-tete de lib xbee - fouj1807 - mcgj2701
00004 */
00005 
00006 #include "xbee.h"
00007 
00008 DigitalOut xbee_transmit_led(LED1);
00009 DigitalOut xbee_receive_led(LED2);
00010 DigitalOut xbee_reset(p8);
00011 
00012 BufferedSerial xbee(p13, p14); // tx, rx
00013 Serial pc_usb(USBTX, USBRX);
00014 void Rx_interrupt();
00015 
00016 #define BUFFER_SIZE 2048
00017 
00018 char TransmitBuffer[BUFFER_SIZE] = {0};
00019 char ReceiveBuffer[BUFFER_SIZE] = {0};
00020 
00021 volatile int rx_in = 0;
00022 volatile int rx_out = 0;
00023 /*
00024 void Rx_interrupt()
00025 {
00026     // Loop just in case more than one character is in UART's receive FIFO buffer
00027     // Stop if buffer full
00028     while ((xbee.readable()) && (((rx_in + 1) % BUFFER_SIZE) != rx_out)) {
00029         
00030         xbee_receive_led= !xbee_receive_led;
00031         ReceiveBuffer[rx_in] = xbee.getc();
00032         // Uncomment to Echo to USB serial to watch data flow
00033         pc_usb.putc(ReceiveBuffer[rx_in]);
00034         rx_in = (rx_in + 1) % BUFFER_SIZE;
00035     }
00036     return;
00037 }
00038 */
00039 
00040 bool addr_64_equal(zigbee_addr_64_t addr1, zigbee_addr_64_t addr2)
00041 {
00042     if( addr1.addr_0 == addr2.addr_0 &&
00043         addr1.addr_1 == addr2.addr_1 &&
00044         addr1.addr_2 == addr2.addr_2 &&
00045         addr1.addr_3 == addr2.addr_3 &&
00046         addr1.addr_4 == addr2.addr_4 &&
00047         addr1.addr_5 == addr2.addr_5 &&
00048         addr1.addr_6 == addr2.addr_6 &&
00049         addr1.addr_7 == addr2.addr_7)
00050     {
00051         return true;
00052     }
00053     return false;
00054 }
00055 
00056 void xbee_init()
00057 {
00058     // Setup a serial interrupt function to receive data
00059     xbee_receive_led = 0;
00060     //xbee.attach(&Rx_interrupt, Serial::RxIrq);    
00061     
00062     xbee_reset = 0;
00063     
00064     wait_ms(400);
00065     
00066     xbee_reset = 1;
00067     
00068     wait_ms(5000);    
00069 }
00070 
00071 void build_api_frame_header(int frame_data_size)
00072 {
00073     // Delimiter
00074     TransmitBuffer[FRAME_DELIMITER_POS] = ZIGBEE_DELIMITER;
00075     TransmitBuffer[FRAME_LEN_MSB_POS] = frame_data_size >> 8;
00076     TransmitBuffer[FRAME_LEN_LSB_POS] = frame_data_size & 0xFF;
00077 }
00078 
00079 void build_api_frame_checksum(int frame_data_size)
00080 {
00081     // Calculate checksum
00082     char checksum = 0xFF;
00083     for (int i = 3; i < FRAME_CHEKSUM_POS; i++)
00084     {
00085         checksum -= TransmitBuffer[i];
00086     }
00087     
00088     // Insert checksum into buffer
00089     TransmitBuffer[FRAME_CHEKSUM_POS] = checksum;
00090 }
00091 
00092 void set_api_frame_type(frame_type_t frame_type)
00093 {
00094     TransmitBuffer[API_FRAME_TYPE_POS] = frame_type;
00095 }
00096 
00097 void set_api_frame_id(int id)
00098 {
00099     TransmitBuffer[API_FRAME_ID_POS] = id;
00100 }
00101 
00102 void set_at_command(int at_command)
00103 {
00104 // NOT IMPLEMENTED
00105 }
00106 
00107 void set_64_addr(zigbee_addr_64_t address)
00108 {
00109     int i = 0;
00110     TransmitBuffer[TRANSMIT_REQ_ADDR64_MSB_POS + i++] = address.addr_0;
00111     TransmitBuffer[TRANSMIT_REQ_ADDR64_MSB_POS + i++] = address.addr_1;
00112     TransmitBuffer[TRANSMIT_REQ_ADDR64_MSB_POS + i++] = address.addr_2;
00113     TransmitBuffer[TRANSMIT_REQ_ADDR64_MSB_POS + i++] = address.addr_3;
00114 
00115     TransmitBuffer[TRANSMIT_REQ_ADDR64_MSB_POS + i++] = address.addr_4;
00116     TransmitBuffer[TRANSMIT_REQ_ADDR64_MSB_POS + i++] = address.addr_5;
00117     TransmitBuffer[TRANSMIT_REQ_ADDR64_MSB_POS + i++] = address.addr_6;
00118     TransmitBuffer[TRANSMIT_REQ_ADDR64_MSB_POS + i++] = address.addr_7;
00119 }
00120 
00121 void set_16_addr(zigbee_addr_16_t address)
00122 {
00123     TransmitBuffer[TRANSMIT_REQ_ADDR16_MSB_POS]         = address.addr_msb;
00124     TransmitBuffer[TRANSMIT_REQ_ADDR16_MSB_POS + 1]     = address.addr_lsb;
00125 }
00126 
00127 void set_broadcast_radius(int position, char radius)
00128 {
00129     TransmitBuffer[position] = radius;
00130 }
00131 
00132 void set_transmit_request_options(int position, char options)
00133 {
00134     TransmitBuffer[position] = options;
00135 }
00136 
00137 void set_transmit_data(int start_pos, char* data, int data_length)
00138 {
00139     for (int i = 0; i < data_length; i++)
00140     {
00141         TransmitBuffer[start_pos + i] = data[i];
00142     }
00143 }
00144 
00145 bool transmit_request_64(char* buffer, int data_length, char options, zigbee_addr_64_t destination)
00146 {
00147     build_api_frame_header(data_length + TRANSMIT_REQ_OVERHEAD_LENGTH);
00148 
00149     set_api_frame_type(TransmitRequest);
00150     set_api_frame_id(0x01);
00151 
00152     set_64_addr(destination);
00153     DECLARE_ADDR16_UNKNOWN_OR_BCAST
00154     set_16_addr(USE_ADDR16_UNKNOWN_OR_BCAST);
00155 
00156     set_broadcast_radius(15, 0);
00157     set_transmit_request_options(15, 0);
00158 
00159     set_transmit_data(TRANSMIT_REQ_DATA_START, buffer, data_length);
00160 
00161     build_api_frame_checksum(data_length + TRANSMIT_REQ_OVERHEAD_LENGTH);
00162 
00163     transmit(data_length);
00164     
00165     return false;
00166 }
00167 
00168 bool transmit_request_16(char* buffer, int data_length, char options, zigbee_addr_16_t destination)
00169 {
00170     build_api_frame_header(data_length + TRANSMIT_REQ_OVERHEAD_LENGTH);
00171 
00172     set_api_frame_type(TransmitRequest);
00173     set_api_frame_id(0x01);
00174     
00175     DECLARE_ADDR64_BCAST
00176     set_64_addr(USE_ADDR64_BCAST);
00177     set_16_addr(destination);
00178 
00179     set_broadcast_radius(15, 0);
00180     set_transmit_request_options(15, 0);
00181 
00182     set_transmit_data(TRANSMIT_REQ_DATA_START, buffer, data_length);
00183 
00184     build_api_frame_checksum(data_length + TRANSMIT_REQ_OVERHEAD_LENGTH);
00185     
00186     transmit(data_length);
00187 
00188     return false;
00189 }
00190 
00191 bool transmit_request(char* buffer, int data_length, char options, zigbee_addr_64_t destination64, zigbee_addr_16_t destination16)
00192 {
00193     build_api_frame_header(data_length + TRANSMIT_REQ_OVERHEAD_LENGTH);
00194     
00195     set_api_frame_type(TransmitRequest);
00196     set_api_frame_id(0x01);
00197 
00198     set_64_addr(destination64);
00199     set_16_addr(destination16);
00200 
00201     set_broadcast_radius(15, 0);
00202     set_transmit_request_options(15, 0);
00203 
00204     set_transmit_data(TRANSMIT_REQ_DATA_START, buffer, data_length);
00205 
00206     build_api_frame_checksum(data_length + TRANSMIT_REQ_OVERHEAD_LENGTH);
00207 
00208     transmit(data_length + TRANSMIT_REQ_OVERHEAD_LENGTH);
00209 
00210     return false;
00211 }
00212 
00213 void remote_at_command_query(char msb, char lsb, char options, zigbee_addr_64_t destination)
00214 {
00215     char remote_command[2] = {msb, lsb};
00216     
00217     build_api_frame_header(2 + REMOTE_AT_OVERHEAD_LENGTH);
00218 
00219     set_api_frame_type(RemoteCommandRequest);
00220     set_api_frame_id(0x01);
00221 
00222     DECLARE_ADDR16_UNKNOWN_OR_BCAST
00223 
00224     set_64_addr(destination);
00225     set_16_addr(USE_ADDR16_UNKNOWN_OR_BCAST);
00226 
00227     // Set as apply
00228     set_transmit_request_options(15, options);
00229 
00230     set_transmit_data(16, remote_command, 2);
00231     
00232     build_api_frame_checksum(2 + REMOTE_AT_OVERHEAD_LENGTH);    
00233 
00234     transmit(2 + REMOTE_AT_OVERHEAD_LENGTH); 
00235 }
00236 
00237 void remote_at_command_set(char msb, char lsb, char parameter, char options, zigbee_addr_64_t destination)
00238 {
00239     char remote_command[3] = {msb, lsb, parameter};
00240 
00241     build_api_frame_header(3 + REMOTE_AT_OVERHEAD_LENGTH);
00242 
00243     set_api_frame_type(RemoteCommandRequest);
00244     set_api_frame_id(0x01);
00245 
00246     DECLARE_ADDR16_UNKNOWN_OR_BCAST
00247 
00248     set_64_addr(destination);
00249     set_16_addr(USE_ADDR16_UNKNOWN_OR_BCAST);
00250 
00251     // Set as apply
00252     set_transmit_request_options(15, options);
00253 
00254     set_transmit_data(16, remote_command, 3);
00255     
00256     build_api_frame_checksum(3 + REMOTE_AT_OVERHEAD_LENGTH);    
00257 
00258     transmit(3 + REMOTE_AT_OVERHEAD_LENGTH); 
00259 }
00260 
00261 
00262 void at_command_query(char msb, char lsb)
00263 {
00264     char command[2] = {msb, lsb};
00265     
00266     build_api_frame_header(2 + REMOTE_AT_OVERHEAD_LENGTH);
00267 
00268     set_api_frame_type(ATCommand);
00269     set_api_frame_id(0x01);
00270 
00271     set_transmit_data(7, command, 2);
00272 
00273     build_api_frame_checksum(2 + REMOTE_AT_OVERHEAD_LENGTH);    
00274 
00275     transmit(2 + REMOTE_AT_OVERHEAD_LENGTH); 
00276 }
00277 
00278 void at_command_set(char msb, char lsb, char* parameter, int parameter_length)
00279 {
00280     char command[2] = {msb, lsb};
00281     
00282     build_api_frame_header(parameter_length + AT_COMMAND_OVERHEAD_LENGTH);
00283 
00284     set_api_frame_type(ATCommand);
00285     set_api_frame_id(0x01);
00286 
00287     set_transmit_data(5, command, 2);
00288     set_transmit_data(7, parameter, parameter_length);
00289 
00290     build_api_frame_checksum(parameter_length + AT_COMMAND_OVERHEAD_LENGTH);    
00291 
00292     transmit(parameter_length + AT_COMMAND_OVERHEAD_LENGTH); 
00293 }
00294 
00295 void transmit(int packet_length)
00296 {
00297     for (int i = 0; i < packet_length + 4; i++)
00298     {
00299         xbee.putc(TransmitBuffer[i]);
00300     }
00301     xbee_transmit_led = !xbee_transmit_led;
00302 }
00303 
00304 bool receive(frame_t* out_frame)
00305 {
00306     static int curr_length = 0;
00307 
00308     static frame_recv_state_t recv_state = wait_delimiter;
00309     static char checksum = 0xFF;
00310 
00311     bool finished_frame = false;
00312 
00313     xbee_receive_led = !xbee_receive_led;
00314     while(xbee.readable() && curr_length < MAX_FRAME_SIZE && !finished_frame)
00315     {
00316         char current = xbee.getc();
00317         switch(recv_state)
00318         {
00319             case wait_delimiter:
00320             {
00321                 if (current == ZIGBEE_DELIMITER)
00322                 {
00323                     curr_length = 0;
00324                     recv_state = read_length_msb;
00325                     out_frame->length = 0;
00326                 }                
00327                 break;
00328             }
00329             case read_length_msb:  
00330             {
00331                 out_frame->length = (current << 8);
00332                 recv_state = read_length_lsb;
00333                 break;
00334             }
00335             case read_length_lsb:
00336             {                 
00337                 out_frame->length |= current;  
00338                 checksum = 0xFF;
00339                 recv_state = read_frame_specific;
00340                 break;
00341             }
00342             case read_frame_specific:
00343             {   
00344                 out_frame->buffer[curr_length++] = current;                
00345                 checksum -= current;
00346                 if (curr_length >= out_frame->length)
00347                 {
00348                     recv_state = read_checksum;
00349                 }
00350                 break;
00351             }
00352             case read_checksum:
00353             {
00354                // pc.printf(":: read_checksum x%x", current);   
00355                 recv_state = wait_delimiter;
00356                 if (checksum == current)
00357                 {
00358                     finished_frame = true;
00359                 }
00360                 break;
00361             }
00362         }     
00363     }
00364     return finished_frame;    
00365 }