Rev 1377 | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 986 | runge | 1 | |
| 2 | function CanNode(hardwareId, numberOfModules) |
||
| 3 | { |
||
| 4 | this.myHardwareId = hardwareId; |
||
| 5 | this.myNumberOfModules = numberOfModules; |
||
| 6 | this.myModules = new Array(); |
||
| 7 | this.myHeartbeatTime = 0; |
||
| 8 | this.myIsOnline = false; |
||
| 1008 | runge | 9 | this.stopProgramming(); |
| 986 | runge | 10 | } |
| 11 | |||
| 12 | CanNode.prototype.myIsOnline = null; |
||
| 13 | CanNode.prototype.myHardwareId = null; |
||
| 14 | CanNode.prototype.myNumberOfModules = null; |
||
| 15 | CanNode.prototype.myModules = null; |
||
| 16 | CanNode.prototype.myHeartbeatTime = null; |
||
| 1008 | runge | 17 | CanNode.prototype.myProgrammingIsBios = null; |
| 1043 | arune | 18 | CanNode.prototype.myProgrammingBiosOffset = null; |
| 1008 | runge | 19 | CanNode.prototype.myProgramming = null; |
| 20 | CanNode.prototype.myProgrammingHex = null; |
||
| 1013 | arune | 21 | CanNode.prototype.myProgrammingHexAddress = null; |
| 1020 | arune | 22 | CanNode.prototype.myProgrammingOffset = null; |
| 1008 | runge | 23 | CanNode.prototype.myProgrammingCallback = null; |
| 24 | CanNode.prototype.myProgrammingWantAck = null; |
||
| 1020 | arune | 25 | CanNode.prototype.myProgrammingState = null; |
| 1034 | arune | 26 | CanNode.prototype.myProgrammingLastPercent = null; |
| 27 | CanNode.prototype.myProgrammingLastTenPercent = null; |
||
| 28 | CanNode.prototype.myProgrammingnrOfTicks = null; |
||
| 29 | CanNode.prototype.myProgrammingTimeout = null; |
||
| 30 | CanNode.prototype.myProgrammingResend = null; |
||
| 31 | CanNode.prototype.myProgrammingLastPacket = null; |
||
| 1037 | arune | 32 | CanNode.prototype.myProgrammingTimeStarted = null; |
| 1040 | runge | 33 | CanNode.prototype.myResetCallback = null; |
| 34 | CanNode.prototype.myResetTimer = null; |
||
| 986 | runge | 35 | |
| 36 | CanNode.prototype.isOnline = function() |
||
| 37 | { |
||
| 38 | return this.myIsOnline; |
||
| 39 | } |
||
| 40 | |||
| 1008 | runge | 41 | CanNode.prototype.start = function() |
| 42 | { |
||
| 43 | var canMessage = new CanNMTMessage("nmt", "Start_App"); |
||
| 44 | canMessage.setData("HardwareId", this.myHardwareId); |
||
| 45 | canMessage.send(); |
||
| 46 | } |
||
| 47 | |||
| 1040 | runge | 48 | CanNode.prototype.reset = function(callback) |
| 986 | runge | 49 | { |
| 1040 | runge | 50 | var self = this; |
| 51 | |||
| 1042 | runge | 52 | if (callback) |
| 1040 | runge | 53 | { |
| 1042 | runge | 54 | this.myResetCallback = callback; |
| 55 | if (this.myResetTimer) |
||
| 56 | { |
||
| 57 | this.myResetTimer.stop(); |
||
| 58 | } |
||
| 59 | |||
| 60 | this.myResetTimer = new Interval( function() |
||
| 61 | { |
||
| 62 | self.myResetTimer.stop(); |
||
| 63 | self.myResetTimer = null; |
||
| 64 | self.myResetCallback(false); |
||
| 65 | self.myResetCallback = null; |
||
| 66 | }, 5000); |
||
| 67 | this.myResetTimer.start(); |
||
| 1040 | runge | 68 | } |
| 69 | |||
| 986 | runge | 70 | var canMessage = new CanNMTMessage("nmt", "Reset"); |
| 71 | canMessage.setData("HardwareId", this.myHardwareId); |
||
| 1008 | runge | 72 | canMessage.send(); |
| 1040 | runge | 73 | |
| 74 | this.setOffline(); |
||
| 986 | runge | 75 | } |
| 76 | |||
| 77 | CanNode.prototype.startApplication = function() |
||
| 78 | { |
||
| 79 | var canMessage = new CanNMTMessage("nmt", "Start_App"); |
||
| 80 | canMessage.setData("HardwareId", this.myHardwareId); |
||
| 1008 | runge | 81 | canMessage.send(); |
| 986 | runge | 82 | } |
| 83 | |||
| 84 | CanNode.prototype.handleHeartbeat = function(numberOfModules) |
||
| 85 | { |
||
| 1008 | runge | 86 | if (numberOfModules) |
| 986 | runge | 87 | { |
| 1008 | runge | 88 | this.myNumberOfModules = numberOfModules; |
| 89 | } |
||
| 90 | |||
| 91 | if (this.myNumberOfModules == null || this.myNumberOfModules > this.myModules.length) |
||
| 92 | { |
||
| 986 | runge | 93 | var canMessage = new CanMessage("mnmt", "To_Owner", "", 0, "List"); |
| 94 | canMessage.setData("HardwareId", this.myHardwareId); |
||
| 1008 | runge | 95 | canMessage.send(); |
| 986 | runge | 96 | } |
| 97 | |||
| 98 | this.onlineHandler(); |
||
| 99 | } |
||
| 100 | |||
| 1008 | runge | 101 | CanNode.prototype.startProgramming = function(hexData, progressCallback, isBios) |
| 102 | { |
||
| 1063 | arune | 103 | this.myProgrammingCallback = progressCallback; |
| 1008 | runge | 104 | if (isBios) |
| 105 | { |
||
| 1013 | arune | 106 | this.myProgrammingIsBios = isBios; |
| 1043 | arune | 107 | this.myProgrammingBiosOffset = hexData.getAddrLower(); |
| 1063 | arune | 108 | //this.myProgrammingCallback(true, "", "got IsBios, address: " + this.myProgrammingBiosOffset, false); |
| 1008 | runge | 109 | } |
| 110 | else |
||
| 111 | { |
||
| 112 | this.myProgrammingIsBios = false; |
||
| 113 | } |
||
| 114 | |||
| 115 | this.myProgramming = true; |
||
| 116 | this.myProgrammingHex = hexData; |
||
| 117 | |||
| 1014 | runge | 118 | CanProgrammingNode = this; |
| 119 | |||
| 1034 | arune | 120 | var self = this; |
| 121 | this.myProgrammingTimeout = new Interval(function() { self.programmingTimeout() }, 6000); |
||
| 122 | this.myProgrammingTimeout.start(); |
||
| 123 | this.myProgrammingState = "RESET"; |
||
| 124 | |||
| 1008 | runge | 125 | this.reset(); |
| 126 | } |
||
| 127 | |||
| 1034 | arune | 128 | CanNode.prototype.programmingTimeout = function() |
| 129 | { |
||
| 130 | switch (this.myProgrammingState) |
||
| 131 | { |
||
| 132 | case "RESET": |
||
| 133 | this.stopProgramming(true, "Timeout while waiting for node to reset"); |
||
| 134 | this.reset(); |
||
| 135 | break; |
||
| 136 | case "DATA": |
||
| 137 | this.stopProgramming(true, "Timeout while waiting for node to ack data packet"); |
||
| 138 | this.reset(); |
||
| 139 | break; |
||
| 140 | case "END": |
||
| 141 | this.stopProgramming(true, "Timeout while waiting for node to ack data packet*"); |
||
| 142 | this.reset(); |
||
| 143 | break; |
||
| 144 | case "CRC": |
||
| 145 | this.stopProgramming(true, "Timeout while waiting for node to send crc"); |
||
| 146 | this.reset(); |
||
| 147 | break; |
||
| 148 | case "COPY": |
||
| 149 | //this will never occur, bios does not send ack for copy command, it just moves data in flash then reset itself |
||
| 1063 | arune | 150 | this.myProgrammingCallback(true, "ERROR", "Unexpected error 100", false); |
| 1034 | arune | 151 | break; |
| 1066 | arune | 152 | case "DONE": |
| 153 | this.stopProgramming(true, "Timeout while waiting for node to start bios"); |
||
| 154 | this.reset(); |
||
| 155 | break; |
||
| 1034 | arune | 156 | default: |
| 1063 | arune | 157 | this.myProgrammingCallback(true, "ERROR", "Unexpected error 101, state: " + this.myProgrammingState, false); |
| 1034 | arune | 158 | break; |
| 159 | } |
||
| 160 | } |
||
| 161 | |||
| 162 | CanNode.prototype.programmingResend = function() |
||
| 163 | { |
||
| 1043 | arune | 164 | this.myProgrammingCallback(true, "", "Resend timeout, a packet was lost, either program data or ack", false); |
| 165 | this.myProgrammingResend.reset(); |
||
| 1034 | arune | 166 | //if we did not got ack then try to resend the data |
| 167 | this.myProgrammingLastPacket.send(); |
||
| 168 | } |
||
| 169 | |||
| 1008 | runge | 170 | CanNode.prototype.handleBiosStart = function(biosVersion, hasApplication) |
| 171 | { |
||
| 1040 | runge | 172 | if (this.myResetCallback) |
| 173 | { |
||
| 174 | this.myResetCallback(true); |
||
| 175 | this.myResetCallback = null; |
||
| 176 | } |
||
| 177 | |||
| 178 | if (this.myResetTimer) |
||
| 179 | { |
||
| 180 | this.myResetTimer.stop(); |
||
| 181 | this.myResetTimer = null; |
||
| 182 | } |
||
| 183 | |||
| 1013 | arune | 184 | //print("node was reset and bios just started, ver:" + biosVersion); |
| 1008 | runge | 185 | if (this.myProgramming) |
| 186 | { |
||
| 1063 | arune | 187 | switch (this.myProgrammingState) |
| 188 | { |
||
| 189 | case "RESET": |
||
| 190 | this.myProgrammingHexAddress = this.myProgrammingHex.getAddrLower(); |
||
| 191 | this.myProgrammingWantAck = (((this.myProgrammingHexAddress-this.myProgrammingBiosOffset)<<8)|((this.myProgrammingHexAddress-this.myProgrammingBiosOffset)>>8))&0xffff; |
||
| 1043 | arune | 192 | |
| 1063 | arune | 193 | var canMessage = new CanNMTMessage("nmt", "Pgm_Start"); |
| 194 | canMessage.setData("HardwareId", this.myHardwareId); |
||
| 195 | canMessage.setData("Address0", (this.myProgrammingHexAddress-this.myProgrammingBiosOffset)&0xff); |
||
| 196 | canMessage.setData("Address1", ((this.myProgrammingHexAddress-this.myProgrammingBiosOffset)>>8)&0xff); |
||
| 197 | canMessage.setData("Address3", ((this.myProgrammingHexAddress-this.myProgrammingBiosOffset)>>16)&0xff); |
||
| 198 | canMessage.setData("Address4", ((this.myProgrammingHexAddress-this.myProgrammingBiosOffset)>>24)&0xff); |
||
| 199 | canMessage.send(); |
||
| 200 | this.myProgrammingState = "DATA"; |
||
| 1008 | runge | 201 | |
| 1063 | arune | 202 | var self = this; |
| 203 | this.myProgrammingTimeout.setTimeout(1000); |
||
| 1034 | arune | 204 | |
| 1063 | arune | 205 | this.myProgrammingResend = new Interval(function() { self.programmingResend() }, 1100); |
| 206 | this.myProgrammingResend.start(); |
||
| 1034 | arune | 207 | |
| 1063 | arune | 208 | var date = new Date(); |
| 209 | this.myProgrammingTimeStarted = date.getTime(); |
||
| 1037 | arune | 210 | |
| 1063 | arune | 211 | this.myProgrammingCallback(true, "START", "Started programming of node", false); |
| 212 | this.myProgrammingCallback(true, "", " 0% [", true); |
||
| 213 | break; |
||
| 214 | case "COPY": |
||
| 215 | //bios was moved and now started (so it seems like it was successfully programmed and moved) |
||
| 216 | //now we should send a new programming with one empty packet to erase application area |
||
| 217 | this.myProgrammingWantAck = 0; |
||
| 218 | var canMessage = new CanNMTMessage("nmt", "Pgm_Start"); |
||
| 219 | canMessage.setData("HardwareId", this.myHardwareId); |
||
| 220 | canMessage.setData("Address0", 0); |
||
| 221 | canMessage.setData("Address1", 0); |
||
| 222 | canMessage.setData("Address3", 0); |
||
| 223 | canMessage.setData("Address4", 0); |
||
| 224 | canMessage.send(); |
||
| 225 | this.myProgrammingState = "APPCLEANDATA"; |
||
| 226 | break; |
||
| 227 | case "DONE": |
||
| 228 | this.stopProgramming(true, "Done, successful"); |
||
| 229 | break; |
||
| 230 | default: |
||
| 231 | this.myProgrammingCallback(true, "ERROR", "Unexpected error 105, state: " + this.myProgrammingState, false); |
||
| 232 | break; |
||
| 233 | } |
||
| 234 | |||
| 1008 | runge | 235 | } |
| 236 | } |
||
| 237 | |||
| 1020 | arune | 238 | CanNode.prototype.handleNack = function(data) |
| 239 | { |
||
| 1043 | arune | 240 | this.stopProgramming(true, "Failed, got NACK, sending reset"); |
| 1020 | arune | 241 | this.reset(); |
| 242 | if (false) |
||
| 243 | { |
||
| 244 | } |
||
| 245 | } |
||
| 246 | |||
| 1008 | runge | 247 | CanNode.prototype.handleAck = function(data) |
| 248 | { |
||
| 1042 | runge | 249 | this.myProgrammingTimeout.reset(); |
| 1034 | arune | 250 | |
| 1020 | arune | 251 | if (data == this.myProgrammingWantAck) |
| 1008 | runge | 252 | { |
| 1020 | arune | 253 | switch (this.myProgrammingState) |
| 1008 | runge | 254 | { |
| 1020 | arune | 255 | case "DATA": |
| 256 | var offset = this.myProgrammingHexOffset; |
||
| 1043 | arune | 257 | this.myProgrammingResend.setTimeout(100); |
| 258 | this.myProgrammingResend.reset(); |
||
| 1008 | runge | 259 | |
| 1022 | arune | 260 | this.myProgrammingWantAck = ((offset<<8)|(offset>>8))&0xffff; |
| 1020 | arune | 261 | var bytesLeft = this.myProgrammingHex.getLength() - this.myProgrammingHexOffset; |
| 262 | |||
| 263 | //here we must handle the possibility that data is less then 48 bits |
||
| 264 | var canMessage = new CanNMTMessage("nmt", "Pgm_Data_48"); |
||
| 265 | switch (bytesLeft) |
||
| 266 | { |
||
| 267 | case 1: |
||
| 268 | canMessage = new CanNMTMessage("nmt", "Pgm_Data_8"); |
||
| 269 | break; |
||
| 270 | case 2: |
||
| 271 | canMessage = new CanNMTMessage("nmt", "Pgm_Data_16"); |
||
| 272 | break; |
||
| 273 | case 3: |
||
| 274 | canMessage = new CanNMTMessage("nmt", "Pgm_Data_24"); |
||
| 275 | break; |
||
| 276 | case 4: |
||
| 277 | canMessage = new CanNMTMessage("nmt", "Pgm_Data_32"); |
||
| 278 | break; |
||
| 279 | case 5: |
||
| 280 | canMessage = new CanNMTMessage("nmt", "Pgm_Data_40"); |
||
| 281 | break; |
||
| 282 | } |
||
| 283 | |||
| 1022 | arune | 284 | canMessage.setData("Offset0", offset&0xff); |
| 285 | canMessage.setData("Offset1", (offset>>8)&0xff); |
||
| 1020 | arune | 286 | for (var i=0; i<bytesLeft && i<6; i++) |
| 287 | { |
||
| 288 | switch (i) |
||
| 289 | { |
||
| 290 | case 0: |
||
| 1043 | arune | 291 | canMessage.setData("Data0", this.myProgrammingHex.getByte(this.myProgrammingHexAddress+offset)); |
| 1020 | arune | 292 | break; |
| 293 | case 1: |
||
| 1043 | arune | 294 | canMessage.setData("Data1", this.myProgrammingHex.getByte(this.myProgrammingHexAddress+offset)); |
| 1020 | arune | 295 | break; |
| 296 | case 2: |
||
| 1043 | arune | 297 | canMessage.setData("Data2", this.myProgrammingHex.getByte(this.myProgrammingHexAddress+offset)); |
| 1020 | arune | 298 | break; |
| 299 | case 3: |
||
| 1043 | arune | 300 | canMessage.setData("Data3", this.myProgrammingHex.getByte(this.myProgrammingHexAddress+offset)); |
| 1020 | arune | 301 | break; |
| 302 | case 4: |
||
| 1043 | arune | 303 | canMessage.setData("Data4", this.myProgrammingHex.getByte(this.myProgrammingHexAddress+offset)); |
| 1020 | arune | 304 | break; |
| 305 | case 5: |
||
| 1043 | arune | 306 | canMessage.setData("Data5", this.myProgrammingHex.getByte(this.myProgrammingHexAddress+offset)); |
| 1020 | arune | 307 | break; |
| 308 | } |
||
| 309 | offset++; |
||
| 310 | } |
||
| 1008 | runge | 311 | canMessage.send(); |
| 1020 | arune | 312 | this.myProgrammingHexOffset = offset; |
| 313 | |||
| 314 | if (this.myProgrammingHexOffset >= this.myProgrammingHex.getLength()) { |
||
| 315 | this.myProgrammingState = "END"; |
||
| 316 | } |
||
| 1008 | runge | 317 | |
| 1034 | arune | 318 | //this.myProgrammingCallback(true, "PROGRESS", this.myProgrammingHexOffset + ":" + this.myProgrammingHex.getLength(), false); |
| 319 | var percent = 100*this.myProgrammingHexOffset / this.myProgrammingHex.getLength(); |
||
| 320 | if (percent >= this.myProgrammingLastPercent+2.5) |
||
| 321 | { |
||
| 322 | this.myProgrammingCallback(true, "", "=", true); |
||
| 323 | this.myProgrammingLastPercent+=2.5; |
||
| 324 | this.myProgrammingnrOfTicks++; |
||
| 325 | } |
||
| 326 | if (percent > this.myProgrammingLastTenPercent+10) |
||
| 327 | { |
||
| 328 | for (var i=this.myProgrammingnrOfTicks; i<40; i++) this.myProgrammingCallback(true, "", " ", true); |
||
| 329 | this.myProgrammingCallback(true, "", "]", true); |
||
| 330 | this.myProgrammingCallback(true, "", "\r", true); |
||
| 331 | this.myProgrammingCallback(true, "", " "+Math.round(percent)+"% [", true); |
||
| 332 | this.myProgrammingLastTenPercent+=10; |
||
| 333 | for (var i=0; i<this.myProgrammingnrOfTicks; i++) this.myProgrammingCallback(true, "", "=", true); |
||
| 334 | } |
||
| 335 | |||
| 336 | this.myProgrammingLastPacket = canMessage; |
||
| 1008 | runge | 337 | break; |
| 338 | |||
| 1020 | arune | 339 | case "END": |
| 1022 | arune | 340 | this.myProgrammingWantAck = ((this.myProgrammingHex.getCRC16()<<8)|(this.myProgrammingHex.getCRC16()>>8))&0xffff; |
| 1037 | arune | 341 | |
| 342 | var timeElapsed = 0; |
||
| 343 | var printTime = ""; |
||
| 344 | if (this.myProgrammingTimeStarted>0) |
||
| 345 | { |
||
| 346 | var date = new Date(); |
||
| 347 | timeElapsed = date.getTime() - this.myProgrammingTimeStarted; |
||
| 348 | printTime = " in " + Math.round(timeElapsed/1000) + "s, " + Math.round(this.myProgrammingHex.getLength()*1000/timeElapsed)+"bytes/s"; |
||
| 349 | } |
||
| 350 | |||
| 1008 | runge | 351 | var canMessage = new CanNMTMessage("nmt", "Pgm_End"); |
| 352 | canMessage.send(); |
||
| 1020 | arune | 353 | |
| 354 | this.myProgrammingState = "CRC"; |
||
| 1034 | arune | 355 | for (var i=this.myProgrammingnrOfTicks; i<40; i++) this.myProgrammingCallback(true, "", " ", true); |
| 356 | this.myProgrammingCallback(true, "", "]", true); |
||
| 357 | this.myProgrammingCallback(true, "", "\r", true); |
||
| 1037 | arune | 358 | this.myProgrammingCallback(true, "", "100% [========================================]"+printTime, true); |
| 1034 | arune | 359 | |
| 360 | if (this.myProgrammingResend != null) |
||
| 361 | { |
||
| 362 | /* Stop the interval */ |
||
| 363 | this.myProgrammingResend.stop(); |
||
| 364 | } |
||
| 365 | |||
| 1020 | arune | 366 | break; |
| 1008 | runge | 367 | |
| 1020 | arune | 368 | case "CRC": |
| 1066 | arune | 369 | this.myProgrammingTimeout.setTimeout(6000); |
| 1020 | arune | 370 | //is this a bios programming? |
| 1043 | arune | 371 | if (this.myProgrammingIsBios) |
| 1020 | arune | 372 | { |
| 373 | this.myProgrammingState = "COPY"; |
||
| 1043 | arune | 374 | this.myProgrammingCallback(true, "\nBIOS", "Start to copy bios to new location", false); |
| 1020 | arune | 375 | var canMessage = new CanNMTMessage("nmt", "Pgm_Copy"); |
| 1043 | arune | 376 | canMessage.setData("Source0", 0); |
| 377 | canMessage.setData("Source1", 0); |
||
| 378 | canMessage.setData("Destination0", this.myProgrammingBiosOffset&0xff); |
||
| 379 | canMessage.setData("Destination1", (this.myProgrammingBiosOffset>>8)&0xff); |
||
| 1063 | arune | 380 | canMessage.setData("Length0", (this.myProgrammingHex.getLength())&0xff); |
| 381 | canMessage.setData("Length1", (this.myProgrammingHex.getLength()>>8)&0xff); |
||
| 1020 | arune | 382 | canMessage.send(); |
| 1063 | arune | 383 | //this.stopProgramming(); |
| 1020 | arune | 384 | } |
| 385 | else |
||
| 386 | { |
||
| 1063 | arune | 387 | this.myProgrammingState = "DONE"; |
| 1020 | arune | 388 | this.reset(); |
| 389 | } |
||
| 1008 | runge | 390 | break; |
| 391 | |||
| 1020 | arune | 392 | case "COPY": //this will never occur, bios does not send ack for copy command, it just moves data in flash then reset itself |
| 1008 | runge | 393 | break; |
| 1063 | arune | 394 | case "APPCLEANDATA": |
| 395 | var canMessage = new CanNMTMessage("nmt", "Pgm_Data_16"); |
||
| 396 | this.myProgrammingWantAck = 0; |
||
| 397 | this.myProgrammingState = "APPCLEANEND"; |
||
| 398 | canMessage.setData("Data0", 0xff); |
||
| 399 | canMessage.setData("Data1", 0xff); |
||
| 400 | canMessage.send(); |
||
| 401 | break; |
||
| 402 | case "APPCLEANEND": |
||
| 403 | this.myProgrammingWantAck = 0x1b0; |
||
| 404 | this.myProgrammingState = "APPCLEANCRC"; |
||
| 405 | var canMessage = new CanNMTMessage("nmt", "Pgm_End"); |
||
| 406 | canMessage.send(); |
||
| 407 | break; |
||
| 408 | case "APPCLEANCRC": |
||
| 409 | this.myProgrammingState = "DONE"; |
||
| 410 | this.reset(); |
||
| 411 | break; |
||
| 412 | |||
| 1008 | runge | 413 | default: |
| 1063 | arune | 414 | this.myProgrammingCallback(true, "ERROR", "Unexpected error 104, state: " + this.myProgrammingState, false); |
| 1020 | arune | 415 | break; |
| 1008 | runge | 416 | } |
| 417 | } |
||
| 418 | else |
||
| 419 | { |
||
| 1020 | arune | 420 | switch (this.myProgrammingState) |
| 421 | { |
||
| 422 | case "DATA": |
||
| 423 | //Fall through |
||
| 424 | case "END": |
||
| 425 | ///TODO: We got something that was not correct... we should abort |
||
| 426 | this.stopProgramming(true, "Failed to program, ack had wrong offset, expected data: "+this.myProgrammingWantAck+" got: "+data); |
||
| 427 | this.reset(); |
||
| 428 | break; |
||
| 429 | case "CRC": |
||
| 430 | this.stopProgramming(true, "Failed to program, CRC not matching, expected data: "+this.myProgrammingWantAck+" got: "+data); |
||
| 431 | this.reset(); |
||
| 432 | break; |
||
| 433 | case "COPY": //this will never occur, bios does not send ack for copy command, it just moves data in flash then reset itself |
||
| 1063 | arune | 434 | this.myProgrammingCallback(true, "ERROR", "Unexpected error 103", false); |
| 1020 | arune | 435 | break; |
| 436 | default: |
||
| 1063 | arune | 437 | this.myProgrammingCallback(true, "ERROR", "Unexpected error 102, state: " + this.myProgrammingState, false); |
| 1020 | arune | 438 | break; |
| 439 | } |
||
| 1008 | runge | 440 | } |
| 441 | } |
||
| 442 | |||
| 443 | CanNode.prototype.stopProgramming = function(status, text) |
||
| 444 | { |
||
| 445 | if (status && text) |
||
| 446 | { |
||
| 1034 | arune | 447 | this.myProgrammingCallback(status, "\nSTOP", text, false); |
| 1008 | runge | 448 | } |
| 1020 | arune | 449 | |
| 1008 | runge | 450 | this.myProgrammingIsBios = false; |
| 451 | this.myProgramming = false; |
||
| 452 | this.myProgrammingHex = new Array(); |
||
| 1013 | arune | 453 | this.myProgrammingHexAddress = 0; |
| 1020 | arune | 454 | this.myProgrammingHexOffset = 0; |
| 1008 | runge | 455 | this.myProgrammingCallback = function() {}; |
| 456 | this.myProgrammingWantAck = null; |
||
| 1020 | arune | 457 | this.myProgrammingState = ""; |
| 1034 | arune | 458 | this.myProgrammingLastPercent = 0; |
| 459 | this.myProgrammingLastTenPercent = 0; |
||
| 460 | this.myProgrammingnrOfTicks = 0; |
||
| 1037 | arune | 461 | this.myProgrammingTimeStarted = 0; |
| 1043 | arune | 462 | this.myProgrammingBiosOffset = 0; |
| 1034 | arune | 463 | |
| 464 | if (this.myProgrammingTimeout != null) |
||
| 465 | { |
||
| 466 | /* Stop the interval */ |
||
| 467 | this.myProgrammingTimeout.stop(); |
||
| 468 | } |
||
| 469 | if (this.myProgrammingResend != null) |
||
| 470 | { |
||
| 471 | /* Stop the interval */ |
||
| 472 | this.myProgrammingResend.stop(); |
||
| 473 | } |
||
| 474 | |||
| 1014 | runge | 475 | CanProgrammingNode = null; |
| 1008 | runge | 476 | } |
| 477 | |||
| 478 | |||
| 479 | |||
| 986 | runge | 480 | CanNode.prototype.addService = function(sequenceNumber, service) |
| 481 | { |
||
| 482 | this.myModules[sequenceNumber] = service; |
||
| 483 | service.setOnline(); |
||
| 484 | } |
||
| 485 | |||
| 486 | CanNode.prototype.onlineHandler = function() |
||
| 487 | { |
||
| 488 | var date = new Date(); |
||
| 489 | this.myHeartbeatTime = date.getTimestamp(); |
||
| 490 | |||
| 491 | if (!this.myIsOnline) |
||
| 492 | { |
||
| 493 | this.myIsOnline = true; |
||
| 494 | |||
| 495 | log(uint2hex(this.myHardwareId, 32) + "> Node went online\n"); |
||
| 496 | |||
| 497 | for (var n in this.myModules) |
||
| 498 | { |
||
| 499 | this.myModules[n].setOnline(); |
||
| 500 | } |
||
| 501 | } |
||
| 502 | } |
||
| 503 | |||
| 504 | CanNode.prototype.checkOffline = function() |
||
| 505 | { |
||
| 506 | if (this.myIsOnline) |
||
| 507 | { |
||
| 508 | var date = new Date(); |
||
| 1377 | arune | 509 | if (this.myHeartbeatTime + 21 < date.getTimestamp()) |
| 986 | runge | 510 | { |
| 1380 | linlun | 511 | log(uint2hex(this.myHardwareId, 32) + "> Offline time: "+(date.getTimestamp()-this.myHeartbeatTime)+"\n"); |
| 986 | runge | 512 | this.setOffline(); |
| 513 | } |
||
| 514 | } |
||
| 515 | } |
||
| 516 | |||
| 517 | CanNode.prototype.setOffline = function() |
||
| 518 | { |
||
| 519 | if (this.myIsOnline) |
||
| 520 | { |
||
| 521 | this.myIsOnline = false; |
||
| 522 | |||
| 523 | log(uint2hex(this.myHardwareId, 32) + "> Node went offline\n"); |
||
| 524 | |||
| 525 | for (var n in this.myModules) |
||
| 526 | { |
||
| 527 | this.myModules[n].setOffline(); |
||
| 528 | } |
||
| 529 | } |
||
| 530 | } |