Code APP3
Dependencies: mbed EthernetInterface WebSocketClient mbed-rtos BufferedSerial
Fork of APP3_Lab by
xbee.cpp
- Committer:
- JayMcGee
- Date:
- 2017-10-02
- Revision:
- 28:322985c7e428
- Parent:
- 25:7b808fb9e025
- Child:
- 27:3baf4701a047
File content as of revision 28:322985c7e428:
/*** * 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); BufferedSerial xbee(p13, p14); // tx, rx Serial pc_usb(USBTX, USBRX); void Rx_interrupt(); #define BUFFER_SIZE 2048 char TransmitBuffer[BUFFER_SIZE] = {0}; char ReceiveBuffer[BUFFER_SIZE] = {0}; volatile int rx_in = 0; volatile int rx_out = 0; /* void Rx_interrupt() { // Loop just in case more than one character is in UART's receive FIFO buffer // Stop if buffer full while ((xbee.readable()) && (((rx_in + 1) % BUFFER_SIZE) != rx_out)) { xbee_receive_led= !xbee_receive_led; ReceiveBuffer[rx_in] = xbee.getc(); // Uncomment to Echo to USB serial to watch data flow pc_usb.putc(ReceiveBuffer[rx_in]); rx_in = (rx_in + 1) % BUFFER_SIZE; } return; } */ bool addr_64_equal(zigbee_addr_64_t addr1, zigbee_addr_64_t addr2) { if( addr1.addr_0 == addr2.addr_0 && addr1.addr_1 == addr2.addr_1 && addr1.addr_2 == addr2.addr_2 && addr1.addr_3 == addr2.addr_3 && addr1.addr_4 == addr2.addr_4 && addr1.addr_5 == addr2.addr_5 && addr1.addr_6 == addr2.addr_6 && addr1.addr_7 == addr2.addr_7) { return true; } return false; } void xbee_init() { // Setup a serial interrupt function to receive data xbee_receive_led = 0; //xbee.attach(&Rx_interrupt, Serial::RxIrq); xbee_reset = 0; wait_ms(400); xbee_reset = 1; wait_ms(5000); } 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_data(int start_pos, char* data, int data_length) { for (int i = 0; i < data_length; i++) { TransmitBuffer[start_pos + 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_data(TRANSMIT_REQ_DATA_START, 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_data(TRANSMIT_REQ_DATA_START, 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_data(TRANSMIT_REQ_DATA_START, buffer, data_length); build_api_frame_checksum(data_length + TRANSMIT_REQ_OVERHEAD_LENGTH); transmit(data_length + TRANSMIT_REQ_OVERHEAD_LENGTH); return false; } void remote_at_command_query(char msb, char lsb, char options, zigbee_addr_64_t destination) { char remote_command[2] = {msb, lsb}; build_api_frame_header(2 + REMOTE_AT_OVERHEAD_LENGTH); set_api_frame_type(RemoteCommandRequest); set_api_frame_id(0x01); DECLARE_ADDR16_UNKNOWN_OR_BCAST set_64_addr(destination); set_16_addr(USE_ADDR16_UNKNOWN_OR_BCAST); // Set as apply set_transmit_request_options(15, options); set_transmit_data(16, remote_command, 2); build_api_frame_checksum(2 + REMOTE_AT_OVERHEAD_LENGTH); transmit(2 + REMOTE_AT_OVERHEAD_LENGTH); } void remote_at_command_set(char msb, char lsb, char parameter, char options, zigbee_addr_64_t destination) { char remote_command[3] = {msb, lsb, parameter}; build_api_frame_header(3 + REMOTE_AT_OVERHEAD_LENGTH); set_api_frame_type(RemoteCommandRequest); set_api_frame_id(0x01); DECLARE_ADDR16_UNKNOWN_OR_BCAST set_64_addr(destination); set_16_addr(USE_ADDR16_UNKNOWN_OR_BCAST); // Set as apply set_transmit_request_options(15, options); set_transmit_data(16, remote_command, 3); build_api_frame_checksum(3 + REMOTE_AT_OVERHEAD_LENGTH); transmit(3 + REMOTE_AT_OVERHEAD_LENGTH); } void at_command_query(char msb, char lsb) { char command[2] = {msb, lsb}; build_api_frame_header(2 + REMOTE_AT_OVERHEAD_LENGTH); set_api_frame_type(ATCommand); set_api_frame_id(0x01); set_transmit_data(7, command, 2); build_api_frame_checksum(2 + REMOTE_AT_OVERHEAD_LENGTH); transmit(2 + REMOTE_AT_OVERHEAD_LENGTH); } void at_command_set(char msb, char lsb, char* parameter, int parameter_length) { char command[2] = {msb, lsb}; build_api_frame_header(parameter_length + AT_COMMAND_OVERHEAD_LENGTH); set_api_frame_type(ATCommand); set_api_frame_id(0x01); set_transmit_data(5, command, 2); set_transmit_data(7, parameter, parameter_length); build_api_frame_checksum(parameter_length + AT_COMMAND_OVERHEAD_LENGTH); transmit(parameter_length + AT_COMMAND_OVERHEAD_LENGTH); } void transmit(int packet_length) { for (int i = 0; i < packet_length + 4; 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 char checksum = 0xFF; bool finished_frame = false; xbee_receive_led = !xbee_receive_led; while(xbee.readable() && curr_length < max_length && !finished_frame) { char current = xbee.getc(); switch(recv_state) { case wait_delimiter: { if (current == ZIGBEE_DELIMITER) { curr_length = 0; recv_state = read_length_msb; out_frame->length = 0; } break; } case read_length_msb: { out_frame->length = (current << 8); recv_state = read_length_lsb; break; } case read_length_lsb: { out_frame->length |= current; checksum = 0xFF; recv_state = read_frame_specific; break; } case read_frame_specific: { out_frame->buffer[curr_length++] = current; checksum -= current; if (curr_length >= out_frame->length) { recv_state = read_checksum; } break; } case read_checksum: { // pc.printf(":: read_checksum x%x", current); recv_state = wait_delimiter; if (checksum == current) { finished_frame = true; } break; } } } return finished_frame; }