Subversion Repositories HomeAutomation

Rev

Rev 876 | Rev 878 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
453 arune 1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Threading;
5
 
6
//this class should probably be integrated into canNMT instead
7
 
8
public class Downloader {
9
    private HexFile hf;
10
    private DaemonConnection dc;
11
    private bool isBiosUpdate;
12
    private ulong dlOffset = 0;
13
    //private Thread down;
14
    private byte receiveID;
770 arune 15
    private uint hwid;
16
    private bool HWID_INUSE;
453 arune 17
 
586 arune 18
    private enum dState { SEND_START, WAIT_ACK_PRG, SEND_PGM_DATA, WAIT_ACK_DATA, RESEND_ADDR, WAIT_DONE, SEND_DONE, SEND_BIOS_UPDATE, SEND_RESET, DONE, DEBUG_STATE2, WAIT_BOOT, SEND_EMPTY_START, WAIT_ACK_PRG_EMPTY, SEND_EMPTY_DATA, WAIT_ACK_EMPTY_DATA, SEND_DONE_EMPTY, WAIT_DONE_EMPTY};
453 arune 19
 
20
    private const byte CAN_NMT              = 0x00;
21
 
22
    private const byte CAN_NMT_RESET        = 0x04;
23
    private const byte CAN_NMT_BIOS_START   = 0x08;
24
    private const byte CAN_NMT_PGM_START    = 0x0C;
25
    private const byte CAN_NMT_PGM_DATA     = 0x10;
26
    private const byte CAN_NMT_PGM_END      = 0x14;
27
    private const byte CAN_NMT_PGM_COPY     = 0x18;
28
    private const byte CAN_NMT_PGM_ACK      = 0x1C;
29
    private const byte CAN_NMT_PGM_NACK     = 0x20;
30
    private const byte CAN_NMT_START_APP    = 0x24;
31
    private const byte CAN_NMT_APP_START    = 0x28;
32
    private const byte CAN_NMT_HEARTBEAT    = 0x2C;
33
 
34
    private const byte MY_ID = 0x00;
35
    //private const byte TARGET_ID = 0x78;
36
    private const byte MY_NID = 0x0;
37
    private const byte ADDR0_INDEX = 0;
38
    private const byte ADDR1_INDEX = 1;
39
    private const byte ADDR2_INDEX = 2;
40
    private const byte ADDR3_INDEX = 3;
770 arune 41
 
42
    private const byte HWID0_INDEX = 4;
43
    private const byte HWID1_INDEX = 5;
44
    private const byte HWID2_INDEX = 6;
45
    private const byte HWID3_INDEX = 7;
453 arune 46
 
632 arune 47
    private const int TIMEOUT_MS = 1000;
48
    private const int TIMEOUT_SHORT_MS = 200;
453 arune 49
 
50
    private long timeStart = 0;
51
 
770 arune 52
    public Downloader(HexFile hf, DaemonConnection dc, byte receiveID, bool isBiosUpdate, bool HWID_INUSE, uint hwid) {
453 arune 53
        this.hf = hf;
54
        this.dc = dc;
55
        this.receiveID = receiveID;
56
        this.isBiosUpdate = isBiosUpdate;
770 arune 57
        this.hwid = hwid;
58
        this.HWID_INUSE = HWID_INUSE;
453 arune 59
    }
60
 
61
    public int calcCRC(HexFile hf) {
62
        int crc=0;
63
        for (ulong i=hf.getAddrLower(); i <= hf.getAddrUpper(); i++) {
64
            crc = crc16_update(crc, hf.getByte(i));
65
        }
66
        return crc;
67
    }
68
 
69
    public int crc16_update(int crc, byte a) {
70
        int i;
71
        crc ^= a;
72
        for (i = 0; i < 8; ++i) {
73
            if ((crc & 1) != 0)
74
                crc = (crc >> 1) ^ 0xA001;
75
            else
76
                crc = (crc >> 1);
77
        }
78
        return crc;
79
    }
80
 
81
    public bool go() {
82
        if (dc==null || hf==null || hf.getLength()==0) return false;
83
        return downloader();
84
    }
85
 
86
    public void abort() {
87
        //if (down != null && down.IsAlive) down.Abort();
88
    }
89
 
90
    public bool downloader() {
91
        dState pgs = dState.SEND_START;
92
        int t = 0;
632 arune 93
        int t2 = 0;
453 arune 94
        CanPacket outCm = null;
95
        CanPacket cm = null;
96
        byte[] data = new byte[8];
97
        uint byteSent = 0;
98
        ulong currentAddress = 0;
99
        bool done = false;
100
        bool errorOccured = false;
101
 
876 arune 102
        //int rotstate=0;
103
        int dldisplaystate=0;
104
 
453 arune 105
        try {
106
            if (isBiosUpdate) {
107
                dlOffset = hf.getAddrLower();
108
                //Console.WriteLine(dlOffset);
109
                //dlOffset = 200;
110
            }
111
 
770 arune 112
            CanNMT cpn = new CanNMT(HWID_INUSE);
453 arune 113
            cpn.setReceiver(receiveID);
114
            bool hasMessage = false;
115
 
116
            while (!done) {
117
                Thread.Sleep(1);
118
 
119
                switch (pgs) {
120
                    case dState.SEND_START:
121
                        // Send boot start packet to target.
122
                        // and wait for ack.
123
                        currentAddress = hf.getAddrLower();
124
                        //data[RID_INDEX] = TARGET_ID;
125
                        data[ADDR0_INDEX] = (byte)((currentAddress-dlOffset) & 0x0000FF);
126
                        data[ADDR1_INDEX] = (byte)(((currentAddress-dlOffset) & 0x00FF00) >> 8);
127
                        data[ADDR2_INDEX] = (byte)(((currentAddress-dlOffset) & 0xFF0000) >> 16);
128
                        data[ADDR3_INDEX] = 0;
770 arune 129
                        if (HWID_INUSE) {
130
                            data[HWID0_INDEX] = (byte)((hwid) & 0xFF);
131
                            data[HWID1_INDEX] = (byte)((hwid>>8) & 0xFF);
132
                            data[HWID2_INDEX] = (byte)((hwid>>16) & 0xFF);
133
                            data[HWID3_INDEX] = (byte)((hwid>>24) & 0xFF);
134
                        }
453 arune 135
                        //outCm = new CanPacket(CAN_NMT, CAN_NMT_PGM_START, MY_ID, receiveID, 4, data);
136
                        outCm = cpn.getPgmStartPacket(data);
137
                        dc.sendCanPacket(outCm);
138
                        t = Environment.TickCount;
632 arune 139
                        t2 = Environment.TickCount;
453 arune 140
                        pgs = dState.WAIT_ACK_PRG;
141
                        timeStart = Environment.TickCount;
876 arune 142
                        Console.WriteLine("Downloading...");
877 arune 143
                        Console.Write("  0%");
453 arune 144
                        break;
145
 
146
 
147
                    case dState.WAIT_ACK_PRG:
148
                        // Check for timeout, resend start packet in that case..
149
                        if ((Environment.TickCount - t) > TIMEOUT_MS) {
150
                            Console.WriteLine("Timeout while waiting for start prg ack.");
151
                            errorOccured = true;
152
                            pgs = dState.SEND_RESET;
153
                        }
467 arune 154
                        //Thread.Sleep(1);
453 arune 155
                        // If received ack.
156
                        hasMessage = dc.getData(out cm);
157
                        if (hasMessage) {
770 arune 158
                            CanNMT cpnin = new CanNMT(cm, HWID_INUSE);
159
                            if (cpnin.isNMTPacket()) {
160
                            //if (cpnin.isNMTPacket() && (cpnin.getSender() == receiveID)) {
453 arune 161
                                // If no error
162
                                if (cpnin.getType() == CAN_NMT_PGM_ACK) {
163
                                    // Start sending program data..
164
                                    byteSent = 0;
165
                                    pgs = dState.SEND_PGM_DATA;
166
                                }
167
                                else if (cpnin.getType() == CAN_NMT_PGM_NACK ) {
168
                                    // else ..
169
                                    Console.WriteLine("Nack on CAN_NMT_PGM_START.");
170
                                    errorOccured = true;
171
                                    pgs = dState.SEND_RESET;
172
                                }
173
                            }
174
                        }
175
                        break;
176
 
177
                    case dState.SEND_PGM_DATA:
178
                        //Console.WriteLine("byteSent = "+byteSent);
876 arune 179
//disable                       Console.Write(".");
180
//Console.Write("\b");
181
//int curleft = Console.CursorLeft;
182
//int curtop = Console.CursorTop;
183
//Console.SetCursorPosition(curleft, curtop-1);
184
 
185
//if (rotstate==0) {
186
//   Console.Write("-");
187
//   rotstate=1;
188
//} else if (rotstate==1) {
189
//   Console.Write("\\");
190
//   rotstate=2;
191
//} else if (rotstate==2) {
192
//   Console.Write("|");
193
//   rotstate=3;
194
//} else if (rotstate==3) {
195
//   Console.Write("/");
196
//   rotstate=0;
197
//}
198
//Console.Write("\r");
199
//dldisplaystate
200
 
201
//FULHACK deulx
202
                        ulong percent = byteSent*100/(hf.getAddrUpper()-currentAddress);
203
 
204
                        if (percent>9 && dldisplaystate==0) {
205
                           Console.Write("\r");
877 arune 206
                           Console.Write(" "+percent+"%");
876 arune 207
                           dldisplaystate=1;
208
                        } else if (percent>19 && dldisplaystate==1) {
209
                           Console.Write("\r");
877 arune 210
                           Console.Write(" "+percent+"%");
876 arune 211
                           dldisplaystate=2;
212
                        } else if (percent>29 && dldisplaystate==2) {
213
                           Console.Write("\r");
877 arune 214
                           Console.Write(" "+percent+"%");
876 arune 215
                           dldisplaystate=3;
216
                        } else if (percent>39 && dldisplaystate==3) {
217
                           Console.Write("\r");
877 arune 218
                           Console.Write(" "+percent+"%");
876 arune 219
                           dldisplaystate=4;
220
                        } else if (percent>49 && dldisplaystate==4) {
221
                           Console.Write("\r");
877 arune 222
                           Console.Write(" "+percent+"%");
876 arune 223
                           dldisplaystate=5;
224
                        } else if (percent>59 && dldisplaystate==5) {
225
                           Console.Write("\r");
877 arune 226
                           Console.Write(" "+percent+"%");
876 arune 227
                           dldisplaystate=6;
228
                        } else if (percent>69 && dldisplaystate==6) {
229
                           Console.Write("\r");
877 arune 230
                           Console.Write(" "+percent+"%");
876 arune 231
                           dldisplaystate=7;
232
                        } else if (percent>79 && dldisplaystate==7) {
233
                           Console.Write("\r");
877 arune 234
                           Console.Write(" "+percent+"%");
876 arune 235
                           dldisplaystate=8;
236
                        } else if (percent>89 && dldisplaystate==8) {
237
                           Console.Write("\r");
877 arune 238
                           Console.Write(" "+percent+"%");
876 arune 239
                           dldisplaystate=9;
240
                        } else if (percent>99 && dldisplaystate==9) {
241
                           Console.Write("\r");
877 arune 242
                           Console.Write(" "+percent+"%");
876 arune 243
                           dldisplaystate=10;
244
                        }
877 arune 245
                        Console.Write(".");
876 arune 246
 
453 arune 247
                        // Send program data.
248
                        byte datalength = 2;
249
                        for (ulong i = 0; i < 6; i++) {
250
                            // Populate data.
251
                            data[i+2] = hf.getByte(currentAddress + i + byteSent);
252
                            if (currentAddress + i + byteSent > hf.getAddrUpper()) {
253
                                break;  //then done
254
                            }
255
                            datalength++;
256
                        }
257
                        data[0] = (byte)(byteSent & 0x00FF);
258
                        data[1] = (byte)((byteSent & 0xFF00) >> 8);
259
 
260
                        outCm = cpn.getPgmDataPacket(data, datalength);
261
                        dc.sendCanPacket(outCm);
262
 
263
                        t = Environment.TickCount;
632 arune 264
                        t2 = Environment.TickCount;
453 arune 265
                        byteSent += 6;
266
                        pgs = dState.WAIT_ACK_DATA;
267
                        break;
268
 
269
 
270
                    case dState.WAIT_ACK_DATA:
271
                        // Wait for pgm ack.
632 arune 272
                        if ((Environment.TickCount - t) > TIMEOUT_MS) {
453 arune 273
                            // Woops, error. 
274
                            Console.WriteLine("Timeout while waiting for data ack.");
275
                            errorOccured = true;
276
                            pgs = dState.SEND_RESET;
277
                        }
634 arune 278
                        else if ((Environment.TickCount - t2) > TIMEOUT_SHORT_MS) {
632 arune 279
                            // Woops, error. 
876 arune 280
//disable                           Console.Write(":");
632 arune 281
                            byteSent -= 6;
282
                            pgs = dState.SEND_PGM_DATA;
283
                            break;
284
                        }
467 arune 285
                        //Thread.Sleep(1);
453 arune 286
                        // If received ack.
287
                        hasMessage = dc.getData(out cm);
288
                        if (hasMessage) {
770 arune 289
                            CanNMT cpnin = new CanNMT(cm, HWID_INUSE);
290
                            if (cpnin.isNMTPacket()) {
291
                            //if (cpnin.isNMTPacket() && (cpnin.getSender() == receiveID)) {
453 arune 292
                                // If no error
293
                                if (cpnin.getType() == CAN_NMT_PGM_ACK) {
294
                                    //currentAddress += 2;
295
                                    // Check if end.
296
                                    if (currentAddress + byteSent > hf.getAddrUpper()) {
297
                                        // Yes, we are done, send done.
298
                                        pgs = dState.SEND_DONE;
299
                                    }
300
                                    else {
301
                                        // More to write.
302
                                        //byteSent = 0;
303
                                        pgs = dState.SEND_PGM_DATA;
304
                                    }
305
                                }
306
                                else if (cpnin.getType() == CAN_NMT_PGM_NACK ) {
307
                                    // else ..
308
                                    Console.WriteLine("Nack on CAN_NMT_PGM_DATA.");
309
                                    errorOccured = true;
310
                                    pgs = dState.SEND_RESET;
311
                                }
312
                            }
313
                        }
314
                        break;
315
 
316
                    case dState.SEND_DONE:
876 arune 317
                       Console.Write("\r");
318
                       Console.Write("100%");
453 arune 319
                        // Send done
320
                        outCm = cpn.getPgmEndPacket();
321
                        dc.sendCanPacket(outCm);
322
 
323
                        t = Environment.TickCount;
632 arune 324
                        t2 = Environment.TickCount;
453 arune 325
                        pgs = dState.WAIT_DONE;
326
                        break;
327
 
328
 
329
                    case dState.WAIT_DONE:
330
                        // Check for timeout, resend done packet in that case..
331
                        if ((Environment.TickCount - t) > TIMEOUT_MS) {
332
                            Console.WriteLine("Timeout while waiting for end prg ack.");
333
                            errorOccured = true;
334
                            pgs = dState.SEND_RESET;
335
                        }
467 arune 336
                        //Thread.Sleep(1);
453 arune 337
 
338
                        hasMessage = dc.getData(out cm);
339
                        if (hasMessage) {
770 arune 340
                            CanNMT cpnin = new CanNMT(cm, HWID_INUSE);
341
                            if (cpnin.isNMTPacket()) {
342
                            //if (cpnin.isNMTPacket() && (cpnin.getSender() == receiveID)) {
453 arune 343
                                // If no error
344
                                if (cpnin.getType() == CAN_NMT_PGM_ACK) {
345
                                    Console.WriteLine("");
346
                                    //
347
                                    int crc = calcCRC(hf);
348
 
349
                                    if (cm.getDataLength() == 2) {
350
                                        byte[] cmdata = cm.getData();
351
                                        if ((cmdata[0] == (crc & 0xFF)) && (cmdata[1] == (crc>>8))) {
352
                                            if (!isBiosUpdate) {
353
                                                Console.WriteLine("Done, successfully programmed application.");
354
                                                pgs = dState.SEND_RESET;
355
                                            } else {
356
                                                Console.WriteLine("Done, successfully programmed bios to application space.");
357
                                                pgs = dState.SEND_BIOS_UPDATE;
358
                                            }
359
                                        } else {
360
                                            string nodecrc = String.Format("{0:x4}", (int)cmdata[0] + (int)(cmdata[1]<<8));
361
                                            nodecrc = "0x"+nodecrc;
362
                                            string realcrc = String.Format("{0:x4}", (int)(crc & 0xFF) + (int)(crc & 0xFF00));
363
                                            realcrc = "0x"+realcrc;
364
                                            Console.WriteLine("CRC failed. Node sent CRC "+nodecrc+" but should be "+realcrc+".");
365
                                            errorOccured = true;
366
                                            pgs = dState.SEND_RESET;
367
                                        }
368
 
369
                                        byteSent = 0;
370
                                    }
371
                                    //Console.WriteLine("crc: " + crc + " " + (crc>>8) + " " + (crc & 0xFF));
372
                                    //Console.WriteLine("ACKpkg with CRC: " + cm.ToString());
373
                                    // 
374
                                }
375
                                else if (cpnin.getType() == CAN_NMT_PGM_NACK) {
376
                                    // else resend addr..
377
                                    Console.WriteLine("Nack on CAN_NMT_PGM_END.");
378
                                    errorOccured = true;
379
                                    pgs = dState.SEND_RESET;
380
                                }
381
                            }
382
                        }
383
                        break;
384
 
385
                    case dState.SEND_BIOS_UPDATE:
386
                        data[0] = (byte)(0 & 0x00FF);
387
                        data[1] = (byte)((0 & 0xFF00) >> 8);
388
                        data[2] = (byte)(dlOffset & 0x00FF);
389
                        data[3] = (byte)((dlOffset & 0xFF00) >> 8);
390
                        data[4] = (byte)((hf.getAddrUpper()-hf.getAddrLower()+1) & 0x00FF);
391
                        data[5] = (byte)(((hf.getAddrUpper()-hf.getAddrLower()+1) & 0xFF00) >> 8);
392
 
393
                        outCm = cpn.getPgmCopyPacket(data);
394
                        Console.WriteLine("Now say a prayer, moving bios");
395
                        dc.sendCanPacket(outCm);
396
                        t = Environment.TickCount;
632 arune 397
                        t2 = Environment.TickCount;
586 arune 398
                        pgs = dState.WAIT_BOOT;
399
                        //pgs = dState.DONE;
453 arune 400
                        break;
586 arune 401
 
402
                    case dState.WAIT_BOOT:
403
                        // Wait for node reset answer (boot msg).
637 arune 404
                        if ((Environment.TickCount - t) > 3*TIMEOUT_MS) {
586 arune 405
                            // Woops, error. 
406
                            Console.WriteLine("Timeout while waiting for node to boot.");
407
                            errorOccured = true;
408
                            pgs = dState.SEND_DONE;
409
                        }
410
                        //Thread.Sleep(1);
411
                        // If received boot msg.
412
                        hasMessage = dc.getData(out cm);
413
                        if (hasMessage) {
770 arune 414
                            CanNMT cpnin = new CanNMT(cm, HWID_INUSE);
415
                            if (cpnin.isNMTPacket()) {
416
                            //if (cpnin.isNMTPacket() && (cpnin.getSender() == receiveID)) {
586 arune 417
                                // If no error
418
                                if (cpnin.getType() == CAN_NMT_BIOS_START) {
419
                                    pgs = dState.SEND_EMPTY_START;
420
                                }
421
                                else {
422
                                    // else ..
423
                                }
424
                            }
425
                        }
426
                        break;
453 arune 427
 
586 arune 428
                    case dState.SEND_EMPTY_START:
429
                        // Send boot start packet to target.
430
                        // and wait for ack.
431
 
432
                        //data[RID_INDEX] = TARGET_ID;
433
                        data[ADDR0_INDEX] = (byte)((0) & 0x0000FF);
434
                        data[ADDR1_INDEX] = (byte)(((0) & 0x00FF00) >> 8);
435
                        data[ADDR2_INDEX] = (byte)(((0) & 0xFF0000) >> 16);
436
                        data[ADDR3_INDEX] = 0;
770 arune 437
                        if (HWID_INUSE) {
438
                            data[HWID0_INDEX] = (byte)((hwid) & 0xFF);
439
                            data[HWID1_INDEX] = (byte)((hwid>>8) & 0xFF);
440
                            data[HWID2_INDEX] = (byte)((hwid>>16) & 0xFF);
441
                            data[HWID3_INDEX] = (byte)((hwid>>24) & 0xFF);
442
                        }
586 arune 443
                        //outCm = new CanPacket(CAN_NMT, CAN_NMT_PGM_START, MY_ID, receiveID, 4, data);
444
                        outCm = cpn.getPgmStartPacket(data);
445
                        dc.sendCanPacket(outCm);
446
                        t = Environment.TickCount;
632 arune 447
                        t2 = Environment.TickCount;
586 arune 448
                        pgs = dState.WAIT_ACK_PRG_EMPTY;
449
                        break;
450
 
451
 
452
                    case dState.WAIT_ACK_PRG_EMPTY:
453
                        // Check for timeout, resend start packet in that case..
637 arune 454
                        if ((Environment.TickCount - t) > 3*TIMEOUT_MS) {
770 arune 455
                            Console.WriteLine("Timeout while waiting for start prg ack during empty-first-block-cycle.");
586 arune 456
                            errorOccured = true;
457
                            pgs = dState.SEND_RESET;
458
                        }
459
                        //Thread.Sleep(1);
460
                        // If received ack.
461
                        hasMessage = dc.getData(out cm);
462
                        if (hasMessage) {
770 arune 463
                            CanNMT cpnin = new CanNMT(cm, HWID_INUSE);
464
                            if (cpnin.isNMTPacket()) {
465
                            //if (cpnin.isNMTPacket() && (cpnin.getSender() == receiveID)) {
586 arune 466
                                // If no error
467
                                if (cpnin.getType() == CAN_NMT_PGM_ACK) {
468
                                    // Start sending program data..
469
                                    byteSent = 0;
470
                                    pgs = dState.SEND_EMPTY_DATA;
471
                                }
472
                                else if (cpnin.getType() == CAN_NMT_PGM_NACK ) {
473
                                    // else ..
474
                                    Console.WriteLine("Nack on CAN_NMT_PGM_START.");
475
                                    errorOccured = true;
476
                                    pgs = dState.SEND_RESET;
477
                                }
478
                            }
479
                        }
480
                        break;
481
 
482
                    case dState.SEND_EMPTY_DATA:
483
                        // Send program data.
484
                        data[0] = 0;
485
                        data[1] = 0;
486
                        data[2] = 0xff;
487
                        data[3] = 0xff;
488
 
489
                        outCm = cpn.getPgmDataPacket(data, 4);
490
                        dc.sendCanPacket(outCm);
491
 
492
                        t = Environment.TickCount;
632 arune 493
                        t2 = Environment.TickCount;
586 arune 494
                        byteSent += 6;
495
                        pgs = dState.WAIT_ACK_EMPTY_DATA;
496
                        break;
497
 
498
 
499
                    case dState.WAIT_ACK_EMPTY_DATA:
500
                        // Wait for pgm ack.
501
                        if ((Environment.TickCount - t) > 2*TIMEOUT_MS) {
502
                            // Woops, error. 
503
                            Console.WriteLine("Timeout while waiting for data ack.");
504
                            errorOccured = true;
505
                            pgs = dState.SEND_RESET;
506
                        }
507
                        //Thread.Sleep(1);
508
                        // If received ack.
509
                        hasMessage = dc.getData(out cm);
510
                        if (hasMessage) {
770 arune 511
                            CanNMT cpnin = new CanNMT(cm, HWID_INUSE);
512
                            if (cpnin.isNMTPacket()) {
513
                            //if (cpnin.isNMTPacket() && (cpnin.getSender() == receiveID)) {
586 arune 514
                                // If no error
515
                                if (cpnin.getType() == CAN_NMT_PGM_ACK) {
516
                                    pgs = dState.SEND_DONE_EMPTY;
517
                                }
518
                                else if (cpnin.getType() == CAN_NMT_PGM_NACK ) {
519
                                    // else ..
520
                                    Console.WriteLine("Nack on CAN_NMT_PGM_DATA.");
521
                                    errorOccured = true;
522
                                    pgs = dState.SEND_RESET;
523
                                }
524
                            }
525
                        }
526
                        break;
527
 
528
                    case dState.SEND_DONE_EMPTY:
529
                        // Send done
530
                        outCm = cpn.getPgmEndPacket();
531
                        dc.sendCanPacket(outCm);
532
 
533
                        t = Environment.TickCount;
632 arune 534
                        t2 = Environment.TickCount;
586 arune 535
                        pgs = dState.WAIT_DONE_EMPTY;
536
                        break;
537
 
538
 
539
                    case dState.WAIT_DONE_EMPTY:
540
                        // Check for timeout, resend done packet in that case..
541
                        if ((Environment.TickCount - t) > TIMEOUT_MS) {
542
                            Console.WriteLine("Timeout while waiting for end prg ack.");
543
                            errorOccured = true;
544
                            pgs = dState.SEND_RESET;
545
                        }
546
                        //Thread.Sleep(1);
547
 
548
                        hasMessage = dc.getData(out cm);
549
                        if (hasMessage) {
770 arune 550
                            CanNMT cpnin = new CanNMT(cm, HWID_INUSE);
551
                            if (cpnin.isNMTPacket()) {
552
                            //if (cpnin.isNMTPacket() && (cpnin.getSender() == receiveID)) {
586 arune 553
                                // If no error
554
                                if (cpnin.getType() == CAN_NMT_PGM_ACK) {
555
                                    Console.WriteLine("");
556
                                    //
557
                                    Console.WriteLine("Done, successfully cleaned application flash.");
558
                                    pgs = dState.SEND_RESET;
559
                                }
560
                                else if (cpnin.getType() == CAN_NMT_PGM_NACK) {
561
                                    // else resend addr..
562
                                    Console.WriteLine("Nack on CAN_NMT_PGM_END.");
563
                                    errorOccured = true;
564
                                    pgs = dState.SEND_RESET;
565
                                }
566
                            }
567
                        }
568
                        break;                     
453 arune 569
                    case dState.SEND_RESET:
570
                        // Send reset
770 arune 571
                        cpn.doReset(dc, receiveID, hwid);
453 arune 572
                        t = Environment.TickCount;
632 arune 573
                        t2 = Environment.TickCount;
453 arune 574
                        pgs = dState.DONE;
575
                        break;
576
 
577
 
578
                    case dState.DONE:
579
                        done = true;
580
                        //down.Abort();
581
                        if (!errorOccured) {
582
                            long tsecs = ((Environment.TickCount - timeStart) / 1000);
583
                            double bitRate = hf.getLength() / ((double)(Environment.TickCount - timeStart) / 1000.0);
584
 
585
                            if (tsecs <= 0) tsecs = 1;
586
                            long mins = tsecs / 60;
587
                            long secs = tsecs % 60;
588
                            string pad = "";
589
                            if (secs < 10) {
590
                                pad = "0";
591
                            }
592
                            Console.WriteLine("Time spent: " + mins + ":" + pad + secs + ", " + Math.Round(bitRate, 2) + " bytes/s");
593
                        }
594
                        //Console.Write("> ");
595
                        break;
596
                }
597
            }
598
 
599
        } catch(Exception) {
600
            Console.WriteLine("Exception occured");
601
            //Console.WriteLine(e);
602
            //skriva ut antal bytes skrivna vore bra här, kanske nån annan form av hjälp för debug, något gick snett liksom
603
 
604
        }
605
 
606
        return !errorOccured;
607
    }
608
}