Subversion Repositories HomeAutomation

Rev

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

  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.  
  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.    
  25.     private bool HWID_INUSE=false;
  26.  
  27.     CanPacket cp;
  28.     private bool running = false;
  29.    
  30.     public CanNMT(bool HWID_INUSE) {
  31.         cp = new CanPacket();
  32.         cp.setExt(1);
  33.         this.HWID_INUSE = HWID_INUSE;
  34.     }
  35.  
  36.     public CanNMT(CanPacket cp, bool HWID_INUSE) {
  37.         this.cp = cp;
  38.         this.cp.setExt(1);
  39.         this.HWID_INUSE = HWID_INUSE;
  40.     }
  41.    
  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.    
  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 ) );
  70.         if (HWID_INUSE) {
  71.            cp.setDataLength(4);
  72.         } else {
  73.            cp.setDataLength(0);
  74.         }
  75.         return cp;
  76.     }
  77.  
  78.     public CanPacket getStartPacket() {
  79.         cp.setId( ( cp.getId()&0x0000FFFF )|( CAN_NMT_START_APP<<16 ) );
  80.         if (HWID_INUSE) {
  81.            cp.setDataLength(4);
  82.         } else {
  83.            cp.setDataLength(0);
  84.         }
  85.         return cp;
  86.     }
  87.  
  88.     public CanPacket getPgmStartPacket(byte[] data) {
  89.         cp.setId( ( cp.getId()&0x0000FFFF )|( CAN_NMT_PGM_START<<16 ) );
  90.         cp.setData(data);
  91.         if (HWID_INUSE) {
  92.            cp.setDataLength(8);
  93.         } else {
  94.            cp.setDataLength(4);
  95.         }
  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.     }
  118.        
  119.     public bool isBiosStart(CanPacket cp, byte sender, uint hwid) {
  120.         bool returnval = false;
  121.         uint id = cp.getId();
  122.         if (HWID_INUSE) {
  123.             byte[] data = cp.getData();
  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;
  126.                 string appinfo = "application installed";
  127.                 if (data[2] == 0) {
  128.                     appinfo = "no application installed";
  129.                 }
  130.                 if (data[3]==0) {
  131.                    appinfo += ", device type unkown";
  132.                 }
  133.                 if (data[3]!=0) {
  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.                     }
  154.                 }
  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.                                     );
  159.             }
  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.             }
  173.         }
  174.         return returnval;
  175.     }
  176.  
  177.     public bool doStart(DaemonConnection dc, byte receiver, uint hwid) {
  178.         return doStart(dc, receiver, 0, hwid);
  179.     }
  180.    
  181.     public bool doStart(DaemonConnection dc, byte receiver, byte sender, uint hwid) {
  182.         bool success = true;
  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.           }    
  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.     }
  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) {
  204.         bool success = false;
  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.       }      
  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)) {
  222.                 if (isBiosStart(getcp, receiver, hwid)) {
  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. }
  243.