Subversion Repositories HomeAutomation

Rev

Rev 467 | Rev 632 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

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