/* AVR Programmer software in JAVA Mike Seeman Created: Dec 28, 2001 Last Modified: June 2, 2002 Programming times for liion.rom: 1/16 - 3 min, 52 sec. */ import java.awt.*; import java.util.*; import java.io.*; import gnu.io.*; //import javax.comm.*; class AvrJavaProg { final static String portNames[] = {"AT90S1200", "AT90S2313", "AT90S4414", "AT90S8515", "AT90S2323", "AT90S4433", "AT90S8535"}; final static String shortNames[] = {"1200", "2313", "4414", "8515", "2323", "4433", "8535"}; final static byte deviceCodes[] = {0x13, 0x20, 0x28, 0x38, 0x48, 0x30, 0x30}; final static int flashSize[] = {1, 2, 4, 8, 2, 4, 8}; final static int eepromSize[] = {64, 100, 100, 100, 100, 256, 512}; final static int signatures[] = {0x01901E, 0x01911E, 0x01921E, 0x01931E, 0x02911E, 0x03921E, 0x03931E}; final static int srec = 1; final static int ihex = 2; final static int hex = 3; final static int baudRate = 57600; File romFile; File eepromFile; int deviceType; CommPortIdentifier progPortID; SerialPort progPort; InputStream inputStream; OutputStream outputStream; public static void main(String[] args) { AvrJavaProg prog; System.out.println("\nAVR Programmer for Java"); System.out.println("Mike Seeman"); System.out.println("For serial programmers -- see app note 910\n"); prog = new AvrJavaProg (args); prog.run(); prog.close(); } public AvrJavaProg (String[] args) { int i; romFile = null; eepromFile = null; deviceType = -1; progPortID = null; progPort = null; inputStream = null; outputStream = null; if (args.length == 0) { printUsage(); } for (i=0; i i+1) { int j; for (j=0; j i+1) { openPort (args[i+1]); i++; } else { printUsage(); return; } } else if (args[i].equals("-e")) { if (args.length > i+1) { /* Make a File class from EEPROM file */ eepromFile = new File(args[i+1]); i++; } else { printUsage(); return; } } else if (args.length == i+1) { /* Make a File class from FLASH file */ romFile = new File(args[i]); } else { printUsage(); return; } } if (romFile == null) { printUsage(); return; } } public void run () { String outputString; int i, temp, dataLength; byte size1[] = new byte[1]; byte size2[] = new byte[2]; byte size3[] = new byte[3]; byte data[], verify[]; if (progPort == null) { return; } try { /* Get Programmer Identity */ size1[0] = 'S'; outputString = stringCommand(size1, 1000, 7); if (outputString.equals("AVR ISP")) { System.out.println("AVR ISP found"); } else if (outputString.length() == 7) { System.out.println("Incompatible programmer found: " + outputString); return; } else { System.out.println("No programmer found on this port."); return; } /* Set Device Type (AT90S1200 if unspecified) */ size2[0] = 'T'; if (deviceType == -1) { size2[1] = deviceCodes[0]; } else { size2[1] = deviceCodes[deviceType]; } temp = intCommand(size2); /* Enter Programming Mode */ size1[0] = 'P'; temp = intCommand(size1, 1000, 1); System.out.println("Entered Programming mode"); /* Get Device Signature */ size1[0] = 's'; temp = intCommand(size1); System.out.println("Device Signature Received"); for (i=0; i>8); size3[2] = (byte)0; temp = intCommand(size3, 1000, 1); //for (i=0; i>8); size3[2] = (byte)0; temp = intCommand(size3, 1000, 1); //for (i=0; i>8)&0xFF); verify[2*i] = (byte)(temp & 0xFF); if (i%(dataLength/32) == 0) { System.out.print("."); } } System.out.print("\n"); for (i=0; i>8); size3[2] = (byte)0; temp = intCommand(size3, 1000, 1); for (i=0; i<(dataLength+4); i++) { size3[0] = 'A'; size3[1] = (byte)(i>>8); size3[2] = (byte)i; temp = intCommand(size3, 1000, 1); /* Program high byte */ size2[0] = 'D'; size2[1] = data[i]; temp = intCommand(size2, 1000, 1); if (i%(dataLength/16 + 1) == 0) { System.out.print("."); } } System.out.print("\n"); //bytesToOutput(data, dataLength); /* Verifying EEPROM */ System.out.print("Verifying EEPROM "); size3[0] = 'A'; size3[1] = (byte)(0>>8); size3[2] = (byte)0; temp = intCommand(size3, 1000, 1); verify = new byte[eepromSize[deviceType]*1024]; for (i=0; i<(dataLength+4); i++) { size3[0] = 'A'; size3[1] = (byte)(i>>8); size3[2] = (byte)i; temp = intCommand(size3, 1000, 1); /* Read byte */ size1[0] = 'd'; temp = intCommandForce(size1, 1000, 1); verify[i] = (byte)(temp); if (i%(dataLength/16 + 1) == 0) { System.out.print("."); } } System.out.print("\n"); //bytesToOutput(verify, dataLength); for (i=0; i totalnum) { totalnum = baseAddress + (num-11)/2; } } else { } break; case srec: if ((buffer[0] == 'S') && (buffer[1] == '1')) { /* Only interpret 2-byte address data records */ baseAddress = (hexToInt(buffer[4], buffer[5])<<8) + hexToInt(buffer[6], buffer[7]); //System.out.println("Addr: " + baseAddress); if ((baseAddress < arraySize)) { for (i=0; i<(num-10)/2; i++) { data[baseAddress+i] = hexToByte(buffer[8+2*i], buffer[9+2*i]); /* Ignore last (checksum) bit */ } if (baseAddress + (num-10)/2 - 1 > totalnum) { totalnum = baseAddress + (num-10)/2; } } else { } } break; case hex: default: System.out.println("Format Unknown"); return -1; } num = 0; linenum++; } else if (temp == '\r') { } else { buffer[num] = (byte)temp; num++; } } /* done reading - close file and make result */ reader.close(); return totalnum; } byte hexToByte (byte bh, byte bl) { int th, tl; if ((bh >= '0') && (bh <= '9')) th = bh - '0'; else if ((bh >= 'A') && (bh <= 'F')) th = bh - 'A' + 10; else th = 0; if ((bl >= '0') && (bl <= '9')) tl = bl - '0'; else if ((bl >= 'A') && (bl <= 'F')) tl = bl - 'A' + 10; else tl = 0; return (byte)((th<<4) + tl); } int hexToInt (byte bh, byte bl) { int th, tl; if ((bh >= '0') && (bh <= '9')) th = bh - '0'; else if ((bh >= 'A') && (bh <= 'F')) th = bh - 'A' + 10; else th = 0; if ((bl >= '0') && (bl <= '9')) tl = bl - '0'; else if ((bl >= 'A') && (bl <= 'F')) tl = bl - 'A' + 10; else tl = 0; return ((th<<4) + tl); } void bytesToOutput (byte data[], int num) { int i, j; byte b, d[] = new byte[2]; for (i=0; i>4); d[1] = (byte)(((int)b)&0x0F); if (d[0] < 10) d[0] += '0'; else d[0] += 'A' - 10; if (d[1] < 10) d[1] += '0'; else d[1] += 'A' - 10; System.out.print(new String(d)); } System.out.print("\n"); } } int intCommand(byte cmd[]) throws IOException { return intCommand(cmd, 200, 10); } int intCommand(byte cmd[], int delay, int numBytes) throws IOException { int ints[] = new int[10]; int num = 0, last; int i, result = 0; long seconds = new Date().getTime(); outputStream.write(cmd); outputStream.flush(); while (((new Date()).getTime() < seconds + delay) && (num < numBytes)) { while (inputStream.available() > 0) { ints[num] = inputStream.read(); num++; } } for (i=0; i 0) { ints[num] = inputStream.read(); num++; } } for (i=0; i 0) { bytes[num] = (byte)inputStream.read(); num++; } } return (new String(bytes, 0, num)); } void printUsage() { System.out.println("Usage: java AvrJavaProg [-c AT90S****] [-p SerialPort]"); System.out.println(" [-e eepromFile] flashFile\n"); System.out.println("-c Assumes target is the specified processor."); System.out.println(" Otherwise uses processor type from programmer."); System.out.println("-p Uses the given port. Otherwise presents a "); System.out.println(" menu to choose from."); System.out.println("-e Programs eepromFile to EEPROM. Otherwise,"); System.out.println(" EEPROM is programmed empty"); } void openPort (String port) { Enumeration ports = CommPortIdentifier.getPortIdentifiers(); CommPortIdentifier id; if (port.length() > 1) { while (ports.hasMoreElements()) { id = (CommPortIdentifier)ports.nextElement(); if ((id.getPortType() == CommPortIdentifier.PORT_SERIAL) &&(id.isCurrentlyOwned() == false)) { if (id.getName().startsWith(port)) { progPortID = id; break; } } } } else { int j = (new Integer(port)).intValue(); while (ports.hasMoreElements()) { id = (CommPortIdentifier)ports.nextElement(); if ((id.getPortType() == CommPortIdentifier.PORT_SERIAL) &&(id.isCurrentlyOwned() == false)) { if (j == 1) { progPortID = id; break; } else { j--; } } } } if (progPortID == null) { System.out.println("Could not find port " + port); return; } //System.out.println("Attempting change of port..."); if (progPortID.isCurrentlyOwned()) { progPort = null; return; } try { progPort = (SerialPort) progPortID.open("AVRJavaProg", 100); } catch (PortInUseException e) { System.out.println("Port " + progPortID.getName() + " is in use: " + e.toString() + " by application: " + e.currentOwner); progPort = null; return; } try { inputStream = progPort.getInputStream(); outputStream = progPort.getOutputStream(); } catch (IOException e) { System.out.println("openCommPort: " + e.toString()); } try { progPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); progPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE); } catch (UnsupportedCommOperationException e) { System.out.println("setBaud error: " + e.toString()); } System.out.println("Opened Port: " + progPort.toString()); } void close () { if (progPort != null) { try { inputStream.close(); outputStream.close(); progPort.close(); } catch (IOException e) { System.out.println("close: " + e); } } } }