From: Bob J. <jac...@us...> - 2005-01-24 05:26:42
|
Update of /cvsroot/jmri/jmri/jmrix/sprog In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4191 Modified Files: SprogReply.java SprogMessage.java Log Message: add bootloader support Index: SprogReply.java =================================================================== RCS file: /cvsroot/jmri/jmri/jmrix/sprog/SprogReply.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** SprogReply.java 27 Jan 2003 05:24:00 -0000 1.1 --- SprogReply.java 24 Jan 2005 05:26:33 -0000 1.2 *************** *** 15,18 **** --- 15,19 ---- // create a new one public SprogReply() { + _isBoot = false; } *************** *** 22,25 **** --- 23,27 ---- log.error("copy ctor of null message"); _nDataChars = m._nDataChars; + _isBoot = m._isBoot; for (int i = 0; i<_nDataChars; i++) _dataChars[i] = m._dataChars[i]; } *************** *** 32,35 **** --- 34,45 ---- } + // from String + public SprogReply(String s, boolean b) { + _nDataChars = s.length(); + for (int i = 0; i<_nDataChars; i++) + _dataChars[i] = s.charAt(i); + _isBoot = b; + } + public void setOpCode(int i) { _dataChars[0]= (char)i;} public int getOpCode() {return _dataChars[0];} *************** *** 43,54 **** } // display format ! public String toString() { ! String s = ""; ! for (int i=0; i<_nDataChars; i++) { ! s+=(char)_dataChars[i]; ! } ! return s; ! } /** --- 53,106 ---- } + // Check and strip framing characters and DLE from a sprog bootloader reply + public boolean strip() { + char tmp[] = new char[_nDataChars]; + int j = 0; + _isBoot = true; // definitely a boot message + // Check framing characters + if (_dataChars[0] != SprogMessage.STX) {return false;} + if (_dataChars[1] != SprogMessage.STX) {return false;} + if (_dataChars[_nDataChars-1] != SprogMessage.ETX) {return false;} + + // Ignore framing characters and strip DLEs + for (int i = 2; i < _nDataChars - 1; i++) { + if (_dataChars[i] == SprogMessage.DLE) {i++;} + tmp[j++] = _dataChars[i]; + } + + // Copy back to original SprogReply + for (int i = 0; i < j; i++) { + _dataChars[i] = tmp[i]; + } + _nDataChars = j; + return true; + } + + // Check and strip checksum from a sprog bootloader reply + // Assumes framing and DLE chars have been stripped + public boolean getChecksum() { + int checksum = 0; + for (int i = 0; i < _nDataChars; i++) { + checksum += (int)(_dataChars[i] & 0xff); + } + _nDataChars--; + return ((checksum & 0xff) == 0); + } + // display format ! // display format ! public String toString() { ! String s = ""; ! if (_isBoot || (_dataChars[0] == SprogMessage.STX)) { ! for (int i=0; i<_nDataChars; i++) { ! s+="<"+(int)(_dataChars[i] & 0xff)+">"; ! } ! } else { ! for (int i=0; i<_nDataChars; i++) { ! s+=(char)_dataChars[i]; ! } ! } ! return s; ! } /** *************** *** 106,114 **** } ! static public int maxSize = 120; // contents (private) private int _nDataChars; private char _dataChars[] = new char[maxSize]; static org.apache.log4j.Category log = org.apache.log4j.Category.getInstance(SprogReply.class.getName()); --- 158,168 ---- } ! // Longest boot reply is 256bytes each preceded by DLE + 2xSTX + ETX ! static public int maxSize = 515; // contents (private) private int _nDataChars; private char _dataChars[] = new char[maxSize]; + private boolean _isBoot = false; static org.apache.log4j.Category log = org.apache.log4j.Category.getInstance(SprogReply.class.getName()); Index: SprogMessage.java =================================================================== RCS file: /cvsroot/jmri/jmri/jmrix/sprog/SprogMessage.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** SprogMessage.java 30 Nov 2003 18:50:15 -0000 1.2 --- SprogMessage.java 24 Jan 2005 05:26:33 -0000 1.3 *************** *** 17,20 **** --- 17,36 ---- // is this logically an abstract class? + // Special characters (NOTE: microchip bootloader does not use standard ASCII) + public static final int STX = 15; + public static final int DLE = 5; + public static final int ETX = 4; + public static final int CR = 0x0d; + public static final int LF = 0x0a; + + // bootloader commands + public static final int RD_VER = 0; + public static final int WT_FLASH = 2; + public static final int ER_FLASH = 3; + public static final int WT_EEDATA = 5; + + // Longest boot message is 256bytes each preceded by DLE + 2xSTX + ETX + public static int MAXSIZE = 515; + // create a new one public SprogMessage(int i) { *************** *** 25,28 **** --- 41,52 ---- } + // from String + public SprogMessage(String s) { + _nDataChars = s.length(); + _dataChars = new int[_nDataChars]; + for (int i = 0; i<_nDataChars; i++) + _dataChars[i] = s.charAt(i); + } + // copy one public SprogMessage(SprogMessage m) { *************** *** 41,51 **** public int getNumDataElements() {return _nDataChars;} public int getElement(int n) {return _dataChars[n];} ! public void setElement(int n, int v) { _dataChars[n] = v&0x7F; } // display format public String toString() { String s = ""; ! for (int i=0; i<_nDataChars; i++) { ! s+=(char)_dataChars[i]; } return s; --- 65,194 ---- public int getNumDataElements() {return _nDataChars;} public int getElement(int n) {return _dataChars[n];} ! public void setElement(int n, int v) { ! if (!SprogTrafficController.instance().isSIIBootMode()) {v &= 0x7f;} ! _dataChars[n] = v; ! } ! ! public void setLength(int i) { _dataChars[1]=i;} ! ! public void setV4Length(int i) { ! _dataChars[0] = hexDigit((i&0xf0)>>4); ! _dataChars[1] = hexDigit(i&0xf); ! } ! ! public void setAddress(int i) { ! _dataChars[2] = i&0xff; ! _dataChars[3] = (i>>8)&0xff; ! _dataChars[4] = i>>16; ! } ! ! public void setV4Address(int i) { ! _dataChars[2] = hexDigit((i&0xf000)>>12); ! _dataChars[3] = hexDigit((i&0xf00)>>8); ! _dataChars[4] = hexDigit((i&0xf0)>>4); ! _dataChars[5] = hexDigit(i&0xf); ! } ! ! public void setV4RecType(int i) { ! _dataChars[6] = hexDigit((i&0xf0)>>4); ! _dataChars[7] = hexDigit(i&0xf); ! } ! ! public void setData(int [] d) { ! for (int i = 0; i < d.length; i++) { ! _dataChars[5+i] = d[i]; ! } ! } ! ! public void setV4Data(int [] d) { ! int j = 8; ! for (int i = 0; i < d.length; i++) { ! _dataChars[j++] = hexDigit((d[i]&0xf0)>>4); ! _dataChars[j++] = hexDigit(d[i]&0xf); ! } ! } ! ! public void setChecksum() { ! int checksum = 0; ! for (int i = 0; i < _nDataChars - 1; i++) { ! checksum += _dataChars[i]; ! } ! checksum = checksum & 0xff; ! if (checksum > 0) { ! checksum = 256 - checksum; ! } ! _dataChars[_nDataChars - 1] = checksum; ! } ! ! public void setV4Checksum(int length, int addr, int type, int [] data) { ! int checksum = length + ((addr&0xff00)>>8) + (addr&0xff) + type; ! for (int i = 0; i < data.length; i++) { ! checksum += data[i]; ! } ! checksum = checksum & 0xff; ! if (checksum > 0) { ! checksum = 256 - checksum; ! } ! _dataChars[_nDataChars - 2] = hexDigit((checksum&0xf0)>>4); ! _dataChars[_nDataChars - 1] = hexDigit(checksum&0x0f); ! } ! ! private int hexDigit(int b) { ! if (b > 9) { ! return (b - 9 + 0x40); ! } ! else { ! return (b + 0x30); ! } ! } ! ! public SprogMessage frame() { ! int j = 2; ! // Create new message to hold the framed one ! SprogMessage f = new SprogMessage(MAXSIZE); ! f.setElement(0, STX); ! f.setElement(1, STX); ! // copy existing message adding DLE ! for (int i = 0; i < _nDataChars; i++) { ! if (_dataChars[i] == STX ! || _dataChars[i] == ETX ! || _dataChars[i] == DLE) { ! f.setElement(j++, DLE); ! } ! f.setElement(j++, _dataChars[i]); ! } ! f.setElement(j++, ETX); ! f._nDataChars = j; ! // return new message ! return f; ! } ! ! public SprogMessage v4frame() { ! int i=0; ! // Create new message to hold the framed one ! SprogMessage f = new SprogMessage(MAXSIZE); ! f.setElement(0, (int)':'); ! // copy existing message adding CRLF ! for (i = 1; i <= _nDataChars; i++) { ! f.setElement(i, _dataChars[i-1]); ! } ! f.setElement(i++, CR); ! f.setElement(i++, LF); ! f._nDataChars = i; ! // return new message ! return f; ! } // display format public String toString() { String s = ""; ! if (!SprogTrafficController.instance().isSIIBootMode()) { ! for (int i=0; i<_nDataChars; i++) { ! s+=(char)_dataChars[i]; ! } ! } else { ! for (int i=0; i<_nDataChars; i++) { ! s+="<"+(int)_dataChars[i]+">"; ! } } return s; *************** *** 63,67 **** // static methods to return a formatted message - static public SprogMessage getEnableMain() { SprogMessage m = new SprogMessage(1); --- 206,209 ---- *************** *** 148,151 **** --- 290,393 ---- } + // Bootloader messages are initially created long enough for + // the message and checksum. The message is then framed with control + // characters before being returned + + static public SprogMessage getReadBootVersion() { + SprogMessage m = new SprogMessage(3); + m.setOpCode(RD_VER); + m.setLength(2); + m.setChecksum(); + return m.frame(); + } + + static public SprogMessage getWriteFlash(int addr, int [] data) { + int l = data.length; + // Writes are rounded up to multiples of 8 bytes + if (l%8 != 0) { l = l + (8 - l%8);} + // and data padded with erased condition + int padded[] = new int[l]; + for (int i = 0; i < l; i++) { + if (i < data.length) { + padded[i] = data[i]; + } else { + padded[i] = 0xff; + } + } + SprogMessage m = new SprogMessage(6 + l); + m.setOpCode(WT_FLASH); + // length is number of 8 byte blocks + m.setLength(l/8); + m.setAddress(addr); + m.setData(padded); + m.setChecksum(); + return m.frame(); + } + + static public SprogMessage getV4WriteFlash(int addr, int [] data, int type) { + // Create a v4 bootloader message which is same format as a record + // in the hex file + int l = (data.length + 5)*2; + SprogMessage m = new SprogMessage(l); + m.setV4Length(data.length); + m.setV4Address(addr); + m.setV4RecType(type); + m.setV4Data(data); + m.setV4Checksum(data.length, addr, type, data); + return m.v4frame(); + } + + static public SprogMessage getV4EndOfFile() { + // Create a v4 bootloader end of file message + int l = 10; + SprogMessage m = new SprogMessage(l); + m.setV4Length(0); + m.setV4Address(0); + m.setV4RecType(1); + m.setV4Checksum(0, 0, 1, new int [0]); + return m.v4frame(); + } + + static public SprogMessage getv4ExtAddr() { + // Create a v4 bootloader extended address message + int l = 14; + int [] data = {0, 0}; + SprogMessage m = new SprogMessage(l); + m.setV4Length(2); + m.setV4Address(0); + m.setV4RecType(4); + m.setV4Data(data); + m.setV4Checksum(0, 0, 4, data); + return m.v4frame(); + } + + static public SprogMessage getEraseFlash(int addr, int rows) { + SprogMessage m = new SprogMessage(6); + m.setOpCode(ER_FLASH); + // Erase a number of 64 byte rows + m.setLength(rows); + m.setAddress(addr); + m.setChecksum(); + return m.frame(); + } + + static public SprogMessage getWriteEE(int addr, int [] data) { + SprogMessage m = new SprogMessage(6 + data.length); + m.setOpCode(WT_EEDATA); + m.setLength(data.length); + m.setAddress(addr & 0xff); + m.setData(data); + m.setChecksum(); + return m.frame(); + } + + static public SprogMessage getReset() { + SprogMessage m = new SprogMessage(3); + m.setOpCode(0); + m.setLength(0); + m.setChecksum(); + return m.frame(); + } + // contents (private) private int _nDataChars = 0; |