diff --git a/LICENSE-d2xx_jar.txt b/LICENSE-d2xx_jar.txt
new file mode 100644
index 0000000..1b5c8ca
--- /dev/null
+++ b/LICENSE-d2xx_jar.txt
@@ -0,0 +1,209 @@
+
+ Driver Licence Terms
+IMPORTANT NOTICE: PLEASE READ CAREFULLY BEFORE INSTALLING THE RELEVANT SOFTWARE: This licence agreement
+("Licence") is a legal agreement between you ("Licencee" or "you") and Future Technology Devices
+International Limited of 2 Seaward Place, Centurion Business Park, Glasgow, Scotland, G41 1HH (UK Company
+ Number SC136640) ("Licensor" or "we) for use of driver software provided by the Licensor ("Software").
+
+BY INSTALLING OR USING THIS SOFTWARE YOU AGREE TO THE TERMS OF THIS LICENCE WHICH WILL BIND YOU. IF YOU
+DO NOT AGREE TO THE TERMS OF THIS LICENCE, WE ARE UNWILLING TO LICENSE THE SOFTWARE TO YOU AND YOU MUST
+DISCONTINUE INSTALLATION OF THE SOFTWARE NOW.
+
+1. Grant and scope of licence
+
+1.1 In consideration of you agreeing to abide by the terms of this Licence, the Licensor hereby grants
+ to you a non-exclusive, non-transferable, royalty free licence to use the Software on the terms of
+ this Licence.
+
+1.2 In this Licence a "Genuine FTDI Component" means an item of hardware that was manufactured for, and
+ sold by, the Licensor or a member of the Licensor's group of companies. It does not include any counterfeit
+ or fake products.
+
+1.3 If you are a manufacturer of a device that includes a Genuine FTDI Component (each a "Device") then
+ you may install the Software onto that device. If you are a seller or distributor of a Device then
+ You may distribute the Software with the Device. If you are a user of a Device then you may install
+ the Software on the Device, or onto a computer system in order to use the Device.
+
+1.4 In each of those cases you may:
+
+1.4.1 install and use the Software for your purposes only; and
+
+1.4.2 only use the Software in conjunction with products based on and/or incorporating a Genuine FTDI Component.
+
+1.5 The Software will not function properly on or with a component that is not a Genuine FTDI Component.
+ Use of the Software as a driver for, or installation of the Software onto, a component that is not
+ a Genuine FTDI Component, including without limitation counterfeit components, MAY IRRETRIEVABLY DAMAGE
+ THAT COMPONENT. It is the Licensee's responsibility to make sure that all chips it installs the Software
+ on, or uses the Software as a driver for, are Genuine FTDI Components. If in doubt then contact the Licensor.
+
+
+2. If a custom vendor ID and/or product ID or description string are used, it is the responsibility of
+ the product manufacturer to maintain any changes and subsequent WHQL re-certification as a result of
+ making these changes.
+
+
+3. Licensee's undertakings
+
+3.1 Except as expressly set out in this Licence or as permitted by any local law, you undertake:
+
+3.1.1 not to copy the Software, except where such copying is incidental to normal use of the Software or
+ where it is necessary for the purpose of back-up or operational security;
+
+3.1.2 not to rent, lease, sub-license, loan, translate, merge, adapt, vary or modify the Software or any
+ part of it;
+
+3.1.3 not to make alterations to, or modifications of, the whole or any part of the Software nor permit
+ the Software or any part of it to be combined with, or become incorporated in, any other programs;
+
+3.1.4 not to disassemble, de-compile, reverse engineer or create derivative works based on the whole or
+ any part of the Software;
+
+3.1.5 to keep all copies of the Software secure;
+
+3.1.6 to include the copyright notice of the Licensor on all entire and partial copies of the Software in
+ any form; and
+
+3.1.7 not to provide, or otherwise make available, the Software in any form, in whole or in part (including,
+ but not limited to, program listings, object and source program listings, object code and source
+ code) to any person.
+
+
+4. Intellectual property rights
+
+4.1 You acknowledge that all intellectual property rights in the Software throughout the world belong to
+ the Licensor, that rights in the Software are licensed (not sold) to you, and that you have no rights
+ in, or to, the Software other than the right to use them in accordance with the terms of this Licence.
+
+
+5. Warranty
+
+5.1 To the maximum extent permitted by applicable law, the software is provided "as is".
+
+5.2 All implied warranties, implied conditions and/or implied licences are excluded from this Licence,
+ including but not limited to implied warranties of quality and/or fitness for purpose (in all cases)
+ to the fullest extent permitted by law.
+
+
+5.3 You acknowledge that the Software has not been developed to meet your individual requirements and that
+ the Software may not be uninterrupted or free of bugs or errors.
+
+
+6. Licensor's liability
+
+6.1 To the maximum extent permitted by applicable law, in no event shall the Licensor be liable for any:
+
+6.1.1 special loss or damage;
+
+6.1.2 incidental loss or damage;
+
+6.1.3 indirect or consequential loss or damage:
+
+6.1.4 loss of income;
+
+6.1.5 loss of business;
+
+6.1.6 loss of profits;
+
+6.1.7 loss of revenue;
+
+6.1.8 loss of contracts;
+
+6.1.9 business interruption;
+
+6.1.10 loss of the use of money or anticipated savings;
+
+6.1.11 loss of information;
+
+6.1.12 loss of opportunity;
+
+6.1.13 loss of goodwill or reputation; and/or
+
+6.1.14 loss of, damage to or corruption of data;
+
+(in each case) of any kind howsoever arising and whether caused by delict (including negligence), breach
+of contract or otherwise.
+
+6.2 FTDI's total liability to you in relation to the Software shall not exceed 500 US Dollars.
+
+6.3 Nothing in this Licence limits or excludes liability for death or personal injury or for fraud.
+
+
+7. Termination
+
+7.1 The Licensor may terminate this Licence immediately if:
+
+7.1.1 you fail to comply with any of the terms and conditions of the Licence; or
+
+7.1.2 you commence or participate in any legal proceedings against the Licensor.
+
+7.2 Upon termination:
+
+7.2.1 all rights granted to you under this Licence shall cease;
+
+7.2.2 you must cease all activities authorised by this Licence; and
+
+7.2.3 you must immediately delete or remove the Software from all computer equipment in your possession
+ and immediately destroy all copies of the Software then in your possession, custody or control.
+
+
+
+8. Transfer of rights and obligations
+
+8.1 You may not transfer, assign, charge or otherwise dispose of this Licence, or any of your rights or
+ obligations arising under it.
+
+8.2 The Licensor may transfer, assign, charge, sub-contract or otherwise dispose of this Licence, or any
+ of his rights or obligations arising under it, at any time during the term of the Licence.
+
+
+9. Waiver
+
+9.1 If the Licensor fails, at any time during the term of this Licence, to insist on strict performance
+ of any of your obligations under this Licence, or if the Licensor fails to exercise any of the rights
+ or remedies to which he is entitled under this Licence, this shall not constitute a waiver of such
+ rights or remedies and shall not relieve you from compliance with such obligations.
+
+9.2 A waiver by the Licensor of any default shall not constitute a waiver of any subsequent default.
+
+9.3 No waiver by the Licensor of any of these terms and conditions shall be effective unless it is expressly
+ stated to be a waiver and is communicated to you in writing.
+
+
+10. Severability
+
+If any of the terms of this Licence are determined by any competent authority to be invalid, unlawful or
+unenforceable to any extent, such term, condition or provision will to that extent be severed from the
+remaining terms, conditions and provisions which will continue to be valid to the fullest extent permitted by law.
+
+
+11. Entire agreement
+
+11.1 This Licence constitutes the whole agreement between us and supersedes any previous arrangement,
+ understanding or agreement between us, relating to the licensing of the Software.
+
+11.2 Each party acknowledges that in entering into this Licence it does not rely on any statement, representation,
+ warranty or understanding other than those expressly set out in this Licence. Each party agrees
+ that it will have no remedy in respect of any statement, representation, warranty or understanding
+ that is not expressly set out in this Licence. Each party agrees that its only remedy in respect
+ of those representations, statements, assurances and warranties that are set out in this Licence
+ will be for breach of contract in accordance with the terms of this Licence.
+
+11.3 The parties agree that nothing in this Licence will limit or exclude any liability they may have
+ for fraud.
+
+
+12. Miscellaneous
+
+12.1 This Licence does not create a partnership or joint venture between the parties to it, nor authorise
+ a party to act as agent for the other.
+
+12.2 This Licence does not create any legal rights enforceable by any third party.
+
+12.3 This Licence may only be varied by express written legal agreement between the parties.
+
+
+13. Law and jurisdiction
+
+This Licence, its subject matter or its formation (including non-contractual disputes or claims) shall
+be governed by and construed in accordance with Scots law and submitted to the non-exclusive jurisdiction
+of the Scottish courts.
\ No newline at end of file
diff --git a/physicaloid/build.gradle b/physicaloid/build.gradle
index 66d4ce8..3951af8 100644
--- a/physicaloid/build.gradle
+++ b/physicaloid/build.gradle
@@ -6,12 +6,12 @@ apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'
android {
- compileSdkVersion 14
+ compileSdkVersion 19
buildToolsVersion "23.0.2"
defaultConfig {
minSdkVersion 14
- targetSdkVersion 14
+ targetSdkVersion 19
}
buildTypes {
diff --git a/physicaloid/libs/d2xx.jar b/physicaloid/libs/d2xx.jar
index be24cf9..aea713f 100644
Binary files a/physicaloid/libs/d2xx.jar and b/physicaloid/libs/d2xx.jar differ
diff --git a/physicaloid/physicaloid.iml b/physicaloid/physicaloid.iml
index 3d36619..b49164d 100644
--- a/physicaloid/physicaloid.iml
+++ b/physicaloid/physicaloid.iml
@@ -81,7 +81,7 @@
-
+
diff --git a/physicaloid/src/main/java/com/physicaloid/lib/programmer/avr/IntelHexFileToBuf.java b/physicaloid/src/main/java/com/physicaloid/lib/programmer/avr/IntelHexFileToBuf.java
index 70e1c4b..f5402a4 100644
--- a/physicaloid/src/main/java/com/physicaloid/lib/programmer/avr/IntelHexFileToBuf.java
+++ b/physicaloid/src/main/java/com/physicaloid/lib/programmer/avr/IntelHexFileToBuf.java
@@ -58,7 +58,7 @@ public void parse(String filePath) throws FileNotFoundException, IOException, Ex
public void parse(InputStream is) throws FileNotFoundException, IOException, Exception {
ihp = new IntelHexParser(is);
- ihpd = new IntelHexParserRun(0, 0xFFFF);
+ ihpd = new IntelHexParserRun(0, 0xFFFFFF);
ihp.setDataListener(ihpd);
ihp.parse();
diff --git a/physicaloid/src/main/java/cz/jaybee/intelhex/BinWriter.java b/physicaloid/src/main/java/cz/jaybee/intelhex/BinWriter.java
new file mode 100644
index 0000000..b7bb1f6
--- /dev/null
+++ b/physicaloid/src/main/java/cz/jaybee/intelhex/BinWriter.java
@@ -0,0 +1,91 @@
+/**
+ * @license Copyright (c) 2015, Jan Breuer All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package cz.jaybee.intelhex;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Binary file writer
+ *
+ * @author Jan Breuer
+ * @license BSD 2-Clause
+ */
+public class BinWriter implements IntelHexDataListener {
+
+ private final Region outputRegion;
+ private final OutputStream destination;
+ private final byte[] buffer;
+ private final MemoryRegions regions;
+ private long maxAddress;
+ private final boolean minimize;
+
+ public BinWriter(Region outputRegion, OutputStream destination, boolean minimize) {
+ this.outputRegion = outputRegion;
+ this.destination = destination;
+ this.minimize = minimize;
+ this.buffer = new byte[(int) (outputRegion.getLength())];
+ Arrays.fill(buffer, (byte) 0xFF);
+ regions = new MemoryRegions();
+ maxAddress = outputRegion.getAddressStart();
+ }
+
+ @Override
+ public void data(long address, byte[] data) {
+ regions.add(address, data.length);
+
+ if ((address >= outputRegion.getAddressStart()) && (address <= outputRegion.getAddressEnd())) {
+ int length = data.length;
+ if ((address + length) > outputRegion.getAddressEnd()) {
+ length = (int) (outputRegion.getAddressEnd() - address + 1);
+ }
+ System.arraycopy(data, 0, buffer, (int) (address - outputRegion.getAddressStart()), length);
+
+ if (maxAddress < (address + data.length - 1)) {
+ maxAddress = address + data.length - 1;
+ }
+ }
+ }
+
+ @Override
+ public void eof() {
+ try {
+ if (!minimize) {
+ maxAddress = outputRegion.getAddressEnd();
+ }
+ destination.write(buffer, 0, (int) (maxAddress - outputRegion.getAddressStart() + 1));
+ } catch (IOException ex) {
+ Logger.getLogger(BinWriter.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ public MemoryRegions getMemoryRegions() {
+ return regions;
+ }
+}
\ No newline at end of file
diff --git a/physicaloid/src/main/java/cz/jaybee/intelhex/IntelHexDataListener.java b/physicaloid/src/main/java/cz/jaybee/intelhex/IntelHexDataListener.java
index ea3ab60..a5d709f 100644
--- a/physicaloid/src/main/java/cz/jaybee/intelhex/IntelHexDataListener.java
+++ b/physicaloid/src/main/java/cz/jaybee/intelhex/IntelHexDataListener.java
@@ -1,12 +1,11 @@
/**
- * @license Copyright (c) 2012, Jan Breuer
- * All rights reserved.
+ * @license Copyright (c) 2015, Jan Breuer All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
@@ -27,13 +26,26 @@
package cz.jaybee.intelhex;
/**
+ * Listener interface to parser events
*
* @author Jan Breuer
* @license BSD 2-Clause
*/
public interface IntelHexDataListener {
+ /**
+ * Every time new data are read from file, this listener method is called
+ * with appropriate values. Multiple calls of this function may be done
+ * inside one memory regions but they will not overlap (if they don't
+ * overlap in original intelhex).
+ *
+ * @param address
+ * @param data
+ */
public void data(long address, byte[] data);
+ /**
+ * After eof is detected in the file, this listener method is called
+ */
public void eof();
-}
+}
\ No newline at end of file
diff --git a/physicaloid/src/main/java/cz/jaybee/intelhex/IntelHexException.java b/physicaloid/src/main/java/cz/jaybee/intelhex/IntelHexException.java
new file mode 100644
index 0000000..6b34b44
--- /dev/null
+++ b/physicaloid/src/main/java/cz/jaybee/intelhex/IntelHexException.java
@@ -0,0 +1,42 @@
+/**
+ * @license Copyright (c) 2015, Jan Breuer All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package cz.jaybee.intelhex;
+
+/**
+ * Custom exception to prevent using general Exception
+ *
+ * @author Jan Breuer
+ * @license BSD 2-Clause
+ */
+public class IntelHexException extends Exception {
+
+ public IntelHexException() {
+ }
+
+ public IntelHexException(String message) {
+ super(message);
+ }
+}
\ No newline at end of file
diff --git a/physicaloid/src/main/java/cz/jaybee/intelhex/IntelHexParser.java b/physicaloid/src/main/java/cz/jaybee/intelhex/IntelHexParser.java
index 1c4a7ab..2577089 100644
--- a/physicaloid/src/main/java/cz/jaybee/intelhex/IntelHexParser.java
+++ b/physicaloid/src/main/java/cz/jaybee/intelhex/IntelHexParser.java
@@ -1,12 +1,11 @@
/**
- * @license Copyright (c) 2012, Jan Breuer
- * All rights reserved.
+ * @license Copyright (c) 2015, Jan Breuer All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
@@ -33,53 +32,100 @@
import java.io.Reader;
/**
+ * Main Intel HEX parser class
*
* @author Jan Breuer
+ * @author Kristian Sloth Lauszus
+ * @author riilabs
* @license BSD 2-Clause
*/
public class IntelHexParser {
- private BufferedReader reader = null;
+ private final BufferedReader reader;
private IntelHexDataListener dataListener = null;
private static final int HEX = 16;
private boolean eof = false;
private int recordIdx = 0;
private long upperAddress = 0;
+ private long startAddress = 0;
+ /**
+ * Class to hold one Intel HEX record - one line in the file
+ */
private class Record {
int length;
int address;
IntelHexRecordType type;
byte[] data;
+
+ /**
+ * Convert the record to pretty string
+ *
+ * @return
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append(type);
+ sb.append(" @");
+ sb.append(String.format("0x%04X", address));
+ sb.append(" [");
+ for (byte c : data) {
+ sb.append(String.format("0x%02X", c));
+ sb.append(" ");
+ }
+ sb.setLength(sb.length() - 1);
+ sb.append("]");
+ return sb.toString();
+ }
}
+ /**
+ * Constructor of the parser with reader
+ *
+ * @param reader
+ */
public IntelHexParser(Reader reader) {
- if (reader instanceof BufferedReader) {
- this.reader = (BufferedReader) reader;
- } else {
- this.reader = new BufferedReader(reader);
- }
+ this.reader = (reader instanceof BufferedReader) ? (BufferedReader) reader : new BufferedReader(reader);
}
+ /**
+ * Constructor of the parser with input stream
+ *
+ * @param stream
+ */
public IntelHexParser(InputStream stream) {
this.reader = new BufferedReader(new InputStreamReader(stream));
}
+ /**
+ * Set data listener to parsing events (data and eof)
+ *
+ * @param listener
+ */
public void setDataListener(IntelHexDataListener listener) {
this.dataListener = listener;
}
- private Record parseRecord(String record) throws Exception {
+ /**
+ * Parse one line of Intel HEX file
+ *
+ * @param record
+ * @return
+ * @throws IntelHexException
+ */
+ private Record parseRecord(String record) throws IntelHexException {
Record result = new Record();
// check, if there wasn an accidential EOF record
if (eof) {
- throw new Exception("Data after eof (" + recordIdx + ")");
+ throw new IntelHexException("Data after eof (" + recordIdx + ")");
}
// every IntelHEX record must start with ":"
if (!record.startsWith(":")) {
- throw new Exception("Invalid Intel HEX record (" + recordIdx + ")");
+ throw new IntelHexException("Invalid Intel HEX record (" + recordIdx + ")");
}
int lineLength = record.length();
@@ -95,13 +141,13 @@ private Record parseRecord(String record) throws Exception {
sum &= 0xff;
if (sum != 0) {
- throw new Exception("Invalid checksum (" + recordIdx + ")");
+ throw new IntelHexException("Invalid checksum (" + recordIdx + ")");
}
// if the length field does not correspond with line length
result.length = hexRecord[0];
if ((result.length + 5) != hexRecord.length) {
- throw new Exception("Invalid record length (" + recordIdx + ")");
+ throw new IntelHexException("Invalid record length (" + recordIdx + ")");
}
// length is OK, copy data
result.data = new byte[result.length];
@@ -113,13 +159,19 @@ private Record parseRecord(String record) throws Exception {
// determine record type
result.type = IntelHexRecordType.fromInt(hexRecord[3] & 0xFF);
if (result.type == IntelHexRecordType.UNKNOWN) {
- throw new Exception("Unsupported record type " + (hexRecord[3] & 0xFF) + " (" + recordIdx + ")");
+ throw new IntelHexException("Unsupported record type " + (hexRecord[3] & 0xFF) + " (" + recordIdx + ")");
}
return result;
}
- private void processRecord(Record record) throws Exception {
+ /**
+ * Process parsed record, copute correct address, emit events
+ *
+ * @param record
+ * @throws IntelHexException
+ */
+ private void processRecord(Record record) throws IntelHexException {
// build full address
long addr = record.address | upperAddress;
switch (record.type) {
@@ -139,7 +191,7 @@ private void processRecord(Record record) throws Exception {
upperAddress = ((record.data[0] & 0xFF) << 8) + (record.data[1] & 0xFF);
upperAddress <<= 16; // ELA is bits 16-31 of the segment base address (SBA), so shift left 16 bits
} else {
- throw new Exception("Invalid EXT_LIN record (" + recordIdx + ")");
+ throw new IntelHexException("Invalid EXT_LIN record (" + recordIdx + ")");
}
break;
@@ -148,21 +200,57 @@ private void processRecord(Record record) throws Exception {
upperAddress = ((record.data[0] & 0xFF) << 8) + (record.data[1] & 0xFF);
upperAddress <<= 4; // ESA is bits 4-19 of the segment base address (SBA), so shift left 4 bits
} else {
- throw new Exception("Invalid EXT_SEG record (" + recordIdx + ")");
+ throw new IntelHexException("Invalid EXT_SEG record (" + recordIdx + ")");
}
break;
- case START_SEG:
case START_LIN:
- throw new Exception(record.type + " record not implemented (" + recordIdx + ")");
+ if (record.length == 4) {
+ startAddress = 0;
+ for (byte c : record.data) {
+ startAddress = startAddress << 8;
+ startAddress |= (c & 0xFF);
+ }
+ } else {
+ throw new IntelHexException("Invalid START_LIN record at line #" + recordIdx + " " + record);
+ }
+ break;
+ case START_SEG:
+ if (record.length == 4) {
+ startAddress = 0;
+ for (byte c : record.data) {
+ startAddress = startAddress << 8;
+ startAddress |= (c & 0xFF);
+ }
+ } else {
+ throw new IntelHexException("Invalid START_SEG record at line #" + recordIdx + " " + record);
+ }
case UNKNOWN:
break;
}
}
- public void parse() throws IOException, Exception {
+ /**
+ * Return program start address/reset address. May not be at the beggining
+ * of the data.
+ *
+ * @return
+ */
+ public long getStartAddress() {
+ return startAddress;
+ }
+
+ /**
+ * Main public method to start parsing of the input
+ *
+ * @throws IntelHexException
+ * @throws IOException
+ */
+ public void parse() throws IntelHexException, IOException {
+ eof = false;
recordIdx = 1;
upperAddress = 0;
+ startAddress = 0;
String recordStr;
while ((recordStr = reader.readLine()) != null) {
@@ -172,7 +260,7 @@ public void parse() throws IOException, Exception {
}
if (!eof) {
- throw new Exception("No eof at the end of file");
+ throw new IntelHexException("No eof at the end of file");
}
}
-}
+}
\ No newline at end of file
diff --git a/physicaloid/src/main/java/cz/jaybee/intelhex/IntelHexParserDemo.java b/physicaloid/src/main/java/cz/jaybee/intelhex/IntelHexParserDemo.java
new file mode 100644
index 0000000..ca7eed1
--- /dev/null
+++ b/physicaloid/src/main/java/cz/jaybee/intelhex/IntelHexParserDemo.java
@@ -0,0 +1,160 @@
+/**
+ * @license Copyright (c) 2015, Jan Breuer All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package cz.jaybee.intelhex;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Class to demonstrate usage of Intel HEX parser
+ *
+ * @author Jan Breuer
+ * @license BSD 2-Clause
+ */
+public class IntelHexParserDemo {
+
+ /**
+ * Convert Intel HEX to bin
+ *
+ * usage:
+ *
+ * IntelHexParserDemo {source} {target}
+ *
+ * IntelHexParserDemo {source} {target} {address_from} {address_to}
+ *
+ * {source} is source Intel HEX file name
+ *
+ * {target} is target BIN file name
+ *
+ * {address_from} is start address e.g. 0x1D000000 or min
+ *
+ * {address_to} is end address e.g. 0x1D07FFFF or max
+ *
+ * if no address_from and address_to is specified, maximum range is used
+ *
+ * @param args the command line arguments
+ */
+ public static void main(String[] args) {
+ String fileIn = "Application.hex";
+ String fileOut = "Application.bin";
+ String dataFrom = "min";
+ String dataTo = "max";
+ boolean minimize = false;
+
+ if (args.length == 0) {
+ System.out.println("usage:");
+ System.out.println(" hex2bin [minimize]");
+ System.out.println();
+ System.out.println(" full address range of app.hex");
+ System.out.println(" hex2bin app.hex app.bin");
+ System.out.println();
+ System.out.println(" limited exact address range of app.hex, undefined data are 0xff");
+ System.out.println(" hex2bin app.hex app.bin 0x0000 0x1fff");
+ System.out.println();
+ System.out.println(" limited minimal address range of app.hex, start at 0x0000,");
+ System.out.println(" max address is 0x1fff, but can be lower");
+ System.out.println(" hex2bin app.hex app.bin 0x0000 0x1fff minimize");
+ return;
+ }
+
+ if (args.length >= 1) {
+ fileIn = args[0];
+ }
+
+ if (args.length >= 2) {
+ fileOut = args[1];
+ }
+
+ if (args.length >= 3) {
+ dataFrom = args[2];
+ }
+
+ if (args.length >= 4) {
+ dataTo = args[3];
+ }
+
+ if (args.length >= 5) {
+ if (args[4].equals("minimize")) {
+ minimize = true;
+ }
+ }
+
+ FileInputStream is = null;
+ try {
+ is = new FileInputStream(fileIn);
+ OutputStream os = new FileOutputStream(fileOut);
+ // init parser
+ IntelHexParser parser = new IntelHexParser(is);
+
+ // 1st iteration - calculate maximum output range
+ RangeDetector rangeDetector = new RangeDetector();
+ parser.setDataListener(rangeDetector);
+ parser.parse();
+ is.getChannel().position(0);
+ Region outputRegion = rangeDetector.getFullRangeRegion();
+
+ // if address parameter is "max", calculate maximum memory region
+ if (!("min".equals(dataFrom))) {
+ outputRegion.setAddressStart(Long.parseLong(dataFrom.substring(2), 16));
+ }
+ if (!("max".equals(dataTo))) {
+ outputRegion.setAddressEnd(Long.parseLong(dataTo.substring(2), 16));
+ }
+
+ // 2nd iteration - actual write of the output
+ BinWriter writer = new BinWriter(outputRegion, os, minimize);
+ parser.setDataListener(writer);
+ parser.parse();
+
+ // print statistics
+ System.out.printf("Program start address 0x%08X\r\n", parser.getStartAddress());
+ System.out.println("Memory regions: ");
+ System.out.println(writer.getMemoryRegions());
+
+ System.out.print("Written output: ");
+ System.out.println(outputRegion);
+
+
+ } catch (IntelHexException ex) {
+ Logger.getLogger(IntelHexParserDemo.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (IOException ex) {
+ Logger.getLogger(IntelHexParserDemo.class.getName()).log(Level.SEVERE, null, ex);
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException ex) {
+ Logger.getLogger(IntelHexParserDemo.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/physicaloid/src/main/java/cz/jaybee/intelhex/IntelHexRecordType.java b/physicaloid/src/main/java/cz/jaybee/intelhex/IntelHexRecordType.java
index ac2c866..bdd562d 100644
--- a/physicaloid/src/main/java/cz/jaybee/intelhex/IntelHexRecordType.java
+++ b/physicaloid/src/main/java/cz/jaybee/intelhex/IntelHexRecordType.java
@@ -1,12 +1,11 @@
/**
- * @license Copyright (c) 2012, Jan Breuer
- * All rights reserved.
+ * @license Copyright (c) 2015, Jan Breuer All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
@@ -27,6 +26,7 @@
package cz.jaybee.intelhex;
/**
+ * Type of one record in Intel HEX file (type of line)
*
* @author Jan Breuer
* @license BSD 2-Clause
@@ -46,10 +46,21 @@ public enum IntelHexRecordType {
this.id = id;
}
+ /**
+ * Convert enum value to integer
+ *
+ * @return
+ */
public int toInt() {
return id;
}
+ /**
+ * Convert integer value to enum value
+ *
+ * @param id
+ * @return
+ */
public static IntelHexRecordType fromInt(int id) {
for (IntelHexRecordType d : IntelHexRecordType.values()) {
if (d.id == id) {
@@ -58,4 +69,4 @@ public static IntelHexRecordType fromInt(int id) {
}
return IntelHexRecordType.UNKNOWN;
}
-}
+}
\ No newline at end of file
diff --git a/physicaloid/src/main/java/cz/jaybee/intelhex/MemoryRegions.java b/physicaloid/src/main/java/cz/jaybee/intelhex/MemoryRegions.java
new file mode 100644
index 0000000..63aa492
--- /dev/null
+++ b/physicaloid/src/main/java/cz/jaybee/intelhex/MemoryRegions.java
@@ -0,0 +1,112 @@
+/**
+ * @license Copyright (c) 2015, Jan Breuer All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package cz.jaybee.intelhex;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Class to hold all memory address regions
+ *
+ * @author Jan Breuer
+ * @author riilabs
+ * @license BSD 2-Clause
+ */
+public class MemoryRegions {
+
+ private final List regions = new ArrayList();
+
+ public void add(long start, long length) {
+ Region prevRegion;
+ if (regions.size() > 0) {
+ prevRegion = regions.get(regions.size() - 1);
+ long nextAddress = prevRegion.getAddressStart() + prevRegion.getLength();
+ if (nextAddress == start) {
+ prevRegion.incLength(length);
+ return;
+ }
+ }
+ regions.add(new Region(start, length));
+ }
+
+ public void compact() {
+ Collections.sort(regions);
+
+ Iterator iter = regions.iterator();
+ Region prev = null;
+ while (iter.hasNext()) {
+ Region curr = iter.next();
+ if (prev == null) {
+ prev = curr;
+ } else {
+ // check for chaining
+ if (curr.getAddressStart() == (prev.getAddressStart() + prev.getLength())) {
+ prev.incLength(curr.getLength());
+ iter.remove();
+ } else {
+ prev = curr;
+ }
+ }
+ }
+ }
+
+ public void clear() {
+ regions.clear();
+ }
+
+ public int size() {
+ return regions.size();
+ }
+
+ public Region get(int index) {
+ return regions.get(index);
+ }
+
+ public Region getFullRangeRegion() {
+ long start = 0;
+ long length = 0;
+ if (!regions.isEmpty()) {
+ start = regions.get(0).getAddressStart();
+ Region last = regions.get(regions.size() - 1);
+ length = last.getAddressStart() + last.getLength() - start;
+ }
+
+ return new Region(start, length);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ for (Region r : regions) {
+ sb.append(r).append("\r\n");
+ }
+
+ return sb.toString();
+ }
+}
\ No newline at end of file
diff --git a/physicaloid/src/main/java/cz/jaybee/intelhex/RangeDetector.java b/physicaloid/src/main/java/cz/jaybee/intelhex/RangeDetector.java
new file mode 100644
index 0000000..78d1ede
--- /dev/null
+++ b/physicaloid/src/main/java/cz/jaybee/intelhex/RangeDetector.java
@@ -0,0 +1,60 @@
+/**
+ * @license Copyright (c) 2015, Jan Breuer All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package cz.jaybee.intelhex;
+
+/**
+ * First pass listener to calculate data address range for further use
+ *
+ * @author riilabs
+ * @author Jan Breuer
+ * @license BSD 2-Clause
+ */
+public class RangeDetector implements IntelHexDataListener {
+
+ private final MemoryRegions regions = new MemoryRegions();
+
+ @Override
+ public void data(long address, byte[] data) {
+ regions.add(address, data.length);
+ }
+
+ @Override
+ public void eof() {
+ regions.compact();
+ }
+
+ public void reset() {
+ regions.clear();
+ }
+
+ public Region getFullRangeRegion() {
+ return regions.getFullRangeRegion();
+ }
+
+ public MemoryRegions getMemoryRegions() {
+ return regions;
+ }
+}
\ No newline at end of file
diff --git a/physicaloid/src/main/java/cz/jaybee/intelhex/Region.java b/physicaloid/src/main/java/cz/jaybee/intelhex/Region.java
new file mode 100644
index 0000000..510cfb3
--- /dev/null
+++ b/physicaloid/src/main/java/cz/jaybee/intelhex/Region.java
@@ -0,0 +1,111 @@
+/**
+ * @license Copyright (c) 2015, Jan Breuer All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package cz.jaybee.intelhex;
+
+/**
+ * One memory region
+ *
+ * @author Jan Breuer
+ * @license BSD 2-Clause
+ */
+public class Region implements Comparable {
+
+ private long addressStart;
+ private long addressEnd;
+
+ public Region(long start, long length) {
+ this.addressStart = start;
+ this.addressEnd = start + length - 1;
+ }
+
+ /**
+ * Get length of the region
+ * @return
+ */
+ public long getLength() {
+ return addressEnd - addressStart + 1;
+ }
+
+ /**
+ * Return last address in memory region
+ * @return
+ */
+ public long getAddressEnd() {
+ return addressEnd;
+ }
+
+ /**
+ * Set end address
+ * @param addressEnd
+ */
+ public void setAddressEnd(long addressEnd) {
+ this.addressEnd = addressEnd;
+ }
+
+ /**
+ * Get start address of the region
+ * @return
+ */
+ public long getAddressStart() {
+ return addressStart;
+ }
+
+ /**
+ * Set start address
+ * @param addressStart
+ */
+ public void setAddressStart(long addressStart) {
+ this.addressStart = addressStart;
+ }
+
+ /**
+ * Increment length of the region by value
+ * @param value
+ */
+ void incLength(long value) {
+ addressEnd += value;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("0x%08x:0x%08x (%dB 0x%08X)", addressStart, addressEnd, getLength(), getLength());
+ }
+
+ /**
+ * Compare, if one region is after another region
+ *
+ * @param o
+ * @return
+ */
+ @Override
+ public int compareTo(Region o) {
+ if (this.addressStart == o.addressStart) {
+ return Long.compare(this.addressEnd, o.addressEnd);
+ } else {
+ return Long.compare(this.addressStart, o.addressStart);
+ }
+ }
+}
\ No newline at end of file