Subversion Repositories HomeAutomation

Rev

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