//********************************// /* */ /* Soubor: xbee_api.c */ /* */ /* Knihovna pro Xbee moduly */ /* Marek Frelich */ /* Projekt MMIA */ /* Datum: 5.5.2012 */ /* */ //********************************// #include "xbee_api.h" #include #include //-------------------------------- Proměnné ---------------------------------------// uint8_t Xbee_Tx_Packet[XBEE_PACKET_LENGTH]; extern uint8_t Xbee_Address[8]; extern uint8_t Xbee_Network[2]; extern uint8_t Xbee_Data[20]; volatile extern uint8_t Xbee_Rx_Packet[XBEE_PACKET_LENGTH]; volatile extern uint8_t Xbee_Rx_OK; extern uint8_t Xbee_AT_Com_Response[2]; extern uint8_t Xbee_AT_Com_Data; extern uint8_t Xbee_Receive_Data[XBEE_PACKET_LENGTH]; extern uint8_t Digital_IO_Mask; //-------------------------------- Přerušení --------------------------------------// // Přijímá po sériové lince pakety od Xbee modulu // Celý paket je uložen v proměnné Xbee_Rx_Packet // Data jsou platná pokud Xbee_Rx_OK = TRUE; ISR (US_INT) { uint8_t data_rx; static uint8_t read_en,packet_ptr; data_rx = UDR; if (data_rx == XBEE_DELIMITER && read_en == FALSE) { read_en = TRUE; packet_ptr = 0; Xbee_Rx_Packet[packet_ptr++] = data_rx; return; } if (read_en == TRUE) { Xbee_Rx_Packet[packet_ptr++] = data_rx; if (packet_ptr < 3) return; if (packet_ptr == Xbee_Rx_Packet[LENGTH_LSB] + 4) { read_en = FALSE; Xbee_Rx_OK = TRUE; } } } //-------------------------------- Funkce -----------------------------------------// // Odeslání AT příkazu do modulu // AT_1 - první znak AT příkazu // AT_2 - druhý znak AT příkazu // value - hodnota pro nastavení // value_en = 1 - nastavení hodnoty value // value_en = 0 - bez hodnoty void Xbee_Send_AT (uint8_t AT_1, uint8_t AT_2, uint8_t value, uint8_t value_en) { if (value_en == 1) { Xbee_Tx_Packet[LENGTH_LSB] = 5; Xbee_Tx_Packet[7] = value; } else { Xbee_Tx_Packet[LENGTH_LSB] = 4; } Xbee_Tx_Packet[LENGTH_MSB] = 0; Xbee_Tx_Packet[FRAME_TYPE] = AT_COMAND; Xbee_Tx_Packet[FRAME_ID] = 0x52; Xbee_Tx_Packet[5] = AT_1; Xbee_Tx_Packet[6] = AT_2; if (value_en == 1) Xbee_Tx_Packet[8] = CRC_Count(Xbee_Tx_Packet,5); else Xbee_Tx_Packet[7] = CRC_Count(Xbee_Tx_Packet,4); USART_Send(Xbee_Tx_Packet,8 + value_en); } // Odeslání dat na zadanou adresu a síť // address - cílová adresa // network - cílová síť // data - data pro odeslání // count_data - počet odesílaných dat void Xbee_Transmit (uint8_t *address, uint8_t *network, uint8_t *data, uint8_t count_data) { uint8_t i; Xbee_Tx_Packet[LENGTH_MSB] = 0; Xbee_Tx_Packet[LENGTH_LSB] = 14 + count_data; Xbee_Tx_Packet[FRAME_TYPE] = TRANSMIT_REQ; Xbee_Tx_Packet[FRAME_ID] = 0x01; Xbee_Tx_Packet[XBEE_ADDRESS] = *address; Xbee_Tx_Packet[XBEE_ADDRESS + 1] = *(address + 1); Xbee_Tx_Packet[XBEE_ADDRESS + 2] = *(address + 2); Xbee_Tx_Packet[XBEE_ADDRESS + 3] = *(address + 3); Xbee_Tx_Packet[XBEE_ADDRESS + 4] = *(address + 4); Xbee_Tx_Packet[XBEE_ADDRESS + 5] = *(address + 5); Xbee_Tx_Packet[XBEE_ADDRESS + 6] = *(address + 6); Xbee_Tx_Packet[XBEE_ADDRESS + 7] = *(address + 7); Xbee_Tx_Packet[NTW_ADDRESS] = *network; Xbee_Tx_Packet[NTW_ADDRESS + 1] = *(network + 1); Xbee_Tx_Packet[15] = 0; Xbee_Tx_Packet[16] = 0; for (i=17;i<(17 + count_data);i++) { Xbee_Tx_Packet[i] = *(data + i - 17); } Xbee_Tx_Packet[18 + count_data] = CRC_Count(Xbee_Tx_Packet,18 + count_data); USART_Send(Xbee_Tx_Packet,18 + count_data); } // Odeslání AT příkazu na vzdálený modul // address - cílová adresa // network - cílová síť // AT_1 - první znak AT příkazu // AT_2 - druhý znak AT příkazu // value - hodnota pro nastavení // value_en = 1 - nastavení hodnoty value // value_en = 0 - bez hodnoty void Xbee_Send_Remote_AT (uint8_t *address, uint8_t *network, uint8_t AT_1, uint8_t AT_2, uint8_t value, uint8_t value_en) { if (value_en == 1) { Xbee_Tx_Packet[LENGTH_LSB] = 17; Xbee_Tx_Packet[18] = value; } else { Xbee_Tx_Packet[LENGTH_LSB] = 16; } Xbee_Tx_Packet[LENGTH_MSB] = 0; Xbee_Tx_Packet[FRAME_TYPE] = REM_AT_COMAND; Xbee_Tx_Packet[FRAME_ID] = 0x01; Xbee_Tx_Packet[16] = AT_1; Xbee_Tx_Packet[17] = AT_2; Xbee_Tx_Packet[XBEE_ADDRESS] = *address; Xbee_Tx_Packet[XBEE_ADDRESS + 1] = *(address + 1); Xbee_Tx_Packet[XBEE_ADDRESS + 2] = *(address + 2); Xbee_Tx_Packet[XBEE_ADDRESS + 3] = *(address + 3); Xbee_Tx_Packet[XBEE_ADDRESS + 4] = *(address + 4); Xbee_Tx_Packet[XBEE_ADDRESS + 5] = *(address + 5); Xbee_Tx_Packet[XBEE_ADDRESS + 6] = *(address + 6); Xbee_Tx_Packet[XBEE_ADDRESS + 7] = *(address + 7); Xbee_Tx_Packet[NTW_ADDRESS] = *network; Xbee_Tx_Packet[NTW_ADDRESS + 1] = *(network + 1); Xbee_Tx_Packet[15] = 0x02; if (value_en == 1) Xbee_Tx_Packet[19] = CRC_Count(Xbee_Tx_Packet,17); else Xbee_Tx_Packet[18] = CRC_Count(Xbee_Tx_Packet,16); USART_Send(Xbee_Tx_Packet,18 + value_en); } // Odpověď modulu na AT příkaz // vrací hodnotu OK nebo ERROR při chybě při vykonávání příkazu nebo jeho nedoručení uint8_t Xbee_AT_Response (uint8_t *data) { uint8_t temp,length; if (*(data + 3) != 0x88) return ERROR; length = *(data + 2); temp = CRC_Count(data,length); if (temp != *(data + length + 3)) return ERROR; Xbee_AT_Com_Response[0] = *(data + 5); Xbee_AT_Com_Response[1] = *(data + 6); if (*(data + 7) != 0) return ERROR; if (length == 6) { Xbee_AT_Com_Data = *(data + 8); return OK_DATA; } return OK; } // Stav modemu // vrací hodnotu v jakém stavu se nachází modul uint8_t Xbee_Status (uint8_t *data) { uint8_t temp,length; if (*(data + 3) != 0x8A) return ERROR; length = *(data + 2); temp = CRC_Count(data,length); if (temp != *(data + length + 3)) return ERROR; return *(data + 4); } // Stav odeslaných dat // OK potvrzuje přijetí dat příjemcem, nebo ERROR nedoručení dat uint8_t Xbee_Transmit_Status (uint8_t *data) { uint8_t temp,length; if (*(data + 3) != 0x8B) return ERROR; length = *(data + 2); temp = CRC_Count(data,length); if (temp != *(data + length + 3)) return ERROR; if (*(data + 8) == 0) return OK; else return ERROR; } // Příjem dat od jiného modulu // data jsou přijata do pole // je přijata i zdrojová adresa a síť uint8_t Xbee_Receive (uint8_t *data) { uint8_t temp,length,i; if (*(data + 3) != 0x90) return ERROR; length = *(data + 2); temp = CRC_Count(data,length); if (temp != *(data + length + 3)) return ERROR; Xbee_Address[0] = *(data + 4); Xbee_Address[1] = *(data + 5); Xbee_Address[2] = *(data + 6); Xbee_Address[3] = *(data + 7); Xbee_Address[4] = *(data + 8); Xbee_Address[5] = *(data + 9); Xbee_Address[6] = *(data + 10); Xbee_Address[7] = *(data + 11); Xbee_Network[0] = *(data + 12); Xbee_Network[1] = *(data + 13); for (i=15;i<(15 + length - 12);i++) { Xbee_Receive_Data[i - 15] = *(data + i); } return OK; } // Příjem dat ze vstupních pinů modulu // maska hodnot jednotlivých pinů je uložena do proměnné Digital_IO_Mask // je přijata i zdrojová adresa a síť uint8_t Xbee_Receive_IO (uint8_t *data) { uint8_t temp,length; if (*(data + 3) != 0x92) return ERROR; length = *(data + 2); temp = CRC_Count(data,length); if (temp != *(data + length + 3)) return ERROR; Xbee_Address[0] = *(data + 4); Xbee_Address[1] = *(data + 5); Xbee_Address[2] = *(data + 6); Xbee_Address[3] = *(data + 7); Xbee_Address[4] = *(data + 8); Xbee_Address[5] = *(data + 9); Xbee_Address[6] = *(data + 10); Xbee_Address[7] = *(data + 11); Xbee_Network[0] = *(data + 12); Xbee_Network[1] = *(data + 13); Digital_IO_Mask = *(data + 17); return OK; } // Odpověď na vzdálený AT příkaz // vrací hodnotu ERROR pokud příkaz nebyl proveden, nebo OK pokud vše proběhlo uint8_t Xbee_Remote_AT_Response (uint8_t *data) { uint8_t temp,length; if (*(data + 3) != 0x97) return ERROR; length = *(data + 2); temp = CRC_Count(data,length); if (temp != *(data + length + 3)) return ERROR; Xbee_Address[0] = *(data + 5); Xbee_Address[1] = *(data + 6); Xbee_Address[2] = *(data + 7); Xbee_Address[3] = *(data + 8); Xbee_Address[4] = *(data + 9); Xbee_Address[5] = *(data + 10); Xbee_Address[6] = *(data + 11); Xbee_Address[7] = *(data + 12); Xbee_Network[0] = *(data + 13); Xbee_Network[1] = *(data + 14); Xbee_AT_Com_Response[0] = *(data + 15); Xbee_AT_Com_Response[1] = *(data + 16); if (*(data + 17) != 0) return ERROR; if (length == 0x13) { Xbee_AT_Com_Data = *(data + 18); return OK_DATA; } return OK; } // Výpočet CRC z odesílaných dat uint8_t CRC_Count (uint8_t *data, uint8_t count) { uint8_t i; uint8_t crc=0; for (i=3;i<(3+count);i++) { crc += *(data + i); } crc = 0xFF - crc; return crc; } // Odeslání dat o délce length po sériové lince void USART_Send (uint8_t *data, uint8_t length) { uint8_t i; for (i=0;i