From: Manfred Steiner <sx@htl-kaindorf.at> Date: Sat, 8 Dec 2018 04:54:57 +0000 (+0100) Subject: Version 2.26 (25.8.2016) X-Git-Url: https://git.htl-mechatronik.at/public/?a=commitdiff_plain;h=0db90c86b51bee47349c70ccdd6e9764de9074a2;p=sx%2Feasyprogrammer.git Version 2.26 (25.8.2016) --- 0db90c86b51bee47349c70ccdd6e9764de9074a2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0cf9cee --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +# Netbeans Java with ant +**/nbproject/private/ +**/build/ +**/dist/ + +# Netbeans Java with Maven +**/target/ + +# Netbeans Java with Gradle +**/.gradle/ +**/.nb-gradle/ + +# Netbeans C/C++ +**/nbproject/private/ +**/build/ +**/dist/ +**/.dep.inc + +# Codeblocks/Structorizer +**/bin/ +**/obj/ +*.depend +*.layout diff --git a/README.md b/README.md new file mode 100644 index 0000000..4f15fa0 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# Easyprogrammer + +## History + +Version | Date | Remarks +--------|-----------|----------------------------- + 2.26 | 25.8.2016 | 1:1 movement from SVN server + diff --git a/bad b/bad new file mode 100644 index 0000000..b7f6623 --- /dev/null +++ b/bad @@ -0,0 +1,144 @@ +root@len:~# usbdump -d 10c4:ea60 -a + 0.000000 1<-- + 0.000041 1<-- + 0.007915 1<-- + 0.007956 1<-- + 0.028046 1<-- + 0.028176 1<-- + 0.098216 1<-- + 0.098254 1<-- + 6.066158 1<-- 72: 0d 0a 42(B) 6f(o) 6f(o) 74(t) 6c(l) 6f(o) 61(a) 64(d) 65(e) 72(r) 20( ) 56(V) 65(e) 72(r) 73(s) 69(i) 6f(o) 6e(n) 20( ) 32(2) 2e(.) 30(0) 35(5) 20( ) 5b([) 41(A) 74(t) 6d(m) 65(e) 67(g) 61(a) 31(1) 36(6) 2c(,) 32(2) 30(0) 31(1) 31(1) 2d(-) 30(0) 38(8) 2d(-) 32(2) 37(7) 2c(,) 53(S) 58(X) 5d(]) 20( ) 20( ) 20( ) 0d 0a 20( ) 2e(.) 2e(.) 2e(.) 20( ) 70(p) 72(r) 65(e) 73(s) 73(s) 20( ) 27(') 40(@) 27(') 0d 0a 2e(.) + 6.116381 1<-- 1: 2e(.) + 6.166489 1<-- 1: 2e(.) + 6.216642 1<-- 1: 2e(.) + 6.266846 1<-- 1: 2e(.) + 6.315690 -->1 1: 40(@) + 6.317352 1<-- 3: 0d 0a 40(@) + 6.320949 -->1 1: 6d(m) + 6.321695 1<-- 1: 6d(m) + 6.322652 -->1 1: 30(0) + 6.323409 1<-- 1: 30(0) + 6.327046 -->1 1: 32(2) + 6.327786 1<-- 1: 32(2) + 6.329665 -->1 1: 40(@) + 6.330409 1<-- 1: 40(@) + 6.331938 -->1 1: 66(f) + 6.332680 1<-- 1: 66(f) + 6.334616 -->1 1: 31(1) + 6.335351 1<-- 1: 31(1) + 6.337155 -->1 1: 32(2) + 6.337887 1<-- 1: 32(2) + 6.339546 -->1 1: 38(8) + 6.340351 1<-- 1: 38(8) + 6.341754 -->1 1: 0a + 6.443451 1<-- 4: 0d 0a 66(f) 3e(>) + 6.446139 -->1 1: 50(P) + 6.446150 -->1 1: 30(0) + 6.446163 -->1 1: 30(0) + 6.447236 -->1 1: 0c + 6.447242 -->1 1: 94 + 6.447258 -->1 9: bd 00 0c 94 da 00 0c 94 da + 6.447303 -->1 26: 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c + 6.447363 -->1 40: 94 da 00 0c 94 da 00 0c 94 00 03 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c + 6.447445 -->1 45: 94 38(8) 03 0c 94 da 00 55(U) 04 7f 04 8a 04 96 04 a6 04 b4 04 c3 04 d2 04 e3 04 ef 04 fd 04 0b 05 1a 05 26(&) 05 3f(?) 05 4b(K) 05 2b(+) 04 49(I) 04 6e(n) 61(a) + 6.447526 -->1 5: 6e(n) 00 69(i) 6e(n) 66(f) + + 7.049728 -->1 1: 50(P) + 7.049805 -->1 1: 30(0) + 7.049823 -->1 1: 30(0) + 7.050864 1<-- 3: 3d(=) 30(0) 30(0) + 7.050996 -->1 1: 0c + 7.051020 -->1 1: 94 + 7.051032 -->1 1: bd + 7.051077 -->1 3: 00 0c 94 + 7.051119 -->1 4: da 00 0c 94 + 7.051148 -->1 2: da 00 + 7.051203 -->1 8: 0c 94 da 00 0c 94 da 00 + 7.051248 -->1 7: 0c 94 da 00 0c 94 da + 7.051376 -->1 26: 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 00 03 0c 94 da 00 0c + 7.051409 -->1 4: 94 da 00 0c + 7.051500 -->1 16: 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c + 7.051548 -->1 8: 94 da 00 0c 94 38(8) 03 0c + 7.051613 -->1 12: 94 da 00 55(U) 04 7f 04 8a 04 96 04 a6 + 7.051665 -->1 8: 04 b4 04 c3 04 d2 04 e3 + 7.051725 -->1 11: 04 ef 04 fd 04 0b 05 1a 05 26(&) 05 + 7.051790 -->1 2: 3f(?) 05 + 7.051848 -->1 8: 4b(K) 05 2b(+) 04 49(I) 04 6e(n) 61(a) + 7.051897 -->1 5: 6e(n) 00 69(i) 6e(n) 66(f) + 7.062135 1<-- 13: 20( ) 38(8) 31(1) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + + + +7.072293 -->1 1: 50(P) + 7.072351 -->1 1: 30(0) + 7.072371 -->1 1: 31(1) + 7.073451 -->1 1: 00 + 7.073470 -->1 1: 40(@) + 7.073475 -->1 1: 7a(z) + 7.073512 -->1 34: 10 f3 5a(Z) 00 a0 72(r) 4e(N) 18 09 00 10 a5 d4 e8 00 00 e8 76(v) 48(H) 17 00 00 e4 0b 54(T) 02 00 00 ca 9a 3b(;) 00 00 00 + 7.073557 -->1 42: e1 f5 05 00 00 80 96 98 00 00 00 40(@) 42(B) 0f 00 00 00 a0 86 01 00 00 00 10 27(') 00 00 00 00 e8 03 00 00 00 00 64(d) 00 00 00 00 00 0a + 7.073638 -->1 48: 00 00 00 00 00 01 00 00 00 00 00 2c(,) 76(v) d8 88 dc 67(g) 4f(O) 08 23(#) df c1 df ae 59(Y) e1 b1 b7 96 e5 e3 e4 53(S) c6 3a(:) e6 51(Q) 99 76(v) 96 e8 e6 c2 84 26(&) eb 89 8c + 7.085477 1<-- 7: 3d(=) 30(0) 0c 0d 0a 66(f) 3e(>) + 7.089387 -->1 1: 50(P) + 7.090945 -->1 1: 30(0) + 7.090960 -->1 1: 31(1) + 7.092043 -->1 1: 00 + 7.092058 -->1 1: 40(@) + 7.092077 -->1 5: 7a(z) 10 f3 5a(Z) 00 + 7.092115 -->1 18: a0 72(r) 4e(N) 18 09 00 10 a5 d4 e8 00 00 e8 76(v) 48(H) 17 00 00 + 7.092166 -->1 23: e4 0b 54(T) 02 00 00 ca 9a 3b(;) 00 00 00 e1 f5 05 00 00 80 96 98 00 00 00 + 7.092243 -->1 35: 40(@) 42(B) 0f 00 00 00 a0 86 01 00 00 00 10 27(') 00 00 00 00 e8 03 00 00 00 00 64(d) 00 00 00 00 00 0a 00 00 00 00 + 7.092378 -->1 25: 00 01 00 00 00 00 00 2c(,) 76(v) d8 88 dc 67(g) 4f(O) 08 23(#) df c1 df ae 59(Y) e1 b1 b7 96 + 7.092476 -->1 19: e5 e3 e4 53(S) c6 3a(:) e6 51(Q) 99 76(v) 96 e8 e6 c2 84 26(&) eb 89 8c + 7.108808 1<-- 7: 3d(=) 10 00 0d 0a 66(f) 3e(>) + 7.116337 -->1 1: 50(P) + 7.116376 -->1 1: 30(0) + 7.116389 -->1 1: 31(1) + 7.117472 -->1 1: 00 + 7.117492 -->1 1: 40(@) + 7.117507 -->1 3: 7a(z) 10 f3 + 7.117558 -->1 17: 5a(Z) 00 a0 72(r) 4e(N) 18 09 00 10 a5 d4 e8 00 00 e8 76(v) 48(H) + 7.117603 -->1 15: 17 00 00 e4 0b 54(T) 02 00 00 ca 9a 3b(;) 00 00 00 + 7.117649 -->1 15: e1 f5 05 00 00 80 96 98 00 00 00 40(@) 42(B) 0f 00 + 7.117718 -->1 22: 00 00 a0 86 01 00 00 00 10 27(') 00 00 00 00 e8 03 00 00 00 00 64(d) 00 + 7.117789 -->1 21: 00 00 00 00 0a 00 00 00 00 00 01 00 00 00 00 00 2c(,) 76(v) d8 88 dc + 7.117864 -->1 25: 67(g) 4f(O) 08 23(#) df c1 df ae 59(Y) e1 b1 b7 96 e5 e3 e4 53(S) c6 3a(:) e6 51(Q) 99 76(v) 96 e8 + 7.117941 -->1 7: e6 c2 84 26(&) eb 89 8c + 7.132067 1<-- 7: 3d(=) 00 00 0d 0a 66(f) 3e(>) + 7.133848 -->1 1: 50(P) + 7.133855 -->1 1: 30(0) + 7.133873 -->1 1: 31(1) + 7.134931 -->1 1: 00 + 7.134960 -->1 1: 40(@) + 7.134972 -->1 1: 7a(z) + 7.134994 -->1 10: 10 f3 5a(Z) 00 a0 72(r) 4e(N) 18 09 00 + 7.135033 -->1 26: 10 a5 d4 e8 00 00 e8 76(v) 48(H) 17 00 00 e4 0b 54(T) 02 00 00 ca 9a 3b(;) 00 00 00 e1 f5 + 7.135086 -->1 37: 05 00 00 80 96 98 00 00 00 40(@) 42(B) 0f 00 00 00 a0 86 01 00 00 00 10 27(') 00 00 00 00 e8 03 00 00 00 00 64(d) 00 00 00 + 7.135170 -->1 51: 00 00 0a 00 00 00 00 00 01 00 00 00 00 00 2c(,) 76(v) d8 88 dc 67(g) 4f(O) 08 23(#) df c1 df ae 59(Y) e1 b1 b7 96 e5 e3 e4 53(S) c6 3a(:) e6 51(Q) 99 76(v) 96 e8 e6 c2 84 26(&) eb 89 8c + 7.155368 1<-- 7: 3d(=) 00 64(d) 0d 0a 66(f) 3e(>) + 7.157929 -->1 1: 50(P) + 7.157939 -->1 1: 30(0) + 7.157953 -->1 1: 31(1) + 7.159010 -->1 1: 00 + 7.159018 -->1 1: 40(@) + 7.159033 -->1 12: 7a(z) 10 f3 5a(Z) 00 a0 72(r) 4e(N) 18 09 00 10 + 7.159079 -->1 48: a5 d4 e8 00 00 e8 76(v) 48(H) 17 00 00 e4 0b 54(T) 02 00 00 ca 9a 3b(;) 00 00 00 e1 f5 05 00 00 80 96 98 00 00 00 40(@) 42(B) 0f 00 00 00 a0 86 01 00 00 00 10 27(') + 7.159141 -->1 62: 00 00 00 00 e8 03 00 00 00 00 64(d) 00 00 00 00 00 0a 00 00 00 00 00 01 00 00 00 00 00 2c(,) 76(v) d8 88 dc 67(g) 4f(O) 08 23(#) df c1 df ae 59(Y) e1 b1 b7 96 e5 e3 e4 53(S) c6 3a(:) e6 51(Q) 99 76(v) 96 e8 e6 c2 84 26(&) + 7.159288 -->1 3: eb 89 8c + 7.178629 1<-- 7: 3d(=) 64(d) 00 0d 0a 66(f) 3e(>) + 7.182071 -->1 1: 50(P) + 7.182120 -->1 1: 30(0) + 7.182133 -->1 1: 31(1) + 7.183221 -->1 1: 00 + 7.183227 -->1 1: 40(@) + 7.183247 -->1 23: 7a(z) 10 f3 5a(Z) 00 a0 72(r) 4e(N) 18 09 00 10 a5 d4 e8 00 00 e8 76(v) 48(H) 17 00 00 + 7.183290 -->1 40: e4 0b 54(T) 02 00 00 ca 9a 3b(;) 00 00 00 e1 f5 05 00 00 80 96 98 00 00 00 40(@) 42(B) 0f 00 00 00 a0 86 01 00 00 00 10 27(') 00 00 00 + 7.183374 -->1 62: 00 e8 03 00 00 00 00 64(d) 00 00 00 00 00 0a 00 00 00 00 00 01 00 00 00 00 00 2c(,) 76(v) d8 88 dc 67(g) 4f(O) 08 23(#) df c1 df ae 59(Y) e1 b1 b7 96 e5 e3 e4 53(S) c6 3a(:) e6 51(Q) 99 76(v) 96 e8 e6 c2 84 26(&) eb 89 8c + 7.201923 1<-- 7: 3d(=) 00 00 0d 0a 66(f) 3e(>) + 7.205091 -->1 1: 46(F) + 7.205130 -->1 1: 46(F) + 7.205146 -->1 1: 46(F) + 9.831366 1<-- + 9.831405 1<-- +^A + diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..a82abdc --- /dev/null +++ b/build.xml @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- You may freely edit this file. See commented blocks below for --> +<!-- some examples of how to customize the build. --> +<!-- (If you delete it and reopen the project it will be recreated.) --> +<!-- By default, only the Clean and Build commands use this build script. --> +<!-- Commands such as Run, Debug, and Test only use this build script if --> +<!-- the Compile on Save feature is turned off for the project. --> +<!-- You can turn off the Compile on Save (or Deploy on Save) setting --> +<!-- in the project's Project Properties dialog box.--> +<project name="easyprogrammer" default="default" basedir="."> + <description>Builds, tests, and runs the project easyprogrammer.</description> + <import file="nbproject/build-impl.xml"/> + <!-- + + There exist several targets which are by default empty and which can be + used for execution of your tasks. These targets are usually executed + before and after some main targets. They are: + + -pre-init: called before initialization of project properties + -post-init: called after initialization of project properties + -pre-compile: called before javac compilation + -post-compile: called after javac compilation + -pre-compile-single: called before javac compilation of single file + -post-compile-single: called after javac compilation of single file + -pre-compile-test: called before javac compilation of JUnit tests + -post-compile-test: called after javac compilation of JUnit tests + -pre-compile-test-single: called before javac compilation of single JUnit test + -post-compile-test-single: called after javac compilation of single JUunit test + -pre-jar: called before JAR building + -post-jar: called after JAR building + -post-clean: called after cleaning build products + + (Targets beginning with '-' are not intended to be called on their own.) + + Example of inserting an obfuscator after compilation could look like this: + + <target name="-post-compile"> + <obfuscate> + <fileset dir="${build.classes.dir}"/> + </obfuscate> + </target> + + For list of available properties check the imported + nbproject/build-impl.xml file. + + + Another way to customize the build is by overriding existing main targets. + The targets of interest are: + + -init-macrodef-javac: defines macro for javac compilation + -init-macrodef-junit: defines macro for junit execution + -init-macrodef-debug: defines macro for class debugging + -init-macrodef-java: defines macro for class execution + -do-jar: JAR building + run: execution of project + -javadoc-build: Javadoc generation + test-report: JUnit report generation + + An example of overriding the target for project execution could look like this: + + <target name="run" depends="easyprogrammer-impl.jar"> + <exec dir="bin" executable="launcher.exe"> + <arg file="${dist.jar}"/> + </exec> + </target> + + Notice that the overridden target depends on the jar target and not only on + the compile target as the regular run target does. Again, for a list of available + properties which you can use, check the target you are overriding in the + nbproject/build-impl.xml file. + + --> + +<target name="-post-jar"> + <jar jarfile="dist/easyprogrammer-withJSSC.jar"> + <zipfileset src="${dist.jar}" excludes="META-INF/*" /> + <zipfileset src="dist/lib/jssc-2.8.0.jar" excludes="META-INF/*" /> + <!--<fileset dir="libs/windows"> + <include name="EasyProgrammer-*.dll" /> + </fileset> --> + <manifest> + <attribute name="Main-Class" value="at.htlkaindorf.sx.EasyProgrammer.gui.EasyProgrammer"/> + </manifest> + </jar> + <move file="dist/easyprogrammer-withJSSC.jar" tofile="dist/easyprogrammer.jar" /> +</target> + +</project> diff --git a/good b/good new file mode 100644 index 0000000..c627206 --- /dev/null +++ b/good @@ -0,0 +1,178 @@ + 0.000000 1<-- + 0.000037 1<-- + 4.933322 1<-- 72: 0d 0a 42(B) 6f(o) 6f(o) 74(t) 6c(l) 6f(o) 61(a) 64(d) 65(e) 72(r) 20( ) 56(V) 65(e) 72(r) 73(s) 69(i) 6f(o) 6e(n) 20( ) 32(2) 2e(.) 30(0) 35(5) 20( ) 5b([) 41(A) 74(t) 6d(m) 65(e) 67(g) 61(a) 31(1) 36(6) 2c(,) 32(2) 30(0) 31(1) 31(1) 2d(-) 30(0) 38(8) 2d(-) 32(2) 37(7) 2c(,) 53(S) 58(X) 5d(]) 20( ) 20( ) 20( ) 0d 0a 20( ) 2e(.) 2e(.) 2e(.) 20( ) 70(p) 72(r) 65(e) 73(s) 73(s) 20( ) 27(') 40(@) 27(') 0d 0a 2e(.) + 4.983453 1<-- 1: 2e(.) + 5.033634 1<-- 1: 2e(.) + 5.083828 1<-- 1: 2e(.) + 5.133950 1<-- 1: 2e(.) + 5.184144 1<-- 1: 2e(.) + 5.232408 -->1 1: 40(@) + 5.234632 1<-- 3: 0d 0a 40(@) + 5.244625 -->1 1: 6d(m) + 5.245416 1<-- 1: 6d(m) + 5.245800 -->1 1: 30(0) + 5.246553 1<-- 1: 30(0) + 5.246968 -->1 1: 32(2) + 5.247706 1<-- 1: 32(2) + 5.248286 -->1 1: 40(@) + 5.249038 1<-- 1: 40(@) + 5.249404 -->1 1: 66(f) + 5.250140 1<-- 1: 66(f) + 5.250562 -->1 1: 31(1) + 5.251308 1<-- 1: 31(1) + 5.254641 -->1 1: 32(2) + 5.255418 1<-- 1: 32(2) + 5.255888 -->1 1: 38(8) + 5.256633 1<-- 1: 38(8) + 5.257159 -->1 1: 0a + 5.358839 1<-- 4: 0d 0a 66(f) 3e(>) + + 5.360713 -->1 131: 50(P) 30(0) 30(0) 0c 94 bd 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 00 03 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 da 00 0c 94 38(8) 03 0c 94 da 00 55(U) 04 7f 04 8a 04 96 04 a6 04 b4 04 c3 04 d2 04 e3 04 ef 04 fd 04 0b 05 1a 05 26(&) 05 3f(?) 05 4b(K) 05 2b(+) 04 49(I) 04 6e(n) 61(a) 6e(n) 00 69(i) 6e(n) 66(f) 00 + 5.384545 1<-- 3: 3d(=) 30(0) 30(0) + 5.395798 1<-- 13: 20( ) 33(3) 31(1) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + + + + 5.396393 -->1 131: 50(P) 30(0) 31(1) 00 40(@) 7a(z) 10 f3 5a(Z) 00 a0 72(r) 4e(N) 18 09 00 10 a5 d4 e8 00 00 e8 76(v) 48(H) 17 00 00 e4 0b 54(T) 02 00 00 ca 9a 3b(;) 00 00 00 e1 f5 05 00 00 80 96 98 00 00 00 40(@) 42(B) 0f 00 00 00 a0 86 01 00 00 00 10 27(') 00 00 00 00 e8 03 00 00 00 00 64(d) 00 00 00 00 00 0a 00 00 00 00 00 01 00 00 00 00 00 2c(,) 76(v) d8 88 dc 67(g) 4f(O) 08 23(#) df c1 df ae 59(Y) e1 b1 b7 96 e5 e3 e4 53(S) c6 3a(:) e6 51(Q) 99 76(v) 96 e8 e6 c2 84 26(&) eb 89 8c 9b + 5.420156 1<-- 3: 3d(=) 30(0) 31(1) + 5.431492 1<-- 13: 20( ) 35(5) 30(0) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 5.432459 -->1 131: 50(P) 30(0) 32(2) 62(b) ed 40(@) 7c(|) 6f(o) fc ef bc 9c 9f 40(@) f2 ba a5 6f(o) a5 f4 90 05 5a(Z) 2a(*) f7 5c(\) 93 6b(k) 6c(l) f9 67(g) 6d(m) c1 1b fc e0 e4 0d 47(G) fe f5 20( ) e6 b5 00 d0 ed 90 2e(.) 03 00 94 35(5) 77(w) 05 00 80 84 1e 08 00 00 20( ) 4e(N) 0a 00 00 00 c8 0c 33(3) 33(3) 33(3) 33(3) 0f 98 6e(n) 12 83 11 41(A) ef 8d 21(!) 14 89 3b(;) e6 55(U) 16 cf fe e6 db 18 d1 84 4b(K) 38(8) 1b f7 7c(|) 1d 90 1d a4 bb e4 24($) 20( ) 32(2) 84 72(r) 5e(^) 22(") 81 00 c9 f1 24($) ec a1 e5 3d(=) 27(') 11 24($) 1f be cf e5 + 5.456243 1<-- 3: 3d(=) 30(0) 32(2) + 5.467552 1<-- 13: 20( ) 46(F) 44(D) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 5.467953 -->1 131: 50(P) 30(0) 33(3) d4 e0 de bf cd bf 10 e0 a0 e6 b0 e0 e4 ed f6 e1 02 c0 05 90 0d 92 a0 3d(=) b1 07 d9 f7 11 e0 a0 ed b0 e0 01 c0 1d 92 ae 31(1) b1 07 e1 f7 0e 94 97 05 0c 94 68(h) 0b 0c 94 00 00 10 92 f1 00 10 92 f0 00 10 92 e0 00 08 95 cf 92 df 92 ef 92 ff 92 0f 93 1f 93 cf 93 df 93 00 d0 1f 92 cd b7 de b7 81 e0 0e 94 b2 02 88 23(#) 09 f4 55(U) c0 80 91 e0 00 86 30(0) 08 f4 50(P) c0 01 e0 10 e0 d1 2c(,) cc 24($) c3 94 81 ea + 5.491779 1<-- 3: 3d(=) 30(0) 33(3) + 5.503039 1<-- 13: 20( ) 35(5) 35(5) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 5.503766 -->1 131: 50(P) 30(0) 34(4) e8 2e(.) 80 e0 f8 2e(.) f8 01 ef 51(Q) ff 4f(O) 80 81 d8 0e 1f 92 df 92 1f 92 8f 93 ff 92 ef 92 0e 94 99 0a c3 94 0c 2d(-) 10 e0 80 91 e0 00 90 e0 04 97 0f 90 0f 90 0f 90 0f 90 0f 90 0f 90 08 17 19 07 1c f3 d1 94 1f 92 df 92 8f ea 90 e0 9f 93 8f 93 1f 92 83 e0 8f 93 ae 01 4f(O) 5f(_) 5f(_) 4f(O) 7a(z) 01 ff 92 4f(O) 93 0e 94 da 0a c7 01 0e 94 ad 0a f8 01 ef 51(Q) ff 4f(O) 20( ) 81 30(0) e0 89 81 99 27(') 87 fd 90 95 0f b6 f8 94 + 5.527593 1<-- 3: 3d(=) 30(0) 34(4) + 5.538906 1<-- 13: 20( ) 37(7) 30(0) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 5.539438 -->1 131: 50(P) 30(0) 35(5) de bf 0f be cd bf 28(() 17 39(9) 07 81 f0 8b eb 90 e0 0e 94 ad 0a 0f 90 0f 90 0f 90 df 91 cf 91 1f 91 0f 91 ff 90 ef 90 df 90 cf 90 08 95 21(!) 81 30(0) e0 8a 81 99 27(') 87 fd 90 95 28(() 17 39(9) 07 39(9) f7 84 eb 90 e0 0e 94 ad 0a e6 cf 0c 94 07 04 08 95 08 95 08 95 08 95 08 95 08 95 8b b3 91 e0 89 27(') 8b bb 08 95 8a 33(3) e9 f0 e0 91 e0 00 ef 30(0) 60(`) f0 10 92 e0 00 80 91 f1 00 8f 3f(?) 91 f0 80 91 f1 00 8f 5f(_) + 5.563221 1<-- 3: 3d(=) 30(0) 35(5) + 5.574500 1<-- 13: 20( ) 31(1) 31(1) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 5.575421 -->1 131: 50(P) 30(0) 36(6) 80 93 f1 00 08 95 ee 23(#) 51(Q) f0 91 e0 9e 0f 90 93 e0 00 f0 e0 ef 51(Q) ff 4f(O) 80 83 8a 30(0) 39(9) f0 08 95 91 e0 90 93 e0 00 80 93 e1 00 08 95 83 e0 0e 94 f3 02 81 e0 0c 94 98 02 90 91 f6 00 80 91 f5 00 98 17 91 f0 e0 91 f5 00 81 e0 8e 0f 80 93 f5 00 f0 e0 ee 50(P) ff 4f(O) 86 81 90 91 f5 00 90 31(1) 10 f0 10 92 f5 00 90 e0 08 95 8e ef 9f ef 08 95 5d(]) 9b fe cf 8c b9 99 27(') 87 fd 90 95 08 95 86 e1 e2 ef + 5.599228 1<-- 3: 3d(=) 30(0) 36(6) + 5.610517 1<-- 13: 20( ) 31(1) 36(6) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 5.611936 -->1 131: 50(P) 30(0) 37(7) f0 e0 df 01 1d 92 8a 95 e9 f7 bf e3 2e(.) e7 85 e0 b1 50(P) 20( ) 40(@) 80 40(@) e1 f7 00 c0 00 00 85 e9 8c bf 8a e0 83 bf 82 e0 89 bf 88 bf 8c e0 89 b9 10 bc 1b b8 86 e8 80 bd 88 e9 8a b9 8f e0 8b bb 18 ba 9f ef 9a bb 84 b3 8f 73(s) 84 bb 97 bb 8e e6 90 e0 90 93 1b 01 80 93 1a 01 80 e6 90 e0 90 93 19 01 80 93 18 01 08 95 08 95 8f 3f(?) 11 f0 8f 5f(_) 08 95 8f ef 08 95 8f 3f(?) 2f(/) ef 92 07 11 f0 01 96 08 95 + 5.635748 1<-- 3: 3d(=) 30(0) 37(7) + 5.647015 1<-- 13: 20( ) 36(6) 32(2) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 5.647829 -->1 131: 50(P) 30(0) 38(8) 8f ef 9f ef 08 95 fc 01 86 2f(/) 90 81 9f 3f(?) 19 f0 9f 5f(_) 90 83 08 95 9f ef 90 83 08 95 fc 01 86 2f(/) 20( ) 81 31(1) 81 2f(/) 3f(?) 9f ef 39(9) 07 29()) f0 2f(/) 5f(_) 3f(?) 4f(O) 31(1) 83 20( ) 83 08 95 2f(/) ef 3f(?) ef 31(1) 83 20( ) 83 08 95 80 91 f2 00 87 ff 08 95 78(x) 94 08 95 e2 ef f0 e0 90 81 8f b7 80 78(x) 89 2b(+) 80 83 f8 94 08 95 8d ec 90 e0 9f 93 8f 93 0e 94 99 0a 0f 90 0f 90 08 95 90 91 f6 00 80 91 f5 00 98 17 38(8) f4 80 91 f6 00 + 5.671620 1<-- 3: 3d(=) 30(0) 38(8) + 5.682916 1<-- 13: 20( ) 45(E) 34(4) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 5.683818 -->1 131: 50(P) 30(0) 39(9) 90 91 f5 00 80 5f(_) 89 1b 08 95 80 91 f6 00 90 91 f5 00 89 1b 08 95 20( ) 91 f2 00 9f b7 90 78(x) 92 2b(+) 90 93 f2 00 f8 94 20( ) 91 f6 00 90 91 f5 00 29()) 17 b0 f0 90 91 f6 00 20( ) 91 f5 00 92 1b 89 17 d0 f4 e0 91 f5 00 e8 0f e0 31(1) 88 f4 f0 e0 ee 50(P) ff 4f(O) 86 81 90 e0 20( ) 91 f2 00 27(') fd 0a c0 08 95 90 91 f6 00 20( ) 91 f5 00 90 5f(_) 92 1b e8 cf e0 51(Q) ed cf 78(x) 94 08 95 8f ef 9f ef ed cf 90 91 f2 00 8f b7 + 5.707632 1<-- 3: 3d(=) 30(0) 39(9) + 5.718882 1<-- 13: 20( ) 31(1) 30(0) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 5.719451 -->1 131: 50(P) 30(0) 41(A) 80 78(x) 89 2b(+) 80 93 f2 00 f8 94 5f(_) 9b 05 c0 8c b1 80 93 f7 00 5f(_) 99 fb cf 10 92 f5 00 10 92 f6 00 10 92 f7 00 80 91 f2 00 87 ff 08 95 78(x) 94 08 95 20( ) 91 f2 00 9f b7 90 78(x) 92 2b(+) 90 93 f2 00 f8 94 90 91 f4 00 98 23(#) 21(!) e0 09 f4 20( ) e0 90 91 f4 00 98 2b(+) 90 93 f4 00 80 91 f2 00 87 ff 01 c0 78(x) 94 82 2f(/) 08 95 20( ) 91 f2 00 9f b7 90 78(x) 92 2b(+) 90 93 f2 00 f8 94 20( ) 91 f4 00 28(() 23(#) 31(1) e0 09 f4 30(0) e0 + 5.743235 1<-- 3: 3d(=) 30(0) 41(A) + 5.754527 1<-- 13: 20( ) 43(C) 39(9) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 5.755015 -->1 131: 50(P) 30(0) 42(B) 20( ) 91 f4 00 98 2f(/) 90 95 92 23(#) 90 93 f4 00 80 91 f2 00 87 ff 01 c0 78(x) 94 83 2f(/) 08 95 90 91 f4 00 98 23(#) 81 e0 09 f4 80 e0 08 95 81 11 04 c0 8f e0 8b bb 18 ba 08 95 80 ef 8b bb 8f ef 88 bb 08 95 84 30(0) 60(`) f4 9b b3 21(!) e0 30(0) e0 08 2e(.) 01 c0 22(") 0f 0a 94 ea f7 61(a) 11 03 c0 92 2b(+) 9b bb 08 95 20( ) 95 29()) 23(#) 2b(+) bb 08 95 84 30(0) 50(P) f4 9b b3 21(!) e0 30(0) e0 08 2e(.) 01 c0 22(") 0f 0a 94 ea f7 92 27(') 9b bb 08 95 + 5.778818 1<-- 3: 3d(=) 30(0) 42(B) + 5.790092 1<-- 13: 20( ) 44(D) 42(B) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 5.791478 -->1 131: 50(P) 30(0) 43(C) 1f 92 0f 92 0f b6 0f 92 11 24($) 2f(/) 93 3f(?) 93 4f(O) 93 5f(_) 93 6f(o) 93 7f 93 8f 93 9f 93 af 93 bf 93 ef 93 ff 93 8c b1 82 35(5) 21(!) f4 90 91 d3 00 90 34(4) a9 f0 80 93 d3 00 0e 94 71(q) 01 ff 91 ef 91 bf 91 af 91 9f 91 8f 91 7f 91 6f(o) 91 5f(_) 91 4f(O) 91 3f(?) 91 2f(/) 91 0f 90 0f be 0f 90 1f 90 18 95 28(() e0 88 e1 90 e0 0f b6 f8 94 a8 95 81 bd 0f be 21(!) bd a8 95 ff cf 1f 92 0f 92 0f b6 0f 92 11 24($) 2f(/) 93 3f(?) 93 4f(O) 93 + 5.815284 1<-- 3: 3d(=) 30(0) 43(C) + 5.826542 1<-- 13: 20( ) 34(4) 36(6) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 5.827825 -->1 131: 50(P) 30(0) 44(D) 5f(_) 93 6f(o) 93 7f 93 8f 93 9f 93 af 93 bf 93 ef 93 ff 93 80 91 d2 00 8f 5f(_) 85 30(0) e0 f1 10 92 d2 00 80 91 d1 00 8f 5f(_) 80 93 d1 00 80 91 d0 00 88 23(#) c1 f0 80 91 f3 00 8f 3f(?) c1 f1 8f 5f(_) 80 93 f3 00 ff 91 ef 91 bf 91 af 91 9f 91 8f 91 7f 91 6f(o) 91 5f(_) 91 4f(O) 91 3f(?) 91 2f(/) 91 0f 90 0f be 0f 90 1f 90 18 95 81 e0 80 93 d0 00 78(x) 94 80 91 d1 00 80 fd 19 c0 81 fd 12 c0 82 fd 1d c0 83 fd 1e c0 84 fd + 5.851633 1<-- 3: 3d(=) 30(0) 44(D) + 5.862906 1<-- 13: 20( ) 31(1) 30(0) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 5.863836 -->1 131: 50(P) 30(0) 45(E) 1f c0 85 fd 14 c0 86 fd 1e c0 87 ff 08 c0 0e 94 6c(l) 01 05 c0 80 93 d2 00 d3 cf 0e 94 66(f) 01 10 92 d0 00 ce cf 0e 94 64(d) 01 fa cf 8f ef c7 cf 0e 94 6a(j) 01 f5 cf 0e 94 67(g) 01 f2 cf 0e 94 68(h) 01 ef cf 0e 94 69(i) 01 ec cf 0e 94 6b(k) 01 e9 cf 80 e1 e8 e0 f1 e0 df 01 1d 92 8a 95 e9 f7 16 be 82 e1 80 b9 81 e0 81 b9 84 e0 86 bf 08 95 08 95 f8 94 80 91 0c 01 90 91 0d 01 8f 3b(;) 9f 47(G) 54(T) f4 80 91 0c 01 + 5.887642 1<-- 3: 3d(=) 30(0) 45(E) + 5.898930 1<-- 13: 20( ) 39(9) 32(2) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 5.899815 -->1 131: 50(P) 30(0) 46(F) 90 91 0d 01 80 5c(\) 9f 4f(O) 90 93 0d 01 80 93 0c 01 78(x) 94 08 95 f8 94 80 91 0c 01 90 91 0d 01 81 34(4) 90 48(H) 54(T) f0 80 91 0c 01 90 91 0d 01 80 54(T) 91 09 90 93 0d 01 80 93 0c 01 78(x) 94 08 95 f8 94 90 93 0d 01 80 93 0c 01 78(x) 94 08 95 f8 94 80 91 0c 01 90 91 0d 01 78(x) 94 08 95 f8 94 20( ) 91 10 01 30(0) 91 11 01 80 91 0c 01 90 91 0d 01 aa 27(') 97 fd a0 95 ba 2f(/) 82 0f 93 1f a1 1d b1 1d 81 15 20( ) e8 92 07 + 5.923582 1<-- 3: 3d(=) 30(0) 46(F) + 5.934886 1<-- 13: 20( ) 35(5) 31(1) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 5.936182 -->1 131: 50(P) 31(1) 30(0) a1 05 b1 05 14 f0 8f ef 9f e7 78(x) 94 08 95 21(!) b1 28(() 7f 80 91 0a 01 90 91 0b 01 89 2b(+) 49(I) f0 80 91 0a 01 90 91 0b 01 01 97 90 93 0b 01 80 93 0a 01 80 91 08 01 90 91 09 01 82 31(1) 91 05 38(8) f0 81 e0 90 e0 90 93 09 01 80 93 08 01 08 95 fc 01 e6 5d(]) ff 4f(O) 0c 94 73(s) 09 80 91 d5 00 81 60(`) 80 93 d5 00 0e 94 26(&) 02 8a e0 e5 ed f0 e0 ae e0 b1 e0 01 90 0d 92 8a 95 e1 f7 0e 94 20( ) 02 84 e9 86 bf 81 e1 + 5.959957 1<-- 3: 3d(=) 31(1) 30(0) + 5.971249 1<-- 13: 20( ) 41(A) 34(4) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 5.972064 -->1 131: 50(P) 31(1) 31(1) 90 e0 90 93 09 01 80 93 08 01 84 e6 80 93 d4 00 08 95 80 91 d4 00 81 50(P) 80 93 d4 00 81 11 d5 cf 10 92 09 01 10 92 08 01 08 95 82 e0 90 e0 90 93 09 01 80 93 08 01 10 92 df 00 20( ) 91 d5 00 2e(.) 7f 20( ) 93 d5 00 30(0) 91 0e 01 36(6) 95 40(@) 91 0f 01 47(G) 95 44(D) 27(') 47(G) 95 84 2f(/) 83 2b(+) 30(0) 91 0f 01 93 2f(/) 96 95 01 96 38(8) 2f(/) 33(3) 0f 21(!) 70(p) 23(#) 2b(+) 20( ) 93 d5 00 99 0f 88 1f 88 27(') 88 1f 89 2b(+) 80 93 d6 00 08 95 8a ef + 5.995871 1<-- 3: 3d(=) 31(1) 31(1) + 6.007135 1<-- 13: 20( ) 38(8) 32(2) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.008641 -->1 131: 50(P) 31(1) 32(2) 90 e0 90 93 0b 01 80 93 0a 01 10 92 09 01 10 92 08 01 08 95 84 ea 86 bf 83 e0 90 e0 90 93 09 01 80 93 08 01 8a e0 80 93 d4 00 08 95 80 91 d4 00 81 50(P) 80 93 d4 00 28(() 30(0) 11 f0 20( ) 31(1) 01 f5 84 e0 90 e0 90 93 09 01 80 93 08 01 08 95 80 e9 83 b9 84 e8 86 bf 85 e0 90 e0 90 93 09 01 80 93 08 01 8a e0 80 93 d4 00 08 95 80 91 d4 00 81 50(P) 80 93 d4 00 28(() 31(1) 09 f4 cd c0 20( ) 32(2) 09 f4 60(`) cf 88 23(#) + 6.032429 1<-- 3: 3d(=) 31(1) 32(2) + 6.043722 1<-- 13: 20( ) 37(7) 30(0) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.044085 -->1 131: 50(P) 31(1) 33(3) 09 f4 5d(]) cf 08 95 80 91 df 00 83 b9 84 e8 86 bf 8a e0 80 93 d4 00 87 e0 90 e0 90 93 09 01 80 93 08 01 08 95 80 91 d4 00 81 50(P) 80 93 d4 00 28(() 32(2) 09 f4 a8 c0 20( ) 32(2) 19 f7 87 e0 90 e0 90 93 09 01 80 93 08 01 08 95 84 ea 86 bf 89 e0 90 e0 90 93 09 01 80 93 08 01 8a e0 80 93 d4 00 08 95 80 91 d4 00 81 50(P) 80 93 d4 00 20( ) 31(1) 49(I) f6 8a e0 90 e0 90 93 09 01 80 93 08 01 08 95 81 e9 83 b9 84 e8 + 6.067882 1<-- 3: 3d(=) 31(1) 33(3) + 6.079153 1<-- 13: 20( ) 45(E) 45(E) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.079542 -->1 131: 50(P) 31(1) 34(4) 86 bf 8b e0 90 e0 90 93 09 01 80 93 08 01 8a e0 80 93 d4 00 08 95 80 91 d4 00 81 50(P) 80 93 d4 00 20( ) 34(4) 09 f4 5b([) c0 28(() 33(3) 09 f4 09 cf 28(() 34(4) 09 f0 a6 cf 05 cf 84 ec 86 bf 8d e0 90 e0 90 93 09 01 80 93 08 01 8a e0 80 93 d4 00 08 95 80 91 d4 00 81 50(P) 80 93 d4 00 20( ) 35(5) 09 f0 91 cf 83 b1 e0 91 df 00 f0 e0 ee 0f ff 1f e9 52(R) ff 4f(O) 10 82 81 83 8e e0 90 e0 90 93 09 01 80 93 08 01 08 95 84 e8 + 6.103322 1<-- 3: 3d(=) 31(1) 34(4) + 6.114599 1<-- 13: 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.115339 -->1 131: 50(P) 31(1) 35(5) 86 bf 8f e0 90 e0 90 93 09 01 80 93 08 01 8a e0 80 93 d4 00 08 95 80 91 d4 00 81 50(P) 80 93 d4 00 28(() 35(5) 09 f0 6c(l) cf 20( ) 91 df 00 e2 2f(/) f0 e0 33(3) b1 ee 0f ff 1f e9 52(R) ff 4f(O) 80 81 91 81 83 2b(+) 91 83 80 83 81 e0 82 0f 80 93 df 00 84 30(0) 48(H) f5 82 e0 90 e0 90 93 09 01 80 93 08 01 08 95 80 91 df 00 e8 2f(/) f0 e0 ee 0f ff 1f e9 52(R) ff 4f(O) 11 82 10 82 81 30(0) 09 f4 bd cf 8c e0 90 e0 90 93 09 01 80 93 + 6.139197 1<-- 3: 3d(=) 31(1) 35(5) + 6.150484 1<-- 13: 20( ) 44(D) 44(D) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.151537 -->1 131: 50(P) 31(1) 36(6) 08 01 08 95 88 e0 90 e0 90 93 09 01 80 93 08 01 08 95 86 e0 90 e0 90 93 09 01 80 93 08 01 08 95 80 e1 90 e0 90 93 09 01 80 93 08 01 08 95 0e 94 be 01 0e 94 a6 03 0e 94 dc 00 8c e7 90 e0 9f 93 8f 93 85 e8 90 e0 9f 93 8f 93 81 e9 90 e0 9f 93 8f 93 85 ec 90 e0 9f 93 8f 93 0e 94 99 0a 0e 94 2f(/) 02 78(x) 94 8d b7 9e b7 08 96 0f b6 f8 94 9e bf 0f be 8d bf 0e 94 f3 01 0e 94 b5 03 0e 94 e3 00 + 6.175354 1<-- 3: 3d(=) 31(1) 36(6) + 6.186634 1<-- 13: 20( ) 36(6) 33(3) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.187466 -->1 131: 50(P) 31(1) 37(7) f9 cf a3 e1 b0 e0 e7 ec f5 e0 0c 94 3c(<) 09 7c(|) 01 1b 01 6a(j) 01 fc 01 17 82 16 82 83 81 81 ff 66(f) c3 be 01 6f(o) 5f(_) 7f 4f(O) 4b(K) 01 f7 01 93 81 f1 01 93 fd 85 91 93 ff 81 91 1f 01 88 23(#) 09 f4 53(S) c3 85 32(2) 39(9) f4 93 fd 85 91 93 ff 81 91 1f 01 85 32(2) 39(9) f4 b7 01 90 e0 0e 94 67(g) 0a 56(V) 01 65(e) 01 e5 cf 10 e0 51(Q) 2c(,) 20( ) e0 20( ) 32(2) a0 f4 8b 32(2) 69(i) f0 30(0) f4 80 32(2) 59(Y) f0 83 32(2) 69(i) f4 20( ) 61(a) 2c(,) c0 8d 32(2) 39(9) f0 80 33(3) + 6.211279 1<-- 3: 3d(=) 31(1) 37(7) + 6.222544 1<-- 13: 20( ) 39(9) 35(5) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.223978 -->1 131: 50(P) 31(1) 38(8) 39(9) f4 21(!) 60(`) 26(&) c0 22(") 60(`) 24($) 60(`) 23(#) c0 28(() 60(`) 21(!) c0 27(') fd 27(') c0 30(0) ed 38(8) 0f 3a(:) 30(0) 78(x) f4 26(&) ff 06 c0 fa e0 1f 9f 30(0) 0d 11 24($) 13 2f(/) 13 c0 6a(j) e0 56(V) 9e 30(0) 0d 11 24($) 53(S) 2e(.) 20( ) 62(b) 0c c0 8e 32(2) 21(!) f4 26(&) fd 11 c3 20( ) 64(d) 06 c0 8c 36(6) 11 f4 20( ) 68(h) 02 c0 88 36(6) 41(A) f4 f1 01 93 fd 85 91 93 ff 81 91 1f 01 81 11 c1 cf 9b eb 98 0f 93 30(0) 18 f4 20( ) 61(a) 80 5e(^) 06 c0 9b e9 98 0f 93 30(0) 08 f0 aa c1 2f(/) 7e(~) 26(&) ff 16 e0 + 6.247765 1<-- 3: 3d(=) 31(1) 38(8) + 6.259098 1<-- 13: 20( ) 38(8) 36(6) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.259952 -->1 131: 50(P) 31(1) 39(9) 2f(/) 73(s) 72(r) 2e(.) 85 36(6) 21(!) f4 f2 2f(/) f0 64(d) 7f 2e(.) 08 c0 86 36(6) 21(!) f4 62(b) 2f(/) 60(`) 68(h) 76(v) 2e(.) 02 c0 11 11 11 50(P) 77(w) fe 07 c0 1c 33(3) 48(H) f4 44(D) 24($) 43(C) 94 41(A) 0e 27(') e0 0b c0 18 30(0) 30(0) f4 21(!) 2f(/) 06 c0 27(') e0 4c(L) e3 44(D) 2e(.) 03 c0 27(') e0 17 e0 41(A) 2c(,) 56(V) 01 74(t) e0 a7 0e b1 1c f6 01 60(`) 81 71(q) 81 82 81 93 81 04 2d(-) a4 01 0e 94 79(y) 09 6c(l) 01 09 81 00 ff 02 c0 03 ff 06 c0 71(q) fc 07 c0 72(r) fc 08 c0 61(a) 2c(,) 08 c0 3d(=) e2 63(c) 2e(.) 05 c0 + 6.283748 1<-- 3: 3d(=) 31(1) 39(9) + 6.295040 1<-- 13: 20( ) 34(4) 41(A) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.296018 -->1 131: 50(P) 31(1) 41(A) 2b(+) e2 62(b) 2e(.) 02 c0 90 e2 69(i) 2e(.) 80 2f(/) 8c 70(p) 99 f1 66(f) 20( ) 11 f0 84 e0 01 c0 83 e0 85 15 10 f0 51(Q) 2c(,) 0b c0 58(X) 1a 73(s) fc 08 c0 b7 01 80 e2 90 e0 0e 94 67(g) 0a 5a(Z) 94 c9 f7 f3 cf 66(f) 20( ) 29()) f0 b7 01 86 2d(-) 90 e0 0e 94 67(g) 0a 03 fd 03 c0 0c e7 10 e0 02 c0 08 e7 10 e0 f7 2d(-) f0 71(q) 7f 2e(.) f8 01 84 91 88 23(#) 09 f4 76(v) c2 71(q) 10 80 52(R) b7 01 90 e0 0e 94 67(g) 0a 0f 5f(_) 1f 4f(O) f2 cf 77(w) fe 0f c0 4c(L) 0c 04 ff 04 c0 + 6.319825 1<-- 3: 3d(=) 31(1) 41(A) + 6.331064 1<-- 13: 20( ) 43(C) 36(6) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.331530 -->1 131: 50(P) 31(1) 42(B) 8a 81 81 33(3) 09 f4 4a(J) 94 14 14 74(t) f5 f8 e0 f4 15 78(x) f5 88 e0 48(H) 2e(.) 2c(,) c0 76(v) fc 2a(*) c0 81 2f(/) 90 e0 8c 15 9d 05 9c f0 6c(l) ef c6 16 6f(o) ef d6 06 74(t) f0 77(w) 2d(-) 70(p) 68(h) 77(w) 2e(.) 0a c0 e2 e0 f0 e0 ec 0f fd 1f e1 0f f1 1d 80 81 80 33(3) 19 f4 11 50(P) 11 11 f4 cf 77(w) fe 0e c0 44(D) 24($) 43(C) 94 41(A) 0e 81 2f(/) 90 e0 c8 16 d9 06 2c(,) f4 1c 19 04 c0 44(D) 24($) 43(C) 94 01 c0 10 e0 77(w) fe 07 c0 1c 14 1d 04 3c(<) f4 96 01 2f(/) 5f(_) 3f(?) 4f(O) + 6.355311 1<-- 3: 3d(=) 31(1) 42(B) + 6.366603 1<-- 13: 20( ) 32(2) 33(3) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.367325 -->1 131: 50(P) 31(1) 43(C) 05 c0 25(%) e0 30(0) e0 02 c0 21(!) e0 30(0) e0 66(f) 20( ) 11 f0 2f(/) 5f(_) 3f(?) 4f(O) 11 23(#) 31(1) f0 41(A) 2f(/) 50(P) e0 4f(O) 5f(_) 5f(_) 4f(O) 24($) 0f 35(5) 1f 45(E) 2d(-) 50(P) e0 24($) 17 35(5) 07 14 f4 52(R) 1a 01 c0 51(Q) 2c(,) 87 2d(-) 89 70(p) 49(I) f4 55(U) 20( ) 39(9) f0 b7 01 80 e2 90 e0 0e 94 67(g) 0a 5a(Z) 94 f7 cf 66(f) 20( ) 29()) f0 b7 01 86 2d(-) 90 e0 0e 94 67(g) 0a 73(s) fc 09 c0 55(U) 20( ) 39(9) f0 b7 01 80 e3 90 e0 0e 94 67(g) 0a 5a(Z) 94 f7 cf 77(w) fe 5f(_) c0 9c 2d(-) 8d 2d(-) d7 fe 02 c0 90 e0 80 e0 + 6.391199 1<-- 3: 3d(=) 31(1) 43(C) + 6.402468 1<-- 13: 20( ) 46(F) 46(F) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.403375 -->1 131: 50(P) 31(1) 44(D) 69(i) 2e(.) 78(x) 2e(.) 40(@) e0 50(P) e0 c6 01 84 19 91 09 9d 87 8c 87 96 01 26(&) 19 37(7) 09 28(() 0d 39(9) 1d 81 2f(/) 90 e0 ee 27(') ff 27(') e8 1b f9 0b ff 87 ee 87 ff ef 6f(o) 16 7f 06 69(i) f4 b7 01 8e e2 90 e0 2b(+) 8b 3a(:) 8b 48(H) 8b 59(Y) 8b 0e 94 67(g) 0a 59(Y) 89 48(H) 89 3a(:) 89 2b(+) 89 c6 14 d7 04 54(T) f0 6c(l) 85 7d(}) 85 66(f) 15 77(w) 05 2c(,) f4 f9 01 e4 0f f5 1f 81 81 01 c0 80 e3 71(q) e0 67(g) 1a 71(q) 08 4f(O) 5f(_) 5f(_) 4f(O) ee 85 ff 85 6e(n) 16 7f 06 6c(l) f0 b7 01 + 6.427193 1<-- 3: 3d(=) 31(1) 44(D) + 6.438514 1<-- 13: 20( ) 30(0) 31(1) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.439110 -->1 131: 50(P) 31(1) 45(E) 90 e0 2b(+) 8b 3a(:) 8b 48(H) 8b 59(Y) 8b 0e 94 67(g) 0a 2b(+) 89 3a(:) 89 48(H) 89 59(Y) 89 ca cf 6c(l) 14 7d(}) 04 39(9) f4 9a 81 96 33(3) 18 f4 95 33(3) 11 f4 04 ff 81 e3 b7 01 90 e0 4b(K) c0 8a 81 81 33(3) 09 f0 0f 7e(~) b7 01 90 e0 0e 94 67(g) 0a 11 11 05 c0 74(t) fe 18 c0 85 e4 90 e0 17 c0 b7 01 8e e2 90 e0 0e 94 67(g) 0a 82 e0 66(f) 24($) 63(c) 94 68(h) 0e f4 01 e8 0f f1 1d 80 81 b7 01 90 e0 0e 94 67(g) 0a 11 50(P) 41(A) f3 86 2d(-) f1 cf 85 e6 90 e0 b7 01 + 6.462928 1<-- 3: 3d(=) 31(1) 45(E) + 6.474205 1<-- 13: 20( ) 33(3) 33(3) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.474761 -->1 131: 50(P) 31(1) 46(F) 0e 94 67(g) 0a d7 fc 05 c0 c1 14 d1 04 39(9) f4 04 ff 05 c0 d1 94 c1 94 d1 08 8d e2 01 c0 8b e2 b7 01 90 e0 0e 94 67(g) 0a 80 e3 6a(j) e0 c6 16 d1 04 2c(,) f0 8f 5f(_) fa e0 cf 1a d1 08 f7 cf b7 01 90 e0 0e 94 67(g) 0a b7 01 c6 01 c0 96 0e 94 67(g) 0a 41(A) c1 83 36(6) 31(1) f0 83 37(7) 79(y) f0 83 35(5) 09 f0 58(X) c0 21(!) c0 56(V) 01 72(r) e0 a7 0e b1 1c f6 01 80 81 89 83 01 e0 10 e0 64(d) 01 14 c0 56(V) 01 f2 e0 af 0e b1 1c f6 01 c0 80 + 6.498561 1<-- 3: 3d(=) 31(1) 46(F) + 6.509854 1<-- 13: 20( ) 36(6) 45(E) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.510369 -->1 131: 50(P) 32(2) 30(0) d1 80 26(&) ff 03 c0 61(a) 2f(/) 70(p) e0 02 c0 6f(o) ef 7f ef c6 01 2b(+) 8b 0e 94 5c(\) 0a 8c 01 2b(+) 89 2f(/) 77(w) 15 c0 56(V) 01 f2 e0 af 0e b1 1c f6 01 c0 80 d1 80 26(&) ff 03 c0 61(a) 2f(/) 70(p) e0 02 c0 6f(o) ef 7f ef c6 01 2b(+) 8b 0e 94 51(Q) 0a 8c 01 2b(+) 89 20( ) 68(h) 72(r) 2e(.) 23(#) fd 1a c0 85 2d(-) 90 e0 08 17 19 07 a8 f4 b7 01 80 e2 90 e0 0e 94 67(g) 0a 5a(Z) 94 f4 cf f6 01 77(w) fc 85 91 77(w) fe 81 91 6f(o) 01 b7 01 90 e0 0e 94 67(g) 0a 51(Q) 10 5a(Z) 94 + 6.534187 1<-- 3: 3d(=) 32(2) 30(0) + 6.545496 1<-- 13: 20( ) 41(A) 32(2) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.546344 -->1 131: 50(P) 32(2) 31(1) 01 50(P) 11 09 01 15 11 05 79(y) f7 e2 c0 84 36(6) 11 f0 89 36(6) 51(Q) f5 56(V) 01 27(') ff 09 c0 f4 e0 af 0e b1 1c f6 01 60(`) 81 71(q) 81 82 81 93 81 0a c0 f2 e0 af 0e b1 1c f6 01 60(`) 81 71(q) 81 88 27(') 77(w) fd 80 95 98 2f(/) 02 2f(/) 0f 76(v) 97 ff 08 c0 90 95 80 95 70(p) 95 61(a) 95 7f 4f(O) 8f 4f(O) 9f 4f(O) 00 68(h) 2a(*) e0 30(0) e0 a4 01 0e 94 0a 0b c8 2e(.) c8 18 3e(>) c0 02 2f(/) 85 37(7) 21(!) f4 0f 7e(~) 2a(*) e0 30(0) e0 1d c0 09 7f 8f 36(6) 91 f0 18 f4 88 35(5) + 6.570194 1<-- 3: 3d(=) 32(2) 31(1) + 6.581492 1<-- 13: 20( ) 38(8) 46(F) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.582275 -->1 131: 50(P) 32(2) 32(2) 59(Y) f0 b0 c0 80 37(7) 19 f0 88 37(7) 11 f0 ab c0 00 61(a) 04 ff 09 c0 04 60(`) 07 c0 24($) ff 08 c0 06 60(`) 06 c0 28(() e0 30(0) e0 05 c0 20( ) e1 30(0) e0 02 c0 20( ) e1 32(2) e0 56(V) 01 07 ff 09 c0 f4 e0 af 0e b1 1c f6 01 60(`) 81 71(q) 81 82 81 93 81 08 c0 f2 e0 af 0e b1 1c f6 01 60(`) 81 71(q) 81 80 e0 90 e0 a4 01 0e 94 0a 0b c8 2e(.) c8 18 0f 77(w) 06 ff 0b c0 20( ) 2f(/) 2e(.) 7f c1 16 50(P) f4 04 ff 0a c0 02 fd 08 c0 20( ) 2f(/) 2e(.) 7e(~) 05 c0 dc 2c(,) + 6.606080 1<-- 3: 3d(=) 32(2) 32(2) + 6.617361 1<-- 13: 20( ) 46(F) 34(4) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.618049 -->1 131: 50(P) 32(2) 33(3) 20( ) 2f(/) 03 c0 dc 2c(,) 01 c0 d1 2e(.) 24($) ff 0d c0 fe 01 ec 0d f1 1d 80 81 80 33(3) 11 f4 29()) 7e(~) 09 c0 22(") ff 06 c0 d3 94 d3 94 04 c0 82 2f(/) 86 78(x) 09 f0 d3 94 23(#) fd 13 c0 20( ) ff 06 c0 1c 2d(-) d5 14 18 f4 15 0d 1d 19 d5 2c(,) d5 14 68(h) f4 b7 01 80 e2 90 e0 2b(+) 8b 0e 94 67(g) 0a d3 94 2b(+) 89 f5 cf d5 14 10 f4 5d(]) 18 01 c0 51(Q) 2c(,) 24($) ff 12 c0 b7 01 80 e3 90 e0 2b(+) 8b 0e 94 67(g) 0a 2b(+) 89 22(") ff 17 c0 21(!) ff 03 c0 88 e5 + 6.641870 1<-- 3: 3d(=) 32(2) 33(3) + 6.653120 1<-- 13: 20( ) 34(4) 43(C) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.653953 -->1 131: 50(P) 32(2) 34(4) 90 e0 02 c0 88 e7 90 e0 b7 01 0c c0 82 2f(/) 86 78(x) 59(Y) f0 21(!) fd 02 c0 80 e2 01 c0 8b e2 27(') fd 8d e2 b7 01 90 e0 0e 94 67(g) 0a c1 16 38(8) f4 b7 01 80 e3 90 e0 0e 94 67(g) 0a 11 50(P) f7 cf ca 94 f4 01 ec 0d f1 1d 80 81 b7 01 90 e0 0e 94 67(g) 0a c1 10 f5 cf 55(U) 20( ) 09 f4 c2 cc b7 01 80 e2 90 e0 0e 94 67(g) 0a 5a(Z) 94 f6 cf f7 01 86 81 97 81 02 c0 8f ef 9f ef 63(c) 96 e2 e1 0c 94 58(X) 09 2f(/) 92 3f(?) 92 4f(O) 92 5f(_) 92 + 6.677750 1<-- 3: 3d(=) 32(2) 34(4) + 6.689043 1<-- 13: 20( ) 31(1) 34(4) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.689453 -->1 131: 50(P) 32(2) 35(5) 6f(o) 92 7f 92 8f 92 9f 92 af 92 bf 92 cf 92 df 92 ef 92 ff 92 0f 93 1f 93 cf 93 df 93 cd b7 de b7 ca 1b db 0b 0f b6 f8 94 de bf 0f be cd bf 09 94 2a(*) 88 39(9) 88 48(H) 88 5f(_) 84 6e(n) 84 7d(}) 84 8c 84 9b 84 aa 84 b9 84 c8 84 df 80 ee 80 fd 80 0c 81 1b 81 aa 81 b9 81 ce 0f d1 1d 0f b6 f8 94 de bf 0f be cd bf ed 01 08 95 ee 0f ff 1f 05 90 f4 91 e0 2d(-) 09 94 28(() 30(0) 08 f0 27(') e0 33(3) 27(') da 01 99 0f 31(1) 1d + 6.713262 1<-- 3: 3d(=) 32(2) 35(5) + 6.724558 1<-- 13: 20( ) 39(9) 46(F) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.725378 -->1 131: 50(P) 32(2) 36(6) 87 fd 91 60(`) 00 96 61(a) 05 71(q) 05 39(9) f4 32(2) 60(`) 2e(.) 5f(_) 3d(=) 93 30(0) e3 2a(*) 95 e1 f7 08 95 9f 3f(?) 30(0) f0 80 38(8) 71(q) 05 61(a) 05 09 f0 3c(<) 5f(_) 3c(<) 5f(_) 3d(=) 93 91 30(0) 08 f0 80 68(h) 91 1d df 93 cf 93 1f 93 0f 93 ff 92 ef 92 19 2f(/) 98 7f 96 95 e9 2f(/) 96 95 96 95 e9 0f ff 27(') e6 52(R) ff 4f(O) 99 27(') 33(3) 27(') ee 24($) ff 24($) a7 01 e7 01 05 90 08 94 07 94 28(() f4 36(6) 0f e7 1e f8 1e 49(I) 1f 51(Q) 1d 66(f) 0f 77(w) 1f 88 1f 99 1f 06 94 a1 f7 05 90 + 6.749208 1<-- 3: 3d(=) 32(2) 36(6) + 6.760478 1<-- 13: 20( ) 32(2) 45(E) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.761002 -->1 131: 50(P) 32(2) 37(7) 07 94 28(() f4 e7 0e f8 1e 49(I) 1f 56(V) 1f c1 1d 77(w) 0f 88 1f 99 1f 66(f) 1f 06 94 a1 f7 05 90 07 94 28(() f4 f8 0e 49(I) 1f 56(V) 1f c7 1f d1 1d 88 0f 99 1f 66(f) 1f 77(w) 1f 06 94 a1 f7 05 90 07 94 20( ) f4 49(I) 0f 56(V) 1f c7 1f d8 1f 99 0f 66(f) 1f 77(w) 1f 88 1f 06 94 a9 f7 84 91 10 95 17 70(p) 41(A) f0 d6 95 c7 95 57(W) 95 47(G) 95 f7 94 e7 94 1a 95 c1 f7 e0 e8 f0 e0 68(h) 94 15 90 15 91 35(5) 91 65(e) 91 95 91 05 90 7f e2 73(s) 95 e1 18 + 6.784776 1<-- 3: 3d(=) 32(2) 37(7) + 6.796079 1<-- 13: 20( ) 37(7) 30(0) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.796677 -->1 131: 50(P) 32(2) 38(8) f1 0a 43(C) 0b 56(V) 0b c9 0b d0 09 c0 f7 e1 0c f1 1e 43(C) 1f 56(V) 1f c9 1f d0 1d 7e(~) f4 70(p) 33(3) 11 f4 8a 95 e6 cf e8 94 01 50(P) 30(0) f0 08 0f 0a f4 00 27(') 02 17 08 f4 20( ) 2f(/) 23(#) 95 02 2f(/) 7a(z) 33(3) 28(() f0 79(y) e3 7d(}) 93 2a(*) 95 e9 f7 10 c0 7d(}) 93 2a(*) 95 89 f6 06 94 97 95 67(g) 95 37(7) 95 17 95 17 94 e1 18 f1 0a 43(C) 0b 56(V) 0b c9 0b d0 09 98 f0 23(#) 95 7e(~) 91 73(s) 95 7a(z) 33(3) 08 f0 70(p) e3 7c(|) 93 20( ) 13 b8 f7 7e(~) 91 70(p) 61(a) 7d(}) 93 30(0) f0 + 6.820485 1<-- 3: 3d(=) 32(2) 38(8) + 6.831781 1<-- 13: 20( ) 38(8) 44(D) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.832806 -->1 131: 50(P) 32(2) 39(9) 83 95 71(q) e3 7d(}) 93 70(p) e3 2a(*) 95 e1 f7 11 24($) ef 90 ff 90 0f 91 1f 91 cf 91 df 91 99 27(') 87 fd 90 95 08 95 fc 01 05 90 61(a) 50(P) 70(p) 40(@) 01 10 d8 f7 80 95 90 95 8e 0f 9f 1f 08 95 fc 01 61(a) 50(P) 70(p) 40(@) 01 90 01 10 d8 f7 80 95 90 95 8e 0f 9f 1f 08 95 0f 93 1f 93 cf 93 df 93 18 2f(/) 09 2f(/) eb 01 8b 81 81 fd 03 c0 8f ef 9f ef 20( ) c0 82 ff 10 c0 4e(N) 81 5f(_) 81 2c(,) 81 3d(=) 81 42(B) 17 53(S) 07 7c(|) f4 e8 81 f9 81 9f 01 + 6.856619 1<-- 3: 3d(=) 32(2) 39(9) + 6.867899 1<-- 13: 20( ) 42(B) 32(2) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.868354 -->1 131: 50(P) 32(2) 41(A) 2f(/) 5f(_) 3f(?) 4f(O) 39(9) 83 28(() 83 10 83 06 c0 e8 85 f9 85 81 2f(/) 09 95 89 2b(+) 29()) f7 2e(.) 81 3f(?) 81 2f(/) 5f(_) 3f(?) 4f(O) 3f(?) 83 2e(.) 83 81 2f(/) 90 2f(/) df 91 cf 91 1f 91 0f 91 08 95 a0 e0 b0 e0 ef e9 fa e0 0c 94 4c(L) 09 fe 01 35(5) 96 61(a) 91 71(q) 91 af 01 80 91 1a 01 90 91 1b 01 0e 94 c1 05 e2 e0 0c 94 68(h) 09 0f 93 1f 93 cf 93 df 93 e0 91 1a 01 f0 91 1b 01 23(#) 81 21(!) ff 1b c0 ec 01 00 e0 10 e0 89 91 60(`) 91 1a 01 70(p) 91 1b 01 + 6.892239 1<-- 3: 3d(=) 32(2) 41(A) + 6.903458 1<-- 13: 20( ) 43(C) 43(C) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.903869 -->1 131: 50(P) 32(2) 42(B) db 01 18 96 ed 91 fc 91 19 97 88 23(#) 31(1) f0 09 95 89 2b(+) 89 f3 0f ef 1f ef ee cf 8a e0 09 95 89 2b(+) 11 f4 c8 01 02 c0 8f ef 9f ef df 91 cf 91 1f 91 0f 91 08 95 ae e0 b0 e0 e0 ee fa e0 0c 94 4a(J) 09 0d 89 1e 89 8f 89 98 8d 26(&) e0 2c(,) 83 1a 83 09 83 97 ff 02 c0 80 e0 90 e8 01 97 9e 83 8d 83 ae 01 45(E) 5e(^) 5f(_) 4f(O) 69(i) 8d 7a(z) 8d ce 01 01 96 0e 94 c1 05 4d(M) 81 5e(^) 81 57(W) fd 0a c0 2f(/) 81 38(8) 85 42(B) 17 53(S) 07 + 6.927669 1<-- 3: 3d(=) 32(2) 42(B) + 6.938937 1<-- 13: 20( ) 37(7) 44(D) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.939784 -->1 131: 50(P) 32(2) 43(C) 0c f4 9a 01 f8 01 e2 0f f3 1f 10 82 2e(.) 96 e4 e0 0c 94 66(f) 09 fa 01 aa 27(') 28(() 30(0) 51(Q) f1 20( ) 31(1) 81 f1 e8 94 6f(o) 93 6e(n) 7f 6e(n) 5f(_) 7f 4f(O) 8f 4f(O) 9f 4f(O) af 4f(O) b1 e0 3e(>) d0 b4 e0 3c(<) d0 67(g) 0f 78(x) 1f 89 1f 9a 1f a1 1d 68(h) 0f 79(y) 1f 8a 1f 91 1d a1 1d 6a(j) 0f 71(q) 1d 81 1d 91 1d a1 1d 20( ) d0 09 f4 68(h) 94 3f(?) 91 2a(*) e0 26(&) 9f 11 24($) 30(0) 19 30(0) 5d(]) 31(1) 93 de f6 cf 01 08 95 46(F) 2f(/) 47(G) 70(p) 40(@) 5d(]) 41(A) 93 b3 e0 0f d0 c9 f7 f6 cf + 6.963608 1<-- 3: 3d(=) 32(2) 43(C) + 6.974900 1<-- 13: 20( ) 38(8) 35(5) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.975742 -->1 131: 50(P) 32(2) 44(D) 46(F) 2f(/) 4f(O) 70(p) 40(@) 5d(]) 4a(J) 33(3) 18 f0 49(I) 5d(]) 31(1) fd 40(@) 52(R) 41(A) 93 02 d0 a9 f7 ea cf b4 e0 a6 95 97 95 87 95 77(w) 95 67(g) 95 ba 95 c9 f7 00 97 61(a) 05 71(q) 05 08 95 9b 01 ac 01 0a 2e(.) 06 94 57(W) 95 47(G) 95 37(7) 95 27(') 95 ba 95 c9 f7 62(b) 0f 73(s) 1f 84 1f 95 1f a0 1d 08 95 f8 94 ff cf 00 00 00 01 00 00 00 00 00 00 9c 01 00 00 00 00 00 02 00 00 00 00 b7 01 00 00 00 00 31(1) 31(1) 3a(:) 33(3) 32(2) 3a(:) 31(1) 31(1) 00 46(F) 65(e) 62(b) 20( ) 32(2) 33(3) 20( ) + 6.999542 1<-- 3: 3d(=) 32(2) 44(D) + 7.010818 1<-- 13: 20( ) 32(2) 38(8) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 7.011360 -->1 131: 50(P) 32(2) 45(E) 32(2) 30(0) 31(1) 36(6) 00 0a 0d 49(I) 32(2) 43(C) 2d(-) 54(T) 65(e) 6d(m) 70(p) 20( ) 4d(M) 65(e) 61(a) 73(s) 00 25(%) 30(0) 32(2) 78(x) 20( ) 2d(-) 3e(>) 20( ) 25(%) 30(0) 32(2) 58(X) 0a 00 25(%) 30(0) 32(2) 58(X) 00 4c(L) 52(R) 43(C) 20( ) 4f(O) 4b(K) 00 4c(L) 52(R) 43(C) 20( ) 45(E) 72(r) 72(r) 6f(o) 72(r) 00 25(%) 73(s) 20( ) 25(%) 73(s) 20( ) 25(%) 73(s) 0a 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 7.035202 1<-- 3: 3d(=) 32(2) 45(E) + 7.046457 1<-- 13: 20( ) 33(3) 45(E) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 7.055935 -->1 1: 46(F) + 7.055945 -->1 1: 46(F) + 7.055960 -->1 1: 46(F) + 7.057064 1<-- 1: 58(X) + 7.314492 1<-- 40: 0a 0d 49(I) 32(2) 43(C) 2d(-) 54(T) 65(e) 6d(m) 70(p) 20( ) 4d(M) 65(e) 61(a) 73(s) 20( ) 46(F) 65(e) 62(b) 20( ) 32(2) 33(3) 20( ) 32(2) 30(0) 31(1) 36(6) 20( ) 31(1) 31(1) 3a(:) 33(3) 32(2) 3a(:) 31(1) 31(1) 0a 0d 0a 0d diff --git a/jssc-2.8.0.jar b/jssc-2.8.0.jar new file mode 100644 index 0000000..d2b5c07 Binary files /dev/null and b/jssc-2.8.0.jar differ diff --git a/manifest.mf b/manifest.mf new file mode 100644 index 0000000..328e8e5 --- /dev/null +++ b/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/measurements/2016-03-04-download-problem/logs b/measurements/2016-03-04-download-problem/logs new file mode 100644 index 0000000..5c119aa --- /dev/null +++ b/measurements/2016-03-04-download-problem/logs @@ -0,0 +1,44 @@ +INFO *13:24:27.539: bytes received, '' in buffer, continue checking pattern [at at.htlkaindorf.sx.EasyProgrammer.serial.Protocol.readResponseString(Protocol.java:282)] +FINER 13:24:27.539: response '=13 26 00 00<0d><0a>f>' received for flash page 13 [at at.htlkaindorf.sx.EasyProgrammer.serial.DownloadProtocol.writeAndCheckPage(DownloadProtocol.java:243)] +FINER 13:24:27.541: writing flash page 14 [at at.htlkaindorf.sx.EasyProgrammer.serial.DownloadProtocol.writeAndCheckPage(DownloadProtocol.java:220)] +INFO *13:24:27.541: waiting for pattern 'f>' [at at.htlkaindorf.sx.EasyProgrammer.serial.Protocol.readResponseString(Protocol.java:271)] +INFO *13:24:27.565: bytes received, '' in buffer, continue checking pattern [at at.htlkaindorf.sx.EasyProgrammer.serial.Protocol.readResponseString(Protocol.java:282)] +INFO *13:24:27.566: waiting for pattern 'f>' [at at.htlkaindorf.sx.EasyProgrammer.serial.Protocol.readResponseString(Protocol.java:271)] +INFO *13:24:27.576: bytes received, '' in buffer, continue checking pattern [at at.htlkaindorf.sx.EasyProgrammer.serial.Protocol.readResponseString(Protocol.java:282)] +FINER 13:24:27.576: writing flash page 14 [at at.htlkaindorf.sx.EasyProgrammer.serial.DownloadProtocol.writeAndCheckPage(DownloadProtocol.java:220)] +INFO *13:24:27.577: waiting for pattern 'f>' [at at.htlkaindorf.sx.EasyProgrammer.serial.Protocol.readResponseString(Protocol.java:271)] +INFO *13:24:27.607: bytes received, '' in buffer, continue checking pattern [at at.htlkaindorf.sx.EasyProgrammer.serial.Protocol.readResponseString(Protocol.java:282)] +FINER 13:24:27.607: writing flash page 14 [at at.htlkaindorf.sx.EasyProgrammer.serial.DownloadProtocol.writeAndCheckPage(DownloadProtocol.java:220)] +INFO *13:24:27.608: waiting for pattern 'f>' [at at.htlkaindorf.sx.EasyProgrammer.serial.Protocol.readResponseString(Protocol.java:271)] +INFO *13:24:27.642: bytes received, '' in buffer, continue checking pattern [at at.htlkaindorf.sx.EasyProgrammer.serial.Protocol.readResponseString(Protocol.java:282)] +FINER 13:24:27.642: writing flash page 14 [at at.htlkaindorf.sx.EasyProgrammer.serial.DownloadProtocol.writeAndCheckPage(DownloadProtocol.java:220)] +INFO *13:24:27.642: waiting for pattern 'f>' [at at.htlkaindorf.sx.EasyProgrammer.serial.Protocol.readResponseString(Protocol.java:271)] +INFO *13:24:27.674: bytes received, '' in buffer, continue checking pattern [at at.htlkaindorf.sx.EasyProgrammer.serial.Protocol.readResponseString(Protocol.java:282)] +FINER 13:24:27.674: writing flash page 14 [at at.htlkaindorf.sx.EasyProgrammer.serial.DownloadProtocol.writeAndCheckPage(DownloadProtocol.java:220)] +INFO *13:24:27.674: waiting for pattern 'f>' [at at.htlkaindorf.sx.EasyProgrammer.serial.Protocol.readResponseString(Protocol.java:271)] +INFO *13:24:27.708: bytes received, '' in buffer, continue checking pattern [at at.htlkaindorf.sx.EasyProgrammer.serial.Protocol.readResponseString(Protocol.java:282)] +FINER 13:24:27.708: writing flash page 14 [at at.htlkaindorf.sx.EasyProgrammer.serial.DownloadProtocol.writeAndCheckPage(DownloadProtocol.java:220)] +INFO *13:24:27.708: waiting for pattern 'f>' [at at.htlkaindorf.sx.EasyProgrammer.serial.Protocol.readResponseString(Protocol.java:271)] +INFO *13:24:27.741: bytes received, '' in buffer, continue checking pattern [at at.htlkaindorf.sx.EasyProgrammer.serial.Protocol.readResponseString(Protocol.java:282)] +WARNING 13:24:27.742: [at at.htlkaindorf.sx.EasyProgrammer.serial.DownloadProtocol.download(DownloadProtocol.java:135)] +-------------------------------------------------------------------------------- +java.lang.Exception: Bootloader Error (unexpected response) + + + + 6.847062 1<-- 3: 3d(=) 31(1) 32(2) + 6.859050 1<-- 13: 20( ) 45(E) 42(B) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 6.865310 -->1 1: 50(P) + 6.865333 -->1 1: 31(1) + 6.866546 -->1 129: 33(3) 2f(/) 93 3f(?) 93 4f(O) 93 5f(_) 93 6f(o) 93 7f 93 8f 93 9f 93 af 93 bf 93 ef 93 ff 93 80 91 df 00 8f 5f(_) 85 30(0) e0 f1 10 92 df 00 80 91 de 00 8f 5f(_) 80 93 de 00 80 91 dd 00 88 23(#) c1 f0 80 91 04 01 8f 3f(?) c1 f1 8f 5f(_) 80 93 04 01 ff 91 ef 91 bf 91 af 91 9f 91 8f 91 7f 91 6f(o) 91 5f(_) 91 4f(O) 91 3f(?) 91 2f(/) 91 0f 90 0f be 0f 90 1f 90 18 95 81 e0 80 93 dd 00 78(x) 94 80 91 de 00 80 fd 19 c0 81 fd 12 c0 82 fd 1d c0 + 7.467351 -->1 1: 57(W) + 7.469293 -->1 130: 31(1) 33(3) 2f(/) 93 3f(?) 93 4f(O) 93 5f(_) 93 6f(o) 93 7f 93 8f 93 9f 93 af 93 bf 93 ef 93 ff 93 80 91 df 00 8f 5f(_) 85 30(0) e0 f1 10 92 df 00 80 91 de 00 8f 5f(_) 80 93 de 00 80 91 dd 00 88 23(#) c1 f0 80 91 04 01 8f 3f(?) c1 f1 8f 5f(_) 80 93 04 01 ff 91 ef 91 bf 91 af 91 9f 91 8f 91 7f 91 6f(o) 91 5f(_) 91 4f(O) 91 3f(?) 91 2f(/) 91 0f 90 0f be 0f 90 1f 90 18 95 81 e0 80 93 dd 00 78(x) 94 80 91 de 00 80 fd 19 c0 81 fd 12 c0 82 fd 1d c0 + 7.492102 1<-- 3: 3d(=) 31(1) 33(3) + 7.503854 1<-- 13: 20( ) 32(2) 36(6) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 7.508264 -->1 1: 50(P) + 7.508300 -->1 1: 31(1) + 7.511312 -->1 129: 34(4) 83 fd 1e c0 84 fd 1f c0 85 fd 14 c0 86 fd 1e c0 87 ff 08 c0 0e 94 a1 02 05 c0 80 93 df 00 d3 cf 0e 94 9b 02 10 92 dd 00 ce cf 0e 94 99 02 fa cf 8f ef c7 cf 0e 94 9f 02 f5 cf 0e 94 9c 02 f2 cf 0e 94 9d 02 ef cf 0e 94 9e 02 ec cf 0e 94 a0 02 e9 cf 80 e1 e9 e1 f1 e0 df 01 1d 92 8a 95 e9 f7 16 be 82 e1 80 b9 81 e0 81 b9 84 e0 86 bf 08 95 08 95 f8 94 80 91 1d 01 90 91 1e 01 8f 3b(;) 9f 47(G) + 7.526238 1<-- 3: 3d(=) 31(1) 8f + 7.537936 1<-- 13: 20( ) 35(5) 45(E) 20( ) 30(0) 30(0) 20( ) 30(0) 30(0) 0d 0a 66(f) 3e(>) + 7.543880 -->1 1: 57(W) + 7.543952 -->1 1: 31(1) diff --git a/measurements/2016-03-04-download-problem/p10i.png b/measurements/2016-03-04-download-problem/p10i.png new file mode 100644 index 0000000..1d6ac5e Binary files /dev/null and b/measurements/2016-03-04-download-problem/p10i.png differ diff --git a/measurements/2016-03-04-download-problem/p11i.png b/measurements/2016-03-04-download-problem/p11i.png new file mode 100644 index 0000000..bf40884 Binary files /dev/null and b/measurements/2016-03-04-download-problem/p11i.png differ diff --git a/measurements/2016-03-04-download-problem/p12.png b/measurements/2016-03-04-download-problem/p12.png new file mode 100644 index 0000000..354b2d4 Binary files /dev/null and b/measurements/2016-03-04-download-problem/p12.png differ diff --git a/measurements/2016-03-04-download-problem/p13.png b/measurements/2016-03-04-download-problem/p13.png new file mode 100644 index 0000000..758c54d Binary files /dev/null and b/measurements/2016-03-04-download-problem/p13.png differ diff --git a/measurements/2016-03-04-download-problem/p14i.png b/measurements/2016-03-04-download-problem/p14i.png new file mode 100644 index 0000000..35568f8 Binary files /dev/null and b/measurements/2016-03-04-download-problem/p14i.png differ diff --git a/measurements/2016-03-04-download-problem/p1i.png b/measurements/2016-03-04-download-problem/p1i.png new file mode 100644 index 0000000..0ab7d27 Binary files /dev/null and b/measurements/2016-03-04-download-problem/p1i.png differ diff --git a/measurements/2016-03-04-download-problem/p2i.png b/measurements/2016-03-04-download-problem/p2i.png new file mode 100644 index 0000000..bff103f Binary files /dev/null and b/measurements/2016-03-04-download-problem/p2i.png differ diff --git a/measurements/2016-03-04-download-problem/p3i.png b/measurements/2016-03-04-download-problem/p3i.png new file mode 100644 index 0000000..c2e5e9b Binary files /dev/null and b/measurements/2016-03-04-download-problem/p3i.png differ diff --git a/measurements/2016-03-04-download-problem/p4i.png b/measurements/2016-03-04-download-problem/p4i.png new file mode 100644 index 0000000..3e7d4f8 Binary files /dev/null and b/measurements/2016-03-04-download-problem/p4i.png differ diff --git a/measurements/2016-03-04-download-problem/p5i.png b/measurements/2016-03-04-download-problem/p5i.png new file mode 100644 index 0000000..aee0f38 Binary files /dev/null and b/measurements/2016-03-04-download-problem/p5i.png differ diff --git a/measurements/2016-03-04-download-problem/p6i.png b/measurements/2016-03-04-download-problem/p6i.png new file mode 100644 index 0000000..abb9276 Binary files /dev/null and b/measurements/2016-03-04-download-problem/p6i.png differ diff --git a/measurements/2016-03-04-download-problem/p7i.png b/measurements/2016-03-04-download-problem/p7i.png new file mode 100644 index 0000000..7bcbe39 Binary files /dev/null and b/measurements/2016-03-04-download-problem/p7i.png differ diff --git a/measurements/2016-03-04-download-problem/p8i.png b/measurements/2016-03-04-download-problem/p8i.png new file mode 100644 index 0000000..1ab995b Binary files /dev/null and b/measurements/2016-03-04-download-problem/p8i.png differ diff --git a/measurements/2016-03-04-download-problem/p9i.png b/measurements/2016-03-04-download-problem/p9i.png new file mode 100644 index 0000000..0756a43 Binary files /dev/null and b/measurements/2016-03-04-download-problem/p9i.png differ diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml new file mode 100644 index 0000000..2fa8535 --- /dev/null +++ b/nbproject/build-impl.xml @@ -0,0 +1,1419 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +*** GENERATED FROM project.xml - DO NOT EDIT *** +*** EDIT ../build.xml INSTEAD *** + +For the purpose of easier reading the script +is divided into following sections: + + - initialization + - compilation + - jar + - execution + - debugging + - javadoc + - test compilation + - test execution + - test debugging + - applet + - cleanup + + --> +<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="easyprogrammer-impl"> + <fail message="Please build using Ant 1.8.0 or higher."> + <condition> + <not> + <antversion atleast="1.8.0"/> + </not> + </condition> + </fail> + <target depends="test,jar,javadoc" description="Build and test whole project." name="default"/> + <!-- + ====================== + INITIALIZATION SECTION + ====================== + --> + <target name="-pre-init"> + <!-- Empty placeholder for easier customization. --> + <!-- You can override this target in the ../build.xml file. --> + </target> + <target depends="-pre-init" name="-init-private"> + <property file="nbproject/private/config.properties"/> + <property file="nbproject/private/configs/${config}.properties"/> + <property file="nbproject/private/private.properties"/> + </target> + <target depends="-pre-init,-init-private" name="-init-user"> + <property file="${user.properties.file}"/> + <!-- The two properties below are usually overridden --> + <!-- by the active platform. Just a fallback. --> + <property name="default.javac.source" value="1.4"/> + <property name="default.javac.target" value="1.4"/> + </target> + <target depends="-pre-init,-init-private,-init-user" name="-init-project"> + <property file="nbproject/configs/${config}.properties"/> + <property file="nbproject/project.properties"/> + </target> + <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init"> + <property name="platform.java" value="${java.home}/bin/java"/> + <available file="${manifest.file}" property="manifest.available"/> + <condition property="splashscreen.available"> + <and> + <not> + <equals arg1="${application.splash}" arg2="" trim="true"/> + </not> + <available file="${application.splash}"/> + </and> + </condition> + <condition property="main.class.available"> + <and> + <isset property="main.class"/> + <not> + <equals arg1="${main.class}" arg2="" trim="true"/> + </not> + </and> + </condition> + <condition property="profile.available"> + <and> + <isset property="javac.profile"/> + <length length="0" string="${javac.profile}" when="greater"/> + <matches pattern="1\.[89](\..*)?" string="${javac.source}"/> + </and> + </condition> + <condition property="do.archive"> + <or> + <not> + <istrue value="${jar.archive.disabled}"/> + </not> + <istrue value="${not.archive.disabled}"/> + </or> + </condition> + <condition property="do.mkdist"> + <and> + <isset property="do.archive"/> + <isset property="libs.CopyLibs.classpath"/> + <not> + <istrue value="${mkdist.disabled}"/> + </not> + </and> + </condition> + <condition property="do.archive+manifest.available"> + <and> + <isset property="manifest.available"/> + <istrue value="${do.archive}"/> + </and> + </condition> + <condition property="do.archive+main.class.available"> + <and> + <isset property="main.class.available"/> + <istrue value="${do.archive}"/> + </and> + </condition> + <condition property="do.archive+splashscreen.available"> + <and> + <isset property="splashscreen.available"/> + <istrue value="${do.archive}"/> + </and> + </condition> + <condition property="do.archive+profile.available"> + <and> + <isset property="profile.available"/> + <istrue value="${do.archive}"/> + </and> + </condition> + <condition property="have.tests"> + <or> + <available file="${test.src.dir}"/> + </or> + </condition> + <condition property="have.sources"> + <or> + <available file="${src.dir}"/> + </or> + </condition> + <condition property="netbeans.home+have.tests"> + <and> + <isset property="netbeans.home"/> + <isset property="have.tests"/> + </and> + </condition> + <condition property="no.javadoc.preview"> + <and> + <isset property="javadoc.preview"/> + <isfalse value="${javadoc.preview}"/> + </and> + </condition> + <property name="run.jvmargs" value=""/> + <property name="run.jvmargs.ide" value=""/> + <property name="javac.compilerargs" value=""/> + <property name="work.dir" value="${basedir}"/> + <condition property="no.deps"> + <and> + <istrue value="${no.dependencies}"/> + </and> + </condition> + <property name="javac.debug" value="true"/> + <property name="javadoc.preview" value="true"/> + <property name="application.args" value=""/> + <property name="source.encoding" value="${file.encoding}"/> + <property name="runtime.encoding" value="${source.encoding}"/> + <condition property="javadoc.encoding.used" value="${javadoc.encoding}"> + <and> + <isset property="javadoc.encoding"/> + <not> + <equals arg1="${javadoc.encoding}" arg2=""/> + </not> + </and> + </condition> + <property name="javadoc.encoding.used" value="${source.encoding}"/> + <property name="includes" value="**"/> + <property name="excludes" value=""/> + <property name="do.depend" value="false"/> + <condition property="do.depend.true"> + <istrue value="${do.depend}"/> + </condition> + <path id="endorsed.classpath.path" path="${endorsed.classpath}"/> + <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'"> + <and> + <isset property="endorsed.classpath"/> + <not> + <equals arg1="${endorsed.classpath}" arg2="" trim="true"/> + </not> + </and> + </condition> + <condition else="" property="javac.profile.cmd.line.arg" value="-profile ${javac.profile}"> + <isset property="profile.available"/> + </condition> + <condition else="false" property="jdkBug6558476"> + <and> + <matches pattern="1\.[56]" string="${java.specification.version}"/> + <not> + <os family="unix"/> + </not> + </and> + </condition> + <condition else="false" property="javac.fork"> + <or> + <istrue value="${jdkBug6558476}"/> + <istrue value="${javac.external.vm}"/> + </or> + </condition> + <property name="jar.index" value="false"/> + <property name="jar.index.metainf" value="${jar.index}"/> + <property name="copylibs.rebase" value="true"/> + <available file="${meta.inf.dir}/persistence.xml" property="has.persistence.xml"/> + <condition property="junit.available"> + <or> + <available classname="org.junit.Test" classpath="${run.test.classpath}"/> + <available classname="junit.framework.Test" classpath="${run.test.classpath}"/> + </or> + </condition> + <condition property="testng.available"> + <available classname="org.testng.annotations.Test" classpath="${run.test.classpath}"/> + </condition> + <condition property="junit+testng.available"> + <and> + <istrue value="${junit.available}"/> + <istrue value="${testng.available}"/> + </and> + </condition> + <condition else="testng" property="testng.mode" value="mixed"> + <istrue value="${junit+testng.available}"/> + </condition> + <condition else="" property="testng.debug.mode" value="-mixed"> + <istrue value="${junit+testng.available}"/> + </condition> + <property name="java.failonerror" value="true"/> + </target> + <target name="-post-init"> + <!-- Empty placeholder for easier customization. --> + <!-- You can override this target in the ../build.xml file. --> + </target> + <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check"> + <fail unless="src.dir">Must set src.dir</fail> + <fail unless="test.src.dir">Must set test.src.dir</fail> + <fail unless="build.dir">Must set build.dir</fail> + <fail unless="dist.dir">Must set dist.dir</fail> + <fail unless="build.classes.dir">Must set build.classes.dir</fail> + <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail> + <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail> + <fail unless="build.test.results.dir">Must set build.test.results.dir</fail> + <fail unless="build.classes.excludes">Must set build.classes.excludes</fail> + <fail unless="dist.jar">Must set dist.jar</fail> + </target> + <target name="-init-macrodef-property"> + <macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1"> + <attribute name="name"/> + <attribute name="value"/> + <sequential> + <property name="@{name}" value="${@{value}}"/> + </sequential> + </macrodef> + </target> + <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors"> + <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${src.dir}" name="srcdir"/> + <attribute default="${build.classes.dir}" name="destdir"/> + <attribute default="${javac.classpath}" name="classpath"/> + <attribute default="${javac.processorpath}" name="processorpath"/> + <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/> + <attribute default="${includes}" name="includes"/> + <attribute default="${excludes}" name="excludes"/> + <attribute default="${javac.debug}" name="debug"/> + <attribute default="${empty.dir}" name="sourcepath"/> + <attribute default="${empty.dir}" name="gensrcdir"/> + <element name="customize" optional="true"/> + <sequential> + <property location="${build.dir}/empty" name="empty.dir"/> + <mkdir dir="${empty.dir}"/> + <mkdir dir="@{apgeneratedsrcdir}"/> + <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}"> + <src> + <dirset dir="@{gensrcdir}" erroronmissingdir="false"> + <include name="*"/> + </dirset> + </src> + <classpath> + <path path="@{classpath}"/> + </classpath> + <compilerarg line="${endorsed.classpath.cmd.line.arg}"/> + <compilerarg line="${javac.profile.cmd.line.arg}"/> + <compilerarg line="${javac.compilerargs}"/> + <compilerarg value="-processorpath"/> + <compilerarg path="@{processorpath}:${empty.dir}"/> + <compilerarg line="${ap.processors.internal}"/> + <compilerarg line="${annotation.processing.processor.options}"/> + <compilerarg value="-s"/> + <compilerarg path="@{apgeneratedsrcdir}"/> + <compilerarg line="${ap.proc.none.internal}"/> + <customize/> + </javac> + </sequential> + </macrodef> + </target> + <target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal"> + <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${src.dir}" name="srcdir"/> + <attribute default="${build.classes.dir}" name="destdir"/> + <attribute default="${javac.classpath}" name="classpath"/> + <attribute default="${javac.processorpath}" name="processorpath"/> + <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/> + <attribute default="${includes}" name="includes"/> + <attribute default="${excludes}" name="excludes"/> + <attribute default="${javac.debug}" name="debug"/> + <attribute default="${empty.dir}" name="sourcepath"/> + <attribute default="${empty.dir}" name="gensrcdir"/> + <element name="customize" optional="true"/> + <sequential> + <property location="${build.dir}/empty" name="empty.dir"/> + <mkdir dir="${empty.dir}"/> + <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}"> + <src> + <dirset dir="@{gensrcdir}" erroronmissingdir="false"> + <include name="*"/> + </dirset> + </src> + <classpath> + <path path="@{classpath}"/> + </classpath> + <compilerarg line="${endorsed.classpath.cmd.line.arg}"/> + <compilerarg line="${javac.profile.cmd.line.arg}"/> + <compilerarg line="${javac.compilerargs}"/> + <customize/> + </javac> + </sequential> + </macrodef> + </target> + <target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac"> + <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${src.dir}" name="srcdir"/> + <attribute default="${build.classes.dir}" name="destdir"/> + <attribute default="${javac.classpath}" name="classpath"/> + <sequential> + <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}"> + <classpath> + <path path="@{classpath}"/> + </classpath> + </depend> + </sequential> + </macrodef> + <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${build.classes.dir}" name="destdir"/> + <sequential> + <fail unless="javac.includes">Must set javac.includes</fail> + <pathconvert pathsep="${line.separator}" property="javac.includes.binary"> + <path> + <filelist dir="@{destdir}" files="${javac.includes}"/> + </path> + <globmapper from="*.java" to="*.class"/> + </pathconvert> + <tempfile deleteonexit="true" property="javac.includesfile.binary"/> + <echo file="${javac.includesfile.binary}" message="${javac.includes.binary}"/> + <delete> + <files includesfile="${javac.includesfile.binary}"/> + </delete> + <delete> + <fileset file="${javac.includesfile.binary}"/> + </delete> + </sequential> + </macrodef> + </target> + <target if="${junit.available}" name="-init-macrodef-junit-init"> + <condition else="false" property="nb.junit.batch" value="true"> + <and> + <istrue value="${junit.available}"/> + <not> + <isset property="test.method"/> + </not> + </and> + </condition> + <condition else="false" property="nb.junit.single" value="true"> + <and> + <istrue value="${junit.available}"/> + <isset property="test.method"/> + </and> + </condition> + </target> + <target name="-init-test-properties"> + <property name="test.binaryincludes" value="<nothing>"/> + <property name="test.binarytestincludes" value=""/> + <property name="test.binaryexcludes" value=""/> + </target> + <target if="${nb.junit.single}" name="-init-macrodef-junit-single" unless="${nb.junit.batch}"> + <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${includes}" name="includes"/> + <attribute default="${excludes}" name="excludes"/> + <attribute default="**" name="testincludes"/> + <attribute default="" name="testmethods"/> + <element name="customize" optional="true"/> + <sequential> + <property name="junit.forkmode" value="perTest"/> + <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}"> + <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/> + <syspropertyset> + <propertyref prefix="test-sys-prop."/> + <mapper from="test-sys-prop.*" to="*" type="glob"/> + </syspropertyset> + <formatter type="brief" usefile="false"/> + <formatter type="xml"/> + <jvmarg value="-ea"/> + <customize/> + </junit> + </sequential> + </macrodef> + </target> + <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-batch" unless="${nb.junit.single}"> + <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${includes}" name="includes"/> + <attribute default="${excludes}" name="excludes"/> + <attribute default="**" name="testincludes"/> + <attribute default="" name="testmethods"/> + <element name="customize" optional="true"/> + <sequential> + <property name="junit.forkmode" value="perTest"/> + <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}"> + <batchtest todir="${build.test.results.dir}"> + <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}"> + <filename name="@{testincludes}"/> + </fileset> + <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}"> + <filename name="${test.binarytestincludes}"/> + </fileset> + </batchtest> + <syspropertyset> + <propertyref prefix="test-sys-prop."/> + <mapper from="test-sys-prop.*" to="*" type="glob"/> + </syspropertyset> + <formatter type="brief" usefile="false"/> + <formatter type="xml"/> + <jvmarg value="-ea"/> + <customize/> + </junit> + </sequential> + </macrodef> + </target> + <target depends="-init-macrodef-junit-init,-init-macrodef-junit-single, -init-macrodef-junit-batch" if="${junit.available}" name="-init-macrodef-junit"/> + <target if="${testng.available}" name="-init-macrodef-testng"> + <macrodef name="testng" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${includes}" name="includes"/> + <attribute default="${excludes}" name="excludes"/> + <attribute default="**" name="testincludes"/> + <attribute default="" name="testmethods"/> + <element name="customize" optional="true"/> + <sequential> + <condition else="" property="testng.methods.arg" value="@{testincludes}.@{testmethods}"> + <isset property="test.method"/> + </condition> + <union id="test.set"> + <fileset dir="${test.src.dir}" excludes="@{excludes},**/*.xml,${excludes}" includes="@{includes}"> + <filename name="@{testincludes}"/> + </fileset> + </union> + <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/> + <testng classfilesetref="test.set" failureProperty="tests.failed" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="easyprogrammer" testname="TestNG tests" workingDir="${work.dir}"> + <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/> + <propertyset> + <propertyref prefix="test-sys-prop."/> + <mapper from="test-sys-prop.*" to="*" type="glob"/> + </propertyset> + <customize/> + </testng> + </sequential> + </macrodef> + </target> + <target name="-init-macrodef-test-impl"> + <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${includes}" name="includes"/> + <attribute default="${excludes}" name="excludes"/> + <attribute default="**" name="testincludes"/> + <attribute default="" name="testmethods"/> + <element implicit="true" name="customize" optional="true"/> + <sequential> + <echo>No tests executed.</echo> + </sequential> + </macrodef> + </target> + <target depends="-init-macrodef-junit" if="${junit.available}" name="-init-macrodef-junit-impl"> + <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${includes}" name="includes"/> + <attribute default="${excludes}" name="excludes"/> + <attribute default="**" name="testincludes"/> + <attribute default="" name="testmethods"/> + <element implicit="true" name="customize" optional="true"/> + <sequential> + <j2seproject3:junit excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}"> + <customize/> + </j2seproject3:junit> + </sequential> + </macrodef> + </target> + <target depends="-init-macrodef-testng" if="${testng.available}" name="-init-macrodef-testng-impl"> + <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${includes}" name="includes"/> + <attribute default="${excludes}" name="excludes"/> + <attribute default="**" name="testincludes"/> + <attribute default="" name="testmethods"/> + <element implicit="true" name="customize" optional="true"/> + <sequential> + <j2seproject3:testng excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}"> + <customize/> + </j2seproject3:testng> + </sequential> + </macrodef> + </target> + <target depends="-init-macrodef-test-impl,-init-macrodef-junit-impl,-init-macrodef-testng-impl" name="-init-macrodef-test"> + <macrodef name="test" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${includes}" name="includes"/> + <attribute default="${excludes}" name="excludes"/> + <attribute default="**" name="testincludes"/> + <attribute default="" name="testmethods"/> + <sequential> + <j2seproject3:test-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}"> + <customize> + <classpath> + <path path="${run.test.classpath}"/> + </classpath> + <jvmarg line="${endorsed.classpath.cmd.line.arg}"/> + <jvmarg line="${run.jvmargs}"/> + <jvmarg line="${run.jvmargs.ide}"/> + </customize> + </j2seproject3:test-impl> + </sequential> + </macrodef> + </target> + <target if="${junit.available}" name="-init-macrodef-junit-debug" unless="${nb.junit.batch}"> + <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${includes}" name="includes"/> + <attribute default="${excludes}" name="excludes"/> + <attribute default="**" name="testincludes"/> + <attribute default="" name="testmethods"/> + <element name="customize" optional="true"/> + <sequential> + <property name="junit.forkmode" value="perTest"/> + <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}"> + <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/> + <syspropertyset> + <propertyref prefix="test-sys-prop."/> + <mapper from="test-sys-prop.*" to="*" type="glob"/> + </syspropertyset> + <formatter type="brief" usefile="false"/> + <formatter type="xml"/> + <jvmarg value="-ea"/> + <jvmarg line="${debug-args-line}"/> + <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/> + <customize/> + </junit> + </sequential> + </macrodef> + </target> + <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-debug-batch"> + <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${includes}" name="includes"/> + <attribute default="${excludes}" name="excludes"/> + <attribute default="**" name="testincludes"/> + <attribute default="" name="testmethods"/> + <element name="customize" optional="true"/> + <sequential> + <property name="junit.forkmode" value="perTest"/> + <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}"> + <batchtest todir="${build.test.results.dir}"> + <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}"> + <filename name="@{testincludes}"/> + </fileset> + <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}"> + <filename name="${test.binarytestincludes}"/> + </fileset> + </batchtest> + <syspropertyset> + <propertyref prefix="test-sys-prop."/> + <mapper from="test-sys-prop.*" to="*" type="glob"/> + </syspropertyset> + <formatter type="brief" usefile="false"/> + <formatter type="xml"/> + <jvmarg value="-ea"/> + <jvmarg line="${debug-args-line}"/> + <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/> + <customize/> + </junit> + </sequential> + </macrodef> + </target> + <target depends="-init-macrodef-junit-debug,-init-macrodef-junit-debug-batch" if="${junit.available}" name="-init-macrodef-junit-debug-impl"> + <macrodef name="test-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${includes}" name="includes"/> + <attribute default="${excludes}" name="excludes"/> + <attribute default="**" name="testincludes"/> + <attribute default="" name="testmethods"/> + <element implicit="true" name="customize" optional="true"/> + <sequential> + <j2seproject3:junit-debug excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}"> + <customize/> + </j2seproject3:junit-debug> + </sequential> + </macrodef> + </target> + <target if="${testng.available}" name="-init-macrodef-testng-debug"> + <macrodef name="testng-debug" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${main.class}" name="testClass"/> + <attribute default="" name="testMethod"/> + <element name="customize2" optional="true"/> + <sequential> + <condition else="-testclass @{testClass}" property="test.class.or.method" value="-methods @{testClass}.@{testMethod}"> + <isset property="test.method"/> + </condition> + <condition else="-suitename easyprogrammer -testname @{testClass} ${test.class.or.method}" property="testng.cmd.args" value="@{testClass}"> + <matches pattern=".*\.xml" string="@{testClass}"/> + </condition> + <delete dir="${build.test.results.dir}" quiet="true"/> + <mkdir dir="${build.test.results.dir}"/> + <j2seproject3:debug classname="org.testng.TestNG" classpath="${debug.test.classpath}"> + <customize> + <customize2/> + <jvmarg value="-ea"/> + <arg line="${testng.debug.mode}"/> + <arg line="-d ${build.test.results.dir}"/> + <arg line="-listener org.testng.reporters.VerboseReporter"/> + <arg line="${testng.cmd.args}"/> + </customize> + </j2seproject3:debug> + </sequential> + </macrodef> + </target> + <target depends="-init-macrodef-testng-debug" if="${testng.available}" name="-init-macrodef-testng-debug-impl"> + <macrodef name="testng-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${main.class}" name="testClass"/> + <attribute default="" name="testMethod"/> + <element implicit="true" name="customize2" optional="true"/> + <sequential> + <j2seproject3:testng-debug testClass="@{testClass}" testMethod="@{testMethod}"> + <customize2/> + </j2seproject3:testng-debug> + </sequential> + </macrodef> + </target> + <target depends="-init-macrodef-junit-debug-impl" if="${junit.available}" name="-init-macrodef-test-debug-junit"> + <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${includes}" name="includes"/> + <attribute default="${excludes}" name="excludes"/> + <attribute default="**" name="testincludes"/> + <attribute default="" name="testmethods"/> + <attribute default="${main.class}" name="testClass"/> + <attribute default="" name="testMethod"/> + <sequential> + <j2seproject3:test-debug-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}"> + <customize> + <classpath> + <path path="${run.test.classpath}"/> + </classpath> + <jvmarg line="${endorsed.classpath.cmd.line.arg}"/> + <jvmarg line="${run.jvmargs}"/> + <jvmarg line="${run.jvmargs.ide}"/> + </customize> + </j2seproject3:test-debug-impl> + </sequential> + </macrodef> + </target> + <target depends="-init-macrodef-testng-debug-impl" if="${testng.available}" name="-init-macrodef-test-debug-testng"> + <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${includes}" name="includes"/> + <attribute default="${excludes}" name="excludes"/> + <attribute default="**" name="testincludes"/> + <attribute default="" name="testmethods"/> + <attribute default="${main.class}" name="testClass"/> + <attribute default="" name="testMethod"/> + <sequential> + <j2seproject3:testng-debug-impl testClass="@{testClass}" testMethod="@{testMethod}"> + <customize2> + <syspropertyset> + <propertyref prefix="test-sys-prop."/> + <mapper from="test-sys-prop.*" to="*" type="glob"/> + </syspropertyset> + </customize2> + </j2seproject3:testng-debug-impl> + </sequential> + </macrodef> + </target> + <target depends="-init-macrodef-test-debug-junit,-init-macrodef-test-debug-testng" name="-init-macrodef-test-debug"/> + <!-- + pre NB7.2 profiling section; consider it deprecated + --> + <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile, -profile-init-check" if="profiler.info.jvmargs.agent" name="profile-init"/> + <target if="profiler.info.jvmargs.agent" name="-profile-pre-init"> + <!-- Empty placeholder for easier customization. --> + <!-- You can override this target in the ../build.xml file. --> + </target> + <target if="profiler.info.jvmargs.agent" name="-profile-post-init"> + <!-- Empty placeholder for easier customization. --> + <!-- You can override this target in the ../build.xml file. --> + </target> + <target if="profiler.info.jvmargs.agent" name="-profile-init-macrodef-profile"> + <macrodef name="resolve"> + <attribute name="name"/> + <attribute name="value"/> + <sequential> + <property name="@{name}" value="${env.@{value}}"/> + </sequential> + </macrodef> + <macrodef name="profile"> + <attribute default="${main.class}" name="classname"/> + <element name="customize" optional="true"/> + <sequential> + <property environment="env"/> + <resolve name="profiler.current.path" value="${profiler.info.pathvar}"/> + <java classname="@{classname}" dir="${profiler.info.dir}" failonerror="${java.failonerror}" fork="true" jvm="${profiler.info.jvm}"> + <jvmarg line="${endorsed.classpath.cmd.line.arg}"/> + <jvmarg value="${profiler.info.jvmargs.agent}"/> + <jvmarg line="${profiler.info.jvmargs}"/> + <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/> + <arg line="${application.args}"/> + <classpath> + <path path="${run.classpath}"/> + </classpath> + <syspropertyset> + <propertyref prefix="run-sys-prop."/> + <mapper from="run-sys-prop.*" to="*" type="glob"/> + </syspropertyset> + <customize/> + </java> + </sequential> + </macrodef> + </target> + <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile" if="profiler.info.jvmargs.agent" name="-profile-init-check"> + <fail unless="profiler.info.jvm">Must set JVM to use for profiling in profiler.info.jvm</fail> + <fail unless="profiler.info.jvmargs.agent">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail> + </target> + <!-- + end of pre NB7.2 profiling section + --> + <target depends="-init-debug-args" name="-init-macrodef-nbjpda"> + <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1"> + <attribute default="${main.class}" name="name"/> + <attribute default="${debug.classpath}" name="classpath"/> + <attribute default="" name="stopclassname"/> + <sequential> + <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}"> + <classpath> + <path path="@{classpath}"/> + </classpath> + </nbjpdastart> + </sequential> + </macrodef> + <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1"> + <attribute default="${build.classes.dir}" name="dir"/> + <sequential> + <nbjpdareload> + <fileset dir="@{dir}" includes="${fix.classes}"> + <include name="${fix.includes}*.class"/> + </fileset> + </nbjpdareload> + </sequential> + </macrodef> + </target> + <target name="-init-debug-args"> + <property name="version-output" value="java version "${ant.java.version}"/> + <condition property="have-jdk-older-than-1.4"> + <or> + <contains string="${version-output}" substring="java version "1.0"/> + <contains string="${version-output}" substring="java version "1.1"/> + <contains string="${version-output}" substring="java version "1.2"/> + <contains string="${version-output}" substring="java version "1.3"/> + </or> + </condition> + <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none"> + <istrue value="${have-jdk-older-than-1.4}"/> + </condition> + <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem"> + <os family="windows"/> + </condition> + <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}"> + <isset property="debug.transport"/> + </condition> + </target> + <target depends="-init-debug-args" name="-init-macrodef-debug"> + <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${main.class}" name="classname"/> + <attribute default="${debug.classpath}" name="classpath"/> + <element name="customize" optional="true"/> + <sequential> + <java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true"> + <jvmarg line="${endorsed.classpath.cmd.line.arg}"/> + <jvmarg line="${debug-args-line}"/> + <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/> + <jvmarg value="-Dfile.encoding=${runtime.encoding}"/> + <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/> + <jvmarg line="${run.jvmargs}"/> + <jvmarg line="${run.jvmargs.ide}"/> + <classpath> + <path path="@{classpath}"/> + </classpath> + <syspropertyset> + <propertyref prefix="run-sys-prop."/> + <mapper from="run-sys-prop.*" to="*" type="glob"/> + </syspropertyset> + <customize/> + </java> + </sequential> + </macrodef> + </target> + <target name="-init-macrodef-java"> + <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1"> + <attribute default="${main.class}" name="classname"/> + <attribute default="${run.classpath}" name="classpath"/> + <attribute default="jvm" name="jvm"/> + <element name="customize" optional="true"/> + <sequential> + <java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true"> + <jvmarg line="${endorsed.classpath.cmd.line.arg}"/> + <jvmarg value="-Dfile.encoding=${runtime.encoding}"/> + <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/> + <jvmarg line="${run.jvmargs}"/> + <jvmarg line="${run.jvmargs.ide}"/> + <classpath> + <path path="@{classpath}"/> + </classpath> + <syspropertyset> + <propertyref prefix="run-sys-prop."/> + <mapper from="run-sys-prop.*" to="*" type="glob"/> + </syspropertyset> + <customize/> + </java> + </sequential> + </macrodef> + </target> + <target name="-init-macrodef-copylibs"> + <macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3"> + <attribute default="${manifest.file}" name="manifest"/> + <element name="customize" optional="true"/> + <sequential> + <property location="${build.classes.dir}" name="build.classes.dir.resolved"/> + <pathconvert property="run.classpath.without.build.classes.dir"> + <path path="${run.classpath}"/> + <map from="${build.classes.dir.resolved}" to=""/> + </pathconvert> + <pathconvert pathsep=" " property="jar.classpath"> + <path path="${run.classpath.without.build.classes.dir}"/> + <chainedmapper> + <flattenmapper/> + <filtermapper> + <replacestring from=" " to="%20"/> + </filtermapper> + <globmapper from="*" to="lib/*"/> + </chainedmapper> + </pathconvert> + <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/> + <copylibs compress="${jar.compress}" excludeFromCopy="${copylibs.excludes}" index="${jar.index}" indexMetaInf="${jar.index.metainf}" jarfile="${dist.jar}" manifest="@{manifest}" rebase="${copylibs.rebase}" runtimeclasspath="${run.classpath.without.build.classes.dir}"> + <fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/> + <manifest> + <attribute name="Class-Path" value="${jar.classpath}"/> + <customize/> + </manifest> + </copylibs> + </sequential> + </macrodef> + </target> + <target name="-init-presetdef-jar"> + <presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1"> + <jar compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}"> + <j2seproject1:fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/> + </jar> + </presetdef> + </target> + <target name="-init-ap-cmdline-properties"> + <property name="annotation.processing.enabled" value="true"/> + <property name="annotation.processing.processors.list" value=""/> + <property name="annotation.processing.processor.options" value=""/> + <property name="annotation.processing.run.all.processors" value="true"/> + <property name="javac.processorpath" value="${javac.classpath}"/> + <property name="javac.test.processorpath" value="${javac.test.classpath}"/> + <condition property="ap.supported.internal" value="true"> + <not> + <matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/> + </not> + </condition> + </target> + <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported"> + <condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}"> + <isfalse value="${annotation.processing.run.all.processors}"/> + </condition> + <condition else="" property="ap.proc.none.internal" value="-proc:none"> + <isfalse value="${annotation.processing.enabled}"/> + </condition> + </target> + <target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline"> + <property name="ap.cmd.line.internal" value=""/> + </target> + <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-test,-init-macrodef-test-debug,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar,-init-ap-cmdline" name="init"/> + <!-- + =================== + COMPILATION SECTION + =================== + --> + <target name="-deps-jar-init" unless="built-jar.properties"> + <property location="${build.dir}/built-jar.properties" name="built-jar.properties"/> + <delete file="${built-jar.properties}" quiet="true"/> + </target> + <target if="already.built.jar.${basedir}" name="-warn-already-built-jar"> + <echo level="warn" message="Cycle detected: easyprogrammer was already built"/> + </target> + <target depends="init,-deps-jar-init" name="deps-jar" unless="no.deps"> + <mkdir dir="${build.dir}"/> + <touch file="${built-jar.properties}" verbose="false"/> + <property file="${built-jar.properties}" prefix="already.built.jar."/> + <antcall target="-warn-already-built-jar"/> + <propertyfile file="${built-jar.properties}"> + <entry key="${basedir}" value=""/> + </propertyfile> + </target> + <target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/> + <target depends="init" name="-check-automatic-build"> + <available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/> + </target> + <target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build"> + <antcall target="clean"/> + </target> + <target depends="init,deps-jar" name="-pre-pre-compile"> + <mkdir dir="${build.classes.dir}"/> + </target> + <target name="-pre-compile"> + <!-- Empty placeholder for easier customization. --> + <!-- You can override this target in the ../build.xml file. --> + </target> + <target if="do.depend.true" name="-compile-depend"> + <pathconvert property="build.generated.subdirs"> + <dirset dir="${build.generated.sources.dir}" erroronmissingdir="false"> + <include name="*"/> + </dirset> + </pathconvert> + <j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/> + </target> + <target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile"> + <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/> + <copy todir="${build.classes.dir}"> + <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/> + </copy> + </target> + <target if="has.persistence.xml" name="-copy-persistence-xml"> + <mkdir dir="${build.classes.dir}/META-INF"/> + <copy todir="${build.classes.dir}/META-INF"> + <fileset dir="${meta.inf.dir}" includes="persistence.xml orm.xml"/> + </copy> + </target> + <target name="-post-compile"> + <!-- Empty placeholder for easier customization. --> + <!-- You can override this target in the ../build.xml file. --> + </target> + <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/> + <target name="-pre-compile-single"> + <!-- Empty placeholder for easier customization. --> + <!-- You can override this target in the ../build.xml file. --> + </target> + <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single"> + <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail> + <j2seproject3:force-recompile/> + <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/> + </target> + <target name="-post-compile-single"> + <!-- Empty placeholder for easier customization. --> + <!-- You can override this target in the ../build.xml file. --> + </target> + <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/> + <!-- + ==================== + JAR BUILDING SECTION + ==================== + --> + <target depends="init" name="-pre-pre-jar"> + <dirname file="${dist.jar}" property="dist.jar.dir"/> + <mkdir dir="${dist.jar.dir}"/> + </target> + <target name="-pre-jar"> + <!-- Empty placeholder for easier customization. --> + <!-- You can override this target in the ../build.xml file. --> + </target> + <target depends="init" if="do.archive" name="-do-jar-create-manifest" unless="manifest.available"> + <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/> + <touch file="${tmp.manifest.file}" verbose="false"/> + </target> + <target depends="init" if="do.archive+manifest.available" name="-do-jar-copy-manifest"> + <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/> + <copy file="${manifest.file}" tofile="${tmp.manifest.file}"/> + </target> + <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+main.class.available" name="-do-jar-set-mainclass"> + <manifest file="${tmp.manifest.file}" mode="update"> + <attribute name="Main-Class" value="${main.class}"/> + </manifest> + </target> + <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+profile.available" name="-do-jar-set-profile"> + <manifest file="${tmp.manifest.file}" mode="update"> + <attribute name="Profile" value="${javac.profile}"/> + </manifest> + </target> + <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+splashscreen.available" name="-do-jar-set-splashscreen"> + <basename file="${application.splash}" property="splashscreen.basename"/> + <mkdir dir="${build.classes.dir}/META-INF"/> + <copy failonerror="false" file="${application.splash}" todir="${build.classes.dir}/META-INF"/> + <manifest file="${tmp.manifest.file}" mode="update"> + <attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/> + </manifest> + </target> + <target depends="init,-init-macrodef-copylibs,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.mkdist" name="-do-jar-copylibs"> + <j2seproject3:copylibs manifest="${tmp.manifest.file}"/> + <echo level="info">To run this application from the command line without Ant, try:</echo> + <property location="${dist.jar}" name="dist.jar.resolved"/> + <echo level="info">java -jar "${dist.jar.resolved}"</echo> + </target> + <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.archive" name="-do-jar-jar" unless="do.mkdist"> + <j2seproject1:jar manifest="${tmp.manifest.file}"/> + <property location="${build.classes.dir}" name="build.classes.dir.resolved"/> + <property location="${dist.jar}" name="dist.jar.resolved"/> + <pathconvert property="run.classpath.with.dist.jar"> + <path path="${run.classpath}"/> + <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/> + </pathconvert> + <condition else="" property="jar.usage.message" value="To run this application from the command line without Ant, try:${line.separator}${platform.java} -cp ${run.classpath.with.dist.jar} ${main.class}"> + <isset property="main.class.available"/> + </condition> + <condition else="debug" property="jar.usage.level" value="info"> + <isset property="main.class.available"/> + </condition> + <echo level="${jar.usage.level}" message="${jar.usage.message}"/> + </target> + <target depends="-do-jar-copylibs" if="do.archive" name="-do-jar-delete-manifest"> + <delete> + <fileset file="${tmp.manifest.file}"/> + </delete> + </target> + <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-jar,-do-jar-delete-manifest" name="-do-jar-without-libraries"/> + <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-copylibs,-do-jar-delete-manifest" name="-do-jar-with-libraries"/> + <target name="-post-jar"> + <!-- Empty placeholder for easier customization. --> + <!-- You can override this target in the ../build.xml file. --> + </target> + <target depends="init,compile,-pre-jar,-do-jar-without-libraries,-do-jar-with-libraries,-post-jar" name="-do-jar"/> + <target depends="init,compile,-pre-jar,-do-jar,-post-jar" description="Build JAR." name="jar"/> + <!-- + ================= + EXECUTION SECTION + ================= + --> + <target depends="init,compile" description="Run a main class." name="run"> + <j2seproject1:java> + <customize> + <arg line="${application.args}"/> + </customize> + </j2seproject1:java> + </target> + <target name="-do-not-recompile"> + <property name="javac.includes.binary" value=""/> + </target> + <target depends="init,compile-single" name="run-single"> + <fail unless="run.class">Must select one file in the IDE or set run.class</fail> + <j2seproject1:java classname="${run.class}"/> + </target> + <target depends="init,compile-test-single" name="run-test-with-main"> + <fail unless="run.class">Must select one file in the IDE or set run.class</fail> + <j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/> + </target> + <!-- + ================= + DEBUGGING SECTION + ================= + --> + <target depends="init" if="netbeans.home" name="-debug-start-debugger"> + <j2seproject1:nbjpdastart name="${debug.class}"/> + </target> + <target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test"> + <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/> + </target> + <target depends="init,compile" name="-debug-start-debuggee"> + <j2seproject3:debug> + <customize> + <arg line="${application.args}"/> + </customize> + </j2seproject3:debug> + </target> + <target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/> + <target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto"> + <j2seproject1:nbjpdastart stopclassname="${main.class}"/> + </target> + <target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/> + <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single"> + <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail> + <j2seproject3:debug classname="${debug.class}"/> + </target> + <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/> + <target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test"> + <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail> + <j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/> + </target> + <target depends="init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/> + <target depends="init" name="-pre-debug-fix"> + <fail unless="fix.includes">Must set fix.includes</fail> + <property name="javac.includes" value="${fix.includes}.java"/> + </target> + <target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix"> + <j2seproject1:nbjpdareload/> + </target> + <target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/> + <!-- + ================= + PROFILING SECTION + ================= + --> + <!-- + pre NB7.2 profiler integration + --> + <target depends="profile-init,compile" description="Profile a project in the IDE." if="profiler.info.jvmargs.agent" name="-profile-pre72"> + <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail> + <nbprofiledirect> + <classpath> + <path path="${run.classpath}"/> + </classpath> + </nbprofiledirect> + <profile/> + </target> + <target depends="profile-init,compile-single" description="Profile a selected class in the IDE." if="profiler.info.jvmargs.agent" name="-profile-single-pre72"> + <fail unless="profile.class">Must select one file in the IDE or set profile.class</fail> + <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail> + <nbprofiledirect> + <classpath> + <path path="${run.classpath}"/> + </classpath> + </nbprofiledirect> + <profile classname="${profile.class}"/> + </target> + <target depends="profile-init,compile-single" if="profiler.info.jvmargs.agent" name="-profile-applet-pre72"> + <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail> + <nbprofiledirect> + <classpath> + <path path="${run.classpath}"/> + </classpath> + </nbprofiledirect> + <profile classname="sun.applet.AppletViewer"> + <customize> + <arg value="${applet.url}"/> + </customize> + </profile> + </target> + <target depends="profile-init,compile-test-single" if="profiler.info.jvmargs.agent" name="-profile-test-single-pre72"> + <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail> + <nbprofiledirect> + <classpath> + <path path="${run.test.classpath}"/> + </classpath> + </nbprofiledirect> + <junit dir="${profiler.info.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${profiler.info.jvm}" showoutput="true"> + <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/> + <jvmarg value="${profiler.info.jvmargs.agent}"/> + <jvmarg line="${profiler.info.jvmargs}"/> + <test name="${profile.class}"/> + <classpath> + <path path="${run.test.classpath}"/> + </classpath> + <syspropertyset> + <propertyref prefix="test-sys-prop."/> + <mapper from="test-sys-prop.*" to="*" type="glob"/> + </syspropertyset> + <formatter type="brief" usefile="false"/> + <formatter type="xml"/> + </junit> + </target> + <!-- + end of pre NB72 profiling section + --> + <target if="netbeans.home" name="-profile-check"> + <condition property="profiler.configured"> + <or> + <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-agentpath:"/> + <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-javaagent:"/> + </or> + </condition> + </target> + <target depends="-profile-check,-profile-pre72" description="Profile a project in the IDE." if="profiler.configured" name="profile" unless="profiler.info.jvmargs.agent"> + <startprofiler/> + <antcall target="run"/> + </target> + <target depends="-profile-check,-profile-single-pre72" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-single" unless="profiler.info.jvmargs.agent"> + <fail unless="run.class">Must select one file in the IDE or set run.class</fail> + <startprofiler/> + <antcall target="run-single"/> + </target> + <target depends="-profile-test-single-pre72" description="Profile a selected test in the IDE." name="profile-test-single"/> + <target depends="-profile-check" description="Profile a selected test in the IDE." if="profiler.configured" name="profile-test" unless="profiler.info.jvmargs"> + <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail> + <startprofiler/> + <antcall target="test-single"/> + </target> + <target depends="-profile-check" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-test-with-main"> + <fail unless="run.class">Must select one file in the IDE or set run.class</fail> + <startprofiler/> + <antcal target="run-test-with-main"/> + </target> + <target depends="-profile-check,-profile-applet-pre72" if="profiler.configured" name="profile-applet" unless="profiler.info.jvmargs.agent"> + <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail> + <startprofiler/> + <antcall target="run-applet"/> + </target> + <!-- + =============== + JAVADOC SECTION + =============== + --> + <target depends="init" if="have.sources" name="-javadoc-build"> + <mkdir dir="${dist.javadoc.dir}"/> + <condition else="" property="javadoc.endorsed.classpath.cmd.line.arg" value="-J${endorsed.classpath.cmd.line.arg}"> + <and> + <isset property="endorsed.classpath.cmd.line.arg"/> + <not> + <equals arg1="${endorsed.classpath.cmd.line.arg}" arg2=""/> + </not> + </and> + </condition> + <condition else="" property="bug5101868workaround" value="*.java"> + <matches pattern="1\.[56](\..*)?" string="${java.version}"/> + </condition> + <javadoc additionalparam="-J-Dfile.encoding=${file.encoding} ${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}"> + <classpath> + <path path="${javac.classpath}"/> + </classpath> + <fileset dir="${src.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}"> + <filename name="**/*.java"/> + </fileset> + <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false"> + <include name="**/*.java"/> + <exclude name="*.java"/> + </fileset> + <arg line="${javadoc.endorsed.classpath.cmd.line.arg}"/> + </javadoc> + <copy todir="${dist.javadoc.dir}"> + <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}"> + <filename name="**/doc-files/**"/> + </fileset> + <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false"> + <include name="**/doc-files/**"/> + </fileset> + </copy> + </target> + <target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview"> + <nbbrowse file="${dist.javadoc.dir}/index.html"/> + </target> + <target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/> + <!-- + ========================= + TEST COMPILATION SECTION + ========================= + --> + <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test"> + <mkdir dir="${build.test.classes.dir}"/> + </target> + <target name="-pre-compile-test"> + <!-- Empty placeholder for easier customization. --> + <!-- You can override this target in the ../build.xml file. --> + </target> + <target if="do.depend.true" name="-compile-test-depend"> + <j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/> + </target> + <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test"> + <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" processorpath="${javac.test.processorpath}" srcdir="${test.src.dir}"/> + <copy todir="${build.test.classes.dir}"> + <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/> + </copy> + </target> + <target name="-post-compile-test"> + <!-- Empty placeholder for easier customization. --> + <!-- You can override this target in the ../build.xml file. --> + </target> + <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/> + <target name="-pre-compile-test-single"> + <!-- Empty placeholder for easier customization. --> + <!-- You can override this target in the ../build.xml file. --> + </target> + <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single"> + <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail> + <j2seproject3:force-recompile destdir="${build.test.classes.dir}"/> + <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" processorpath="${javac.test.processorpath}" sourcepath="${test.src.dir}" srcdir="${test.src.dir}"/> + <copy todir="${build.test.classes.dir}"> + <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/> + </copy> + </target> + <target name="-post-compile-test-single"> + <!-- Empty placeholder for easier customization. --> + <!-- You can override this target in the ../build.xml file. --> + </target> + <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/> + <!-- + ======================= + TEST EXECUTION SECTION + ======================= + --> + <target depends="init" if="have.tests" name="-pre-test-run"> + <mkdir dir="${build.test.results.dir}"/> + </target> + <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run"> + <j2seproject3:test includes="${includes}" testincludes="**/*Test.java"/> + </target> + <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run"> + <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail> + </target> + <target depends="init" if="have.tests" name="test-report"/> + <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/> + <target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/> + <target depends="init" if="have.tests" name="-pre-test-run-single"> + <mkdir dir="${build.test.results.dir}"/> + </target> + <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single"> + <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail> + <j2seproject3:test excludes="" includes="${test.includes}" testincludes="${test.includes}"/> + </target> + <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single"> + <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail> + </target> + <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/> + <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single-method"> + <fail unless="test.class">Must select some files in the IDE or set test.class</fail> + <fail unless="test.method">Must select some method in the IDE or set test.method</fail> + <j2seproject3:test excludes="" includes="${javac.includes}" testincludes="${test.class}" testmethods="${test.method}"/> + </target> + <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method" if="have.tests" name="-post-test-run-single-method"> + <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail> + </target> + <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method,-post-test-run-single-method" description="Run single unit test." name="test-single-method"/> + <!-- + ======================= + TEST DEBUGGING SECTION + ======================= + --> + <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test"> + <fail unless="test.class">Must select one file in the IDE or set test.class</fail> + <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testincludes="${javac.includes}"/> + </target> + <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test-method"> + <fail unless="test.class">Must select one file in the IDE or set test.class</fail> + <fail unless="test.method">Must select some method in the IDE or set test.method</fail> + <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testMethod="${test.method}" testincludes="${test.class}" testmethods="${test.method}"/> + </target> + <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test"> + <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/> + </target> + <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/> + <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/> + <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test"> + <j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/> + </target> + <target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/> + <!-- + ========================= + APPLET EXECUTION SECTION + ========================= + --> + <target depends="init,compile-single" name="run-applet"> + <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail> + <j2seproject1:java classname="sun.applet.AppletViewer"> + <customize> + <arg value="${applet.url}"/> + </customize> + </j2seproject1:java> + </target> + <!-- + ========================= + APPLET DEBUGGING SECTION + ========================= + --> + <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet"> + <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail> + <j2seproject3:debug classname="sun.applet.AppletViewer"> + <customize> + <arg value="${applet.url}"/> + </customize> + </j2seproject3:debug> + </target> + <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/> + <!-- + =============== + CLEANUP SECTION + =============== + --> + <target name="-deps-clean-init" unless="built-clean.properties"> + <property location="${build.dir}/built-clean.properties" name="built-clean.properties"/> + <delete file="${built-clean.properties}" quiet="true"/> + </target> + <target if="already.built.clean.${basedir}" name="-warn-already-built-clean"> + <echo level="warn" message="Cycle detected: easyprogrammer was already built"/> + </target> + <target depends="init,-deps-clean-init" name="deps-clean" unless="no.deps"> + <mkdir dir="${build.dir}"/> + <touch file="${built-clean.properties}" verbose="false"/> + <property file="${built-clean.properties}" prefix="already.built.clean."/> + <antcall target="-warn-already-built-clean"/> + <propertyfile file="${built-clean.properties}"> + <entry key="${basedir}" value=""/> + </propertyfile> + </target> + <target depends="init" name="-do-clean"> + <delete dir="${build.dir}"/> + <delete dir="${dist.dir}" followsymlinks="false" includeemptydirs="true"/> + </target> + <target name="-post-clean"> + <!-- Empty placeholder for easier customization. --> + <!-- You can override this target in the ../build.xml file. --> + </target> + <target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/> + <target name="-check-call-dep"> + <property file="${call.built.properties}" prefix="already.built."/> + <condition property="should.call.dep"> + <and> + <not> + <isset property="already.built.${call.subproject}"/> + </not> + <available file="${call.script}"/> + </and> + </condition> + </target> + <target depends="-check-call-dep" if="should.call.dep" name="-maybe-call-dep"> + <ant antfile="${call.script}" inheritall="false" target="${call.target}"> + <propertyset> + <propertyref prefix="transfer."/> + <mapper from="transfer.*" to="*" type="glob"/> + </propertyset> + </ant> + </target> +</project> diff --git a/nbproject/configs/crumb_2.properties b/nbproject/configs/crumb_2.properties new file mode 100644 index 0000000..e69de29 diff --git a/nbproject/configs/empty.properties b/nbproject/configs/empty.properties new file mode 100644 index 0000000..e69de29 diff --git a/nbproject/configs/nano.properties b/nbproject/configs/nano.properties new file mode 100644 index 0000000..e69de29 diff --git a/nbproject/configs/sure.properties b/nbproject/configs/sure.properties new file mode 100644 index 0000000..e69de29 diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties new file mode 100644 index 0000000..4eef77a --- /dev/null +++ b/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=e013f057 +build.xml.script.CRC32=50389c62 +build.xml.stylesheet.CRC32=8064a381@1.75.2.48 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=e013f057 +nbproject/build-impl.xml.script.CRC32=034e3503 +nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48 diff --git a/nbproject/project.properties b/nbproject/project.properties new file mode 100644 index 0000000..2625832 --- /dev/null +++ b/nbproject/project.properties @@ -0,0 +1,76 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=easyprogrammer +application.vendor=steiner +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/easyprogrammer.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.jssc-2.8.0.jar=jssc-2.8.0.jar +includes=** +jar.compress=false +javac.classpath=\ + ${file.reference.jssc-2.8.0.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.external.vm=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.7 +javac.target=1.7 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class=at.htlkaindorf.sx.EasyProgrammer.gui.EasyProgrammer +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..0be439a --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://www.netbeans.org/ns/project/1"> + <type>org.netbeans.modules.java.j2seproject</type> + <configuration> + <data xmlns="http://www.netbeans.org/ns/j2se-project/3"> + <name>easyprogrammer</name> + <source-roots> + <root id="src.dir"/> + </source-roots> + <test-roots> + <root id="test.src.dir"/> + </test-roots> + </data> + </configuration> +</project> diff --git a/released/easyprogrammer.jar b/released/easyprogrammer.jar new file mode 100644 index 0000000..1998e82 Binary files /dev/null and b/released/easyprogrammer.jar differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/data/ByteFifo.java b/src/at/htlkaindorf/sx/EasyProgrammer/data/ByteFifo.java new file mode 100644 index 0000000..88e3926 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/data/ByteFifo.java @@ -0,0 +1,113 @@ +package at.htlkaindorf.sx.EasyProgrammer.data; + +/** + * + * @author steiner + */ +public class ByteFifo +{ + private final Object lock = new Object(); + private byte [] buffer; + private int wIndex; + private int rIndex; + private int available; + + + public ByteFifo (int size) + { + buffer = new byte [size]; + } + + public void push (byte b) + { + synchronized (lock) + { + if (available == buffer.length) + { + byte [] oldBuffer = buffer; + buffer = new byte[buffer.length*2]; + for (int i=0; i<available; i++) + { + int ri = (rIndex + i)%oldBuffer.length; + buffer[i] = oldBuffer[ri]; + } + rIndex = 0; + wIndex = available; + buffer[available++] = b; + } + else + { + buffer[wIndex] = b; + available++; + if (wIndex>=buffer.length) + wIndex = 0; + } + } + } + + public void push (byte [] ba) + { + synchronized (lock) + { + if ((available+ba.length) >= buffer.length) + { + byte [] oldBuffer = buffer; + buffer = new byte[buffer.length*2]; + for (int i=0; i<available; i++) + { + int ri = (rIndex + i)%oldBuffer.length; + buffer[i] = oldBuffer[ri]; + } + rIndex = 0; + wIndex = available; + for (byte b : ba) + buffer[available++] = b; + } + else + { + for (byte b : ba) + { + buffer[wIndex++] = b; + if (wIndex>=buffer.length) + wIndex = 0; + available++; + } + } + } + } + + + public int pop () + { + synchronized (lock) + { + if (available<=0) + return -1; + byte rv = buffer[rIndex++]; + available--; + if (rIndex>=buffer.length) + rIndex = 0; + return rv<0 ? (int)rv+256 : (int)rv; + } + } + + + public int available () + { + synchronized (lock) + { + return available; + } + } + + public void flush () + { + synchronized (lock) + { + available = 0; + rIndex = 0; + wIndex = 0; + } + } + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/data/CpuTyp.java b/src/at/htlkaindorf/sx/EasyProgrammer/data/CpuTyp.java new file mode 100644 index 0000000..ecbddec --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/data/CpuTyp.java @@ -0,0 +1,241 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.htlkaindorf.sx.EasyProgrammer.data; + +/** + * + * @author steiner + */ +public class CpuTyp +{ + public enum Typ {Unknown, UserSpecified, Atmega324P, Atmega328P, + Atmega328, Atmega16, Atmega8L, + AT90CAN128, Atmega1284P }; + + private Typ typ; + private int bootloaderSize; + private int flashSize; + private int pageSize; + private String resetCommand; + + public CpuTyp(Typ typ) + { + this.typ = typ; + } + + + public CpuTyp(Typ typ, int bootloaderSize, String resetCommand) + { + this.typ = typ; + this.bootloaderSize = bootloaderSize; + this.resetCommand = resetCommand; + } + + + public int getFlashSize () + { + switch (typ) + { + case Atmega8L: return 8*1024; + case Atmega16: return 16*1024; + case Atmega324P: return 32*1024; + case Atmega328 : return 32*1024; + case Atmega328P: return 32*1024; + case AT90CAN128: return 0x20000; + case Atmega1284P: return 128*1024; + case UserSpecified: if (this.flashSize>0) return this.flashSize; break; + } + throw new RuntimeException("CPU-Typ not known"); + } + + + public int getPageSize () + { + switch (typ) + { + case Atmega8L: return 64; + case Atmega16: return 128; + case Atmega324P: return 128; + case Atmega328 : return 128; + case Atmega328P: return 128; + case AT90CAN128: return 256; + case Atmega1284P: return 256; + case UserSpecified: if (this.pageSize>0) return this.pageSize; break; + } + throw new RuntimeException("CPU-Typ not known"); + } + + public int getPages () throws Exception + { + return this.getFlashSize()/this.getPageSize(); + } + + public String getName () + { + if (this.typ != Typ.Unknown) + return this.typ.toString(); + throw new RuntimeException("CPU-Typ not known"); + } + + public String getDescription () + { + return String.format("%s (%dKiB, %d Bytes per Page)", typ.name(), getFlashSize()/1024, getPageSize()); + } + + public String[] getAvailableNames () + { + String [] s = new String[Typ.values().length-1]; + + int i=0; + for (Typ t : Typ.values()) + { + if (t != Typ.Unknown && t != Typ.UserSpecified) + s[i++] = t.toString(); + } + + return s; + } + + + public void setTyp(Typ typ) + { + this.typ = typ; + } + + public void setTyp(String typName) throws Exception + { + for (Typ t : Typ.values()) + { + if (t != Typ.Unknown && typName.equals(t.toString())) + { + this.typ = t; + return; + } + } + throw new Exception("CPU-Typ not known"); + } + + + public String getResetCommand () + { + return resetCommand; + } + + + public void setResetCommand (String resetCommand) + { + this.resetCommand = resetCommand; + } + + + public void setBootloaderSize(int bootloaderSize) + { + this.bootloaderSize = bootloaderSize; + } + + public int getBootloaderSize () + { + return bootloaderSize; + } + + public int getBootloaderSizeIndex () throws Exception + { + switch (typ) + { + case Atmega8L: + case Atmega16: + case Atmega324P: + case Atmega328: + case Atmega328P: + case AT90CAN128: + switch (bootloaderSize) + { + case 0: return 0; + case 512: return 1; + case 1024: return 2; + case 2048: return 3; + default: throw new Exception("Unvalid Bootloader size"); + } + } + throw new RuntimeException("CPU-Typ not known"); + } + + + public int getBootloaderBytes (int index) throws Exception + { + switch (typ) + { + case Atmega1284P: + switch (index) + { + case 0: return 1024; + case 1: return 2048; + case 2: return 4096; + case 3: return 8192; + default: throw new Exception ("index out of range"); + } + + case Atmega328P: case Atmega16: case Atmega8L: + switch (index) + { + case 0: return 0; + case 1: return 512; + case 2: return 1024; + case 3: return 2048; + default: throw new Exception ("index out of range"); + } + + case UserSpecified: + switch (index) + { + case 0: return 0; + case 1: return bootloaderSize; + default: throw new Exception ("index out of range"); + } + + } + throw new RuntimeException("CPU-Typ not known"); + } + + + public String[] getAvailableBootloaderSizes () + { + return getBootloaderSizeTypes().split(","); + } + + + public String getBootloaderSizeTypes() + { + switch (typ) + { + case Atmega328P: return "No Bootloader,512 Bytes,1024 Bytes,2048 Bytes"; + case Atmega16: return "No Bootloader,512 Bytes,1024 Bytes,2048 Bytes"; + case Atmega8L: return "No Bootloader,512 Bytes,1024 Bytes,2048 Bytes"; + case Atmega1284P: return ("1024 Bytes,2048 Bytes,4096 Bytes,8192 Bytes"); + case UserSpecified: return String.format("No Bootloader,%d Bytes", bootloaderSize); + } + throw new RuntimeException("CPU-Typ not known"); + } + + + public void setFlashSize(int flashSize) + { + this.flashSize = flashSize; + } + + + public void setPageSize(int pageSize) + { + this.pageSize = pageSize; + } + + + public Typ getTyp() + { + return typ; + } + + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/data/LineTerminal.java b/src/at/htlkaindorf/sx/EasyProgrammer/data/LineTerminal.java new file mode 100644 index 0000000..775fcb2 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/data/LineTerminal.java @@ -0,0 +1,349 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.htlkaindorf.sx.EasyProgrammer.data; + +import java.awt.Point; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; + +/** + * Simple Line-Terminal with special ctrl codes '\n','\r','\b'.</BR> + * @author Manfred Steiner + */ +public class LineTerminal extends Terminal +{ + private static final int DEFAULT_STRING_SIZE = 128; + public static final int MODE_NL_IS_CR = 0; + + private Point cursorPos; + + private int mode; + private int numberOfLines; // number of lines available in text[] + private int firstLine; // first line number in text[] + private int lastLine; // last line number in text[] + private int start; // index of 'firstLine' + private int maxColumnsIndex; // index of line with largest number of columns + private int columns; // needed number of columns + private StringBuilder [] data; // byte representation of terminal content (for debugging purposes) + private StringBuilder [] text; // text representation of terminal content (for text output) + + + public LineTerminal (int numberOfLines) + { + super(); + this.numberOfLines = numberOfLines; + this.cursorPos = new Point(0,0); + this.data = new StringBuilder [this.numberOfLines]; + this.text = new StringBuilder [this.numberOfLines]; + for (int i=0; i<this.numberOfLines; i++) + { + this.data[i] = new StringBuilder(DEFAULT_STRING_SIZE); + this.text[i] = new StringBuilder(DEFAULT_STRING_SIZE); + } + } + + public boolean isTextAvailable (int line, int pos) + { + int i = getIndex(line); + if (i<0 || pos>=this.text[i].length()) + return false; + return true; + } + + + public boolean isLineAvailable (int line, int pos) + { + int i = getIndex(line); + if (i<0) + return false; + return true; + } + + + public char getText (int line, int pos) throws IndexOutOfBoundsException + { + int i = getIndex(line); + if (i<0 || pos<0 || pos>=text[i].length()) + throw new IndexOutOfBoundsException(); + + return text[i].charAt(pos); + } + + + public String getText (int line) throws IndexOutOfBoundsException + { + int i = getIndex(line); + if (i<0) + throw new IndexOutOfBoundsException(); + + return text[i].toString(); + } + + + public void append (char c) + { + switch (c) + { + case '\n': ctrl_nl(); return; + case '\r': ctrl_cr(); return; + case '\b': ctrl_bs(); return; + } + + int i = getIndex(this.cursorPos.y); + if (this.cursorPos.x >= this.text[i].length()) + { + this.text[i].append(c); + this.data[i].append(c); + } + else + { + this.text[i].setCharAt(this.cursorPos.x, c); + this.data[i].append(c); + } + if (this.text[i].length()>this.columns) + { + this.columns = this.text[i].length(); + this.maxColumnsIndex = i; + } + this.cursorPos.x++; + } + + + public void append (String s) + { + for (int i=0; i<s.length(); i++) + this.append(s.charAt(i)); + } + + + public void append (byte b) + { + this.append((char) b); + } + + public void append (byte [] b, int numberOfbytes) + { + for (int i=0; i<b.length && i<numberOfbytes; i++) + this.append(b[i]); + } + + public void append (byte [] b) + { + for (int i=0; i<b.length; i++) + this.append(b[i]); + } + + + @Override + public int getLines() + { + return this.lastLine-this.firstLine + 1; + } + + public int getFirstLine () + { + return this.firstLine; + } + + + public int getLastLine () + { + return this.lastLine; + } + + public int getCursorLine () + { + return this.cursorPos.y; + } + + + public void copyToClipboard (Clipboard clip) + { + //Clipboard clip = getToolkit().getSystemClipboard(); + StringSelection cont; + StringBuilder str = new StringBuilder(128); + + for (int z=0; z<this.getLines(); z++) + { + str.append(this.getText(z)).append("\n"); + } + + cont = new StringSelection(str.toString()); + clip.setContents(cont, null); + } + + + public void deleteContent () + { + this.cursorPos = new Point(0,0); + this.data = new StringBuilder [this.numberOfLines]; + this.text = new StringBuilder [this.numberOfLines]; + for (int i=0; i<this.numberOfLines; i++) + { + this.data[i] = new StringBuilder(DEFAULT_STRING_SIZE); + this.text[i] = new StringBuilder(DEFAULT_STRING_SIZE); + } + this.firstLine = 0; + this.lastLine = 0; + this.start = 0; + this.maxColumnsIndex = 0; + this.columns = 0; + } + + + @Override + public int getColumns() + { + return this.columns; + } + + + @Override + public int length (int line) + { + int i = getIndex(line); + if (i>=0) + return text[i].length(); + return 0; + } + + + @Override + public String toString() + { + return this.getClass().getCanonicalName() + "[" + + "length=" + this.text.length + + ",lines=" + this.getLines() + + ",columns=" + this.getColumns() + + ",first=" + this.firstLine + + ",last=" + this.lastLine + + ",start=" + this.start + + ",maxColumnsIndex=" + this.maxColumnsIndex + + "]"; + } + + + + + /* ********************************************************************* + * private methods + ********************************************************************** */ + + private int getIndex (int line) + { + if (line<this.firstLine || line>this.lastLine) + return -1; + int index = line - this.firstLine + this.start; + if (index>=this.numberOfLines) + index -= this.numberOfLines; + return index; + } + + + private void ctrl_nl () + { + if (mode != LineTerminal.MODE_NL_IS_CR) + throw new RuntimeException("not supported yet"); + + int i = getIndex(this.cursorPos.y); + this.data[i].append('\n'); + + this.cursorPos.y++; + this.cursorPos.x = 0; + + if (this.getIndex(this.cursorPos.y)<0) + { + this.lastLine++; + if (getIndex(lastLine) == getIndex(firstLine)) + { + this.start++; + if (this.start >= this.numberOfLines) + this.start = 0; + this.firstLine++; + } + i = this.getIndex(this.cursorPos.y); + if (text[i].length()>0) + { + if (text[i].length()>DEFAULT_STRING_SIZE*8) + text[i] = new StringBuilder(DEFAULT_STRING_SIZE); + else + text[i].delete(0, text[i].length()); + + if (data[i].length()>DEFAULT_STRING_SIZE*8) + data[i] = new StringBuilder(DEFAULT_STRING_SIZE); + else + data[i].delete(0, data[i].length()); + } + + if (this.maxColumnsIndex == i) + { + this.columns = 0; + for (i=0; i<text.length; i++) + { + if (text[i].length() > columns) + { + columns = text[i].length(); + maxColumnsIndex = i; + } + } + } + + } + } + + + private void ctrl_cr () + { + if (mode != LineTerminal.MODE_NL_IS_CR) + throw new RuntimeException("not supported yet"); + + int i = getIndex(this.cursorPos.y); + this.data[i].append('\r'); + this.cursorPos.x = 0; + } + + private void ctrl_bs () + { + if (mode != LineTerminal.MODE_NL_IS_CR) + throw new RuntimeException("not supported yet"); + + int i = getIndex(this.cursorPos.y); + this.data[i].append('\b'); + + if (this.cursorPos.x>0) + this.cursorPos.x--; + } + + + + + public static void main(String[] args) + { + LineTerminal t = new LineTerminal(4); + t.append("Line 0\n"); + t.append("Line 1\n"); + t.append("Line 2\n"); + t.append("Line 3\n"); + t.append("Line 4\n"); + t.append("Line 5\n"); + t.append("Line 6\n"); + t.append("Line 7"); + System.out.println(" Lines=" + t.getLines()); + System.out.println(t.getText(4)); + System.out.println(t.getText(5)); + System.out.println(t.getText(6)); + System.out.println(t.getText(7)); + System.out.println(t); + + } + + + + + + + + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/data/MemoryContent.java b/src/at/htlkaindorf/sx/EasyProgrammer/data/MemoryContent.java new file mode 100644 index 0000000..9ed1b76 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/data/MemoryContent.java @@ -0,0 +1,399 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.htlkaindorf.sx.EasyProgrammer.data; + +import java.util.Iterator; + +/** + * Content and paramters of the µC memory.</BR> + * @author steiner + */ +public final class MemoryContent implements Iterable +{ + private int [][] mem; + private int size; + private int pages; + private int pageSize; + private boolean complete; + private int validBytes; + private int validPages; + private MemoryContent oldMemoryContent; + private boolean modeString; + final private String headerFormat; + + /** + * Constructor with flash memory size and page-size (in bytes).<br> + * Default value for the ATmega328P is: size=32768, pageSize=128 + * @param size Flash memory size in number of bytes. + * @param pageSize Size of one page (programable unit) in flash memory. + * @throws RuntimeException in case of size or pageSize is less than or equal to zero.. + */ + public MemoryContent(int size, int pageSize, String headerFormat) throws RuntimeException + { + this.size = size; + this.pages = size / pageSize; + this.pageSize = pageSize; + this.mem = null; + this.modeString = true; + this.headerFormat = headerFormat; + clearMemory(); + } + + + public void setModeString(boolean modeString) + { + this.modeString = modeString; + } + + + public void clearMemory () throws RuntimeException + { + if (this.pages<=0 || this.pageSize<=0) + throw new RuntimeException("pages and/or pageSize must be greater than 0"); + + if (this.mem == null) + { + this.mem = new int [pages] []; + for (int i=0; i<pages; i++) + this.mem[i] = null; + } + + for (int i=0; i<pages; i++) + { + if (mem[i]==null) + mem[i] = new int [pageSize]; + for (int j=0; j<pageSize; j++) + mem[i][j] = -1; + } + + this.validBytes = 0; + } + + + + public int getValidBytes () + { + return validBytes; + } + + public int getValidPages () + { + return validPages; + } + + + public int getPageSize() + { + return pageSize; + } + + + public int getPages() + { + return pages; + } + + + public int getSize() + { + return size; + } + + + public void setMemoryByte (int address, int value) throws Exception + { + if (address<0 || address>=this.size) + throw new Exception("address out of range"); + + if (isComplete()) + throw new Exception("memory is set completly"); + + int page = address / this.pageSize; + int pos = address % this.pageSize; + this.mem[page][pos] = value; + } + + + public int byteAt (int address) throws Exception + { + if (address<0 || address>=this.size) + throw new Exception("address out of range"); + + int page = address / this.pageSize; + int offset = address % this.pageSize; + return this.mem[page][offset]; + } + + + public int byteAt (int page, int offset) throws Exception + { + if (page<0 || page>=this.pages || offset<0 || offset>=this.pageSize) + throw new Exception("address via page/offset is out of range"); + + return this.mem[page][offset]; + } + + + public boolean isByteDownloadNeeded (int page, int offset) + { + if (page<0 || page>=this.pages || offset<0 || offset>=this.pageSize) + return false; + + if (this.oldMemoryContent != null) + { + try + { + int old = this.oldMemoryContent.byteAt(page,offset); + int act = this.byteAt(page, offset); + if (act<0 || act>255 || act == old) + return false; + } + catch (Exception ex) { } + } + { + if (page<0 || page>=this.pages || offset<0 || offset>=this.pageSize) + return false; + + } + + if (this.mem[page][offset]<0 || this.mem[page][offset]>255) + return false; + + return true; + } + + + public boolean isComplete() + { + return complete; + } + + + public void setComplete(boolean complete) + { + if (complete == false) + throw new RuntimeException("not allowed"); + + if (this.complete == false && complete==true) + { + this.complete = true; + this.validBytes = 0; + this.validPages = 0; + for (int i=0; i<this.pages; i++) + { + boolean valid = false; + for (int j=0; j<this.pageSize; j++) + { + if (mem[i][j]>=0 && mem[i][j]<=255) + { + this.validBytes++; + valid = true; + } + } + if (valid) + this.validPages++; + } + } + } + + + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(128); + sb.append(this.getClass().getCanonicalName()); + sb.append("["); + sb.append("size="); sb.append(size); + sb.append(", pages="); sb.append(pages); + sb.append(", pageSize="); sb.append(pageSize); + sb.append(", validBytes="); sb.append(validBytes); + sb.append("]\n"); + + sb.append("mem["); sb.append(mem.length); sb.append("]["); + sb.append(mem[0].length); sb.append("]="); + for (int i=0; i<this.pages; i++) + { + sb.append(String.format("\n%04x: ", i*this.pageSize)); + for (int j=0; j<this.pageSize; j++) + { + if (mem[i][j]>=0 && mem[i][j]<=255) + sb.append(String.format(" %02x", mem[i][j])); + else + sb.append(" "); + } + } + + return sb.toString(); + } + + + public void setOldMemoryContent (MemoryContent oldMemoryContent) + { + this.oldMemoryContent = oldMemoryContent; + } + + + public Iterator<String> iterator() + { + if (this.modeString) + return new StringIterator(this); + return new ByteIterator(this); + } + + + private class StringIterator implements Iterator + { + MemoryContent mem; + int page; + int pos; + StringBuilder sb; + + public StringIterator(MemoryContent mem) + { + this.mem = mem; + sb = new StringBuilder(256); + } + + public String next () + { + sb.delete(0, sb.length()); + + while (mem.mem[page] != null) + { + int j; + for (j=0; j<mem.pageSize; j++) + { + if (mem.mem[page][j]>=0 && mem.mem[page][j]<=255) + break; + } + if (j<mem.pageSize) + { + sb.append(String.format(headerFormat, page)); + for (j=0; j<mem.pageSize; j++) + { + if (mem.mem[page][j]>=0 && mem.mem[page][j]<=255) + sb.append(String.format("%02X", mem.mem[page][j])); + else + sb.append("00"); + } + page++; + break; + } + page++; + } + + if (sb.length()==0) + return null; + + return sb.toString(); + } + + + public boolean hasNext() + { + while (page<mem.getPageSize() && mem.mem[page] != null) + { + int j; + for (j=0; j<mem.pageSize; j++) + { + if (mem.isByteDownloadNeeded(page,j)) + break; + // if (mem.mem[page][j]>=0 && mem.mem[page][j]<=255) + // break; + } + if (j<mem.pageSize) + return true; + + page++; + } + return false; + } + + public void remove() + { + page++; + } + + } + + private class ByteIterator implements Iterator + { + MemoryContent mem; + int page; + int pos; + byte [] b; + + public ByteIterator(MemoryContent mem) + { + this.mem = mem; + String s = String.format(headerFormat, 0); + b = new byte[mem.getPageSize()+s.length()]; + } + + public byte [] next () + { + for (int i=0; i<b.length; i++) + b[i] = 0; + + while (mem.mem[page] != null) + { + int j; + for (j=0; j<mem.pageSize; j++) + { + if (mem.mem[page][j]>=0 && mem.mem[page][j]<=255) + break; + } + if (j<mem.pageSize) + { + String s = String.format(headerFormat, page); + int k; + for (k=0; k<s.length(); k++) + b[k] = (byte)s.charAt(k); + + for (j=0; j<mem.pageSize; j++) + { + if (mem.mem[page][j]>=0 && mem.mem[page][j]<=255) + b[j+k] = (byte)mem.mem[page][j]; + } + page++; + break; + } + page++; + } + + return b; + } + + + public boolean hasNext() + { + while (page<mem.pages && mem.mem[page] != null) + { + int j; + for (j=0; j<mem.pageSize; j++) + { + if (mem.isByteDownloadNeeded(page,j)) + break; + // if (mem.mem[page][j]>=0 && mem.mem[page][j]<=255) + // break; + } + if (j<mem.pageSize) + return true; + + page++; + } + return false; + } + + public void remove() + { + page++; + } + + } + + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/data/ProgramFile.java b/src/at/htlkaindorf/sx/EasyProgrammer/data/ProgramFile.java new file mode 100644 index 0000000..ebcae2b --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/data/ProgramFile.java @@ -0,0 +1,254 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.htlkaindorf.sx.EasyProgrammer.data; + + +import at.htlkaindorf.sx.EasyProgrammer.gui.DialogSelectProgramFile; +import java.io.*; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.TimeZone; + +/** + * + * @author steiner + */ +public class ProgramFile implements Iterable +{ + private byte [] hexData; + private byte [] rsnData; + private CpuTyp cpu; + private MemoryContent memoryContent; + private MemoryContent oldMemoryContent; + private ArrayList<String> errorList; + private long lastModified; + private int bootloaderMode; + + DialogSelectProgramFile dialogSelectProgramFile; + + public ProgramFile(DialogSelectProgramFile dialogSelectProgramFile, CpuTyp target) + { + this.dialogSelectProgramFile = dialogSelectProgramFile; + cpu = target; + //cpu = ProgramFile.CpuTyp.ATMEGA328P; + //cpu = ProgramFile.CpuTyp.ATMEGA8L; + } + + + public void setCpu(CpuTyp cpu) throws Exception + { + this.cpu = cpu; + loadFile(); + } + + public CpuTyp getCpu() + { + return cpu; + } + + public int getHexLength() + { + if (hexData == null) + return 0; + return hexData.length; + } + + public int getRsnLength() + { + if (rsnData == null) + return 0; + return rsnData.length; + } + + public int getMemoryLength () + { + if (this.memoryContent==null) + return 0; + return this.memoryContent.getValidBytes(); + } + + + public int getMemoryPages () + { + if (this.memoryContent==null) + return 0; + + return this.memoryContent.getValidPages(); + } + + + public ArrayList<String> getErrorList() + { + return errorList; + } + + + public int getBootloaderMode() + { + return bootloaderMode; + } + + + + public void setBootloaderMode(int bootloaderMode) + { + this.bootloaderMode = bootloaderMode; + + if (this.memoryContent != null) + switch (bootloaderMode) + { + case 0: this.memoryContent.setModeString(true); break; + case 1: this.memoryContent.setModeString(true); break; + case 2: this.memoryContent.setModeString(false); break; + case 3: this.memoryContent.setModeString(false); break; + } + + if (this.oldMemoryContent != null) + switch (bootloaderMode) + { + case 0: this.oldMemoryContent.setModeString(true); break; + case 1: this.oldMemoryContent.setModeString(true); break; + case 2: this.oldMemoryContent.setModeString(false); break; + case 3: this.oldMemoryContent.setModeString(false); break; + } + + } + + + public String getBootloaderStartCmd () + { + if (this.memoryContent == null) + return null; + + switch(this.bootloaderMode) + { + case 0: return "@m00@f" + this.memoryContent.getPageSize(); + case 1: return "@m01@s0c@f" + this.memoryContent.getPageSize(); + case 2: return "@m02@f" + this.memoryContent.getPageSize(); + case 3: return "@m03@s0c@f" + this.memoryContent.getPageSize(); + } + return null; + } + + public void completeDownloadDone () + { + this.oldMemoryContent = this.memoryContent; + } + + + public void loadFile () throws Exception + { + if (this.memoryContent != null) + { + this.oldMemoryContent = this.memoryContent; + this.memoryContent = null; + this.hexData = null; + this.rsnData = null; + this.lastModified = 0L; + this.errorList = null; + } + + if (this.dialogSelectProgramFile==null) + throw new RuntimeException("Cannot get path/file infos..."); + + String fileName = this.dialogSelectProgramFile.getFolderName() + this.dialogSelectProgramFile.getFileName(); + + FileInputStream is; + try + { + File f = new File(fileName); + lastModified = f.lastModified(); + is = new FileInputStream(fileName); + } + catch (FileNotFoundException ex) + { + throw new Exception("Datei '" + fileName + "' kann nicht geöffnet werden (" + ex.getMessage() + ")"); + } + catch (SecurityException ex) + { + throw new Exception("Datei '" + fileName + "' kann nicht geöffnet werden (" + ex.getMessage() + ")"); + } + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + RSNOutputStream ros = new RSNOutputStream(os); + ros.setParameter(cpu.getPageSize(), cpu.getFlashSize(), cpu); + + if (is !=null && os != null) + { + byte [] b = new byte [8192]; + int len = 0; + do + { + len = is.read(b); + if (len>0) + ros.write(b, 0, len); + } + while (len>0); + hexData = os.toByteArray(); + this.memoryContent = ros.getMemoryContent(); + this.errorList = ros.getErrorList(); + //System.out.println(this.memoryContent); + os.close(); + ros.close(); + os = null; + //for (int i=0; i<hexData.length; i++) + //System.out.print((char)hexData[i]); + } + + if (is != null) + is.close(); + is = null; + } + + public boolean isAvailable () + { + return dialogSelectProgramFile.getFolderName() != null && dialogSelectProgramFile.getFileName() != null; + } + + public boolean isModified () + { + if (this.dialogSelectProgramFile.getFolderName() == null || this.dialogSelectProgramFile.getFileName() == null) + return false; + + String fileName = this.dialogSelectProgramFile.getFolderName() + this.dialogSelectProgramFile.getFileName(); + File f = new File(fileName); + if (lastModified == f.lastModified()) + return false; + + return true; + } + + public String getLastModifiedString () + { + Date when = new Date(lastModified); + //SimpleDateFormat sdf = new SimpleDateFormat( "EEEE yyyy/MM/dd hh:mm:ss aa zz : zzzzzz" ); + SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd / HH:mm:ss" ); + sdf.setTimeZone(TimeZone.getDefault()); // local time + String str = sdf.format(when); + return str; + } + + + public void setDownloadModeFast (boolean modeFast) + { + if (memoryContent != null) + { + if (modeFast == true) + memoryContent.setOldMemoryContent(this.oldMemoryContent); + else + memoryContent.setOldMemoryContent(null); + } + } + + public Iterator iterator() + { + return this.memoryContent.iterator(); + } + + + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/data/RSNOutputStream.java b/src/at/htlkaindorf/sx/EasyProgrammer/data/RSNOutputStream.java new file mode 100644 index 0000000..f932873 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/data/RSNOutputStream.java @@ -0,0 +1,304 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.htlkaindorf.sx.EasyProgrammer.data; + +import java.io.*; +import java.util.ArrayList; + +/** + * + * @author steiner + */ +public class RSNOutputStream extends FilterOutputStream +{ + private MemoryContent memoryContent; + private int address; + private int offset; // always zero if Intel Hex Record Typ 2,3,4 not supported + private char [] line; + private int linePos; + private int lineNumber; + private boolean fileComplete; + private ArrayList<String> errorList; + private CpuTyp cpu; + private String headerFormat; + + public RSNOutputStream(OutputStream out) + { + super(out); + //this.out = out; + } + + + public void setParameter (int pageSize, int memorySize, CpuTyp cpu) + { + if (memorySize % pageSize != 0) + throw new RuntimeException("Pagesize " + pageSize + " doesn't fit to memorysize " + memorySize); + + this.cpu = cpu; + if (cpu.getFlashSize()/cpu.getPageSize() > 256) + headerFormat = "P%03X"; + else + headerFormat = "P%02X"; + memoryContent = new MemoryContent(memorySize, pageSize, headerFormat); + this.line = new char [43]; + this.lineNumber = 1; + } + + + public MemoryContent getMemoryContent() + { + return memoryContent; + } + + + public ArrayList<String> getErrorList() + { + return errorList; + } + + + @Override + public void close() throws IOException + { + super.close(); + } + + + @Override + public void flush() throws IOException + { + super.flush(); + memoryContent = new MemoryContent(32768, 128, headerFormat); + address = 0; + linePos = 0; + this.lineNumber = 1; + fileComplete = false; + } + + + @Override + public void write(int b) throws IOException + { + //super.write(b); + if (b<0 || b>255) + throw new IOException("b out of range"); + + if (b == 13) return; + if (b == 10) + { + //if (lineNumber==625) + // System.out.println("Test"); + + try { executeIntelHexLine(line, linePos - 1); } + catch (Exception ex) + { + if (errorList==null) + errorList = new ArrayList<String>(); + errorList.add("Fehler in Zeile " + lineNumber + ": " + ex.getMessage()); + } + lineNumber++; + linePos = 0; + return; + } + + if (b == ':') + { + if (linePos > 0) + throw new IOException("':' only allowed on first position of a line"); + } + else if ( !((b>='0' && b<='9') || (b>='A' && b<='F') || (b>='a' && b<='f')) ) + throw new IOException("'" + (char) b + "' is not a hexadecimal digit"); + + if (linePos>=line.length) + throw new IOException("Size of line " + lineNumber + " too large"); + + line[linePos++] = (char) b; + } + + + @Override + public void write(byte[] b) throws IOException + { + for (int i= 0; i<b.length; i++) + { + if (b[i]<0) write(b[i]+256); + else write(b[i]); + } + } + + + @Override + public void write(byte[] b, int off, int len) throws IOException + { + for (int i=0; i<len; i++) + { + if (b[i+off]<0) write(b[i+off]+256); + else write(b[i+off]); + } + } + + + void executeIntelHexLine (char [] line, int bytes) throws Exception + { + String errMsg = null; + + if (line[0] != ':') + throw new Exception("Kein Intel-Hex Format, ':' fehlt als erstes Zeichen"); + + if (line.length<4) + throw new Exception("Kein Intel-Hex Format, Zeile zu kurz"); + + StringBuilder sb = new StringBuilder(" "); + int chksum = 0; + int [] b = new int [21]; + + //System.out.print("Intel-Hex :"); + for (int i=0; i<(line.length-1)/2; i++) + { + sb.setCharAt(0, line[i*2+1]); + sb.setCharAt(1, line[i*2+2]); + b[i] = Integer.parseInt(sb.toString(), 16); + if (i==0 && b[i] > (line.length-1)/2-5) + throw new Exception("Intel-Hex Format - Länge fehlerhaft"); + //System.out.print(" " + Integer.toHexString(b[i])); + if (i<(line.length-1)/2-1 && i<(b[0]+4)) + chksum += b[i]; + else + { + chksum = (256 - chksum % 256) % 256; + //chksum = (256 - chksum % 256); + if (b[i] != chksum) + throw new Exception("Intel-Hex Format Checksum-Fehler"); + //System.out.println(" - Checksum ok"); + switch (b[3]) + { + case 0: // Binaerdaten + executeIntelHexTyp00(b); + break; + + case 1: // File-Ende + executeIntelHexTyp01(b); + break; + + case 2: // Extended Segment Address + throw new Exception("Intel-Hex Format - Typ 02 not supported yet"); + + case 3: // Start Segment Address Record + throw new Exception("Intel-Hex Format - Typ 03 not supported yet"); + + case 4: // Extended Linear Address Record + throw new Exception("Intel-Hex Format - Typ 04 not supported yet"); + + case 5: // Start Linear Address Record + throw new Exception("Intel-Hex Format - Typ 05 not supported yet"); + + default: + throw new Exception("Intel-Hex Format - Unbekannter Record Typ"); + } + + return; + } + } + + throw new RuntimeException("Intel-Hex Format: unerwartetes Ende"); + } + + private void executeIntelHexTyp00(int [] b) throws Exception + { + if (b[3] != 0) + throw new RuntimeException("Falscher Typ"); + int add = this.offset + b[1]*256+b[2]; + int len = b[0]; + int page; + int pos; + for (int i=0; i<len; i++) + { + add = this.offset + b[1]*256+b[2] + i; + try { this.memoryContent.setMemoryByte(add, b[i+4]); } + catch (Exception ex) + { + throw new Exception("Intel Hex - " + ex.getMessage()); + } + } + } + + private void executeIntelHexTyp01(int [] b) throws Exception + { + if (b[3] != 1) + throw new RuntimeException("Falscher Typ"); + fileComplete = true; + if (this.out != null) + { + byte [] bout = new byte [this.memoryContent.getPageSize()]; + boolean isEmpty; + try + { + for (int i=0; i<this.memoryContent.getPages(); i++) + { + isEmpty = true; + for (int j=0; j<this.memoryContent.getPageSize(); j++) + if (this.memoryContent.byteAt(i,j)>=0) isEmpty = false; + if (!isEmpty) + { + out.write((byte)'P'); + String str = String.format("%02X", i); + out.write((byte)str.charAt(0)); + out.write((byte)str.charAt(1)); + for (int j=0; j<this.memoryContent.getPageSize(); j++) + { + if (this.memoryContent.byteAt(i,j)<0 ||this.memoryContent.byteAt(i,j)>255) + str = "00"; + else + str = String.format("%02X", this.memoryContent.byteAt(i,j)); + out.write((byte)str.charAt(0)); + out.write((byte)str.charAt(1)); + } + out.write(10); + } + } + out.write('F'); + out.write('F'); + out.write('F'); + } + catch (IOException ex) + { + throw new Exception("IOException - " + ex.getMessage()); + } + } + memoryContent.setComplete(true); + } + + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(128); + sb.append(this.getClass().getCanonicalName()); + sb.append("["); + sb.append("address="); sb.append(address); + sb.append(", offset="); sb.append(offset); + sb.append(", linePos="); sb.append(linePos); + sb.append(", lineNumber="); sb.append(lineNumber); + sb.append(", fileComplete="); sb.append(fileComplete); + sb.append(", memoryContent="); sb.append(memoryContent); + sb.append("]\n"); + sb.append("line["); sb.append(line.length); sb.append("]='"); + for (int i=0; i<line.length; i++) + sb.append(line[i]); + sb.append("'\n"); + + if (this.memoryContent != null) + { + sb.append("memoryContent("); sb.append(memoryContent); sb.append(")="); + sb.append(this.memoryContent.toString()); + } + + return sb.toString(); + } + + + + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/data/Terminal.java b/src/at/htlkaindorf/sx/EasyProgrammer/data/Terminal.java new file mode 100644 index 0000000..c2e3910 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/data/Terminal.java @@ -0,0 +1,29 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.htlkaindorf.sx.EasyProgrammer.data; + + +/** + * Abstract Terminal class. + * @author Manfred Steiner + */ +public abstract class Terminal +{ + public abstract void append (byte b); + public abstract void append (byte [] b, int numberOfbytes); + public abstract void append (byte [] b); + public abstract void append (char c); + public abstract void append (String s); + public abstract void deleteContent (); + public abstract char getText (int line, int pos) throws IndexOutOfBoundsException; + public abstract String getText (int line) throws IndexOutOfBoundsException; + public abstract boolean isTextAvailable (int line, int pos); + public abstract int getLines (); + public abstract int getColumns (); + public abstract int length (int line); + public abstract int getFirstLine (); + public abstract int getLastLine (); + public abstract int getCursorLine (); +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogAbout.form b/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogAbout.form new file mode 100644 index 0000000..eb66a80 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogAbout.form @@ -0,0 +1,147 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="title" type="java.lang.String" value="Über..."/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[620, 140]"/> + </Property> + <Property name="name" type="java.lang.String" value="AboutDialog" noResource="true"/> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSizePolicy" type="int" value="1"/> + <SyntheticProperty name="generateCenter" type="boolean" value="false"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,54,0,0,2,15"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="panCenter"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jpanCenterNorth"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="10" left="10" right="10" top="10"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="10" left="10" right="10" top="10"/> + </Border> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="0"/> + <Property name="rows" type="int" value="2"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jlaName"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Arial" size="24" style="1"/> + </Property> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="text" type="java.lang.String" value="EasyProgrammer"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jlaCopyright"> + <Properties> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="text" type="java.lang.String" value="(C) 2013-2016, Manfred Steiner"/> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JLabel" name="jlaIcon"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/at/htlkaindorf/sx/EasyProgrammer/icons/EasyProgrammer.png"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JScrollPane" name="jScrollPane"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="10" left="10" right="10" top="10"/> + </Border> + </Property> + </Properties> + <AuxValues> + <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/> + </AuxValues> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTextPane" name="textPane"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="panSouth"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="butSchliessen"> + <Properties> + <Property name="text" type="java.lang.String" value="Schliessen"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[5, 5, 5, 5]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onButtonSchliessen"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogAbout.java b/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogAbout.java new file mode 100644 index 0000000..814df2f --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogAbout.java @@ -0,0 +1,271 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * AboutDialog.java + * + * Created on 28.07.2010, 08:34:55 + */ +package at.htlkaindorf.sx.EasyProgrammer.gui; + +import at.htlkaindorf.sx.EasyProgrammer.libs.EasyProgrammerLib; +import at.htlkaindorf.sx.EasyProgrammer.logging.Logger; +import java.io.File; +import java.util.*; +import javax.swing.text.BadLocationException; +import javax.swing.text.Style; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyledDocument; + + +/** + * Dialogfenster 'About'.</BR> + * @author Manfred Steiner + */ +public final class DialogAbout extends javax.swing.JDialog +{ + public final static String version = "2.26 (25.8.2016)"; + public final static String source = "https://www.htl-mechatronik.at/svn/easyprogrammer/?p=26"; + + private static final Logger LOG = Logger.getLogger(DialogAbout.class.getName()); + + + + /** Creates new form AboutDialog */ + public DialogAbout(java.awt.Frame parent, boolean modal) + { + super(parent, modal); + initComponents(); + insertSystemInfo(); + pack(); + setLocationRelativeTo(parent); + setResizable(false); + } + + + public void insertSystemInfo() + { + // UnComment next Statement to see all available Properties in a additional window + // showSysPropListGUI(); + + Properties pr = System.getProperties(); + StyledDocument doc = textPane.getStyledDocument(); + + Style styleBold = textPane.addStyle("Arial 12 Bold", null); + StyleConstants.setBold(styleBold,true); + StyleConstants.setFontFamily(styleBold, "Arial"); + StyleConstants.setFontSize(styleBold, 12); + + Style styleNormal = textPane.addStyle("Arial 12 Normal", null); + StyleConstants.setFontFamily(styleNormal, "Arial"); + StyleConstants.setFontSize(styleNormal, 12); + + try + { + doc.insertString(doc.getLength(), "Produkt Version: ", styleBold); + doc.insertString(doc.getLength(), version + "\n", styleNormal); + doc.insertString(doc.getLength(), "Source: ", styleBold); + doc.insertString(doc.getLength(), source + "\n", styleNormal); + + doc.insertString(doc.getLength(), "Java: ", styleBold); + doc.insertString(doc.getLength(), System.getProperty("java.runtime.version"), styleNormal); + doc.insertString(doc.getLength(), "; " + System.getProperty("java.vm.name"), styleNormal); + doc.insertString(doc.getLength(), System.getProperty("java.vm.version") + "\n", styleNormal); + + doc.insertString(doc.getLength(), "System: ", styleBold); + doc.insertString(doc.getLength(), System.getProperty("os.name"), styleNormal); + doc.insertString(doc.getLength(), " Version " + System.getProperty("os.version"), styleNormal); + doc.insertString(doc.getLength(), " running on " + System.getProperty("os.arch"), styleNormal); + doc.insertString(doc.getLength(), "; " + System.getProperty("sun.jnu.encoding"), styleNormal); + doc.insertString(doc.getLength(), "; " + System.getProperty("user.language"), styleNormal); + doc.insertString(doc.getLength(), "_" + System.getProperty("user.country"), styleNormal); + + doc.insertString(doc.getLength(), "\nBenutzer: ", styleBold); + doc.insertString(doc.getLength(), System.getProperty("user.name"), styleNormal); + + doc.insertString(doc.getLength(), "\nBenutzerverzeichnis: ", styleBold); + doc.insertString(doc.getLength(), System.getProperty("user.home"), styleNormal); + + doc.insertString(doc.getLength(), "\nArbeitsverzeichnis: ", styleBold); + doc.insertString(doc.getLength(), System.getProperty("user.dir"), styleNormal); + + doc.insertString(doc.getLength(), "\nExterne Klassen in: ", styleBold); + doc.insertString(doc.getLength(), System.getProperty("java.ext.dirs"), styleNormal); + + doc.insertString(doc.getLength(), "\n" + "EasyProgrammerLib: ", styleBold); + if (!EasyProgrammerLib.isLibAvailable()) + doc.insertString(doc.getLength(), "not available", styleNormal); + else + { + File libFile = EasyProgrammerLib.getLibFile(); + doc.insertString(doc.getLength(), EasyProgrammerLib.getLibraryVersion() + " (" + libFile.getName() + ")", styleNormal); + } + + String version = "n/a"; + try { version = jssc.SerialNativeInterface.getNativeLibraryVersion(); } + catch (Exception ex) { LOG.warning(ex); } + doc.insertString(doc.getLength(), "\nJSSC Native: ", styleBold); + doc.insertString(doc.getLength(), version, styleNormal); + + version = "n/a"; + try { version = jssc.SerialNativeInterface.getLibraryVersion(); } + catch (Exception ex) { LOG.warning(ex); } + doc.insertString(doc.getLength(), "\nJSSC: ", styleBold); + doc.insertString(doc.getLength(), version, styleNormal); + } + + catch (BadLocationException ble) + { + System.err.println("Couldn't insert initial text into text pane."); + } + + } + + + + /** Panel to display the (limited) GUI intereface. */ + public void showSysPropListGUI() + { +// JFrame window = new JFrame("System Properties"); +// window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); +// JPanel panel = new JPanel(); +// JTextArea m_propertiesTA = new JTextArea(20, 40); +// +// //... Add property list data to text area. +// Properties pr = System.getProperties(); +// TreeSet<String> propKeys = new TreeSet(pr.keySet()); +// for (Iterator it = propKeys.iterator(); it.hasNext(); ) +// { +// String key = (String)it.next(); +// m_propertiesTA.append("" + key + "=" + pr.get(key) + "\n"); +// } +// +// panel.setLayout(new BorderLayout()); +// panel.add(new JScrollPane(m_propertiesTA), BorderLayout.CENTER); +// +// window.setContentPane(panel); +// window.pack(); +// window.setVisible(true); + } + + + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + panCenter = new javax.swing.JPanel(); + jpanCenterNorth = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + jlaName = new javax.swing.JLabel(); + jlaCopyright = new javax.swing.JLabel(); + jlaIcon = new javax.swing.JLabel(); + jScrollPane = new javax.swing.JScrollPane(); + textPane = new javax.swing.JTextPane(); + panSouth = new javax.swing.JPanel(); + butSchliessen = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle("Ãber..."); + setMinimumSize(new java.awt.Dimension(620, 140)); + setName("AboutDialog"); // NOI18N + + panCenter.setLayout(new java.awt.BorderLayout()); + + jpanCenterNorth.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + jPanel1.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10)); + jPanel1.setLayout(new java.awt.GridLayout(2, 0)); + + jlaName.setFont(new java.awt.Font("Arial", 1, 24)); // NOI18N + jlaName.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jlaName.setText("EasyProgrammer"); + jPanel1.add(jlaName); + + jlaCopyright.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jlaCopyright.setText("(C) 2013-2016, Manfred Steiner"); + jPanel1.add(jlaCopyright); + + jpanCenterNorth.add(jPanel1); + + jlaIcon.setIcon(new javax.swing.ImageIcon(getClass().getResource("/at/htlkaindorf/sx/EasyProgrammer/icons/EasyProgrammer.png"))); // NOI18N + jpanCenterNorth.add(jlaIcon); + + panCenter.add(jpanCenterNorth, java.awt.BorderLayout.NORTH); + + jScrollPane.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + textPane.setEditable(false); + jScrollPane.setViewportView(textPane); + + panCenter.add(jScrollPane, java.awt.BorderLayout.CENTER); + + getContentPane().add(panCenter, java.awt.BorderLayout.CENTER); + + butSchliessen.setText("Schliessen"); + butSchliessen.setMargin(new java.awt.Insets(5, 5, 5, 5)); + butSchliessen.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + onButtonSchliessen(evt); + } + }); + panSouth.add(butSchliessen); + + getContentPane().add(panSouth, java.awt.BorderLayout.SOUTH); + + pack(); + }// </editor-fold>//GEN-END:initComponents + + private void onButtonSchliessen(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onButtonSchliessen + {//GEN-HEADEREND:event_onButtonSchliessen + // TODO add your handling code here: + dispose(); + }//GEN-LAST:event_onButtonSchliessen + + + /** + * @param args the command line arguments + */ + public static void main(String args[]) + { + java.awt.EventQueue.invokeLater(new Runnable() + { + + @Override + public void run() + { + DialogAbout dialog = new DialogAbout(new javax.swing.JFrame(), true); + dialog.addWindowListener(new java.awt.event.WindowAdapter() + { + + @Override + public void windowClosing(java.awt.event.WindowEvent e) + { + System.exit(0); + } + }); + dialog.setVisible(true); + } + }); + } + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton butSchliessen; + private javax.swing.JPanel jPanel1; + private javax.swing.JScrollPane jScrollPane; + private javax.swing.JLabel jlaCopyright; + private javax.swing.JLabel jlaIcon; + private javax.swing.JLabel jlaName; + private javax.swing.JPanel jpanCenterNorth; + private javax.swing.JPanel panCenter; + private javax.swing.JPanel panSouth; + private javax.swing.JTextPane textPane; + // End of variables declaration//GEN-END:variables +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogProperties.form b/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogProperties.form new file mode 100644 index 0000000..742fea8 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogProperties.form @@ -0,0 +1,268 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.8" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="title" type="java.lang.String" value="Einstellungen"/> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSizePolicy" type="int" value="1"/> + <SyntheticProperty name="generateCenter" type="boolean" value="false"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,11,0,0,1,37"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jpanCenter"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="First"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="15" right="5" top="5"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="West"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="0"/> + <Property name="rows" type="int" value="6"/> + <Property name="verticalGap" type="int" value="3"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="Microprocessor"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="Flash-Size"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="Pagesize"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="Pages"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="Bootloader-Size"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel11"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="Reset String"/> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="1" top="5"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="0"/> + <Property name="rows" type="int" value="6"/> + <Property name="verticalGap" type="int" value="3"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JComboBox" name="jcbMicroprocessor"> + <Properties> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="3"> + <StringItem index="0" value="Atmega328P"/> + <StringItem index="1" value="Atmega8"/> + <StringItem index="2" value="User-Defined"/> + </StringArray> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onMicroprocessorChange"/> + </Events> + </Component> + <Component class="javax.swing.JFormattedTextField" name="jftfFlashSize"> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jftfFlashSizeActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JFormattedTextField" name="jftfPageSize"> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jftfPageSizeActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="jtfPages"> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jtfPagesActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jcbBootloaderSize"> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jcbBootloaderSizeonMicroprocessorChange"/> + </Events> + </Component> + <Component class="javax.swing.JTextField" name="jtfResetString"> + <Properties> + <Property name="text" type="java.lang.String" value="@R"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jtfResetStringActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="1" right="15" top="5"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="0"/> + <Property name="rows" type="int" value="6"/> + <Property name="verticalGap" type="int" value="3"/> + </Layout> + <SubComponents> + <Component class="javax.swing.Box$Filler" name="filler1"> + <Properties> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[1, 1]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[1, 1]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[1, 1]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.RigidArea"/> + </AuxValues> + </Component> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="text" type="java.lang.String" value="KiB"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="text" type="java.lang.String" value="Bytes"/> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel5"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Last"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.JCheckBox" name="jcbResetCmd"> + <Properties> + <Property name="selected" type="boolean" value="true"/> + <Property name="text" type="java.lang.String" value="Sende nach dem Reset String "\u005cr\u005cn"" containsInvalidXMLChars="true"/> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jpanSouth"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="horizontalGap" type="int" value="10"/> + </Layout> + <SubComponents> + <Container class="javax.swing.JPanel" name="jpanButtons"> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="0"/> + <Property name="horizontalGap" type="int" value="10"/> + <Property name="rows" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="jbutOK"> + <Properties> + <Property name="text" type="java.lang.String" value="OK"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onBtOK"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jbutCancel"> + <Properties> + <Property name="text" type="java.lang.String" value="Abbrechen"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[5, 5, 5, 5]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onBtAbbrechen"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogProperties.java b/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogProperties.java new file mode 100644 index 0000000..1a34023 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogProperties.java @@ -0,0 +1,500 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * KoeffSpeichernDialog.java + * + * Created on 27.07.2010, 13:12:15 + */ +package at.htlkaindorf.sx.EasyProgrammer.gui; + + +import at.htlkaindorf.sx.EasyProgrammer.data.CpuTyp; +import at.htlkaindorf.sx.EasyProgrammer.serial.SerialPortInfo; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import javax.swing.JPanel; +import javax.swing.JRootPane; + + +/** + * + * @author steiner + */ +public class DialogProperties extends javax.swing.JDialog +{ + private boolean pressedOK = false; + private CpuTyp cpuTyp; + + + /** Creates new form KoeffSpeichernDialog */ + public DialogProperties(java.awt.Frame parent, String title, boolean modal) + { + super(parent, title, modal); + + initComponents(); + + javax.swing.text.MaskFormatter mf=null; + try + { + mf = new javax.swing.text.MaskFormatter ("###"); + } + catch (java.text.ParseException e) {} + javax.swing.text.DefaultFormatterFactory dff = new javax.swing.text.DefaultFormatterFactory(mf); + + this.jftfFlashSize.setFormatterFactory(dff); + + cpuTyp = new CpuTyp(CpuTyp.Typ.Atmega328P); + jcbMicroprocessor.setModel(new javax.swing.DefaultComboBoxModel(cpuTyp.getAvailableNames())); + try + { + this.jcbMicroprocessor.setSelectedItem(cpuTyp.getName()); + this.UpdateFields(); + } + catch (Exception ex) { ex.printStackTrace(); }; + + String [] availBLSizes = cpuTyp.getAvailableBootloaderSizes(); + jcbBootloaderSize.setModel(new javax.swing.DefaultComboBoxModel(availBLSizes)); + try + { + jcbBootloaderSize.setSelectedIndex(cpuTyp.getBootloaderSizeIndex()); + UpdateFields(); + } + catch (Exception ex) { ex.printStackTrace(); }; + +// this.addComponentListener(new ComponentAdapter() +// { +// @Override +// public void componentResized (ComponentEvent e) +// { +// } +// }); + + } + + @Override + public void setVisible (boolean b) + { + pack(); + setMinimumSize(getPreferredSize()); + setLocationRelativeTo(getParent()); + super.setVisible(b); //To change body of generated methods, choose Tools | Templates. + } + + + @Override + public void setMinimumSize (Dimension minimumSize) + { + super.setMinimumSize(minimumSize); + } + + + public boolean isPressedOK () + { + return pressedOK; + } + + public CpuTyp getCpuTyp() + { + return cpuTyp; + } + + + public void setCpuTyp(CpuTyp cpuTyp) + { + this.cpuTyp = cpuTyp; + + if (jcbBootloaderSize.getItemCount()>0) + { + try + { + jcbBootloaderSize.setSelectedIndex(cpuTyp.getBootloaderSizeIndex()); + } + catch (Exception ex) + { + ex.printStackTrace(System.err); + } + } + + if (jcbMicroprocessor.getItemCount()>0) + { + try + { + this.jcbMicroprocessor.setSelectedItem(cpuTyp.getName()); + } + catch (Exception ex) + { + ex.printStackTrace(System.err); + } + } + + String resetCmd = cpuTyp.getResetCommand(); + if (resetCmd.endsWith("\r\n")) + { + jtfResetString.setText(resetCmd.substring(0, resetCmd.length()-2)); + jcbResetCmd.setSelected(true); + } + else + { + jtfResetString.setText(resetCmd); + jcbResetCmd.setSelected(false); + } + + + } + + public String getResetString () + { + if (jcbResetCmd.isSelected()) + return jtfResetString.getText() + "\r\n"; + else + return jtfResetString.getText(); + } + + + + public void endDialogWithOK () + { + dispose(); + cpuTyp.setResetCommand(getResetString()); + this.pressedOK = true; + } + + private void changeMicroprocessor () + { + String s = (String) this.jcbMicroprocessor.getSelectedItem(); + try + { + cpuTyp.setTyp(s); + UpdateFields(); + } + catch (Exception ex) + { + ex.printStackTrace(System.err); + } + } + + private void UpdateFields () throws Exception + { + if (this.cpuTyp.getTyp()==CpuTyp.Typ.UserSpecified) + { + this.jftfFlashSize.setEnabled(true); + this.jftfPageSize.setEnabled(true); + return; + } + + //System.out.println(cpuTyp.getFlashSize()/1024); + this.jftfFlashSize.setText(String.format("%d", cpuTyp.getFlashSize()/1024)); + this.jftfFlashSize.setEnabled(false); + this.jftfPageSize.setText(String.format("%d",cpuTyp.getPageSize())); + this.jftfPageSize.setEnabled(false); + this.jtfPages.setText(String.format("%d",cpuTyp.getPages())); + this.jtfPages.setEnabled(false); + + //jcbBootloaderSize.setSelectedIndex(cpuTyp.getBootloaderSizeIndex()); + + String resetCmd = cpuTyp.getResetCommand(); + if (resetCmd==null) + resetCmd = "@reset\n\r"; + if (resetCmd.endsWith("\r\n")) + { + jtfResetString.setText(resetCmd.substring(0, resetCmd.length()-2)); + jcbResetCmd.setSelected(true); + } + else + { + jtfResetString.setText(resetCmd); + jcbResetCmd.setSelected(false); + } + jtfResetString.setEnabled(true); + jcbResetCmd.setEnabled(true); + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() + { + + jpanCenter = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + jLabel2 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + jLabel5 = new javax.swing.JLabel(); + jLabel6 = new javax.swing.JLabel(); + jLabel11 = new javax.swing.JLabel(); + jPanel3 = new javax.swing.JPanel(); + jcbMicroprocessor = new javax.swing.JComboBox(); + jftfFlashSize = new javax.swing.JFormattedTextField(); + jftfPageSize = new javax.swing.JFormattedTextField(); + jtfPages = new javax.swing.JTextField(); + jcbBootloaderSize = new javax.swing.JComboBox(); + jtfResetString = new javax.swing.JTextField(); + jPanel4 = new javax.swing.JPanel(); + filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(1, 1), new java.awt.Dimension(1, 1), new java.awt.Dimension(1, 1)); + jLabel7 = new javax.swing.JLabel(); + jLabel8 = new javax.swing.JLabel(); + jPanel5 = new javax.swing.JPanel(); + jcbResetCmd = new javax.swing.JCheckBox(); + jpanSouth = new javax.swing.JPanel(); + jpanButtons = new javax.swing.JPanel(); + jbutOK = new javax.swing.JButton(); + jbutCancel = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle("Einstellungen"); + + jpanCenter.setLayout(new java.awt.BorderLayout()); + + jPanel2.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 15, 5, 5)); + jPanel2.setLayout(new java.awt.GridLayout(6, 0, 0, 3)); + + jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel2.setText("Microprocessor"); + jPanel2.add(jLabel2); + + jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel3.setText("Flash-Size"); + jPanel2.add(jLabel3); + + jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel4.setText("Pagesize"); + jPanel2.add(jLabel4); + + jLabel5.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel5.setText("Pages"); + jPanel2.add(jLabel5); + + jLabel6.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel6.setText("Bootloader-Size"); + jPanel2.add(jLabel6); + + jLabel11.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel11.setText("Reset String"); + jPanel2.add(jLabel11); + + jpanCenter.add(jPanel2, java.awt.BorderLayout.WEST); + + jPanel3.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 1)); + jPanel3.setLayout(new java.awt.GridLayout(6, 0, 0, 3)); + + jcbMicroprocessor.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Atmega328P", "Atmega8", "User-Defined" })); + jcbMicroprocessor.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onMicroprocessorChange(evt); + } + }); + jPanel3.add(jcbMicroprocessor); + + jftfFlashSize.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + jftfFlashSizeActionPerformed(evt); + } + }); + jPanel3.add(jftfFlashSize); + + jftfPageSize.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + jftfPageSizeActionPerformed(evt); + } + }); + jPanel3.add(jftfPageSize); + + jtfPages.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + jtfPagesActionPerformed(evt); + } + }); + jPanel3.add(jtfPages); + + jcbBootloaderSize.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + jcbBootloaderSizeonMicroprocessorChange(evt); + } + }); + jPanel3.add(jcbBootloaderSize); + + jtfResetString.setText("@R"); + jtfResetString.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + jtfResetStringActionPerformed(evt); + } + }); + jPanel3.add(jtfResetString); + + jpanCenter.add(jPanel3, java.awt.BorderLayout.CENTER); + + jPanel4.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 1, 5, 15)); + jPanel4.setLayout(new java.awt.GridLayout(6, 0, 0, 3)); + jPanel4.add(filler1); + + jLabel7.setText("KiB"); + jPanel4.add(jLabel7); + + jLabel8.setText("Bytes"); + jPanel4.add(jLabel8); + + jpanCenter.add(jPanel4, java.awt.BorderLayout.EAST); + + jcbResetCmd.setSelected(true); + jcbResetCmd.setText("Sende nach dem Reset String \"\\r\\n\""); + jPanel5.add(jcbResetCmd); + + jpanCenter.add(jPanel5, java.awt.BorderLayout.PAGE_END); + + getContentPane().add(jpanCenter, java.awt.BorderLayout.PAGE_START); + + jpanSouth.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 10, 5)); + + jpanButtons.setLayout(new java.awt.GridLayout(1, 0, 10, 0)); + + jbutOK.setText("OK"); + jbutOK.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onBtOK(evt); + } + }); + jpanButtons.add(jbutOK); + + jbutCancel.setText("Abbrechen"); + jbutCancel.setMargin(new java.awt.Insets(5, 5, 5, 5)); + jbutCancel.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onBtAbbrechen(evt); + } + }); + jpanButtons.add(jbutCancel); + + jpanSouth.add(jpanButtons); + + getContentPane().add(jpanSouth, java.awt.BorderLayout.SOUTH); + + pack(); + }// </editor-fold>//GEN-END:initComponents + + private void onBtAbbrechen(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onBtAbbrechen + {//GEN-HEADEREND:event_onBtAbbrechen + // TODO add your handling code here: + dispose(); + }//GEN-LAST:event_onBtAbbrechen + + private void onBtOK(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onBtOK + {//GEN-HEADEREND:event_onBtOK + // TODO add your handling code here: + endDialogWithOK(); + }//GEN-LAST:event_onBtOK + + private void onMicroprocessorChange(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onMicroprocessorChange + {//GEN-HEADEREND:event_onMicroprocessorChange + changeMicroprocessor(); + }//GEN-LAST:event_onMicroprocessorChange + + private void jftfFlashSizeActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jftfFlashSizeActionPerformed + {//GEN-HEADEREND:event_jftfFlashSizeActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jftfFlashSizeActionPerformed + + private void jftfPageSizeActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jftfPageSizeActionPerformed + {//GEN-HEADEREND:event_jftfPageSizeActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jftfPageSizeActionPerformed + + private void jtfPagesActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jtfPagesActionPerformed + {//GEN-HEADEREND:event_jtfPagesActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jtfPagesActionPerformed + + private void jtfResetStringActionPerformed (java.awt.event.ActionEvent evt)//GEN-FIRST:event_jtfResetStringActionPerformed + {//GEN-HEADEREND:event_jtfResetStringActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jtfResetStringActionPerformed + + private void jcbBootloaderSizeonMicroprocessorChange (java.awt.event.ActionEvent evt)//GEN-FIRST:event_jcbBootloaderSizeonMicroprocessorChange + {//GEN-HEADEREND:event_jcbBootloaderSizeonMicroprocessorChange + // TODO add your handling code here: + }//GEN-LAST:event_jcbBootloaderSizeonMicroprocessorChange + + + /** + * @param args the command line arguments + */ + public static void main(String args[]) + { + java.awt.EventQueue.invokeLater(new Runnable() + { + + public void run() + { + DialogProperties dialog = new DialogProperties(new javax.swing.JFrame(), "Einstellungen", true); + dialog.addWindowListener(new java.awt.event.WindowAdapter() + { + + public void windowClosing(java.awt.event.WindowEvent e) + { + System.exit(0); + } + }); + dialog.setVisible(true); + } + }); + } + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.Box.Filler filler1; + private javax.swing.JLabel jLabel11; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JButton jbutCancel; + private javax.swing.JButton jbutOK; + private javax.swing.JComboBox jcbBootloaderSize; + private javax.swing.JComboBox jcbMicroprocessor; + private javax.swing.JCheckBox jcbResetCmd; + private javax.swing.JFormattedTextField jftfFlashSize; + private javax.swing.JFormattedTextField jftfPageSize; + private javax.swing.JPanel jpanButtons; + private javax.swing.JPanel jpanCenter; + private javax.swing.JPanel jpanSouth; + private javax.swing.JTextField jtfPages; + private javax.swing.JTextField jtfResetString; + // End of variables declaration//GEN-END:variables + + + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogSelectProgramFile.java b/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogSelectProgramFile.java new file mode 100644 index 0000000..f608006 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogSelectProgramFile.java @@ -0,0 +1,143 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.htlkaindorf.sx.EasyProgrammer.gui; + +import at.htlkaindorf.sx.EasyProgrammer.libs.EasyProgrammerLib; +import java.io.File; +import java.util.ArrayList; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.filechooser.FileNameExtensionFilter; + +/** + * + * @author steiner + */ +public class DialogSelectProgramFile +{ + private boolean pressedOK; + private String fileName; + private String folderName; + private JFrame parentFrame; + private JFileChooser fileChooser; + + + + public DialogSelectProgramFile (JFrame parentFrame) + { + this.parentFrame = parentFrame; + } + + + public void setFileName(String fileName) + { + this.fileName = fileName; + } + + + public void setFolderName(String folderName) + { + this.folderName = folderName; + } + + + public String getFileName() + { + return fileName; + } + + + public String getFolderName() + { + return folderName; + } + + + public boolean isPressedOK() + { + return pressedOK; + } + + + public void setVisible(boolean visible) + { + String[] filterPattern = { "hex", "*"}; + String[] filterName = { "Hex-Datei", "Alle Dateien" }; + String fname = null; + String folder = null; + + if (visible == false) return; + + if (EasyProgrammerLib.isLibAvailable() == true) + { + EasyProgrammerLib.showOpenHexFileDialog(folderName, fileName); + File file = EasyProgrammerLib.getSelectedFile(); + if (file != null) + { + fname = file.getName(); + folder = file.getAbsolutePath(); + char [] dir = folder.toCharArray(); + if (folder.lastIndexOf("\\") >= 0) + folder = String.valueOf(dir, 0, folder.lastIndexOf("\\")+1); + else if (folder.lastIndexOf("/") >= 0) + folder = String.valueOf(dir, 0, folder.lastIndexOf("/")+1); + else + folder = ""; + } + } + else + { + if (fileChooser == null) + { + fileChooser = new JFileChooser(); + fileChooser.setDialogTitle("Programmdatei (Hex-File) für ATmega328P auswählen..."); + fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + fileChooser.setMultiSelectionEnabled(false); + FileNameExtensionFilter fileFilter = new FileNameExtensionFilter ("Hex-Datei (*.hex)", "hex"); + fileChooser.addChoosableFileFilter(fileFilter); + //fileChooser.addChoosableFileFilter(new FileNameExtensionFilter ("Alle Dateien", "*")); + fileChooser.setFileFilter(fileFilter); + if (fileName != null) + fileChooser.setSelectedFile(new File(fileName)); + if (this.folderName == null) + { + String dir = System.getProperty("user.dir"); + if (dir != null) fileChooser.setCurrentDirectory(new File(dir)); + } + else + fileChooser.setCurrentDirectory(new File(folderName)); + } + if (folderName != null) + fileChooser.setCurrentDirectory(new File(folderName)); + fileChooser.showOpenDialog(parentFrame); + File file = fileChooser.getSelectedFile(); + if (file != null) + { + fname = file.getName(); + folder = fileChooser.getCurrentDirectory().getAbsolutePath(); + } + } + + fileName = null; + folderName = null; + pressedOK = false; + if (fname!=null && folder!=null) + { + if (System.getProperty("os.name").toLowerCase().contains("win")) + { + if (folder.endsWith("\\")==false) + folder = folder + '\\'; + } + else if (folder.endsWith("/")==false) + folder = folder + '/'; // for Linux + + pressedOK = true; + fileName = fname; + folderName = folder; + } + } + + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogSerialConfig.form b/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogSerialConfig.form new file mode 100644 index 0000000..69ee48f --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogSerialConfig.form @@ -0,0 +1,219 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> + <Properties> + <Property name="defaultCloseOperation" type="int" value="2"/> + <Property name="title" type="java.lang.String" value="Einstellungen"/> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[300, 280]"/> + </Property> + <Property name="resizable" type="boolean" value="false"/> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="formSizePolicy" type="int" value="1"/> + <SyntheticProperty name="generateCenter" type="boolean" value="false"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-23,0,0,1,36"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="panCenter"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="10" left="10" right="10" top="10"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="2"/> + <Property name="horizontalGap" type="int" value="5"/> + <Property name="rows" type="int" value="1"/> + </Layout> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="0"/> + <Property name="rows" type="int" value="5"/> + <Property name="verticalGap" type="int" value="3"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="Schnittstelle"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 16]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="Baudrate"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 16]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="Datenbits"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 16]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel4"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="Parity-Bit"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 16]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="Stopbits"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[80, 16]"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel2"> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="0"/> + <Property name="rows" type="int" value="5"/> + <Property name="verticalGap" type="int" value="3"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JTextField" name="textDesiredInterface"> + <Properties> + <Property name="text" type="java.lang.String" value="COM1"/> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="comboBaudrate"> + <Properties> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="5"> + <StringItem index="0" value="9600"/> + <StringItem index="1" value="19200"/> + <StringItem index="2" value="38400"/> + <StringItem index="3" value="57600"/> + <StringItem index="4" value="115200"/> + </StringArray> + </Property> + <Property name="selectedIndex" type="int" value="3"/> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="comboDatabits"> + <Properties> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="4"> + <StringItem index="0" value="5"/> + <StringItem index="1" value="6"/> + <StringItem index="2" value="7"/> + <StringItem index="3" value="8"/> + </StringArray> + </Property> + <Property name="selectedIndex" type="int" value="3"/> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="comboParity"> + <Properties> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="3"> + <StringItem index="0" value="kein"/> + <StringItem index="1" value="gerade"/> + <StringItem index="2" value="ungerade"/> + </StringArray> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="comboStopbits"> + <Properties> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="2"> + <StringItem index="0" value="1"/> + <StringItem index="1" value="2"/> + </StringArray> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="panSouth"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="2" left="5" right="5" top="1"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jpanButtons"> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="2"/> + <Property name="horizontalGap" type="int" value="10"/> + <Property name="rows" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="butOK"> + <Properties> + <Property name="text" type="java.lang.String" value="OK"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onBtOK"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="butCancel"> + <Properties> + <Property name="text" type="java.lang.String" value="Abbrechen"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[5, 5, 5, 5]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onBtAbbrechen"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogSerialConfig.java b/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogSerialConfig.java new file mode 100644 index 0000000..b3abb0d --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/gui/DialogSerialConfig.java @@ -0,0 +1,279 @@ +/* + * KoeffSpeichernDialog.java + * + * Created on 27.07.2010, 13:12:15 + */ +package at.htlkaindorf.sx.EasyProgrammer.gui; + +import at.htlkaindorf.sx.EasyProgrammer.serial.SerialPortInfoFactory; +import at.htlkaindorf.sx.EasyProgrammer.serial.SerialPortInfo; +import java.awt.Dimension; +import java.awt.Point; +import javafx.scene.control.ComboBox; +import javax.swing.ComboBoxModel; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JComboBox; + +/** + * + * @author steiner + */ +public final class DialogSerialConfig extends javax.swing.JDialog +{ + private boolean pressedOK; + private SerialPortInfo serialPortInfo; + + /** Creates new form KoeffSpeichernDialog */ + public DialogSerialConfig(java.awt.Frame parent, String title, boolean modal) + { + super(parent, title, modal); + initComponents(); + } + + + @Override + public void setVisible (boolean visible) + { + if (visible) + { + pressedOK = false; + pack(); + setMinimumSize(getPreferredSize()); + setResizable(false); + setLocationRelativeTo(getParent()); + init(); + } + super.setVisible(visible); + } + + private void init () + { + textDesiredInterface.setText(serialPortInfo.getName()); + updateModel(comboBaudrate, serialPortInfo.getSupportedBaudrates(), serialPortInfo.getBaudrateIndex()); + updateModel(comboDatabits, serialPortInfo.getSupportedDatabits(), serialPortInfo.getDatabitIndex()); + updateModel(comboParity, serialPortInfo.getSupportedParityModes(), serialPortInfo.getParityModeIndex()); + updateModel(comboStopbits, serialPortInfo.getSupportedStopBits(), serialPortInfo.getStopBitIndex()); + } + + + private void updateModel (JComboBox cb, String [] values, int selectedIndex) + { + ComboBoxModel m = cb.getModel(); + for (int i=0; i<m.getSize(); i++) + { + if (!m.getElementAt(i).equals(values[i])) + { + cb.setModel(new DefaultComboBoxModel<>(values)); + cb.getModel().setSelectedItem(values[selectedIndex]); + return; + } + } + m.setSelectedItem(values[selectedIndex]); + } + + public void setSerialPortInfo (SerialPortInfo serialPortInfo) + { + this.serialPortInfo = serialPortInfo; + } + + + public boolean isPressedOK() + { + return pressedOK; + } + + public void endDialogWithOK() + { + String n = textDesiredInterface.getText(); + String b = (String)comboBaudrate.getSelectedItem(); + String d = (String)comboDatabits.getSelectedItem(); + String p = (String)comboParity.getSelectedItem(); + String s = (String)comboStopbits.getSelectedItem(); + serialPortInfo = SerialPortInfoFactory.getSerialPortInfo(n, b, d, p, s); + pressedOK = true; + dispose(); + } + + + public SerialPortInfo getSerialPortInfo () + { + return serialPortInfo; + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() + { + + panCenter = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + jLabel5 = new javax.swing.JLabel(); + jPanel2 = new javax.swing.JPanel(); + textDesiredInterface = new javax.swing.JTextField(); + comboBaudrate = new javax.swing.JComboBox(); + comboDatabits = new javax.swing.JComboBox(); + comboParity = new javax.swing.JComboBox(); + comboStopbits = new javax.swing.JComboBox(); + panSouth = new javax.swing.JPanel(); + jpanButtons = new javax.swing.JPanel(); + butOK = new javax.swing.JButton(); + butCancel = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle("Einstellungen"); + setMinimumSize(new java.awt.Dimension(300, 280)); + setResizable(false); + + panCenter.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10)); + panCenter.setLayout(new java.awt.GridLayout(1, 2, 5, 0)); + + jPanel1.setLayout(new java.awt.GridLayout(5, 0, 0, 3)); + + jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel1.setText("Schnittstelle"); + jLabel1.setPreferredSize(new java.awt.Dimension(80, 16)); + jPanel1.add(jLabel1); + + jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel2.setText("Baudrate"); + jLabel2.setPreferredSize(new java.awt.Dimension(80, 16)); + jPanel1.add(jLabel2); + + jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel3.setText("Datenbits"); + jLabel3.setPreferredSize(new java.awt.Dimension(80, 16)); + jPanel1.add(jLabel3); + + jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel4.setText("Parity-Bit"); + jLabel4.setPreferredSize(new java.awt.Dimension(80, 16)); + jPanel1.add(jLabel4); + + jLabel5.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel5.setText("Stopbits"); + jLabel5.setPreferredSize(new java.awt.Dimension(80, 16)); + jPanel1.add(jLabel5); + + panCenter.add(jPanel1); + + jPanel2.setLayout(new java.awt.GridLayout(5, 0, 0, 3)); + + textDesiredInterface.setText("COM1"); + jPanel2.add(textDesiredInterface); + + comboBaudrate.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "9600", "19200", "38400", "57600", "115200" })); + comboBaudrate.setSelectedIndex(3); + jPanel2.add(comboBaudrate); + + comboDatabits.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "5", "6", "7", "8" })); + comboDatabits.setSelectedIndex(3); + jPanel2.add(comboDatabits); + + comboParity.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "kein", "gerade", "ungerade" })); + jPanel2.add(comboParity); + + comboStopbits.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "1", "2" })); + jPanel2.add(comboStopbits); + + panCenter.add(jPanel2); + + getContentPane().add(panCenter, java.awt.BorderLayout.NORTH); + + panSouth.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 5, 2, 5)); + + jpanButtons.setLayout(new java.awt.GridLayout(1, 2, 10, 0)); + + butOK.setText("OK"); + butOK.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onBtOK(evt); + } + }); + jpanButtons.add(butOK); + + butCancel.setText("Abbrechen"); + butCancel.setMargin(new java.awt.Insets(5, 5, 5, 5)); + butCancel.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onBtAbbrechen(evt); + } + }); + jpanButtons.add(butCancel); + + panSouth.add(jpanButtons); + + getContentPane().add(panSouth, java.awt.BorderLayout.SOUTH); + + pack(); + }// </editor-fold>//GEN-END:initComponents + + private void onBtAbbrechen(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onBtAbbrechen + {//GEN-HEADEREND:event_onBtAbbrechen + // TODO add your handling code here: + dispose(); + }//GEN-LAST:event_onBtAbbrechen + + private void onBtOK(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onBtOK + {//GEN-HEADEREND:event_onBtOK + // TODO add your handling code here: + endDialogWithOK(); + }//GEN-LAST:event_onBtOK + + + /** + * @param args the command line arguments + */ + public static void main(String args[]) + { + java.awt.EventQueue.invokeLater(new Runnable() + { + + public void run() + { + DialogSerialConfig dialog = new DialogSerialConfig(new javax.swing.JFrame(), "Einstellungen", true); + dialog.addWindowListener(new java.awt.event.WindowAdapter() + { + + public void windowClosing(java.awt.event.WindowEvent e) + { + System.exit(0); + } + }); + dialog.setVisible(true); + } + }); + } + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton butCancel; + private javax.swing.JButton butOK; + private javax.swing.JComboBox comboBaudrate; + private javax.swing.JComboBox comboDatabits; + private javax.swing.JComboBox comboParity; + private javax.swing.JComboBox comboStopbits; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jpanButtons; + private javax.swing.JPanel panCenter; + private javax.swing.JPanel panSouth; + private javax.swing.JTextField textDesiredInterface; + // End of variables declaration//GEN-END:variables +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/gui/EasyProgrammer.form b/src/at/htlkaindorf/sx/EasyProgrammer/gui/EasyProgrammer.form new file mode 100644 index 0000000..00973a8 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/gui/EasyProgrammer.form @@ -0,0 +1,1147 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.2" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JFrameFormInfo"> + <NonVisualComponents> + <Menu class="javax.swing.JMenuBar" name="menuBar"> + <SubComponents> + <Menu class="javax.swing.JMenu" name="menuFile"> + <Properties> + <Property name="text" type="java.lang.String" value="Datei"/> + </Properties> + <SubComponents> + <MenuItem class="javax.swing.JMenuItem" name="menuFileOpen"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/at/htlkaindorf/sx/EasyProgrammer/icons/Open16.gif"/> + </Property> + <Property name="text" type="java.lang.String" value="Öffnen"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onMenuFileOpen"/> + </Events> + </MenuItem> + <MenuItem class="javax.swing.JPopupMenu$Separator" name="jSeparator1"> + </MenuItem> + <MenuItem class="javax.swing.JMenuItem" name="menuExit"> + <Properties> + <Property name="text" type="java.lang.String" value="Beenden"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onMenuExit"/> + </Events> + </MenuItem> + </SubComponents> + </Menu> + <Menu class="javax.swing.JMenu" name="menuEdit"> + <Properties> + <Property name="text" type="java.lang.String" value="Bearbeiten"/> + </Properties> + <SubComponents> + <MenuItem class="javax.swing.JMenuItem" name="menuEditProperties"> + <Properties> + <Property name="text" type="java.lang.String" value="Einstellungen µC"/> + <Property name="enabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onMenuEditProperties"/> + </Events> + </MenuItem> + <MenuItem class="javax.swing.JMenuItem" name="menuSerialProperties"> + <Properties> + <Property name="text" type="java.lang.String" value="Serielle Schnittstelle"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onMenuEditSerialProperties"/> + </Events> + </MenuItem> + <MenuItem class="javax.swing.JPopupMenu$Separator" name="jSeparator2"> + </MenuItem> + <MenuItem class="javax.swing.JMenuItem" name="menuCopy"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/at/htlkaindorf/sx/EasyProgrammer/icons/Copy16.gif"/> + </Property> + <Property name="text" type="java.lang.String" value="Kopieren"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onMenuCopy"/> + </Events> + </MenuItem> + <MenuItem class="javax.swing.JMenuItem" name="menuPaste"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/at/htlkaindorf/sx/EasyProgrammer/icons/Paste16.gif"/> + </Property> + <Property name="text" type="java.lang.String" value="Einfügen"/> + <Property name="enabled" type="boolean" value="false"/> + </Properties> + </MenuItem> + <MenuItem class="javax.swing.JPopupMenu$Separator" name="jSeparator3"> + </MenuItem> + <MenuItem class="javax.swing.JMenuItem" name="menuDeleteTerminalContent"> + <Properties> + <Property name="text" type="java.lang.String" value="Terminalinhalt löschen"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onMenuDeleteTerminalContent"/> + </Events> + </MenuItem> + </SubComponents> + </Menu> + <Menu class="javax.swing.JMenu" name="menuHelp"> + <Properties> + <Property name="text" type="java.lang.String" value="Hilfe"/> + </Properties> + <SubComponents> + <MenuItem class="javax.swing.JMenuItem" name="jmiHelp"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/at/htlkaindorf/sx/EasyProgrammer/icons/About16.gif"/> + </Property> + <Property name="text" type="java.lang.String" value="Über EasyProgrammer..."/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onMenuAbout"/> + </Events> + </MenuItem> + <MenuItem class="javax.swing.JMenuItem" name="jmiMonitor"> + <Properties> + <Property name="text" type="java.lang.String" value="Monitor"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jmiMonitoronMenuAbout"/> + </Events> + </MenuItem> + </SubComponents> + </Menu> + </SubComponents> + </Menu> + </NonVisualComponents> + <Properties> + <Property name="defaultCloseOperation" type="int" value="3"/> + <Property name="title" type="java.lang.String" value="EasyProgrammer (JSSC)"/> + <Property name="iconImage" type="java.awt.Image" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="appIcon" type="code"/> + </Property> + <Property name="name" type="java.lang.String" value="EasyProgrammer" noResource="true"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[700, 383]"/> + </Property> + </Properties> + <SyntheticProperties> + <SyntheticProperty name="menuBar" type="java.lang.String" value="menuBar"/> + <SyntheticProperty name="formSizePolicy" type="int" value="1"/> + <SyntheticProperty name="generateCenter" type="boolean" value="false"/> + </SyntheticProperties> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,0,0,0,2,37"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JToolBar" name="toolBar"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo"> + <LineBorder> + <Color PropertyName="color" blue="cc" green="cc" red="cc" type="rgb"/> + </LineBorder> + </Border> + </Property> + <Property name="rollover" type="boolean" value="true"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="First"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="iconFileOpen"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/at/htlkaindorf/sx/EasyProgrammer/icons/Open24.gif"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Datei öffnen"/> + <Property name="borderPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="horizontalTextPosition" type="int" value="0"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[1, 5, 1, 5]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="verticalTextPosition" type="int" value="3"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onIconFileOpen"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 10]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 10]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 10]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="iconRefresh"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/at/htlkaindorf/sx/EasyProgrammer/icons/Refresh24.gif"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Aktualisieren"/> + <Property name="borderPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="horizontalTextPosition" type="int" value="0"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[1, 10, 1, 10]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="verticalTextPosition" type="int" value="3"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onIconRefresh"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 10]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 10]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 10]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="iconConnect"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/at/htlkaindorf/sx/EasyProgrammer/icons/connect24.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Mit µC-System verbinden"/> + <Property name="borderPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="horizontalTextPosition" type="int" value="0"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[1, 10, 1, 10]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="verticalTextPosition" type="int" value="3"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onIconConnect"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="iconDisconnect"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/at/htlkaindorf/sx/EasyProgrammer/icons/disconnect24.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Von µC-System trennen"/> + <Property name="borderPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="horizontalTextPosition" type="int" value="0"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[1, 10, 1, 10]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="verticalTextPosition" type="int" value="3"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onIconDisconnect"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 10]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 10]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 10]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="iconCopy"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/at/htlkaindorf/sx/EasyProgrammer/icons/Copy24.gif"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Terminal-Inhalt in die Zwischenablage kopieren"/> + <Property name="borderPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="horizontalTextPosition" type="int" value="0"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[1, 10, 1, 10]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="verticalTextPosition" type="int" value="3"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onIconCopy"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="iconPaste"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/at/htlkaindorf/sx/EasyProgrammer/icons/Paste24.gif"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Inhalt der Zwischenablage als Terminal-Eingabe verwenden"/> + <Property name="borderPainted" type="boolean" value="false"/> + <Property name="enabled" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="horizontalTextPosition" type="int" value="0"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[1, 10, 1, 10]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="verticalTextPosition" type="int" value="3"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onIconPaste"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="iconProperties"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/at/htlkaindorf/sx/EasyProgrammer/icons/Preferences24.gif"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Terminal Einstellungen verändern"/> + <Property name="borderPainted" type="boolean" value="false"/> + <Property name="enabled" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="horizontalTextPosition" type="int" value="0"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[1, 10, 1, 10]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="verticalTextPosition" type="int" value="3"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onIconProperties"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="iconCleanTerminal"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/at/htlkaindorf/sx/EasyProgrammer/icons/CleanTerminal24.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Terminalinhalt löschen"/> + <Property name="borderPainted" type="boolean" value="false"/> + <Property name="enabled" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="horizontalTextPosition" type="int" value="0"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[1, 10, 1, 10]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="verticalTextPosition" type="int" value="3"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onIconCleanTerminal"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 10]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 10]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 10]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="iconDownload"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/at/htlkaindorf/sx/EasyProgrammer/icons/Download24.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Download Hex-File"/> + <Property name="borderPainted" type="boolean" value="false"/> + <Property name="enabled" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="horizontalTextPosition" type="int" value="0"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[1, 10, 1, 10]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="verticalTextPosition" type="int" value="3"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onIconDownload"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="iconStop"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/at/htlkaindorf/sx/EasyProgrammer/icons/Stop24.png"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Stop"/> + <Property name="borderPainted" type="boolean" value="false"/> + <Property name="enabled" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="horizontalTextPosition" type="int" value="0"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[1, 10, 1, 10]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="verticalTextPosition" type="int" value="3"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onIconStop"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 10]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 10]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 10]"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="iconAbout"> + <Properties> + <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> + <Image iconType="3" name="/at/htlkaindorf/sx/EasyProgrammer/icons/About24.gif"/> + </Property> + <Property name="toolTipText" type="java.lang.String" value="Über EasyProgrammer (Version...)"/> + <Property name="borderPainted" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="horizontalTextPosition" type="int" value="0"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[1, 10, 1, 10]"/> + </Property> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[30, 24]"/> + </Property> + <Property name="verticalTextPosition" type="int" value="3"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onIconAbout"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="panCenter"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="2" left="2" right="2" top="2"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="panCenterNorth"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="panSerialInterface"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder title="Serielle Schnittstelle"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="First"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="panSerialInterface2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="javax.swing.JComboBox" name="comboInterface"> + <Properties> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="2" left="1" right="1" top="2"/> + </Border> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onComboInterface"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="North"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="panSerialInterfaceEast"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="verticalGap" type="int" value="0"/> + </Layout> + <SubComponents> + <Container class="javax.swing.JPanel" name="panSerialInterrfaceButtons"> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="0"/> + <Property name="horizontalGap" type="int" value="5"/> + <Property name="rows" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="butConnect"> + <Properties> + <Property name="text" type="java.lang.String" value="Verbinden"/> + <Property name="enabled" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[3, 10, 3, 10]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onButtonConnect"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="butDisconnect"> + <Properties> + <Property name="text" type="java.lang.String" value="Trennen"/> + <Property name="enabled" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[3, 3, 3, 3]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onButtonDisconnect"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jpanSerailConfig"> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/> + <SubComponents> + <Component class="javax.swing.Box$Filler" name="filler4"> + <Properties> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 32767]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 0]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 0]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.HorizontalStrut"/> + </AuxValues> + </Component> + <Component class="javax.swing.JTextField" name="textSerialConfig"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="text" type="java.lang.String" value="115200,none,1.5"/> + <Property name="focusable" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[0, 5, 0, 5]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[120, 27]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="textSerialConfigActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JButton" name="butSerialConfig"> + <Properties> + <Property name="text" type="java.lang.String" value="Einstellungen"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[3, 3, 3, 3]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onButtonSerialConfig"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="panProgramFile"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder title="Programmdatei (Hex-File)"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Last"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="javax.swing.JButton" name="butSelectProgramFile"> + <Properties> + <Property name="text" type="java.lang.String" value="Datei"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[3, 10, 3, 10]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onSelectProgramFile"/> + </Events> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="West"/> + </Constraint> + </Constraints> + </Component> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="3" left="1" right="1" top="3"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="0"/> + <Property name="rows" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JTextField" name="tfProgramFileName"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="toolTipText" type="java.lang.String" value=""/> + <Property name="focusable" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="tfProgramFileNameActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="3" left="1" right="1" top="3"/> + </Border> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[40, 33]"/> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="0"/> + <Property name="rows" type="int" value="1"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JTextField" name="textHexSize"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="focusable" type="boolean" value="false"/> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="panCenterCenter"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="10"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="0"/> + <Property name="rows" type="int" value="1"/> + </Layout> + <SubComponents> + <Container class="javax.swing.JPanel" name="textTerminal"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder title="Terminal"/> + </Border> + </Property> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="0"/> + <Property name="rows" type="int" value="1"/> + </Layout> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="panCenterSouth"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="5" right="5" top="5"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Last"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="panDownload"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder title="Zielsystem / Download"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"> + <Property name="alignment" type="int" value="0"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="butReset"> + <Properties> + <Property name="text" type="java.lang.String" value="Reset"/> + <Property name="enabled" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[5, 5, 5, 5]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onButtonReset"/> + </Events> + </Component> + <Component class="javax.swing.Box$Filler" name="filler1"> + <Properties> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[20, 32767]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[20, 0]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[20, 0]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.HorizontalStrut"/> + </AuxValues> + </Component> + <Component class="javax.swing.JCheckBox" name="chkResetBeforeDownload"> + <Properties> + <Property name="selected" type="boolean" value="true"/> + <Property name="text" type="java.lang.String" value="Reset"/> + <Property name="enabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="butDownloadStart"> + <Properties> + <Property name="text" type="java.lang.String" value="Start"/> + <Property name="enabled" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[5, 10, 5, 10]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onDownload"/> + </Events> + </Component> + <Component class="javax.swing.Box$Filler" name="filler3"> + <Properties> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 32767]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 0]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[10, 0]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.HorizontalStrut"/> + </AuxValues> + </Component> + <Component class="javax.swing.JButton" name="butDownloadStop"> + <Properties> + <Property name="text" type="java.lang.String" value="Stop"/> + <Property name="enabled" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[5, 10, 5, 10]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onButtonStop"/> + </Events> + </Component> + <Component class="javax.swing.Box$Filler" name="filler2"> + <Properties> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[20, 32767]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[20, 0]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[20, 0]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.HorizontalStrut"/> + </AuxValues> + </Component> + <Component class="javax.swing.JButton" name="butDownloadProperties"> + <Properties> + <Property name="text" type="java.lang.String" value="Einstellungen"/> + <Property name="enabled" type="boolean" value="false"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[5, 5, 5, 5]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="butDownloadPropertiesonButtonStop"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="panGlobal"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="javax.swing.Box$Filler" name="filler5"> + <Properties> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32767, 10]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 12]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 12]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/> + </AuxValues> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="First"/> + </Constraint> + </Constraints> + </Component> + <Container class="javax.swing.JPanel" name="jpanGlobalButtons"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> + <Property name="columns" type="int" value="1"/> + <Property name="rows" type="int" value="2"/> + <Property name="verticalGap" type="int" value="5"/> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="butProperties"> + <Properties> + <Property name="text" type="java.lang.String" value="Einstellungen µC"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[2, 2, 2, 2]"/> + </Property> + </Properties> + <Events> + <EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="onFilePropertiesGainLost"/> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onButtonProperties"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="butRefresh"> + <Properties> + <Property name="text" type="java.lang.String" value="Aktualisieren"/> + <Property name="actionCommand" type="java.lang.String" value="Refresh"/> + <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor"> + <Insets value="[2, 2, 2, 2]"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onRefresh"/> + </Events> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.Box$Filler" name="filler6"> + <Properties> + <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[32767, 10]"/> + </Property> + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 4]"/> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[0, 4]"/> + </Property> + </Properties> + <AuxValues> + <AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/> + </AuxValues> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Last"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="panSouth"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="panSouthSouth"> + <Properties> + <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> + <Color blue="cc" green="cc" red="cc" type="rgb"/> + </Property> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo"> + <EmptyBorder bottom="5" left="6" right="5" top="5"/> + </Border> + </Property> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="South"/> + </Constraint> + </Constraints> + + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/> + <SubComponents> + <Component class="javax.swing.JProgressBar" name="progressBar"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="West"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="testUserMessage"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="text" type="java.lang.String" value="User Message"/> + <Property name="focusable" type="boolean" value="false"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="Center"/> + </Constraint> + </Constraints> + </Component> + <Component class="javax.swing.JTextField" name="textStatus"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + <Property name="horizontalAlignment" type="int" value="0"/> + <Property name="text" type="java.lang.String" value="Status"/> + </Properties> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription"> + <BorderConstraints direction="East"/> + </Constraint> + </Constraints> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/gui/EasyProgrammer.java b/src/at/htlkaindorf/sx/EasyProgrammer/gui/EasyProgrammer.java new file mode 100644 index 0000000..6a08978 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/gui/EasyProgrammer.java @@ -0,0 +1,2444 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * EasyProgrammer.java + * + * Created on 20.10.2010, 12:18:57 + */ +package at.htlkaindorf.sx.EasyProgrammer.gui; + +import at.htlkaindorf.sx.EasyProgrammer.data.CpuTyp; +import at.htlkaindorf.sx.EasyProgrammer.data.ProgramFile; +import at.htlkaindorf.sx.EasyProgrammer.libs.EasyProgrammerLib; +import at.htlkaindorf.sx.EasyProgrammer.logging.LogWriterHandler; +import at.htlkaindorf.sx.EasyProgrammer.logging.Logger; +import at.htlkaindorf.sx.EasyProgrammer.serial.DownloadFile; +import at.htlkaindorf.sx.EasyProgrammer.serial.DownloadProtocol; +import at.htlkaindorf.sx.EasyProgrammer.serial.ResetProtocol; +import at.htlkaindorf.sx.EasyProgrammer.serial.SerialInterface; +import at.htlkaindorf.sx.EasyProgrammer.serial.SerialPortInfo; +import at.htlkaindorf.sx.EasyProgrammer.serial.SerialPortInfoFactory; +import at.htlkaindorf.sx.EasyProgrammer.serial.TerminalProtocol; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Toolkit; +import java.io.File; +import java.io.FileNotFoundException; +import java.net.URL; +import java.util.*; +import java.util.logging.Level; +import javax.swing.ComboBoxModel; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JOptionPane; +import javax.swing.JScrollPane; +import javax.swing.ScrollPaneConstants; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +/** + * + * @author steiner + */ +public final class EasyProgrammer extends javax.swing.JFrame +{ + private static final Logger LOG = Logger.getLogger(EasyProgrammer.class.getName()); + public final String SERIAL_DEFAULT_CONFIG = "57600/8N1"; + + public enum SwingWorkerTyp { REFRESH, CONNECT, LOADPROGRAMFILE, DOWNLOAD, RESET }; + public enum MessageTyp { DEFAULT, USER, STATUS, USERANDSTATUS }; + + private ArrayList<String> arglist; + private int exitCode; + private CpuTyp target; + private boolean resetBeforeDownload; + private String fileName; + private int waitTimeMillis; + + private GUISwingWorker swingWorker; + private javax.swing.JScrollPane textarea; + private JScrollPane scrollpane; + protected TerminalArea terminalArea; + protected TerminalProtocol terminalProtocol; + protected DownloadProtocol downloadProtocol; + protected ResetProtocol resetProtocol; + private DialogProperties dlgProperties; + + private DialogSerialConfig dialogSerialConfig; + private final List<SerialPortInfo> argSerialConfigs = new LinkedList<>(); + private DialogSelectProgramFile dialogSelectProgramFile; + protected ProgramFile programFile; + protected SerialInterface serialInterface; + private SerialPortInfo serialPortInfo; + private SerialPortInfo[] availableSerialPorts; + private String [] processArgs; + //private CpuTyp target; + private int serverPort; + private java.awt.Image appIcon; + + + /** Creates new form EasyProgrammer + * @param arglist */ + public EasyProgrammer(ArrayList<String> arglist) + { + this.arglist = arglist; + + try + { + if (arglist.contains("--batch")) + initInBatchMode(); + else + initInGUIMode(); + } + catch (Exception ex) + { + ex.printStackTrace(System.err); + return; + } + + String errMessage = null; + + } + + + + private void initInGUIMode () throws Exception + { + String errMessage = null; + + java.awt.Toolkit toolkit = this.getToolkit(); + URL url = this.getClass().getResource ("/at/htlkaindorf/sx/EasyProgrammer/icons/EasyProgrammer.png"); + this.appIcon = Toolkit.getDefaultToolkit().createImage(url); + + try + { + String version = jssc.SerialNativeInterface.getLibraryVersion(); + String nativeVersion = jssc.SerialNativeInterface.getNativeLibraryVersion(); + String msg = String.format("Using JSSC Version %s / Native %s", version, nativeVersion); + if (LOG.isInfoLogged()) + LOG.info(msg); + else + System.out.println(msg); + } + catch (Throwable th) + { + LOG.warning("No serial library (JSSC) available"); + JOptionPane.showMessageDialog(null, "Kein Zugriff auf Bibkliotheken für die serielle Schnittstelle", + "Fehler aufgetreten...", JOptionPane.ERROR_MESSAGE); + System.exit(1); + } + + try + { + String version = EasyProgrammerLib.getLibraryVersion(); + String nativeVersion = EasyProgrammerLib.getNativeLibraryVersion(); + String msg = String.format("Using EasyprogrammerLib Version %s / Native %s", version, nativeVersion); + if (LOG.isInfoLogged()) + LOG.info(msg); + else + System.out.println(msg); + } + catch (Throwable th) + { + LOG.warning(th); + } + + + initComponents(); + textStatus.setPreferredSize(new Dimension(Math.max(textStatus.getPreferredSize().width, 120), textStatus.getPreferredSize().height)); + setLookAndFeel(); + panSerialInterface2.setLayout(new SlidingWidthLayout()); + + + try + { + parseArguments(); + } + catch (Exception ex) + { + String msg = ex.getMessage(); + if (msg==null || msg.isEmpty()) + msg = ex.getClass().getName(); + JOptionPane.showMessageDialog(this, msg, "Fehler", JOptionPane.ERROR_MESSAGE); + exitCode = -150; + throw new Exception("Initialization in GUI mode failed", ex); + } + + serialInterface.checkInterfaces(); + updateComboInterface(); + ComboBoxModel m = comboInterface.getModel(); + if (!argSerialConfigs.isEmpty()) + { + String desiredName = argSerialConfigs.get(0).getName(); + String desiredConfig = argSerialConfigs.get(0).getConfigString(); + nextModelItem: for (int i=0; i<m.getSize(); i++) + { + Object item = m.getElementAt(i); + if (item instanceof SerialPortInfo) + { + SerialPortInfo pi = (SerialPortInfo) item; + for (int j=0; j<argSerialConfigs.size(); j++) + { + SerialPortInfo argpi = argSerialConfigs.get(j); + if (pi.getName().startsWith(argpi.getName())) + { + pi.setConfiguration(argpi.getConfigString()); + if (j==0) + m.setSelectedItem(item); + continue nextModelItem; + } + } + pi.setConfiguration(desiredConfig); + } + } + } + if (m.getSelectedItem() != null && m.getSelectedItem() instanceof SerialPortInfo) + textSerialConfig.setText( ((SerialPortInfo)m.getSelectedItem()).getConfigString()); + + dialogSerialConfig = new DialogSerialConfig(this, "Serielle Schnittstelle", true); + + this.chkResetBeforeDownload.setSelected(resetBeforeDownload); + if (dialogSelectProgramFile.getFileName() != null) + { + tfProgramFileName.setText(dialogSelectProgramFile.getFileName()); + tfProgramFileName.setToolTipText(dialogSelectProgramFile.getFolderName() + dialogSelectProgramFile.getFileName()); + } + + swingWorker = new GUISwingWorker(this); + terminalArea = new TerminalArea(); + scrollpane = new JScrollPane(terminalArea, + ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS + ); + Dimension size = new Dimension(scrollpane.getPreferredSize()); + size.height += 60; + scrollpane.setPreferredSize(size); + terminalArea.setViewport(scrollpane.getViewport()); + textTerminal.add(scrollpane); + terminalArea.requestFocus(); + + try + { + terminalProtocol = new TerminalProtocol(terminalArea, serialInterface); + terminalArea.setTerminalProtocol(terminalProtocol); + } + catch (Exception ex) + { + serialInterface = null; + JOptionPane.showMessageDialog(this, ex.getMessage(), "Fehler", JOptionPane.ERROR_MESSAGE); + exitCode = -151; + throw new Exception("Initialization in GUI mode failed"); + } + + + processArgs = null; + + this.setUserMessage(null); + this.setStatus(null); + this.buttonRefresh(null); + + if (tfProgramFileName.getText() != null && tfProgramFileName.getText().length()>0) + { + try { startSwingWorkerLater(SwingWorkerTyp.LOADPROGRAMFILE); } + catch (Exception ex) + { + System.err.println("Cannot execute 'select program file' (" + ex.getMessage() + ")"); + } + } + size = textHexSize.getPreferredSize(); + size.width = Math.max(size.width, 200); + textHexSize.setPreferredSize(size); + pack(); + setMinimumSize(new Dimension(650,500)); + setSize(new Dimension(750,600)); + +// size = getPreferredSize(); +// size.width = Math.min(size.width, 750); +// size.height = Math.min(size.height, 800); +// setMinimumSize(size); + + + } + + + private void initInBatchMode () throws Exception + { + String errMessage = null; + + try + { + parseArguments(); + } + catch (Exception ex) + { + ex.printStackTrace(System.err); + System.out.println("Error: " + ex.getMessage()); + exitCode = -101; + throw new Exception("Initialization in batch mode failed"); + } + + GUISwingWorker guiSwingWorker = new GUISwingWorker(this); + try + { + guiSwingWorker.loadFile(); + System.out.println("Hex-File succussfully loaded (" + + this.programFile.getMemoryLength() + " Bytes)"); + } + catch (Exception ex) + { + if (programFile == null || programFile.getErrorList()==null) + System.out.println("Error: Keine Hex-Programmdatei angegeben"); + else + { + System.out.println("Error on loading file:"); + ArrayList<String> errList = programFile.getErrorList(); + for (String error : errList) + System.out.println(" " + error); + } + exitCode = -102; + throw new Exception("Initialization in batch mode failed"); + } + + String ifc = String.format("%s (%s)", argSerialConfigs.get(0).getName(), argSerialConfigs.get(0).getConfigString()); + DownloadFile downloadFile = new DownloadFile(argSerialConfigs.get(0), programFile); + try + { + downloadFile.open(); + try + { + downloadFile.start(); + System.out.println(String.format("serial interface %s connected.", ifc)); + if (resetBeforeDownload) + downloadFile.resetTarget(target.getResetCommand()); + downloadFile.waitOnBootloader(waitTimeMillis, true); + downloadFile.download(arglist.contains("--nocheck")); + downloadFile.close(); + exitCode = 0; + } + catch (Exception ex) + { + downloadFile.close(); + exitCode = -103; + throw new Exception("Cannot download file"); + } + finally + { + System.out.println(String.format("serial interface %s disconnected.", ifc)); + } } + catch (Exception ex) + { + System.out.println(String.format("cannot open serial interface %s", ifc)); + + } + } + + private void parseArguments () throws Exception + { + int pos; + + this.serverPort = -1; + pos = arglist.indexOf("--port"); + if (pos>=0) + { + Scanner scanner = new Scanner(arglist.get(pos+1)); + this.serverPort = scanner.nextInt(); + if (this.serverPort <= 1000 || this.serverPort>65535) + { + String error = "Fehler bei der Option --port\n" + + "Server-Port '" + arglist.get(pos+1) + "' ungültig\n" + + "Gültig sind Portwerte zwischen 1000 und 65535"; + this.serverPort = -1; + throw new Exception(error); + } + } + + pos = arglist.indexOf("--target"); + if (pos<0) + target = new CpuTyp(CpuTyp.Typ.Atmega328P); + else + { + for (CpuTyp.Typ cputyp : CpuTyp.Typ.values()) + { + if (arglist.get(pos+1).equalsIgnoreCase(cputyp.name())) + { + target = new CpuTyp(cputyp); + break; + } + } + if (target == null) + { + String error = "Fehler bei der Option --target\n" + + "Target (CPU-Typ) '" + arglist.get(pos+1) + "' ungültig\n" + + "Verfügbar sind: " + target.getAvailableNames(); + throw new Exception(error); + } + } + + pos = arglist.indexOf("--noreset"); + if (pos>=0) + resetBeforeDownload = false; + else + resetBeforeDownload = true; + + + pos = arglist.indexOf("--resetcmd"); + String resetCmd = "@R"; + if (pos>=0) + { + if (arglist.size()>(pos+1) && !arglist.get(pos+1).startsWith("-")) + resetCmd = arglist.get(pos+1); + } + //target.setResetCommand(resetCmd + "\r\n"); + target.setResetCommand(resetCmd); + + resetCmd = null; + pos = arglist.indexOf("--resetseq"); + if (pos>=0) + { + if (arglist.size()>(pos+1) && !arglist.get(pos+1).startsWith("-")) + resetCmd = arglist.get(pos+1); + } + if (resetCmd != null) + target.setResetCommand(resetCmd); + + target.setBootloaderSize(2048); + + pos = arglist.indexOf("--wait"); + int waitTime = 10000; + if (pos>=0 && arglist.size()>(pos+1) && !arglist.get(pos+1).startsWith("-")) + { + try + { + waitTime = Integer.parseInt(arglist.get(pos+1)); + if (waitTime<100) + throw new Exception((String)null); + } + catch (Exception ex) + { + String error = "Fehler bei der Option --wait\n" + + "Hinter '--wait' befindet sich keine gültige Zahl\n" + + "Die Zahl muss >= 100 (ms) sein. Beispiel: --wait 5000"; + throw new Exception(error); + } + } + this.waitTimeMillis = waitTime; + + System.out.format("Target = %s\n", target==null ? "unknown" : target.getDescription()); + + try + { + serialInterface = new SerialInterface(); + jmiMonitor.setVisible(serialInterface.getMonitor() != null); + downloadProtocol = null; + resetProtocol = null; //new ResetProtocol(terminalArea, serialInterface); + } + catch (Exception ex) + { + String error = "Schwerwiegender Fehler\n" + + "Es fehlen die Programm-Bibliotheken für die serielle Schnittstelle!"; + throw new Exception(error); + } + + dlgProperties = new DialogProperties(this, "Einstellungen", true); + //this.chkResetBeforeDownload.setSelected(resetBeforeDownload); + this.dlgProperties.setCpuTyp(target); + + this.dialogSelectProgramFile = new DialogSelectProgramFile(this); + this.programFile = new ProgramFile(this.dialogSelectProgramFile, this.dlgProperties.getCpuTyp()); + + pos = arglist.indexOf("--hexfile"); + if (pos>=0 && arglist.size()>pos+1) + { + String fname = arglist.get(pos+1); + File file = null; + if (dialogSelectProgramFile.getFolderName() != null) + file = new File(dialogSelectProgramFile.getFolderName() + fname); + else + file = new File(fname); + + if (file != null && file.exists() && file.isFile()) + { + String fileName = file.getName(); + String dirName = file.getPath(); + dirName = dirName.substring(0, dirName.length()-fileName.length()); + dialogSelectProgramFile.setFolderName(dirName); + dialogSelectProgramFile.setFileName(fileName); + //System.out.println("Folder " + dialogSelectProgramFile.getFolderName()); + //System.out.println("Dir " + dirName); + //System.out.println("File " + fileName); + System.out.println("File '" + fname + "' will be used"); + } + else + System.out.println("File '" + fname + "' not found"); + } + + pos = arglist.indexOf("--interface-names"); + if (pos>=0) + { + try + { + System.out.println("Interface names = " + arglist.get(pos+1)); + String [] portNames = arglist.get(pos+1).split(","); + for (String n : portNames) + argSerialConfigs.add(SerialPortInfoFactory.getSerialPortInfo(n, SERIAL_DEFAULT_CONFIG)); + } + catch (Exception ex) + { + String error = "Fehler bei der Option --interface-names\n" + + "'" + arglist.get(pos+1) + "' ist fehlerhaft"; + throw new IllegalArgumentException(error, ex); + } + } + + pos = arglist.indexOf("--interface"); + if (pos>=0) + { + try + { + String config = arglist.get(pos+1); + String [] interfaces = config.split(";"); + for (String ifc : interfaces) + { + String serialConfig; + String serialName; + String [] f = ifc.split(":"); + switch (f.length) + { + case 1: serialName = f[0]; serialConfig = SERIAL_DEFAULT_CONFIG; break; + case 2: serialName = f[0]; serialConfig = f[1]; break; + default: throw new Exception(String.format("unvalid serial configuration '%s'", config)); + } + argSerialConfigs.add(SerialPortInfoFactory.getSerialPortInfo(serialName, serialConfig)); + } + } + catch (Exception ex) + { + String error = "Fehler bei der Option --interface\n" + + "'" + arglist.get(pos+1) + "' ist fehlerhaft"; + throw new IllegalArgumentException(error, ex); + } + } + + if (!argSerialConfigs.isEmpty()) + System.out.println(String.format("Desired Interface = %s (%s)", argSerialConfigs.get(0).getName(), argSerialConfigs.get(0).getConfigString())); + + pos = arglist.indexOf("--directory"); + if (pos>=0 && arglist.size()>pos+1) + { + String dirname = arglist.get(pos+1); + File dir = new File(dirname); + if (dir != null && dir.exists()) + { + dialogSelectProgramFile.setFolderName(dirname); + System.out.println("Directory '" + dirname + "' will be used"); + } + else + System.out.println("Directory '" + dirname + "' not found"); + } + } + + public int executeInBatchMode () + { + System.out.println("Done"); + return exitCode; + } + + + private void setLookAndFeel() + { + if (System.getProperty("os.name").toLowerCase().contains("win")) + { + try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } + catch (ClassNotFoundException ex) { } + catch (InstantiationException ex) { } + catch (IllegalAccessException ex) { } + catch (UnsupportedLookAndFeelException ex) { } + SwingUtilities.updateComponentTreeUI(this); + } + } + + protected void setUserMessage (String msg) + { + this.testUserMessage.setText(msg); + } + + + public CpuTyp getCpuTyp () + { + return dlgProperties.getCpuTyp(); + } + + public int getServerPort () + { + return this.serverPort; + } + + + public int getWaitTimeMillis () + { + return waitTimeMillis; + } + + + + public boolean containsArgument (String arg) + { + if (arglist != null && arglist.contains(arg)) + return true; + else + return false; + } + + + private void startProcess (String status, String [] arg) + { + setStatus(status); + this.processArgs = arg; + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + } + + private void startProcess (String status, String arg) + { + setStatus(status); + this.processArgs = new String [1]; + this.processArgs[0] = arg; + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + } + + protected void startProcess (String status) + { + setStatus(status); + this.processArgs = null; + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + } + + protected void endProcess () + { + setStatus(null); + this.processArgs = null; + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + + protected void setStatus (String status) + { + this.textStatus.setText(status); + } + + + + private void runDialogProperties () + { + String cpu = dlgProperties.getCpuTyp().getName(); + dlgProperties.setVisible(true); + if ( !dlgProperties.isPressedOK()) + return; + String ncpu = dlgProperties.getCpuTyp().getName(); + if (!cpu.equals(ncpu) && programFile != null) + { + try + { + programFile.setCpu(dlgProperties.getCpuTyp()); + LOG.info(String.format("Reloading program file with new cpu %s", ncpu)); + } + catch (Exception ex) + { + LOG.warning(ex); + } + + } + + + } + + private void runDialogSerialProperties () + { + dialogSerialConfig.setSerialPortInfo((SerialPortInfo)comboInterface.getSelectedItem()); + dialogSerialConfig.setVisible(true); + + if (!dialogSerialConfig.isPressedOK()) + return; + + serialPortInfo = dialogSerialConfig.getSerialPortInfo(); + DefaultComboBoxModel model = (DefaultComboBoxModel) comboInterface.getModel(); + for (int i=0; i<model.getSize(); i++) + { + SerialPortInfo spi = (SerialPortInfo)model.getElementAt(i); + if (spi!=serialPortInfo) + continue; + comboInterface.setSelectedIndex(i); + textSerialConfig.setText(serialPortInfo.getConfigString()); + //LOG.debug(textSerialConfig.getPreferredSize().toString()); + //textSerialConfig.setColumns(textSerialConfig.getText().length()); + //LOG.debug(textSerialConfig.getPreferredSize().toString()); + panSerialInterface.validate(); + panSerialInterface.repaint(); + return; + } + model.addElement(serialPortInfo); + comboInterface.setSelectedIndex(model.getSize()-1); + textSerialConfig.setText(serialPortInfo.getConfigString()); + textSerialConfig.setColumns(textSerialConfig.getText().length()); + panSerialInterface.validate(); + panSerialInterface.repaint(); + } + + protected void updateButtons () + { + //LOG.debug("Update Buttons", 2); + this.menuEditProperties.setEnabled(true); + this.butProperties.setEnabled(true); + + updateSerialButtons(); + updateDownloadButtons(); + iconCleanTerminal.setEnabled(true); + + if (this.swingWorker != null) + { + if (this.swingWorker.isDownloadInProgress() || this.swingWorker.isResetInProgress()) + { + this.butSelectProgramFile.setEnabled(false); + this.butReset.setEnabled(false); + this.menuFileOpen.setEnabled(false); + this.iconFileOpen.setEnabled(false); + this.butRefresh.setEnabled(false); + this.iconRefresh.setEnabled(false); + this.comboInterface.setEnabled(false); + return; + } + } + + this.butSelectProgramFile.setEnabled(true); + this.menuFileOpen.setEnabled(true); + this.iconFileOpen.setEnabled(true); + if (comboInterface.getModel().getSize()>0) + this.comboInterface.setEnabled(true); + if (serialInterface != null && serialInterface.isConnected()) + { + this.butRefresh.setEnabled(false); + this.iconRefresh.setEnabled(false); + this.comboInterface.setEnabled(false); + } + else + { + this.butRefresh.setEnabled(true); + this.butRefresh.setEnabled(true); + this.iconRefresh.setEnabled(true); + } + } + + + protected void updateSerialButtons() + { + //LOG.debug("Serial Buttons update", 2); + if (this.swingWorker != null) + { + if (this.swingWorker.isDownloadInProgress() || this.swingWorker.isResetInProgress()) + { + this.comboInterface.setEnabled(false); + this.butConnect.setEnabled(false); + this.butDisconnect.setEnabled(false); + this.iconConnect.setEnabled(false); + this.iconDisconnect.setEnabled(false); + this.butReset.setEnabled(false); + this.butSerialConfig.setEnabled(false); + if (this.terminalArea != null) + this.terminalArea.setFocusBlocked(true); + return; + } + } + + SerialPortInfo name = (SerialPortInfo) comboInterface.getSelectedItem(); + if (name != null) + textSerialConfig.setText(name.getConfigString()); + else + textSerialConfig.setText(null); + + if (name == null) + { + this.comboInterface.setEnabled(false); + this.butConnect.setEnabled(false); + this.butDisconnect.setEnabled(false); + this.iconConnect.setEnabled(false); + this.iconDisconnect.setEnabled(false); + this.butReset.setEnabled(false); + this.butSerialConfig.setEnabled(false); + if (this.terminalArea != null) + this.terminalArea.setFocusBlocked(true); + } + else if (!serialInterface.isInterfaceAvailable(name) && serialInterface.getPort()==null) + { + this.comboInterface.setEnabled(false); + this.butConnect.setEnabled(false); + this.butDisconnect.setEnabled(false); + this.iconConnect.setEnabled(false); + this.iconDisconnect.setEnabled(false); + this.butReset.setEnabled(false); + this.butSerialConfig.setEnabled(true); + if (this.terminalArea != null) + this.terminalArea.setFocusBlocked(true); + } + else if(serialInterface.isInterfaceAvailable(name) == true && serialInterface.getPort() == null) + { + this.comboInterface.setEnabled(true); + this.butConnect.setEnabled(true); + this.butDisconnect.setEnabled(false); + this.iconConnect.setEnabled(true); + this.iconDisconnect.setEnabled(false); + this.butReset.setEnabled(false); + this.butSerialConfig.setEnabled(true); + if (this.terminalArea != null) + this.terminalArea.setFocusBlocked(true); + } + else + { + this.comboInterface.setEnabled(false); + this.butConnect.setEnabled(false); + this.butDisconnect.setEnabled(true); + this.iconConnect.setEnabled(false); + this.iconDisconnect.setEnabled(true); + this.butReset.setEnabled(true); + this.butSerialConfig.setEnabled(false); + if (this.terminalArea != null) + this.terminalArea.setFocusBlocked(false); + } + } + + public void setFocusToTerminal () + { + if (this.terminalArea == null) + return; + + if (this.terminalArea.isFocusBlocked()) + return; + + this.terminalArea.requestFocus(); + } + + + protected void updateComboInterface() + { + boolean update = false; + ArrayList<SerialPortInfo> names = null; + + SerialPortInfo selected = (SerialPortInfo) this.comboInterface.getSelectedItem(); + ArrayList<SerialPortInfo> avail = serialInterface.getInterfaceNameList(); + if (avail.contains(selected)) + names = avail; + else + { + names = new ArrayList<>(avail); + if (selected != null) + names.add(selected); + Collections.sort(names); + } + comboInterface.setModel(new DefaultComboBoxModel(names.toArray())); + if (selected != null) + { + comboInterface.setSelectedItem(selected); + comboInterface.validate(); + comboInterface.repaint(); + } + else if (!names.isEmpty()) + { + comboInterface.setSelectedIndex(0); + selected = (SerialPortInfo)comboInterface.getSelectedItem(); + } + if (selected != null) + { + textSerialConfig.setText(selected.getConfigString()); + panSerialInterface.validate(); + panSerialInterface.repaint(); + } + //LOG.debug(String.format("updateComboInterface avail=%d, selected=%s", avail.size(), selected)); + } + + + protected void updateDownloadButtons() + { + if (this.swingWorker != null) + { + if (this.swingWorker.isDownloadInProgress()) + { + butReset.setEnabled(false); + butDownloadStart.setEnabled(false); + iconDownload.setEnabled(false); + butDownloadStop.setEnabled(true); + iconStop.setEnabled(true); + this.chkResetBeforeDownload.setEnabled(false); + return; + } + if (this.swingWorker.isResetInProgress()) + { + butReset.setEnabled(false); + butDownloadStart.setEnabled(false); + iconDownload.setEnabled(false); + butDownloadStop.setEnabled(false); + iconStop.setEnabled(false); + this.chkResetBeforeDownload.setEnabled(false); + return; + } + } + + if (this.serialInterface.isConnected() == false) + { + butReset.setEnabled(false); + butDownloadStart.setEnabled(false); + iconDownload.setEnabled(false); + butDownloadStop.setEnabled(false); + iconStop.setEnabled(false); + this.chkResetBeforeDownload.setEnabled(false); + return; + } + + if (this.programFile != null && this.programFile.getMemoryLength()>0) + { + butReset.setEnabled(true); + butDownloadStart.setEnabled(true); + iconDownload.setEnabled(true); + butDownloadStop.setEnabled(false); + iconStop.setEnabled(false); + this.chkResetBeforeDownload.setEnabled(true); + return; + } + + butReset.setEnabled(true); + butDownloadStart.setEnabled(false); + iconDownload.setEnabled(false); + butDownloadStop.setEnabled(false); + iconStop.setEnabled(false); + this.chkResetBeforeDownload.setEnabled(false); + } + + + protected void updateTextHexSize() + { + ArrayList errList = programFile.getErrorList(); + + if (programFile == null || dialogSelectProgramFile==null || dialogSelectProgramFile.getFileName() == null) + { + textHexSize.setText(null); + textHexSize.setToolTipText(null); + return; + } + + String err = null; + if (programFile.getErrorList() != null && programFile.getErrorList().size()>0) + { + StringBuilder sb = new StringBuilder(128); + + for (int i=0; i<errList.size(); i++) + { + if (programFile.getErrorList().get(i) instanceof String && sb.length()==0) + { + sb.append("Erster "); + sb.append((String)errList.get(i)); + } + } + err = sb.toString(); + } + + if (programFile.getMemoryLength()==0) + { + textHexSize.setText("0 Bytes, Datei fehlerhaft"); + textHexSize.setToolTipText(err); + return; + } + + if (programFile.getErrorList()!=null && programFile.getMemoryLength()>0) + { + textHexSize.setText(programFile.getMemoryLength() + " Bytes, Datei fehlerhaft"); + textHexSize.setToolTipText(err); + return; + } + + + // Program file ok + textHexSize.setText(programFile.getMemoryLength() + " Bytes, keine Fehler" ); + textHexSize.setToolTipText(programFile.getLastModifiedString()); + } + + + public String getProgramFileName () + { + return dialogSelectProgramFile.getFileName(); + } + + public SerialPortInfo getSerialPortInfo () + { + return serialPortInfo; + } + + private void comboInterface (java.awt.event.ActionEvent evt) + { + updateSerialButtons(); + } + + + public void execSwingWorkerProcess (SwingWorkerTyp swt, MessageTyp mt, List<String> chunks ) + { + switch (swt) + { + case REFRESH: case CONNECT: case LOADPROGRAMFILE: + switch (chunks.size()) + { + case 1: + setUserMessage((String)chunks.get(0)); + return; + + case 2: + setUserMessage((String)chunks.get(0)); + setStatus((String)chunks.get(1)); + return; + } + break; + } + throw new RuntimeException ("execSwingWorkerProcess - Unknown Typ/Message"); + } + + + public void execSwingWorkerDone (SwingWorkerTyp swt, int result) + { + switch (swt) + { + case REFRESH: + //** BUTTON REFRESH START ******************************************** + updateComboInterface(); + updateSerialButtons(); + if (result==0) + setUserMessage("Aktualisierung erfolgreich beendet"); + else + setUserMessage("Fehler bei der Aktualisierung"); + return; + + + case CONNECT: + switch (result) + { + case 0: + setUserMessage("Verbindung zu '" + serialPortInfo.getName() + "' erfolgreich geöffnet"); + break; + + default: + setUserMessage("Fehler: Schnittstelle kann nicht geöffnet werden"); + } + updateButtons(); + updateSerialButtons(); + return; + + + case LOADPROGRAMFILE: + switch (result) + { + case 0: // thread ends with no errors + textHexSize.setText(programFile.getMemoryLength() + " Bytes, keine Fehler" ); + textHexSize.setToolTipText(null); + setUserMessage("Programmdatei '" + dialogSelectProgramFile.getFileName() + "' erfolgreich geladen"); + return; + + case -1: // thread ends with "no memory byte found" + textHexSize.setText(programFile.getMemoryLength() + " Bytes, Datei fehlerhaft" ); + textHexSize.setToolTipText(null); + setUserMessage("Fehlerhafte Programmdatei (keine Intel-Hex Datei?)"); + return; + + case -2: // thread ends with some errors in Intel Hex File + if (programFile.getErrorList() == null) + { + textHexSize.setText(programFile.getMemoryLength() + " Bytes, Datei fehlerhaft" ); + textHexSize.setToolTipText(null); + } + else + { + ArrayList errList = programFile.getErrorList(); + textHexSize.setText(programFile.getMemoryLength() + " Bytes, " + errList.size() + " Fehler" ); + StringBuilder sb = new StringBuilder(128); + for (int i=0; i<errList.size(); i++) + { + if (errList.get(i) instanceof String && sb.length()==0) + { + sb.append("Erster "); + sb.append((String)errList.get(i)); + } + } + textHexSize.setToolTipText(sb.toString()); + } + setUserMessage("Fehlerhafte Programmdatei (Intel-Hex Formatfehler)"); + return; + + case -3: // thread ends with Exception + textHexSize.setText(programFile.getMemoryLength() + " Bytes, Datei fehlerhaft" ); + textHexSize.setToolTipText(null); + setUserMessage("Fehlerhafte Programmdatei (Intel-Hex Formatfehler)"); + return; + + default: + textHexSize.setText(programFile.getMemoryLength() + " Bytes, Datei fehlerhaft" ); + textHexSize.setToolTipText(null); + setUserMessage("Laden fehlgeschlagen (interner Fehler " + + result + ")"); + return; + } + } + throw new RuntimeException ("execSwingWorkerDone - Unknown typ/result"); + } + + + public void startSwingWorkerLater (SwingWorkerTyp typ) + { + this.swingWorker.startLater(typ); + } + + + public void startSwingWorker (SwingWorkerTyp typ) throws Exception + { + if (this.swingWorker.isUsed()) + throw new Exception("SwingWorker already used"); + + this.swingWorker.start(typ); + } + + + private void buttonRefresh (java.awt.event.ActionEvent evt) + { + this.setProgressBar(-1); + try { startSwingWorker(SwingWorkerTyp.REFRESH); } + catch (Exception ex) + { + System.err.println("Cannot execute 'refresh' (" + ex.getMessage() + ")"); + } + } + + + private void buttonConnect(java.awt.event.ActionEvent evt) + { + serialPortInfo = (SerialPortInfo)comboInterface.getSelectedItem(); + this.setProgressBar(-1); + try { startSwingWorker(SwingWorkerTyp.CONNECT); } + catch (Exception ex) + { + System.err.println("Cannot execute 'connect' (" + ex.getMessage() + ")"); + } + } + + + private void buttonDisconnect(java.awt.event.ActionEvent evt) + { + serialInterface.disconnect(); + this.setUserMessage("Verbindung geschlossen"); + updateButtons(); + updateSerialButtons(); + updateDownloadButtons(); + this.setProgressBar(-1); + } + + + private void buttonSelectProgramFile (java.awt.event.ActionEvent evt) + { + this.setProgressBar(-1); + this.dialogSelectProgramFile.setVisible(true); + if (this.dialogSelectProgramFile.isPressedOK()) + { + tfProgramFileName.setText(dialogSelectProgramFile.getFileName()); + tfProgramFileName.setToolTipText(dialogSelectProgramFile.getFolderName() + dialogSelectProgramFile.getFileName()); + + try { startSwingWorker(SwingWorkerTyp.LOADPROGRAMFILE); } + catch (Exception ex) + { + System.err.println("Cannot execute 'select program file' (" + ex.getMessage() + ")"); + } + } + } + + public String handleServerRequest (String command) + { + //System.out.println("Request eingetroffen: " + command); + if (command.equals("download")) + { + if (this.serialInterface.isConnected()==false) + return "download fails, target not connected"; + + buttonDownloadStart(null); + return "start download"; + } + + if (command.equals("connect")) + { + if (this.serialInterface.isConnected()) + return "target is already connected"; + + buttonConnect(null); + return "start connect"; + } + + if (command.startsWith("send_") && command.length()==6) + { + char c = command.charAt(5); + this.serialInterface.write(this, c); + return (char)c + " gesendet"; + } + + return "error (unvalid request)"; + } + + + private void buttonDownloadStart (java.awt.event.ActionEvent evt) + { + this.setProgressBar(-1); + this.programFile.setDownloadModeFast(false); + try { startSwingWorker(SwingWorkerTyp.DOWNLOAD); } + catch (Exception ex) + { + System.err.println("Cannot execute 'Download' (" + ex.getMessage() + ")"); + } + } + + + private void buttonStop (java.awt.event.ActionEvent evt) + { + if (this.swingWorker == null || this.swingWorker.isDownloadInProgress()==false) + return; + + this.swingWorker.stopDownload(); + } + + + private void buttonReset (java.awt.event.ActionEvent evt) + { + this.setProgressBar(-1); + try { startSwingWorker(SwingWorkerTyp.RESET); } + catch (Exception ex) + { + System.err.println("Cannot execute 'reset' (" + ex.getMessage() + ")"); + } + } + + + protected void setProgressBar (int value) + { + if (value<0) + { + this.progressBar.setValue(0); + this.progressBar.setStringPainted(false); + this.progressBar.setString(null); + } + else + { + this.progressBar.setValue(value); + this.progressBar.setStringPainted(true); + if (value < 100) + this.progressBar.setString(String.format("%3d %%", value)); + else + this.progressBar.setString("Fertig"); + } + } + + public void copyToClipBoard () + { + this.terminalArea.copyToClipBoard(); + } + + public void cleanTerminalContent () + { + this.terminalArea.deleteContent(); + this.invalidate(); + this.repaint(); + } + + public boolean isResetBeforeDownloadSelected () + { + return chkResetBeforeDownload.isSelected(); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() + { + + toolBar = new javax.swing.JToolBar(); + iconFileOpen = new javax.swing.JButton(); + jLabel7 = new javax.swing.JLabel(); + iconRefresh = new javax.swing.JButton(); + jLabel1 = new javax.swing.JLabel(); + iconConnect = new javax.swing.JButton(); + iconDisconnect = new javax.swing.JButton(); + jLabel5 = new javax.swing.JLabel(); + iconCopy = new javax.swing.JButton(); + iconPaste = new javax.swing.JButton(); + iconProperties = new javax.swing.JButton(); + iconCleanTerminal = new javax.swing.JButton(); + jLabel6 = new javax.swing.JLabel(); + iconDownload = new javax.swing.JButton(); + iconStop = new javax.swing.JButton(); + jLabel8 = new javax.swing.JLabel(); + iconAbout = new javax.swing.JButton(); + panCenter = new javax.swing.JPanel(); + panCenterNorth = new javax.swing.JPanel(); + panSerialInterface = new javax.swing.JPanel(); + panSerialInterface2 = new javax.swing.JPanel(); + comboInterface = new javax.swing.JComboBox(); + panSerialInterfaceEast = new javax.swing.JPanel(); + panSerialInterrfaceButtons = new javax.swing.JPanel(); + butConnect = new javax.swing.JButton(); + butDisconnect = new javax.swing.JButton(); + jpanSerailConfig = new javax.swing.JPanel(); + filler4 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 32767)); + textSerialConfig = new javax.swing.JTextField(); + butSerialConfig = new javax.swing.JButton(); + panProgramFile = new javax.swing.JPanel(); + butSelectProgramFile = new javax.swing.JButton(); + jPanel3 = new javax.swing.JPanel(); + tfProgramFileName = new javax.swing.JTextField(); + jPanel4 = new javax.swing.JPanel(); + textHexSize = new javax.swing.JTextField(); + panCenterCenter = new javax.swing.JPanel(); + textTerminal = new javax.swing.JPanel(); + panCenterSouth = new javax.swing.JPanel(); + panDownload = new javax.swing.JPanel(); + butReset = new javax.swing.JButton(); + filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(20, 0), new java.awt.Dimension(20, 0), new java.awt.Dimension(20, 32767)); + chkResetBeforeDownload = new javax.swing.JCheckBox(); + butDownloadStart = new javax.swing.JButton(); + filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 32767)); + butDownloadStop = new javax.swing.JButton(); + filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(20, 0), new java.awt.Dimension(20, 0), new java.awt.Dimension(20, 32767)); + butDownloadProperties = new javax.swing.JButton(); + panGlobal = new javax.swing.JPanel(); + filler5 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 12), new java.awt.Dimension(0, 12), new java.awt.Dimension(32767, 10)); + jpanGlobalButtons = new javax.swing.JPanel(); + butProperties = new javax.swing.JButton(); + butRefresh = new javax.swing.JButton(); + filler6 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 4), new java.awt.Dimension(0, 4), new java.awt.Dimension(32767, 10)); + panSouth = new javax.swing.JPanel(); + panSouthSouth = new javax.swing.JPanel(); + progressBar = new javax.swing.JProgressBar(); + testUserMessage = new javax.swing.JTextField(); + textStatus = new javax.swing.JTextField(); + menuBar = new javax.swing.JMenuBar(); + menuFile = new javax.swing.JMenu(); + menuFileOpen = new javax.swing.JMenuItem(); + jSeparator1 = new javax.swing.JPopupMenu.Separator(); + menuExit = new javax.swing.JMenuItem(); + menuEdit = new javax.swing.JMenu(); + menuEditProperties = new javax.swing.JMenuItem(); + menuSerialProperties = new javax.swing.JMenuItem(); + jSeparator2 = new javax.swing.JPopupMenu.Separator(); + menuCopy = new javax.swing.JMenuItem(); + menuPaste = new javax.swing.JMenuItem(); + jSeparator3 = new javax.swing.JPopupMenu.Separator(); + menuDeleteTerminalContent = new javax.swing.JMenuItem(); + menuHelp = new javax.swing.JMenu(); + jmiHelp = new javax.swing.JMenuItem(); + jmiMonitor = new javax.swing.JMenuItem(); + + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + setTitle("EasyProgrammer (JSSC)"); + setIconImage(appIcon); + setName("EasyProgrammer"); // NOI18N + setPreferredSize(new java.awt.Dimension(700, 383)); + + toolBar.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(204, 204, 204))); + toolBar.setRollover(true); + + iconFileOpen.setIcon(new javax.swing.ImageIcon(getClass().getResource("/at/htlkaindorf/sx/EasyProgrammer/icons/Open24.gif"))); // NOI18N + iconFileOpen.setToolTipText("Datei öffnen"); + iconFileOpen.setBorderPainted(false); + iconFileOpen.setFocusable(false); + iconFileOpen.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + iconFileOpen.setMargin(new java.awt.Insets(1, 5, 1, 5)); + iconFileOpen.setMaximumSize(new java.awt.Dimension(30, 24)); + iconFileOpen.setMinimumSize(new java.awt.Dimension(30, 24)); + iconFileOpen.setPreferredSize(new java.awt.Dimension(30, 24)); + iconFileOpen.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + iconFileOpen.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onIconFileOpen(evt); + } + }); + toolBar.add(iconFileOpen); + + jLabel7.setMaximumSize(new java.awt.Dimension(10, 10)); + jLabel7.setMinimumSize(new java.awt.Dimension(10, 10)); + jLabel7.setPreferredSize(new java.awt.Dimension(10, 10)); + toolBar.add(jLabel7); + + iconRefresh.setIcon(new javax.swing.ImageIcon(getClass().getResource("/at/htlkaindorf/sx/EasyProgrammer/icons/Refresh24.gif"))); // NOI18N + iconRefresh.setToolTipText("Aktualisieren"); + iconRefresh.setBorderPainted(false); + iconRefresh.setFocusable(false); + iconRefresh.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + iconRefresh.setMargin(new java.awt.Insets(1, 10, 1, 10)); + iconRefresh.setMaximumSize(new java.awt.Dimension(30, 24)); + iconRefresh.setMinimumSize(new java.awt.Dimension(30, 24)); + iconRefresh.setPreferredSize(new java.awt.Dimension(30, 24)); + iconRefresh.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + iconRefresh.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onIconRefresh(evt); + } + }); + toolBar.add(iconRefresh); + + jLabel1.setMaximumSize(new java.awt.Dimension(10, 10)); + jLabel1.setMinimumSize(new java.awt.Dimension(10, 10)); + jLabel1.setPreferredSize(new java.awt.Dimension(10, 10)); + toolBar.add(jLabel1); + + iconConnect.setIcon(new javax.swing.ImageIcon(getClass().getResource("/at/htlkaindorf/sx/EasyProgrammer/icons/connect24.png"))); // NOI18N + iconConnect.setToolTipText("Mit µC-System verbinden"); + iconConnect.setBorderPainted(false); + iconConnect.setFocusable(false); + iconConnect.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + iconConnect.setMargin(new java.awt.Insets(1, 10, 1, 10)); + iconConnect.setMaximumSize(new java.awt.Dimension(30, 24)); + iconConnect.setMinimumSize(new java.awt.Dimension(30, 24)); + iconConnect.setPreferredSize(new java.awt.Dimension(30, 24)); + iconConnect.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + iconConnect.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onIconConnect(evt); + } + }); + toolBar.add(iconConnect); + + iconDisconnect.setIcon(new javax.swing.ImageIcon(getClass().getResource("/at/htlkaindorf/sx/EasyProgrammer/icons/disconnect24.png"))); // NOI18N + iconDisconnect.setToolTipText("Von µC-System trennen"); + iconDisconnect.setBorderPainted(false); + iconDisconnect.setFocusable(false); + iconDisconnect.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + iconDisconnect.setMargin(new java.awt.Insets(1, 10, 1, 10)); + iconDisconnect.setMaximumSize(new java.awt.Dimension(30, 24)); + iconDisconnect.setMinimumSize(new java.awt.Dimension(30, 24)); + iconDisconnect.setPreferredSize(new java.awt.Dimension(30, 24)); + iconDisconnect.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + iconDisconnect.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onIconDisconnect(evt); + } + }); + toolBar.add(iconDisconnect); + + jLabel5.setMaximumSize(new java.awt.Dimension(10, 10)); + jLabel5.setMinimumSize(new java.awt.Dimension(10, 10)); + jLabel5.setPreferredSize(new java.awt.Dimension(10, 10)); + toolBar.add(jLabel5); + + iconCopy.setIcon(new javax.swing.ImageIcon(getClass().getResource("/at/htlkaindorf/sx/EasyProgrammer/icons/Copy24.gif"))); // NOI18N + iconCopy.setToolTipText("Terminal-Inhalt in die Zwischenablage kopieren"); + iconCopy.setBorderPainted(false); + iconCopy.setFocusable(false); + iconCopy.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + iconCopy.setMargin(new java.awt.Insets(1, 10, 1, 10)); + iconCopy.setMaximumSize(new java.awt.Dimension(30, 24)); + iconCopy.setMinimumSize(new java.awt.Dimension(30, 24)); + iconCopy.setPreferredSize(new java.awt.Dimension(30, 24)); + iconCopy.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + iconCopy.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onIconCopy(evt); + } + }); + toolBar.add(iconCopy); + + iconPaste.setIcon(new javax.swing.ImageIcon(getClass().getResource("/at/htlkaindorf/sx/EasyProgrammer/icons/Paste24.gif"))); // NOI18N + iconPaste.setToolTipText("Inhalt der Zwischenablage als Terminal-Eingabe verwenden"); + iconPaste.setBorderPainted(false); + iconPaste.setEnabled(false); + iconPaste.setFocusable(false); + iconPaste.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + iconPaste.setMargin(new java.awt.Insets(1, 10, 1, 10)); + iconPaste.setMaximumSize(new java.awt.Dimension(30, 24)); + iconPaste.setMinimumSize(new java.awt.Dimension(30, 24)); + iconPaste.setPreferredSize(new java.awt.Dimension(30, 24)); + iconPaste.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + iconPaste.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onIconPaste(evt); + } + }); + toolBar.add(iconPaste); + + iconProperties.setIcon(new javax.swing.ImageIcon(getClass().getResource("/at/htlkaindorf/sx/EasyProgrammer/icons/Preferences24.gif"))); // NOI18N + iconProperties.setToolTipText("Terminal Einstellungen verändern"); + iconProperties.setBorderPainted(false); + iconProperties.setEnabled(false); + iconProperties.setFocusable(false); + iconProperties.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + iconProperties.setMargin(new java.awt.Insets(1, 10, 1, 10)); + iconProperties.setMaximumSize(new java.awt.Dimension(30, 24)); + iconProperties.setMinimumSize(new java.awt.Dimension(30, 24)); + iconProperties.setPreferredSize(new java.awt.Dimension(30, 24)); + iconProperties.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + iconProperties.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onIconProperties(evt); + } + }); + toolBar.add(iconProperties); + + iconCleanTerminal.setIcon(new javax.swing.ImageIcon(getClass().getResource("/at/htlkaindorf/sx/EasyProgrammer/icons/CleanTerminal24.png"))); // NOI18N + iconCleanTerminal.setToolTipText("Terminalinhalt löschen"); + iconCleanTerminal.setBorderPainted(false); + iconCleanTerminal.setEnabled(false); + iconCleanTerminal.setFocusable(false); + iconCleanTerminal.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + iconCleanTerminal.setMargin(new java.awt.Insets(1, 10, 1, 10)); + iconCleanTerminal.setMaximumSize(new java.awt.Dimension(30, 24)); + iconCleanTerminal.setMinimumSize(new java.awt.Dimension(30, 24)); + iconCleanTerminal.setPreferredSize(new java.awt.Dimension(30, 24)); + iconCleanTerminal.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + iconCleanTerminal.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onIconCleanTerminal(evt); + } + }); + toolBar.add(iconCleanTerminal); + + jLabel6.setMaximumSize(new java.awt.Dimension(10, 10)); + jLabel6.setMinimumSize(new java.awt.Dimension(10, 10)); + jLabel6.setPreferredSize(new java.awt.Dimension(10, 10)); + toolBar.add(jLabel6); + + iconDownload.setIcon(new javax.swing.ImageIcon(getClass().getResource("/at/htlkaindorf/sx/EasyProgrammer/icons/Download24.png"))); // NOI18N + iconDownload.setToolTipText("Download Hex-File"); + iconDownload.setBorderPainted(false); + iconDownload.setEnabled(false); + iconDownload.setFocusable(false); + iconDownload.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + iconDownload.setMargin(new java.awt.Insets(1, 10, 1, 10)); + iconDownload.setMaximumSize(new java.awt.Dimension(30, 24)); + iconDownload.setMinimumSize(new java.awt.Dimension(30, 24)); + iconDownload.setPreferredSize(new java.awt.Dimension(30, 24)); + iconDownload.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + iconDownload.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onIconDownload(evt); + } + }); + toolBar.add(iconDownload); + + iconStop.setIcon(new javax.swing.ImageIcon(getClass().getResource("/at/htlkaindorf/sx/EasyProgrammer/icons/Stop24.png"))); // NOI18N + iconStop.setToolTipText("Stop"); + iconStop.setBorderPainted(false); + iconStop.setEnabled(false); + iconStop.setFocusable(false); + iconStop.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + iconStop.setMargin(new java.awt.Insets(1, 10, 1, 10)); + iconStop.setMaximumSize(new java.awt.Dimension(30, 24)); + iconStop.setMinimumSize(new java.awt.Dimension(30, 24)); + iconStop.setPreferredSize(new java.awt.Dimension(30, 24)); + iconStop.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + iconStop.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onIconStop(evt); + } + }); + toolBar.add(iconStop); + + jLabel8.setMaximumSize(new java.awt.Dimension(10, 10)); + jLabel8.setMinimumSize(new java.awt.Dimension(10, 10)); + jLabel8.setPreferredSize(new java.awt.Dimension(10, 10)); + toolBar.add(jLabel8); + + iconAbout.setIcon(new javax.swing.ImageIcon(getClass().getResource("/at/htlkaindorf/sx/EasyProgrammer/icons/About24.gif"))); // NOI18N + iconAbout.setToolTipText("Ãber EasyProgrammer (Version...)"); + iconAbout.setBorderPainted(false); + iconAbout.setFocusable(false); + iconAbout.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + iconAbout.setMargin(new java.awt.Insets(1, 10, 1, 10)); + iconAbout.setMaximumSize(new java.awt.Dimension(30, 24)); + iconAbout.setMinimumSize(new java.awt.Dimension(30, 24)); + iconAbout.setPreferredSize(new java.awt.Dimension(30, 24)); + iconAbout.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + iconAbout.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onIconAbout(evt); + } + }); + toolBar.add(iconAbout); + + getContentPane().add(toolBar, java.awt.BorderLayout.PAGE_START); + + panCenter.setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 2, 2, 2)); + panCenter.setLayout(new java.awt.BorderLayout()); + + panCenterNorth.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + panCenterNorth.setLayout(new java.awt.BorderLayout()); + + panSerialInterface.setBorder(javax.swing.BorderFactory.createTitledBorder("Serielle Schnittstelle")); + panSerialInterface.setLayout(new java.awt.BorderLayout()); + + panSerialInterface2.setLayout(new java.awt.BorderLayout()); + + comboInterface.setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 1, 2, 1)); + comboInterface.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onComboInterface(evt); + } + }); + panSerialInterface2.add(comboInterface, java.awt.BorderLayout.NORTH); + + panSerialInterface.add(panSerialInterface2, java.awt.BorderLayout.CENTER); + + panSerialInterfaceEast.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 5, 0)); + + panSerialInterrfaceButtons.setLayout(new java.awt.GridLayout(1, 0, 5, 0)); + + butConnect.setText("Verbinden"); + butConnect.setEnabled(false); + butConnect.setMargin(new java.awt.Insets(3, 10, 3, 10)); + butConnect.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onButtonConnect(evt); + } + }); + panSerialInterrfaceButtons.add(butConnect); + + butDisconnect.setText("Trennen"); + butDisconnect.setEnabled(false); + butDisconnect.setMargin(new java.awt.Insets(3, 3, 3, 3)); + butDisconnect.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onButtonDisconnect(evt); + } + }); + panSerialInterrfaceButtons.add(butDisconnect); + + panSerialInterfaceEast.add(panSerialInterrfaceButtons); + + jpanSerailConfig.add(filler4); + + textSerialConfig.setEditable(false); + textSerialConfig.setText("115200,none,1.5"); + textSerialConfig.setFocusable(false); + textSerialConfig.setMargin(new java.awt.Insets(0, 5, 0, 5)); + textSerialConfig.setMinimumSize(new java.awt.Dimension(120, 27)); + textSerialConfig.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + textSerialConfigActionPerformed(evt); + } + }); + jpanSerailConfig.add(textSerialConfig); + + panSerialInterfaceEast.add(jpanSerailConfig); + + butSerialConfig.setText("Einstellungen"); + butSerialConfig.setMargin(new java.awt.Insets(3, 3, 3, 3)); + butSerialConfig.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onButtonSerialConfig(evt); + } + }); + panSerialInterfaceEast.add(butSerialConfig); + + panSerialInterface.add(panSerialInterfaceEast, java.awt.BorderLayout.EAST); + + panCenterNorth.add(panSerialInterface, java.awt.BorderLayout.PAGE_START); + + panProgramFile.setBorder(javax.swing.BorderFactory.createTitledBorder("Programmdatei (Hex-File)")); + panProgramFile.setLayout(new java.awt.BorderLayout()); + + butSelectProgramFile.setText("Datei"); + butSelectProgramFile.setMargin(new java.awt.Insets(3, 10, 3, 10)); + butSelectProgramFile.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onSelectProgramFile(evt); + } + }); + panProgramFile.add(butSelectProgramFile, java.awt.BorderLayout.WEST); + + jPanel3.setBorder(javax.swing.BorderFactory.createEmptyBorder(3, 1, 3, 1)); + jPanel3.setLayout(new java.awt.GridLayout(1, 0)); + + tfProgramFileName.setEditable(false); + tfProgramFileName.setToolTipText(""); + tfProgramFileName.setFocusable(false); + tfProgramFileName.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + tfProgramFileNameActionPerformed(evt); + } + }); + jPanel3.add(tfProgramFileName); + + panProgramFile.add(jPanel3, java.awt.BorderLayout.CENTER); + + jPanel4.setBorder(javax.swing.BorderFactory.createEmptyBorder(3, 1, 3, 1)); + jPanel4.setMinimumSize(new java.awt.Dimension(40, 33)); + jPanel4.setLayout(new java.awt.GridLayout(1, 0)); + + textHexSize.setEditable(false); + textHexSize.setFocusable(false); + jPanel4.add(textHexSize); + + panProgramFile.add(jPanel4, java.awt.BorderLayout.EAST); + + panCenterNorth.add(panProgramFile, java.awt.BorderLayout.PAGE_END); + + panCenter.add(panCenterNorth, java.awt.BorderLayout.NORTH); + + panCenterCenter.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 5, 5, 5)); + panCenterCenter.setLayout(new java.awt.GridLayout(1, 0)); + + textTerminal.setBorder(javax.swing.BorderFactory.createTitledBorder("Terminal")); + textTerminal.setLayout(new java.awt.GridLayout(1, 0)); + panCenterCenter.add(textTerminal); + + panCenter.add(panCenterCenter, java.awt.BorderLayout.CENTER); + + panCenterSouth.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + panCenterSouth.setLayout(new java.awt.BorderLayout()); + + panDownload.setBorder(javax.swing.BorderFactory.createTitledBorder("Zielsystem / Download")); + panDownload.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT)); + + butReset.setText("Reset"); + butReset.setEnabled(false); + butReset.setMargin(new java.awt.Insets(5, 5, 5, 5)); + butReset.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onButtonReset(evt); + } + }); + panDownload.add(butReset); + panDownload.add(filler1); + + chkResetBeforeDownload.setSelected(true); + chkResetBeforeDownload.setText("Reset"); + chkResetBeforeDownload.setEnabled(false); + panDownload.add(chkResetBeforeDownload); + + butDownloadStart.setText("Start"); + butDownloadStart.setEnabled(false); + butDownloadStart.setMargin(new java.awt.Insets(5, 10, 5, 10)); + butDownloadStart.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onDownload(evt); + } + }); + panDownload.add(butDownloadStart); + panDownload.add(filler3); + + butDownloadStop.setText("Stop"); + butDownloadStop.setEnabled(false); + butDownloadStop.setMargin(new java.awt.Insets(5, 10, 5, 10)); + butDownloadStop.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onButtonStop(evt); + } + }); + panDownload.add(butDownloadStop); + panDownload.add(filler2); + + butDownloadProperties.setText("Einstellungen"); + butDownloadProperties.setEnabled(false); + butDownloadProperties.setMargin(new java.awt.Insets(5, 5, 5, 5)); + butDownloadProperties.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + butDownloadPropertiesonButtonStop(evt); + } + }); + panDownload.add(butDownloadProperties); + + panCenterSouth.add(panDownload, java.awt.BorderLayout.CENTER); + + panGlobal.setLayout(new java.awt.BorderLayout()); + panGlobal.add(filler5, java.awt.BorderLayout.PAGE_START); + + jpanGlobalButtons.setLayout(new java.awt.GridLayout(2, 1, 0, 5)); + + butProperties.setText("Einstellungen µC"); + butProperties.setMargin(new java.awt.Insets(2, 2, 2, 2)); + butProperties.addFocusListener(new java.awt.event.FocusAdapter() + { + public void focusLost(java.awt.event.FocusEvent evt) + { + onFilePropertiesGainLost(evt); + } + }); + butProperties.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onButtonProperties(evt); + } + }); + jpanGlobalButtons.add(butProperties); + + butRefresh.setText("Aktualisieren"); + butRefresh.setActionCommand("Refresh"); + butRefresh.setMargin(new java.awt.Insets(2, 2, 2, 2)); + butRefresh.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onRefresh(evt); + } + }); + jpanGlobalButtons.add(butRefresh); + + panGlobal.add(jpanGlobalButtons, java.awt.BorderLayout.CENTER); + panGlobal.add(filler6, java.awt.BorderLayout.PAGE_END); + + panCenterSouth.add(panGlobal, java.awt.BorderLayout.EAST); + + panCenter.add(panCenterSouth, java.awt.BorderLayout.PAGE_END); + + getContentPane().add(panCenter, java.awt.BorderLayout.CENTER); + + panSouth.setLayout(new java.awt.BorderLayout()); + + panSouthSouth.setBackground(new java.awt.Color(204, 204, 204)); + panSouthSouth.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 6, 5, 5)); + panSouthSouth.setLayout(new java.awt.BorderLayout()); + panSouthSouth.add(progressBar, java.awt.BorderLayout.WEST); + + testUserMessage.setEditable(false); + testUserMessage.setText("User Message"); + testUserMessage.setFocusable(false); + panSouthSouth.add(testUserMessage, java.awt.BorderLayout.CENTER); + + textStatus.setEditable(false); + textStatus.setHorizontalAlignment(javax.swing.JTextField.CENTER); + textStatus.setText("Status"); + panSouthSouth.add(textStatus, java.awt.BorderLayout.EAST); + + panSouth.add(panSouthSouth, java.awt.BorderLayout.SOUTH); + + getContentPane().add(panSouth, java.awt.BorderLayout.SOUTH); + + menuFile.setText("Datei"); + + menuFileOpen.setIcon(new javax.swing.ImageIcon(getClass().getResource("/at/htlkaindorf/sx/EasyProgrammer/icons/Open16.gif"))); // NOI18N + menuFileOpen.setText("Ãffnen"); + menuFileOpen.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onMenuFileOpen(evt); + } + }); + menuFile.add(menuFileOpen); + menuFile.add(jSeparator1); + + menuExit.setText("Beenden"); + menuExit.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onMenuExit(evt); + } + }); + menuFile.add(menuExit); + + menuBar.add(menuFile); + + menuEdit.setText("Bearbeiten"); + + menuEditProperties.setText("Einstellungen µC"); + menuEditProperties.setEnabled(false); + menuEditProperties.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onMenuEditProperties(evt); + } + }); + menuEdit.add(menuEditProperties); + + menuSerialProperties.setText("Serielle Schnittstelle"); + menuSerialProperties.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onMenuEditSerialProperties(evt); + } + }); + menuEdit.add(menuSerialProperties); + menuEdit.add(jSeparator2); + + menuCopy.setIcon(new javax.swing.ImageIcon(getClass().getResource("/at/htlkaindorf/sx/EasyProgrammer/icons/Copy16.gif"))); // NOI18N + menuCopy.setText("Kopieren"); + menuCopy.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onMenuCopy(evt); + } + }); + menuEdit.add(menuCopy); + + menuPaste.setIcon(new javax.swing.ImageIcon(getClass().getResource("/at/htlkaindorf/sx/EasyProgrammer/icons/Paste16.gif"))); // NOI18N + menuPaste.setText("Einfügen"); + menuPaste.setEnabled(false); + menuEdit.add(menuPaste); + menuEdit.add(jSeparator3); + + menuDeleteTerminalContent.setText("Terminalinhalt löschen"); + menuDeleteTerminalContent.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onMenuDeleteTerminalContent(evt); + } + }); + menuEdit.add(menuDeleteTerminalContent); + + menuBar.add(menuEdit); + + menuHelp.setText("Hilfe"); + + jmiHelp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/at/htlkaindorf/sx/EasyProgrammer/icons/About16.gif"))); // NOI18N + jmiHelp.setText("Ãber EasyProgrammer..."); + jmiHelp.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + onMenuAbout(evt); + } + }); + menuHelp.add(jmiHelp); + + jmiMonitor.setText("Monitor"); + jmiMonitor.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + jmiMonitoronMenuAbout(evt); + } + }); + menuHelp.add(jmiMonitor); + + menuBar.add(menuHelp); + + setJMenuBar(menuBar); + + pack(); + }// </editor-fold>//GEN-END:initComponents + + private void onMenuAbout(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onMenuAbout + {//GEN-HEADEREND:event_onMenuAbout + DialogAbout aboutDialog = new DialogAbout(this, true); + aboutDialog.setVisible(true); + }//GEN-LAST:event_onMenuAbout + + private void onMenuEditProperties(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onMenuEditProperties + {//GEN-HEADEREND:event_onMenuEditProperties + this.runDialogProperties(); + }//GEN-LAST:event_onMenuEditProperties + + private void onIconFileOpen(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onIconFileOpen + {//GEN-HEADEREND:event_onIconFileOpen + buttonSelectProgramFile(evt); + }//GEN-LAST:event_onIconFileOpen + + private void onIconAbout(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onIconAbout + {//GEN-HEADEREND:event_onIconAbout + this.onMenuAbout(evt); + }//GEN-LAST:event_onIconAbout + + private void tfProgramFileNameActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_tfProgramFileNameActionPerformed + {//GEN-HEADEREND:event_tfProgramFileNameActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_tfProgramFileNameActionPerformed + + private void onRefresh(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onRefresh + {//GEN-HEADEREND:event_onRefresh + this.buttonRefresh(evt); + }//GEN-LAST:event_onRefresh + + private void onComboInterface(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onComboInterface + {//GEN-HEADEREND:event_onComboInterface + this.comboInterface(evt); + }//GEN-LAST:event_onComboInterface + + private void onButtonConnect(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onButtonConnect + {//GEN-HEADEREND:event_onButtonConnect + buttonConnect(evt); + }//GEN-LAST:event_onButtonConnect + + private void onButtonDisconnect(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onButtonDisconnect + {//GEN-HEADEREND:event_onButtonDisconnect + buttonDisconnect(evt); + }//GEN-LAST:event_onButtonDisconnect + + private void onFilePropertiesGainLost(java.awt.event.FocusEvent evt)//GEN-FIRST:event_onFilePropertiesGainLost + {//GEN-HEADEREND:event_onFilePropertiesGainLost + //this.terminalArea.requestFocus(); + }//GEN-LAST:event_onFilePropertiesGainLost + + private void onSelectProgramFile(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onSelectProgramFile + {//GEN-HEADEREND:event_onSelectProgramFile + buttonSelectProgramFile(evt); + }//GEN-LAST:event_onSelectProgramFile + + private void onDownload(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onDownload + {//GEN-HEADEREND:event_onDownload + buttonDownloadStart(evt); + }//GEN-LAST:event_onDownload + + private void onButtonStop(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onButtonStop + {//GEN-HEADEREND:event_onButtonStop + buttonStop(evt); + }//GEN-LAST:event_onButtonStop + + private void onButtonReset(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onButtonReset + {//GEN-HEADEREND:event_onButtonReset + buttonReset(evt); + }//GEN-LAST:event_onButtonReset + + private void onMenuFileOpen(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onMenuFileOpen + {//GEN-HEADEREND:event_onMenuFileOpen + buttonSelectProgramFile(evt); + }//GEN-LAST:event_onMenuFileOpen + + private void onMenuExit(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onMenuExit + {//GEN-HEADEREND:event_onMenuExit + this.setVisible(false); + this.dispose(); + }//GEN-LAST:event_onMenuExit + + private void textSerialConfigActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_textSerialConfigActionPerformed + {//GEN-HEADEREND:event_textSerialConfigActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_textSerialConfigActionPerformed + + private void onIconCopy(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onIconCopy + {//GEN-HEADEREND:event_onIconCopy + this.copyToClipBoard(); + }//GEN-LAST:event_onIconCopy + + private void onIconPaste(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onIconPaste + {//GEN-HEADEREND:event_onIconPaste + // TODO add your handling code here: + }//GEN-LAST:event_onIconPaste + + private void onIconProperties(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onIconProperties + {//GEN-HEADEREND:event_onIconProperties + // TODO add your handling code here: + }//GEN-LAST:event_onIconProperties + + private void onIconRefresh(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onIconRefresh + {//GEN-HEADEREND:event_onIconRefresh + buttonRefresh(evt); + }//GEN-LAST:event_onIconRefresh + + private void onButtonSerialConfig(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onButtonSerialConfig + {//GEN-HEADEREND:event_onButtonSerialConfig + runDialogSerialProperties(); + }//GEN-LAST:event_onButtonSerialConfig + + private void onIconConnect(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onIconConnect + {//GEN-HEADEREND:event_onIconConnect + buttonConnect(evt); + }//GEN-LAST:event_onIconConnect + + private void onIconDisconnect(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onIconDisconnect + {//GEN-HEADEREND:event_onIconDisconnect + buttonDisconnect(evt); + }//GEN-LAST:event_onIconDisconnect + + private void butDownloadPropertiesonButtonStop(java.awt.event.ActionEvent evt)//GEN-FIRST:event_butDownloadPropertiesonButtonStop + {//GEN-HEADEREND:event_butDownloadPropertiesonButtonStop + // TODO add your handling code here: + }//GEN-LAST:event_butDownloadPropertiesonButtonStop + + private void onMenuEditSerialProperties(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onMenuEditSerialProperties + {//GEN-HEADEREND:event_onMenuEditSerialProperties + this.runDialogSerialProperties(); + }//GEN-LAST:event_onMenuEditSerialProperties + + private void onMenuCopy(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onMenuCopy + {//GEN-HEADEREND:event_onMenuCopy + copyToClipBoard(); + }//GEN-LAST:event_onMenuCopy + + private void onMenuDeleteTerminalContent(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onMenuDeleteTerminalContent + {//GEN-HEADEREND:event_onMenuDeleteTerminalContent + cleanTerminalContent(); + }//GEN-LAST:event_onMenuDeleteTerminalContent + + private void onIconDownload(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onIconDownload + {//GEN-HEADEREND:event_onIconDownload + buttonDownloadStart(evt); + }//GEN-LAST:event_onIconDownload + + private void onIconStop(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onIconStop + {//GEN-HEADEREND:event_onIconStop + buttonStop(evt); + }//GEN-LAST:event_onIconStop + + private void onIconCleanTerminal(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onIconCleanTerminal + {//GEN-HEADEREND:event_onIconCleanTerminal + cleanTerminalContent(); + }//GEN-LAST:event_onIconCleanTerminal + + private void onButtonProperties(java.awt.event.ActionEvent evt)//GEN-FIRST:event_onButtonProperties + {//GEN-HEADEREND:event_onButtonProperties + this.runDialogProperties(); + }//GEN-LAST:event_onButtonProperties + + private void jmiMonitoronMenuAbout(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jmiMonitoronMenuAbout + {//GEN-HEADEREND:event_jmiMonitoronMenuAbout + serialInterface.printMonitor(); + }//GEN-LAST:event_jmiMonitoronMenuAbout + + + private static String [] getOptionInfo (String s) + { + String [] f = new String [4]; + f[0] = s.substring(0,2); + f[1] = s.substring(3,4); + f[2] = s.substring(4,26).trim(); + f[3] = s.substring(26).trim(); + + return f; + } + + /** + * @param args the command line arguments + */ + public static void main(final String args[]) throws FileNotFoundException + { + boolean linux = System.getProperty("os.name").contains("nux") ? true : false; + + String [] availOptions = { + "-h 0 --help @Afor help of command line options", + "-V 0 --version @Afor current software version", + "-b 0 --batch @Aexecute easyprogrammer in batch mode (without GUI)", + "-i 1 --interface @Wfor desired interface ( -i COM1 or -i COM1:57600/N/1", + "-i 1 --interface @Lfor desired interface ( -i /dev/ttyUSB0 or -i /dev/ttyUSB0:57600/N/1)", + "-n 1 --interface-names @Wfor available interface names ( -n COM1,COM2,COM3)", + "-n 1 --interface-names @Lfor available interface names ( -n /dev/ttyS0,/dev/ttyUSB0)", + "-d 1 --directory @Ldirectory path for program file (-d /home/user/hex-files)", + "-d 1 --directory @Wdirectory path for program file (-d C:\\temp)", + "-f 1 --hexfile @Aname of program-file (-f test.hex)", + "-r 0 --noreset @Asend no reset-command before download", + "-C 1 --resetcmd @Asend '@reset' (or given string) +CR +LF before download", + "-R 1 --resetseq @Asend '@reset' (or given string) (without CR or LF) before download", + "-c 0 --nocheck @Adon't check system response after download", + "-t 1 --target @A'-t atmeag328p' or '-t atmega16' or -t atmega8L' (default atmega328p)", + "-p 1 --port @Astart server on specified port ( -p 4711)", + "-w 1 --wait @ATime in ms waiting for Bootloader repsonse", + "-l 1 --loglevel @ALOG-Level (SEVERE,WARNING,INFO,CONFIG,FINE,FINER,FINEST,ALL)" + }; + + if (args.length>0 && (args[0].equals("-h") || args[0].equals("--help"))) + { + System.out.println("EasyProgrammer Version " + DialogAbout.version); + System.out.println("(C) Manfred Steiner (sx@htl-kaindorf.ac.at)"); + System.out.println(); + System.out.println("Available argument options are:"); + + for (String s : availOptions) + { + String [] f = getOptionInfo(s); + int argcnt = Integer.parseInt(f[1]); + if (f[3].startsWith("@A") || (linux && f[3].startsWith("@L")) || (!linux && f[3].startsWith("@W")) ) + { + System.out.print(" " + f[0]); + System.out.print(" " + f[2]); + for (int i=0; i<(20-f[2].length()); i++) + System.out.print(" "); + if (argcnt==0) + System.out.print(" "); + else for (int i=0; i<argcnt; i++) + System.out.print("<...> "); + System.out.println(f[3].substring(2)); + } + } + + System.out.println(); + System.exit(0); + } + + final ArrayList<String> arglist = new ArrayList<String>(); + + for (int pos=0; pos<args.length; pos++) + { + String a = args[pos]; + if (a.charAt(0) == '-' && a.charAt(1) != '-') + { + for (int i = 1; i<a.length(); i++ ) + { + boolean found = false; + for (String s : availOptions) + { + String [] f = getOptionInfo(s); + int argcnt = Integer.parseInt(f[1]); + + if (f[0].equals(a)) + { + arglist.add(f[2]); + for (int j=0; j<argcnt; j++) + arglist.add(args[pos+j+1]); + pos += argcnt; + found = true; + } + } + if (!found) + { + String msg = "Error: unknown option (-" + a.charAt(i) + ")"; + System.err.println(msg); + if (arglist.contains("--batch")==false) + JOptionPane.showMessageDialog(null, msg, "Programmstart fehlgeschlagen", JOptionPane.ERROR_MESSAGE); + System.exit(-1); + } + } + } + else if (a.startsWith("--")) + { + boolean found = false; + for (String s : availOptions) + { + String [] f = getOptionInfo(s); + int argcnt = Integer.parseInt(f[1]); + + if (f[2].equals(a)) + { + arglist.add(f[2]); + for (int j=0; j<argcnt; j++) + arglist.add(args[pos+j+1]); + pos += argcnt; + found = true; + break; + } + } + if (!found) + { + String msg = "Error: unknown option (" + a + ")"; + System.err.println(msg); + if (arglist.contains("--batch")==false) + JOptionPane.showMessageDialog(null, msg, "Programmstart fehlgeschlagen", JOptionPane.ERROR_MESSAGE); + System.exit(-1); + } + } + else + { + String msg = "Error: unknown option (" + a + ")"; + System.err.println(msg); + if (arglist.contains("--batch")==false) + JOptionPane.showMessageDialog(null, msg, "Programmstart fehlgeschlagen", JOptionPane.ERROR_MESSAGE); + System.exit(-1); + } + + } + //System.out.println(arglist); + + if (arglist.contains("--version")) + { + System.out.println("EasyProgrammer Version " + DialogAbout.version); + System.out.println("(C) Manfred Steiner (sx@htl-kaindorf.ac.at)"); + System.out.println(" ... start with -h or --help for more information"); + System.out.println(); + } + + if (arglist.contains("--batch")) + { + int ret = new EasyProgrammer(arglist).executeInBatchMode(); + System.exit(ret); + } + + Logger.setParentLogger(LOG); + LOG.setUseParentHandlers(false); + LogWriterHandler logWriterHandler = new LogWriterHandler(System.out, System.out); + LOG.setLevel(Level.WARNING); + logWriterHandler.setLevel(Level.WARNING); + LOG.setLocationShown(false); + LOG.addHandler(logWriterHandler); + if (arglist.contains("--loglevel")) + { + LOG.setLocationShown(true); + switch (arglist.get(arglist.indexOf("--loglevel")+1)) + { + case "SEVERE": LOG.setLevel(Level.SEVERE); break; + case "WARNING": LOG.setLevel(Level.WARNING); break; + case "INFO": LOG.setLevel(Level.INFO); break; + case "CONFIG": LOG.setLevel(Level.CONFIG); break; + case "FINE": LOG.setLevel(Level.FINE); break; + case "FINER": LOG.setLevel(Level.FINER); break; + case "FINEST": LOG.setLevel(Level.FINEST); break; + case "ALL": LOG.setLevel(Level.ALL); break; + default: + System.out.println("Unvalid Log-Level, stay on WARNING"); + } + + switch (arglist.get(arglist.indexOf("--loglevel")+1)) + { + case "SEVERE": logWriterHandler.setLevel(Level.SEVERE); break; + case "WARNING": logWriterHandler.setLevel(Level.WARNING); break; + case "INFO": logWriterHandler.setLevel(Level.INFO); break; + case "CONFIG": logWriterHandler.setLevel(Level.CONFIG); break; + case "FINE": logWriterHandler.setLevel(Level.FINE); break; + case "FINER": logWriterHandler.setLevel(Level.FINER); break; + case "FINEST": logWriterHandler.setLevel(Level.FINEST); break; + case "ALL": logWriterHandler.setLevel(Level.ALL); break; + } + } + + try + { + for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) + { + if ("Nimbus".equals(info.getName())) + { + javax.swing.UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } + catch (ClassNotFoundException ex) + { + java.util.logging.Logger.getLogger(EasyProgrammer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + catch (InstantiationException ex) + { + java.util.logging.Logger.getLogger(EasyProgrammer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + catch (IllegalAccessException ex) + { + java.util.logging.Logger.getLogger(EasyProgrammer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + catch (javax.swing.UnsupportedLookAndFeelException ex) + { + java.util.logging.Logger.getLogger(EasyProgrammer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + + UIManager.getLookAndFeelDefaults().put("ScrollBar.minimumThumbSize", new Dimension(30, 30)); + + java.awt.EventQueue.invokeLater(new Runnable() + { + @Override + public void run() + { + new EasyProgrammer(arglist).setVisible(true); + } + }); + } + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton butConnect; + private javax.swing.JButton butDisconnect; + private javax.swing.JButton butDownloadProperties; + private javax.swing.JButton butDownloadStart; + private javax.swing.JButton butDownloadStop; + private javax.swing.JButton butProperties; + private javax.swing.JButton butRefresh; + private javax.swing.JButton butReset; + private javax.swing.JButton butSelectProgramFile; + private javax.swing.JButton butSerialConfig; + private javax.swing.JCheckBox chkResetBeforeDownload; + private javax.swing.JComboBox comboInterface; + private javax.swing.Box.Filler filler1; + private javax.swing.Box.Filler filler2; + private javax.swing.Box.Filler filler3; + private javax.swing.Box.Filler filler4; + private javax.swing.Box.Filler filler5; + private javax.swing.Box.Filler filler6; + private javax.swing.JButton iconAbout; + private javax.swing.JButton iconCleanTerminal; + private javax.swing.JButton iconConnect; + private javax.swing.JButton iconCopy; + private javax.swing.JButton iconDisconnect; + private javax.swing.JButton iconDownload; + private javax.swing.JButton iconFileOpen; + private javax.swing.JButton iconPaste; + private javax.swing.JButton iconProperties; + private javax.swing.JButton iconRefresh; + private javax.swing.JButton iconStop; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPopupMenu.Separator jSeparator1; + private javax.swing.JPopupMenu.Separator jSeparator2; + private javax.swing.JPopupMenu.Separator jSeparator3; + private javax.swing.JMenuItem jmiHelp; + private javax.swing.JMenuItem jmiMonitor; + private javax.swing.JPanel jpanGlobalButtons; + private javax.swing.JPanel jpanSerailConfig; + private javax.swing.JMenuBar menuBar; + private javax.swing.JMenuItem menuCopy; + private javax.swing.JMenuItem menuDeleteTerminalContent; + private javax.swing.JMenu menuEdit; + private javax.swing.JMenuItem menuEditProperties; + private javax.swing.JMenuItem menuExit; + private javax.swing.JMenu menuFile; + private javax.swing.JMenuItem menuFileOpen; + private javax.swing.JMenu menuHelp; + private javax.swing.JMenuItem menuPaste; + private javax.swing.JMenuItem menuSerialProperties; + private javax.swing.JPanel panCenter; + private javax.swing.JPanel panCenterCenter; + private javax.swing.JPanel panCenterNorth; + private javax.swing.JPanel panCenterSouth; + private javax.swing.JPanel panDownload; + private javax.swing.JPanel panGlobal; + private javax.swing.JPanel panProgramFile; + private javax.swing.JPanel panSerialInterface; + private javax.swing.JPanel panSerialInterface2; + private javax.swing.JPanel panSerialInterfaceEast; + private javax.swing.JPanel panSerialInterrfaceButtons; + private javax.swing.JPanel panSouth; + private javax.swing.JPanel panSouthSouth; + private javax.swing.JProgressBar progressBar; + private javax.swing.JTextField testUserMessage; + private javax.swing.JTextField textHexSize; + private javax.swing.JTextField textSerialConfig; + private javax.swing.JTextField textStatus; + private javax.swing.JPanel textTerminal; + private javax.swing.JTextField tfProgramFileName; + private javax.swing.JToolBar toolBar; + // End of variables declaration//GEN-END:variables +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/gui/GUISwingWorker.java b/src/at/htlkaindorf/sx/EasyProgrammer/gui/GUISwingWorker.java new file mode 100644 index 0000000..b371cb7 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/gui/GUISwingWorker.java @@ -0,0 +1,916 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.htlkaindorf.sx.EasyProgrammer.gui; + +import at.htlkaindorf.sx.EasyProgrammer.gui.EasyProgrammer.SwingWorkerTyp; +import at.htlkaindorf.sx.EasyProgrammer.logging.Logger; +import at.htlkaindorf.sx.EasyProgrammer.serial.DownloadProtocol; +import at.htlkaindorf.sx.EasyProgrammer.serial.ResetProtocol; +import at.htlkaindorf.sx.EasyProgrammer.server.IDEServer; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.PipedReader; +import java.io.PipedWriter; +import java.util.ArrayList; +import java.util.InputMismatchException; +import java.util.LinkedList; +import java.util.List; +import java.util.Scanner; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import javax.swing.SwingWorker; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +/** + * + * @author Manfred Steiner + */ +public class GUISwingWorker +{ + + private static final Logger LOG = Logger.getLogger(GUISwingWorker.class.getName()); + LinkedList<SwingWorkerTyp> list = new LinkedList(); + + EasyProgrammer easyProgrammer; + SwingWorker sw; + IDEServerSwingWorker idesw; + + + public GUISwingWorker(EasyProgrammer easyProgrammer) + { + this.easyProgrammer = easyProgrammer; + if (easyProgrammer.getServerPort()>1000) + { + this.idesw = new IDEServerSwingWorker(); + this.idesw.execute(); + } + } + + public boolean isUsed () + { + if (sw != null) + return true; + + return false; + } + + public void setProgress (int progress) + { + + } + + public boolean isDownloadInProgress () + { + if (this.sw != null && this.sw instanceof DownloadSwingWorker) + return true; + + return false; + } + + public boolean isResetInProgress () + { + if (this.sw != null && this.sw instanceof ResetSwingWorker) + return true; + + return false; + } + + + public void stopDownload () + { + if (this.isDownloadInProgress() == false) + return; + + this.sw.cancel(true); + } + + + public void startLater (SwingWorkerTyp typ) + { + if (easyProgrammer==null) + throw new RuntimeException("Internal error"); + if (isUsed()) + list.add(typ); + else + start(typ); + } + + public void start (SwingWorkerTyp typ) + { + if (isUsed() || easyProgrammer==null) + throw new RuntimeException("Internal error"); + + switch (typ) + { + case REFRESH: + easyProgrammer.startProcess("Aktualisieren"); + sw = new RefreshSwingWorker(); + break; + + case CONNECT: + easyProgrammer.startProcess("Verbinden"); + sw = new ConnectSwingWorker(); + break; + + case LOADPROGRAMFILE: + easyProgrammer.startProcess("Hex-File laden"); + sw = new LoadProgramFileSwingWorker(); + break; + + case DOWNLOAD: + if (easyProgrammer.serialInterface.isConnected()) + { + easyProgrammer.startProcess("Download"); + sw = new DownloadSwingWorker(easyProgrammer.containsArgument("--nocheck")); + easyProgrammer.updateButtons(); + sw.addPropertyChangeListener((PropertyChangeListener)sw); + } + else + throw new RuntimeException("Download not possible when interface not connected"); + + break; + + case RESET: + if (easyProgrammer.serialInterface.isConnected()) + { + easyProgrammer.startProcess("Reset"); + sw = new ResetSwingWorker(); + easyProgrammer.updateButtons(); + sw.addPropertyChangeListener((PropertyChangeListener)sw); + } + else + throw new RuntimeException("Reset not possible when interface not connected"); + break; + + } + + sw.execute(); + } + + + private void removeActiveSwingWorker () + { + sw = null; + if (list.size()>0) + start(list.remove(0)); + } + + + public void execSwingWorkerProcess (SwingWorkerTyp swt, List<String> chunks ) + { + switch (swt) + { + case REFRESH: case CONNECT: case LOADPROGRAMFILE: + if (chunks.size()>0) + { + easyProgrammer.setUserMessage((String)chunks.get(chunks.size()-1)); + return; + } + } + throw new RuntimeException ("execSwingWorkerProcess - Unknown Typ/Message"); + } + + + public void execSwingWorkerDone (SwingWorkerTyp swt, int result) + { + switch (swt) + { + case LOADPROGRAMFILE: + switch (result) + { + case 0: // thread ends with no errors + easyProgrammer.updateTextHexSize(); + if (easyProgrammer.getProgramFileName() != null) + easyProgrammer.setUserMessage("Programmdatei '" + easyProgrammer.getProgramFileName() + "' erfolgreich geladen"); + else + easyProgrammer.setUserMessage("Initialisierung abgeschlossen"); + return; + + case -1: // thread ends with "no memory byte found" + easyProgrammer.updateTextHexSize(); + easyProgrammer.setUserMessage("Fehlerhafte Programmdatei (keine Intel-Hex Datei?)"); + return; + + case -2: // thread ends with some errors in Intel Hex File + easyProgrammer.updateTextHexSize(); + easyProgrammer.setUserMessage("Fehlerhafte Programmdatei (Intel-Hex Formatfehler)"); + return; + + case -3: // thread ends with Exception + easyProgrammer.updateTextHexSize(); + easyProgrammer.setUserMessage("Fehlerhafte Programmdatei (Intel-Hex Formatfehler)"); + return; + + default: + easyProgrammer.updateTextHexSize(); + easyProgrammer.setUserMessage("Laden fehlgeschlagen (interner Fehler " + + result + ")"); + return; + } + } + throw new RuntimeException ("execSwingWorkerDone - Unknown typ/result"); + } + + + public void loadFile () throws Exception + { + try + { + easyProgrammer.programFile.loadFile(); + if (easyProgrammer.programFile.getMemoryLength()<=0) + throw new Exception("Datei kann nicht geladen werden"); + + ArrayList errList = easyProgrammer.programFile.getErrorList(); + if (errList != null) + throw new Exception("Datei fehlerhaft (1)"); + } + catch (Exception ex) + { + throw new Exception("Datei fehlerhaft (2)"); + } + } + + + public void propertyChange(PropertyChangeEvent evt) + { + System.out.println(evt); + //throw new UnsupportedOperationException("Not supported yet."); + } + + + + class RefreshSwingWorker extends SwingWorker<Integer,String> + { + // Job wird in eigenem Thread ausgeführt. Hier dürfen keine Manipulationen + // an Swing-Komponenten stattfinden. + @Override + protected Integer doInBackground() throws Exception + { + publish("Verfügbare serielle Schnittstellen finden..."); + easyProgrammer.serialInterface.updateInterfaces(); + publish("Serielle Schnittstellen testen"); + easyProgrammer.serialInterface.checkInterfaces(); + if (easyProgrammer.getProgramFileName() == null) + return 0; + + publish("Hex-Datei aktualisieren"); + if (easyProgrammer.programFile.isModified()) + { + publish("Aktualisiere Programmdatei '" + easyProgrammer.getProgramFileName() + "'"); + //System.out.println("Aktualisiere Datei"); + try + { + loadFile(); + LOG.info("reloading file "); + } + catch (Exception ex) + { + ex.printStackTrace(System.err); + return -1; + } + } + return 0; + } + + // Durch publish() veröffentliche Zwischenergebnisse behandeln. + // process() wird innerhalb des EDT aufgerufen. Hier können Manipulationen + // an GUI-Elementen sicher vorgenommen werden. + @Override + protected void process(List<String> chunks) + { + execSwingWorkerProcess(SwingWorkerTyp.REFRESH, chunks); + } + + // Worker hat seinen Job beendet. done() wird innerhalb des EDT aufgerufen. + // Hier können Manipulationen an GUI-Elementen sicher vorgenommen werden. + @Override + protected void done() + { + try + { + int result = get(); + execSwingWorkerDone(SwingWorkerTyp.LOADPROGRAMFILE, result); + easyProgrammer.setProgressBar(100); + } + catch (Exception ex) + { + LOG.warning(ex); + easyProgrammer.setProgressBar(-1); + if (ex instanceof ExecutionException && ex.getCause() instanceof Exception) + ex = (Exception) ex.getCause(); + String msg = ex.getMessage(); + if (msg==null || msg.isEmpty()) + msg = ex.getClass().getSimpleName(); + easyProgrammer.setUserMessage(String.format("Error (%s)", msg)); + } + finally + { + easyProgrammer.updateComboInterface(); + easyProgrammer.updateSerialButtons(); + easyProgrammer.updateTextHexSize(); + + removeActiveSwingWorker(); + easyProgrammer.updateButtons(); + easyProgrammer.setFocusToTerminal(); + easyProgrammer.endProcess(); + } + + +// Integer result = -1000; +// +// try { result = get(); } +// catch (InterruptedException ex) { throw new RuntimeException(ex); } +// catch (ExecutionException ex) { /* throw new RuntimeException(ex); */ } +// finally +// { +// //System.out.println("Swingworker done"); +// //execSwingWorkerDone(SwingWorkerTyp.REFRESH, result); +// easyProgrammer.updateComboInterface(); +// easyProgrammer.updateSerialButtons(); +// easyProgrammer.updateTextHexSize(); +// +// if (result>-200 && result<=-100) +// { +// execSwingWorkerDone(SwingWorkerTyp.LOADPROGRAMFILE, result+100); +// } +// if (result==0 || result==-100) +// easyProgrammer.setUserMessage("Aktualisierung erfolgreich beendet"); +// else +// easyProgrammer.setUserMessage("Fehler bei der Aktualisierung"); +// +// easyProgrammer.updateButtons(); +// removeActiveSwingWorker(); +// easyProgrammer.endProcess(); +// } + } + } + + + class ConnectSwingWorker extends SwingWorker<Integer,String> + { + // Job wird in eigenem Thread ausgeführt. Hier dürfen keine Manipulationen + // an Swing-Komponenten stattfinden. + @Override + protected Integer doInBackground() throws Exception + { + publish("Ãffne Schnittstelle '" + easyProgrammer.getSerialPortInfo() + "'"); + easyProgrammer.serialInterface.connect(easyProgrammer.getSerialPortInfo()); + //System.out.println(" " + easyProgrammer); + //System.out.println(" " + easyProgrammer.serialInterface); + //System.out.println(" " + easyProgrammer.serialInterface.getPort()); + if (easyProgrammer.serialInterface.getPort()==null) + return -1; + return 0; + } + + // Durch publish() veröffentliche Zwischenergebnisse behandeln. + // process() wird innerhalb des EDT aufgerufen. Hier können Manipulationen + // an GUI-Elementen sicher vorgenommen werden. + @Override + protected void process(List<String> chunks) + { + execSwingWorkerProcess(SwingWorkerTyp.CONNECT, chunks); + } + + // Worker hat seinen Job beendet. done() wird innerhalb des EDT aufgerufen. + // Hier können Manipulationen an GUI-Elementen sicher vorgenommen werden. + @Override + protected void done() + { + Integer result = -1000; + + try { result = get(); } + catch (InterruptedException ex) { throw new RuntimeException(ex); } + catch (ExecutionException ex) { /*throw new RuntimeException(ex); */ } + finally + { + switch (result) + { + case 0: + easyProgrammer.setUserMessage("Verbindung zu '" + easyProgrammer.getSerialPortInfo() + "' erfolgreich geöffnet"); + break; + + default: + easyProgrammer.setUserMessage("Fehler: Schnittstelle kann nicht geöffnet werden"); + } + easyProgrammer.updateButtons(); + easyProgrammer.updateSerialButtons(); + easyProgrammer.updateDownloadButtons(); + removeActiveSwingWorker(); + easyProgrammer.setFocusToTerminal(); + easyProgrammer.endProcess(); + } + } + } + + class LoadProgramFileSwingWorker extends SwingWorker<Integer,String> + { + // Job wird in eigenem Thread ausgeführt. Hier dürfen keine Manipulationen + // an Swing-Komponenten stattfinden. + @Override + protected Integer doInBackground() throws Exception + { + publish("Lade Programmdatei '" + easyProgrammer.getProgramFileName() + "'"); + try { loadFile(); } + catch (Exception ex) + { + ex.printStackTrace(System.err); + return -1; + } + return 0; + } + + // Durch publish() veröffentliche Zwischenergebnisse behandeln. + // process() wird innerhalb des EDT aufgerufen. Hier können Manipulationen + // an GUI-Elementen sicher vorgenommen werden. + @Override + protected void process(List<String> chunks) + { + execSwingWorkerProcess(SwingWorkerTyp.LOADPROGRAMFILE, chunks); + } + + // Worker hat seinen Job beendet. done() wird innerhalb des EDT aufgerufen. + // Hier können Manipulationen an GUI-Elementen sicher vorgenommen werden. + @Override + protected void done() + { + Integer result = -1000; + + try { result = get(); } + catch (InterruptedException ex) { throw new RuntimeException(ex); } + catch (ExecutionException ex) { /* throw new RuntimeException(ex); */ } + finally + { + execSwingWorkerDone(SwingWorkerTyp.LOADPROGRAMFILE, result); + easyProgrammer.updateDownloadButtons(); + easyProgrammer.updateTextHexSize(); + removeActiveSwingWorker(); + easyProgrammer.endProcess(); + } + } + } + + class IDEServerSwingWorker extends SwingWorker<Integer,String> + { + final private Thread thread; + private BufferedReader inPipeReader; + private BufferedWriter outPipeWriter; + private PipedReader inPipe; + private PipedWriter outPipe; + + + public IDEServerSwingWorker() + { + super(); + this.thread = Thread.currentThread(); + inPipe = new PipedReader(); + inPipeReader = new BufferedReader(inPipe); + try + { + outPipe = new PipedWriter(inPipe); + outPipeWriter = new BufferedWriter(outPipe); + } + catch (IOException ex) + { + ex.printStackTrace(System.err); + } + } + + + // Job wird in eigenem Thread ausgeführt. Hier dürfen keine Manipulationen + // an Swing-Komponenten stattfinden. + @Override + protected Integer doInBackground() throws Exception + { + //System.out.println("Starte IDEServer..."); + IDEServer server = new IDEServer(easyProgrammer.getServerPort()); + + while (server != null) + { + try + { + //System.out.println("Server: Wait for Request "); + String [] request = server.getRequest().split(" "); + //System.out.println("Server: Request eingetroffen (" + request + ")"); + String answer = ""; + for (String cmd : request) + { + if (cmd.startsWith("wait_") && cmd.endsWith("ms")) + { + long time = -1; + try + { + Scanner scanner = new Scanner(cmd.substring(5, cmd.length()-2)); + time = scanner.nextInt(); + } + catch (InputMismatchException ex) {} + if (time>0 && time<1000) + { + Thread.sleep(time); + answer = answer + " '" + time + "ms delay done'"; + } + else + answer = answer + "'wait_???ms error'"; + } + else + { + publish(cmd); + String cmd_answer = inPipeReader.readLine(); + if (cmd_answer != null && cmd_answer.startsWith("start")) + { + int i = 0; + for (i=0; i<20000 && sw != null; i++) + Thread.sleep(50); + String [] s = cmd_answer.split(" "); + cmd_answer = s[1] + " done in " + (i*50) + "ms"; + } + answer = answer + " '" + cmd_answer + "'"; + } + } + server.send(answer); + } + catch (Exception ex) + { + ex.printStackTrace(System.err); + return -1; + } + } + + return 0; + } + + // Durch publish() veröffentliche Zwischenergebnisse behandeln. + // process() wird innerhalb des EDT aufgerufen. Hier können Manipulationen + // an GUI-Elementen sicher vorgenommen werden. + @Override + protected void process(List<String> chunks) + { + //System.out.println("Process request " + chunks.get(0)); + try + { + outPipeWriter.write(easyProgrammer.handleServerRequest(chunks.get(0))); + outPipeWriter.newLine(); outPipeWriter.flush(); + } + catch (IOException ex) + { + ex.printStackTrace(System.err); + } + + chunks.remove(0); + } + + // Worker hat seinen Job beendet. done() wird innerhalb des EDT aufgerufen. + // Hier können Manipulationen an GUI-Elementen sicher vorgenommen werden. + @Override + protected void done() + { + Integer result = -1000; + + try { result = get(); } + catch (InterruptedException ex) { throw new RuntimeException(ex); } + catch (ExecutionException ex) { /* throw new RuntimeException(ex); */ } + finally + { + System.out.println("IDEServer beendet"); + } + } + } + + + class DownloadSwingWorker extends SwingWorker<Integer,String> implements PropertyChangeListener, ChangeListener + { + DownloadProtocol downloadProtocol; + boolean nocheck; + + + public DownloadSwingWorker(boolean nocheck) + { + super(); + this.nocheck = nocheck; + } + + private void updateFile () throws Exception + { + if (easyProgrammer.programFile.isModified()) + { + publish("Aktualisiere Programmdatei '" + easyProgrammer.getProgramFileName() + "'"); + //System.out.println("Aktualisiere Datei"); + try + { + loadFile(); + LOG.info("reloading file"); + } + catch (Exception ex) + { + ex.printStackTrace(System.err); + throw new Exception("Hex-File Aktualisierung gscheitert"); + } + finally + { + publish("FileUpdate"); // update TolTipp data + } + } + } + + private void resetTarget () throws Exception + { + easyProgrammer.programFile.setBootloaderMode(2); + setProgress(0); + + try + { + downloadProtocol = new DownloadProtocol(easyProgrammer.serialInterface, easyProgrammer.terminalArea); + //downloadProtocol.connect(); + if (easyProgrammer.isResetBeforeDownloadSelected()) + { + publish("Reset + Warten auf Bootloader-Antwort"); + String resetCmd = easyProgrammer.getCpuTyp().getResetCommand(); + downloadProtocol.reset(this, true, resetCmd); + } + } + catch (UnsupportedOperationException ex) + { + ex.printStackTrace(System.err); + throw new Exception("Reset kann nicht ausgeführt werden (2)"); + } + catch (Exception ex) + { + ex.printStackTrace(System.err); + throw new Exception("Reset kann nicht ausgeführt werden (1)"); + } + } + + private void waitForBootloader () throws Exception + { + if (downloadProtocol.isBootloaderDetetcted()) + return; + + if (downloadProtocol.isBootloaderDetetcted() == false) + { + int timeout = easyProgrammer.getWaitTimeMillis(); + if (easyProgrammer.isResetBeforeDownloadSelected()) + publish("Reset gescheitert. Warte " + timeout + "ms auf Bootloader..."); + else + publish("Warte " + timeout + "ms auf Bootloader..."); + for (int i=0; i<=timeout/100; i++) + { + if (downloadProtocol.isBootloaderDetetcted()) + return; + setProgress(i*10000/timeout); + try { Thread.sleep(100); } + catch (Exception ex) + { + throw new Exception ("Warten auf Bootloader - abgebrochen"); + } + } + } + throw new Exception("Bootloader nicht detektiert (Timeout)"); + } + + private void downloadFile () throws Exception + { + setProgress(0); + try { downloadProtocol.download(easyProgrammer.programFile, this); } + catch (UnsupportedOperationException ex) + { + LOG.warning(ex); + throw new Exception ("Download gescheitert (1)", ex); + } + catch (Exception ex) + { + if (!ex.getMessage().contains("Download ok")) + LOG.warning(ex); + if (ex instanceof InterruptedException) + throw new Exception ("Download abgebrochen", ex); + else + { + if (ex.getMessage().contains("Download ok")) + { + if (this.nocheck==false) + throw ex; + } + else + { + LOG.warning(ex); + throw new Exception ("Download gescheitert (2)", ex); + } + } + } + } + + + @Override + protected Integer doInBackground() throws Exception + { + int ret = 0; + + try + { + updateFile(); + resetTarget(); + waitForBootloader(); + downloadFile(); + setProgress(100); + publish("Download erfolgreich abgeschlossen"); + } + catch (Exception ex) + { + if (ex.getMessage().contains("Download ok") == false) + { + publish("Fehler: " + ex.getMessage()); + ret = -1; + } + else + { + // Download ok but no correct system answer + publish (ex.getMessage()); + ret = -2; + } + //stateChanged(new ChangeEvent("Error (-997): Download gescheitert")); + } + finally + { + if (downloadProtocol.isConnected()) + downloadProtocol.disconnect(); + downloadProtocol = null; + } + + return ret; + } + + + @Override + protected void process(List<String> chunks) + { + if (chunks.size()>0) + { + for (String str : chunks) + { + if (str != null && str.contains("FileUpdate")) + easyProgrammer.updateTextHexSize(); + } + easyProgrammer.setUserMessage((String)chunks.get(chunks.size()-1)); + } + } + + // Worker hat seinen Job beendet. done() wird innerhalb des EDT aufgerufen. + // Hier können Manipulationen an GUI-Elementen sicher vorgenommen werden. + @Override + protected void done() + { + try + { + int result = get(); + easyProgrammer.setProgressBar(100); + easyProgrammer.programFile.completeDownloadDone(); + } + catch (Exception ex) + { + LOG.warning(ex); + easyProgrammer.setProgressBar(-1); + if (ex instanceof ExecutionException && ex.getCause() instanceof Exception) + ex = (Exception) ex.getCause(); + String msg = ex.getMessage(); + if (msg==null || msg.isEmpty()) + msg = ex.getClass().getSimpleName(); + easyProgrammer.setUserMessage(String.format("Error (%s)", msg)); + } + finally + { + removeActiveSwingWorker(); + easyProgrammer.updateButtons(); + easyProgrammer.setFocusToTerminal(); + easyProgrammer.endProcess(); + } + } + + + public void stopDownload () + { + System.out.println("Stop"); + } + + public void propertyChange(PropertyChangeEvent evt) + { + if (this.isDone() == false) + easyProgrammer.setProgressBar(this.getProgress()); + } + + + public void stateChanged(ChangeEvent e) + { + Object obj = e.getSource(); + + if (obj instanceof Integer) + setProgress((Integer)obj); + else if(obj instanceof String) + publish((String)obj); + } + } + + + class ResetSwingWorker extends SwingWorker<Integer,String> implements PropertyChangeListener, ChangeListener + { + ResetProtocol resetProtocol; + + @Override + @SuppressWarnings("SleepWhileHoldingLock") + protected Integer doInBackground() throws Exception + { + setProgress(0); + try + { + resetProtocol = new ResetProtocol(easyProgrammer.serialInterface, easyProgrammer.terminalArea); + resetProtocol.connect(); + resetProtocol.reset(this, false, easyProgrammer.getCpuTyp().getResetCommand()); + } + catch (UnsupportedOperationException ex) + { + stateChanged(new ChangeEvent("Error (-997): Download gescheitert")); + return -3; + } + catch (Exception ex) + { + throw ex; + } + finally + { + resetProtocol.disconnect(); + resetProtocol = null; + } + + setProgress(100); + stateChanged(new ChangeEvent("Reset erfolgreich")); + return 0; + } + + // Durch publish() veröffentliche Zwischenergebnisse behandeln. + // process() wird innerhalb des EDT aufgerufen. Hier können Manipulationen + // an GUI-Elementen sicher vorgenommen werden. + @Override + protected void process(List<String> chunks) + { + if (chunks.size()>0) + { + easyProgrammer.setUserMessage((String)chunks.get(chunks.size()-1)); + } + //System.out.println("Progress: " + getProgress()); + } + + // Worker hat seinen Job beendet. done() wird innerhalb des EDT aufgerufen. + // Hier können Manipulationen an GUI-Elementen sicher vorgenommen werden. + @Override + protected void done() + { + try + { + int result = get(); + easyProgrammer.setProgressBar(100); + } + catch (Exception ex) + { + LOG.warning(ex); + easyProgrammer.setProgressBar(-1); + if (ex instanceof ExecutionException && ex.getCause() instanceof Exception) + ex = (Exception) ex.getCause(); + String msg = ex.getMessage(); + if (msg==null || msg.isEmpty()) + msg = ex.getClass().getSimpleName(); + easyProgrammer.setUserMessage(String.format("Error (%s)", msg)); + } + finally + { + removeActiveSwingWorker(); + easyProgrammer.updateButtons(); + easyProgrammer.setFocusToTerminal(); + easyProgrammer.endProcess(); + } + } + + @Override + public void propertyChange(PropertyChangeEvent evt) + { + if (this.isDone() == false) + easyProgrammer.setProgressBar(this.getProgress()); + } + + + @Override + public void stateChanged(ChangeEvent e) + { + Object obj = e.getSource(); + + if (obj instanceof Integer) + setProgress((Integer)obj); + else if(obj instanceof String) + publish((String)obj); + } + } + + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/gui/SlidingWidthLayout.java b/src/at/htlkaindorf/sx/EasyProgrammer/gui/SlidingWidthLayout.java new file mode 100644 index 0000000..b3ceea0 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/gui/SlidingWidthLayout.java @@ -0,0 +1,192 @@ +package at.htlkaindorf.sx.EasyProgrammer.gui; + +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Insets; +import java.awt.LayoutManager; + + +/** + * + * @author steiner + */ +public class SlidingWidthLayout implements LayoutManager, java.io.Serializable +{ + private int hgap; + private int vgap; + + @Override + public void addLayoutComponent (String name, Component comp) + { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + + @Override + public void removeLayoutComponent (Component comp) + { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + + @Override + public Dimension preferredLayoutSize (Container parent) + { + synchronized (parent.getTreeLock()) + { + Insets insets = parent.getInsets(); + int ncomponents = parent.getComponentCount(); + int nrows = 1; + int ncols = 1; + + if (nrows > 0) + { + ncols = (ncomponents + nrows - 1) / nrows; + } + else + { + nrows = (ncomponents + ncols - 1) / ncols; + } + int w = 0; + int h = 0; + for (int i = 0; i < ncomponents; i++) + { + Component comp = parent.getComponent(i); + Dimension d = comp.getPreferredSize(); + if (w < d.width) + { + w = d.width; + } + if (h < d.height) + { + h = d.height; + } + } + return new Dimension(insets.left + insets.right + ncols * w + (ncols - 1) * hgap, + insets.top + insets.bottom + nrows * h + (nrows - 1) * vgap); + } + } + + + @Override + public Dimension minimumLayoutSize (Container parent) + { + synchronized (parent.getTreeLock()) + { + Insets insets = parent.getInsets(); + int ncomponents = parent.getComponentCount(); + int nrows = 1; + int ncols = 1; + + if (nrows > 0) + { + ncols = (ncomponents + nrows - 1) / nrows; + } + else + { + nrows = (ncomponents + ncols - 1) / ncols; + } + int w = 0; + int h = 0; + for (int i = 0; i < ncomponents; i++) + { + Component comp = parent.getComponent(i); + Dimension d = comp.getMinimumSize(); + if (w < d.width) + { + w = d.width; + } + if (h < d.height) + { + h = d.height; + } + } + return new Dimension(insets.left + insets.right + ncols * w + (ncols - 1) * hgap, + insets.top + insets.bottom + nrows * h + (nrows - 1) * vgap); + } + } + + + @Override + public void layoutContainer (Container parent) + { + synchronized (parent.getTreeLock()) + { + Insets insets = parent.getInsets(); + int ncomponents = parent.getComponentCount(); + int nrows = 1; + int ncols = 1; + boolean ltr = parent.getComponentOrientation().isLeftToRight(); + + if (ncomponents == 0) + { + return; + } + if (nrows > 0) + { + ncols = (ncomponents + nrows - 1) / nrows; + } + else + { + nrows = (ncomponents + ncols - 1) / ncols; + } + // 4370316. To position components in the center we should: + // 1. get an amount of extra space within Container + // 2. incorporate half of that value to the left/top position + // Note that we use trancating division for widthOnComponent + // The reminder goes to extraWidthAvailable + int totalGapsWidth = (ncols - 1) * hgap; + int widthWOInsets = parent.getWidth() - (insets.left + insets.right); + int widthOnComponent = (widthWOInsets - totalGapsWidth) / ncols; + int extraWidthAvailable = (widthWOInsets - (widthOnComponent * ncols + totalGapsWidth)) / 2; + + int totalGapsHeight = (nrows - 1) * vgap; + int heightWOInsets = parent.getHeight() - (insets.top + insets.bottom); + int heightOnComponent = (heightWOInsets - totalGapsHeight) / nrows; + int extraHeightAvailable = (heightWOInsets - (heightOnComponent * nrows + totalGapsHeight)) / 2; + if (ltr) + { + for (int c = 0, x = insets.left + extraWidthAvailable; c < ncols; c++, x += widthOnComponent + hgap) + { + for (int r = 0, y = insets.top + extraHeightAvailable; r < nrows; r++, y += heightOnComponent + vgap) + { + int i = r * ncols + c; + if (i < ncomponents) + { + // parent.getComponent(i).setBounds(x, y, widthOnComponent, heightOnComponent); + int h = parent.getComponent(i).getPreferredSize().height; + if (h<heightOnComponent) + { + y = y + (heightOnComponent-h)/2; + parent.getComponent(i).setBounds(x, y, widthOnComponent, h); + } + else + { + parent.getComponent(i).setBounds(x, y, widthOnComponent, heightOnComponent); + } + + } + } + } + } + else + { + for (int c = 0, x = (parent.getWidth() - insets.right - widthOnComponent) - extraWidthAvailable; c < ncols; c++, x -= widthOnComponent + hgap) + { + for (int r = 0, y = insets.top + extraHeightAvailable; r < nrows; r++, y += heightOnComponent + vgap) + { + int i = r * ncols + c; + if (i < ncomponents) + { + parent.getComponent(i).setBounds(x, y, widthOnComponent, heightOnComponent); + } + } + } + } + } + } + + + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/gui/TerminalArea.java b/src/at/htlkaindorf/sx/EasyProgrammer/gui/TerminalArea.java new file mode 100644 index 0000000..cb87889 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/gui/TerminalArea.java @@ -0,0 +1,656 @@ + +package at.htlkaindorf.sx.EasyProgrammer.gui; + +import at.htlkaindorf.sx.EasyProgrammer.data.LineTerminal; +import at.htlkaindorf.sx.EasyProgrammer.serial.SerialInterface; +import at.htlkaindorf.sx.EasyProgrammer.serial.TerminalProtocol; +import java.awt.AWTEvent; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.datatransfer.Clipboard; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ExecutionException; +import javax.accessibility.Accessible; +import javax.swing.JComponent; +import javax.swing.JViewport; +import javax.swing.Scrollable; +import javax.swing.SwingConstants; +import javax.swing.SwingWorker; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +/** + * Implementation of a Text Terminal GUI. + * @author Manfred Steiner + * see also http://download.oracle.com/javase/tutorial/uiswing/components/scrollpane.html + */ +public final class TerminalArea extends JComponent implements Scrollable, Accessible +{ + private LineTerminal terminal; // + private InputListener inputListener; + private JViewport viewport; + //private SerialInterface serialInterface; + private TerminalProtocol terminalProtocol; + private Font font; // font for drawing text + private Color noFocusBGColor; // bgColor in case of focus is lost + private Color lineBGColor; // backgrund Color for line output + private Dimension charSize; // width and heigth of one character (monospaced font) + private Dimension terminalSize; + private Rectangle visibleText; // visible area in lines and columns + private Point textOffset; // start point of text area in panel area (normally x=1,y=10) + private StringBuilder tempText; // text for special purposes (line number...) + private char[] tempChar; + private boolean hasFocus; // =true when TerminalArea has focus (background is white) + private boolean focusBlocked; // =true when no focus should be accepted (i.e. no interface available) + private boolean printLine; + private boolean printRow; + private boolean isfontChanged; // indicates change of Font (size) + private int paintCounter; + + + public TerminalArea() + { + super(); + + this.terminal = new LineTerminal(300); + this.noFocusBGColor = new Color(240,240,240); + this.lineBGColor = new Color(255,255,150); + enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.INPUT_METHOD_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK); + inputListener = new InputListener(this); + addMouseListener(inputListener); + addMouseWheelListener(inputListener); + addFocusListener(inputListener); + addKeyListener(inputListener); + setLayout(null); + updateUI(); + + font = new Font("Monospaced", Font.PLAIN, 16); + this.charSize = new Dimension(16,16); + this.terminalSize = new Dimension(0,0); + this.visibleText = new Rectangle(); + this.textOffset = new Point(1,4); + this.tempText = new StringBuilder(20); + this.tempChar = new char [1]; + this.printLine = true; + this.printRow = false; + this.isfontChanged = true; + + if (printRow) + this.textOffset.x += 4*16; + + if (printLine) + this.textOffset.x += 6*16; + + } + + public void copyToClipBoard () + { + Clipboard clip = getToolkit().getSystemClipboard(); + terminal.copyToClipboard(clip); + } + + public void deleteContent () + { + this.terminal.deleteContent(); + + } + + + public void setFocusBlocked(boolean focusBlocked) + { + this.focusBlocked = focusBlocked; + if (this.hasFocus) + this.setFocus(false); + } + + + public boolean isFocusBlocked() + { + return focusBlocked; + } + + + public void resizeFont (int sizeChange) + { + if (sizeChange == 0) + return; + + int size = this.font.getSize(); + size += sizeChange; + + if (size<2) size=2; + if (size>100) size=100; + + font = new Font("Monospaced", Font.PLAIN, size); + this.charSize = new Dimension(size, size); + this.isfontChanged = true; + this.revalidate(); + this.repaint(); + } + + // viewport must be known to set scroll position by program + public void setViewport(JViewport viewport) + { + this.viewport = viewport; + this.viewport.setScrollMode(JViewport.BLIT_SCROLL_MODE); + } + + + public void setTerminalProtocol(TerminalProtocol terminalProtocol) + { + this.terminalProtocol = terminalProtocol; + } + + + public void append (String s) + { + for (int i=0; i<s.length(); i++) + append(s.charAt(i)); + } + + + public void append (char c) + { + int lines = terminal.getLines(); + int columns = terminal.getColumns(); + int lastLine = terminal.getLastLine(); + terminal.append(c); + + int posY = terminal.getCursorLine(); + + if (lines != terminal.getLines() || columns != terminal.getColumns() || lastLine != terminal.getLastLine() + || posY > (this.visibleText.y + + this.visibleText.height + terminal.getFirstLine()) ) + { + //System.out.println("posY=" + posY + " visible=" + this.visibleText); + updateSize(); + Rectangle nrect = new Rectangle(); + nrect.width = textOffset.x + terminal.getColumns()*charSize.width; + nrect.height = 2*textOffset.y + terminal.getLines()*charSize.height; + Rectangle rect = this.viewport.getViewRect(); + if (nrect.height > rect.height) + { + //System.out.print("Scroll Y: " + rect + " terminal:" + nrect); + nrect.y = nrect.height - rect.height; + nrect.height = rect.height; + this.viewport.scrollRectToVisible(nrect); + //System.out.println(" scroll: " + nrect); + } + } + + //this.revalidate(); + this.repaint(); + //if (c=='\n') System.out.println("append: " + terminal); + } + + + private void updateSize () + { + int lines = terminal.getLines(); + int columns = terminal.getColumns(); + terminalSize.width = charSize.width*columns + textOffset.x; + terminalSize.height = charSize.height*lines + 2*textOffset.y; + + Dimension dimParent = this.getParent().getSize(); + if (dimParent.width > terminalSize.width) + terminalSize.width = dimParent.width; + if (dimParent.height > terminalSize.height) + terminalSize.height = dimParent.height; + this.setPreferredSize(terminalSize); + this.setSize(terminalSize); + //System.out.println("updateSize:" + terminalSize); + } + + + private void setVisible (Rectangle rect) + { + int x = rect.x - textOffset.x; + this.visibleText.x = x / this.charSize.width; + visibleText.width = rect.width / charSize.width + 1; + if (x % charSize.width == 0 && rect.width % charSize.width != 0) + visibleText.width--; + + int y = rect.y - textOffset.y; + visibleText.y = y / charSize.height; + visibleText.height = rect.height / charSize.height + 1; + if (y % charSize.height == 0 && rect.height % charSize.height != 0) + visibleText.height--; + + if (visibleText.width<0 || visibleText.height<0) + throw new RuntimeException("setVisible <0 ???"); + + //System.out.println("setVisible: " + rect + " --> " + visibleText); + } + + + public void setFocus(boolean focus) + { + if (focusBlocked) + focus = false; + + this.hasFocus = focus; + if (focus) + { + this.viewport.setBackground(Color.WHITE); + this.setBackground(Color.WHITE); + } + else + { + this.viewport.setBackground(this.noFocusBGColor); + this.setBackground(this.noFocusBGColor); + } + this.revalidate(); + this.repaint(); + } + + + + @Override + public void paint(Graphics g) + { + super.paint(g); + paintCounter++; + + g.setFont(font); + if (isfontChanged) + { + FontMetrics fontMetrics = g.getFontMetrics(); + charSize.height = (fontMetrics.getHeight()-fontMetrics.getHeight()/4); + if (charSize.height <= 0) charSize.height = 1; + charSize.width = fontMetrics.charWidth('0'); + isfontChanged = false; + updateSize(); + this.textOffset.x = 1; + if (printRow) this.textOffset.x += 4*charSize.width; + if (printLine) this.textOffset.x += 6*charSize.width; + } + + // clear background + Rectangle rect = g.getClipBounds(); + if (this.printLine==true) + { + g.setColor(this.lineBGColor); + g.fillRect(rect.x, rect.y, this.textOffset.x-charSize.width/2, rect.height); + rect.x = this.textOffset.x - charSize.width/2; + } + g.setColor(this.getBackground()); + g.fillRect(rect.x, rect.y, rect.width,rect.height); + g.setColor(Color.BLACK); + rect = g.getClipBounds(); + + if (rect.height>20) + this.tempChar[0] = 'h'; + + //if (rect.height>20) System.out.println("Paint: " + rect); + + if (rect.height>10 && rect.height<20) + g.drawRect(rect.x, rect.y, rect.width-1, rect.height-1); + + // calculate visible rows and cols + setVisible(rect); + + for (int i= visibleText.y; i< (visibleText.y + visibleText.height); i++) + { + int line = i + terminal.getFirstLine(); + this.tempText.delete(0, this.tempText.length()); + + if (visibleText.x<0 && terminal.isLineAvailable(line, 0)) + { + if (this.printLine==true) + this.tempText.append(String.format("%5d ", line)); + if (this.printRow==true) + this.tempText.append(String.format("%3d ", 0)); + g.drawString(this.tempText.toString(), 1, textOffset.y + charSize.height*(i+1)); + //System.out.println("Draw: " + this.tempText + " y=" + (textOffset.y + charSize.height*(i+1))); + } + + for (int j = Math.max(0,visibleText.x); j<=Math.min(visibleText.x+visibleText.width, terminal.length(line)-1); j++) + { + //System.out.print(paintCounter + ": Char " + i + "/" + j); + if (terminal.isTextAvailable(line, j)) + { + this.tempChar[0] = terminal.getText(line, j); + g.drawChars(this.tempChar, 0, 1, textOffset.x + this.charSize.width*j, textOffset.y + this.charSize.height*(i+1)); + //System.out.print(" available"); + } + // System.out.println(""); + } + } + + } + + + + + + + + + + // The scroll pane calls the client's getScrollableUnitIncrement method whenever + // the user clicks one of the buttons on the scroll bar. + // This method returns the number of pixels to scroll. + @Override + public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) + { + //System.out.println("Terminal: getScrollableUnitIncrement"); + if (orientation == SwingConstants.HORIZONTAL) + { + return charSize.width; + } + else + { + return charSize.height; + } + } + + // Get the preferred size of the viewport. This allows the client to influence the size of the viewport + // in which it is displayed. + @Override + public Dimension getPreferredScrollableViewportSize() + { + //System.out.println("Terminal: getPreferredScrollableViewportSize" + this.getPreferredSize()); + return this.getPreferredSize(); + } + + + // The scroll pane calls the client's getScrollableBlockIncrement method each time the user clicks on the track. + // This method returns the height of the visible rectangle minus a tick mark. This behavior is typical, + // but true if scrolling vertically, otherwise, it's the width. + // A block increment should be slightly smaller than the viewport to leave a littl of the previous visible area + // for context. For example, a text area might leave one or two lines of text for context + @Override + public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) + { + //System.out.println("Terminal: getScrollableBlockIncrement"); + if (orientation == SwingConstants.HORIZONTAL) + { + return (visibleRect.width/charSize.width) * charSize.width; + } + else + { + return (visibleRect.height/charSize.height) * charSize.height; + } + } + + // Get whether the scroll pane should force the client to be the same width as the viewport. + // A return value of true effectively disallows horizontal scrolling. + @Override + public boolean getScrollableTracksViewportWidth() + { + //System.out.println("Terminal: getScrollableTracksViewportWidth"); + return false; + } + + // Get whether the scroll pane should force the client to be the same height as the viewport. + // A return value of true effectively disallows vertical scrolling. + @Override + public boolean getScrollableTracksViewportHeight() + { + //System.out.println("Terminal: getScrollableTracksViewportHeight"); + return false; + } + + + @Override + protected void processKeyEvent(KeyEvent e) + { + super.processKeyEvent(e); + //System.out.println("processKeyEvent"); + } + + + @Override + protected void processMouseEvent(MouseEvent e) + { + super.processMouseEvent(e); + //System.out.println("processMouseEvent"); + } + + + @Override + protected void processMouseMotionEvent(MouseEvent e) + { + super.processMouseMotionEvent(e); + //System.out.println("processMouseMotionEvent"); + } + + + @Override + protected void processMouseWheelEvent(MouseWheelEvent e) + { + super.processMouseWheelEvent(e); + //System.out.println("processMouseWheelEvent"); + } + + @Override + //public boolean isFocusTraversable() + public boolean isFocusable() + { + return true; + } + + + static final class InputListener implements ChangeListener, FocusListener, MouseListener, MouseWheelListener, KeyListener + { + TerminalArea terminalArea; + private boolean dragActive; + private int dot; + private int mark; + + InputListener (TerminalArea terminalArea) + { + this.terminalArea = terminalArea; + } + + + @Override + public final String toString () + { + return "InputEvent"; + } + + + // --- ChangeListener methods ------------------- + + public final void stateChanged (ChangeEvent e) + { + } + + // --- FocusListener methods ----------------------------------- + public void focusGained (FocusEvent fe) + { + //AppContext.getAppContext().put(FOCUSED_COMPONENT, fe.getSource()); + terminalArea.setFocus(true); + //System.out.println("Focus gained"); + } + + public void focusLost (FocusEvent fe) + { + terminalArea.setFocus(false); + //System.out.println("Focus lost"); + } + + // --- MouseListener methods ----------------------------------- + + public final void mousePressed (MouseEvent e) + { + dragActive = true; + //System.out.println("mousePressed"); + } + + public final void mouseReleased (MouseEvent e) + { + dragActive = false; + //System.out.println(" mouseReleased"); + } + + public final void mouseClicked (MouseEvent e) + { + terminalArea.requestFocus(); + //System.out.println("mouseClicked"); + } + + public final void mouseEntered (MouseEvent e) + { + //System.out.println("mouseEntered"); + } + + public final void mouseExited(MouseEvent e) + { + //System.out.println("mouseExited"); + } + + // --- KeyListener methods ------------------- + + public void keyTyped(KeyEvent e) + { + char c; + //System.out.println("keytyped code=" + e.getKeyCode() + " char=" + (int)e.getKeyChar() + " mod=" + e.getModifiers() + " " + KeyEvent.getKeyModifiersText(e.getModifiers())); + //this.terminalArea.append(e.getKeyChar()); + //System.out.println(); + //System.out.println(KeyEvent.CTRL_DOWN_MASK); + //System.out.println(InputEvent.CTRL_DOWN_MASK); + + if (this.terminalArea.terminalProtocol.isConnected()) + { + try + { + c = e.getKeyChar(); + + if ((e.getModifiersEx()&KeyEvent.CTRL_DOWN_MASK) == KeyEvent.CTRL_DOWN_MASK) + { + if (c==10) c=10; + } + else + { + if (c==10) + { + this.terminalArea.terminalProtocol.write('\r'); + this.terminalArea.terminalProtocol.write('\n'); + //System.out.println("write char=" + (int)'\r' + " " + (int)'\n'); + return; + } + } + //System.out.println("write char=" + (int)c); + this.terminalArea.terminalProtocol.write(c); + } + catch (Exception ex) + { + ex.printStackTrace(System.err); + } + + /* + if (c=='\n') + { + this.terminalArea.serialInterface.write('\r'); + this.terminalArea.serialInterface.write('\n'); + } + else + this.terminalArea.serialInterface.write(e.getKeyChar()); + */ + } + + } + + public void keyPressed(KeyEvent e) + { + if (e.getKeyChar() == KeyEvent.CHAR_UNDEFINED) + { + int key = e.getKeyCode(); + //Funktionstaste abfragen + if (key == KeyEvent.VK_F1) + { + SwingWorker<Integer, String> worker = new SwingWorker<Integer, String>() + { + // Job wird in eigenem Thread ausgeführt. Hier dürfen keine Manipulationen + // an Swing-Komponenten stattfinden. + @Override + protected Integer doInBackground() throws Exception + { + for (int zeile=0; zeile<300; zeile++) + { + int spalten = (3*zeile) % 20 + 1; + if (zeile==20) spalten=90; + for (int spalte=0; spalte<spalten; spalte++) + { + terminalArea.append(Character.toChars(48 + (spalte+zeile)%10)[0]); + Thread.sleep(1); + + } + terminalArea.append('\n'); + //this.terminalArea.append('\r'); + } + + //publish("Verfügbare serielle Schnittstellen finden...", "Aktualisieren"); + //serialInterface.updateInterfaces(); + //blish("Serielle Schnittstellen testen"); + //serialInterface.checkInterfaces(); + return 0; + } + + // Durch publish() veröffentliche Zwischenergebnisse behandeln. + // process() wird innerhalb des EDT aufgerufen. Hier können Manipulationen + // an GUI-Elementen sicher vorgenommen werden. + @Override + protected void process(List<String> chunks) + { + } + + // Worker hat seinen Job beendet. done() wird innerhalb des EDT aufgerufen. + // Hier können Manipulationen an GUI-Elementen sicher vorgenommen werden. + @Override + protected void done() + { + Integer result = -1; + + try + { + result = get(); // Endergebnis aus doInBackground() holen. + } + catch (InterruptedException ex) + { + throw new RuntimeException(ex); + } + catch (ExecutionException ex) + { + //throw new RuntimeException(ex); + } + finally + { + } + } + + }; + worker.execute(); + } + } + } + + public void keyReleased(KeyEvent e) + { + //System.out.println("keyreleased"); + } + + + public void mouseWheelMoved(MouseWheelEvent e) + { + if (e.isControlDown()) + this.terminalArea.resizeFont(e.getWheelRotation()); + } + } + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/About16.gif b/src/at/htlkaindorf/sx/EasyProgrammer/icons/About16.gif new file mode 100644 index 0000000..04da95e Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/About16.gif differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/About24.gif b/src/at/htlkaindorf/sx/EasyProgrammer/icons/About24.gif new file mode 100644 index 0000000..9e11689 Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/About24.gif differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/CleanTerminal.png b/src/at/htlkaindorf/sx/EasyProgrammer/icons/CleanTerminal.png new file mode 100644 index 0000000..89420eb Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/CleanTerminal.png differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/CleanTerminal16.png b/src/at/htlkaindorf/sx/EasyProgrammer/icons/CleanTerminal16.png new file mode 100644 index 0000000..152787a Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/CleanTerminal16.png differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/CleanTerminal24.png b/src/at/htlkaindorf/sx/EasyProgrammer/icons/CleanTerminal24.png new file mode 100644 index 0000000..a39e0f9 Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/CleanTerminal24.png differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/Copy16.gif b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Copy16.gif new file mode 100644 index 0000000..fa98681 Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Copy16.gif differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/Copy24.gif b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Copy24.gif new file mode 100644 index 0000000..c665d07 Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Copy24.gif differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/Download.png b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Download.png new file mode 100644 index 0000000..1dbf99f Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Download.png differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/Download16.png b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Download16.png new file mode 100644 index 0000000..7ad6177 Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Download16.png differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/Download24.png b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Download24.png new file mode 100644 index 0000000..7d3e816 Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Download24.png differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/EasyProgrammer.png b/src/at/htlkaindorf/sx/EasyProgrammer/icons/EasyProgrammer.png new file mode 100644 index 0000000..9cf502d Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/EasyProgrammer.png differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/Information16.gif b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Information16.gif new file mode 100644 index 0000000..5748e32 Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Information16.gif differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/Information24.gif b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Information24.gif new file mode 100644 index 0000000..16cb3de Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Information24.gif differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/Open16.gif b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Open16.gif new file mode 100644 index 0000000..fabd567 Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Open16.gif differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/Open24.gif b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Open24.gif new file mode 100644 index 0000000..2086bc2 Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Open24.gif differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/Paste16.gif b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Paste16.gif new file mode 100644 index 0000000..f118c7e Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Paste16.gif differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/Paste24.gif b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Paste24.gif new file mode 100644 index 0000000..26cc4c5 Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Paste24.gif differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/Preferences24.gif b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Preferences24.gif new file mode 100644 index 0000000..2e727b2 Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Preferences24.gif differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/Refresh24.gif b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Refresh24.gif new file mode 100644 index 0000000..577c462 Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Refresh24.gif differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/Stop.png b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Stop.png new file mode 100644 index 0000000..398597e Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Stop.png differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/Stop16.png b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Stop16.png new file mode 100644 index 0000000..59b0824 Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Stop16.png differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/Stop24.png b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Stop24.png new file mode 100644 index 0000000..59429ce Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/Stop24.png differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/connect24.png b/src/at/htlkaindorf/sx/EasyProgrammer/icons/connect24.png new file mode 100644 index 0000000..d2c7c51 Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/connect24.png differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/disconnect24.png b/src/at/htlkaindorf/sx/EasyProgrammer/icons/disconnect24.png new file mode 100644 index 0000000..8903bf1 Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/disconnect24.png differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/easyprogrammer_128x128.ico b/src/at/htlkaindorf/sx/EasyProgrammer/icons/easyprogrammer_128x128.ico new file mode 100644 index 0000000..213d5c7 Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/easyprogrammer_128x128.ico differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/easyprogrammer_16x16.ico b/src/at/htlkaindorf/sx/EasyProgrammer/icons/easyprogrammer_16x16.ico new file mode 100644 index 0000000..1b2478c Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/easyprogrammer_16x16.ico differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/easyprogrammer_32x32.ico b/src/at/htlkaindorf/sx/EasyProgrammer/icons/easyprogrammer_32x32.ico new file mode 100644 index 0000000..697aaea Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/easyprogrammer_32x32.ico differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/icons/easyprogrammer_64x64.ico b/src/at/htlkaindorf/sx/EasyProgrammer/icons/easyprogrammer_64x64.ico new file mode 100644 index 0000000..47863fe Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/icons/easyprogrammer_64x64.ico differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/libs/EasyProgrammer/win32/EasyProgrammer32.dll b/src/at/htlkaindorf/sx/EasyProgrammer/libs/EasyProgrammer/win32/EasyProgrammer32.dll new file mode 100644 index 0000000..b8f0061 Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/libs/EasyProgrammer/win32/EasyProgrammer32.dll differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/libs/EasyProgrammer/win32/version.txt b/src/at/htlkaindorf/sx/EasyProgrammer/libs/EasyProgrammer/win32/version.txt new file mode 100644 index 0000000..a4d477c --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/libs/EasyProgrammer/win32/version.txt @@ -0,0 +1 @@ +EasyProgrammer32.dll_1.00_x86_Dec 30 2010_16:12:51_SX \ No newline at end of file diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/libs/EasyProgrammer/win64/EasyProgrammer64.dll b/src/at/htlkaindorf/sx/EasyProgrammer/libs/EasyProgrammer/win64/EasyProgrammer64.dll new file mode 100644 index 0000000..eaa8b72 Binary files /dev/null and b/src/at/htlkaindorf/sx/EasyProgrammer/libs/EasyProgrammer/win64/EasyProgrammer64.dll differ diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/libs/EasyProgrammer/win64/version.txt b/src/at/htlkaindorf/sx/EasyProgrammer/libs/EasyProgrammer/win64/version.txt new file mode 100644 index 0000000..fb892c1 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/libs/EasyProgrammer/win64/version.txt @@ -0,0 +1 @@ +EasyProgrammer64.dll_1.00_amd64_Dec 30 2010_17:32:40_SX \ No newline at end of file diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/libs/EasyProgrammerLib.java b/src/at/htlkaindorf/sx/EasyProgrammer/libs/EasyProgrammerLib.java new file mode 100644 index 0000000..00153ca --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/libs/EasyProgrammerLib.java @@ -0,0 +1,412 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.htlkaindorf.sx.EasyProgrammer.libs; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.InputStreamReader; + +/** + * + * @author steiner + */ +public class EasyProgrammerLib +{ + private static final String libVersion = "1.00"; + private static final String libMinorSuffix = "0"; + private static String libNativeVersion; + + public static final int OS_LINUX = 0; + public static final int OS_WINDOWS = 1; + public static final int OS_SOLARIS = 2; + public static final int OS_MAC_OS_X = 3; + private static int osType = -1; + + public final static long OFN_PATHMUSTEXIST = 2048; + public final static long OFN_FILEMUSTEXIST = 4096; + public final static long OFN_HIDEREADONLY = 4; + + private static String libPlatform; + private static String libDate; + private static String libTime; + private static String libAutor; + private static Throwable staticException; + private static File libFile; + + private static File selectedFile; + + private static native String getLibVersionString (); + private static native void enableFunctionTest (); + private static native void disableFunctionTest (); + private static native void openFileName (String filename) throws Exception; + private static native void zeroGlobalVariable (String variable) throws Exception; + private static native void setGlobalString (String variable, String field, byte [] value) throws Exception; + private static native void setGlobalLONG (String variable, String field, long value) throws Exception; + private static native void setGlobalWORD (String variable, String field, long value) throws Exception; + private static native void setGlobalDWORD (String variable, String field, long value) throws Exception; + private static native void setGlobalLPARAM (String variable, String field, long value) throws Exception; + private static native String getGlobalString (String variable, String field) throws Exception; + private static native long getGlobalLONG (String variable, String field) throws Exception; + private static native long getGlobalWORD (String variable, String field) throws Exception; + private static native long getGlobalDWORD (String variable, String field) throws Exception; + private static native long getGlobalLPARAM (String variable, String field) throws Exception; + private static native void printStatus(); + + + static + { + String libFolderPath; + String libName; + + String osName = System.getProperty("os.name"); + String architecture = System.getProperty("os.arch"); + String userHome = System.getProperty("user.home"); + String fileSeparator = System.getProperty("file.separator"); + String tmpFolder = System.getProperty("java.io.tmpdir"); + String libRootFolder = new File(userHome).canWrite() ? userHome : tmpFolder; + String javaLibPath = System.getProperty("java.library.path"); + + if (osName.equals("Linux")) + { + osName = "linux"; + osType = OS_LINUX; + } + else if (osName.startsWith("Win")) + { + osName = "windows"; + osType = OS_WINDOWS; + }//since 0.9.0 -> + else if (osName.equals("SunOS")) + { + osName = "solaris"; + osType = OS_SOLARIS; + } + else if (osName.equals("Mac OS X") || osName.equals("Darwin")) + {//os.name "Darwin" since 2.6.0 + osName = "mac_os_x"; + osType = OS_MAC_OS_X; + }//<- since 0.9.0 + + if (architecture.equals("i386") || architecture.equals("i686")) + { + architecture = "x86"; + } + else if (architecture.equals("amd64") || architecture.equals("universal")) + {//os.arch "universal" since 2.6.0 + architecture = "x86_64"; + } + else if (architecture.equals("arm")) + {//since 2.1.0 + String floatStr = "sf"; + if (javaLibPath.toLowerCase().contains("gnueabihf") || javaLibPath.toLowerCase().contains("armhf")) + { + floatStr = "hf"; + } + else + { + try + { + Process readelfProcess = Runtime.getRuntime().exec("readelf -A /proc/self/exe"); + BufferedReader reader = new BufferedReader(new InputStreamReader(readelfProcess.getInputStream())); + String buffer = ""; + while ((buffer = reader.readLine()) != null && !buffer.isEmpty()) + { + if (buffer.toLowerCase().contains("Tag_ABI_VFP_args".toLowerCase())) + { + floatStr = "hf"; + break; + } + } + reader.close(); + } + catch (Exception ex) + { + //Do nothing + } + } + architecture = "arm" + floatStr; + } + + libFolderPath = libRootFolder + fileSeparator + ".easyprogrammer" + fileSeparator + osName; + libName = "EasyProgrammer-" + libVersion + "_" + architecture; + libName = System.mapLibraryName(libName); + + if (libName.endsWith(".dylib")) + { // MacOSX 10.8 fix + libName = libName.replace(".dylib", ".jnilib"); + } + + boolean loadLib = false; + + if (isLibFolderExist(libFolderPath)) + { + if (isLibFileExist(libFolderPath + fileSeparator + libName)) + { + loadLib = true; + } + else if (extractLib((libFolderPath + fileSeparator + libName), osName, libName)) + { + loadLib = true; + } + } + else if (new File(libFolderPath).mkdirs()) + { + if (extractLib((libFolderPath + fileSeparator + libName), osName, libName)) + { + loadLib = true; + } + } + + try + { + if (loadLib) + { + String libFileName = libFolderPath + fileSeparator + libName; + libFile = new File(libFileName); + System.load(libFileName); + String versionBase = libVersion; + String versionNative = getLibVersionString(); + + if (versionNative != null && !versionNative.isEmpty()) + { + String [] info = versionNative.split("_"); + if (info.length>=1) libName = info[0]; + if (info.length>=2) libNativeVersion = info[1]; + if (info.length>=3) libPlatform = info[2]; + if (info.length>=4) libDate = info[3]; + if (info.length>=5) libTime = info[4]; + if (info.length>=6) libAutor = info[5]; + } + + if (!versionBase.equals(libNativeVersion)) + { + System.err.println("Warning! EasyProgrammer Java and Native versions mismatch (Java: " + versionBase + ", Native: " + versionNative + ")"); + } + } + } + catch (Throwable th) + { + libFile = null; + } + } + + + private static boolean isLibFolderExist (String libFolderPath) + { + boolean returnValue = false; + File folder = new File(libFolderPath); + if (folder.exists() && folder.isDirectory()) + { + returnValue = true; + } + return returnValue; + } + + + private static boolean isLibFileExist (String libFilePath) + { + boolean returnValue = false; + File folder = new File(libFilePath); + if (folder.exists() && folder.isFile()) + { + returnValue = true; + } + return returnValue; + } + + + private static boolean extractLib (String libFilePath, String osName, String libName) + { + boolean returnValue = false; + libFile = new File(libFilePath); + InputStream input; + FileOutputStream output = null; + input = EasyProgrammerLib.class.getResourceAsStream("/libs/" + osName + "/" + libName); + if (input != null) + { + int read; + byte[] buffer = new byte[4096]; + try + { + output = new FileOutputStream(libFilePath); + while ((read = input.read(buffer)) != -1) + { + output.write(buffer, 0, read); + } + output.close(); + input.close(); + returnValue = true; + } + catch (Exception ex) + { + try + { + output.close(); + if (libFile.exists()) + libFile.delete(); + } + catch (Exception ex_out) { } + finally + { + libFile = null; + } + + try + { + input.close(); + } + catch (Exception ex_in) { } + } + } + return returnValue; + } + + + public static String getLibraryVersion() + { + return libVersion + "." + libMinorSuffix; + } + + public static String getLibraryBaseVersion() + { + return libVersion; + } + + public static String getLibraryMinorSuffix() + { + return libMinorSuffix; + } + + public static String getNativeLibraryVersion() + { + return libNativeVersion; + } + + + public static File getLibFile () + { + return libFile; + } + + + public static boolean isLibAvailable() + { + return libFile!=null && libFile.canRead(); + } + + + + public static String getLibAutor() + { + return libAutor; + } + + + public static String getLibDate() + { + return libDate; + } + + + public static String getLibTime() + { + return libTime; + } + + + public static String getLibPlatform() + { + return libPlatform; + } + + + public static void showOpenHexFileDialog (String path, String fileName) + { + String name = null; + int indexPath = -1; + int indexExtension = -1; + + try + { + zeroGlobalVariable("openFileName"); + if (selectedFile != null) + { + System.out.println("Name = " + selectedFile.getPath() ); + //setGlobalString("openFileName", "lpstrFile", selectedFile.getPath().getBytes()); + } + + setGlobalString("openFileName", "lpstrFilter", "Alle Dateien\0*.*\0Programmdatei (*.hex)\0*.hex\0\0".getBytes()); + setGlobalDWORD("openFileName", "nFilterIndex", 2); + setGlobalString("openFileName", "lpstrTitle", "Programmdatei (Hex-File) fuer ATmega328P auswaehlen...".getBytes()); + setGlobalDWORD("openFileName", "Flags", OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY); + if (selectedFile != null) + openFileName(selectedFile.getPath()); + else + openFileName(null); + + name = getGlobalString("openFileName", "lpstrFile"); + indexPath = (int) getGlobalWORD("openFileName", "nFileOffset"); + indexExtension = (int) getGlobalWORD("openFileName", "nFileExtension"); + } + catch (Exception ex) + { + throw new RuntimeException(ex.getMessage()); + } + + if (name == null || name.length() == 0) + selectedFile = null; + else + selectedFile = new File(name); + } + + public static File getSelectedFile () + { + return selectedFile; + } + + public static void main(String[] args) + { + System.out.println("Lib available: " + isLibAvailable()); + if (isLibAvailable()) + { + System.out.println("Library: " + getLibVersionString()); + System.out.println("Platform: " + getLibPlatform()); + System.out.println("Date: " + getLibDate()); + System.out.println("Time: " + getLibTime()); + System.out.println("Autor: " + getLibAutor()); + } + else + { + System.out.println("Error: " + staticException); + } + + //EasyProgrammerLib ep = new EasyProgrammerLib(); + //EasyProgrammerLib.enableFunctionTest(); + //EasyProgrammerLib.disableFunctionTest(); + //EasyProgrammerLib.printStatus(); + int err = 0; + try + { + zeroGlobalVariable("openFileName"); + setGlobalString("openFileName", "lpstrFilter", "Alle Dateien\0*.*\0Programmdatei (*.hex)\0*.hex\0\0".getBytes()); + setGlobalDWORD("openFileName", "nFilterIndex", 2); + setGlobalString("openFileName", "lpstrTitle", "Programmdatei öffnen".getBytes()); + setGlobalDWORD("openFileName", "Flags", OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY); + openFileName(null); + System.out.println("FileName = " + getGlobalString("openFileName", "lpstrFile")); + System.out.println("nFilterIndex = " + getGlobalDWORD("openFileName", "nFilterIndex")); + System.out.println("nFileOffset = " + getGlobalWORD("openFileName", "nFileOffset")); + System.out.println("nFileExtension = " + getGlobalWORD("openFileName", "nFileExtension")); + + } + catch (Exception ex) + { + ex.printStackTrace(); + } + //EasyProgrammerLib.printStatus(); + } +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/libs/bootloader/bootloader_Atmega328P.hex b/src/at/htlkaindorf/sx/EasyProgrammer/libs/bootloader/bootloader_Atmega328P.hex new file mode 100644 index 0000000..68297cf --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/libs/bootloader/bootloader_Atmega328P.hex @@ -0,0 +1,129 @@ +:107800000C94343C0C94513C0C94513C0C94513CE1 +:107810000C94513C0C94513C0C94513C0C94513CB4 +:107820000C94513C0C94513C0C94513C0C94513CA4 +:107830000C94513C0C94513C0C94513C0C94513C94 +:107840000C94513C0C94513C0C94513C0C94513C84 +:107850000C94513C0C94513C0C94513C0C94513C74 +:107860000C94513C0C94513C11241FBECFEFD8E036 +:10787000DEBFCDBF11E0A0E0B1E0E0E9FFE702C06C +:1078800005900D92A631B107D9F711E0A6E1B1E05C +:1078900001C01D92A931B107E1F70E94793F0C9414 +:1078A000C63F0C94003C14BE88E10FB6F894809358 +:1078B0006000109260000FBE92E09093C000809331 +:1078C000C1001092C50089E18093C40008958091A1 +:1078D000C000881F8827881F08958091C00087FFF7 +:1078E000FCCF8091C60008958093C6008091C000AF +:1078F00085FFFCCF0895FC0107C08093C6008091EE +:10790000C00085FFFCCF319680818823B1F70895B0 +:107910009C01F9012F5F3F4F8491882339F08093B8 +:10792000C6008091C00085FFFCCFF3CF08958DE0A5 +:107930008093C6008091C00085FFFCCF8AE08093D1 +:10794000C6008091C00085FFFCCF0895982F80531A +:107950008A3068F08151863010F4865F0895892F4F +:107960008156863010F080E00895892F875508955C +:107970000F931F93062F0E94A63C182F802F0E9462 +:10798000A63C1295107F810F1F910F910895FC0165 +:10799000808161810E94B83C809318010895FC01A8 +:1079A000808161810E94B83C282F90E00497803646 +:1079B000910548F41092C1001092C5002093C400B4 +:1079C00088E18093C1000895982F92959F708F70E1 +:1079D0009A3018F0292F295C02C0292F205D8A30A7 +:1079E00018F0982F995C02C0982F905D2093C600E4 +:1079F0008091C00085FFFCCF9093C6008091C000AD +:107A000085FFFCCF0895EF92FF921F93CF93DF93F2 +:107A1000EC0189816A810E94B83C182FE82EFF246E +:107A20000E94973C812F0E94E43C8AE38093C60029 +:107A30008091C00085FFFCCFF694FE2CEE24F794D5 +:107A4000E79410E0F701E10FF11D949188818236EF +:107A500039F49093C6008091C00085FFFCCF03C02D +:107A6000892F0E94E43C1F5F103861F70E94973C09 +:107A7000DF91CF911F91FF90EF9008952F923F9249 +:107A80004F925F926F927F928F929F92AF92BF922E +:107A9000CF92DF92EF92FF920F931F93DF93CF93DA +:107AA000CDB7DEB7CD58D1400FB6F894DEBF0FBECC +:107AB000CDBF88EE93E02CE231E0F9013197F1F788 +:107AC0000197D9F70E94973C80E091E00E947B3CAF +:107AD000CC24DD24F2E88F2E912C8C0E9D1E1E01ED +:107AE0000894211C311CBE016F577F4FC457DE4FD5 +:107AF00079836883CC58D1408091C00087FFFCCF48 +:107B00008091C600F401EC0DFD1D80830894C11C1A +:107B1000D11C73E0C716D10461F4F401808186346E +:107B200059F7F8E5F093C6008091C00085FFFCCFBF +:107B300020C063E8C616D104F9F67DE37093C60051 +:107B40008091C00085FFFCCFF40181818093C60045 +:107B50008091C00085FFFCCFF40182818093C60034 +:107B60008091C00085FFFCCFCB5FDE4F1882C550EF +:107B7000D140F4018081863471F488EE93E0ECE228 +:107B8000F1E03197F1F70197D1F7E0911601F0910B +:107B900017010995F8C0803509F0F5C0F401F181AD +:107BA000C657DE4FF883CA58D140F401A280B09086 +:107BB0001801EE24FF2403E010E090E03FC0F1E064 +:107BC000FB1538F463E06B15F8F48601EE24FF240E +:107BD00027C0D401A00FB11F0F5F1F4FF401E00FAA +:107BE000F11F8C916081C557DE4F9883CB58D140EF +:107BF0000E94B83CF101EE0DFF1D8083C557DE4F9A +:107C00009881CB58D14008C0F101EE0DFF1DD40181 +:107C1000A00FB11F8C91808370E8E716F1042CF45B +:107C2000F101EE0DFF1D8081980F0894E11CF11CFD +:107C300081E8E816F10434F40F5F1F4F0C151D05A1 +:107C40000CF4BDCFBB2019F0E2E0BE1641F4F0E821 +:107C5000EF16F104F1F01E2D0027016076C061E0FF +:107C6000B61619F073E0B716A1F481E8E816F1042E +:107C700021F01E2D0027026068C0CF57DF4F88819A +:107C8000C158D040981729F0792E662483010360EB +:107C90005CC0F999FECFC657DE4F8881CA58D140E3 +:107CA0006A2D0E94B83C482F50E05695542F442727 +:107CB0005795479563E0FA0160935700E89507B63A +:107CC00000FCFDCFD1019A0111965C9011974424DC +:107CD0008C91F201E80FF11DCF0161E0F9010C0177 +:107CE00060935700E895112412962E5F3F4FC457BA +:107CF000DE4F88819981CC58D140A817B90721F768 +:107D000065E0FA0160935700E89507B600FCFDCFE7 +:107D100071E170935700E89520E030E090E0F901C0 +:107D2000E40FF51FE4919E0FD101A20FB31F8C91B8 +:107D3000E81721F0122F0027046007C02F5F3F4F84 +:107D40002038310561F700E010E080E28093C60042 +:107D50008091C00085FFFCCF892F0E94E43C90E217 +:107D60009093C6008091C00085FFFCCF802F0E94B9 +:107D7000E43CE0E2E093C6008091C00085FFFCCFC8 +:107D8000812F0E94E43C0E94973C80E091E00E9499 +:107D90007B3CCC24DD24B0CEFC018081813391F486 +:107DA0008181823379F48281883361F48091180172 +:107DB000843018F40E943E3D05C0E0911401F0911A +:107DC00015010995E0911601F091170109950895A3 +:107DD000EF92FF920F931F93DF93CF93CDB7DEB750 +:107DE00060970FB6F894DEBF0FBECDBF982F20E08E +:107DF000AE014F5F5F4F992371F02F3060F4909385 +:107E0000C6008091C00085FFFCCFFA01E20FF11D92 +:107E100090832F5F90E08091C00087FF06C0809123 +:107E2000C00087FFFCCF9091C6009A3011F09D30C2 +:107E300011F7CE010196FC01E20FF11D1082022F15 +:107E40000F5F10E07C0140C0F701E10FF11D808160 +:107E50008034C9F51F5F812F90E0F701E80FF91F0B +:107E6000E081E73631F1E83628F4E436E1F0E63631 +:107E700051F513C0E23711F1E33719F0ED3619F57A +:107E800006C001968E0D9F1D0E94CF3C1CC001961E +:107E90008E0D9F1D0E94C73C16C001968E0D9F1D22 +:107EA0000E94CC3E10C001968E0D9F1D0E94033D86 +:107EB0000AC0E0911601F091170104C0E09114018D +:107EC000F091150109951F5F101708F4BDCFE091DF +:107ED0001401F0911501099560960FB6F894DEBF74 +:107EE0000FBECDBFCF91DF911F910F91FF90EF900B +:107EF0000895EF92FF921F93CF93DF930E94533C1C +:107F0000109218010E94973C84EC9FE70E94883CE5 +:107F10000E94973C83E091E00E947B3C0E94973C4A +:107F2000C0E0D0E010E0ACE2EA2EA1E0FA2E82E15F +:107F300091E00E947B3C219684EF91E0F70131971C +:107F4000F1F70197D9F78091C00087FF06C08091B3 +:107F5000C00087FFFCCF1091C600C832D10511F0D8 +:107F6000103429F70E94973CA8971CF4812F0E9497 +:107F7000E83EE0911601F0911701099580E090E04C +:107F8000DF91CF911F91FF90EF900895F894FFCF6C +:107F9000663E00202E2E2E207072657373202740BF +:067FA00027002E0000780E +:107FC400426F6F746C6F6164657220566572736979 +:107FD4006F6E20322E3035205B41746D65676133DE +:107FE4003238502C323031312D30382D32372C5339 +:0C7FF400585D2000E83EC47F02003412FB +:040000030000780081 +:00000001FF diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/libs/bootloader/bootloader_Atmega8L.hex b/src/at/htlkaindorf/sx/EasyProgrammer/libs/bootloader/bootloader_Atmega8L.hex new file mode 100644 index 0000000..ce5d378 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/libs/bootloader/bootloader_Atmega8L.hex @@ -0,0 +1,112 @@ +:1018000012C02CC02BC02AC029C028C027C026C0A7 +:1018100025C024C023C022C021C020C01FC01EC0BC +:101820001DC01CC01BC011241FBECFE5D4E0DEBF0D +:10183000CDBF10E0A0E6B0E0ECE7FEE102C005900D +:101840000D92A637B107D9F710E0A6E7B0E001C0C6 +:101850001D92A937B107E1F7D0D20EC3D1CF14BE84 +:1018600088E10FB6F89481BD11BC0FBE92E09BB920 +:101870008AB910BC89E189B908958BB1881F88277E +:10188000881F08955F9BFECF8CB108958CB95D9B36 +:10189000FECF0895FC0104C08CB95D9BFECF31964C +:1018A00080818823C9F70895FC01019624912223A1 +:1018B00021F02CB95D9BFECFF7CF08958DE08CB958 +:1018C0005D9BFECF8AE08CB95D9BFECF0895982F7B +:1018D00080538A3068F08151863010F4865F089515 +:1018E000892F8156863010F080E00895892F875522 +:1018F00008950F931F93062FEADF182F802FE7DF3D +:101900001295107F810F1F910F910895FC01808126 +:101910006181EFDF809378000895FC01808161810F +:10192000E8DF282F90E004978036910528F41AB854 +:1019300010BC29B988E18AB90895982F92959F70B3 +:101940008F709A3010F0995C01C0905D8A3010F071 +:10195000895C01C0805D9CB95D9BFECF8CB95D9BAD +:10196000FECF0895FF920F931F93CF93DF93FC0157 +:1019700080816181BEDF182FA1DF812FDEDF8AE346 +:101980008CB95D9BFECF012F10E096E0000F111F78 +:101990009A95E1F7C0E0D0E080E2F82EFE01E00F7A +:1019A000F11FE4918E2FC9DFFCB85D9BFECFCE0105 +:1019B00087709070892B19F4FCB85D9BFECF21963F +:1019C000C034D10559F77ADFDF91CF911F910F9184 +:1019D000FF9008952F923F924F925F926F927F9265 +:1019E0008F929F92AF92BF92CF92DF92EF92FF922F +:1019F0000F931F93DF93CF93CDB7DEB7CD5CD0406D +:101A00000FB6F894DEBF0FBECDBF88EE93E02CE298 +:101A100031E0F9013197F1F70197D9F74FDF80E60F +:101A200090E038DF20E030E0F2E48F2E912C8C0E35 +:101A30009D1E1E010894211C311CBE016F5B7F4F4F +:101A4000C453DF4F79836883CC5CD04001C09601DA +:101A50005F9BFECF8CB1F401E20FF31F808369011D +:101A60000894C11CD11C71E0C716D10429F4F401FB +:101A700080818A3061F76901F3E0CF16D10449F41F +:101A8000F4018081863419F7F8E5FCB95D9BFECF3F +:101A900017C063E4C616D104D1F67DE37CB95D9B23 +:101AA000FECFF40181818CB95D9BFECFF401828170 +:101AB0008CB95D9BFECFCB57DF4F1882C558D04005 +:101AC000F4018081863471F488EE93E0ECE2F1E079 +:101AD0003197F1F70197D1F7E0917600F091770017 +:101AE0000995E8C0803509F0E5C0F401F181C653DD +:101AF000DF4FF883CA5CD040F401A280B090780038 +:101B0000EE24FF2403E010E090E03EC0F1E0FB157E +:101B100038F463E06B15F0F48601EE24FF2426C050 +:101B2000D401A00FB11F0F5F1F4FF401E00FF11F91 +:101B30008C916081C553DF4F9883CB5CD040D9DE58 +:101B4000F101EE0DFF1D8083C553DF4F9881CB5C03 +:101B5000D04008C0F101EE0DFF1DD401A00FB11F50 +:101B60008C91808370E4E716F1042CF4F101EE0D02 +:101B7000FF1D8081980F0894E11CF11C81E4E81698 +:101B8000F10434F40F5F1F4F0C151D050CF4BECF8C +:101B9000BB2019F0E2E0BE1641F4F0E4EF16F104C8 +:101BA000E1F01E2D0027016073C061E0B61619F048 +:101BB00073E0B71691F481E4E816F10421F01E2DCC +:101BC0000027026065C022968FAD2297981729F0F2 +:101BD000792E6624830103605BC0E199FECFC65372 +:101BE000DF4F8881CA5CD0406A2D83DE482F50E0E9 +:101BF00066E0440F551F6A95E1F763E0FA016093D0 +:101C00005700E89507B600FCFDCFD1019A01119667 +:101C10005C90119744248C91F201E80FF11DCF01E3 +:101C200061E0F9010C0160935700E89511241296C8 +:101C30002E5F3F4FC453DF4F88819981CC5CD040E9 +:101C4000A817B90721F765E0FA0160935700E895F6 +:101C500007B600FCFDCF71E170935700E89520E0D6 +:101C600030E090E0F901E40FF51FE4919E0FD101FF +:101C7000A20FB31F8C91E81721F0122F00270460E8 +:101C800007C02F5F3F4F2034310561F700E010E0BF +:101C900080E28CB95D9BFECF892F4FDE90E29CB92C +:101CA0005D9BFECF802F49DEE0E2ECB95D9BFECF6D +:101CB000812F43DE03DE80E690E0ECDDCC24DD24E2 +:101CC000C6CEFC018081863371F48181843359F45E +:101CD00080917800843010F47DDE05C0E0917400BE +:101CE000F09175000995E0917600F09177000995E3 +:101CF0000895EF92FF920F931F93DF93CF93CDB789 +:101D0000DEB760970FB6F894DEBF0FBECDBF20E000 +:101D1000AE014F5F5F4F882359F02F3048F48CB9E4 +:101D20005D9BFECFFA01E20FF11D80832F5F80E003 +:101D30005F9B03C05F9BFECF8CB18A3011F08D306A +:101D400051F7CE010196FC01E20FF11D1082022F26 +:101D50000F5F10E07C013CC0F701E10FF11D8081B5 +:101D60008034A9F51F5F812F90E0F701E80FF91F7C +:101D7000E081E73611F1E83628F4E436C9F0E636BA +:101D800031F511C0E237F1F0E33719F0ED36F9F42F +:101D900005C001968E0D9F1DC0DD19C001968E0DE8 +:101DA0009F1DB4DD14C001968E0D9F1D8ADF0FC0EC +:101DB00001968E0D9F1DD6DD0AC0E0917600F09150 +:101DC000770004C0E0917400F091750009951F5FE1 +:101DD000101710F273DDE0917400F0917500099511 +:101DE00060960FB6F894DEBF0FBECDBFCF91DF91E6 +:101DF0001F910F91FF90EF900895EF92FF921F9324 +:101E0000CF93DF932CDD1092780058DD84EC9FE1B6 +:101E10004BDD54DD83E690E03DDD50DDC0E0D0E0F9 +:101E200010E0ACE2EA2EA1E0FA2E82E790E032DD8B +:101E3000219684EF91E0F7013197F1F70197D9F7F7 +:101E40005F9B03C05F9BFECF1CB1C832D10511F070 +:101E5000103459F733DDA89714F4812F4ADFE0914D +:101E60007600F0917700099580E090E0DF91CF91C6 +:0C1E70001F91FF90EF900895F894FFCFB1 +:101E7C00663E00202E2E2E20707265737320274034 +:061E8C0027002E000018E3 +:101FC400426F6F746C6F61646572205665727369D9 +:101FD4006F6E20322E3035205B41746D6567613839 +:101FE4004C2C323031312D30382D32382C53585D51 +:0C1FF40020000000790EC41F020034120F +:0400000300001800E1 +:00000001FF diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/libs/bootloader/bootloader_atmega16.hex b/src/at/htlkaindorf/sx/EasyProgrammer/libs/bootloader/bootloader_atmega16.hex new file mode 100644 index 0000000..1d3a7c7 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/libs/bootloader/bootloader_atmega16.hex @@ -0,0 +1,114 @@ +:103800000C942A1C0C94471C0C94471C0C94471CC9 +:103810000C94471C0C94471C0C94471C0C94471C9C +:103820000C94471C0C94471C0C94471C0C94471C8C +:103830000C94471C0C94471C0C94471C0C94471C7C +:103840000C94471C0C94471C0C94471C0C94471C6C +:103850000C94471C11241FBECFE5D4E0DEBFCDBFC2 +:1038600010E0A0E6B0E0E0EAFEE302C005900D92B1 +:10387000A637B107D9F710E0A6E7B0E001C01D9266 +:10388000A937B107E1F70E94061F0C944E1F0C9454 +:10389000001C14BE88E10FB6F89481BD11BC0FBEA8 +:1038A00092E09BB98AB910BC89E189B9089508955D +:1038B0008BB1881F8827881F08955F9BFECF8CB12E +:1038C00008958CB95D9BFECF0895FC0104C08CB9AE +:1038D0005D9BFECF319680818823C9F70895FC0156 +:1038E00001962491222321F02CB95D9BFECFF7CFC6 +:1038F00008958DE08CB95D9BFECF8AE08CB95D9B0D +:10390000FECF0895982F80538A3068F08151863019 +:1039100010F4865F0895892F8156863010F080E07C +:103920000895892F875508950F931F93062F0E949E +:10393000821C182F802F0E94821C1295107F810FED +:103940001F910F910895FC01808161810E94941C58 +:10395000809378000895982F92959F708F709A3079 +:1039600010F0995C01C0905D8A3010F0895C01C054 +:10397000805D9CB95D9BFECF8CB95D9BFECF0895A9 +:10398000EF92FF921F93CF93DF93EC0189816A81BD +:103990000E94941C182FE82EFF240E94791C812F6E +:1039A0000E94AB1C8AE38CB95D9BFECFF694FE2C83 +:1039B000EE24F794E79410E0F701E10FF11D9491E4 +:1039C0008881823621F49CB95D9BFECF03C0892F8C +:1039D0000E94AB1C1F5F103879F70E94791CDF91A1 +:1039E000CF911F91FF90EF9008952F923F924F92A9 +:1039F0005F926F927F928F929F92AF92BF92CF927F +:103A0000DF92EF92FF920F931F93DF93CF93CDB787 +:103A1000DEB7CD58D1400FB6F894DEBF0FBECDBF94 +:103A200088EE93E02CE231E0F9013197F1F701974C +:103A3000D9F70E94791C80E690E00E94651CCC2496 +:103A4000DD24F2E88F2E912C8C0E9D1E1E01089411 +:103A5000211C311CBE016F577F4FC457DE4F798345 +:103A60006883CC58D1405F9BFECF8CB1F401EC0D44 +:103A7000FD1D80830894C11CD11C73E0C716D104BE +:103A800049F4F4018081863471F7F8E5FCB95D9B57 +:103A9000FECF17C063E8C616D10429F77DE37CB9D1 +:103AA0005D9BFECFF40181818CB95D9BFECFF4015B +:103AB00082818CB95D9BFECFCB5FDE4F1882C550F3 +:103AC000D140F4018081863471F488EE93E0ECE219 +:103AD000F1E03197F1F70197D1F7E0917600F0919D +:103AE00077000995EFC0803509F0ECC0F401F18151 +:103AF000C657DE4FF883CA58D140F401A280B09077 +:103B00007800EE24FF2403E010E090E03FC0F1E0F5 +:103B1000FB1538F463E06B15F8F48601EE24FF24FE +:103B200027C0D401A00FB11F0F5F1F4FF401E00F9A +:103B3000F11F8C916081C557DE4F9883CB58D140DF +:103B40000E94941CF101EE0DFF1D8083C557DE4FCE +:103B50009881CB58D14008C0F101EE0DFF1DD40172 +:103B6000A00FB11F8C91808370E8E716F1042CF44C +:103B7000F101EE0DFF1D8081980F0894E11CF11CEE +:103B800081E8E816F10434F40F5F1F4F0C151D0592 +:103B90000CF4BDCFBB2019F0E2E0BE1641F4F0E812 +:103BA000EF16F104F1F01E2D0027016076C061E0F0 +:103BB000B61619F073E0B716A1F481E8E816F1041F +:103BC00021F01E2D0027026068C0CF57DF4F88818B +:103BD000C158D040981729F0792E662483010360DC +:103BE0005CC0E199FECFC657DE4F8881CA58D140EC +:103BF0006A2D0E94941C482F50E05695542F44275C +:103C00005795479563E0FA0160935700E89507B62A +:103C100000FCFDCFD1019A0111965C9011974424CC +:103C20008C91F201E80FF11DCF0161E0F9010C0167 +:103C300060935700E895112412962E5F3F4FC457AA +:103C4000DE4F88819981CC58D140A817B90721F758 +:103C500065E0FA0160935700E89507B600FCFDCFD8 +:103C600071E170935700E89520E030E090E0F901B1 +:103C7000E40FF51FE4919E0FD101A20FB31F8C91A9 +:103C8000E81721F0122F0027046007C02F5F3F4F75 +:103C90002038310561F700E010E080E28CB95D9BCF +:103CA000FECF892F0E94AB1C90E29CB95D9BFECF9A +:103CB000802F0E94AB1CE0E2ECB95D9BFECF812F10 +:103CC0000E94AB1C0E94791C80E690E00E94651C5B +:103CD000CC24DD24C8CEFC018081813391F4818124 +:103CE000823379F48281883361F480917800843062 +:103CF00018F40E94F51C05C0E0917400F091750065 +:103D00000995E0917600F091770009950895EF927A +:103D1000FF920F931F93DF93CF93CDB7DEB76097DA +:103D20000FB6F894DEBF0FBECDBF20E0AE014F5FEF +:103D30005F4F882359F02F3048F48CB95D9BFECF3C +:103D4000FA01E20FF11D80832F5F80E05F9B03C0CB +:103D50005F9BFECF8CB18A3011F08D3051F7CE01D0 +:103D60000196FC01E20FF11D1082022F0F5F10E09F +:103D70007C0138C0F701E10FF11D8081803489F5A5 +:103D80001F5F812F90E0F701E80FF91FE081E73610 +:103D9000F1F0E83628F4E436A1F0E63611F50BC070 +:103DA000ED3619F0E237E9F417C001968E0D9F1D2C +:103DB0000E94A31C16C001968E0D9F1D0E946B1EB3 +:103DC00010C001968E0D9F1D0E94C01C0AC0E0917C +:103DD0007600F091770004C0E0917400F0917500D6 +:103DE00009951F5F101730F2E0917400F091750093 +:103DF000099560960FB6F894DEBF0FBECDBFCF9188 +:103E0000DF911F910F91FF90EF900895EF92FF9235 +:103E10001F93CF93DF930E94491C109278000E9459 +:103E2000791C84EC9FE30E946F1C0E94791C83E63E +:103E300090E00E94651C0E94791CC0E0D0E010E078 +:103E4000ACE2EA2EA1E0FA2E82E790E00E94651C27 +:103E5000219684EF91E0F7013197F1F70197D9F7B7 +:103E60005F9B03C05F9BFECF1CB1C832D10511F030 +:103E7000103451F70E94791CA8971CF4812F0E94DE +:103E8000871EE0917600F0917700099580E090E040 +:103E9000DF91CF911F91FF90EF900895F894FFCF9D +:103EA000663E00202E2E2E207072657373202740F0 +:063EB00027002E0000387F +:103FC400426F6F746C6F61646572205665727369B9 +:103FD4006F6E20322E3035205B41746D6567613120 +:103FE400362C323031312D30382D32372C53585D48 +:0C3FF40020202000871EC43F0200341271 +:0400000300003800C1 +:00000001FF diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/logging/ExtendedLogRecord.java b/src/at/htlkaindorf/sx/EasyProgrammer/logging/ExtendedLogRecord.java new file mode 100644 index 0000000..a6f0500 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/logging/ExtendedLogRecord.java @@ -0,0 +1,101 @@ +package at.htlkaindorf.sx.EasyProgrammer.logging; + +import java.util.logging.Level; +import java.util.logging.LogRecord; + + +/** + * + * @author Manfred Steiner (sx@htl-kaindorf.ac.at) + */ +public abstract class ExtendedLogRecord extends LogRecord +{ + protected final StackTraceElement location; + protected final StackTraceElement [] stackTrace; + + public ExtendedLogRecord (Level level, String msg, int locationStackTraceIndex) + { + this(level, msg, locationStackTraceIndex+1, 0); + } + + + public ExtendedLogRecord (Level level, String msg, int locationStackTraceIndex, int locationStackTraceDepth) + { + super(level, msg); + Throwable th = new Throwable(); + +// for (StackTraceElement e : th.getStackTrace()) +// System.out.println(String.format("at %s.%s(%s:%d)", +// e.getClassName(), e.getMethodName(), +// e.getFileName(), e.getLineNumber())); + + location = th.getStackTrace()[locationStackTraceIndex]; + if (locationStackTraceDepth !=0) + { + stackTrace = new StackTraceElement[locationStackTraceDepth>0 ? Math.min(locationStackTraceDepth, th.getStackTrace().length-locationStackTraceIndex-1) : th.getStackTrace().length-locationStackTraceIndex-1]; + for (int i=0; i<stackTrace.length; i++) + stackTrace[i] = th.getStackTrace()[locationStackTraceIndex+i+1]; + } + else + stackTrace = null; + } + + + public ExtendedLogRecord (Level level, String msg, Throwable th, int locationStackTraceIndex) + { + this(level, msg, th, locationStackTraceIndex+1, 0); + } + + + public ExtendedLogRecord (Level level, String msg, Throwable th, int locationStackTraceIndex, int locationStackTraceDepth) + { + super(level, msg); + setThrown(th); + location = th.getStackTrace()[locationStackTraceIndex]; + if (locationStackTraceDepth != 0) + { + stackTrace = new StackTraceElement[locationStackTraceDepth>0 ? locationStackTraceDepth : th.getStackTrace().length-locationStackTraceIndex-1]; + for (int i=0; i<stackTrace.length; i++) + stackTrace[i] = th.getStackTrace()[locationStackTraceIndex+i+1]; + } + else + stackTrace = null; + } + + public StackTraceElement getLocation () + { + return location; + } + + public StackTraceElement getStackTraceElement (int index) + { + return index>=0 && index<stackTrace.length ? stackTrace[index] : null; + } + + public StackTraceElement [] getStackTraceElements () + { + return stackTrace; + } + + + public String getLocationAsString () + { + return String.format("at %s.%s(%s:%d)", + location.getClassName(), location.getMethodName(), + location.getFileName(), location.getLineNumber()); + } + + + public String getStackTraceElementAsString (int index) + { + StackTraceElement e = stackTrace[index]; + return String.format("at %s.%s(%s:%d)", + e.getClassName(), e.getMethodName(), + e.getFileName(), e.getLineNumber()); + } + + public boolean isCallStackEmpty () + { + return stackTrace==null || stackTrace.length==0; + } +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogConfigRecord.java b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogConfigRecord.java new file mode 100644 index 0000000..d6c4dbc --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogConfigRecord.java @@ -0,0 +1,45 @@ +package at.htlkaindorf.sx.EasyProgrammer.logging; + +import java.util.logging.Level; + + +/** + * + * @author Manfred Steiner (sx@htl-kaindorf.ac.at) + */ +public class LogConfigRecord extends ExtendedLogRecord +{ + LogConfigRecord (String msg) + { + super(Level.CONFIG, msg, 2); + } + + LogConfigRecord (String msg, Throwable th) + { + super(Level.CONFIG, msg, 2); + setThrown(th); + } + + LogConfigRecord (String msg, int locationStackTraceIndex) + { + super(Level.CONFIG, msg, locationStackTraceIndex); + } + + LogConfigRecord (String msg, Throwable th, int locationStackTraceIndex) + { + super(Level.CONFIG, msg, locationStackTraceIndex); + setThrown(th); + } + + LogConfigRecord (String msg, int locationStackTraceIndex, int locationStackTraceDepth) + { + super(Level.CONFIG, msg, locationStackTraceIndex, locationStackTraceDepth); + } + + LogConfigRecord (String msg, Throwable th, int locationStackTraceIndex, int locationStackTraceDepth) + { + super(Level.CONFIG, msg, locationStackTraceIndex, locationStackTraceDepth); + setThrown(th); + } + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogDebugRecord.java b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogDebugRecord.java new file mode 100644 index 0000000..769f529 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogDebugRecord.java @@ -0,0 +1,44 @@ +package at.htlkaindorf.sx.EasyProgrammer.logging; + +import java.util.logging.Level; + + +/** + * + * @author Manfred Steiner (sx@htl-kaindorf.ac.at) + */ +public class LogDebugRecord extends ExtendedLogRecord +{ + LogDebugRecord (Level level, String msg) + { + super(level, msg, 2); + } + + LogDebugRecord (Level level, String msg, Throwable th) + { + super(level, msg, 2); + setThrown(th); + } + + LogDebugRecord (Level level, String msg, int locationStackTraceIndex) + { + super(level, msg, locationStackTraceIndex); + } + + LogDebugRecord (Level level, String msg, Throwable th, int locationStackTraceIndex) + { + super(level, msg, locationStackTraceIndex); + setThrown(th); + } + + LogDebugRecord (Level level, String msg, int locationStackTraceIndex, int locationStackTraceDepth) + { + super(level, msg, locationStackTraceIndex, locationStackTraceDepth); + } + + LogDebugRecord (Level level, String msg, Throwable th, int locationStackTraceIndex, int locationStackTraceDepth) + { + super(level, msg, locationStackTraceIndex, locationStackTraceDepth); + setThrown(th); + } +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogFineRecord.java b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogFineRecord.java new file mode 100644 index 0000000..4eca8a5 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogFineRecord.java @@ -0,0 +1,43 @@ +package at.htlkaindorf.sx.EasyProgrammer.logging; + +import java.util.logging.Level; + +/** + * + * @author Manfred Steiner (sx@htl-kaindorf.ac.at) + */ +public class LogFineRecord extends ExtendedLogRecord +{ + public LogFineRecord (String msg) + { + super(Level.FINE, msg, 2); + } + + public LogFineRecord (String msg, Throwable th) + { + super(Level.FINE, msg, 2); + setThrown(th); + } + + LogFineRecord (String msg, int locationStackTraceIndex) + { + super(Level.FINE, msg, locationStackTraceIndex); + } + + LogFineRecord (String msg, Throwable th, int locationStackTraceIndex) + { + super(Level.FINE, msg, locationStackTraceIndex); + setThrown(th); + } + + LogFineRecord (String msg, int locationStackTraceIndex, int locationStackTraceDepth) + { + super(Level.FINE, msg, locationStackTraceIndex, locationStackTraceDepth); + } + + LogFineRecord (String msg, Throwable th, int locationStackTraceIndex, int locationStackTraceDepth) + { + super(Level.FINE, msg, locationStackTraceIndex, locationStackTraceDepth); + setThrown(th); + } +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogFinerRecord.java b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogFinerRecord.java new file mode 100644 index 0000000..06ea2d4 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogFinerRecord.java @@ -0,0 +1,44 @@ +package at.htlkaindorf.sx.EasyProgrammer.logging; + +import java.util.logging.Level; + +/** + * + * @author Manfred Steiner (sx@htl-kaindorf.ac.at) + */ +public class LogFinerRecord extends ExtendedLogRecord +{ + public LogFinerRecord (String msg) + { + super(Level.FINER, msg, 2); + } + + public LogFinerRecord (String msg, Throwable th) + { + super(Level.FINER, msg, 2); + setThrown(th); + } + + LogFinerRecord (String msg, int locationStackTraceIndex) + { + super(Level.FINER, msg, locationStackTraceIndex); + } + + LogFinerRecord (String msg, Throwable th, int locationStackTraceIndex) + { + super(Level.FINER, msg, locationStackTraceIndex); + setThrown(th); + } + + LogFinerRecord (String msg, int locationStackTraceIndex, int locationStackTraceDepth) + { + super(Level.FINER, msg, locationStackTraceIndex, locationStackTraceDepth); + } + + LogFinerRecord (String msg, Throwable th, int locationStackTraceIndex, int locationStackTraceDepth) + { + super(Level.FINER, msg, locationStackTraceIndex, locationStackTraceDepth); + setThrown(th); + } + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogFinestRecord.java b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogFinestRecord.java new file mode 100644 index 0000000..11f1c4b --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogFinestRecord.java @@ -0,0 +1,45 @@ +package at.htlkaindorf.sx.EasyProgrammer.logging; + +import java.util.logging.Level; + + +/** + * + * @author Manfred Steiner (sx@htl-kaindorf.ac.at) + */ +public class LogFinestRecord extends ExtendedLogRecord +{ + public LogFinestRecord (String msg) + { + super(Level.FINEST, msg, 2); + } + + public LogFinestRecord (String msg, Throwable th) + { + super(Level.FINEST, msg, 2); + setThrown(th); + } + + LogFinestRecord (String msg, int locationStackTraceIndex) + { + super(Level.FINEST, msg, locationStackTraceIndex); + } + + LogFinestRecord (String msg, Throwable th, int locationStackTraceIndex) + { + super(Level.FINEST, msg, locationStackTraceIndex); + setThrown(th); + } + + LogFinestRecord (String msg, int locationStackTraceIndex, int locationStackTraceDepth) + { + super(Level.FINEST, msg, locationStackTraceIndex, locationStackTraceDepth); + } + + LogFinestRecord (String msg, Throwable th, int locationStackTraceIndex, int locationStackTraceDepth) + { + super(Level.FINEST, msg, locationStackTraceIndex, locationStackTraceDepth); + setThrown(th); + } + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogInfoRecord.java b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogInfoRecord.java new file mode 100644 index 0000000..43189bc --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogInfoRecord.java @@ -0,0 +1,44 @@ +package at.htlkaindorf.sx.EasyProgrammer.logging; + +import java.util.logging.Level; + + +/** + * + * @author Manfred Steiner (sx@htl-kaindorf.ac.at) + */ +public class LogInfoRecord extends ExtendedLogRecord +{ + LogInfoRecord (String msg) + { + super(Level.INFO, msg, 2); + } + + LogInfoRecord (String msg, Throwable th) + { + super(Level.INFO, msg, 2); + setThrown(th); + } + + LogInfoRecord (String msg, int locationStackTraceIndex) + { + super(Level.INFO, msg, locationStackTraceIndex); + } + + LogInfoRecord (String msg, Throwable th, int locationStackTraceIndex) + { + super(Level.INFO, msg, locationStackTraceIndex); + setThrown(th); + } + + LogInfoRecord (String msg, int locationStackTraceIndex, int locationStackTraceDepth) + { + super(Level.INFO, msg, locationStackTraceIndex, locationStackTraceDepth); + } + + LogInfoRecord (String msg, Throwable th, int locationStackTraceIndex, int locationStackTraceDepth) + { + super(Level.INFO, msg, locationStackTraceIndex, locationStackTraceDepth); + setThrown(th); + } +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogSevereRecord.java b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogSevereRecord.java new file mode 100644 index 0000000..7cf4c30 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogSevereRecord.java @@ -0,0 +1,43 @@ +package at.htlkaindorf.sx.EasyProgrammer.logging; + +import java.util.logging.Level; + +/** + * + * @author Manfred Steiner (sx@htl-kaindorf.ac.at) + */ +public class LogSevereRecord extends ExtendedLogRecord +{ + public LogSevereRecord (String msg) + { + super(Level.SEVERE, msg, 2); + } + + public LogSevereRecord (String msg, Throwable th) + { + super(Level.SEVERE, msg, 2); + setThrown(th); + } + + LogSevereRecord (String msg, int locationStackTraceIndex) + { + super(Level.SEVERE, msg, locationStackTraceIndex); + } + + LogSevereRecord (String msg, Throwable th, int locationStackTraceIndex) + { + super(Level.SEVERE, msg, locationStackTraceIndex); + setThrown(th); + } + + LogSevereRecord (String msg, int locationStackTraceIndex, int locationStackTraceDepth) + { + super(Level.SEVERE, msg, locationStackTraceIndex, locationStackTraceDepth); + } + + LogSevereRecord (String msg, Throwable th, int locationStackTraceIndex, int locationStackTraceDepth) + { + super(Level.SEVERE, msg, locationStackTraceIndex, locationStackTraceDepth); + setThrown(th); + } +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogStackHandler.java b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogStackHandler.java new file mode 100644 index 0000000..27de2ed --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogStackHandler.java @@ -0,0 +1,126 @@ +package at.htlkaindorf.sx.EasyProgrammer.logging; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Date; +import java.util.LinkedList; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + + +/** + * + * @author Manfred Steiner (sx@htl-kaindorf.ac.at) + */ +public class LogStackHandler extends Handler +{ + private static LogStackHandler instance; + + public synchronized static LogStackHandler getInstance() + { + if (instance == null) + instance = new LogStackHandler(); + return instance; + } + + // ****************************************************************************** + + private final LinkedList<LogRecord> recordList = new LinkedList<>(); + + private LogStackHandler () + { + } + + public synchronized void clear () + { + recordList.clear(); + } + + @Override + public synchronized void publish (LogRecord record) + { + if (record.getLevel().intValue() >= getLevel().intValue()) + recordList.add(record); + } + + @Override + public void close () throws SecurityException + { + recordList.clear(); + } + + @Override + public void flush () + { + } + + public synchronized String getLogRecordsAsString () + { + StringBuilder sb = new StringBuilder(); + + sb.append(at.htlkaindorf.sx.EasyProgrammer.gui.DialogAbout.version).append("\n\n"); + sb.append(String.format("Logging: %d records available:\n\n", recordList.size())); + String f = String.format("%%d: ", Math.max(1, Math.log(recordList.size()+1))); + for (int i=0; i<recordList.size(); i++) + { + LogRecord record = recordList.get(i); + int l1 = Level.INFO.intValue(); + int l2 = record.getLevel().intValue(); + sb.append(String.format(f, i+1, record.getLevel().intValue() <= Level.INFO.intValue() ? " " : "--- ERROR ---")); + String s = String.format("%1$-7s%2$c%3$tT.%3$tL: ", record.getLevel().getName(), (record instanceof LogDebugRecord ? '*' : ' '), new Date(record.getMillis())); + sb.append(s); + int len = s.length(); + + if (record.getMessage() != null) + { + sb.append(record.getMessage()); + len += record.getMessage().length(); + } + + Throwable th = record.getThrown(); + //if (th==null && record instanceof ExtendedLogRecord) + if (record instanceof ExtendedLogRecord) + { + ExtendedLogRecord elr = (ExtendedLogRecord)record; + StackTraceElement location = elr.getLocation(); + sb.append(" ["); + sb.append(elr.getLocationAsString()); + sb.append("]"); + if (!elr.isCallStackEmpty()) + { + String format = String.format("%%%dd -> [%%s]", len-3); + for (int j=0; j<elr.getStackTraceElements().length; j++) + { + sb.append("\n"); + sb.append(String.format(format, j+1, elr.getStackTraceElementAsString(j))); + } + } + } + + + sb.append("\n"); + if (th != null) + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(baos); + th.printStackTrace(ps); + sb.append(baos.toString()); + sb.append("================================================================================\n"); + } + } + + return sb.toString(); + } + + public synchronized boolean isEmpty () + { + return recordList.isEmpty(); + } + + public synchronized int size () + { + return recordList.size(); + } + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogWarningRecord.java b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogWarningRecord.java new file mode 100644 index 0000000..f9c0dd1 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogWarningRecord.java @@ -0,0 +1,43 @@ +package at.htlkaindorf.sx.EasyProgrammer.logging; + +import java.util.logging.Level; + +/** + * + * @author Manfred Steiner (sx@htl-kaindorf.ac.at) + */ +public class LogWarningRecord extends ExtendedLogRecord +{ + public LogWarningRecord (String msg) + { + super(Level.WARNING, msg, 2); + } + + public LogWarningRecord (String msg, Throwable th) + { + super(Level.WARNING, msg, 2); + setThrown(th); + } + + LogWarningRecord (String msg, int locationStackTraceIndex) + { + super(Level.WARNING, msg, locationStackTraceIndex); + } + + LogWarningRecord (String msg, Throwable th, int locationStackTraceIndex) + { + super(Level.WARNING, msg, locationStackTraceIndex); + setThrown(th); + } + + LogWarningRecord (String msg, int locationStackTraceIndex, int locationStackTraceDepth) + { + super(Level.WARNING, msg, locationStackTraceIndex, locationStackTraceDepth); + } + + LogWarningRecord (String msg, Throwable th, int locationStackTraceIndex, int locationStackTraceDepth) + { + super(Level.WARNING, msg, locationStackTraceIndex, locationStackTraceDepth); + setThrown(th); + } +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogWriterHandler.java b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogWriterHandler.java new file mode 100644 index 0000000..c5a0bf5 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/logging/LogWriterHandler.java @@ -0,0 +1,143 @@ +package at.htlkaindorf.sx.EasyProgrammer.logging; + +import java.io.PrintStream; +import java.io.PrintWriter; +import java.util.Date; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + + +/** + * + * @author Manfred Steiner (sx@htl-kaindorf.ac.at) + */ +public class LogWriterHandler extends Handler +{ + private final PrintWriter out; + private final PrintWriter err; + private final PrintStream outStream; + private final PrintStream errStream; + + public LogWriterHandler (PrintWriter out, PrintWriter err) + { + if (out == null || err == null) + throw new NullPointerException(); + this.out = out; + this.err = err; + this.outStream = null; + this.errStream = null; + } + + public LogWriterHandler (PrintStream out, PrintStream err) + { + if (out == null || err == null) + throw new NullPointerException(); + this.outStream = out; + this.errStream = err; + this.out = new PrintWriter(out); + this.err = new PrintWriter(err); + } + + @Override + public void publish (LogRecord record) + { + if (record.getLevel().intValue() < getLevel().intValue()) + return; + + int l1 = Level.INFO.intValue(); + int l2 = record.getLevel().intValue(); + + PrintWriter pw = record.getLevel().intValue() <= Level.INFO.intValue() ? out : err; + String s = String.format("%1$-7s%2$c%3$tT.%3$tL: ", record.getLevel().getName(), (record instanceof LogDebugRecord ? '*' : ' '), new Date(record.getMillis())); + pw.print(s); + int len = s.length(); + + if (record.getMessage() != null) + { + String msg = record.getMessage(); + for (int i=0; i<msg.length(); i++) + { + char c = msg.charAt(i); + int x = (int)c; + if (Character.isISOControl(c)) + { + pw.print("<"); + pw.print(String.format("%02x", (int)c)); + pw.print(">"); + len +=4; + } + else + { + pw.print(c); + len++; + } + } + } + + Throwable th = record.getThrown(); + //if (th==null && record instanceof ExtendedLogRecord) + if (record instanceof ExtendedLogRecord) + { + ExtendedLogRecord elr = (ExtendedLogRecord)record; + StackTraceElement location = elr.getLocation(); + pw.print(" ["); + pw.print(elr.getLocationAsString()); + String str = elr.getLocationAsString(); + pw.print("]"); + if (!elr.isCallStackEmpty()) + { + String format = String.format("%%%dd -> [%%s]", len-3); + for (int i=0; i<elr.getStackTraceElements().length; i++) + { + pw.println(); + pw.print(String.format(format, i+1, elr.getStackTraceElementAsString(i))); + } + } + } + + pw.println(); + if (th != null) + { + pw.println("--------------------------------------------------------------------------------"); + th.printStackTrace(pw); + pw.println("================================================================================"); + } + + pw.flush(); + } + + @Override + public void flush () + { + out.flush(); + err.flush(); + } + + @Override + public void close () throws SecurityException + { + + } + + public PrintWriter getErrorWriter () + { + return err; + } + + public PrintWriter getOutWriter () + { + return out; + } + + public PrintStream getErrorStream () + { + return errStream; + } + + public PrintStream getOutStream () + { + return outStream; + } + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/logging/Logger.java b/src/at/htlkaindorf/sx/EasyProgrammer/logging/Logger.java new file mode 100644 index 0000000..334be4b --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/logging/Logger.java @@ -0,0 +1,476 @@ +package at.htlkaindorf.sx.EasyProgrammer.logging; + +import java.util.HashMap; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + + +/** + * + * @author Manfred Steiner (sx@htl-kaindorf.ac.at) + */ +public class Logger +{ + private static final HashMap<String,Logger> loggerMap = new HashMap<>(); + private static Logger parentLogger; + + public static synchronized Logger getLogger (String name) + { + Logger logger = loggerMap.get(name); + if (logger == null) + { + logger = new Logger(name); + if (parentLogger != null) + { + logger.setParent(parentLogger); + logger.setUseParentHandlers(true); + } + loggerMap.put(name, logger); + } + return logger; + } + + public static synchronized Logger getLogger (String name, Logger parent) + { + Logger logger = loggerMap.get(name); + if (logger == null) + { + logger = new Logger(name); + logger.setParent(parent); + loggerMap.put(name, logger); + } + return logger; + } + + public static synchronized void setParentLogger (Logger logger) + { + parentLogger = logger; + for (Logger l : loggerMap.values()) + { + if (l != logger) + { + l.setParent(logger); + l.setUseParentHandlers(true); + } + } + } + + // ********************************************************* + + protected final java.util.logging.Logger logger; + protected boolean locationShown = true; + protected Level debugLevel = Level.INFO; + + private Logger (String name) + { + logger = java.util.logging.Logger.getLogger(name); + } + + + /** + * Readjusting the logging level of this logger. + * The level is adjusted to the logging level of the parent and the registered handlers. + * If no handler is registered and no parent is active, the level is set to Level.OFF + */ + public synchronized void updateEffectiveLevel () + { + int levelValue = Level.OFF.intValue(); + + if (logger.getUseParentHandlers() && getParent()!=null) + levelValue = getParent().getLevel().intValue(); + + for (Handler h : getHandlers()) + levelValue = Math.min(levelValue, h.getLevel().intValue()); + + if (levelValue>=Level.OFF.intValue()) + setLevel(Level.OFF); + else if (levelValue>=Level.SEVERE.intValue()) + setLevel(Level.SEVERE); + else if (levelValue>=Level.WARNING.intValue()) + setLevel(Level.WARNING); + else if (levelValue>=Level.INFO.intValue()) + setLevel(Level.INFO); + else if (levelValue>=Level.CONFIG.intValue()) + setLevel(Level.CONFIG); + else if (levelValue>=Level.FINE.intValue()) + setLevel(Level.FINE); + else if (levelValue>=Level.FINER.intValue()) + setLevel(Level.FINER); + else if (levelValue>=Level.FINEST.intValue()) + setLevel(Level.FINEST); + else + setLevel(Level.ALL); + } + + public synchronized void setLocationShown (boolean showLocation) + { + this.locationShown = showLocation; + } + + public boolean isLocationShown () + { + return locationShown; + } + + public java.util.logging.Logger getParent () + { + return logger.getParent(); + } + + public void setParent (Logger parent) + { + logger.setParent(parent.logger); + } + + public void setUseParentHandlers (boolean useParentHandlers) + { + logger.setUseParentHandlers(useParentHandlers); + } + + public boolean getUseParentHandlers () + { + return logger.getUseParentHandlers(); + } + + public void addHandler (Handler handler) + { + logger.addHandler(handler); + updateEffectiveLevel(); + } + + public java.util.logging.Handler [] getHandlers () + { + return logger.getHandlers(); + } + + public void removeHandler (java.util.logging.Handler handler) + { + logger.removeHandler(handler); + } + + + public void setLevel (Level level) + { + logger.setLevel(level); + } + + public void setLevel (String level) + { + switch (level) + { + case "ALL": logger.setLevel(Level.ALL); break; + case "FINEST": logger.setLevel(Level.FINEST); break; + case "FINER": logger.setLevel(Level.FINER); break; + case "FINE": logger.setLevel(Level.FINE); break; + case "CONFIG": logger.setLevel(Level.CONFIG); break; + case "INFO": logger.setLevel(Level.INFO); break; + case "WARNING": logger.setLevel(Level.WARNING); break; + case "SEVERE": logger.setLevel(Level.SEVERE); break; + case "OFF": logger.setLevel(Level.OFF); break; + default: + int l = Integer.parseInt(level); + logger.setLevel(new SpecialLevel("Level " + l, l)); + break; + } + } + + public Level getLevel () + { + Level rv = logger.getLevel(); + if (rv == null && logger.getParent() != null) + rv = logger.getParent().getLevel(); + return rv; + } + + public boolean isLoggable (Level level) + { + return logger.isLoggable(level); + } + + public boolean isFinestLogged () + { + return logger.isLoggable(Level.FINEST); + } + + public boolean isFinerLogged () + { + return logger.isLoggable(Level.FINER); + } + + public boolean isFineLogged () + { + return logger.isLoggable(Level.FINE); + } + + public boolean isConfigLogged () + { + return logger.isLoggable(Level.CONFIG); + } + + public boolean isInfoLogged () + { + return logger.isLoggable(Level.INFO); + } + + public boolean isWarningLogged () + { + return logger.isLoggable(Level.WARNING); + } + + public boolean isSevereLogged () + { + return logger.isLoggable(Level.SEVERE); + } + + + public void log (Level l, String msg, Throwable th) + { + if (locationShown) + { + if (l.intValue()>=Level.SEVERE.intValue()) logger.log(new LogSevereRecord(msg, th, 3)); + else if (l.intValue()>=Level.WARNING.intValue()) logger.log(new LogWarningRecord(msg, th, 3)); + else if (l.intValue()>=Level.INFO.intValue()) logger.log(new LogInfoRecord(msg, th, 3)); + else if (l.intValue()>=Level.CONFIG.intValue()) logger.log(new LogConfigRecord(msg, th, 3)); + else if (l.intValue()>=Level.FINE.intValue()) logger.log(new LogFineRecord(msg, th, 3)); + else if (l.intValue()>=Level.FINER.intValue()) logger.log(new LogFinerRecord(msg, th, 3)); + else if (l.intValue()>=Level.FINEST.intValue()) logger.log(new LogFinestRecord(msg, th, 3)); + } + else + { + logger.log(l, msg, th); + } + } + + + public void log (Level l, String msg) + { + if (locationShown) + { + if (l.intValue()>=Level.SEVERE.intValue()) logger.log(new LogSevereRecord(msg, 3)); + else if (l.intValue()>=Level.WARNING.intValue()) logger.log(new LogWarningRecord(msg, 3)); + else if (l.intValue()>=Level.INFO.intValue()) logger.log(new LogInfoRecord(msg, 3)); + else if (l.intValue()>=Level.CONFIG.intValue()) logger.log(new LogConfigRecord(msg, 3)); + else if (l.intValue()>=Level.FINE.intValue()) logger.log(new LogFineRecord(msg, 3)); + else if (l.intValue()>=Level.FINER.intValue()) logger.log(new LogFinerRecord(msg, 3)); + else if (l.intValue()>=Level.FINEST.intValue()) logger.log(new LogFinestRecord(msg, 3)); + } + else + { + logger.log(l, msg); + } + } + + + public class SpecialLevel extends Level + { + public SpecialLevel (String name, int level) + { + super(name, level); + } + } + + + public void log (LogRecord record) + { + logger.log(record); + } + + + public void finest (String msg) + { + if (locationShown) + logger.log(new LogFinestRecord(msg, 3)); + else + logger.finest(msg); + } + + public void finest (String msg, Throwable th) + { + if (locationShown) + logger.log(new LogFinestRecord(msg, th, 3)); + else + logger.log(Level.FINEST, msg, th); + } + + public void finer (String msg) + { + if (locationShown) + logger.log(new LogFinerRecord(msg, 3)); + else + logger.finer(msg); + } + + public void finer (String msg, Throwable th) + { + if (locationShown) + logger.log(new LogFinerRecord(msg, th, 3)); + else + logger.log(Level.FINER, msg, th); + } + + public void fine (String msg) + { + if (locationShown) + logger.log(new LogFineRecord(msg, 3)); + else + logger.fine(msg); + } + + public void fine (String msg, int stackTraceDepth) + { + if (locationShown) + logger.log(new LogFineRecord(msg, 3, stackTraceDepth)); + else + logger.fine(msg); + } + + public void fine (String msg, Throwable th) + { + if (locationShown) + logger.log(new LogFineRecord(msg, th, 3)); + else + logger.log(Level.FINE, msg, th); + } + + public void config (String msg) + { + if (locationShown) + logger.log(new LogConfigRecord(msg, 3)); + else + logger.config(msg); + } + + public void config (String msg, Throwable th) + { + if (locationShown) + logger.log(new LogFineRecord(msg, th, 3)); + else + logger.log(Level.CONFIG, msg, th); + } + + public void info (String msg) + { + if (locationShown) + logger.log(new LogInfoRecord(msg, 3)); + else + logger.info(msg); + } + + public void info (String msg, Throwable th) + { + if (locationShown) + logger.log(new LogInfoRecord(msg, th, 3)); + else + logger.log(Level.INFO, msg, th); + } + + public void warning (String msg) + { + if (locationShown) + logger.log(new LogWarningRecord(msg, 3)); + else + logger.warning(msg); + } + + public void warning (Throwable th) + { + if (locationShown) + logger.log(new LogWarningRecord(null, th, 3)); + else + logger.log(Level.WARNING, null, th); + } + + public void warning (String msg, Throwable th) + { + if (locationShown) + logger.log(new LogWarningRecord(msg, th, 3)); + else + logger.log(Level.WARNING, msg, th); + } + + public void severe (String msg) + { + if (locationShown) + logger.log(new LogSevereRecord(msg, 3)); + else + logger.severe(msg); + } + + public void severe (Throwable th) + { + if (locationShown) + logger.log(new LogSevereRecord(null, th, 3)); + else + logger.log(Level.SEVERE, null, th); + } + + public void severe (String msg, Throwable th) + { + if (locationShown) + logger.log(new LogSevereRecord(msg, th, 3)); + else + logger.log(Level.SEVERE, msg, th); + } + + public void debug (String msg) + { + if (locationShown) + logger.log(new LogDebugRecord(debugLevel, msg, 3)); + else + logger.log(new LogRecord(debugLevel, msg)); + } + + public void debug (String msg, int stackTraceDepth) + { + if (locationShown) + logger.log(new LogDebugRecord(debugLevel, msg, 3, stackTraceDepth)); + else + logger.log(new LogRecord(debugLevel, msg)); + } + + public void debug (Throwable th) + { + if (locationShown) + logger.log(new LogDebugRecord(debugLevel, null, th, 3)); + else + { + LogRecord r = new LogRecord(debugLevel, null); + r.setThrown(th); + logger.log(r); + } + } + + public void debug (Throwable th, int stackTraceDepth) + { + if (locationShown) + logger.log(new LogDebugRecord(debugLevel, null, 3, stackTraceDepth)); + else + logger.log(new LogRecord(debugLevel, null)); + } + + public void debug (String msg, Throwable th) + { + if (locationShown) + logger.log(new LogDebugRecord(debugLevel, msg, th, 3)); + else + { + LogRecord r = new LogRecord(debugLevel, msg); + r.setThrown(th); + logger.log(r); + } + } + + public void debug (String msg, Throwable th, int stackTraceDepth) + { + if (locationShown) + logger.log(new LogDebugRecord(debugLevel, msg, th, 3, stackTraceDepth)); + else + { + LogRecord r = new LogRecord(debugLevel, msg); + r.setThrown(th); + logger.log(r); + } + } + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/manpage/easyprogrammer.1 b/src/at/htlkaindorf/sx/EasyProgrammer/manpage/easyprogrammer.1 new file mode 100644 index 0000000..80fa2fe --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/manpage/easyprogrammer.1 @@ -0,0 +1,66 @@ +.TH easyprogrammer 1 "March 03, 2016" "" "easyprogrammer" + +.SH NAME +easyprogrammer \- Terminal/Hexfile-Download Programm for Atmel Atmega microcontrollers with HTL Bootloader + +.SH SYNOPSIS +.B easyprogrammer +.RI [ options ] +.br + +.SH DESCRIPTION +Diese man-Page beschreibt die zu Verfügung stehenden Optionen der unter Java laufenden GUI-Applikation +.B easyprogrammer +Beim Start des Programmes stehen verschiedene Startoptionen zur Verfügung. +.PP +\fBeasyprogrammer\fP erlaubt den Reset des Zielsystems mittels einstellbarer Kommandosequenz, den Download eines uC-Programmes (in Form eines Intel Hex-File), sowie die Kommunikation mit dem Zielsystem mit Hilfe eines Terminals. +.PP +In der Programmdatei (dem java-Archiv \fBeasyprogrammer.jar\fP) sind auch die Hex-Dateien der Bootloader enthalten. + +.SH OPTIONS +.B +.IP "-h oder --help" +Alle verfügbaren Optionen werden ausgegeben. +.B +.IP "-v oder --version" +Aktuelle Software Version wird ausgegeben. +.B +.IP "-b oder --batch" +Easyprogrammer wird im Batch Modus (ohne GUI Interface) gestartet. +.B +.IP "-i <interface-name> oder --interface <interface-name>" +Gewünschtes Interface, zB "-i /dev/ttyUSB0" oder "/dev/ttyUSB0:57600/8N1" +.B +.IP "-n <name1,name2, ...> oder --interface-names <name1,name2, ...>" +Interface Namen die in der Auswahl bereitgestellt werden. +.B +.IP "-d <directory-name> oder --directory <directory-name>" +Verzeichnis-Pfad zu den Hex-Programmdateien. +.B +.IP "-f <filename> oder --hexfile <filename>" +Name der Hex-Programmdatei. Kann auch mit vollstaendigem Dateipfad sein. +.B +.IP "-r oder --noreset" +Die Funktion "Reset Target vor Download" wird deaktiviert +.B +.IP "-C <reset-command> oder --resetcmd <reset-command>" +Anstelle '@R' wird der angegebene String als Reset-Kommando verwendet. +.B +.IP "-R <reset-sequence> oder --resetseq <reset-sequence>" +Anstelle '@rR<CR><LF>' werden nur die angegeben zeichen ohne Zeilenvorschub gesendet. +.B +.IP "-c oder --nocheck" +Antwort des Zielsystems wird nach dem Download nicht überprüft. +.B +.IP "-t <uC> oder --target <uC>" +Typ des µC angeben. Gültige Werte für <uC> sind: atmega8l, atmega16, atmega328p +.B +.IP "-p <portnr> oder --port <portnr>" +easyprogrammer startet auch als Serverdienst mit dem angegeben Port. +.B +.IP "-w <time in ms> oder --wait <time in ms>" +Zeit in Millisekunden die auf den Bootloader gewartet wird. +.IP "-l <loglevel> oder --loglevel <loglevel>" +loglevel: SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST oder ALL +.SH AUTHOR +Manfred Steiner <sx@htl-kaindorf.ac.at> diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/serial/DebugOutputStream.java b/src/at/htlkaindorf/sx/EasyProgrammer/serial/DebugOutputStream.java new file mode 100644 index 0000000..722ad31 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/serial/DebugOutputStream.java @@ -0,0 +1,171 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package at.htlkaindorf.sx.EasyProgrammer.serial; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; + +/** + * + * @author steiner + */ +public class DebugOutputStream extends FilterOutputStream +{ + ArrayList<int []> mem; + int [] page; + int pos; + + public DebugOutputStream(OutputStream out) + { + super(out); + mem = new ArrayList<int []>(); + page = new int [8192]; + pos = 0; + } + + + @Override + public void close() throws IOException + { + super.close(); + } + + + @Override + public void flush() throws IOException + { + super.flush(); + } + + + @Override + public void write(int b) throws IOException + { + super.write(b); + page[pos++] = b; + if (pos>=page.length) + { + mem.add(page); + page = new int [8192]; + pos = 0; + } + } + + + @Override + public void write(byte[] b) throws IOException + { + super.write(b); +/* + for (int i=0; i<b.length; i++) + { + page[pos++] = b[i]; + if (pos>=page.length) + { + mem.add(page); + page = new int [8192]; + pos = 0; + } + } + if (pos>132) + System.out.println("Error?"); + */ + } + + + @Override + public void write(byte[] b, int off, int len) throws IOException + { + super.write(b, off, len); + + /* + for (int i=off; i<b.length && i<(off+len); i++) + { + page[pos++] = b[i]; + if (pos>=page.length) + { + mem.add(page); + page = new int [8192]; + pos = 0; + } + } + */ + + } + + + public int length () + { + return mem.size()*8129 + pos; + } + + int elementAt (int index) throws IndexOutOfBoundsException + { + int p = index / 8192; + int i = index % 8192; + + if (p<mem.size()) + return mem.get(p)[i]; + + if (p==mem.size()) + return page[i]; + + throw new IndexOutOfBoundsException(); + } + + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(128); + sb.append(this.getClass().getCanonicalName()); + sb.append("["); + sb.append("mem="); sb.append(mem); + sb.append(", page="); sb.append(page); + sb.append(", pos="); sb.append(pos); + sb.append("]"); + + for (int i=0; i<this.length(); i++) + { + if (i%16 == 0) + sb.append(String.format("\n %04X: ", i)); + int x = this.elementAt(i); + if (x<-128 || x>127) + sb.append(" --"); + else + { + if (x<0) x +=256; + sb.append(String.format(" %02X", x)); + } + if (i%4==3) + sb.append(" "); + if (i%16==15) + { + sb.append(" "); + for (int j=i-15; j<=i; j++) + { + x = this.elementAt(j); + if (x<32 || x>126) + sb.append("."); + else + sb.append((char)x); + if (j%4==3) + sb.append(" "); + } + } + } + sb.append("\n"); + + return sb.toString(); + } + + + + + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/serial/DownloadFile.java b/src/at/htlkaindorf/sx/EasyProgrammer/serial/DownloadFile.java new file mode 100644 index 0000000..34bc426 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/serial/DownloadFile.java @@ -0,0 +1,556 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.htlkaindorf.sx.EasyProgrammer.serial; + +import at.htlkaindorf.sx.EasyProgrammer.data.ProgramFile; +import at.htlkaindorf.sx.EasyProgrammer.logging.Logger; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.util.Iterator; + +// Download protocol +// starte Bootloader -> ..... kommt +// sende "@m02@f128P" + <LF> -> Antwort: <CR><LF>f> +// sende "Pxx<Byte 0><Byte 1> ... <Byte 127>" wobei xx = Pagenummer in hex +// Antwort: "=<xx> <ChkSum> <Error> <Error-Code><CR><LF>f>" zB: =00 27 00 00<CR><LF>f> +// Nun fuer alle Pages den Vorgang wiederholen +// anschliessend "FFF" senden, dadurch wird der Bootloader beendet und die Applikation gestartet + +/** + * + * @author alle + */ +public class DownloadFile +{ + + private static final Logger LOG = Logger.getLogger(DownloadFile.class.getName()); + + private long startTime; + private boolean startCmdSent; + private boolean downloadDone; + private boolean noSystemResponseCheck; + private jssc.SerialPort serialPort; + private SerialPortInfo serialPortInfo; + private ProgramFile programFile; + private BufferedOutputStream outStream; + private BufferedInputStream inStream; + + + + + + public DownloadFile (SerialPortInfo serialPortInfo, ProgramFile programFile) + { + this.serialPortInfo = serialPortInfo; + this.programFile = programFile; + } + + + public void open () throws Exception + { + jssc.SerialPort serialPort = new jssc.SerialPort(serialPortInfo.getName()); + if (!serialPort.openPort()) + throw new Exception("cannot open serial port " + serialPortInfo.getName()); + + try + { + serialPortInfo.setJSSCSerialPortParams(serialPort); + } + catch (Exception ex) + { + close(); + } + } + + + public void close () throws Exception + { + if (serialPort != null && serialPort.isOpened()) + { + try + { + if (!serialPort.closePort()) + throw new Exception("serial port close error"); + } + catch (Exception ex) + { + LOG.warning(ex); + } + } + serialPort = null; + } + + + public void start () + { + startTime = System.currentTimeMillis(); + } + + private String getStatus (String status) + { + StringBuilder sb = new StringBuilder(status.length() + 16); + sb.append(String.format(" [%5dms] ", System.currentTimeMillis() - startTime)); + for (int i=0; i<status.length(); i++) + { + char c = status.charAt(i); + switch (c) + { + case '\n': sb.append("\\n"); break; + case '\r': sb.append("\\r"); break; + default: + sb.append(c>=32 && c<127 ? c : '.'); + } + + } + return sb.toString(); + } + + + private char getPrintableChar(int value) + { + if (value<32 || value>'~') return ('.'); + return (char)value; + } + + + public void waitOnBootloader (int ms, boolean sendCmdStart) throws Exception + { + int len=0; + StringBuilder response = new StringBuilder(256); + startCmdSent = false; + + if (serialPort == null || inStream==null || outStream==null) + throw new RuntimeException ("waitOnBootloader Problem"); + System.out.println(getStatus("wait on Bootloader response ")); + + long timeout = System.nanoTime() + ((long)ms)*1000000; + + //setReceiveTimeOut(100); + while (inStream.available()>0) + inStream.read(); + + while (System.nanoTime()<timeout) + { + try + { + int c = inStream.read(); + if (c>=0) + { + response.append((char)c); + System.out.print(getPrintableChar(c)); + if (++len==80) + { + System.out.print("\r"); + len = 0; + } + } + + long t0 = System.nanoTime(); + if (c<0 || ((char)c)!='.') + continue; + c = inStream.read(); + long t1 = System.nanoTime(); + if (c<0 || ((char)c)!='.') + continue; + long dt = (t1-t0)/1000000; + if (dt>30 && dt<80) + { + if (sendCmdStart) + { + //outStream.write(programFile.getBootloaderStartCmd().getBytes()); + outStream.write('@'); + outStream.flush(); + Thread.sleep(100); + c = -1; + while(inStream.available()>0) + { + c = inStream.read(); + if (c=='@') break; + c = -1; + } + if (c!='@') + throw new Exception("error on sending @"); + startCmdSent = true; + } + if (len>0) System.out.println(""); + int i = response.toString().indexOf("Bootloader Version "); + int j = response.toString().indexOf("]"); + if (i<0 || j<0 || (j-i)<40 || (j-i)>50) + System.out.println(getStatus("Bootloader detected")); + else + { + String version = response.substring(i, j+1); + System.out.println(getStatus(version + " detected")); + } + return; + } + } + catch (Exception ex) + { + break; + } + } + if (len>0) System.out.println(""); + System.out.println(getStatus("No Bootloader detected")); + throw new Exception("Bootloader not detected"); + } + + public void resetTarget (String resetCmd) throws Exception + { + System.out.println(getStatus("Reset Target with '" + resetCmd + "'")); + outStream.write(resetCmd.getBytes()); + //outStream.write('\r'); + //outStream.write('\n'); + outStream.flush(); + } + + private void sendAndCheckCommand (String cmd, String check, int timeoutMillis) throws Exception + { + Thread.sleep(10); + while (inStream.available()>0) + inStream.read(); + + outStream.write(cmd.getBytes()); + outStream.flush(); + //System.out.println("send '" + cmd + "'"); + long timeout = System.nanoTime() + timeoutMillis*1000000; + StringBuilder sb = new StringBuilder(cmd.length()+16); + + if (check==null) + { + Thread.sleep(timeoutMillis); + return; + } + + while (System.nanoTime() < timeout) + { + while (inStream.available()>0) + { + int c = inStream.read(); + if (c>=0 && c<=255) sb.append((char)c); + if (sb.toString().endsWith(check)) + return; + } + Thread.sleep(1); + } + +// System.out.print("response does not match "); +// for (int i=0; i<sb.length(); i++) +// { +// if (sb.charAt(i)>= ' ' && sb.charAt(i)<'.') +// System.out.print((char)sb.charAt(i)); +// else +// System.out.print("<" + (int)sb.charAt(i) + ">"); +// } +// System.out.println(""); + throw new Exception("response does not match"); + } + + + public void download (boolean noSystemResponseCheck) throws Exception + { + this.noSystemResponseCheck = noSystemResponseCheck; + downloadDone = false; + programFile.setBootloaderMode(2); + + try + { + if (startCmdSent==false) + { + String cmd = programFile.getBootloaderStartCmd() + "P\n"; + sendAndCheckCommand(cmd, "f>", 200); + startCmdSent = true; + } + else + { + String cmd = programFile.getBootloaderStartCmd().substring(1) + "P\n"; + sendAndCheckCommand(cmd, "f>", 200); + } + + int pages = programFile.getMemoryPages(); + System.out.println(getStatus(pages + " Pages werden geladen")); + int attempt = 1; + Object page = null; + + // Bug in Bootloader, first response is wrong + // Bugfix, write first page without check, repeat later in loop + + System.out.print(getStatus("Download: ")); + + for (Iterator<Object> it = programFile.iterator(); it.hasNext(); ) + { + if (attempt==1) + page = it.next(); + int pagenr; + //Thread.sleep(70); + + try + { + switch(programFile.getBootloaderMode()) + { + case 0: pagenr = writeAndCheckPage((String) page); break; // character without checksum + case 1: pagenr = writeAndCheckPage((String) page); break; // character with checksum + case 2: pagenr = writeAndCheckPage((byte []) page); break; // binary without checksum + case 3: pagenr = writeAndCheckPage((byte []) page); break; // binary with checksum + default: + throw new Exception("Unknown Bootloader-mode"); + } + //gui.stateChanged(new ChangeEvent((pagenr*100)/pages)); + attempt = 1; + System.out.print("."); + } + catch (Exception ex) + { + ex.printStackTrace(System.err); + System.out.print("E"); + if (ex instanceof InterruptedException) + throw ex; + if (attempt>5) + throw ex; + attempt++; + } + } + downloadDone = true; + } + catch (Exception ex) + { + //if ((ex instanceof InterruptedException) == false) + // gui.stateChanged(new ChangeEvent("Error:" + ex.getMessage())); + throw ex; + + } + finally + { + if (downloadDone) + { + System.out.println(" -> sucessfully done"); + System.out.println(getStatus("Stop Download and start application")); + } + else + { + System.out.println(" -> fails"); + System.out.println(getStatus("Stop Download and start application. Maybe will not work!")); + } + try + { + endBootloader(); + if (!noSystemResponseCheck) + System.out.println(getStatus("Antwort des Zielsystems ok")); + } + catch (Exception ex) + { + System.out.println(getStatus(ex.getMessage())); + } + } + } + + + private void endBootloader () throws Exception + { + try + { + if (noSystemResponseCheck) + sendAndCheckCommand("FFF", null, 100); + else + sendAndCheckCommand("FFF", ">", 100); + } + catch (Exception ex) + { + //System.out.println(ex.getMessage()); + if (downloadDone) + throw new Exception("Download ok, System liefert keine Antwort"); + else + throw new Exception("Error on Bootloader end command"); + } + + } + + + + private int writeAndCheckPage (String s) throws Exception + { + StringBuilder pageNr = new StringBuilder(2); + + pageNr.append((char)s.charAt(1)); + pageNr.append((char)s.charAt(2)); + + Thread.sleep(50); + return Integer.valueOf(pageNr.toString(), 16); + } + + + private int writeAndCheckPage (byte [] b) throws Exception + { + StringBuilder sb = new StringBuilder(16); + int pos = 0; + + StringBuilder pageNr = new StringBuilder(2); + pageNr.append((char)b[1]); + pageNr.append((char)b[2]); + int page = Integer.valueOf(pageNr.toString(), 16); + + String str = null; + + try + { + outStream.write(b); + outStream.flush(); + + //Thread.sleep(100); + long start = System.currentTimeMillis(); + str = readResponseString("=?? ?? ?? ??\r\nf>", 500); + + //System.out.print("receive: " + lenInBuffer + " Bytes"); + //System.out.println(" " + bytesToString(inputBytes, 0, pos, true)); + + if (str == null || str.length()==0) + throw new Exception("Bootloader Error (no response)"); + else if (str.charAt(0)!='=' || str.charAt(3)!=' ' || str.charAt(6)!=' ' || str.charAt(9)!=' ' || + str.charAt(12)!=13 || str.charAt(13)!=10 || str.charAt(14)!='f' || str.charAt(15)!='>') + throw new Exception("Bootloader Error (unexpected response)"); + else + { + try + { + int recpage = parseValue(str, "=XX ?? ?? ????f>"); + int chk = parseValue(str, "=?? XX ?? ????f>"); + int errpos = parseValue(str, "=?? ?? XX ????f>"); + int errcode = parseValue(str, "=?? ?? ?? XX??f>"); + int chksum = 0; + for (int i=3; i<b.length; i++) + chksum = (chksum + this.toUnsignedByte(b[i])) % 256; + //System.out.println("ok, page=" + page + ", chk=" + chk + ", chksum=" + chksum + ", errcode=" + errcode + ", errpos=" + errpos); + if (recpage != page) + throw new Exception("Page Error (expected=" + page + " received=" + recpage + ")"); + if (chksum != chk) + throw new Exception("Checksum Error (expected=" + chksum + " received=" + chk + ")"); + if (errcode != 0) + throw new Exception("Bootloader Error (code=" + errcode + " on position " + errpos + ")"); + } + catch (Exception ex) + { + throw new Exception("Download Error (unexpected response)"); + } + } + } + catch (Exception ex) + { + System.out.println(""); + System.out.println("response " + str.length() + " Bytes "); + byte [] ba = str.getBytes(); + for (byte x : ba) + System.out.print(String.format("%02x ", x)); + System.out.print(" "); + for (byte x : ba) + System.out.print((char)(x>=32 && x<127 ? x : '.')); + System.out.println(""); + + //ex.printStackTrace(System.err); + throw ex; + } + + //System.out.println("page " + page + " ok"); + + return page; + } + + private int parseValue (String str, String filter) throws Exception + { + int i; + int value = 0; + boolean error = false; + + if (filter.length() != str.length()) + throw new Exception("Parse error, wrong length"); + + for (i=0; i<str.length() && error==false; i++) + { + char c = str.charAt(i); + switch (filter.charAt(i)) + { + case 'X': + c = Character.toLowerCase(c); + if (c >= '0' && c <= '9') + value = value*16+ c - '0'; + else if (c >= 'a' && c <= 'f') + value = value*16+ c - 'a' + 10; + else + error = true; + break; //no hex digit + + case '?': + break; + + default: + if (str.charAt(i) != filter.charAt(i)) + error = true; + break; + } + } + + if (error) + throw new Exception("Parse error on Position " + i); + + return value; + } + + + private int toUnsignedByte (byte b) + { + return b<0 ? b+256 : b; + } + + + private String readResponseString (String pattern, int timeoutMillis) throws Exception + { + //System.out.println(System.currentTimeMillis() + ": readResponseString '" + pattern + "' timeout=" + timeoutMillis); + + StringBuilder sb = new StringBuilder (256); + long timeout = System.nanoTime() + timeoutMillis*1000000; + + try + { + while (System.nanoTime()<timeout) + { + while (inStream.available()>0 && sb.length()<pattern.length()) + { + int b = inStream.read(); + if (b<0 || b>255) throw new Exception("Wrong char"); + sb.append((char)b); + } + + if (sb.length()==pattern.length()) + { + for (int i=0; i<sb.length(); i++) + { + char c = pattern.charAt(i); + if (c!='?' && c!=sb.charAt(i)) + throw new Exception("Pattern mismatch"); + } + return sb.toString(); + } + } + throw new Exception("Timeout"); + } + catch (Exception ex) + { +// System.out.print("Error on Response (" + ex.getMessage() + ")"); +// if (sb.length()==0) +// System.out.println(" - no bytes received"); +// else +// { +// System.out.print(" " + sb.length() + " Bytes received: "); +// byte [] ba = sb.toString().getBytes(); +// for (int i=0; i<ba.length; i++) +// { +// System.out.print("<" + String.format("%02x", ba[i]) + "> "); +// } +// System.out.println(""); +// } + throw ex; + } + } + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/serial/DownloadProtocol.java b/src/at/htlkaindorf/sx/EasyProgrammer/serial/DownloadProtocol.java new file mode 100644 index 0000000..7e9170d --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/serial/DownloadProtocol.java @@ -0,0 +1,479 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.htlkaindorf.sx.EasyProgrammer.serial; + +import at.htlkaindorf.sx.EasyProgrammer.data.ProgramFile; +import at.htlkaindorf.sx.EasyProgrammer.gui.TerminalArea; +import at.htlkaindorf.sx.EasyProgrammer.logging.Logger; +import java.io.IOException; +import java.util.Iterator; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +/** + * + * @author steiner + */ +public final class DownloadProtocol extends ResetProtocol +{ + private static final Logger LOG = Logger.getLogger(DownloadProtocol.class.getName()); + + private ChangeListener gui; + private int recentPortSpeed; + + public DownloadProtocol (SerialInterface serialInterface, TerminalArea terminalArea) + { + super(serialInterface, terminalArea); + recentPortSpeed = -1; + } + + + @Override + public void dataAvailable () + { + super.dataAvailable(); //To change body of generated methods, choose Tools | Templates. + } + + + + + @Override + public int read() throws Exception, IOException, NullPointerException + { + return super.read(); + /* + int b = super.read(); + if (b>=0) + { + System.out.print("DP read: "); + if (b>=32 && b<128) + System.out.print((char) b); + else + System.out.print(" "); + System.out.println(" " + b); + } + return b; + * + */ + } + + + @Override + public void write(int b) throws Exception + { + /* + System.out.print("DP write: "); + if (b>=32 && b<128) + System.out.print((char) b); + else + System.out.print(" "); + System.out.println(" " + b); + * + */ + + super.write(b); + } + + + + + @SuppressWarnings("SleepWhileHoldingLock") + public void download (ProgramFile file, ChangeListener gui) throws Exception + { + this.gui = gui; + + int pages =file.getMemoryPages(); + gui.stateChanged(new ChangeEvent("Bootloader detektiert, " + pages + " Pages werden geladen")); + LOG.info(String.format("flashing %d pages", pages)); + try + { + String cmd = file.getBootloaderStartCmd(); + startBootloader(cmd); + //System.out.println("'" + file.getBootloaderStartCmd() + "' written and checked"); + int attempt = 1; + Object page = null; + + for (Iterator<Object> it = file.iterator(); it.hasNext(); ) + { + //System.out.println("download page (attempt " + attempt + ")"); + if (attempt==1) + page = it.next(); + int pagenr; + + try + { + switch(file.getBootloaderMode()) + { + case 0: pagenr = writeAndCheckPage((String) page); break; // character without checksum + case 1: pagenr = writeAndCheckPage((String) page); break; // character with checksum + case 2: pagenr = writeAndCheckPage((byte []) page); break; // binary without checksum + case 3: pagenr = writeAndCheckPage((byte []) page); break; // binary with checksum + default: + throw new Exception("Unknown Bootloader-mode"); + } + gui.stateChanged(new ChangeEvent((pagenr*100)/pages)); + attempt = 1; + } + catch (IllegalStateException ex) + { + throw ex; + } + catch (Exception ex) + { + if (ex instanceof InterruptedException) + throw ex; + if (attempt>5) + throw ex; + attempt++; + } + } + if (file.getCpu().getFlashSize()/file.getCpu().getPageSize()>256) + endBootloader("FFFF"); + else + endBootloader("FFF"); + } + catch (Exception ex) + { + if ((ex instanceof InterruptedException) == false) + gui.stateChanged(new ChangeEvent("Error:" + ex.getMessage())); + LOG.warning(ex); + try + { + if (file.getCpu().getFlashSize()/file.getCpu().getPageSize()>256) + endBootloader("FFFF"); + else + endBootloader("FFF"); + throw ex; + } + catch (Exception e) + { + e.addSuppressed(ex); + throw e; + } + } + finally + { + this.disconnect(); + } + } + + + private int parseValue (String str, String filter) throws Exception + { + int i; + int value = 0; + boolean error = false; + + if (filter.length() != str.length()) + throw new Exception("Parse error, wrong length"); + + for (i=0; i<str.length() && error==false; i++) + { + char c = str.charAt(i); + switch (filter.charAt(i)) + { + case 'X': + c = Character.toLowerCase(c); + if (c >= '0' && c <= '9') + value = value*16+ c - '0'; + else if (c >= 'a' && c <= 'f') + value = value*16+ c - 'a' + 10; + else + error = true; + break; //no hex digit + + case '?': + break; + + default: + if (str.charAt(i) != filter.charAt(i)) + error = true; + break; + } + } + + if (error) + throw new Exception(String.format("Parse error in '%s' on Position %d", str, i)); + return value; + } + + + private int writeAndCheckPage (String s) throws Exception + { + StringBuilder pageNr = new StringBuilder(2); + + pageNr.append((char)s.charAt(1)); + pageNr.append((char)s.charAt(2)); + + Thread.sleep(50); + return Integer.valueOf(pageNr.toString(), 16); + } + + + private int writeAndCheckPage (byte [] b) throws Exception + { + StringBuilder sb = new StringBuilder(16); + int pos = 0; + + int n = (int)(Math.log(b.length)/Math.log(2)); + int headerLength = b.length - (int)Math.pow(2, n); + + StringBuilder pageNr = new StringBuilder(headerLength-1); + for (int i=1; i<headerLength; i++) + pageNr.append((char)b[i]); + int page = Integer.valueOf(pageNr.toString(), 16); + + try + { + flush(); + if (LOG.isFineLogged()) + LOG.fine(String.format("writing flash page %s", pageNr)); + write(b); // write always whole buffer, otherwise problems in virtualized systems (loss of data) + long start = System.currentTimeMillis(); + if (LOG.isFinestLogged()) + LOG.finest(String.format("done, waiting for response on flash page %s", pageNr)); + long startTimeMillis = System.currentTimeMillis(); + String str; + try + { + str = readResponseString("f>", 500); + if (str==null) + throw new Exception("readResponseString 'f>' fails"); + long dt = System.currentTimeMillis() - startTimeMillis; + if (dt>100) + LOG.warning(String.format("unexpected delay in response (%dms)", dt)); + else if (LOG.isFinerLogged()) + LOG.finer(String.format("detect proper response in %dms", dt)); + + } + catch (Exception ex) + { + long dt = System.currentTimeMillis() - startTimeMillis; + LOG.warning(String.format("waiting %dms, no valid response detected", dt)); + throw new IllegalStateException("no valid response"); + } + + //System.out.println(" " + bytesToString(inputBytes, 0, pos, true)); + + if (str.charAt(0)=='=' + && str.charAt(headerLength)==' ' + && str.charAt(headerLength+3)==' ' + && str.charAt(headerLength+6)==' ' + && str.charAt(headerLength+9)==13 + && str.charAt(headerLength+10)==10 + && str.charAt(headerLength+11)=='f' + && str.charAt(headerLength+12)=='>') + { + if (LOG.isFinerLogged()) + LOG.finer(String.format("response '%s' received for flash page %s", str, pageNr)); + try + { + StringBuilder fsb = new StringBuilder("="); + for (int i=0; i<headerLength-1; i++) + fsb.append("X"); + int recpage = parseValue(str, fsb.toString() + " ?? ?? ????f>"); + + fsb.delete(1, fsb.length()); + for (int i=0; i<headerLength-1; i++) + fsb.append("?"); + + int chk = parseValue(str, fsb.toString() + " XX ?? ????f>"); + int errpos = parseValue(str, fsb.toString() + " ?? XX ????f>"); + int errcode = parseValue(str, fsb.toString() + " ?? ?? XX??f>"); + int chksum = 0; + + for (int i=headerLength; i<b.length; i++) + chksum = (chksum + this.toUnsignedByte(b[i])) % 256; + //System.out.println("ok, page=" + page + ", chk=" + chk + ", chksum=" + chksum + ", errcode=" + errcode + ", errpos=" + errpos); + if (recpage != page) + throw new Exception("Page Error (expected=" + page + " received=" + recpage + ")"); + if (chksum != chk) + throw new Exception("Checksum Error (expected=" + chksum + " received=" + chk + ")"); + if (errcode != 0) + throw new Exception("Bootloader Error (code=" + errcode + " on position " + errpos + ")"); + } + catch (Exception ex) + { + LOG.warning(ex); + throw new Exception("Download Error (unexpected response)", ex); + } + } + else if (str.length()==0) + throw new Exception("Bootloader Error (no response)"); + else + throw new Exception(String.format("Bootloader Error (unexpected response %s for page %s)", str, pageNr)); + } + catch (Exception ex) + { + throw ex; + } + + //System.out.println("page " + page + " ok"); + + return page; + } + + private void startBootloader (String cmd) throws Exception + { + byte [] response = new byte[4]; + int pos; + boolean error; + + flush(); + write('@'); + String str = readResponseString("@", 200); + + if (str == null || str.endsWith("@") == false) + throw new Exception("Bootloader entry with '@' failed"); + + //System.out.println("@ detected"); + + StringBuilder sb = new StringBuilder(16); + int ucRegUBRR0L = -1; + for (int i=1; i<cmd.length(); i++) + { + response[0] = (byte)cmd.charAt(i); + //System.out.println("write " + cmd.charAt(i) + " sb= '" + sb.toString() + "'"); + try { writeAndCheckResponse((byte) cmd.charAt(i), response, 0, 1); } + catch (Exception ex) + { + throw new Exception("unexpected response while download-start"); + } + + sb.append(cmd.charAt(i)); + if (sb.length()==4 && sb.toString().startsWith("@s")) + { + System.out.println("switch speed to " + sb); + ucRegUBRR0L = Integer.valueOf(sb.substring(2), 16); + } + + if (cmd.charAt(i) == '@') + sb.replace(0, sb.length(), "@"); + } + + if (ucRegUBRR0L>0) + { + write(10); + this.recentPortSpeed = this.setSerialPortSpeed(1000000/(ucRegUBRR0L+1)); + Thread.sleep(50); + } + else + { + response[0] = 13; response[1] = 10; response[2] = 'f'; response[3] = '>'; + try { writeAndCheckResponse((byte)10, response, 0, 4); } + catch (Exception ex) + { + throw new Exception("unexpected response after download-start"); + } + } + + //System.out.println("Init done " + this.bytesToString(this.inputBytes, 0, 4, true)); + } + + private void endBootloader (String endCmd) throws Exception + { + int pos; + boolean downloadOK = false; + + flush(); + try + { + write(endCmd); + if (recentPortSpeed >= 0) + { + Thread.sleep(100); + this.setSerialPortSpeed(recentPortSpeed); + recentPortSpeed = -1; + } + String str = readResponseString("X", 300); + + if (str==null) + throw new Exception("Error on Bootloader end command"); + + downloadOK = true; + // check now response of System + //str = this.readResponseString(">", 200); + //if (str.contains("Systemmonitor")) + // terminalArea.append(str + "\n\r>"); + terminalArea.append("\n\r"); + + //if (str.contains(">")) System.out.println("Download fertig"); + } + catch (Exception ex) + { + //System.out.println(ex.getMessage()); + if (downloadOK) + throw new Exception("Download ok, System liefert keine Antwort", ex); + else + throw ex; + } + + } + + + @SuppressWarnings("CallToNativeMethodWhileLocked") + private void writeAndCheckResponse (byte send, byte [] response, int offset, int len) throws Exception + { + int pos = 0; + + flush(); + write(send); + String str = readResponseString(len, 200); + if (str != null && str.length() == len) + return; + + throw new Exception("expect " + len + " Bytes, get " + this.available() + " Bytes"); +/* + try + { + + while (true) + { + synchronized (waitThread) + { + this.waitThread.wait(500); + if (lenInBuffer == pos) + throw new Exception("Timeout"); + pos = lenInBuffer; + if (pos > len) + { + lenInBuffer = 0; + String t = this.bytesToString(inputBytes, offset, pos, true); + throw new Exception("expect " + len + " Bytes, get " + pos + " Bytes"); + } + if (pos == len) + { + lenInBuffer = 0; + for (int i=0; i<len; i++) + { + //System.out.println("receive " + (char) inputBytes[i] + "(" + (int)inputBytes[i] + ")"); + if (inputBytes[i] != response[offset+i]) + { + StringBuilder sb = new StringBuilder(128); + sb.append("send ").append(send).append("(").append((int) send).append("), expect "); + for (int j=0; j<len; j++) + sb.append(response[offset+j]); + sb.append("get "); + for (int j=0; j<pos; j++) + sb.append(inputBytes[j]); + throw new Exception(sb.toString()); + } + } + return; + } + } // synchronized + + } + } + catch (IOException ex) + { + throw new Exception("write " + send + "(" + (int)send + ") - IOException " + ex.getMessage()); + } + * */ + + } + + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/serial/Protocol.java b/src/at/htlkaindorf/sx/EasyProgrammer/serial/Protocol.java new file mode 100644 index 0000000..517d715 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/serial/Protocol.java @@ -0,0 +1,566 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.htlkaindorf.sx.EasyProgrammer.serial; + +import at.htlkaindorf.sx.EasyProgrammer.logging.Logger; +import java.io.IOException; +import javax.swing.event.ChangeListener; + +/** + * + * @author Manfred Steiner + */ +public abstract class Protocol +{ + + private static final Logger LOG = Logger.getLogger(Protocol.class.getName()); + + protected enum BufferTyp { NOBUFFER, FIFO, RINGBUFFER }; + + private boolean connected; + private SerialInterface serialInterface; + private ChangeListener gui; + private byte [] receiveBuffer; + private boolean receiveBufferFull; + private int receiveBufferFullCounter; + private int posBufRead; + private int posBufWrite; + private BufferTyp typ; + private boolean receiveData; + private final Thread waitThread; + + + + + public Protocol (SerialInterface serialInterface) + { + this.serialInterface = serialInterface; + this.waitThread = Thread.currentThread(); + this.typ = BufferTyp.NOBUFFER; + this.receiveData = true; + } + + + public Protocol (SerialInterface serialInterface, int bufferSize, BufferTyp bufferTyp) + { + this.serialInterface = serialInterface; + this.waitThread = Thread.currentThread(); + this.typ = bufferTyp; + this.receiveData = true; + if (bufferSize > 0) + this.receiveBuffer = new byte [bufferSize+1]; + } + + + protected void setTyp(BufferTyp typ) + { + this.typ = typ; + } + + + public void setChangeListener(ChangeListener changeListener) + { + this.gui = changeListener; + } + + + protected void flush () + { + if (this.waitThread != null) + synchronized (this.waitThread) + { + this.posBufRead = 0; + this.posBufWrite = 0; + } + } + + + + public boolean isBootloaderDetetcted () + { + if (this.serialInterface != null) + return this.serialInterface.isBootloaderDetetcted(); + return false; + } + + + public void waitOnBootLoaderDetected (long timeout) throws InterruptedException + { + if (this.waitThread == null) + return; + + long end; + synchronized (this.waitThread) + { + end = System.currentTimeMillis() + timeout; + do + { + if (isBootloaderDetetcted() == true) + break; + this.waitThread.wait(end - System.currentTimeMillis()); + } + while (System.currentTimeMillis() < end); + } + //System.out.println("Bootloader detected (time=" + (System.currentTimeMillis() - end + timeout) + "ms)"); + } + + + protected int available () + { + if (this.waitThread != null) + { + synchronized (this.waitThread) + { + if (this.posBufWrite >= this.posBufRead) + return this.posBufWrite - this.posBufRead; + else + return this.posBufWrite + this.receiveBuffer.length - this.posBufRead; + } + } + throw new RuntimeException("available() only useable when buffer is used"); + } + + protected int waitOnResponse (int minBytes, long timeout) throws InterruptedException + { + if (this.waitThread == null) + throw new RuntimeException("waitOnResponse() only useable when buffer is used"); + + if (minBytes <= 0) + return 0; + + synchronized (this.waitThread) + { + for (;;) + { + int oldlen = (posBufWrite >= posBufRead) ? (posBufWrite - posBufRead) + : (posBufWrite + receiveBuffer.length - posBufRead); + if (oldlen >= minBytes) + return oldlen; + + this.waitThread.wait(timeout); + int newlen = (posBufWrite >= posBufRead) ? (posBufWrite - posBufRead) + : (posBufWrite + receiveBuffer.length - posBufRead); + //System.out.println("newlen = " + newlen); + if (newlen == oldlen) + return newlen; // timeout + } + } + } + + + protected String readResponseString (int size, long timeout) throws InterruptedException + { + if (size>=0) + waitOnResponse(size, timeout); + return readResponseString(size); + } + + protected int readResponseByte () + { + int c = -1; + synchronized (this.waitThread) + { + if (this.posBufRead != this.posBufWrite) + { + c = (int) this.receiveBuffer[this.posBufRead++]; + if (this.posBufRead >= receiveBuffer.length) + this.posBufRead = 0; + this.receiveBufferFull = false; + } + } + return c; + } + + protected String readResponseString (int size) + { + if (this.waitThread == null) + throw new RuntimeException("getResponseString() only useable when buffer is used"); + + String str; + synchronized (this.waitThread) + { + if (this.available() <= 0) + str = null; + else + { + if (size<0) + size = this.available(); + StringBuilder sb = new StringBuilder(size); + while (size>0) + { + int c = -1; + if (this.posBufRead != this.posBufWrite) + { + c = (int) this.receiveBuffer[this.posBufRead++]; + if (this.posBufRead >= receiveBuffer.length) + this.posBufRead = 0; + this.receiveBufferFull = false; + } + if (c>=0) + sb.append((char) c); + size--; + } + str = sb.toString(); + this.posBufRead = 0; + this.posBufWrite = 0; + } + } + return str; + } + + protected int findPatternPosition (String pattern) + { + if (this.waitThread == null) + throw new RuntimeException("waitThread == null"); + + if (pattern == null || pattern.length() <= 0) + return -1; + + int pos; + int i = 0; + + synchronized (this.waitThread) + { + pos = this.posBufRead; + while (pos != this.posBufWrite && i< pattern.length()) + { + if (this.receiveBuffer[pos] == pattern.charAt(i)) + { + i++; + } + else + { + pos = pos - i; + if (pos < 0) + pos = pos + receiveBuffer.length; + i = 0; + } + pos++; + if (pos >= receiveBuffer.length) + pos = 0; + } + } + if (i>=pattern.length()) + { + pos = pos - pattern.length(); + if (pos < 0) + pos = pos + receiveBuffer.length; + return pos; + } + return -1; + } + + protected String readResponseString (String pattern, long timeout) throws InterruptedException + { + if (this.waitThread == null) + throw new RuntimeException("waitThread == null"); + + int pos = -1; + long end = System.currentTimeMillis() + timeout; + + do + { + synchronized (this.waitThread) + { + pos = findPatternPosition(pattern); + if (pos < 0) + { + serialInterface.addInputDetector(pattern, this.waitThread); + //LOG.debug(String.format("waiting for pattern '%s'", pattern), 4); + this.waitThread.wait(timeout); + StringBuilder sb = new StringBuilder(); + try + { + for (int i=posBufRead; i!=posBufWrite; i++) + { + if (i>=receiveBuffer.length) + i = 0; + byte b = receiveBuffer[i]; + char c = (char)b; + if (Character.isISOControl(c)) + sb.append(String.format("<%02x>", b<0 ? b+256 : b)); + else + sb.append(c); + } + //LOG.debug(String.format("bytes received, '%s' in buffer, continue checking pattern", sb.toString())); + } + catch (Exception ex) + { + LOG.warning(ex); + } + } + } + } + while (pos < 0 && System.currentTimeMillis() < end); + + if (pos < 0) + { + // System.out.println("error " + this.available()); + return null; + } + + + int size = pos - this.posBufRead; + if (size < 0) + size = size + this.receiveBuffer.length; + size = size + pattern.length(); + return readResponseString(size); + } + + public void open (SerialInterface serialInterface) + { + this.serialInterface = serialInterface; + this.serialInterface.addProtocol(this); + } + + public void close () + { + this.serialInterface.removeProtocol(this); + this.serialInterface = null; + } + + + public boolean isReceiveData() + { + return receiveData; + } + + + public void setReceiveData(boolean receiveData) + { + this.receiveData = receiveData; + } + + + public void dataAvailable() + { + int b; + int free = 0; + + //LOG.debug(String.format("Bytes received")); + + if (receiveData == false || this.connected == false) + return; + + if (this.waitThread == null) + throw new RuntimeException("dataAvailable should be overridden"); + + switch (this.typ) + { + case FIFO: + do + { + if (free <= 0) + { + synchronized (waitThread) + { + free = free + posBufRead - posBufWrite - 1; + if (free < 0) + free = receiveBuffer.length; + if (free == 0) + { + this.receiveBufferFull = true; + this.receiveBufferFullCounter++; + waitThread.notify(); + return; + } + } + } + + b = -1; + try { b = read(); } + catch (Exception e) { e.printStackTrace(System.err); } + + if (b>=0 && b<255) + { + synchronized (waitThread) + { + receiveBuffer[posBufWrite++] = (byte) b; + if (posBufWrite >= receiveBuffer.length) + posBufWrite = 0; + free--; + //LOG.debug(String.format("Bytes received: %d free", free)); + waitThread.notify(); + } + } + } + while (b>=0 && b<=255); + break; + + + case RINGBUFFER: + try + { + b = read(); + while (b>=0 && b<=255) + { + char c = (b>=32 && b<127) ? (char)b : ' '; + //LOG.debug(String.format("Protocol: receive byte 0x%02x %c", b, c)); + //System.out.println("receive " + (char) b); + synchronized (waitThread) + { + int end = posBufWrite + 1; + if (end >= receiveBuffer.length) + end = 0; + receiveBuffer[posBufWrite] = (byte)b; + posBufWrite = end; + waitThread.notify(); + if (end == posBufRead) + posBufRead++; + if (posBufRead >= receiveBuffer.length) + posBufRead = 0; + } + b = read(); + } + } + catch (Exception ex) { ex.printStackTrace(System.err); } + + break; + + case NOBUFFER: + synchronized (waitThread) + { + try { this.serialInterface.read(this, null, 0, 0); } // remove all bytes from inputstream in SerialInterface + catch (Exception ex) { ex.printStackTrace(System.err); } + finally { waitThread.notify(); } + } + break; + } + } + + protected void wasDisconnected() + { + this.connected = false; + } + + + protected void wasConnected() + { + this.connected = true; + } + + + protected void paused() + { + this.connected = false; + } + + + protected void continued() + { + this.connected = true; + } + + + public boolean isConnected() + { + return connected; + } + + public void connect () throws Exception + { + if (this.serialInterface == null) + throw new Exception("Protocol: interface not open (serialInterface==null)"); + + this.serialInterface.addProtocol(this); + } + + public void disconnect () throws Exception + { + if (this.serialInterface == null) + throw new Exception("Protocol: interface not open (serialInterface==null)"); + + this.serialInterface.removeProtocol(this); + } + + public int setSerialPortSpeed (int baudrate) throws Exception + { + if (this.serialInterface == null) + throw new Exception("Protocol: interface not open (serialInterface==null)"); + + return serialInterface.setPortSpeed(baudrate); + } + + public int availableOnInput () throws Exception, IOException + { + if (this.serialInterface == null) + throw new Exception("Protocol: interface not open (serialInterface==null)"); + return serialInterface.availableOnInput(); + } + + public int read(byte[] b, int off, int len) throws Exception, IOException, NullPointerException + { + if (this.serialInterface == null) + throw new Exception("Protocol: interface not open (serialInterface==null)"); + return this.serialInterface.read(this, b, off, len); + } + + public int read() throws Exception, IOException, NullPointerException + { + if (this.serialInterface == null) + throw new Exception("Protocol: interface not open (serialInterface==null)"); + return this.serialInterface.read(this); + } + + public void write(int b) throws Exception + { + if (this.serialInterface == null) + throw new Exception("Protocol: interface not open (serialInterface==null)"); + this.serialInterface.write(this, b); + } + + public void write(byte[] b) throws Exception + { + if (this.serialInterface == null) + throw new Exception("Protocol: interface not open (serialInterface==null)"); + this.serialInterface.write(this, b); + } + + public void write(String s) throws Exception + { + if (this.serialInterface == null) + throw new Exception("Protocol: interface not open (serialInterface==null)"); + this.serialInterface.write(this, s); + } + + public void write(byte[] b, int off, int len) throws Exception + { + if (this.serialInterface == null) + throw new Exception("Protocol: interface not open (serialInterface==null)"); + this.serialInterface.write(this, b, off, len); + } + + public int toUnsignedByte (byte b) + { + return b<0 ? b+256 : b; + } + + public String bytesToString (byte [] b, int offset, int len, boolean withHex) + { + StringBuilder sb = new StringBuilder(32); + + for (int i=0; i<len; i++) + { + int val = toUnsignedByte(b[offset+i]); + if (val<32 || val>127) + sb.append("."); + else + sb.append((char) val); + } + if (withHex) + { + sb.append(" "); + for (int i=0; i<len; i++) + { + int val = toUnsignedByte(b[offset+i]); + sb.append(String.format(" %02x", val)); + } + } + + return sb.toString(); + } + + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/serial/ResetProtocol.java b/src/at/htlkaindorf/sx/EasyProgrammer/serial/ResetProtocol.java new file mode 100644 index 0000000..ba47958 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/serial/ResetProtocol.java @@ -0,0 +1,136 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.htlkaindorf.sx.EasyProgrammer.serial; + +import at.htlkaindorf.sx.EasyProgrammer.gui.TerminalArea; +import at.htlkaindorf.sx.EasyProgrammer.logging.Logger; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +/** + * + * @author steiner + */ +public class ResetProtocol extends Protocol +{ + + private static final Logger LOG = Logger.getLogger(ResetProtocol.class.getName()); + + private String bootloaderVersion; + protected TerminalArea terminalArea; + + public ResetProtocol (SerialInterface serialInterface, TerminalArea terminalArea) + { + //super(serialInterface, 128, Protocol.BufferTyp.RINGBUFFER); + super(serialInterface, 256, Protocol.BufferTyp.RINGBUFFER); + this.terminalArea = terminalArea; + this.open(serialInterface); + } + + + @Override + public void dataAvailable () + { + super.dataAvailable(); //To change body of generated methods, choose Tools | Templates. + } + + + + + public void reset (ChangeListener gui, boolean stayInBootloader, String resetCmd) throws Exception + { + //new Exception("Test").printStackTrace(System.err); + this.setChangeListener(gui); + boolean isResetSequence = resetCmd.endsWith("\r\n"); + if (isResetSequence) + resetCmd = resetCmd.substring(0, resetCmd.length()-2); + + if (isBootloaderDetetcted()) + { + if (terminalArea != null) + terminalArea.append("\n\r"); + } + else + { + String str = null; + int counter = 0; + boolean error; + + do + { + counter++; + error = false; + gui.stateChanged(new ChangeEvent("Sende Reset-Kommando '" + resetCmd + + (isResetSequence ? "\n\r" : "") + + "' (" + counter + ".Versuch)")); + if (isResetSequence) + { + write("\r\n"); + } + Thread.sleep(25); + flush(); + write(resetCmd.getBytes()); + if (isResetSequence) + { + write("\r\n"); + } + if (stayInBootloader == false) + gui.stateChanged(new ChangeEvent(25*counter)); + waitOnBootLoaderDetected(500); + str = readResponseString(-1, 1); + if (str==null || str.contains("Bootloader")==false) + { + error = true; + // target system in download mode, waiting for transfer of 128 bytes?? + for (int i=0; i<300; i++) + write('F'); + str = readResponseString(">", 300); + if (str == null && counter >= 3) + throw new Exception("no or unexpected system response"); + } + } + while (error); + + String [] msg = str.split("\r\n"); + for (String s : msg) + { + if (terminalArea != null && s != null && s.contains("Bootloader")) + { + terminalArea.append("\n\r"); + terminalArea.append(s); + terminalArea.append("\n\r"); + } + } + } + + if (stayInBootloader) + return; + + gui.stateChanged(new ChangeEvent(50)); + + if (isBootloaderDetetcted()) + { + gui.stateChanged(new ChangeEvent("Bootloader aktiv, sende @g Kommando")); + write("@g\n"); + gui.stateChanged(new ChangeEvent(75)); + String str = readResponseString("@g", 200); + gui.stateChanged(new ChangeEvent(100)); + terminalArea.append("\n\r"); + flush(); + + if (str == null || !str.contains("@g")) + { + LOG.warning("missing proper response on reset sequence"); + throw new Exception("reset sequence fails"); + } + + LOG.info("Reset sequence success."); + return; + } + } + + +} + diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/serial/SerialInterface.java b/src/at/htlkaindorf/sx/EasyProgrammer/serial/SerialInterface.java new file mode 100644 index 0000000..0550a5c --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/serial/SerialInterface.java @@ -0,0 +1,872 @@ +package at.htlkaindorf.sx.EasyProgrammer.serial; + +// for package gnu.io in linux: +// apt-get install librxtx-java +// Netbeans: Source Package - Properties - Libraries - Add JAR/Folder +// /usr/share/java/RXTXcomm.jar + + +//import gnu.io.*; +import at.htlkaindorf.sx.EasyProgrammer.data.ByteFifo; +import at.htlkaindorf.sx.EasyProgrammer.logging.Logger; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.util.*; +import java.util.concurrent.atomic.AtomicReference; +import jssc.SerialPort; +import jssc.SerialPortEvent; +import jssc.SerialPortException; + +/** + * Zugriff auf die serielle Schnittstelle.</BR> + * @author Manfred Steiner + */ +public final class SerialInterface +{ + private static final Logger LOG = Logger.getLogger(SerialInterface.class.getName()); + + public static Map<String, String> getLinuxPortProperties (String portName) + { + String os = System.getProperty("os.name").toLowerCase(); + Map<String, String> props = new HashMap<String, String>(); + if (!os.contains("linux")) + return props; + + try + { + // portName has the format /dev/ttyUSB0 + String dev = portName.split("/")[2]; + File sysfsNode = new File("/sys/bus/usb-serial/devices/" + dev); + + // resolve the symbolic link and store the resulting components in an array + String[] sysfsPath = sysfsNode.getCanonicalPath().split("/"); + + // walk the tree to the root + for (int i = sysfsPath.length - 2; i > 0; i--) + { + String curPath = "/"; + for (int j = 1; j <= i; j++) + { + curPath += sysfsPath[j] + "/"; + } + + // look for specific attributes + String[] attribs = + { + "idProduct", "idVendor", "manufacturer", "product", "serial" + }; + for (int j = 0; j < attribs.length; j++) + { + try + { + Scanner in = new Scanner(new FileReader(curPath + attribs[j])); + // we treat the values just as strings + props.put(attribs[j], in.next()); + } + catch (Exception e) + { + // ignore the attribute + } + } + + // stop once we have at least one attribute + if (props.size() > 0) + { + break; + } + + } + } + catch (Exception e) + { + // nothing to do, return what we have so far + } + + return props; + } + + private SerialPort port; + private int baudRate; + private int dataBits; + private int stopBits; + private int parity; + private SerialInputStream inputStream; + private SerialPortEventListener serialPortEventListener; + private ArrayList<SerialPortInfo> interfaceNameList; + private ArrayList<SerialPortInfo> availInterfaceList; + private ArrayList<Protocol> protocolList; + private int totalBytesRead; + //private boolean outputBufferEmpty; + private int dotCounter; + private long lastDotTime; + + private ArrayList <Character> history; + private Thread receiveThread; + private final ByteFifo receiveFifo = new ByteFifo(1024); + private Monitor monitor = null; //new Monitor(65536); + + + + public SerialInterface () throws Exception + { + interfaceNameList = new ArrayList<>(); + availInterfaceList = new ArrayList<>(); + protocolList = new ArrayList <Protocol>(); + serialPortEventListener = new SerialPortEventListener(); + //outputBufferEmpty = true; + history = new ArrayList <Character>(); + updateInterfaces(); // can cause an Exception if DLL not available + } + + public void printMonitor () + { + if (monitor != null) + monitor.print(System.out); + } + + + synchronized public void addProtocol (Protocol protocol) + { + if (protocolList.contains(protocol)) + protocolList.remove(protocol); + + LOG.fine("Adding protocol " + protocol.getClass().getSimpleName()); + + if (protocolList.size()>0) + protocolList.get(0).paused(); + protocolList.add(0, protocol); + if (this.isConnected()) + protocol.wasConnected(); + } + + synchronized public void removeProtocol (Protocol protocol) + { + protocolList.remove(protocol); + LOG.fine("removing protocol " + protocol.getClass().getSimpleName()); + + try + { + if (this.inputStream != null) + { + while (this.inputStream.available()>0) + this.inputStream.read(null); + } + } + catch (IOException ex) + { + ex.printStackTrace(System.err); + } + + if (protocolList.size()>0) + { + protocolList.get(0).continued(); + LOG.fine("switch back to protocol " + protocolList.get(0).getClass().getSimpleName()); + } + } + + /* + synchronized private void setOutputBufferEmpty (boolean value) + { + this.outputBufferEmpty = value; + } + * + */ + + public int availableOnInput () throws Exception,IOException + { + if (this.inputStream == null) + throw new Exception("SerialInterface: inputStream==null"); + return this.inputStream.available(); + } + + + +// public ArrayList<SerialPortInfo> getAvailInterfaceList() +// { +// return availInterfaceList; +// } + + + public ArrayList<SerialPortInfo> getInterfaceNameList() + { + return interfaceNameList; + } + + + public boolean isInterfaceAvailable (SerialPortInfo name) + { + return this.availInterfaceList.contains(name); + } + + + public boolean isConnected () + { + if (this.inputStream != null && this.port != null && this.port.isOpened()) + return true; + + return false; + } + + + public void updateInterfaces() throws Exception + { + interfaceNameList = new ArrayList<SerialPortInfo>(); + SerialPortInfoFactory.refresh(false); + String [] ports = jssc.SerialPortList.getPortNames(); + for (String name : ports) + interfaceNameList.add(SerialPortInfoFactory.getSerialPortInfo(name)); + +// LOG.debug("updateInterfaces"); +// System.out.print(" interfaceNameList:"); +// for (SerialPortInfo pi : interfaceNameList) +// System.out.print(" " + pi.toString()); +// System.out.println(); + } + + + public void checkInterfaces() throws Exception + { + availInterfaceList.addAll(interfaceNameList); +// LOG.debug("checkInterfaces"); +// System.out.print(" availInterfaceList:"); +// for (SerialPortInfo pi : availInterfaceList) +// System.out.print(" " + pi.toString()); +// System.out.println(); + + +// CommPortIdentifier portID; +// updateInterfaces(); // can throw an Exception if library not available +// availInterfaceList = new ArrayList<String>(); +// SerialPort sp; +// +// for (String name : interfaceNameList ) +// { +// try +// { +// portID = CommPortIdentifier.getPortIdentifier(name); +// if (portID.getPortType() != CommPortIdentifier.PORT_SERIAL) +// throw new RuntimeException("port list has a none serial port member"); +// else +// { +// if (port != null && port.getName().contains(name)) +// this.availInterfaceList.add(name); +// else +// { +// sp = (SerialPort) portID.open("EasyProgrammer", 500); +// sp.close(); +// sp = null; +// this.availInterfaceList.add(name); +// } +// } +// } +// catch (NoSuchPortException ex) +// { +// } +// catch (PortInUseException ex) +// { +// } +// } + } + + public int setPortSpeed (int baudRate) throws Exception + { + if (port == null) + throw new Exception("port not open"); + + if (baudRate != this.baudRate && port != null) + port.setParams(baudRate, dataBits, stopBits, parity); + + return baudRate; +// port.closePort(); +// CommPortIdentifier portID = CommPortIdentifier.getPortIdentifier("COM1"); +// port = (SerialPort) portID.open("EasyProgrammer", 1000); +// port.setSerialPortParams(baudrate, databits, stopbits, parity); +// this.inputStream = port.getInputStream(); +// this.outputStream = port.getOutputStream(); +// try +// { +// port.addEventListener(serialPortEventListener); +// //System.out.println("EventListener erfolgreich etabliert"); +// port.notifyOnDataAvailable(true); +// port.notifyOnOutputEmpty(true); +// } +// catch (TooManyListenersException e) +// { +// System.out.println("TooManyListenersException für Serialport"); +// } +// System.out.println("baudrate set to " + baudrate); +// return speed; + } + + public void connect (SerialPortInfo serialPortInfo) throws IOException + { + if (port != null) + throw new RuntimeException("Connect ... but interface is already connected"); + + totalBytesRead = 0; + + try + { + port = new jssc.SerialPort(serialPortInfo.getName()); + if (!port.openPort()) + throw new Exception("result of openPort() is false"); + } + catch (Exception ex) + { + port = null; + throw new IOException("cannot open port " + serialPortInfo.getName()); + } + + try + { + serialPortInfo.setJSSCSerialPortParams(port); + inputStream = new SerialInputStream(port); + for (Protocol protocol : protocolList) + protocol.wasConnected(); + + receiveThread = new Thread(new DataAvailableThread()); + receiveThread.start(); + port.addEventListener(serialPortEventListener); + } + catch (Exception ex) + { + IOException ioex = new IOException(ex); + ioex.printStackTrace(System.err); + try + { + if (!port.closePort()) + throw new SerialPortException(port.getPortName(), "closePort", ""); + throw ioex; + } + catch (SerialPortException e) + { + e.addSuppressed(ex); + ioex = new IOException(e); + } + port = null; + inputStream = null; + throw ioex; + } + } + + + public void disconnect() + { + if (port == null) + throw new IllegalStateException("Disconnect ... but interface is not connected"); + + for (Protocol protocol : this.protocolList) + protocol.wasDisconnected(); + + try + { + if (!port.closePort()) + throw new SerialPortException(port.getPortName(), "closePort", "closePort return value false"); + } + catch (Exception ex) + { + ex.printStackTrace(System.err); + } + finally + { + inputStream = null; + port = null; + totalBytesRead = 0; + if (receiveThread != null) + receiveThread.interrupt(); + receiveThread = null; + } + + } + + + private void detectBootloader (int b) + { + if ((char)b != '.') + { + this.dotCounter = 0; + this.lastDotTime = 0; + return; + } + if (this.lastDotTime==0) + { + this.dotCounter = 0; + this.lastDotTime = System.nanoTime(); + } + else + { + long time = System.nanoTime(); + long dt = Math.abs((time-this.lastDotTime)/1048576); + if (dt>=35 && dt<=55) + this.dotCounter++; + else + this.dotCounter=0; + this.lastDotTime = System.nanoTime(); + } + } + + public boolean isBootloaderDetetcted () + { + long dt = 0; + + if (this.lastDotTime != 0) + { + long time = System.nanoTime(); + dt = Math.abs((time-this.lastDotTime)/1048576); + if (dt<=55 && this.dotCounter > 2) + return true; + } + if (dt>55) + this.dotCounter = 0; + + return false; + } + + private void checkProtocol (Object source) + { + if (!(source instanceof Protocol)) + System.out.println("ERROR"); + else if (((Protocol)source) != protocolList.get(0)) + System.out.println("Wrong Protocol"); + } + + + public int read (Object source, byte[] b, int off, int len) throws Exception, IOException, NullPointerException + { + checkProtocol(source); + if (inputStream == null) + throw new Exception("SerialInterface: inputStream==null"); + if (b==null || len<=0) + { + while(inputStream.read(source) >= 0); + return 0; + } + int rv = 0; + for (int i=0; len>0; i++, len--) + { + int x = inputStream.read(source); + if (x<0) + return rv; + b[i] = (byte) x; + rv++; + } + return inputStream.read(b, off, len); + } + + public int read (Object source) throws Exception, IOException + { + int b; + + if (inputStream == null) + throw new Exception("SerialInterface: inputStream==null"); + if (inputStream.available()>0) + b = inputStream.read(source); + else + b = -1; + + if (b>=0) + { + detectBootloader(b); +/* + history.add((char)b); + if (b==':') + { + String s = ""; + for (int i=0; i<history.size(); i++) + { + Character c = history.get(i); + System.out.print(String.format(" %02x", (int)c)); + if (Character.isLetterOrDigit(c)) + s = s + c; + else + s = s + "."; + if (i % 16 == 0) + { + System.out.println(" " + s); + s = ""; + } + } + System.out.println(""); + } + * + */ + } + return b; + } + + public SerialPort getPort() + { + return port; + } + + public void write (Object source, char c) + { + if (port==null || !port.isOpened()) + return; + try + { + if (!port.writeByte((byte)c)) + throw new IOException(); + if (monitor != null) + monitor.addWriteByte(source, (byte)c); + } + catch (Exception ex) + { + LOG.warning(ex); + } + } + + public void write(Object source, int b) throws Exception, IOException + { + if (port==null || !port.isOpened()) + return; + try + { + if (!port.writeByte((byte)b)) + throw new IOException(); + if (monitor != null) + monitor.addWriteByte(source, (byte)b); + } + catch (Exception ex) + { + LOG.warning(ex); + } + } + + public void write(Object source, byte[] ba) throws Exception, IOException + { + if (port==null || !port.isOpened()) + return; + try + { + if (!port.writeBytes(ba)) + throw new IOException(); + if (monitor != null) + { + for (byte b : ba) + monitor.addWriteByte(source, b); + } + } + catch (Exception ex) + { + LOG.warning(ex); + } + } + + public void write(Object source, byte[] ba, int off, int len) throws Exception, IOException + { + write(source, Arrays.copyOfRange(ba, off, off+len)); + } + + public void write (Object source, String s) throws Exception + { + write(source, s.getBytes()); + } + + + + public void write (Object source, Object obj) throws Exception + { + if (obj instanceof String) + { + write (source, (String) obj); + } + else if(obj instanceof byte[]) + { + try + { + write (source, (byte []) obj); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw new RuntimeException(e.getMessage()); + } + } + else + throw new RuntimeException("Not supported object type"); + } + + + public DebugOutputStream getDebugOutputStream () + { + //if (this.outputStream != null && this.outputStream instanceof DebugOutputStream) + // return (DebugOutputStream) this.outputStream; + return null; + } + + + public Monitor getMonitor () + { + return monitor; + } + + private class InputNotification + { + private final Object toNotifyObject; + private final String pattern; + private int i; + + public InputNotification (String pattern, Object toNotifyObject) + { + this.toNotifyObject = toNotifyObject; + this.pattern = pattern; + } + + private void put (char b) + { + if (pattern.charAt(i) == b) + i++; + else + i = 0; + if (i>=pattern.length()) + { + i = 0; + if (toNotifyObject != null) + { + synchronized (toNotifyObject) + { + toNotifyObject.notify(); + } + } + } + } + + } + + private final AtomicReference<InputNotification> inputNotification = new AtomicReference<>(); + + public void addInputDetector (String pattern, Object toNotify) + { + inputNotification.set(new InputNotification(pattern, toNotify)); + } + + + private class DataAvailableThread implements Runnable + { + + @Override + public void run () + { + LOG.finer("Start of DataAvailableThread"); + try + { + synchronized (receiveFifo) + { + while (!Thread.interrupted()) + { + int n = receiveFifo.available(); + if (protocolList.size()>0 && n>0) + { + LOG.finest(String.format("%d bytes available in receive FIFO", n)); + protocolList.get(0).dataAvailable(); + } + try + { + receiveFifo.wait(); + } + catch (InterruptedException ex) + { + break; + } + } + } + } + finally + { + LOG.finer("End of DataAvailableThread"); + } + } + + } + + /** + * + * @author steiner + */ + public class SerialPortEventListener implements jssc.SerialPortEventListener + { + @Override + public void serialEvent (SerialPortEvent spe) + { + if (spe.isRXCHAR()) + { + try + { + byte [] ba = port.readBytes(); + receiveFifo.push(ba); + synchronized (receiveFifo) + { + receiveFifo.notify(); + } + } + catch (Exception ex) + { + LOG.warning(ex); + } + } + } + } + + private class SerialInputStream extends InputStream + { + private final SerialPort port; + + public SerialInputStream (SerialPort port) + { + this.port = port; + } + + @Override + public int available () throws IOException + { + try + { + //return port.getInputBufferBytesCount(); + return receiveFifo.available(); + } + catch (Exception ex) + { + throw new IOException(ex); + } + } + + + public int read (Object source) throws IOException + { + if (receiveFifo.available()<=0) + return -1; + + int b = receiveFifo.pop(); + if (b>=0) + { + if (monitor != null) + monitor.addReadByte(source, b); + } + + return b; + } + + @Override + public int read () throws IOException + { + IOException ex = new IOException("wrong method"); + ex.printStackTrace(System.out); + return read((Object)null); + } + } + + + public class Monitor + { + private final long [] wTimeStamp; + private final long [] rTimeStamp; + private final Object [] wSource; + private final Object [] rSource; + private int wIndex; + private int rIndex; + private final byte [] w; + private final byte [] r; + + + public Monitor (int size) + { + wTimeStamp = new long [size]; + rTimeStamp = new long [size]; + wSource = new Object [size]; + rSource = new Object [size]; + w = new byte [size]; + r = new byte [size]; + } + + public synchronized void addWriteByte (Object source, int b) + { + //LOG.debug(String.format("writing %02x %c", b, (b>=32 && b<127) ? (char)b : ' '), 5); + if (wIndex<w.length) + { + wTimeStamp[wIndex] = System.currentTimeMillis(); + wSource[wIndex] = source; + w[wIndex++] = (byte)(b>=128 ? b-256 : b); + } + } + + public synchronized void addWriteByte (Object source, byte b) + { + //LOG.debug(String.format("writing %02x %c", b<0 ? b+256: b, (b>=32 && b<127) ? (char)b : ' '), 5); + if (wIndex<w.length) + { + wTimeStamp[wIndex] = System.currentTimeMillis(); + wSource[wIndex] = source; + w[wIndex++] = b; + } + } + + public synchronized void addReadByte (Object source, int b) + { + if (rIndex<r.length) + { + rTimeStamp[rIndex] = System.currentTimeMillis(); + rSource[rIndex] = source; + r[rIndex++] = (byte)(b>=128 ? b-256 : b); + } + } + + public synchronized void addReadByte (Object source, byte b) + { + if (rIndex<r.length) + { + rTimeStamp[rIndex] = System.currentTimeMillis(); + rSource[rIndex] = source; + r[rIndex++] = b; + } + } + + public void print (PrintStream s) + { + int ri=0, wi=0; + long tStart = 0; + if (wIndex>0) tStart = wTimeStamp[0]; + if (rIndex>0) tStart = Math.min(tStart, rTimeStamp[0]); + + while (true) + { + if (ri>=rIndex && wi>=wIndex) + return; + + long wts = wi<wIndex ? wTimeStamp[wi] : Long.MAX_VALUE; + long rts = ri<rIndex ? rTimeStamp[ri] : Long.MAX_VALUE; + + if (rts<wts) + { + long dt = rts-tStart; + s.append(String.format("%6dms: ", dt)); + int b = r[ri]<0 ? ((int)r[ri])+256 : ((int)r[ri]); + char c = (b>=32 && b<127) ? (char)b : ' '; + s.append(String.format("%c %02x ", c, b)); + if (rSource[ri]!=null) + s.append(String.format("%35s", rSource[ri].getClass().getSimpleName())); + s.println(); + ri++; + } + else + { + long dt = wts-tStart; + s.append(String.format("%6dms: ", dt)); + int b = w[wi]<0 ? ((int)w[wi])+256 : ((int)w[wi]); + char c = (b>=32 && b<127) ? (char)b : ' '; + s.append(String.format(" %c %02x ", c, b)); + if (wSource[wi]!=null) + s.append(String.format("%s", wSource[wi].getClass().getSimpleName())); + s.println(); + wi++; + } + } + } + + } + + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/serial/SerialPortInfo.java b/src/at/htlkaindorf/sx/EasyProgrammer/serial/SerialPortInfo.java new file mode 100644 index 0000000..4b67236 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/serial/SerialPortInfo.java @@ -0,0 +1,28 @@ +package at.htlkaindorf.sx.EasyProgrammer.serial; + + +/** + * + * @author steiner + */ +public abstract class SerialPortInfo implements Comparable +{ + public abstract String getName (); + public abstract String getPID (); + public abstract String getVID (); + public abstract String getManufacturer (); + public abstract String getSerialNumber (); + public abstract String getProductName (); + public abstract String [] getSupportedBaudrates(); + public abstract String [] getSupportedStopBits(); + public abstract String [] getSupportedDatabits(); + public abstract String [] getSupportedParityModes(); + public abstract int getBaudrateIndex(); + public abstract int getStopBitIndex(); + public abstract int getDatabitIndex(); + public abstract int getParityModeIndex(); + public abstract String getConfigString (); + public abstract void setConfiguration (String config) throws IllegalArgumentException; + public abstract void setConfiguration (String baudRate, String dataBits, String parityMode, String stopBits) throws IllegalArgumentException; + public abstract boolean setJSSCSerialPortParams (jssc.SerialPort port) throws jssc.SerialPortException; +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/serial/SerialPortInfoFactory.java b/src/at/htlkaindorf/sx/EasyProgrammer/serial/SerialPortInfoFactory.java new file mode 100644 index 0000000..a55c980 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/serial/SerialPortInfoFactory.java @@ -0,0 +1,573 @@ +package at.htlkaindorf.sx.EasyProgrammer.serial; + +import at.htlkaindorf.sx.EasyProgrammer.logging.Logger; +import java.io.File; +import java.io.FileReader; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Scanner; +import java.util.TreeMap; +import jssc.SerialPortList; + + +/** + * + * @author steiner + */ +public class SerialPortInfoFactory +{ + private static final Logger LOG = Logger.getLogger(SerialPortInfoFactory.class.getName()); + private static final String[] ATTRIBUTES = { "idProduct", "idVendor", "manufacturer", "product", "serial" }; + + private final static LinkedHashMap<String,Integer> jsscBaudrates = new LinkedHashMap<>(); + private final static LinkedHashMap<String,Integer> jsscDatabits = new LinkedHashMap<>(); + private final static LinkedHashMap<String,Integer> jsscStopBits = new LinkedHashMap<>(); + private final static LinkedHashMap<String,Integer> jsscParityModes = new LinkedHashMap<>(); + + private final static String [] jsscSupportedBaudrates; + private final static String [] jsscSupportedDatabits; + private final static String [] jsscSupportedStopBits; + private final static String [] jsscSupportedParityModes; + + static + { + jsscBaudrates.put( "110", jssc.SerialPort.BAUDRATE_110); + jsscBaudrates.put( "300", jssc.SerialPort.BAUDRATE_300); + jsscBaudrates.put( "600", jssc.SerialPort.BAUDRATE_600); + jsscBaudrates.put( "1200", jssc.SerialPort.BAUDRATE_1200); + jsscBaudrates.put( "4800", jssc.SerialPort.BAUDRATE_4800); + jsscBaudrates.put( "9600", jssc.SerialPort.BAUDRATE_9600); + jsscBaudrates.put( "14400", jssc.SerialPort.BAUDRATE_14400); + jsscBaudrates.put( "19200", jssc.SerialPort.BAUDRATE_19200); + jsscBaudrates.put( "38400", jssc.SerialPort.BAUDRATE_38400); + jsscBaudrates.put( "57600", jssc.SerialPort.BAUDRATE_57600); + jsscBaudrates.put("115200", jssc.SerialPort.BAUDRATE_115200); + jsscBaudrates.put("128000", jssc.SerialPort.BAUDRATE_128000); + jsscBaudrates.put("256000", jssc.SerialPort.BAUDRATE_256000); + + jsscDatabits.put("5", jssc.SerialPort.DATABITS_5); + jsscDatabits.put("6", jssc.SerialPort.DATABITS_6); + jsscDatabits.put("7", jssc.SerialPort.DATABITS_7); + jsscDatabits.put("8", jssc.SerialPort.DATABITS_8); + + jsscStopBits.put( "1", jssc.SerialPort.STOPBITS_1); + jsscStopBits.put("1.5", jssc.SerialPort.STOPBITS_1_5); + jsscStopBits.put( "2", jssc.SerialPort.STOPBITS_2); + + jsscParityModes.put("N", jssc.SerialPort.PARITY_NONE); + jsscParityModes.put("E", jssc.SerialPort.PARITY_EVEN); + jsscParityModes.put("O", jssc.SerialPort.PARITY_ODD); + jsscParityModes.put("S", jssc.SerialPort.PARITY_SPACE); + jsscParityModes.put("M", jssc.SerialPort.PARITY_MARK); + + jsscSupportedBaudrates = jsscBaudrates.keySet().toArray(new String[0]); + jsscSupportedDatabits = jsscDatabits.keySet().toArray(new String[0]); + jsscSupportedStopBits = jsscStopBits.keySet().toArray(new String[0]); + jsscSupportedParityModes = jsscParityModes.keySet().toArray(new String[0]); + + } + + + private static SerialPortInfoFactory instance; + +// public static SerialPortName getSerialPortName (String name, Map<String, String> properties) +// { +// if (instance == null) +// instance = new SerialPortNameFactory(); +// return instance.findSerialPortName(name, properties); +// } + + public static SerialPortInfo getSerialPortInfo (String name) + { + if (instance == null) + instance = new SerialPortInfoFactory(); + SerialPortInfo rv = instance.findSerialPortInfo(name); + //LOG.debug(String.format("getSerialPortName(%s)->%d", name, rv.hashCode())); + return rv; + } + + public static SerialPortInfo getSerialPortInfo (String name, String config) + { + if (instance == null) + instance = new SerialPortInfoFactory(); + SerialPortInfo rv = instance.findSerialPortInfo(name, config); + //LOG.debug(String.format("getSerialPortInfo(%s,%s)->%d", name, config, rv.hashCode())); + return rv; + } + + public static SerialPortInfo getSerialPortInfo (String name, String baudRate, String dataBits, String parityMode, String stopBits) + { + if (instance == null) + instance = new SerialPortInfoFactory(); + SerialPortInfo rv = instance.findSerialPortInfo(name, baudRate, dataBits, parityMode, stopBits); + return rv; + } + + public static void refresh (boolean allowRemovement) + { + if (instance == null) + instance = new SerialPortInfoFactory(); + instance.refreshPortInfoMap(allowRemovement); + } + + + public static void updateSerialPortProperties (String portName, Map<String,String> properties) + { + String os = System.getProperty("os.name").toLowerCase(); + if (!os.contains("linux")) + { + properties.clear(); + return; + } + + try + { + // portName has the format /dev/ttyUSB0 + String dev = portName.split("/")[2]; + File sysfsNode = new File("/sys/bus/usb-serial/devices/" + dev); + + // resolve the symbolic link and store the resulting components in an array + String[] sysfsPath = sysfsNode.getCanonicalPath().split("/"); + + // walk the tree to the root + for (int i = sysfsPath.length - 2; i > 0; i--) + { + String curPath = "/"; + for (int j = 1; j <= i; j++) + { + curPath += sysfsPath[j] + "/"; + } + + // look for specific attributes + for (String att : ATTRIBUTES) + { + File f = new File(curPath + att); + if (!f.canRead()) + { + properties.remove(att); + continue; + } + try + { + Scanner in = new Scanner(new FileReader(f)); + // we treat the values just as strings + String value = in.next(); + if (!value.equals(properties.get(att))) + properties.put(att, value); + } + catch (Exception e) + { + // ignore the attribute + } + } + + // stop once we have at least one attribute + if (!properties.isEmpty()) + break; + + } + } + catch (Exception e) + { + // nothing to do, return what we have so far + } + } + + + + + + + private final HashMap<String, SerialPortInfo> map = new HashMap<>(); + + + private SerialPortInfoFactory () + { + } + + public void refreshPortInfoMap (boolean allowRemovement) + { + List<SerialPortInfo> avail = new LinkedList<>(); + String [] ports = jssc.SerialPortList.getPortNames(); + synchronized (this) + { + for (String port : ports) + { + SerialPortInfo pi; + if (map.containsKey(port)) + pi = map.get(port); + else + pi = new JSSCSerialPortInfo(port); + if (pi instanceof JSSCSerialPortInfo) + ((JSSCSerialPortInfo)pi).refreshProperties(); + avail.add(pi); + } + for (String n : map.keySet()) + { + SerialPortInfo pi = map.get(n); + if (!avail.contains(pi)) + { + if (allowRemovement) + map.remove(pi); + else + if (pi instanceof JSSCSerialPortInfo) + ((JSSCSerialPortInfo)pi).removeProperties(); + } + } + } + } + + private SerialPortInfo findSerialPortInfo (String name) + { + SerialPortInfo rv; + + if (map.containsKey(name)) + rv = map.get(name); + else + { + rv = new JSSCSerialPortInfo(name); + map.put(name, rv); + } + return rv; + } + + + private SerialPortInfo findSerialPortInfo (String name, String config) + { + SerialPortInfo rv; + + if (map.containsKey(name)) + { + rv = map.get(name); + rv.setConfiguration(config); + } + else + { + rv = new JSSCSerialPortInfo(name, config); + map.put(name, rv); + } + return rv; + } + + + private SerialPortInfo findSerialPortInfo (String name, String baudRate, String dataBits, String parityMode, String stopBits) + { + SerialPortInfo rv; + + if (map.containsKey(name)) + { + rv = map.get(name); + rv.setConfiguration(baudRate, dataBits, parityMode, stopBits); + } + else + { + rv = new JSSCSerialPortInfo(name); + rv.setConfiguration(baudRate, dataBits, parityMode, stopBits); + map.put(name, rv); + } + return rv; + } + + + public class JSSCSerialPortInfo extends SerialPortInfo + { + private final String name; + private final Map<String, String> properties; + private int baudRate; + private int dataBits; + private int parity; + private int stopBits; + private String cachedConfigString; + + + private JSSCSerialPortInfo (String name) + { + this.name = name; + baudRate = jssc.SerialPort.BAUDRATE_57600; + dataBits = jssc.SerialPort.DATABITS_8; + parity = jssc.SerialPort.PARITY_NONE; + stopBits = jssc.SerialPort.STOPBITS_1; + properties = new HashMap<>(); + updateSerialPortProperties(name, properties); + } + + + private JSSCSerialPortInfo (String name, String config) + { + this(name); + setConfiguration(config); + } + + + public void updateProperties () + { + updateSerialPortProperties(name, properties); + } + + + @Override + public String getName () + { + return name; + } + + + @Override + public String getPID () + { + return properties.get("idProduct"); + } + + @Override + public String getVID () + { + return properties.get("idVendor"); + } + + @Override + public String getManufacturer () + { + return properties.get("manufacturer"); + } + + @Override + public String getSerialNumber () + { + return properties.get("serial"); + } + + @Override + public String getProductName () + { + return properties.get("product"); + } + + private String findKey (Map<String,Integer> m, int value) throws IllegalArgumentException + { + for (String k : m.keySet()) + { + if (m.get(k) == value) + return k; + } + throw new IllegalArgumentException(String.format("Key not found for value %d", value)); + } + + @Override + public String getConfigString () + { + if (cachedConfigString==null) + { + try + { + String b = findKey(jsscBaudrates, baudRate); + String d = findKey(jsscDatabits, dataBits); + String p = findKey(jsscParityModes, parity); + String s = findKey(jsscStopBits, stopBits); + cachedConfigString = String.format("%s/%s%s%s", b, d, p, s); + } + catch (Exception ex) + { + LOG.warning(ex); + cachedConfigString="?/???"; + } + } + return cachedConfigString; + } + + + @Override + public void setConfiguration (String shortConfig) throws IllegalArgumentException + { + try + { + int b, d, p, s; + + if (!shortConfig.contains("/")) + { + b = jsscBaudrates.get(shortConfig); + d = jssc.SerialPort.DATABITS_8; + p = jssc.SerialPort.PARITY_NONE; + s = jssc.SerialPort.STOPBITS_1; + } + else + { + String [] str = shortConfig.split("/"); + b = jsscBaudrates.get(str[0]); + d = jsscDatabits.get(str[1].substring(0,1)); + p = jsscParityModes.get(str[1].substring(1,2)); + s = jsscStopBits.get(str[1].substring(2)); + } + + synchronized (this) + { + if (b!=baudRate || d!=dataBits || parity!=p || stopBits!=s) + { + cachedConfigString = null; + baudRate = b; + dataBits = d; + parity = p; + stopBits = s; + } + } + } + catch (Exception ex) + { + throw new IllegalArgumentException(String.format("Unvalid serial configuration '%s'", shortConfig), ex); + } + } + + + + @Override + public void setConfiguration (String baudRate, String dataBits, String parityMode, String stopBits) throws IllegalArgumentException + { + try + { + int b = jsscBaudrates.get(baudRate); + int d = jsscDatabits.get(dataBits); + int p = jsscParityModes.get(parityMode); + int s = jsscStopBits.get(stopBits); + + synchronized (this) + { + cachedConfigString = null; + this.baudRate = b; + this.dataBits = d; + this.parity = p; + this.stopBits = s; + } + } + catch (Exception ex) + { + throw new IllegalArgumentException("Unvalid serial configuration", ex); + } + } + + + @Override + public String[] getSupportedBaudrates () + { + return jsscSupportedBaudrates; + } + + + @Override + public String[] getSupportedStopBits () + { + return jsscSupportedStopBits; + } + + + @Override + public String[] getSupportedDatabits () + { + return jsscSupportedDatabits; + } + + + @Override + public String[] getSupportedParityModes () + { + return jsscSupportedParityModes; + } + + + @Override + public boolean setJSSCSerialPortParams (jssc.SerialPort port) throws jssc.SerialPortException + { + return port.setParams(baudRate, dataBits, stopBits, parity); + } + + + @Override + public int getBaudrateIndex () + { + for (int i=0; i<jsscSupportedBaudrates.length; i++) + { + if (jsscBaudrates.get(jsscSupportedBaudrates[i]) == baudRate) + return i; + } + return -1; + } + + + @Override + public int getStopBitIndex () + { + for (int i=0; i<jsscSupportedStopBits.length; i++) + { + if (jsscStopBits.get(jsscSupportedStopBits[i]) == stopBits) + return i; + } + return -1; + } + + + @Override + public int getDatabitIndex () + { + for (int i=0; i<jsscSupportedDatabits.length; i++) + { + if (jsscDatabits.get(jsscSupportedDatabits[i]) == dataBits) + return i; + } + return -1; + } + + + @Override + public int getParityModeIndex () + { + for (int i=0; i<jsscSupportedParityModes.length; i++) + { + if (jsscParityModes.get(jsscSupportedParityModes[i]) == parity) + return i; + } + return -1; + } + + + + @Override + public String toString () + { + String n = getProductName(); + if (n != null && !n.isEmpty()) + return String.format("%s (%s)", name, n); + else + return name; + } + + + @Override + public int compareTo (Object o) + { + if (o==null) + throw new NullPointerException(); + if (!(o instanceof SerialPortInfo)) + throw new IllegalArgumentException("wrong class or interface"); + return this.getName().compareTo(((SerialPortInfo)o).getName()); + } + + + private void refreshProperties () + { + properties.clear(); + updateSerialPortProperties(name, properties); + cachedConfigString = null; + } + + + private void removeProperties () + { + properties.clear(); + cachedConfigString = null; + } + + } +} + + diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/serial/TerminalProtocol.java b/src/at/htlkaindorf/sx/EasyProgrammer/serial/TerminalProtocol.java new file mode 100644 index 0000000..8b5a623 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/serial/TerminalProtocol.java @@ -0,0 +1,110 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.htlkaindorf.sx.EasyProgrammer.serial; + +import at.htlkaindorf.sx.EasyProgrammer.gui.TerminalArea; +import java.io.IOException; + +/** + * + * @author steiner + */ +public class TerminalProtocol extends Protocol +{ + private TerminalArea terminalArea; + + private long totalBytesRead; + private long tempBytesRead; + private boolean connected; + + + + public TerminalProtocol (TerminalArea terminalArea, SerialInterface serialInterface) + { + super(serialInterface); + this.terminalArea = terminalArea; + this.open(serialInterface); + } + + + public void execCommand (String command) + { + System.out.println(command); + } + + + @Override + public void paused() + { + //System.out.println("Terminal paused"); + this.connected = false; + } + + + @Override + public void continued() + { + //System.out.println("Terminal continued"); + dataAvailable(); + this.connected = true; + } + + + @Override + public void dataAvailable() + { + try + { + int b; + byte[] data = new byte[128]; + int num; + + b = read(); + while (b>=0 && b<=255) + { + terminalArea.append((char)b); + totalBytesRead++; + if ((totalBytesRead - tempBytesRead)>400 && availableOnInput()>500) + { + System.err.println("Serial: " + totalBytesRead + " Bytes empfangen avail=" + availableOnInput()); + tempBytesRead = totalBytesRead; + } + b = read(); + } + } + catch (IOException ex) + { + System.out.println("TerminalProtocol: Fehler beim Lesen empfangener Daten"); + ex.printStackTrace(System.err); + } + catch (Exception ex) + { + System.out.println("TerminalProtocol: Fehler beim Lesen empfangener Daten"); + ex.printStackTrace(System.err); + } + } + + + @Override + public void wasDisconnected() + { + this.connected = false; + } + + + @Override + public void wasConnected() + { + this.connected = true; + } + + + @Override + public boolean isConnected() + { + return this.connected; + } + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/server/IDEServer.java b/src/at/htlkaindorf/sx/EasyProgrammer/server/IDEServer.java new file mode 100644 index 0000000..94a1a95 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/server/IDEServer.java @@ -0,0 +1,69 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.htlkaindorf.sx.EasyProgrammer.server; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PipedReader; +import java.io.PipedWriter; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author steiner + */ +public class IDEServer +{ + private ServerSocket serverSocket; + private int port; + private Socket socket; + + public IDEServer (int port) throws IOException + { + this.port = port; + this.serverSocket = new ServerSocket (port); + System.out.println("IDEServer auf port " + port + " gestartet"); + } + + public String getRequest () throws IOException + { + if (this.serverSocket == null) + throw new IOException("Server not running"); + + if (this.socket != null) + throw new IOException("Request pending"); + + socket = this.serverSocket.accept(); + final BufferedReader reader = new BufferedReader (new InputStreamReader(socket.getInputStream())); + final String request = reader.readLine(); + return request; + } + + public void send (String answer) throws IOException + { + if (this.socket == null) + throw new IOException("Cannot send answer becaus no request pending"); + + final BufferedWriter writer = new BufferedWriter (new OutputStreamWriter(socket.getOutputStream())); + writer.write(answer); writer.newLine(); writer.flush(); + this.socket = null; + } + + public void stop () throws Exception + { + if (this.serverSocket == null) + throw new Exception("Server not running"); + + this.serverSocket.close(); + System.out.println("IDEServer beendet"); + } + +} diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/server/SimpleClient.java b/src/at/htlkaindorf/sx/EasyProgrammer/server/SimpleClient.java new file mode 100644 index 0000000..d79fdb6 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/server/SimpleClient.java @@ -0,0 +1,74 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.htlkaindorf.sx.EasyProgrammer.server; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.net.InetAddress; +import java.net.Socket; + +/** + * + * @author steiner + */ +public class SimpleClient +{ + + public static String sendRequestAndReceiveAnswer(String host, int port, String request) throws Exception + { + Socket socket = null; + try + { + final InetAddress address = InetAddress.getByName(host); + socket = new Socket(address, port); + final BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); + final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); + + // sende Anfrage + writer.write(request); + writer.newLine(); + writer.flush(); + System.out.println("Client (Codeblocks): Befehl an den Server gesendet, warte auf Antwort..."); + return reader.readLine(); + } + catch (Exception e) + { + } + finally + { + if (socket != null) + { + socket.close(); + } + socket = null; + } + + return null; + } + + + public static void main (String[] args) + { + try + { + String antwort = sendRequestAndReceiveAnswer("localhost", 4711, "connect"); + System.out.println("Antwort vom Server: " + antwort); + Thread.sleep(2000); + antwort = sendRequestAndReceiveAnswer("localhost", 4711, "download"); + System.out.println("Antwort vom Server: " + antwort); + Thread.sleep(5000); + antwort = sendRequestAndReceiveAnswer("localhost", 4711, "download"); + System.out.println("Antwort vom Server: " + antwort); + + } + catch (Exception e) + { + e.printStackTrace(System.err); + } + } + +} \ No newline at end of file diff --git a/src/at/htlkaindorf/sx/EasyProgrammer/server/SimpleServer.java b/src/at/htlkaindorf/sx/EasyProgrammer/server/SimpleServer.java new file mode 100644 index 0000000..dfc2e52 --- /dev/null +++ b/src/at/htlkaindorf/sx/EasyProgrammer/server/SimpleServer.java @@ -0,0 +1,197 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.htlkaindorf.sx.EasyProgrammer.server; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PipedReader; +import java.io.PipedWriter; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Serverapplikation für eine Server/client Anwendung. + * @author steiner + * Verwendet wird die Klasse ServerSocket, der Konstruktor mit dem port + * und die Methode accept, die wartet bis ein client eine Verbindugn aufgenommen + * hat + */ +public class SimpleServer +{ + private ServerSocket serverSocket; + private int port; + private SimpleServerThread thread = null; + private PipedWriter outPipe; + private BufferedReader inPipeReader; + private PipedReader inPipe; + + private class HandleRequestThread extends Thread + { + Socket socket; + + + public HandleRequestThread(Socket socket) + { + this.socket = socket; + } + + @Override + public void run() + { + System.out.println("HandleRequest: Thread gestartet"); + try + { + final BufferedReader reader = new BufferedReader (new InputStreamReader(socket.getInputStream())); + final BufferedWriter writer = new BufferedWriter (new OutputStreamWriter(socket.getOutputStream())); + final String anfrage = reader.readLine(); + writer.write(createAnswer(anfrage)); writer.newLine(); writer.flush(); + } + catch (Exception e) + { + } + System.out.println("HandleRequest: Thread beendet"); + } + } + + + private class SimpleServerThread extends Thread + { + @Override + public void run() + { + System.out.println("Server: Thread gestartet"); + while (!isInterrupted()) + { + try + { + handleRequest(); + } + catch (Exception e) + { + } + } + System.out.println("Server: Thread beendet"); + } + } + + public SimpleServer(int port, PipedWriter outPipe, PipedReader inPipe) throws IOException + { + this.port = port; + this.outPipe = outPipe; + this.inPipe = inPipe; + this.inPipeReader = new BufferedReader(inPipe); + } + + public void start() throws IOException + { + if (thread==null) + { + serverSocket = new ServerSocket (port); + thread = new SimpleServerThread(); + thread.start(); + } + else + throw new IOException("Es läuft bereits ein Server-Thread (nur ein Thread erlaubt)"); + } + + public void stop() throws IOException + { + if (thread != null) + { + thread.interrupt(); + serverSocket.close(); + serverSocket = null; + } + else + throw new IOException("Stop eines Servers der nicht gestartet wurde nicht möglich"); + } + + public String createAnswer (String request) + { + System.out.println("Server: Request bekommen: " + request); + try + { + this.outPipe.write(request); this.outPipe.write(10); + System.out.println("Server: Request über pipe gesendet " + outPipe); + System.out.println("Server: Warte auf Antwort... von " + inPipe); + String answer = this.inPipeReader.readLine(); + System.out.println("Server: Antwort: " + answer); + return answer; + } + catch (IOException ex) + { + ex.printStackTrace(System.err); + } + + return null; + } + + public void handleRequest() + { + try + { + final Socket socket = this.serverSocket.accept(); + if (socket != null) + { + new HandleRequestThread(socket).start(); + } + } + catch (IOException ex) + { + ex.printStackTrace(System.err); + } + } + + + public static void main(String[] args) + { + try + { + // Ports bis 1024 sind reserviert, bei Linux sogar root Rechte nötig + // der eigene Rechner ist immer 127.0.0.1 oder localhost + PipedReader inPipeS2C = new PipedReader(); + PipedWriter outPipeS2C = new PipedWriter(inPipeS2C); + PipedReader inPipeC2S = new PipedReader(); + PipedWriter outPipeC2S = new PipedWriter(inPipeC2S); + + System.out.println("main: S2C: " + outPipeS2C + " -> " + inPipeS2C); + System.out.println("main: C2S: " + inPipeC2S + " <- " + outPipeC2S); + + SimpleServer server = new SimpleServer(4711, outPipeS2C, inPipeC2S); + server.start(); + Thread.sleep(5000); + final BufferedReader reader = new BufferedReader(inPipeS2C); + System.out.println("main: Warte auf Daten von " + inPipeS2C); + String request = reader.readLine(); + System.out.println("main: Befehl bekommen: " + request); + outPipeC2S.write("Ha Ha Ha"); outPipeC2S.write(10); + System.out.println("main: Antwort gesendet über pipe " + outPipeC2S); + Thread.sleep(10000); + System.out.println("main: stoppe Server"); + server.stop(); + //server.testComm(); + } + catch (IOException e) + { + e.printStackTrace(System.err); + } + catch (InterruptedException e) + { + e.printStackTrace(System.err); + } + + } + + +}