Subversion Repositories HomeAutomation

Rev

Rev 1636 | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
450 arune 1
using System.Threading;
2
using System;
3
 
4
public class CanNMT {
5
    private const byte CAN_NMT              = 0x00;
6
 
7
    private const byte CAN_NMT_RESET        = 0x04;
8
    private const byte CAN_NMT_BIOS_START   = 0x08;
9
    private const byte CAN_NMT_PGM_START    = 0x0C;
10
    private const byte CAN_NMT_PGM_DATA     = 0x10;
11
    private const byte CAN_NMT_PGM_END      = 0x14;
12
    private const byte CAN_NMT_PGM_COPY     = 0x18;
13
    private const byte CAN_NMT_PGM_ACK      = 0x1C;
14
    private const byte CAN_NMT_PGM_NACK     = 0x20;
15
    private const byte CAN_NMT_START_APP    = 0x24;
16
    private const byte CAN_NMT_APP_START    = 0x28;
17
    private const byte CAN_NMT_HEARTBEAT    = 0x2C;
18
 
1635 linlun 19
    private const byte DEVICETYPE_AVR_ATmega8   = 1;
20
    private const byte DEVICETYPE_AVR_ATmega48  = 2;
21
    private const byte DEVICETYPE_AVR_ATmega88  = 3;
22
    private const byte DEVICETYPE_AVR_ATmega168 = 4;
23
    private const byte DEVICETYPE_AVR_ATmega328 = 5;
24
 
770 arune 25
    private bool HWID_INUSE=false;
26
 
450 arune 27
    CanPacket cp;
28
    private bool running = false;
29
 
770 arune 30
    public CanNMT(bool HWID_INUSE) {
450 arune 31
        cp = new CanPacket();
32
        cp.setExt(1);
770 arune 33
        this.HWID_INUSE = HWID_INUSE;
450 arune 34
    }
453 arune 35
 
770 arune 36
    public CanNMT(CanPacket cp, bool HWID_INUSE) {
453 arune 37
        this.cp = cp;
38
        this.cp.setExt(1);
770 arune 39
        this.HWID_INUSE = HWID_INUSE;
453 arune 40
    }
450 arune 41
 
453 arune 42
    public byte getSender() {
43
        return (byte)((cp.getId()>>8)&0xFF);
44
    }
45
 
46
    public bool isNMTPacket() {
47
        if (((cp.getId()>>24)&0xFF) == 0) {
48
            return true;
49
        }
50
        return false;
51
    }
52
 
53
    public byte getType() {
54
        return (byte)((cp.getId()>>16)&0xFF);
55
    }
56
 
57
    public byte getReceiver() {
58
        return (byte)((cp.getId()>>0)&0xFF);
59
    }
60
 
450 arune 61
    public void setSender(byte id) {
62
        cp.setId( ( ( cp.getId()&0x00FF00FF )|((uint)id<<8) ) );
63
    }
64
    public void setReceiver(byte id) {
65
        cp.setId( ( ( cp.getId()&0x00FFFF00 )|((uint)id) ) );
66
    }
67
 
68
    public CanPacket getResetPacket() {
69
        cp.setId( ( cp.getId()&0x0000FFFF )|( CAN_NMT_RESET<<16 ) );
770 arune 70
        if (HWID_INUSE) {
71
           cp.setDataLength(4);
72
        } else {
73
           cp.setDataLength(0);
74
        }
450 arune 75
        return cp;
76
    }
77
 
78
    public CanPacket getStartPacket() {
79
        cp.setId( ( cp.getId()&0x0000FFFF )|( CAN_NMT_START_APP<<16 ) );
770 arune 80
        if (HWID_INUSE) {
81
           cp.setDataLength(4);
82
        } else {
83
           cp.setDataLength(0);
84
        }
450 arune 85
        return cp;
86
    }
453 arune 87
 
88
    public CanPacket getPgmStartPacket(byte[] data) {
89
        cp.setId( ( cp.getId()&0x0000FFFF )|( CAN_NMT_PGM_START<<16 ) );
90
        cp.setData(data);
770 arune 91
        if (HWID_INUSE) {
92
           cp.setDataLength(8);
93
        } else {
94
           cp.setDataLength(4);
95
        }
453 arune 96
        return cp;
97
    }
98
 
99
    public CanPacket getPgmDataPacket(byte[] data, byte datalen) {
100
        cp.setId( ( cp.getId()&0x0000FFFF )|( CAN_NMT_PGM_DATA<<16 ) );
101
        cp.setData(data);
102
        cp.setDataLength(datalen);
103
        return cp;
104
    }
105
 
106
    public CanPacket getPgmEndPacket() {
107
        cp.setId( ( cp.getId()&0x0000FFFF )|( CAN_NMT_PGM_END<<16 ) );
108
        cp.setDataLength(0);
109
        return cp;
110
    }
111
 
112
    public CanPacket getPgmCopyPacket(byte[] data) {
113
        cp.setId( ( cp.getId()&0x0000FFFF )|( CAN_NMT_PGM_COPY<<16 ) );
114
        cp.setData(data);
115
        cp.setDataLength(6);
116
        return cp;
117
    }
1636 linlun 118
 
770 arune 119
    public bool isBiosStart(CanPacket cp, byte sender, uint hwid) {
450 arune 120
        bool returnval = false;
121
        uint id = cp.getId();
770 arune 122
        if (HWID_INUSE) {
450 arune 123
            byte[] data = cp.getData();
770 arune 124
            if ((id&0x00FF0000) == (CAN_NMT_BIOS_START<<16) && data[4]==((hwid)&0xff) && data[5]==((hwid>>8)&0xff) && data[6]==((hwid>>16)&0xff) && data[7]==((hwid>>24)&0xff)) {
125
                returnval = true;
1634 arune 126
                string appinfo = "application installed";
770 arune 127
                if (data[2] == 0) {
1634 arune 128
                    appinfo = "no application installed";
770 arune 129
                }
1634 arune 130
                if (data[3]==0) {
131
                   appinfo += ", device type unkown";
770 arune 132
                }
1634 arune 133
                if (data[3]!=0) {
1635 linlun 134
                    switch(data[3]){
135
                        case DEVICETYPE_AVR_ATmega8:
136
                            appinfo += ", device type ATmega8";
137
                            break;
138
                        case DEVICETYPE_AVR_ATmega48:
139
                            appinfo += ", device type ATmega48";
140
                            break;
141
                        case DEVICETYPE_AVR_ATmega88:
142
                            appinfo += ", device type ATmega88";
143
                            break;
144
                        case DEVICETYPE_AVR_ATmega168:
145
                            appinfo += ", device type ATmega168";
146
                            break;
147
                        case DEVICETYPE_AVR_ATmega328:
148
                            appinfo += ", device type ATmega328";
149
                            break;
150
                        default:
151
                            appinfo += ", device type unknown";
152
                            break;          
153
                    }
1634 arune 154
                }
770 arune 155
                Console.WriteLine("Bios started on node 0x" + String.Format("{0:x2}", sender) +
156
                                    ", bios version 0x" + String.Format("{0:x2}", data[1]) + String.Format("{0:x2}", data[0]) +
157
                                    ", " + appinfo
158
                                    );
450 arune 159
            }
770 arune 160
        } else {
161
            if ((id&0x00FF0000) == (CAN_NMT_BIOS_START<<16) && (id&0x0000FF00) == (sender<<8)) {
162
                returnval = true;
163
                byte[] data = cp.getData();
164
                string appinfo = "Application installed";
165
                if (data[2] == 0) {
166
                    appinfo = "No application installed";
167
                }
168
                Console.WriteLine("Bios started on node 0x" + String.Format("{0:x2}", sender) +
169
                                    ", bios version 0x" + String.Format("{0:x2}", data[1]) + String.Format("{0:x2}", data[0]) +
170
                                    ", " + appinfo
171
                                    );
172
            }
450 arune 173
        }
174
        return returnval;
175
    }
176
 
770 arune 177
    public bool doStart(DaemonConnection dc, byte receiver, uint hwid) {
178
        return doStart(dc, receiver, 0, hwid);
450 arune 179
    }
180
 
770 arune 181
    public bool doStart(DaemonConnection dc, byte receiver, byte sender, uint hwid) {
450 arune 182
        bool success = true;
770 arune 183
 
184
          if (HWID_INUSE) {
185
           byte[] data = new byte[8];
186
           data[0] = (byte)(hwid&0xff); data[1] = (byte)((hwid>>8)&0xff); data[2] = (byte)((hwid>>16)&0xff); data[3] = (byte)((hwid>>24)&0xff);  
187
           cp.setData(data);
188
           cp.setDataLength(4);
189
          }    
450 arune 190
        setReceiver(receiver);
191
        dc.sendCanPacket(getStartPacket());
192
        return success;
193
    }
194
 
195
    public bool doReset(DaemonConnection dc, byte receiver) {
196
        return doReset(dc, receiver, 0);
197
    }
770 arune 198
 
199
    public bool doReset(DaemonConnection dc, byte receiver, uint hwid) {
200
        return doReset(dc, receiver, 0, hwid);
201
    }
202
 
203
    public bool doReset(DaemonConnection dc, byte receiver, byte sender, uint hwid) {
450 arune 204
        bool success = false;
770 arune 205
 
206
      if (HWID_INUSE) {
207
       byte[] data = new byte[8];
208
       data[0] = (byte)(hwid&0xff); data[1] = (byte)((hwid>>8)&0xff); data[2] = (byte)((hwid>>16)&0xff); data[3] = (byte)((hwid>>24)&0xff);  
209
       cp.setData(data);
210
       cp.setDataLength(4);
211
      } else {
212
        setReceiver(receiver);
213
      }      
450 arune 214
 
215
        dc.sendCanPacket(getResetPacket());
216
        CanPacket getcp;
217
        running = true;
218
        dc.flushData();
219
        for (int i = 0; i < 150; i++) {
220
            Thread.Sleep(50);
221
            if (dc.getData(out getcp)) {
770 arune 222
                if (isBiosStart(getcp, receiver, hwid)) {
450 arune 223
                    success = true;
224
                    break;
225
                }
226
            }
227
 
228
            if (!running) {
229
                break;
230
            }
231
        }
232
        if (!success) {
233
            Console.WriteLine("Timed out while waiting for node to reset");
234
        }
235
        return success;
236
    }
237
 
238
    public void stop() {
239
        running = false;
240
    }
241
 
242
}