Class containing functions usefull to communication between PC and Xbee device
Dependents: Coordinator_node Router_node
xbee.cpp@20:e119856dbc5e, 2017-02-15 (annotated)
- Committer:
- EmileArseneault
- Date:
- Wed Feb 15 05:55:34 2017 +0000
- Revision:
- 20:e119856dbc5e
- Parent:
- 19:8da8068315da
Essaie de wait for response et cleanage
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ShaolinPoutine | 2:0000443a78fe | 1 | #include "xbee.h" |
ShaolinPoutine | 2:0000443a78fe | 2 | |
EmileArseneault | 20:e119856dbc5e | 3 | char TransmissionNumber = 2; |
EmileArseneault | 18:39c72589645f | 4 | Mutex mTransmissionNumber; |
EmileArseneault | 18:39c72589645f | 5 | |
EmileArseneault | 18:39c72589645f | 6 | char GetTransmissionNumber() |
EmileArseneault | 18:39c72589645f | 7 | { |
EmileArseneault | 18:39c72589645f | 8 | char nextnumber = 0; |
EmileArseneault | 18:39c72589645f | 9 | |
EmileArseneault | 18:39c72589645f | 10 | mTransmissionNumber.lock(); |
EmileArseneault | 18:39c72589645f | 11 | nextnumber = TransmissionNumber; |
EmileArseneault | 18:39c72589645f | 12 | if(nextnumber == 255) |
EmileArseneault | 18:39c72589645f | 13 | { |
EmileArseneault | 20:e119856dbc5e | 14 | TransmissionNumber = 2; |
EmileArseneault | 18:39c72589645f | 15 | } |
EmileArseneault | 18:39c72589645f | 16 | else |
EmileArseneault | 18:39c72589645f | 17 | { |
EmileArseneault | 18:39c72589645f | 18 | TransmissionNumber++; |
EmileArseneault | 18:39c72589645f | 19 | } |
EmileArseneault | 18:39c72589645f | 20 | mTransmissionNumber.unlock(); |
EmileArseneault | 18:39c72589645f | 21 | |
EmileArseneault | 18:39c72589645f | 22 | return nextnumber; |
EmileArseneault | 18:39c72589645f | 23 | } |
EmileArseneault | 18:39c72589645f | 24 | |
EmileArseneault | 20:e119856dbc5e | 25 | XBee::XBee(PinName reset, PinName transfer, PinName receive, Mail<char, 250>* m, Mail<char[256], 16>* w, Mail<char[254], 25>* r) : |
EmileArseneault | 5:9b4d93bd6725 | 26 | rst(reset), comm(transfer, receive) |
EmileArseneault | 5:9b4d93bd6725 | 27 | { |
EmileArseneault | 5:9b4d93bd6725 | 28 | // Constructor |
EmileArseneault | 5:9b4d93bd6725 | 29 | mail = m; |
ShaolinPoutine | 15:04e892ae9361 | 30 | webmail = w; |
EmileArseneault | 20:e119856dbc5e | 31 | frameresponsemail = r; |
EmileArseneault | 5:9b4d93bd6725 | 32 | rst = 0; |
EmileArseneault | 5:9b4d93bd6725 | 33 | wait(0.4); |
EmileArseneault | 5:9b4d93bd6725 | 34 | rst = 1; |
EmileArseneault | 5:9b4d93bd6725 | 35 | wait(3); // waiting for initiation |
ShaolinPoutine | 15:04e892ae9361 | 36 | buffer[0] = '\0'; |
ShaolinPoutine | 15:04e892ae9361 | 37 | } |
ShaolinPoutine | 15:04e892ae9361 | 38 | |
ShaolinPoutine | 15:04e892ae9361 | 39 | void XBee::appendBuffer(char* c) |
ShaolinPoutine | 15:04e892ae9361 | 40 | { |
ShaolinPoutine | 15:04e892ae9361 | 41 | int i = 0; |
ShaolinPoutine | 15:04e892ae9361 | 42 | int j = 0; |
ShaolinPoutine | 15:04e892ae9361 | 43 | |
ShaolinPoutine | 15:04e892ae9361 | 44 | while (buffer[i] != '\0') i++; |
ShaolinPoutine | 15:04e892ae9361 | 45 | |
ShaolinPoutine | 15:04e892ae9361 | 46 | while (c[j]!= '\0' || i < 255) |
ShaolinPoutine | 15:04e892ae9361 | 47 | { |
ShaolinPoutine | 15:04e892ae9361 | 48 | buffer[i] = c[j]; |
ShaolinPoutine | 15:04e892ae9361 | 49 | i++;j++; |
ShaolinPoutine | 15:04e892ae9361 | 50 | } |
ShaolinPoutine | 15:04e892ae9361 | 51 | buffer[i] = '\0'; |
ShaolinPoutine | 15:04e892ae9361 | 52 | } |
ShaolinPoutine | 15:04e892ae9361 | 53 | |
ShaolinPoutine | 15:04e892ae9361 | 54 | void XBee::sendBuffer() |
ShaolinPoutine | 15:04e892ae9361 | 55 | { |
ShaolinPoutine | 15:04e892ae9361 | 56 | char* s = (char *) webmail->alloc(); |
ShaolinPoutine | 15:04e892ae9361 | 57 | |
ShaolinPoutine | 15:04e892ae9361 | 58 | int i = 0; |
ShaolinPoutine | 15:04e892ae9361 | 59 | while (buffer[i]!= '\0' || i < 255) |
ShaolinPoutine | 15:04e892ae9361 | 60 | { |
ShaolinPoutine | 15:04e892ae9361 | 61 | s[i] = buffer[i]; |
ShaolinPoutine | 15:04e892ae9361 | 62 | i++; |
ShaolinPoutine | 15:04e892ae9361 | 63 | } |
ShaolinPoutine | 15:04e892ae9361 | 64 | s[i] = '\0'; |
ShaolinPoutine | 15:04e892ae9361 | 65 | |
ShaolinPoutine | 15:04e892ae9361 | 66 | webmail->put((char(*)[256]) s); |
ShaolinPoutine | 15:04e892ae9361 | 67 | |
ShaolinPoutine | 15:04e892ae9361 | 68 | buffer[0] = '\0'; |
EmileArseneault | 5:9b4d93bd6725 | 69 | } |
EmileArseneault | 5:9b4d93bd6725 | 70 | |
EmileArseneault | 9:902d0f74333c | 71 | char XBee::getChar() |
EmileArseneault | 9:902d0f74333c | 72 | { |
EmileArseneault | 9:902d0f74333c | 73 | while (!comm.readable()) |
EmileArseneault | 9:902d0f74333c | 74 | { |
EmileArseneault | 9:902d0f74333c | 75 | wait(0.02); |
EmileArseneault | 9:902d0f74333c | 76 | } |
EmileArseneault | 9:902d0f74333c | 77 | return comm.getc(); |
EmileArseneault | 9:902d0f74333c | 78 | } |
EmileArseneault | 9:902d0f74333c | 79 | |
ShaolinPoutine | 2:0000443a78fe | 80 | void XBee::pcPrint(char* c) |
ShaolinPoutine | 2:0000443a78fe | 81 | { |
ShaolinPoutine | 2:0000443a78fe | 82 | int i = 0; |
ShaolinPoutine | 2:0000443a78fe | 83 | while( (c)[i] != '\0') |
ShaolinPoutine | 2:0000443a78fe | 84 | { |
ShaolinPoutine | 2:0000443a78fe | 85 | mail->put(&(c[i])); |
ShaolinPoutine | 2:0000443a78fe | 86 | i++; |
ShaolinPoutine | 2:0000443a78fe | 87 | } |
ShaolinPoutine | 2:0000443a78fe | 88 | } |
ShaolinPoutine | 2:0000443a78fe | 89 | |
EmileArseneault | 5:9b4d93bd6725 | 90 | void XBee::printInt(int i) |
EmileArseneault | 5:9b4d93bd6725 | 91 | { |
EmileArseneault | 5:9b4d93bd6725 | 92 | bool signe = i > 0; |
EmileArseneault | 5:9b4d93bd6725 | 93 | char *c = mail->alloc(); |
EmileArseneault | 5:9b4d93bd6725 | 94 | if (signe) |
EmileArseneault | 5:9b4d93bd6725 | 95 | { |
EmileArseneault | 5:9b4d93bd6725 | 96 | *c = '-'; |
EmileArseneault | 5:9b4d93bd6725 | 97 | mail->put(c); |
ShaolinPoutine | 8:ba349a2eeb37 | 98 | i *= -1; |
EmileArseneault | 5:9b4d93bd6725 | 99 | } |
EmileArseneault | 5:9b4d93bd6725 | 100 | |
EmileArseneault | 5:9b4d93bd6725 | 101 | int diviseur = 1; |
EmileArseneault | 5:9b4d93bd6725 | 102 | int modulo = 10; |
EmileArseneault | 5:9b4d93bd6725 | 103 | int j = 9; |
EmileArseneault | 5:9b4d93bd6725 | 104 | char chiffre[10]; |
EmileArseneault | 5:9b4d93bd6725 | 105 | |
EmileArseneault | 5:9b4d93bd6725 | 106 | while (i / diviseur > 0 && j >= 0) |
EmileArseneault | 5:9b4d93bd6725 | 107 | { |
ShaolinPoutine | 8:ba349a2eeb37 | 108 | chiffre[j] = (char) (i % modulo)/diviseur; |
EmileArseneault | 5:9b4d93bd6725 | 109 | modulo *= 10; |
EmileArseneault | 5:9b4d93bd6725 | 110 | diviseur *= 10; |
EmileArseneault | 5:9b4d93bd6725 | 111 | j--; |
EmileArseneault | 5:9b4d93bd6725 | 112 | } |
EmileArseneault | 5:9b4d93bd6725 | 113 | |
EmileArseneault | 5:9b4d93bd6725 | 114 | j = 0; |
EmileArseneault | 5:9b4d93bd6725 | 115 | bool numberHasStarted = false; |
EmileArseneault | 5:9b4d93bd6725 | 116 | while (j < 10) |
EmileArseneault | 5:9b4d93bd6725 | 117 | { |
EmileArseneault | 5:9b4d93bd6725 | 118 | if (chiffre[j] != 0 || numberHasStarted || j == 9) |
EmileArseneault | 5:9b4d93bd6725 | 119 | { |
EmileArseneault | 5:9b4d93bd6725 | 120 | numberHasStarted = true; |
EmileArseneault | 5:9b4d93bd6725 | 121 | c = mail->alloc(); |
ShaolinPoutine | 8:ba349a2eeb37 | 122 | *c = chiffre[j] + 0x30; |
EmileArseneault | 5:9b4d93bd6725 | 123 | mail->put(c); |
EmileArseneault | 5:9b4d93bd6725 | 124 | } |
EmileArseneault | 5:9b4d93bd6725 | 125 | j++; |
EmileArseneault | 5:9b4d93bd6725 | 126 | } |
EmileArseneault | 5:9b4d93bd6725 | 127 | } |
EmileArseneault | 5:9b4d93bd6725 | 128 | |
ShaolinPoutine | 2:0000443a78fe | 129 | void XBee::printHexa(char c) |
ShaolinPoutine | 2:0000443a78fe | 130 | { |
ShaolinPoutine | 2:0000443a78fe | 131 | char *msb = mail->alloc(); |
ShaolinPoutine | 2:0000443a78fe | 132 | *msb = c >> 4; |
ShaolinPoutine | 2:0000443a78fe | 133 | char *lsb = mail->alloc(); |
ShaolinPoutine | 2:0000443a78fe | 134 | *lsb = c & 0xF; |
ShaolinPoutine | 2:0000443a78fe | 135 | |
ShaolinPoutine | 2:0000443a78fe | 136 | if (*msb < 10) |
ShaolinPoutine | 2:0000443a78fe | 137 | *msb += 0x30; |
ShaolinPoutine | 2:0000443a78fe | 138 | else |
ShaolinPoutine | 2:0000443a78fe | 139 | *msb += 0x37; |
ShaolinPoutine | 2:0000443a78fe | 140 | |
ShaolinPoutine | 2:0000443a78fe | 141 | if (*lsb < 10) |
ShaolinPoutine | 2:0000443a78fe | 142 | *lsb += 0x30; |
ShaolinPoutine | 2:0000443a78fe | 143 | else |
ShaolinPoutine | 2:0000443a78fe | 144 | *lsb += 0x37; |
ShaolinPoutine | 2:0000443a78fe | 145 | |
ShaolinPoutine | 2:0000443a78fe | 146 | char * str = "0x"; |
ShaolinPoutine | 2:0000443a78fe | 147 | pcPrint(str); |
ShaolinPoutine | 2:0000443a78fe | 148 | mail->put(msb); |
ShaolinPoutine | 2:0000443a78fe | 149 | mail->put(lsb); |
ShaolinPoutine | 2:0000443a78fe | 150 | str = " "; |
ShaolinPoutine | 2:0000443a78fe | 151 | pcPrint(str); |
ShaolinPoutine | 2:0000443a78fe | 152 | } |
ShaolinPoutine | 2:0000443a78fe | 153 | |
EmileArseneault | 20:e119856dbc5e | 154 | char XBee::SendATCommand(char firstChar, char secondChar, char *optionalParam, int paramLen) |
ShaolinPoutine | 2:0000443a78fe | 155 | { |
ShaolinPoutine | 2:0000443a78fe | 156 | // Frame Type 0x08 |
ShaolinPoutine | 2:0000443a78fe | 157 | // Two char as parameters |
ShaolinPoutine | 2:0000443a78fe | 158 | |
ShaolinPoutine | 2:0000443a78fe | 159 | char cmdtosend[10]; |
ShaolinPoutine | 2:0000443a78fe | 160 | char sum = 0; |
ShaolinPoutine | 2:0000443a78fe | 161 | int cmdlength = 8; |
ShaolinPoutine | 2:0000443a78fe | 162 | int i = 0; |
ShaolinPoutine | 2:0000443a78fe | 163 | |
ShaolinPoutine | 2:0000443a78fe | 164 | cmdtosend[0] = FRAMEDELIMITER; |
ShaolinPoutine | 2:0000443a78fe | 165 | cmdtosend[1] = 0x00; |
ShaolinPoutine | 2:0000443a78fe | 166 | cmdtosend[2] = 0x04 + paramLen; |
ShaolinPoutine | 2:0000443a78fe | 167 | cmdtosend[3] = 0x08; |
EmileArseneault | 18:39c72589645f | 168 | cmdtosend[4] = GetTransmissionNumber(); |
ShaolinPoutine | 2:0000443a78fe | 169 | cmdtosend[5] = firstChar; |
ShaolinPoutine | 2:0000443a78fe | 170 | cmdtosend[6] = secondChar; |
ShaolinPoutine | 2:0000443a78fe | 171 | |
ShaolinPoutine | 2:0000443a78fe | 172 | // Ajouter les parametres au message |
ShaolinPoutine | 2:0000443a78fe | 173 | if(optionalParam != NULL) |
ShaolinPoutine | 2:0000443a78fe | 174 | { |
ShaolinPoutine | 2:0000443a78fe | 175 | i = 0; |
ShaolinPoutine | 2:0000443a78fe | 176 | cmdlength += paramLen; |
ShaolinPoutine | 2:0000443a78fe | 177 | |
ShaolinPoutine | 2:0000443a78fe | 178 | while (i < paramLen) |
ShaolinPoutine | 2:0000443a78fe | 179 | { |
ShaolinPoutine | 2:0000443a78fe | 180 | cmdtosend[7 + i] = (optionalParam)[i]; |
ShaolinPoutine | 2:0000443a78fe | 181 | i++; |
ShaolinPoutine | 2:0000443a78fe | 182 | } |
ShaolinPoutine | 2:0000443a78fe | 183 | pcPrint("\r\n\0"); |
ShaolinPoutine | 2:0000443a78fe | 184 | } |
ShaolinPoutine | 2:0000443a78fe | 185 | |
ShaolinPoutine | 2:0000443a78fe | 186 | // Calculate checksum |
ShaolinPoutine | 2:0000443a78fe | 187 | i = 3; |
ShaolinPoutine | 2:0000443a78fe | 188 | while (i < (cmdlength - 1)) |
ShaolinPoutine | 2:0000443a78fe | 189 | { |
ShaolinPoutine | 2:0000443a78fe | 190 | sum += cmdtosend[i]; |
ShaolinPoutine | 2:0000443a78fe | 191 | i++; |
ShaolinPoutine | 2:0000443a78fe | 192 | } |
ShaolinPoutine | 2:0000443a78fe | 193 | cmdtosend[cmdlength - 1] = 0xFF - sum; |
ShaolinPoutine | 2:0000443a78fe | 194 | |
ShaolinPoutine | 2:0000443a78fe | 195 | // Envoyer la commande sur UART |
ShaolinPoutine | 2:0000443a78fe | 196 | i = 0; |
ShaolinPoutine | 2:0000443a78fe | 197 | while (i < cmdlength) |
ShaolinPoutine | 2:0000443a78fe | 198 | { |
ShaolinPoutine | 2:0000443a78fe | 199 | comm.putc(cmdtosend[i]); |
ShaolinPoutine | 2:0000443a78fe | 200 | i++; |
ShaolinPoutine | 2:0000443a78fe | 201 | } |
ShaolinPoutine | 2:0000443a78fe | 202 | |
EmileArseneault | 9:902d0f74333c | 203 | wait(0.2); |
EmileArseneault | 20:e119856dbc5e | 204 | return cmdtosend[4]; |
ShaolinPoutine | 2:0000443a78fe | 205 | } |
ShaolinPoutine | 2:0000443a78fe | 206 | |
EmileArseneault | 18:39c72589645f | 207 | void XBee::InterpretMessage() |
ShaolinPoutine | 2:0000443a78fe | 208 | { |
ShaolinPoutine | 2:0000443a78fe | 209 | if (comm.readable()) |
ShaolinPoutine | 2:0000443a78fe | 210 | { |
EmileArseneault | 9:902d0f74333c | 211 | char start = getChar(); // = FRAMEDELIMITER |
ShaolinPoutine | 2:0000443a78fe | 212 | //assert |
EmileArseneault | 9:902d0f74333c | 213 | if (start == FRAMEDELIMITER) |
EmileArseneault | 9:902d0f74333c | 214 | { |
EmileArseneault | 9:902d0f74333c | 215 | char len_msb = getChar(); |
EmileArseneault | 9:902d0f74333c | 216 | char len_lsb = getChar(); |
EmileArseneault | 9:902d0f74333c | 217 | |
EmileArseneault | 9:902d0f74333c | 218 | int len = ((int) len_msb << 4) + (int) len_lsb; |
EmileArseneault | 9:902d0f74333c | 219 | |
EmileArseneault | 9:902d0f74333c | 220 | // Resolving frame type |
EmileArseneault | 9:902d0f74333c | 221 | char type = getChar(); |
EmileArseneault | 9:902d0f74333c | 222 | len--; |
EmileArseneault | 9:902d0f74333c | 223 | |
EmileArseneault | 9:902d0f74333c | 224 | switch (type){ |
EmileArseneault | 9:902d0f74333c | 225 | case 0x88: ATCommandResponse(len); |
EmileArseneault | 9:902d0f74333c | 226 | break; |
EmileArseneault | 9:902d0f74333c | 227 | case 0x8A: ModemStatus(len); |
EmileArseneault | 9:902d0f74333c | 228 | break; |
EmileArseneault | 9:902d0f74333c | 229 | case 0x8B: ZigBeeTransmitStatus(len); |
EmileArseneault | 9:902d0f74333c | 230 | break; |
EmileArseneault | 9:902d0f74333c | 231 | case 0x90: ZigBeeReceivePacket(len); |
EmileArseneault | 9:902d0f74333c | 232 | break; |
EmileArseneault | 9:902d0f74333c | 233 | default: pcPrint("Please implement response of type "); |
EmileArseneault | 9:902d0f74333c | 234 | printHexa(type); |
EmileArseneault | 9:902d0f74333c | 235 | pcPrint("\r\n\0"); |
EmileArseneault | 9:902d0f74333c | 236 | for (int i = 0; i <len; i++) |
EmileArseneault | 9:902d0f74333c | 237 | { |
EmileArseneault | 9:902d0f74333c | 238 | getChar(); |
EmileArseneault | 9:902d0f74333c | 239 | } |
EmileArseneault | 9:902d0f74333c | 240 | } |
ShaolinPoutine | 2:0000443a78fe | 241 | } |
EmileArseneault | 13:e0c47bcc92e7 | 242 | else |
EmileArseneault | 13:e0c47bcc92e7 | 243 | { |
EmileArseneault | 13:e0c47bcc92e7 | 244 | pcPrint("Not valid Frame\r\n"); |
EmileArseneault | 13:e0c47bcc92e7 | 245 | } |
ShaolinPoutine | 2:0000443a78fe | 246 | } |
ShaolinPoutine | 2:0000443a78fe | 247 | } |
ShaolinPoutine | 2:0000443a78fe | 248 | |
ShaolinPoutine | 2:0000443a78fe | 249 | void XBee::ATCommandResponse(int len) |
ShaolinPoutine | 2:0000443a78fe | 250 | { |
EmileArseneault | 20:e119856dbc5e | 251 | //char *receivedResponse = (char *)frameresponsemail->alloc(); |
EmileArseneault | 20:e119856dbc5e | 252 | //receivedResponse[0] = FRAMEDELIMITER; |
EmileArseneault | 20:e119856dbc5e | 253 | //receivedResponse[1] = len >> 4; |
EmileArseneault | 20:e119856dbc5e | 254 | //receivedResponse[2] = len; |
EmileArseneault | 20:e119856dbc5e | 255 | //receivedResponse[3] = 0x88; |
EmileArseneault | 20:e119856dbc5e | 256 | |
ShaolinPoutine | 2:0000443a78fe | 257 | char total = 0x88; |
EmileArseneault | 20:e119856dbc5e | 258 | char id; |
EmileArseneault | 20:e119856dbc5e | 259 | char command[2]; |
EmileArseneault | 20:e119856dbc5e | 260 | char status; |
ShaolinPoutine | 2:0000443a78fe | 261 | int i = 0; |
EmileArseneault | 20:e119856dbc5e | 262 | char data[255]; |
EmileArseneault | 20:e119856dbc5e | 263 | char checksum = 0; |
EmileArseneault | 20:e119856dbc5e | 264 | |
EmileArseneault | 20:e119856dbc5e | 265 | id = getChar(); |
EmileArseneault | 20:e119856dbc5e | 266 | |
EmileArseneault | 20:e119856dbc5e | 267 | command[0] = getChar(); |
EmileArseneault | 20:e119856dbc5e | 268 | command[1] = getChar(); |
EmileArseneault | 20:e119856dbc5e | 269 | total += command[0]; |
EmileArseneault | 20:e119856dbc5e | 270 | total += command[1]; |
EmileArseneault | 20:e119856dbc5e | 271 | |
EmileArseneault | 20:e119856dbc5e | 272 | status = getChar(); |
EmileArseneault | 20:e119856dbc5e | 273 | |
EmileArseneault | 20:e119856dbc5e | 274 | len -= 4; |
EmileArseneault | 20:e119856dbc5e | 275 | |
EmileArseneault | 18:39c72589645f | 276 | pcPrint("ID:"); |
EmileArseneault | 18:39c72589645f | 277 | printHexa(id); |
EmileArseneault | 18:39c72589645f | 278 | pcPrint(" response to command \0"); |
EmileArseneault | 20:e119856dbc5e | 279 | printHexa(command[0]); |
EmileArseneault | 20:e119856dbc5e | 280 | printHexa(command[1]); |
ShaolinPoutine | 2:0000443a78fe | 281 | pcPrint(" is \0"); |
ShaolinPoutine | 2:0000443a78fe | 282 | |
ShaolinPoutine | 4:e8f4d41c0fbc | 283 | if (len == 0) |
ShaolinPoutine | 4:e8f4d41c0fbc | 284 | { |
ShaolinPoutine | 4:e8f4d41c0fbc | 285 | switch (status) |
ShaolinPoutine | 4:e8f4d41c0fbc | 286 | { |
ShaolinPoutine | 4:e8f4d41c0fbc | 287 | case 0 : pcPrint("OK"); break; |
ShaolinPoutine | 4:e8f4d41c0fbc | 288 | case 1 : pcPrint("ERROR"); break; |
ShaolinPoutine | 4:e8f4d41c0fbc | 289 | case 2 : pcPrint("Invalid Command"); break; |
ShaolinPoutine | 4:e8f4d41c0fbc | 290 | case 3 : pcPrint("Invalid Parameter"); break; |
ShaolinPoutine | 4:e8f4d41c0fbc | 291 | case 4 : pcPrint("Tx Failure"); break; |
ShaolinPoutine | 4:e8f4d41c0fbc | 292 | default : pcPrint("Unknow error ..."); break; |
ShaolinPoutine | 4:e8f4d41c0fbc | 293 | } |
ShaolinPoutine | 4:e8f4d41c0fbc | 294 | } |
ShaolinPoutine | 4:e8f4d41c0fbc | 295 | |
EmileArseneault | 20:e119856dbc5e | 296 | //receivedResponse[4] = id; |
EmileArseneault | 20:e119856dbc5e | 297 | //receivedResponse[5] = command[0]; |
EmileArseneault | 20:e119856dbc5e | 298 | //receivedResponse[6] = command[1]; |
EmileArseneault | 20:e119856dbc5e | 299 | //receivedResponse[7] = status; |
EmileArseneault | 20:e119856dbc5e | 300 | |
ShaolinPoutine | 2:0000443a78fe | 301 | while (i < len) |
ShaolinPoutine | 2:0000443a78fe | 302 | { |
ShaolinPoutine | 2:0000443a78fe | 303 | if (comm.readable()) |
ShaolinPoutine | 2:0000443a78fe | 304 | { |
EmileArseneault | 9:902d0f74333c | 305 | data[i] = getChar(); |
EmileArseneault | 20:e119856dbc5e | 306 | //receivedResponse[8 + i] = data[i]; |
ShaolinPoutine | 2:0000443a78fe | 307 | total += data[i]; |
ShaolinPoutine | 2:0000443a78fe | 308 | printHexa(data[i]); |
ShaolinPoutine | 2:0000443a78fe | 309 | i++; |
ShaolinPoutine | 2:0000443a78fe | 310 | } |
ShaolinPoutine | 2:0000443a78fe | 311 | } |
ShaolinPoutine | 2:0000443a78fe | 312 | |
EmileArseneault | 20:e119856dbc5e | 313 | checksum = getChar(); |
EmileArseneault | 20:e119856dbc5e | 314 | //receivedResponse[8 + i] = checksum; |
EmileArseneault | 20:e119856dbc5e | 315 | //frameresponsemail->put((char(*)[254])&receivedResponse[0]); |
EmileArseneault | 20:e119856dbc5e | 316 | |
EmileArseneault | 20:e119856dbc5e | 317 | // Verify checksum |
EmileArseneault | 20:e119856dbc5e | 318 | total += id; |
EmileArseneault | 20:e119856dbc5e | 319 | total += status; |
ShaolinPoutine | 2:0000443a78fe | 320 | total += checksum; |
EmileArseneault | 20:e119856dbc5e | 321 | |
ShaolinPoutine | 2:0000443a78fe | 322 | if (total != 0xFF) |
ShaolinPoutine | 2:0000443a78fe | 323 | { |
ShaolinPoutine | 2:0000443a78fe | 324 | pcPrint("Checksum is wrong\0"); |
ShaolinPoutine | 2:0000443a78fe | 325 | } |
ShaolinPoutine | 2:0000443a78fe | 326 | pcPrint("\r\n\0"); |
ShaolinPoutine | 2:0000443a78fe | 327 | } |
ShaolinPoutine | 2:0000443a78fe | 328 | |
ShaolinPoutine | 2:0000443a78fe | 329 | void XBee::ModemStatus(int len) |
ShaolinPoutine | 2:0000443a78fe | 330 | { |
EmileArseneault | 9:902d0f74333c | 331 | char status = getChar(); |
ShaolinPoutine | 2:0000443a78fe | 332 | |
ShaolinPoutine | 2:0000443a78fe | 333 | switch (status){ |
ShaolinPoutine | 2:0000443a78fe | 334 | case 0 : pcPrint("Hardware reset\r\n\0"); break; |
ShaolinPoutine | 2:0000443a78fe | 335 | case 1 : pcPrint("Watchdog timer reset\r\n\0"); break; |
ShaolinPoutine | 2:0000443a78fe | 336 | case 2 : pcPrint("Joined network (routers and end devices)\r\n\0"); break; |
ShaolinPoutine | 2:0000443a78fe | 337 | case 3 : pcPrint("Disassociated\r\n\0"); break; |
ShaolinPoutine | 2:0000443a78fe | 338 | case 6 : pcPrint("Coordinator started\r\n\0"); break; |
ShaolinPoutine | 2:0000443a78fe | 339 | case 7 : pcPrint("Network security key was updated\r\n\0"); break; |
ShaolinPoutine | 2:0000443a78fe | 340 | case 0x0D : pcPrint("Voltage supply limit exceeded\r\n\0"); break; |
ShaolinPoutine | 2:0000443a78fe | 341 | case 0x11 : pcPrint("Modem configuration changed while join in progress\r\n\0"); break; |
ShaolinPoutine | 2:0000443a78fe | 342 | default : pcPrint("stack error\r\n\0"); break; |
ShaolinPoutine | 2:0000443a78fe | 343 | } |
ShaolinPoutine | 2:0000443a78fe | 344 | |
EmileArseneault | 9:902d0f74333c | 345 | char checksum = getChar(); |
ShaolinPoutine | 2:0000443a78fe | 346 | |
ShaolinPoutine | 2:0000443a78fe | 347 | checksum += 0x8A + status; |
ShaolinPoutine | 2:0000443a78fe | 348 | |
ShaolinPoutine | 2:0000443a78fe | 349 | if (checksum != 0xFF) |
ShaolinPoutine | 2:0000443a78fe | 350 | { |
ShaolinPoutine | 2:0000443a78fe | 351 | pcPrint("Checksum is wrong\r\n\0"); |
ShaolinPoutine | 2:0000443a78fe | 352 | } |
ShaolinPoutine | 3:4c1dec78117b | 353 | } |
ShaolinPoutine | 3:4c1dec78117b | 354 | |
ShaolinPoutine | 3:4c1dec78117b | 355 | void XBee::ZigBeeTransmitStatus(int len) |
ShaolinPoutine | 3:4c1dec78117b | 356 | { |
EmileArseneault | 9:902d0f74333c | 357 | char id = getChar(); |
EmileArseneault | 9:902d0f74333c | 358 | char msb = getChar(); |
EmileArseneault | 9:902d0f74333c | 359 | char lsb = getChar(); |
EmileArseneault | 9:902d0f74333c | 360 | char retry = getChar(); |
EmileArseneault | 9:902d0f74333c | 361 | char status = getChar(); |
EmileArseneault | 9:902d0f74333c | 362 | char discovery = getChar(); |
EmileArseneault | 5:9b4d93bd6725 | 363 | char checksum; |
ShaolinPoutine | 3:4c1dec78117b | 364 | |
ShaolinPoutine | 8:ba349a2eeb37 | 365 | pcPrint("Response to transmit #"); |
ShaolinPoutine | 8:ba349a2eeb37 | 366 | printHexa(id); |
EmileArseneault | 5:9b4d93bd6725 | 367 | pcPrint(" is : "); |
ShaolinPoutine | 3:4c1dec78117b | 368 | |
ShaolinPoutine | 3:4c1dec78117b | 369 | if (status == 0) |
ShaolinPoutine | 3:4c1dec78117b | 370 | { |
ShaolinPoutine | 3:4c1dec78117b | 371 | pcPrint("Success\r\n"); |
ShaolinPoutine | 3:4c1dec78117b | 372 | } |
ShaolinPoutine | 3:4c1dec78117b | 373 | else |
ShaolinPoutine | 3:4c1dec78117b | 374 | { |
ShaolinPoutine | 3:4c1dec78117b | 375 | switch (status){ |
ShaolinPoutine | 3:4c1dec78117b | 376 | case 0x01 : pcPrint("MAC ACK Failure\r\n"); break; |
ShaolinPoutine | 3:4c1dec78117b | 377 | case 0x02 : pcPrint("CCA Failure\r\n"); break; |
ShaolinPoutine | 3:4c1dec78117b | 378 | case 0x15 : pcPrint("Invalid destination endpoint\r\n"); break; |
ShaolinPoutine | 3:4c1dec78117b | 379 | case 0x21 : pcPrint("Network ACK Failure\r\n"); break; |
ShaolinPoutine | 3:4c1dec78117b | 380 | case 0x22 : pcPrint("Not Joined to Network\r\n"); break; |
ShaolinPoutine | 3:4c1dec78117b | 381 | case 0x23 : pcPrint("Self-addressed\r\n"); break; |
ShaolinPoutine | 3:4c1dec78117b | 382 | case 0x24 : pcPrint("Address Not Found\r\n"); break; |
ShaolinPoutine | 3:4c1dec78117b | 383 | case 0x25 : pcPrint("Route Not Found\r\n"); break; |
ShaolinPoutine | 3:4c1dec78117b | 384 | case 0x26 : pcPrint("Broadcast source failed to hear a neighbor relay the message\r\n"); break; |
ShaolinPoutine | 3:4c1dec78117b | 385 | case 0x2B : pcPrint("Invalid binding table index\r\n"); break; |
ShaolinPoutine | 3:4c1dec78117b | 386 | case 0x2C : pcPrint("Resource error lack of free buffers, timers, etc.\r\n"); break; |
ShaolinPoutine | 3:4c1dec78117b | 387 | case 0x2D : pcPrint("Attempted broadcast with APS transmission\r\n"); break; |
ShaolinPoutine | 3:4c1dec78117b | 388 | case 0x2E : pcPrint("Attempted unicast with APS transmission, but EE=0\r\n"); break; |
ShaolinPoutine | 3:4c1dec78117b | 389 | case 0x32 : pcPrint("Resource error lack of free buffers, timers, etc.\r\n"); break; |
ShaolinPoutine | 3:4c1dec78117b | 390 | case 0x74 : pcPrint("Data payload too large\r\n"); break; |
ShaolinPoutine | 3:4c1dec78117b | 391 | default : pcPrint("Unknow error ...\r\n"); break; |
ShaolinPoutine | 3:4c1dec78117b | 392 | } |
ShaolinPoutine | 3:4c1dec78117b | 393 | } |
EmileArseneault | 5:9b4d93bd6725 | 394 | |
EmileArseneault | 9:902d0f74333c | 395 | checksum = getChar(); |
EmileArseneault | 5:9b4d93bd6725 | 396 | // Validate checksum TODO |
ShaolinPoutine | 3:4c1dec78117b | 397 | } |
ShaolinPoutine | 3:4c1dec78117b | 398 | |
ShaolinPoutine | 3:4c1dec78117b | 399 | void XBee::ZigBeeReceivePacket(int len) |
ShaolinPoutine | 3:4c1dec78117b | 400 | { |
ShaolinPoutine | 3:4c1dec78117b | 401 | int i = 0; |
ShaolinPoutine | 3:4c1dec78117b | 402 | char adresse64bit[8]; |
ShaolinPoutine | 3:4c1dec78117b | 403 | char adresse16bit[2]; |
ShaolinPoutine | 3:4c1dec78117b | 404 | char receiveOptions; |
EmileArseneault | 5:9b4d93bd6725 | 405 | char checksum; |
EmileArseneault | 10:dac25a0076f5 | 406 | char data = 0; |
EmileArseneault | 10:dac25a0076f5 | 407 | char total = 0x90; |
EmileArseneault | 11:7b5b9c1ab757 | 408 | |
EmileArseneault | 11:7b5b9c1ab757 | 409 | printHexa(len+1); // DEBUG PRINT |
EmileArseneault | 11:7b5b9c1ab757 | 410 | pcPrint(" On recoit :"); // DEBUG PRINT |
EmileArseneault | 11:7b5b9c1ab757 | 411 | |
ShaolinPoutine | 3:4c1dec78117b | 412 | while(i < 8) |
ShaolinPoutine | 3:4c1dec78117b | 413 | { |
EmileArseneault | 9:902d0f74333c | 414 | adresse64bit[i] = getChar(); |
EmileArseneault | 11:7b5b9c1ab757 | 415 | pcPrint(" "); // DEBUG PRINT |
EmileArseneault | 11:7b5b9c1ab757 | 416 | printHexa(adresse64bit[i]); // DEBUG PRINT |
EmileArseneault | 10:dac25a0076f5 | 417 | total += adresse64bit[i]; |
ShaolinPoutine | 3:4c1dec78117b | 418 | i++; |
ShaolinPoutine | 3:4c1dec78117b | 419 | } |
ShaolinPoutine | 3:4c1dec78117b | 420 | |
EmileArseneault | 9:902d0f74333c | 421 | adresse16bit[0] = getChar(); |
EmileArseneault | 9:902d0f74333c | 422 | adresse16bit[1] = getChar(); |
ShaolinPoutine | 3:4c1dec78117b | 423 | |
EmileArseneault | 10:dac25a0076f5 | 424 | total += adresse16bit[0]; |
EmileArseneault | 10:dac25a0076f5 | 425 | total += adresse16bit[1]; |
ShaolinPoutine | 3:4c1dec78117b | 426 | |
EmileArseneault | 11:7b5b9c1ab757 | 427 | pcPrint(" "); // DEBUG PRINT |
EmileArseneault | 11:7b5b9c1ab757 | 428 | printHexa(adresse16bit[0]); // DEBUG PRINT |
EmileArseneault | 11:7b5b9c1ab757 | 429 | pcPrint(" "); // DEBUG PRINT |
EmileArseneault | 11:7b5b9c1ab757 | 430 | printHexa(adresse16bit[1]); // DEBUG PRINT |
EmileArseneault | 11:7b5b9c1ab757 | 431 | |
EmileArseneault | 10:dac25a0076f5 | 432 | receiveOptions = getChar(); |
EmileArseneault | 11:7b5b9c1ab757 | 433 | pcPrint(" "); // DEBUG PRINT |
EmileArseneault | 11:7b5b9c1ab757 | 434 | printHexa(receiveOptions); // DEBUG PRINT |
EmileArseneault | 11:7b5b9c1ab757 | 435 | |
EmileArseneault | 10:dac25a0076f5 | 436 | total += receiveOptions; |
EmileArseneault | 10:dac25a0076f5 | 437 | |
EmileArseneault | 11:7b5b9c1ab757 | 438 | //printHexa(len - 11); |
EmileArseneault | 11:7b5b9c1ab757 | 439 | //pcPrint(" Data received : "); |
ShaolinPoutine | 3:4c1dec78117b | 440 | |
ShaolinPoutine | 3:4c1dec78117b | 441 | i = 11; |
ShaolinPoutine | 3:4c1dec78117b | 442 | while (i < len) |
ShaolinPoutine | 3:4c1dec78117b | 443 | { |
EmileArseneault | 10:dac25a0076f5 | 444 | data = getChar(); |
EmileArseneault | 10:dac25a0076f5 | 445 | total += data; |
EmileArseneault | 11:7b5b9c1ab757 | 446 | pcPrint(" "); // DEBUG PRINT |
EmileArseneault | 11:7b5b9c1ab757 | 447 | printHexa(data); // DEBUG PRINT |
ShaolinPoutine | 3:4c1dec78117b | 448 | i++; |
ShaolinPoutine | 3:4c1dec78117b | 449 | } |
ShaolinPoutine | 3:4c1dec78117b | 450 | |
EmileArseneault | 9:902d0f74333c | 451 | checksum = getChar(); |
EmileArseneault | 10:dac25a0076f5 | 452 | total += checksum; |
EmileArseneault | 10:dac25a0076f5 | 453 | |
EmileArseneault | 11:7b5b9c1ab757 | 454 | pcPrint(" "); // DEBUG PRINT |
EmileArseneault | 11:7b5b9c1ab757 | 455 | printHexa(checksum); // DEBUG PRINT |
EmileArseneault | 11:7b5b9c1ab757 | 456 | |
EmileArseneault | 11:7b5b9c1ab757 | 457 | pcPrint("\r\n"); |
EmileArseneault | 11:7b5b9c1ab757 | 458 | |
EmileArseneault | 10:dac25a0076f5 | 459 | if (total != 0xFF) |
EmileArseneault | 10:dac25a0076f5 | 460 | { |
EmileArseneault | 10:dac25a0076f5 | 461 | pcPrint("Checksum is wrong\0"); |
EmileArseneault | 10:dac25a0076f5 | 462 | } |
EmileArseneault | 10:dac25a0076f5 | 463 | pcPrint("\r\n\0"); |
ShaolinPoutine | 3:4c1dec78117b | 464 | // Validate checksum TODO |
ShaolinPoutine | 6:3b97770f30e6 | 465 | } |
ShaolinPoutine | 6:3b97770f30e6 | 466 | |
EmileArseneault | 9:902d0f74333c | 467 | void XBee::ZigBeeTransmit(int adresse16, int adresse64msb, int adresse64lsb, char *data, int dataLength) |
ShaolinPoutine | 6:3b97770f30e6 | 468 | { |
ShaolinPoutine | 6:3b97770f30e6 | 469 | // Frame Type 0x10 |
ShaolinPoutine | 6:3b97770f30e6 | 470 | // 0x0000000000000000 - Reserved 64-bit address for the coordinator |
ShaolinPoutine | 6:3b97770f30e6 | 471 | // 0x000000000000FFFF - Broadcast address |
ShaolinPoutine | 6:3b97770f30e6 | 472 | |
ShaolinPoutine | 6:3b97770f30e6 | 473 | // The Transmit Status frame (0x8B) est la reponse |
ShaolinPoutine | 6:3b97770f30e6 | 474 | char cmdtosend[25]; |
ShaolinPoutine | 6:3b97770f30e6 | 475 | char checksum = 0x00; |
ShaolinPoutine | 6:3b97770f30e6 | 476 | int cmdlength = 18; |
ShaolinPoutine | 6:3b97770f30e6 | 477 | int i = 3; |
ShaolinPoutine | 6:3b97770f30e6 | 478 | |
ShaolinPoutine | 6:3b97770f30e6 | 479 | //ID command to set/read operating 64 bit PAN ID |
ShaolinPoutine | 6:3b97770f30e6 | 480 | //WR command to set operating 64 bit PAN ID across reboot |
ShaolinPoutine | 6:3b97770f30e6 | 481 | //OI command to read operating 16 bit PAN ID |
ShaolinPoutine | 6:3b97770f30e6 | 482 | //II command to set operating 16 bit PAN ID |
ShaolinPoutine | 6:3b97770f30e6 | 483 | |
ShaolinPoutine | 6:3b97770f30e6 | 484 | cmdtosend[0] = FRAMEDELIMITER; |
ShaolinPoutine | 6:3b97770f30e6 | 485 | cmdtosend[1] = 0x00; |
ShaolinPoutine | 6:3b97770f30e6 | 486 | cmdtosend[2] = 0x0E + dataLength; |
ShaolinPoutine | 6:3b97770f30e6 | 487 | cmdtosend[3] = 0x10; // Frame type |
ShaolinPoutine | 6:3b97770f30e6 | 488 | cmdtosend[4] = 0x01; // Frame number |
EmileArseneault | 12:e62381cdc9de | 489 | |
EmileArseneault | 12:e62381cdc9de | 490 | cmdtosend[5] = (adresse64msb & 0xFF000000) >> 24; // MSB adresse 64-bit |
EmileArseneault | 12:e62381cdc9de | 491 | cmdtosend[6] = (adresse64msb & 0x00FF0000) >> 16; |
EmileArseneault | 12:e62381cdc9de | 492 | cmdtosend[7] = (adresse64msb & 0x0000FF00) >> 8; |
EmileArseneault | 12:e62381cdc9de | 493 | cmdtosend[8] = adresse64msb & 0x000000FF; |
EmileArseneault | 12:e62381cdc9de | 494 | |
EmileArseneault | 12:e62381cdc9de | 495 | cmdtosend[9] = (adresse64lsb & 0xFF000000) >> 24; |
EmileArseneault | 12:e62381cdc9de | 496 | cmdtosend[10] = (adresse64lsb & 0x00FF0000) >> 16; |
EmileArseneault | 12:e62381cdc9de | 497 | cmdtosend[11] = (adresse64lsb & 0x0000FF00) >> 8; |
EmileArseneault | 12:e62381cdc9de | 498 | cmdtosend[12] = adresse64lsb & 0x000000FF; // LSB adresse 64-bit |
EmileArseneault | 12:e62381cdc9de | 499 | |
EmileArseneault | 12:e62381cdc9de | 500 | cmdtosend[13] = adresse16 >> 8; // MSB adresse 16-bit |
EmileArseneault | 12:e62381cdc9de | 501 | cmdtosend[14] = adresse16 & 0x00FF; // LSB adresse 16-bit |
ShaolinPoutine | 6:3b97770f30e6 | 502 | cmdtosend[15] = 0x00; // Broadcast Radius |
ShaolinPoutine | 6:3b97770f30e6 | 503 | cmdtosend[16] = 0x00; // Options |
ShaolinPoutine | 6:3b97770f30e6 | 504 | |
ShaolinPoutine | 6:3b97770f30e6 | 505 | // Set RF DATA |
ShaolinPoutine | 6:3b97770f30e6 | 506 | if(data != NULL) |
ShaolinPoutine | 6:3b97770f30e6 | 507 | { |
ShaolinPoutine | 6:3b97770f30e6 | 508 | i = 0; |
ShaolinPoutine | 6:3b97770f30e6 | 509 | cmdlength += dataLength; |
ShaolinPoutine | 6:3b97770f30e6 | 510 | |
ShaolinPoutine | 6:3b97770f30e6 | 511 | while (i < dataLength) |
ShaolinPoutine | 6:3b97770f30e6 | 512 | { |
ShaolinPoutine | 6:3b97770f30e6 | 513 | cmdtosend[17 + i] = (data)[i]; |
ShaolinPoutine | 6:3b97770f30e6 | 514 | i++; |
ShaolinPoutine | 6:3b97770f30e6 | 515 | } |
ShaolinPoutine | 6:3b97770f30e6 | 516 | } |
ShaolinPoutine | 6:3b97770f30e6 | 517 | |
ShaolinPoutine | 6:3b97770f30e6 | 518 | // Calculate checksum |
ShaolinPoutine | 6:3b97770f30e6 | 519 | i = 3; |
ShaolinPoutine | 6:3b97770f30e6 | 520 | while (i < (cmdlength - 1)) |
ShaolinPoutine | 6:3b97770f30e6 | 521 | { |
ShaolinPoutine | 6:3b97770f30e6 | 522 | checksum += cmdtosend[i]; |
ShaolinPoutine | 6:3b97770f30e6 | 523 | i++; |
ShaolinPoutine | 6:3b97770f30e6 | 524 | } |
ShaolinPoutine | 6:3b97770f30e6 | 525 | cmdtosend[cmdlength - 1] = 0xFF - checksum; |
ShaolinPoutine | 6:3b97770f30e6 | 526 | |
ShaolinPoutine | 6:3b97770f30e6 | 527 | // Envoyer la commande sur UART |
ShaolinPoutine | 6:3b97770f30e6 | 528 | i = 0; |
EmileArseneault | 11:7b5b9c1ab757 | 529 | pcPrint("On envoie :"); // DEBUG PRINT |
ShaolinPoutine | 6:3b97770f30e6 | 530 | while (i < cmdlength) |
ShaolinPoutine | 6:3b97770f30e6 | 531 | { |
EmileArseneault | 11:7b5b9c1ab757 | 532 | comm.putc(cmdtosend[i]); // DEBUG PRINT |
EmileArseneault | 11:7b5b9c1ab757 | 533 | pcPrint(" "); |
EmileArseneault | 11:7b5b9c1ab757 | 534 | printHexa(cmdtosend[i]); // DEBUG PRINT |
ShaolinPoutine | 6:3b97770f30e6 | 535 | i++; |
ShaolinPoutine | 6:3b97770f30e6 | 536 | } |
EmileArseneault | 11:7b5b9c1ab757 | 537 | pcPrint("\r\n"); // DEBUG PRINT |
ShaolinPoutine | 6:3b97770f30e6 | 538 | wait(0.1); |
EmileArseneault | 9:902d0f74333c | 539 | } |
EmileArseneault | 9:902d0f74333c | 540 | |
EmileArseneault | 9:902d0f74333c | 541 | void XBee::BroadcastHelloWorld() |
EmileArseneault | 9:902d0f74333c | 542 | { |
EmileArseneault | 9:902d0f74333c | 543 | char hello[5] = {'H', 'e', 'l', 'l', 'o'}; |
EmileArseneault | 9:902d0f74333c | 544 | char world[5] = {'w', 'o', 'r', 'l', 'd'}; |
EmileArseneault | 9:902d0f74333c | 545 | |
EmileArseneault | 9:902d0f74333c | 546 | while (1) |
EmileArseneault | 9:902d0f74333c | 547 | { |
EmileArseneault | 9:902d0f74333c | 548 | ZigBeeTransmit(0x0000, 0x00000000, 0x00000000, &hello[0], 5); |
EmileArseneault | 9:902d0f74333c | 549 | ZigBeeTransmit(0x0000, 0x00000000, 0x00000000, &world[0], 5); |
EmileArseneault | 9:902d0f74333c | 550 | wait(2); |
EmileArseneault | 9:902d0f74333c | 551 | } |
ShaolinPoutine | 2:0000443a78fe | 552 | } |