diff options
103 files changed, 6207 insertions, 608 deletions
| diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..f929a866 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +ao-tools/libaltos/altos.dll		export-ignore +ao-tools/libaltos/libaltos.dylib	export-ignore @@ -14,6 +14,9 @@  .deps  TAGS  aclocal.m4 +libtool +ltmain.sh +src/Version  src/ao_flight_test  src/ao_gps_test  src/ao_gps_test_skytraq @@ -1,3 +1,1061 @@ +commit 59798c6fd11502a9c8b66090c23ba50eb250692e +Author: Keith Packard <keithp@keithp.com> +Date:   Fri Sep 3 12:43:45 2010 -0700 + +    altosui: Catch I/O errors on telemetry device, report to user +     +    This catches the USB device being unplugged and makes sure the +    user sees an error dialog in this case. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 16d8d6a8853d09f683b13f9cda3c3174a0aab130 +Author: Keith Packard <keithp@keithp.com> +Date:   Fri Sep 3 12:31:05 2010 -0700 + +    altosui: Must flush serial line after configuring for telemetry +     +    Without flushing the configuration commands to the serial device, it +    never sees them as the telemetry input thread doesn't flush. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit d4f64e95e31e2335470efc15df2ab357b7d197f3 +Author: Keith Packard <keithp@keithp.com> +Date:   Fri Sep 3 11:48:55 2010 -0700 + +    Revert "altosui: Deal with altos bug setting radio channel while monitoring" +     +    This reverts commit ba65e4aeb952a1cf49a77f1e24e235508fcea71f. +     +    Testing the old code + +commit 71191ecef3ba0e00d0f8a7cd1a24982bfa44ec72 +Author: Keith Packard <keithp@keithp.com> +Date:   Fri Sep 3 01:30:33 2010 -0700 + +    altosui: Allow 'connect to device' when already connected +     +    Opening another serial device involves shutting down the display +    thread (to reset its state) and spawning another one. Shutting down +    the display thread normally closes the serial device as a part of the +    process, and if this isn't done before the new serial device is +    opened, then the new serial device ends up getting closed too. +     +    Interrupting the display thread and waiting for it to stop before +    opening the new serial device solves the problem. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit ba65e4aeb952a1cf49a77f1e24e235508fcea71f +Author: Keith Packard <keithp@keithp.com> +Date:   Fri Sep 3 01:21:57 2010 -0700 + +    altosui: Deal with altos bug setting radio channel while monitoring +     +    If the monitoring thread is active, then setting the radio channel can +    sometimes cause the monitoring thread to get stuck. I'm not entirely +    sure why though. For now, work around the issue by making sure +    monitoring is off, and the monitoring thread has stopped, before +    changing the radio channel. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit e5ef42c2b22c6639d90631dbbb588f9fd2494385 +Author: Keith Packard <keithp@keithp.com> +Date:   Fri Sep 3 01:12:24 2010 -0700 + +    altosui: Report telemetry CRC errors in UI +     +    Telemetry CRC errors can signal problems with TeleMetrum or TeleDongle +    units, so report them in the UI. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 3b3aa448f3a0f44137f7530b04b58967ba5f22f5 +Author: Keith Packard <keithp@keithp.com> +Date:   Thu Sep 2 21:11:29 2010 -0700 + +    altosui: build Mac OS .zip file to include paths +     +    Without the paths, the OS X zip file doesn't create a usable +    application structure. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit cff0d1ef6b338b3d5ad9450d4d5f95df934cb5e4 +Author: Keith Packard <keithp@keithp.com> +Date:   Wed Sep 1 22:56:34 2010 -0700 + +    altosui: Post error dialog on invalid ROM config values. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 8d8980f56a4f2c7d6f2ce667130706e0f04f8ded +Author: Keith Packard <keithp@keithp.com> +Date:   Wed Sep 1 22:56:12 2010 -0700 + +    altosui: Remove some debug printfs from AltosRomconfig class +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 5ee6cd41ed189c3166f76558ecada80917f40652 +Author: Keith Packard <keithp@keithp.com> +Date:   Wed Sep 1 22:47:15 2010 -0700 + +    altosui: Hide internal rom config UI helper function +     +    This was getting mis-used by the flash UI causing the rom dialog +    'cancel' button to work just like 'ok'. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 9a690c9795e8257d2a3225f905117681668a472f +Author: Keith Packard <keithp@keithp.com> +Date:   Wed Sep 1 22:46:04 2010 -0700 + +    altosui: allow flashing to be canceled from the rom config dialog +     +    Was using the rom config class wrong, causing cancel actions to work +    just like 'ok' actions. Oops. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 2f07ad14a16dbf1b75c71784ceae303825c90ade +Author: Keith Packard <keithp@keithp.com> +Date:   Wed Sep 1 22:43:22 2010 -0700 + +    altosui: Abort flashing if debug port isn't working +     +    Check each command going over the debug port and make sure it works as +    expected. This commit adds checks for initializing the clock, +    selecting the desired program counter and running the flash +    program. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit cf30343aadd5039627a85319872685f743e64b16 +Author: Bdale Garbee <bdale@gag.com> +Date:   Thu Sep 2 00:55:41 2010 -0400 + +    update changelogs for Debian build + +commit 59a40f6d5a2159b9009a3fa0737bb679efd5b32c +Author: Bdale Garbee <bdale@gag.com> +Date:   Thu Sep 2 00:55:01 2010 -0400 + +    another distclean fix + +commit 59ff9180f11063c257746b895a167179b3a4ff7c +Author: Bdale Garbee <bdale@gag.com> +Date:   Thu Sep 2 00:53:16 2010 -0400 + +    and a few more distclean fixes + +commit 3aafd70257b70b7c11ba9c55749157979bc61ea2 +Author: Bdale Garbee <bdale@gag.com> +Date:   Thu Sep 2 00:52:04 2010 -0400 + +    more makefile distclean target work + +commit d5a6ad87c7a9ac03b2e694bed0a54b6cc4322a6f +Author: Bdale Garbee <bdale@gag.com> +Date:   Thu Sep 2 00:50:16 2010 -0400 + +    update changelogs for Debian build + +commit 14fa24ed93b3b1cec08a170004c6fb7f4d74f7e5 +Author: Bdale Garbee <bdale@gag.com> +Date:   Thu Sep 2 00:48:31 2010 -0400 + +    update changelogs for Debian build + +commit 83552dfa0d38db9cdf3efc89e64e6c7896467856 +Author: Bdale Garbee <bdale@gag.com> +Date:   Thu Sep 2 00:47:54 2010 -0400 + +    add distclean targets to libaltos and altosui to all Debian package to build + +commit 6f24d2a476759104a10b26b54faff2b18b0e208b +Author: Bdale Garbee <bdale@gag.com> +Date:   Thu Sep 2 00:46:21 2010 -0400 + +    update changelogs for Debian build + +commit d079bfe86ed40ff450ece445cf5f5e3970e44cec +Author: Bdale Garbee <bdale@gag.com> +Date:   Thu Sep 2 00:44:30 2010 -0400 + +    update changelogs for Debian build + +commit a470315e5d822a69ef5304512cf73c604c88e481 +Author: Keith Packard <keithp@keithp.com> +Date:   Wed Sep 1 20:14:51 2010 -0700 + +    altosui: Remove Manifest.txt from git repo as it's built now +     +    This file is built with appropriate contents for each different .jar file. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 1177e0a684328422be5adc68093d0091a218a824 +Author: Keith Packard <keithp@keithp.com> +Date:   Wed Sep 1 19:53:24 2010 -0700 + +    altos: Bounds check Skytraq GPS tracking data array +     +    Missing GPS serial data could cause the tracking array reset to +    get skipped, causing the array to be overrun, smashing critical data +    beyond the array. +     +    This was detected using the 'altosui' flash command to program a +    device from TM. Hitting the USB that hard caused TM to crash with a +    mutex error (3 beeps) after the ao_gps_task structure was overwritten +    with zeros. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 775acb89660cdee2f3c54c38297baefe39f2414c +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 30 22:24:09 2010 -0700 + +    altosui: missed AltosReader.class in the Makefile +     +    This caused clean builds to fail to make this file +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit bd2b9d958c2b7f846031b076ed51c4fbaaf2d68f +Author: Bdale Garbee <bdale@gag.com> +Date:   Tue Aug 31 00:20:06 2010 -0400 + +    update changelogs for Debian build + +commit d006c5e1255433181aca4c8e6a277b2d1bc0841b +Author: Bdale Garbee <bdale@gag.com> +Date:   Tue Aug 31 00:19:37 2010 -0400 + +    add runtime dependencies for altos binary package + +commit c1c7d731e3774883fa0bb5538be225a59334d124 +Author: Bdale Garbee <bdale@gag.com> +Date:   Mon Aug 30 19:52:51 2010 -0600 + +    update changelogs for Debian build + +commit c35632efb1919764e4b8581ed6fcf2bedd4bd517 +Author: Bdale Garbee <bdale@gag.com> +Date:   Mon Aug 30 19:37:50 2010 -0600 + +    update changelogs for Debian build + +commit 2a004d17a13b4ff52d892bfdecff8ad3d0823f7c +Author: Bdale Garbee <bdale@gag.com> +Date:   Mon Aug 30 19:37:17 2010 -0600 + +    don't build all the "fat" jar deliverables by default + +commit 507e429db6638f82c32449e9c5ca06b46da30134 +Author: Bdale Garbee <bdale@gag.com> +Date:   Mon Aug 30 19:09:00 2010 -0600 + +    update changelogs for Debian build + +commit 25764fcd1b65c3a5a817afdb5901ac30e8a5f0c0 +Author: Bdale Garbee <bdale@gag.com> +Date:   Mon Aug 30 19:08:29 2010 -0600 + +    update changelogs for Debian build + +commit 4790f78aead8a816e5b247c022b2998ce3a94053 +Author: Bdale Garbee <bdale@gag.com> +Date:   Mon Aug 30 18:48:50 2010 -0600 + +    add a .gitattributes file, configuring the Mac and Windows binary library +    files with the export-ignore attribute, in hopes that this will prevent +    them showing up in source packages + +commit 81318e5b7179b0311ab099043ecb04a25d763750 +Author: Bdale Garbee <bdale@gag.com> +Date:   Mon Aug 30 18:15:40 2010 -0600 + +    make invocation of 'install' pathless to work on more Unix variants + +commit cbc72399a0f4d7429df0189bcdae683dd491cb9e +Author: Bdale Garbee <bdale@gag.com> +Date:   Mon Aug 30 17:56:56 2010 -0600 + +    continue even if rm's don't have anything to do + +commit a9a8d23c877e6f6c76857b7c85e3d43b4da1db27 +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 30 05:49:11 2010 -0700 + +    altosui: Devices with USB id 0x000a always get listed +     +    List 'unknown' AltusMetrum devices anytime the UI needs a device +    name. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit a94900b8862b99b4e317ea0ee3edd2a560f270c7 +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 30 05:48:23 2010 -0700 + +    altosui: build debian-style altosui too +     +    This adds the dependencies to make sure altosui and altosui.jar get built. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 38ac388baf8125c0644b868a7aaf8eba1bdf990d +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 30 05:28:37 2010 -0700 + +    altosui: Build linux, mac and windows archives on Linux +     +    This adds 'fat' archives for each target OS. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 35d9a8214252dbe79aeb69ae47d2e5c58a654702 +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 30 05:27:45 2010 -0700 + +    libaltos: Use overlapped I/O on windows +     +    Otherwise, reads block writes and vice-versa. Crazy stuff. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit c7ba92317ac55272acbde12416448ebd17b983a6 +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 30 04:52:00 2010 -0700 + +    altos: Windows sends USB Out packets of 0 length. Ack them. +     +    This was an untested case as no other operating system sents 0-length +    out packets (they're not necessary). The correct response is to ACK +    them by clearing the OUTPKT_RDY bit so that another packet can be sent. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 20a472cfe3369200150ea4ff067ceb28968dbcac +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 30 02:58:23 2010 -0700 + +    libaltos: Add pre-built Windows .dll +     +    This lets us create the windows distribution on Linux. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 0300fe581c949232bc52b05fe9c1f6032cad6b60 +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 30 02:56:25 2010 -0700 + +    libaltos: Add pre-built Mac OS X libaltos.dylib +     +    This allows the mac bits to be built on Linux. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 5d48c494325524bbeed10e0dc7300ed44e7e208e +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 30 02:53:26 2010 -0700 + +    Update telemetrum.inf to include all current USB ids. +     +    Windows 7 has 'encouraged' us to split out each product into a +    separate USB ID. telemetrum.inf now has all of them listed. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit df34bbe7d1c43b12ab6d610fe810b6e1683e4c21 +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 30 02:49:49 2010 -0700 + +    libaltos: Improve Makefile +     +    Builds Windows .dll correctly now and sample app. +    Moves linux install target to end so it is not default +    Adds .NOTPARALLEL to disable parallel gnumake. +    Removes -g debugging flags to shrink file size. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit dd5374b8e660012ae4f8b058454fd101e0749ca7 +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 30 02:00:30 2010 -0700 + +    libaltos: Fix windows build. +     +    Need stdlib.h to get calloc/free defined, remove debug printfs, fix +    serial timeouts. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 63c832394a829f41b8f77d075786530536360349 +Author: Keith Packard <keithp@keithp.com> +Date:   Sun Aug 29 23:22:27 2010 -0700 + +    altos: shut down packet mode cleanly +     +    Instead of constantly bashing the packet master thread, let it shut +    itself down in an orderly fashion. It will shut down fairly quickly as +    all of the activities in that thread are bounded. Otherwise, the +    master packet thread might leave mutexes locked and all sorts of other +    horrors. +     +    Tested on Linux and Mac OS X and shown to be reliable. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 43619c13f749b79c096d1e8fdab3d5cfb5fd85f1 +Author: Keith Packard <keithp@keithp.com> +Date:   Sun Aug 29 22:42:23 2010 -0700 + +    altos: Abort radio harder when terminating packet mode. +     +    Make sure the master radio tasks don't get stuck waiting for an +    incoming packet again by aborting the radio each time we poke the +    tasks. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit c4a8569f61eddf690d00337543462235ecbfbe54 +Author: Keith Packard <keithp@keithp.com> +Date:   Sun Aug 29 22:41:18 2010 -0700 + +    altos: flush pending output when terminating packet mode +     +    Just in case the last command sent hasn't been transmitted, hang +    around for up to a second waiting for the data to get across the link. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 1acd3c7ec167b1b18e4ea493e5978c938a91cc89 +Author: Keith Packard <keithp@keithp.com> +Date:   Sun Aug 29 21:45:19 2010 -0700 + +    libaltos: cjnitest needs altos_flush now + +commit 6527357d1f0e94faf9e7dacac10a39875131be7c +Author: Keith Packard <keithp@keithp.com> +Date:   Sun Aug 29 21:43:46 2010 -0700 + +    libaltos: Missing OS_LDFLAGS on cjnitest build + +commit b7fa1ea3338f63b8edcf8aacccb5e519ca0b213f +Author: Keith Packard <keithp@keithp.com> +Date:   Sun Aug 29 21:41:40 2010 -0700 + +    libaltos: Mac OS X cannot use 'poll(2)' on serial lines. +     +    Who ships this stuff, anyway? Instead of blocking, we'll poll every 100ms now, +    otherwise, we won't be able to abort the read when the device is closed. Yay! +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit e60c59123232915e808cee23ef89eb1a38ced34b +Author: Keith Packard <keithp@keithp.com> +Date:   Sun Aug 29 21:40:21 2010 -0700 + +    altosui: discard invalid lines while reading Eeprom flight data +     +    This shouldn't happen, but it's easy enough to get back in sync by just +    skipping lines with weird contents. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit ae02b1590439d5c8dfb472cf1f83a14fdcfbaf11 +Author: Keith Packard <keithp@keithp.com> +Date:   Sun Aug 29 21:36:47 2010 -0700 + +    altosui: provide separate flush_input/flush_output for serial. deal with monitor automatically +     +    (yes, this should be two patches, but the diffs in AltosSerial were merged together). +     +    First, this replaces the existing flush/flush_reply mess with two simple functions, +    one to flush output to the serial device, making sure that all data written will be seen +    while we wait for input. The other sucks any pending input off of the serial line and +    discards it. +     +    Second, AltosSerial now tracks whether the serial line is being used for telemetry +    monitoring. If so, it enables monitoring, otherwise it disables it. Eliminates a +    bunch of manual state tracking elsewhere. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit edcfb1bdf64772d3b83405ccf99385b8fea5d8e4 +Author: Keith Packard <keithp@keithp.com> +Date:   Sun Aug 29 17:33:59 2010 -0700 + +    libaltos: AltusMetrum devices use more than one USB ID. +     +    List all usb devices, picking those with AltusMetrum IDs. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 236685807b63860ad033aa0254ce8f6d8d36d4ef +Author: Bdale Garbee <bdale@gag.com> +Date:   Fri Aug 27 22:26:09 2010 -0600 + +    update changelogs for Debian build + +commit 1cda15fdef2d9d3e54354bd5c43a0bcc7e3240cb +Author: Bdale Garbee <bdale@gag.com> +Date:   Fri Aug 27 22:24:51 2010 -0600 + +    fix up for an 0.7 release + +commit 4c5c7c7f198775c398c1ad2edafb3488384cc297 +Author: Bdale Garbee <bdale@gag.com> +Date:   Fri Aug 27 22:13:38 2010 -0600 + +    update changelogs for Debian build + +commit 42055af5c6f17d14a2f1c6a2b5e1ce6d3b45a615 +Author: Bdale Garbee <bdale@gag.com> +Date:   Fri Aug 27 13:13:19 2010 -0600 + +    update changelogs for Debian build + +commit 0bd4cc03b3bf23aa32b5ce1921078021d1d8a9c6 +Author: Bdale Garbee <bdale@gag.com> +Date:   Fri Aug 27 13:12:46 2010 -0600 + +    fix path to installed shared library + +commit 99c1d9b4ef10ec4ebbee058ce0bb38c954a0a3a6 +Author: Bdale Garbee <bdale@gag.com> +Date:   Fri Aug 27 12:41:26 2010 -0600 + +    update changelogs for Debian build + +commit cf65c6b8056c4af7c26b52ec6f9fbd3400cef638 +Merge: 5f2f6a8 ae5eff7 +Author: Bdale Garbee <bdale@gag.com> +Date:   Fri Aug 27 12:38:25 2010 -0600 + +    Merge branch 'bdale' +     +    Conflicts: +    	debian/control + +commit ae5eff7bc0b63047737223423009707bedcb00f5 +Author: Bdale Garbee <bdale@gag.com> +Date:   Fri Aug 27 12:37:36 2010 -0600 + +    Revert "lose the prebuild hook for now while I'm fumbling" +     +    This reverts commit a21b6bb60ac1c07ebd161534a4ea63bfde50dcdf. + +commit de2e71c4923a0282df74dbe37d087c34b4ddd279 +Author: Bdale Garbee <bdale@gag.com> +Date:   Fri Aug 27 12:25:20 2010 -0600 + +    fix man page delivery path + +commit a8dbe082960dc9bdd44c6e4b1198423c4e566029 +Author: Bdale Garbee <bdale@gag.com> +Date:   Fri Aug 27 12:18:28 2010 -0600 + +    install altosui man page + +commit 5cc933039e4763b8675611c63b6147b42878a2bb +Author: Bdale Garbee <bdale@gag.com> +Date:   Fri Aug 27 12:16:19 2010 -0600 + +    fix permissions on installed jar file, switch from ao-view to altosui in +    the desktop file + +commit 138009e9fad01f79df4c3820fbc206f78688bdce +Author: Bdale Garbee <bdale@gag.com> +Date:   Fri Aug 27 12:06:01 2010 -0600 + +    update Debian standards version + +commit c280071b7db4e9a7af31dc5740eb8d27f137950e +Author: Bdale Garbee <bdale@gag.com> +Date:   Fri Aug 27 12:04:13 2010 -0600 + +    fix up the wrapper's path to the jar file + +commit 5f2f6a8f9ba56be867888758848bc7f152ccbd47 +Merge: 63bd34c 9d1b27f +Author: Keith Packard <keithp@keithp.com> +Date:   Fri Aug 27 11:00:31 2010 -0700 + +    Merge remote branch 'origin/master' into new-packet-format + +commit 63bd34cd1b5a411489e8c3ab377f0fe0eec11f67 +Author: Keith Packard <keithp@keithp.com> +Date:   Fri Aug 27 10:58:55 2010 -0700 + +    altosui: add elevation and range information +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 72a18502e40f55cbba6418dc94315517881cd411 +Author: Bdale Garbee <bdale@gag.com> +Date:   Fri Aug 27 11:51:24 2010 -0600 + +    add an install target for altosui + +commit 72c33a72ee105ec692dad62d6d9c1ad40b89bfe8 +Author: Bdale Garbee <bdale@gag.com> +Date:   Fri Aug 27 11:45:19 2010 -0600 + +    add install target for libaltos + +commit a21b6bb60ac1c07ebd161534a4ea63bfde50dcdf +Author: Bdale Garbee <bdale@gag.com> +Date:   Fri Aug 27 11:26:29 2010 -0600 + +    lose the prebuild hook for now while I'm fumbling + +commit 9ea94411c9730f7a271366d309ab4827beeeb839 +Author: Bdale Garbee <bdale@gag.com> +Date:   Fri Aug 27 11:17:54 2010 -0600 + +    add a dummy install target + +commit c443f43f8dee6e0fcbcecf9d09e948fd928b7af4 +Merge: 2950431 2923cf5 +Author: Bdale Garbee <bdale@gag.com> +Date:   Fri Aug 27 03:08:53 2010 -0600 + +    Merge branch 'new-packet-format' of ssh://git.gag.com/scm/git/fw/altos into new-package-format + +commit 2923cf5057f9cef110dd547d8677ea5b60e00796 +Author: Keith Packard <keithp@keithp.com> +Date:   Fri Aug 27 00:10:29 2010 -0700 + +    altos: prepare for sdcc 2.9.1 +     +    A few minor language changes -- non-standard keywords are now prefixed +    with __, such as 'at', 'interrupt', 'naked'. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 68967157cee620ebedcc8c2ffd6fc7656532087b +Author: Keith Packard <keithp@keithp.com> +Date:   Thu Aug 26 23:55:44 2010 -0700 + +    altosui: command line args are converted to csv format +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 7e0506dc2014b7178f52b950e8c1cb820b35f9c6 +Author: Keith Packard <keithp@keithp.com> +Date:   Thu Aug 26 23:54:53 2010 -0700 + +    altosui: Remove debug printf from AltosState.java +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 49364608b59de7421ab00d87d2685bc3b5f58411 +Author: Keith Packard <keithp@keithp.com> +Date:   Thu Aug 26 23:53:06 2010 -0700 + +    altosui: When parsing saved telem files, errors shouldn't abort file +     +    Make syntax errors in telem files just skip the current line and move +    on to the next one instead of abandoning the whole file. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit a16db143fc7ca72dc91e7989420049192114642d +Author: Keith Packard <keithp@keithp.com> +Date:   Thu Aug 26 23:50:51 2010 -0700 + +    altosui: Serial line is in UTF-8 encoding. Deal with it. +     +    We read bytes from the serial line and need to convert each line into +    a string. So, save the bytes and at EOL, pass the whole mess to the +    string constructor with the appropriate encoding info. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 0942912163255523d923140c01afbdb5da1c19b5 +Author: Keith Packard <keithp@keithp.com> +Date:   Thu Aug 26 23:49:37 2010 -0700 + +    altosui: Add support for old (version < 3) telemetry files +     +    This lets the code read telemetry files from pre-released versions of +    the software. Not strictly necessary for production, but useful for +    analysing old files. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit e383595cd281687de903fb6176564bbef270cb83 +Author: Keith Packard <keithp@keithp.com> +Date:   Thu Aug 26 23:47:38 2010 -0700 + +    altosui: AltosEepromReader was mis-setting boost tick +     +    It was supposed to use record.tick instead of the (unset) state.tick +    value. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 651f6102ac79459fc8d5679d852c963dcb5bb3fc +Author: Keith Packard <keithp@keithp.com> +Date:   Thu Aug 26 23:44:25 2010 -0700 + +    altosui: add rssi and distance/dir from pad to CSV files +     +    Just adds a couple more fields to the CSV files that might be interesting. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 3dc67c1401976d6e9e2e942d5a4707a4810a0404 +Author: Keith Packard <keithp@keithp.com> +Date:   Thu Aug 26 23:43:00 2010 -0700 + +    altosui: Add AltosGreatCircle constructors +     +    This adds constructurs from AltosGPS pairs and also one from empty +    args (which defines both distance and bearing as 0). +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit f0fd423d0bf83bc5c3f9d39e9c09397fbe8caed2 +Author: Keith Packard <keithp@keithp.com> +Date:   Thu Aug 26 23:41:26 2010 -0700 + +    altosui: Move number parsing code to Altos general class +     +    This moves these shared functions to the global shared class. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 68b2b66d7574dfd0bd5e3571b8ffad32ca5d2b73 +Author: Keith Packard <keithp@keithp.com> +Date:   Thu Aug 26 23:37:29 2010 -0700 + +    altos: mark gps date written only after it gets into eeprom +     +    Data logging doesn't start until boost detect occurs. As the GPS date +    is only logged once, if that happens before logging is written to the +    flash, then the GPS date will never get saved. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit aa6c27df5db6bdae59d00affccb891854a6caa18 +Author: Keith Packard <keithp@keithp.com> +Date:   Thu Aug 26 15:59:09 2010 -0700 + +    altos: print GPS state flags in GPS 'g' command +     +    Having the GPS state information can help with GPS debugging. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 34055129b4008f6a9833887b12dee39ffa408002 +Author: Keith Packard <keithp@keithp.com> +Date:   Thu Aug 26 15:57:09 2010 -0700 + +    altos: always rebuild ao_product.c to track git version +     +    The git version is built into ao_product.c and saved in eeprom log +    files, providing useful diagnostics about the firmware revision used +    for each flight. However, if ao_product.c isn't recompiled, then the +    updated version won't be included. Force recompilation of this file +    each time make is run to ensure that the final output contains an +    updated version number. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 99400fdc0f19ef538fc362dde5c3ab5b7cdac409 +Author: Keith Packard <keithp@keithp.com> +Date:   Tue Aug 24 16:43:38 2010 -0700 + +    altosui: flush replies from serial link when entering debug mode +     +    We use replies in debug mode a lot and depend on them matching the +    expected parameters. The case which caused trouble was using +    TeleMetrum to reprogram TeleDongle -- sending the 'm 0' command (to +    disable telemetry monitoring on TeleDongle) to the TeleMetrum caused +    it to reply 'Syntax Error' which confused the subsequent flashing +    operation. Flushing that reply gets things back in sync. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit ba086cc77273efe5397f60dcaccd1e3771441481 +Author: Keith Packard <keithp@keithp.com> +Date:   Tue Aug 24 04:02:27 2010 -0700 + +    altosui: write USB serial number string while flashing +     +    USB serial number is encoded in UCS2 as a part of the string +    descriptors. Place those right after the other rom config bits so that +    altosui can find it. altosui is changed to write the serial number there. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 220f3afdaa432c65f8ad45be7cdbe5c8a3616db3 +Author: Keith Packard <keithp@keithp.com> +Date:   Tue Aug 24 04:01:47 2010 -0700 + +    altosui: always display romconfig ui while flashing + +commit f62b2aa08ebfd912b3c732397d43ff9f6162ec88 +Author: Keith Packard <keithp@keithp.com> +Date:   Tue Aug 24 04:01:14 2010 -0700 + +    altosui: fetch existing romconfig for flashing + +commit d93787284c8e514a929edb9f944c98ae0206a33f +Author: Keith Packard <keithp@keithp.com> +Date:   Tue Aug 24 03:59:09 2010 -0700 + +    altosui: Delay mapping Flash UI until flashing actually starts +     +    The flash operation may be abandoned before it even starts; this makes +    sure the UI doesn't flash up on the screen. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 7d44cbd621d2b113ac2b802ef17e3d8a660ce7f2 +Author: Keith Packard <keithp@keithp.com> +Date:   Tue Aug 24 03:58:00 2010 -0700 + +    altosui: disable radio monitoring while using serial line for debugging + +commit 7bd220dfd9b3fb0e42eb90c3b37eb7b4169eb21b +Author: Keith Packard <keithp@keithp.com> +Date:   Tue Aug 24 00:29:11 2010 -0700 + +    altosui: Add ability to create CSV file from telem or eeprom files +     +    This creates a comma separated value file to export data for +    external programs. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 634a550149e7c344a22a637ba484f115592b1018 +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 23 23:15:05 2010 -0700 + +    altosui: refactor logfile chooser dialog to share more code +     +    Move file opening logic into logfile chooser as it can be shared that way. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit a55b132668a819cc26478a609cb79bd9190deb9d +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 23 23:01:36 2010 -0700 + +    altosui: Separate out log file choosing dialog to share with CSV generator +     +    This dialog will be shared with the CSV file generating code, so split +    it out instead of duplicating it. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 295043112ccde35092945c286596f9045ee6fa05 +Merge: 2007288 ef8376c +Author: Bdale Garbee <bdale@gag.com> +Date:   Mon Aug 23 23:11:22 2010 -0600 + +    Merge branch 'new-packet-format' of ssh://git.gag.com/scm/git/fw/altos into new-package-format + +commit ef8376c4dd8262a34e02b6bb9e19e907ac2f4330 +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 23 22:08:30 2010 -0700 + +    altosui: make default Manifest look for built-in freetts + +commit 56b906f535ac2f86bcab71addbbcd376d74f6a73 +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 23 22:03:36 2010 -0700 + +    altos: Place rom config variables in fixed location +     +    The device serial number and radio calibration values are stored in +    flash, mostly so that TeleDongle gets them saved. +     +    Placing them in well-known locations (starting at 0xa0) makes it +    possible to find the previous configuration and to re-write it +    easily, without requiring the .map file. +     +    altosui doesn't have the .map file parsing code, so it relies upon +    this new technique. As a benefit, it reads the old values from the +    device before reprogramming it. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 4c0c099716197ef7539be0cf55bbb164f6804958 +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 23 22:02:21 2010 -0700 + +    altosui: Finish device programming code +     +    Altosui can now reprogram Altusmetrum devices. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit bd2b44ddd61fadd8bf8ee6bf783ce019b1be7cc0 +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 23 22:01:38 2010 -0700 + +    altosui: Remove debug printf from AltosRomconfig + +commit c3f57ffdb6c74de90d982eacd604e658ce9b00a5 +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 23 22:01:11 2010 -0700 + +    altosui: flush serial output before waiting for reply + +commit 8857ac5e43eac6db8d5594b8864df497a712242b +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 23 22:00:16 2010 -0700 + +    altosui: remove debug printf from AltosHexfile + +commit b1758be01397fd49c441f40852f3558fe9343a2d +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 23 21:58:50 2010 -0700 + +    altosui: Add lots more cc1111 debug interface functions +     +    These are sufficient to program the flash. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit f9e80f39bc39e5882bfe75f959b6501cb3277cd2 +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 23 21:55:49 2010 -0700 + +    libaltos: use pipe to wake up getchar on close. use mutexes + +commit 86f7b9314b042f2e512fdf35067817e68532867b +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 23 21:54:47 2010 -0700 + +    altosui: pad TM config dialog values to avoid clipping descenders + +commit b8519b8669ff54741dd738ac343fbd2424451247 +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 23 21:53:37 2010 -0700 + +    ao-dumplog: Fix --remote and --channel options to actually work + +commit ebeb13688a9a5442c838641ede6ba0dc92c9a1a4 +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 23 14:32:58 2010 -0700 + +    altosui: Add debug dongle API, split flash UI out +     +    Create an API to talk through the debug port on another AltOS +    device. Split the flash UI out from the flash implementation so that a +    command line flash utility can be written. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 7f8d7978606abe544b1b9b6065c5480ed813b8ec +Author: Keith Packard <keithp@keithp.com> +Date:   Mon Aug 23 11:53:19 2010 -0700 + +    altosui: Add .ihx file reading code and stub out flashing UI +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 2007288da8a83e3aa925e11cc196f1c65aab2e5c +Author: Bdale Garbee <bdale@gag.com> +Date:   Thu Aug 5 15:00:15 2010 -0400 + +    working on java packaging details + +commit 44b26dd550eef789e70082ccaa46d7d430c67bce +Author: Bdale Garbee <bdale@gag.com> +Date:   Thu Aug 5 15:15:04 2010 -0400 + +    add freetts as a build dep + +commit 0e17853c08f77debef3e8cf82e9cdb6a5079fc9b +Author: Keith Packard <keithp@keithp.com> +Date:   Sun Aug 22 23:06:15 2010 -0700 + +    altosui: Set callsign when fetching eeprom data over the air +     +    The updated firmware places the callsign in each packet to comply with +    regulations, this ensures that TeleDongle has the current callsign +    configured. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 953bc3438b10b21f3d65d292356c4ab2de23cddd +Author: Keith Packard <keithp@keithp.com> +Date:   Sun Aug 22 23:05:20 2010 -0700 + +    altosui: Add TeleMetrum configuration +     +    This presents a dialog with all of the user-settable options in the +    TeleMetrum set for editing. Combo boxes are used for everything except +    the callsign. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit e1463d8e265dfd42c824d90088cd2a51b4cf8131 +Author: Keith Packard <keithp@keithp.com> +Date:   Sat Aug 21 17:57:31 2010 -0700 + +    altosui: Make teledongle callsign configurable +     +    Teledongle uses the callsign in packet mode; this provides a way to +    set that. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 09252ec22d58e946494e4ca2cf367bf3bbe1cc50 +Author: Keith Packard <keithp@keithp.com> +Date:   Sat Aug 21 17:09:41 2010 -0700 + +    altos: Define USB product ID in per-product Makefile.defs file +     +    This allows Win7 to tell which kind of device is connected purely by +    USB id as it doesn't expose the USB product ID string to user space. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 22800dc094797e1e0ad99124198809d0360f7556 +Author: Keith Packard <keithp@keithp.com> +Date:   Tue Aug 17 18:22:28 2010 -0700 + +    altosui: Select devices by USB vendor/product ID. +     +    Because Win7 doesn't expose the product name, we're swtiching to using +    the USB idProduct/idVendor values. This patch adds support for +    selecting devices by those new IDs. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit d14c96663a1027164fa30ed89b53f5a9d3fdb82b +Author: Keith Packard <keithp@keithp.com> +Date:   Tue Aug 17 18:19:43 2010 -0700 + +    libaltos: integrate Windows support. +     +    This adds Windows support for discovery and I/O. +     +    The API to the library is mostly unchanged, except that it now exports +    product and vendor USB IDs as Win7 doesn't expose the product name +    anywhere that we've been able to find, so we'll be updating the +    firmware to use unique idProduct values for each product. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 9d1b27fa147fc8b765d5be165ebef7ee0f85bd37 +Author: Bdale Garbee <bdale@gag.com> +Date:   Wed Aug 11 22:11:50 2010 -0400 + +    update changelogs for Debian build +  commit b6da90b4627dde1fe88240c38c51559d8f781dd0  Author: Bdale Garbee <bdale@gag.com>  Date:   Wed Aug 11 17:15:39 2010 -0400 @@ -16,6 +1074,55 @@ Date:   Wed Aug 11 08:36:59 2010 -0400      update changelogs for Debian build +commit 294d9c7db21eaf1e71504dbcca5040371abcce55 +Author: Keith Packard <keithp@keithp.com> +Date:   Sat Aug 7 22:30:55 2010 -0400 + +    ao-dumplog: add --channel option (for use with -R option) +     +    Sets the channel when downloading data with the -R option. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit f317f1324b69b4241f4bb192e164b33d712d5a43 +Author: Keith Packard <keithp@keithp.com> +Date:   Sat Aug 7 00:42:25 2010 -0400 + +    altosui: Start adding code to write csv files from eeprom/telem files +     +    This is a start to code which can write out a csv file full of flight +    data from either an eeprom or telem input file. It's not hooked up, +    but the restructuring necessary is finished and the output is started. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 4738cb2fc639adb1d9237e6c903479f0690dd81a +Author: Keith Packard <keithp@keithp.com> +Date:   Sat Aug 7 00:40:59 2010 -0400 + +    altos: add callsign to packet mode, increase payload to 64 bytes +     +    Untested, but it 'should' work. Need to add callsign setting to packet +    mode users. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit b7699a5907e64bc7547fcc27e73f4a35bbaabfff +Author: Keith Packard <keithp@keithp.com> +Date:   Fri Aug 6 13:09:21 2010 -0400 + +    altosui: Add comments to Eeprom reader + +commit 0e917f3ff822616adb147517ac961422e5fedbfd +Author: Keith Packard <keithp@keithp.com> +Date:   Thu Aug 5 22:49:53 2010 -0400 + +    altosui: Compute flight state from eeprom data +     +    This lets eeprom files be used to replay flights. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> +  commit a0a9b445a4d379730b67720f8d7b682d5206a582  Author: Bdale Garbee <bdale@gag.com>  Date:   Thu Aug 5 15:16:48 2010 -0400 @@ -52,12 +1159,88 @@ Date:   Thu Aug 5 15:00:15 2010 -0400      working on java packaging details +commit d8bf05f7ad55964c9bce0551e58f4ef6c9f721ad +Author: Keith Packard <keithp@keithp.com> +Date:   Thu Aug 5 13:50:18 2010 -0400 + +    altosui: Split flight record out of telemetry class +     +    This will permit either telemetry or eeprom data to be used to +    construct the sequence of flight events for reply or data generation. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 85a670b5a904d6750d0f179ae307baeb8fc7cbd2 +Author: Keith Packard <keithp@keithp.com> +Date:   Thu Aug 5 13:40:17 2010 -0400 + +    altosui: Explicitly initialize Altos class +     +    Because the Altos class is never instantiated, the static initializers +    are never called, leaving the string to state mapping empty. Hand-code +    the call to the initialer instead. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> +  commit 02f17f2cd26189e2676a9dc0d86bd959ed0bc3f4  Author: Bdale Garbee <bdale@gag.com>  Date:   Thu Aug 5 00:54:05 2010 -0400      move to science menu +commit 9e8f7f75442303f9bfa99a0435984f5d36863ae6 +Author: Keith Packard <keithp@keithp.com> +Date:   Sat Jul 31 10:34:21 2010 -0700 + +    altosui: Split status and info panels into separate files +     +    This moves some code out of AltosUI.java into separate files +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 9c9b35254c693b3ade42b24d1e29eaf31e6ba2aa +Author: Keith Packard <keithp@keithp.com> +Date:   Sat Jul 31 10:24:56 2010 -0700 + +    altosui: Clear displayed data rows as needed. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 88e0137a60d7a13ddb7781befa76650e13ad44ae +Author: Keith Packard <keithp@keithp.com> +Date:   Sat Jul 31 10:07:38 2010 -0700 + +    altosui: Merge gps date and time classes into gps class +     +    No reason to split out the date and time information from the other gps info. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit 1c3b2fe357d6acf28f48aeddd91693f10381be51 +Author: Keith Packard <keithp@keithp.com> +Date:   Sat Jul 31 10:05:15 2010 -0700 + +    altosui: Capture config and version info in .eeprom files +     +    Instead of only writing the serial number to the .eeprom file, write +    all of the config values and all of the version reply to the .eeprom +    file. The config values, in particular, contain the accelerometer +    calibration data which is needed to correctly compute acceleration +    from the captured accelerometer data. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> + +commit e286eb61ad2a90746c1c31f95d26d5edb48738d3 +Author: Keith Packard <keithp@keithp.com> +Date:   Sat Jul 31 09:57:49 2010 -0700 + +    altosui: rename AltosEeprom -> AltosEepromDownload, split out Altos constants +     +    Renames the eeprom downloading code and adds a new file to share the +    flight data constants across the various UI modules. +     +    Signed-off-by: Keith Packard <keithp@keithp.com> +  commit e3a9e3815db3f290e28b40ae02aa654f515cfc37  Author: Bdale Garbee <bdale@gag.com>  Date:   Sat Jul 31 10:55:27 2010 -0600 diff --git a/Makefile.am b/Makefile.am index 39e7c244..66d7cb55 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,3 +11,6 @@ ChangeLog:  	(touch ChangeLog; echo 'git directory not found: installing possibly empty changelog.' >&2)  dist-hook: ChangeLog + +fat: +	cd ao-tools/altosui && $(MAKE) fat diff --git a/ao-tools/altosui/.gitignore b/ao-tools/altosui/.gitignore index 59913193..89be1d53 100644 --- a/ao-tools/altosui/.gitignore +++ b/ao-tools/altosui/.gitignore @@ -1,2 +1,19 @@ -*.class +windows/ +linux/ +macosx/ +fat/ +Manifest.txt +Manifest-fat.txt +libaltosJNI +classes  altosui +altosui-test +classaltosui.stamp +Altos-Linux-*.tar.bz2 +Altos-Mac-*.zip +Altos-Windows-*.exe +*.dll +*.dylib +*.so +*.jar +*.class diff --git a/ao-tools/altosui/Altos.java b/ao-tools/altosui/Altos.java index 53359e23..07bd01ae 100644 --- a/ao-tools/altosui/Altos.java +++ b/ao-tools/altosui/Altos.java @@ -114,4 +114,90 @@ public class Altos {  	static final int AO_GPS_DATE_VALID = (1 << 6);  	static final int AO_GPS_NUM_SAT_SHIFT = 0;  	static final int AO_GPS_NUM_SAT_MASK = 0xf; + +	static boolean isspace(int c) { +		switch (c) { +		case ' ': +		case '\t': +			return true; +		} +		return false; +	} + +	static boolean ishex(int c) { +		if ('0' <= c && c <= '9') +			return true; +		if ('a' <= c && c <= 'f') +			return true; +		if ('A' <= c && c <= 'F') +			return true; +		return false; +	} + +	static boolean ishex(String s) { +		for (int i = 0; i < s.length(); i++) +			if (!ishex(s.charAt(i))) +				return false; +		return true; +	} + +	static int fromhex(int c) { +		if ('0' <= c && c <= '9') +			return c - '0'; +		if ('a' <= c && c <= 'f') +			return c - 'a' + 10; +		if ('A' <= c && c <= 'F') +			return c - 'A' + 10; +		return -1; +	} + +	static int fromhex(String s) throws NumberFormatException { +		int c, v = 0; +		for (int i = 0; i < s.length(); i++) { +			c = s.charAt(i); +			if (!ishex(c)) { +				if (i == 0) +					throw new NumberFormatException(String.format("invalid hex \"%s\"", s)); +				return v; +			} +			v = v * 16 + fromhex(c); +		} +		return v; +	} + +	static boolean isdec(int c) { +		if ('0' <= c && c <= '9') +			return true; +		return false; +	} + +	static boolean isdec(String s) { +		for (int i = 0; i < s.length(); i++) +			if (!isdec(s.charAt(i))) +				return false; +		return true; +	} + +	static int fromdec(int c) { +		if ('0' <= c && c <= '9') +			return c - '0'; +		return -1; +	} + +	static int fromdec(String s) throws NumberFormatException { +		int c, v = 0; +		int sign = 1; +		for (int i = 0; i < s.length(); i++) { +			c = s.charAt(i); +			if (i == 0 && c == '-') { +				sign = -1; +			} else if (!isdec(c)) { +				if (i == 0) +					throw new NumberFormatException(String.format("invalid number \"%s\"", s)); +				return v; +			} else +				v = v * 10 + fromdec(c); +		} +		return v * sign; +	}  } diff --git a/ao-tools/altosui/AltosCRCException.java b/ao-tools/altosui/AltosCRCException.java new file mode 100644 index 00000000..4a529bcf --- /dev/null +++ b/ao-tools/altosui/AltosCRCException.java @@ -0,0 +1,26 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +public class AltosCRCException extends Exception { +	public int rssi; + +	public AltosCRCException (int in_rssi) { +		rssi = in_rssi; +	} +} diff --git a/ao-tools/altosui/AltosCSV.java b/ao-tools/altosui/AltosCSV.java index 24936758..4ce8e30e 100644 --- a/ao-tools/altosui/AltosCSV.java +++ b/ao-tools/altosui/AltosCSV.java @@ -19,12 +19,20 @@ package altosui;  import java.lang.*;  import java.io.*; +import java.text.*; +import java.util.*; +  import altosui.AltosRecord; +import altosui.AltosReader;  public class AltosCSV { -	File		name; -	PrintStream	out; -	boolean		header_written; +	File			name; +	PrintStream		out; +	boolean			header_written; +	boolean			seen_boost; +	int			boost_tick; +	LinkedList<AltosRecord>	pad_records; +	AltosState		state;  	static final int ALTOS_CSV_VERSION = 1; @@ -36,6 +44,7 @@ public class AltosCSV {  	 *	flight number  	 *	callsign  	 *	time (seconds since boost) +	 *	rssi  	 *  	 * Flight status  	 *	state @@ -45,6 +54,7 @@ public class AltosCSV {  	 *	acceleration (m/s²)  	 *	pressure (mBar)  	 *	altitude (m) +	 *	height (m)  	 *	accelerometer speed (m/s)  	 *	barometer speed (m/s)  	 *	temp (°C) @@ -65,6 +75,10 @@ public class AltosCSV {  	 *	hour (0-23)  	 *	minute (0-59)  	 *	second (0-59) +	 *	from_pad_dist (m) +	 *	from_pad_azimuth (deg true) +	 *	from_pad_range (m) +	 *	from_pad_elevation (deg from horizon)  	 *  	 * GPS Sat data  	 *	hdop @@ -72,12 +86,14 @@ public class AltosCSV {  	 */  	void write_general_header() { -		out.printf("version serial flight call time"); +		out.printf("version serial flight call time rssi");  	}  	void write_general(AltosRecord record) { -		out.printf("%s,%d,%d,%s,%d", -			   record.version, record.serial, record.flight, record.callsign, record.tick); +		out.printf("%s,%d,%d,%s,%8.2f,%4d", +			   record.version, record.serial, record.flight, record.callsign, +			   (double) record.time, +			   record.rssi);  	}  	void write_flight_header() { @@ -85,31 +101,137 @@ public class AltosCSV {  	}  	void write_flight(AltosRecord record) { -		out.printf("%d,%s", record.state, record.state()); +		out.printf("%d,%8s", record.state, record.state()); +	} + +	void write_basic_header() { +		out.printf("acceleration pressure altitude height accel_speed baro_speed temperature battery_voltage drogue_voltage main_voltage"); +	} + +	void write_basic(AltosRecord record) { +		out.printf("%8.2f,%10.2f,%8.2f,%8.2f,%8.2f,%8.2f,%5.1f,%5.2f,%5.2f,%5.2f", +			   record.acceleration(), +			   record.pressure(), +			   record.altitude(), +			   record.height(), +			   record.accel_speed(), +			   state.baro_speed, +			   record.temperature(), +			   record.battery_voltage(), +			   record.drogue_voltage(), +			   record.main_voltage()); +	} + +	void write_gps_header() { +		out.printf("connected locked nsat latitude longitude altitude year month day hour minute second pad_dist pad_range pad_az pad_el"); +	} + +	void write_gps(AltosRecord record) { +		AltosGPS	gps = record.gps; +		if (gps == null) +			gps = new AltosGPS(); + +		AltosGreatCircle from_pad = state.from_pad; +		if (from_pad == null) +			from_pad = new AltosGreatCircle(); + +		out.printf("%2d,%2d,%3d,%12.7f,%12.7f,%6d,%5d,%3d,%3d,%3d,%3d,%3d,%9.0f,%9.0f,%4.0f,%4.0f", +			   gps.connected?1:0, +			   gps.locked?1:0, +			   gps.nsat, +			   gps.lat, +			   gps.lon, +			   gps.alt, +			   gps.year, +			   gps.month, +			   gps.day, +			   gps.hour, +			   gps.minute, +			   gps.second, +			   from_pad.distance, +			   state.range, +			   from_pad.bearing, +			   state.elevation);  	}  	void write_header() {  		out.printf("# "); write_general_header();  		out.printf(" "); write_flight_header(); +		out.printf(" "); write_basic_header(); +		out.printf(" "); write_gps_header(); +		out.printf ("\n"); +	} + +	void write_one(AltosRecord record) { +		state = new AltosState(record, state); +		write_general(record); out.printf(","); +		write_flight(record); out.printf(","); +		write_basic(record); out.printf(","); +		write_gps(record);  		out.printf ("\n");  	} +	void flush_pad() { +		while (!pad_records.isEmpty()) { +			write_one (pad_records.remove()); +		} +	} +  	public void write(AltosRecord record) {  		if (!header_written) {  			write_header();  			header_written = true;  		} -		write_general(record); out.printf(","); -		write_flight(record); -		out.printf ("\n"); +		if (!seen_boost) { +			if (record.state >= Altos.ao_flight_boost) { +				seen_boost = true; +				boost_tick = record.tick; +				flush_pad(); +			} +		} +		if (seen_boost) +			write_one(record); +		else +			pad_records.add(record);  	}  	public PrintStream out() {  		return out;  	} +	public void close() { +		if (!pad_records.isEmpty()) { +			boost_tick = pad_records.element().tick; +			flush_pad(); +		} +		out.close(); +	} + +	public void write(AltosReader reader) { +		AltosRecord	record; + +		reader.write_comments(out()); +		try { +			for (;;) { +				record = reader.read(); +				if (record == null) +					break; +				write(record); +			} +		} catch (IOException ie) { +			System.out.printf("IOException\n"); +		} catch (ParseException pe) { +			System.out.printf("ParseException %s\n", pe.getMessage()); +		} +	} +  	public AltosCSV(File in_name) throws FileNotFoundException {  		name = in_name;  		out = new PrintStream(name); +		pad_records = new LinkedList<AltosRecord>(); +	} + +	public AltosCSV(String in_string) throws FileNotFoundException { +		this(new File(in_string));  	}  } diff --git a/ao-tools/altosui/AltosCSVUI.java b/ao-tools/altosui/AltosCSVUI.java new file mode 100644 index 00000000..2d812361 --- /dev/null +++ b/ao-tools/altosui/AltosCSVUI.java @@ -0,0 +1,83 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.table.*; +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.prefs.*; +import java.util.concurrent.LinkedBlockingQueue; + +import altosui.AltosLogfileChooser; +import altosui.AltosCSV; + +public class AltosCSVUI +	extends JDialog +	implements Runnable, ActionListener +{ +	JFrame		frame; +	Thread		thread; +	AltosReader	reader; +	AltosCSV	writer; + +	public void run() { +		AltosLogfileChooser	chooser; + +		chooser = new AltosLogfileChooser(frame); +		reader = chooser.runDialog(); +		if (reader == null) +			return; +		JFileChooser	csv_chooser; + +		File file = chooser.file(); +		String path = file.getPath(); +		int dot = path.lastIndexOf("."); +		if (dot >= 0) +			path = path.substring(0,dot); +		path = path.concat(".csv"); +		csv_chooser = new JFileChooser(path); +		int ret = csv_chooser.showSaveDialog(frame); +		if (ret == JFileChooser.APPROVE_OPTION) { +			try { +				writer = new AltosCSV(csv_chooser.getSelectedFile()); +			} catch (FileNotFoundException ee) { +				JOptionPane.showMessageDialog(frame, +							      file.getName(), +							      "Cannot open file", +							      JOptionPane.ERROR_MESSAGE); +			} +			writer.write(reader); +			reader.close(); +			writer.close(); +		} +	} + +	public void actionPerformed(ActionEvent e) { +	} + +	public AltosCSVUI(JFrame in_frame) { +		frame = in_frame; +		thread = new Thread(this); +		thread.start(); +	} +} diff --git a/ao-tools/altosui/AltosConfig.java b/ao-tools/altosui/AltosConfig.java index ac73e7c5..3d970748 100644 --- a/ao-tools/altosui/AltosConfig.java +++ b/ao-tools/altosui/AltosConfig.java @@ -122,17 +122,17 @@ public class AltosConfig implements Runnable, ActionListener {  	void start_serial() throws InterruptedException {  		if (remote) { -			serial_line.printf("m 0\n");  			serial_line.set_channel(AltosPreferences.channel());  			serial_line.set_callsign(AltosPreferences.callsign());  			serial_line.printf("p\n"); +			serial_line.flush_input();  		}  	}  	void stop_serial() throws InterruptedException {  		if (remote) { -			serial_line.printf("~\n"); -			serial_line.flush(); +			serial_line.printf("~"); +			serial_line.flush_output();  		}  	} diff --git a/ao-tools/altosui/AltosConfigUI.java b/ao-tools/altosui/AltosConfigUI.java index 1d8c579a..605ccc8b 100644 --- a/ao-tools/altosui/AltosConfigUI.java +++ b/ao-tools/altosui/AltosConfigUI.java @@ -44,7 +44,10 @@ import altosui.AltosFlightInfoTableModel;  import libaltosJNI.*; -public class AltosConfigUI extends JDialog implements ActionListener, ItemListener, DocumentListener { +public class AltosConfigUI +	extends JDialog +	implements ActionListener, ItemListener, DocumentListener +{  	Container	pane;  	Box		box; @@ -144,6 +147,7 @@ public class AltosConfigUI extends JDialog implements ActionListener, ItemListen  		c.fill = GridBagConstraints.NONE;  		c.anchor = GridBagConstraints.LINE_START;  		c.insets = il; +		c.ipady = 5;  		version_label = new JLabel("Software version:");  		pane.add(version_label, c); @@ -154,6 +158,7 @@ public class AltosConfigUI extends JDialog implements ActionListener, ItemListen  		c.weightx = 1;  		c.anchor = GridBagConstraints.LINE_START;  		c.insets = ir; +		c.ipady = 5;  		version_value = new JLabel("");  		pane.add(version_value, c); @@ -164,6 +169,7 @@ public class AltosConfigUI extends JDialog implements ActionListener, ItemListen  		c.fill = GridBagConstraints.NONE;  		c.anchor = GridBagConstraints.LINE_START;  		c.insets = il; +		c.ipady = 5;  		serial_label = new JLabel("Serial:");  		pane.add(serial_label, c); @@ -174,6 +180,7 @@ public class AltosConfigUI extends JDialog implements ActionListener, ItemListen  		c.weightx = 1;  		c.anchor = GridBagConstraints.LINE_START;  		c.insets = ir; +		c.ipady = 5;  		serial_value = new JLabel("");  		pane.add(serial_value, c); @@ -184,7 +191,7 @@ public class AltosConfigUI extends JDialog implements ActionListener, ItemListen  		c.fill = GridBagConstraints.NONE;  		c.anchor = GridBagConstraints.LINE_START;  		c.insets = il; -		c.ipady = 3; +		c.ipady = 5;  		main_deploy_label = new JLabel("Main Deploy Altitude(m):");  		pane.add(main_deploy_label, c); @@ -275,7 +282,7 @@ public class AltosConfigUI extends JDialog implements ActionListener, ItemListen  		/* Buttons */  		c = new GridBagConstraints();  		c.gridx = 0; c.gridy = 7; -		c.gridwidth = 2; +		c.gridwidth = 6;  		c.fill = GridBagConstraints.NONE;  		c.anchor = GridBagConstraints.LINE_START;  		c.insets = il; @@ -285,8 +292,8 @@ public class AltosConfigUI extends JDialog implements ActionListener, ItemListen  		save.setActionCommand("save");  		c = new GridBagConstraints(); -		c.gridx = 2; c.gridy = 7; -		c.gridwidth = 2; +		c.gridx = 0; c.gridy = 7; +		c.gridwidth = 6;  		c.fill = GridBagConstraints.NONE;  		c.anchor = GridBagConstraints.CENTER;  		c.insets = il; @@ -296,8 +303,8 @@ public class AltosConfigUI extends JDialog implements ActionListener, ItemListen  		reset.setActionCommand("reset");  		c = new GridBagConstraints(); -		c.gridx = 4; c.gridy = 7; -		c.gridwidth = 2; +		c.gridx = 0; c.gridy = 7; +		c.gridwidth = 6;  		c.fill = GridBagConstraints.NONE;  		c.anchor = GridBagConstraints.LINE_END;  		c.insets = il; diff --git a/ao-tools/altosui/AltosDebug.java b/ao-tools/altosui/AltosDebug.java new file mode 100644 index 00000000..3f469d48 --- /dev/null +++ b/ao-tools/altosui/AltosDebug.java @@ -0,0 +1,264 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +import java.lang.*; +import java.io.*; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.LinkedList; +import java.util.Iterator; +import altosui.AltosSerial; +import altosui.AltosRomconfig; + +public class AltosDebug extends AltosSerial { + +	public static final byte WR_CONFIG =		0x1d; +	public static final byte RD_CONFIG =		0x24; +	public static final byte CONFIG_TIMERS_OFF =		(1 << 3); +	public static final byte CONFIG_DMA_PAUSE =		(1 << 2); +	public static final byte CONFIG_TIMER_SUSPEND =		(1 << 1); +	public static final byte SET_FLASH_INFO_PAGE =		(1 << 0); + +	public static final byte GET_PC	=		0x28; +	public static final byte READ_STATUS =		0x34; +	public static final byte STATUS_CHIP_ERASE_DONE =	(byte) (1 << 7); +	public static final byte STATUS_PCON_IDLE =		(1 << 6); +	public static final byte STATUS_CPU_HALTED =		(1 << 5); +	public static final byte STATUS_POWER_MODE_0 =		(1 << 4); +	public static final byte STATUS_HALT_STATUS =		(1 << 3); +	public static final byte STATUS_DEBUG_LOCKED =		(1 << 2); +	public static final byte STATUS_OSCILLATOR_STABLE =	(1 << 1); +	public static final byte STATUS_STACK_OVERFLOW =	(1 << 0); + +	public static final byte SET_HW_BRKPNT =	0x3b; +	public static byte       HW_BRKPNT_N(byte n)	{ return (byte) ((n) << 3); } +	public static final byte HW_BRKPNT_N_MASK =		(0x3 << 3); +	public static final byte HW_BRKPNT_ENABLE =		(1 << 2); + +	public static final byte HALT =			0x44; +	public static final byte RESUME	=		0x4c; +	public static       byte DEBUG_INSTR(byte n)	{ return (byte) (0x54|(n)); } +	public static final byte STEP_INSTR =		0x5c; +	public static        byte STEP_REPLACE(byte n)	{ return  (byte) (0x64|(n)); } +	public static final byte GET_CHIP_ID =		0x68; + + +	boolean	debug_mode; + +	void ensure_debug_mode() { +		if (!debug_mode) { +			printf("D\n"); +			flush_input(); +			debug_mode = true; +		} +	} + +	void dump_memory(String header, int address, byte[] bytes, int start, int len) { +		System.out.printf("%s\n", header); +		for (int j = 0; j < len; j++) { +			if ((j & 15) == 0) { +				if (j != 0) +					System.out.printf("\n"); +				System.out.printf ("%04x:", address + j); +			} +			System.out.printf(" %02x", bytes[start + j]); +		} +		System.out.printf("\n"); +	} + +	/* +	 * Write target memory +	 */ +	public void write_memory(int address, byte[] bytes, int start, int len) { +		ensure_debug_mode(); +//		dump_memory("write_memory", address, bytes, start, len); +		printf("O %x %x\n", len, address); +		for (int i = 0; i < len; i++) +			printf("%02x", bytes[start + i]); +	} + +	public void write_memory(int address, byte[] bytes) { +		write_memory(address, bytes, 0, bytes.length); +	} + +	/* +	 * Read target memory +	 */ +	public byte[] read_memory(int address, int length) +		throws IOException, InterruptedException { +		byte[]	data = new byte[length]; + +		flush_input(); +		ensure_debug_mode(); +		printf("I %x %x\n", length, address); +		int i = 0; +		int start = 0; +		while (i < length) { +			String	line = get_reply().trim(); +			if (!Altos.ishex(line) || line.length() % 2 != 0) +				throw new IOException( +					String.format +					("Invalid reply \"%s\"", line)); +			int this_time = line.length() / 2; +			for (int j = 0; j < this_time; j++) +				data[start + j] = (byte) ((Altos.fromhex(line.charAt(j*2)) << 4) + +						  Altos.fromhex(line.charAt(j*2+1))); +			start += this_time; +			i += this_time; +		} +//		dump_memory("read_memory", address, data, 0, length); + +		return data; +	} + +	/* +	 * Write raw bytes to the debug link using the 'P' command +	 */ +	public void write_bytes(byte[] bytes) throws IOException { +		int i = 0; +		ensure_debug_mode(); +		while (i < bytes.length) { +			int this_time = bytes.length - i; +			if (this_time > 8) +				this_time = 0; +			printf("P"); +			for (int j = 0; j < this_time; j++) +				printf(" %02x", bytes[i+j]); +			printf("\n"); +			i += this_time; +		} +	} + +	public void write_byte(byte b) throws IOException { +		byte[] bytes = { b }; +		write_bytes(bytes); +	} + +	/* +	 * Read raw bytes from the debug link using the 'G' command +	 */ +	public byte[] read_bytes(int length) +		throws IOException, InterruptedException { + +		flush_input(); +		ensure_debug_mode(); +		printf("G %x\n", length); +		int i = 0; +		byte[] data = new byte[length]; +		while (i < length) { +			String line = get_reply().trim(); +			String tokens[] = line.split("\\s+"); +			for (int j = 0; j < tokens.length; j++) { +				if (!Altos.ishex(tokens[j]) || +				    tokens[j].length() != 2) +					throw new IOException( +						String.format +						("Invalid read_bytes reply \"%s\"", line)); +				try { +					data[i + j] = (byte) Integer.parseInt(tokens[j], 16); +				} catch (NumberFormatException ne) { +					throw new IOException( +						String.format +						("Invalid read_bytes reply \"%s\"", line)); +				} +			} +			i += tokens.length; +		} +		return data; +	} + +	public byte read_byte() throws IOException, InterruptedException { +		return read_bytes(1)[0]; +	} + +	public byte debug_instr(byte[] instruction) throws IOException, InterruptedException { +		byte[] command = new byte[1 + instruction.length]; +		command[0] = DEBUG_INSTR((byte) instruction.length); +		for (int i = 0; i < instruction.length; i++) +			command[i+1] = instruction[i]; +		write_bytes(command); +		return read_byte(); +	} + +	public byte resume() throws IOException, InterruptedException { +		write_byte(RESUME); +		return read_byte(); +	} + +	public int read_uint16() throws IOException, InterruptedException { +		byte[] d = read_bytes(2); +		return ((int) (d[0] & 0xff) << 8) | (d[1] & 0xff); +	} + +	public int read_uint8()  throws IOException, InterruptedException { +		byte[] d = read_bytes(1); +		return (int) (d[0] & 0xff); +	} + +	public int get_chip_id() throws IOException, InterruptedException { +		write_byte(GET_CHIP_ID); +		return read_uint16(); +	} + +	public int get_pc() throws IOException, InterruptedException { +		write_byte(GET_PC); +		return read_uint16(); +	} + +	public byte read_status() throws IOException, InterruptedException { +		write_byte(READ_STATUS); +		return read_byte(); +	} + +	static final byte LJMP			= 0x02; + +	public void set_pc(int pc) throws IOException, InterruptedException { +		byte high = (byte) (pc >> 8); +		byte low = (byte) pc; +		byte[] jump_mem = { LJMP, high, low }; +		debug_instr(jump_mem); +	} + +	public boolean check_connection() throws IOException, InterruptedException { +		byte reply = read_status(); +		if ((reply & STATUS_CHIP_ERASE_DONE) == 0) +			return false; +		if ((reply & STATUS_PCON_IDLE) != 0) +			return false; +		if ((reply & STATUS_POWER_MODE_0) == 0) +			return false; +		return true; +	} + +	public AltosRomconfig romconfig() { +		try { +			byte[] bytes = read_memory(0xa0, 10); +			return new AltosRomconfig(bytes, 0); +		} catch (IOException ie) { +		} catch (InterruptedException ie) { +		} +		return new AltosRomconfig(); +	} + +	/* +	 * Reset target +	 */ +	public void reset() { +		printf ("R\n"); +	} +}
\ No newline at end of file diff --git a/ao-tools/altosui/AltosDevice.java b/ao-tools/altosui/AltosDevice.java index 3daf0742..e62a0a7a 100644 --- a/ao-tools/altosui/AltosDevice.java +++ b/ao-tools/altosui/AltosDevice.java @@ -32,6 +32,7 @@ public class AltosDevice extends altos_device {  			System.err.println("Native library failed to load.\n" + e);  		}  	} +	public final static int AltusMetrum = libaltosConstants.USB_PRODUCT_ALTUSMETRUM;  	public final static int TeleMetrum = libaltosConstants.USB_PRODUCT_TELEMETRUM;  	public final static int TeleDongle = libaltosConstants.USB_PRODUCT_TELEDONGLE;  	public final static int TeleTerra = libaltosConstants.USB_PRODUCT_TELETERRA; @@ -58,33 +59,23 @@ public class AltosDevice extends altos_device {  	public boolean matchProduct(int want_product) { +		if (!isAltusMetrum()) +			return false; +  		if (want_product == Any)  			return true;  		if (want_product == BaseStation)  			return matchProduct(TeleDongle) || matchProduct(TeleTerra); -		if (!isAltusMetrum()) -			return false; -  		int have_product = getProduct(); -		if (want_product == have_product) +		if (have_product == AltusMetrum)	/* old devices match any request */  			return true; -		if (have_product != libaltosConstants.USB_PRODUCT_ALTUSMETRUM) -			return false; - -		String name = getName(); +		if (want_product == have_product) +			return true; -		if (name == null) -			return false; -		if (want_product == libaltosConstants.USB_PRODUCT_TELEMETRUM) -			return name.startsWith("TeleMetrum"); -		if (want_product == libaltosConstants.USB_PRODUCT_TELEDONGLE) -			return name.startsWith("TeleDongle"); -		if (want_product == libaltosConstants.USB_PRODUCT_TELETERRA) -			return name.startsWith("TeleTerra");  		return false;  	} diff --git a/ao-tools/altosui/AltosEepromDownload.java b/ao-tools/altosui/AltosEepromDownload.java index 02a71118..6dbbd3eb 100644 --- a/ao-tools/altosui/AltosEepromDownload.java +++ b/ao-tools/altosui/AltosEepromDownload.java @@ -142,6 +142,7 @@ public class AltosEepromDownload implements Runnable {  				if (values == null) {  					System.out.printf("invalid line: %s\n", line); +					continue;  				} else if (values[0] != addr) {  					System.out.printf("data address out of sync at 0x%x\n",  							  block * 256 + values[0]); @@ -223,10 +224,10 @@ public class AltosEepromDownload implements Runnable {  	public void run () {  		if (remote) { -			serial_line.printf("m 0\n");  			serial_line.set_channel(AltosPreferences.channel());  			serial_line.set_callsign(AltosPreferences.callsign()); -			serial_line.printf("p\n"); +			serial_line.printf("p\nE 0\n"); +			serial_line.flush_input();  		}  		monitor = new AltosEepromMonitor(frame, Altos.ao_flight_boost, Altos.ao_flight_landed); @@ -247,6 +248,7 @@ public class AltosEepromDownload implements Runnable {  		if (remote)  			serial_line.printf("~");  		monitor.done(); +		serial_line.flush_output();  		serial_line.close();  	} diff --git a/ao-tools/altosui/AltosEepromReader.java b/ao-tools/altosui/AltosEepromReader.java index c29fd90b..cb82f9a9 100644 --- a/ao-tools/altosui/AltosEepromReader.java +++ b/ao-tools/altosui/AltosEepromReader.java @@ -42,7 +42,7 @@ import altosui.AltosEepromMonitor;   */  class AltosOrderedRecord extends AltosEepromRecord implements Comparable<AltosOrderedRecord> { -	int	index; +	public int	index;  	public AltosOrderedRecord(String line, int in_index, int prev_tick)  		throws ParseException { @@ -56,6 +56,11 @@ class AltosOrderedRecord extends AltosEepromRecord implements Comparable<AltosOr  		index = in_index;  	} +	public AltosOrderedRecord(int in_cmd, int in_tick, int in_a, int in_b, int in_index) { +		super(in_cmd, in_tick, in_a, in_b); +		index = in_index; +	} +  	public int compareTo(AltosOrderedRecord o) {  		int	tick_diff = tick - o.tick;  		if (tick_diff != 0) @@ -96,10 +101,12 @@ public class AltosEepromReader extends AltosReader {  	int			gps_tick; -	boolean			saw_boost; -  	int			boost_tick; +	boolean			saw_gps_date; + +	boolean			missing_gps_time; +  	public AltosRecord read() throws IOException, ParseException {  		for (;;) {  			if (record == null) { @@ -107,7 +114,7 @@ public class AltosEepromReader extends AltosReader {  					if (last_reported)  						return null;  					last_reported = true; -					return state; +					return new AltosRecord(state);  				}  				record = record_iterator.next(); @@ -121,9 +128,7 @@ public class AltosEepromReader extends AltosReader {  			state.tick = record.tick;  			switch (record.cmd) {  			case Altos.AO_LOG_FLIGHT: -				state.ground_accel = record.a; -				state.flight = record.b; -				seen |= seen_flight; +				/* recorded when first read from the file */  				break;  			case Altos.AO_LOG_SENSOR:  				state.accel = record.a; @@ -133,8 +138,6 @@ public class AltosEepromReader extends AltosReader {  					ground_pres += state.pres;  					state.ground_pres = (int) (ground_pres / n_pad_samples);  					state.flight_pres = state.ground_pres; -					System.out.printf("ground pressure %d altitude %f\n", -							  record.b, state.altitude());  					ground_accel += state.accel;  					state.ground_accel = (int) (ground_accel / n_pad_samples);  					state.flight_accel = state.ground_accel; @@ -156,12 +159,19 @@ public class AltosEepromReader extends AltosReader {  				seen |= seen_deploy;  				break;  			case Altos.AO_LOG_STATE: -				System.out.printf("state %d\n", record.a);  				state.state = record.a;  				break;  			case Altos.AO_LOG_GPS_TIME:  				gps_tick = state.tick; +				AltosGPS old = state.gps;  				state.gps = new AltosGPS(); + +				/* GPS date doesn't get repeated through the file */ +				if (old != null) { +					state.gps.year = old.year; +					state.gps.month = old.month; +					state.gps.day = old.day; +				}  				state.gps.hour = (record.a & 0xff);  				state.gps.minute = (record.a >> 8);  				state.gps.second = (record.b & 0xff); @@ -191,7 +201,7 @@ public class AltosEepromReader extends AltosReader {  				}  				break;  			case Altos.AO_LOG_GPS_DATE: -				state.gps.year = record.a & 0xff; +				state.gps.year = (record.a & 0xff) + 2000;  				state.gps.month = record.a >> 8;  				state.gps.day = record.b & 0xff;  				break; @@ -218,6 +228,7 @@ public class AltosEepromReader extends AltosReader {  			case Altos.AO_LOG_PRODUCT:  				break;  			case Altos.AO_LOG_SERIAL_NUMBER: +				state.serial = record.a;  				break;  			case Altos.AO_LOG_SOFTWARE_VERSION:  				break; @@ -228,6 +239,7 @@ public class AltosEepromReader extends AltosReader {  	public void write_comments(PrintStream out) {  		Iterator<AltosOrderedRecord>	iterator = records.iterator(); +		out.printf("# Comments\n");  		while (iterator.hasNext()) {  			AltosOrderedRecord	record = iterator.next();  			switch (record.cmd) { @@ -250,7 +262,7 @@ public class AltosEepromReader extends AltosReader {  				out.printf ("# Accel cal: %d %d\n", record.a, record.b);  				break;  			case Altos.AO_LOG_RADIO_CAL: -				out.printf ("# Radio cal: %d %d\n", record.a); +				out.printf ("# Radio cal: %d\n", record.a);  				break;  			case Altos.AO_LOG_MANUFACTURER:  				out.printf ("# Manufacturer: %s\n", record.data); @@ -269,6 +281,34 @@ public class AltosEepromReader extends AltosReader {  	}  	/* +	 * Given an AO_LOG_GPS_TIME record with correct time, and one +	 * missing time, rewrite the missing time values with the good +	 * ones, assuming that the difference between them is 'diff' seconds +	 */ +	void update_time(AltosOrderedRecord good, AltosOrderedRecord bad) { + +		int diff = (bad.tick - good.tick + 50) / 100; + +		int hour = (good.a & 0xff); +		int minute = (good.a >> 8); +		int second = (good.b & 0xff); +		int flags = (good.b >> 8); +		int seconds = hour * 3600 + minute * 60 + second; + +		int new_seconds = seconds + diff; +		if (new_seconds < 0) +			new_seconds += 24 * 3600; +		int new_second = (new_seconds % 60); +		int new_minutes = (new_seconds / 60); +		int new_minute = (new_minutes % 60); +		int new_hours = (new_minutes / 60); +		int new_hour = (new_hours % 24); + +		bad.a = new_hour + (new_minute << 8); +		bad.b = new_second + (flags << 8); +	} + +	/*  	 * Read the whole file, dumping records into a RB tree so  	 * we can enumerate them in time order -- the eeprom data  	 * are sometimes out of order with GPS data getting timestamps @@ -283,9 +323,13 @@ public class AltosEepromReader extends AltosReader {  		seen = 0;  		records = new TreeSet<AltosOrderedRecord>(); +		AltosOrderedRecord last_gps_time = null; +  		int index = 0;  		int tick = 0; +		boolean missing_time = false; +  		try {  			for (;;) {  				String line = AltosRecord.gets(input); @@ -294,12 +338,55 @@ public class AltosEepromReader extends AltosReader {  				AltosOrderedRecord record = new AltosOrderedRecord(line, index++, tick);  				if (record == null)  					break; +				if (record.cmd == Altos.AO_LOG_INVALID) +					continue;  				tick = record.tick; -				if (!saw_boost && record.cmd == Altos.AO_LOG_STATE && -				    record.a == Altos.ao_flight_boost) -				{ -					saw_boost = true; -					boost_tick = state.tick; +				if (record.cmd == Altos.AO_LOG_FLIGHT) { +					state.ground_accel = record.a; +					state.flight = record.b; +					boost_tick = tick; +					seen |= seen_flight; +				} + +				/* Two firmware bugs caused the loss of some GPS data. +				 * The flight date would never be recorded, and often +				 * the flight time would get overwritten by another +				 * record. Detect the loss of the GPS date and fix up the +				 * missing time records +				 */ +				if (record.cmd == Altos.AO_LOG_GPS_DATE) +					saw_gps_date = true; + +				/* go back and fix up any missing time values */ +				if (record.cmd == Altos.AO_LOG_GPS_TIME) { +					last_gps_time = record; +					if (missing_time) { +						Iterator<AltosOrderedRecord> iterator = records.iterator(); +						while (iterator.hasNext()) { +							AltosOrderedRecord old = iterator.next(); +							if (old.cmd == Altos.AO_LOG_GPS_TIME && +							    old.a == -1 && old.b == -1) +							{ +								update_time(record, old); +							} +						} +						missing_time = false; +					} +				} + +				if (record.cmd == Altos.AO_LOG_GPS_LAT) { +					if (last_gps_time == null || last_gps_time.tick != record.tick) { +						AltosOrderedRecord add_gps_time = new AltosOrderedRecord(Altos.AO_LOG_GPS_TIME, +													 record.tick, +													 -1, -1, index-1); +						if (last_gps_time != null) +							update_time(last_gps_time, add_gps_time); +						else +							missing_time = true; + +						records.add(add_gps_time); +						record.index = index++; +					}  				}  				records.add(record);  			} diff --git a/ao-tools/altosui/AltosEepromRecord.java b/ao-tools/altosui/AltosEepromRecord.java index 86ac1fd2..95cbe015 100644 --- a/ao-tools/altosui/AltosEepromRecord.java +++ b/ao-tools/altosui/AltosEepromRecord.java @@ -44,10 +44,10 @@ public class AltosEepromRecord {  	public int	tick;  	public int	a;  	public int	b; -	String		data; +	public String	data;  	public boolean	tick_valid; -	public AltosEepromRecord (String line) throws ParseException { +	public AltosEepromRecord (String line) {  		tick_valid = false;  		tick = 0;  		a = 0; @@ -55,56 +55,72 @@ public class AltosEepromRecord {  		data = null;  		if (line == null) {  			cmd = Altos.AO_LOG_INVALID; +			data = "";  		} else { -			String[] tokens = line.split("\\s+"); +			try { +				String[] tokens = line.split("\\s+"); -			if (tokens[0].length() == 1) { -				if (tokens.length != 4) -					throw new ParseException(line, 0); -				cmd = tokens[0].codePointAt(0); -				tick = Integer.parseInt(tokens[1],16); -				tick_valid = true; -				a = Integer.parseInt(tokens[2],16); -				b = Integer.parseInt(tokens[3],16); -			} else if (tokens[0].equals("Config") && tokens[1].equals("version:")) { -				cmd = Altos.AO_LOG_CONFIG_VERSION; -				data = tokens[2]; -			} else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { -				cmd = Altos.AO_LOG_MAIN_DEPLOY; -				a = Integer.parseInt(tokens[2]); -			} else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { -				cmd = Altos.AO_LOG_APOGEE_DELAY; -				a = Integer.parseInt(tokens[2]); -			} else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { -				cmd = Altos.AO_LOG_RADIO_CHANNEL; -				a = Integer.parseInt(tokens[2]); -			} else if (tokens[0].equals("Callsign:")) { -				cmd = Altos.AO_LOG_CALLSIGN; -				data = tokens[1].replaceAll("\"",""); -			} else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { -				cmd = Altos.AO_LOG_ACCEL_CAL; -				a = Integer.parseInt(tokens[3]); -				b = Integer.parseInt(tokens[5]); -			} else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { -				cmd = Altos.AO_LOG_RADIO_CAL; -				a = Integer.parseInt(tokens[2]); -			} else if (tokens[0].equals("manufacturer")) { -				cmd = Altos.AO_LOG_MANUFACTURER; -				data = tokens[1]; -			} else if (tokens[0].equals("product")) { -				cmd = Altos.AO_LOG_PRODUCT; -				data = tokens[1]; -			} else if (tokens[0].equals("serial-number")) { -				cmd = Altos.AO_LOG_SERIAL_NUMBER; -				a = Integer.parseInt(tokens[1]); -			} else if (tokens[0].equals("software-version")) { -				cmd = Altos.AO_LOG_SOFTWARE_VERSION; -				data = tokens[1]; -			} else { +				if (tokens[0].length() == 1) { +					if (tokens.length != 4) { +						cmd = Altos.AO_LOG_INVALID; +						data = line; +					} else { +						cmd = tokens[0].codePointAt(0); +						tick = Integer.parseInt(tokens[1],16); +						tick_valid = true; +						a = Integer.parseInt(tokens[2],16); +						b = Integer.parseInt(tokens[3],16); +					} +				} else if (tokens[0].equals("Config") && tokens[1].equals("version:")) { +					cmd = Altos.AO_LOG_CONFIG_VERSION; +					data = tokens[2]; +				} else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { +					cmd = Altos.AO_LOG_MAIN_DEPLOY; +					a = Integer.parseInt(tokens[2]); +				} else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { +					cmd = Altos.AO_LOG_APOGEE_DELAY; +					a = Integer.parseInt(tokens[2]); +				} else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { +					cmd = Altos.AO_LOG_RADIO_CHANNEL; +					a = Integer.parseInt(tokens[2]); +				} else if (tokens[0].equals("Callsign:")) { +					cmd = Altos.AO_LOG_CALLSIGN; +					data = tokens[1].replaceAll("\"",""); +				} else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { +					cmd = Altos.AO_LOG_ACCEL_CAL; +					a = Integer.parseInt(tokens[3]); +					b = Integer.parseInt(tokens[5]); +				} else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { +					cmd = Altos.AO_LOG_RADIO_CAL; +					a = Integer.parseInt(tokens[2]); +				} else if (tokens[0].equals("manufacturer")) { +					cmd = Altos.AO_LOG_MANUFACTURER; +					data = tokens[1]; +				} else if (tokens[0].equals("product")) { +					cmd = Altos.AO_LOG_PRODUCT; +					data = tokens[1]; +				} else if (tokens[0].equals("serial-number")) { +					cmd = Altos.AO_LOG_SERIAL_NUMBER; +					a = Integer.parseInt(tokens[1]); +				} else if (tokens[0].equals("software-version")) { +					cmd = Altos.AO_LOG_SOFTWARE_VERSION; +					data = tokens[1]; +				} else { +					cmd = Altos.AO_LOG_INVALID; +					data = line; +				} +			} catch (NumberFormatException ne) {  				cmd = Altos.AO_LOG_INVALID;  				data = line;  			}  		}  	} +	public AltosEepromRecord(int in_cmd, int in_tick, int in_a, int in_b) { +		tick_valid = true; +		cmd = in_cmd; +		tick = in_tick; +		a = in_a; +		b = in_b; +	}  } diff --git a/ao-tools/altosui/AltosFlash.java b/ao-tools/altosui/AltosFlash.java new file mode 100644 index 00000000..a3e431cd --- /dev/null +++ b/ao-tools/altosui/AltosFlash.java @@ -0,0 +1,347 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.table.*; +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.prefs.*; +import java.util.concurrent.LinkedBlockingQueue; + +import altosui.AltosHexfile; + +public class AltosFlash { +	File		file; +	FileInputStream	input; +	AltosHexfile	image; +	JFrame		frame; +	AltosDevice	debug_dongle; +	AltosDebug	debug; +	AltosRomconfig	rom_config; +	ActionListener	listener; +	boolean		aborted; + +	static final byte MOV_direct_data	= (byte) 0x75; +	static final byte MOV_DPTR_data16	= (byte) 0x90; +	static final byte MOV_A_data		= (byte) 0x74; +	static final byte MOVX_atDPTR_A		= (byte) 0xf0; +	static final byte MOVX_A_atDPTR	        = (byte) 0xe0; +	static final byte INC_DPTR		= (byte) 0xa3; +	static final byte TRAP			= (byte) 0xa5; + +	static final byte JB			= (byte) 0x20; + +	static final byte MOV_A_direct		= (byte) 0xe5; +	static final byte MOV_direct1_direct2	= (byte) 0x85; +	static final byte MOV_direct_A		= (byte) 0xf5; +	static final byte MOV_R0_data		= (byte) (0x78 | 0); +	static final byte MOV_R1_data		= (byte) (0x78 | 1); +	static final byte MOV_R2_data		= (byte) (0x78 | 2); +	static final byte MOV_R3_data		= (byte) (0x78 | 3); +	static final byte MOV_R4_data		= (byte) (0x78 | 4); +	static final byte MOV_R5_data		= (byte) (0x78 | 5); +	static final byte MOV_R6_data		= (byte) (0x78 | 6); +	static final byte MOV_R7_data		= (byte) (0x78 | 7); +	static final byte DJNZ_R0_rel		= (byte) (0xd8 | 0); +	static final byte DJNZ_R1_rel		= (byte) (0xd8 | 1); +	static final byte DJNZ_R2_rel		= (byte) (0xd8 | 2); +	static final byte DJNZ_R3_rel		= (byte) (0xd8 | 3); +	static final byte DJNZ_R4_rel		= (byte) (0xd8 | 4); +	static final byte DJNZ_R5_rel		= (byte) (0xd8 | 5); +	static final byte DJNZ_R6_rel		= (byte) (0xd8 | 6); +	static final byte DJNZ_R7_rel		= (byte) (0xd8 | 7); + +	static final byte P1DIR			= (byte) 0xFE; +	static final byte P1			= (byte) 0x90; + +	/* flash controller */ +	static final byte FWT			= (byte) 0xAB; +	static final byte FADDRL		= (byte) 0xAC; +	static final byte FADDRH		= (byte) 0xAD; +	static final byte FCTL			= (byte) 0xAE; +	static final byte FCTL_BUSY		= (byte) 0x80; +	static final byte FCTL_BUSY_BIT		= (byte) 7; +	static final byte FCTL_SWBSY		= (byte) 0x40; +	static final byte FCTL_SWBSY_BIT	= (byte) 6; +	static final byte FCTL_CONTRD		= (byte) 0x10; +	static final byte FCTL_WRITE		= (byte) 0x02; +	static final byte FCTL_ERASE		= (byte) 0x01; +	static final byte FWDATA		= (byte) 0xAF; + +	static final byte ACC			= (byte) 0xE0; + +	/* offsets within the flash_page program */ +	static final int FLASH_ADDR_HIGH	= 8; +	static final int FLASH_ADDR_LOW		= 11; +	static final int RAM_ADDR_HIGH		= 13; +	static final int RAM_ADDR_LOW		= 14; +	static final int FLASH_WORDS_HIGH	= 16; +	static final int FLASH_WORDS_LOW	= 18; +	static final int FLASH_TIMING		= 21; + +	/* sleep mode control */ +	static final int SLEEP			= (byte) 0xbe; +	static final int  SLEEP_USB_EN		= (byte) 0x80; +	static final int  SLEEP_XOSC_STB	= (byte) 0x40; +	static final int  SLEEP_HFRC_STB	= (byte) 0x20; +	static final int  SLEEP_RST_MASK	= (byte) 0x18; +	static final int   SLEEP_RST_POWERON	= (byte) 0x00; +	static final int   SLEEP_RST_EXTERNAL	= (byte) 0x10; +	static final int   SLEEP_RST_WATCHDOG	= (byte) 0x08; +	static final int  SLEEP_OSC_PD		= (byte) 0x04; +	static final int  SLEEP_MODE_MASK	= (byte) 0x03; +	static final int   SLEEP_MODE_PM0	= (byte) 0x00; +	static final int   SLEEP_MODE_PM1	= (byte) 0x01; +	static final int   SLEEP_MODE_PM2	= (byte) 0x02; +	static final int   SLEEP_MODE_PM3	= (byte) 0x03; + +	/* clock controller */ +	static final byte CLKCON		= (byte) 0xC6; +	static final byte  CLKCON_OSC32K	= (byte) 0x80; +	static final byte  CLKCON_OSC		= (byte) 0x40; +	static final byte  CLKCON_TICKSPD	= (byte) 0x38; +	static final byte  CLKCON_CLKSPD	= (byte) 0x07; + +	static final byte[] flash_page_proto = { + +		MOV_direct_data, P1DIR, (byte) 0x02, +		MOV_direct_data, P1,	(byte) 0xFF, + +		MOV_direct_data, FADDRH, 0,	/* FLASH_ADDR_HIGH */ + +		MOV_direct_data, FADDRL, 0,	/* FLASH_ADDR_LOW */ + +		MOV_DPTR_data16, 0, 0,		/* RAM_ADDR_HIGH, RAM_ADDR_LOW */ + +		MOV_R7_data, 0,			/* FLASH_WORDS_HIGH */ + +		MOV_R6_data, 0,			/* FLASH_WORDS_LOW */ + + +		MOV_direct_data, FWT, 0x20,	/* FLASH_TIMING */ + +		MOV_direct_data, FCTL, FCTL_ERASE, +/* eraseWaitLoop: */ +		MOV_A_direct,		FCTL, +		JB, ACC|FCTL_BUSY_BIT, (byte) 0xfb, + +		MOV_direct_data, P1, (byte) 0xfd, + +		MOV_direct_data, FCTL, FCTL_WRITE, +/* writeLoop: */ +		MOV_R5_data, 2, +/* writeWordLoop: */ +		MOVX_A_atDPTR, +		INC_DPTR, +		MOV_direct_A, FWDATA, +		DJNZ_R5_rel, (byte) 0xfa,		/* writeWordLoop */ +/* writeWaitLoop: */ +		MOV_A_direct, FCTL, +		JB, ACC|FCTL_SWBSY_BIT, (byte) 0xfb,	/* writeWaitLoop */ +		DJNZ_R6_rel, (byte) 0xf1,		/* writeLoop */ +		DJNZ_R7_rel, (byte) 0xef,			/* writeLoop */ + +		MOV_direct_data, P1DIR, (byte) 0x00, +		MOV_direct_data, P1,	(byte) 0xFF, +		TRAP, +	}; + +	public byte[] make_flash_page(int flash_addr, int ram_addr, int byte_count) { +		int flash_word_addr = flash_addr >> 1; +		int flash_word_count = ((byte_count + 1) >> 1); + +		byte[] flash_page = new byte[flash_page_proto.length]; +		for (int i = 0; i < flash_page.length; i++) +			flash_page[i] = flash_page_proto[i]; + +		flash_page[FLASH_ADDR_HIGH]  = (byte) (flash_word_addr >> 8); +		flash_page[FLASH_ADDR_LOW]   = (byte) (flash_word_addr); +		flash_page[RAM_ADDR_HIGH]    = (byte) (ram_addr >> 8); +		flash_page[RAM_ADDR_LOW]     = (byte) (ram_addr); + +		byte flash_words_low = (byte) (flash_word_count); +		byte flash_words_high = (byte) (flash_word_count >> 8); +		/* the flashing code has a minor 'bug' */ +		if (flash_words_low != 0) +			flash_words_high++; + +		flash_page[FLASH_WORDS_HIGH] = (byte) flash_words_high; +		flash_page[FLASH_WORDS_LOW]  = (byte) flash_words_low; +		return flash_page; +	} + +	static byte[] set_clkcon_fast = { +		MOV_direct_data, CLKCON, 0x00 +	}; + +	static byte[] get_sleep = { +		MOV_A_direct, SLEEP +	}; + +	public void clock_init() throws IOException, InterruptedException { +		debug.debug_instr(set_clkcon_fast); + +		byte	status; +		for (int times = 0; times < 20; times++) { +			Thread.sleep(1); +			status = debug.debug_instr(get_sleep); +			if ((status & SLEEP_XOSC_STB) != 0) +				return; +		} +		throw new IOException("Failed to initialize target clock"); +	} + +	void action(String s, int percent) { +		if (listener != null && !aborted) +			listener.actionPerformed(new ActionEvent(this, +								 percent, +								 s)); +	} + +	void action(int part, int total) { +		int percent = 100 * part / total; +		action(String.format("%d/%d (%d%%)", +				     part, total, percent), +		       percent); +	} + +	void run(int pc) throws IOException, InterruptedException { +		debug.set_pc(pc); +		int set_pc = debug.get_pc(); +		if (pc != set_pc) +			throw new IOException("Failed to set target program counter"); +		debug.resume(); + +		for (int times = 0; times < 20; times++) { +			byte status = debug.read_status(); +			if ((status & AltosDebug.STATUS_CPU_HALTED) != 0) +				return; +		} + +		throw new IOException("Failed to execute program on target"); +	} + +	public void flash() throws IOException, FileNotFoundException, InterruptedException { +		if (!check_rom_config()) +			throw new IOException("Invalid rom config settings"); +		if (image.address + image.data.length > 0x8000) +			throw new IOException(String.format("Flash image too long %d", +							    image.address + +							    image.data.length)); +		if ((image.address & 0x3ff) != 0) +			throw new IOException(String.format("Flash image must start on page boundary (is 0x%x)", +							    image.address)); +		int ram_address = 0xf000; +		int flash_prog = 0xf400; + +		/* +		 * Store desired config values into image +		 */ +		rom_config.write(image); +		/* +		 * Bring up the clock +		 */ +		clock_init(); + +		int remain = image.data.length; +		int flash_addr = image.address; +		int image_start = 0; + +		action("start", 0); +		action(0, image.data.length); +		while (remain > 0 && !aborted) { +			int this_time = remain; +			if (this_time > 0x400) +				this_time = 0x400; + +			/* write the data */ +			debug.write_memory(ram_address, image.data, +					   image_start, this_time); + +			/* write the flash program */ +			byte[] flash_page = make_flash_page(flash_addr, +							    ram_address, +							    this_time); +			debug.write_memory(flash_prog, flash_page); + +			run(flash_prog); + +			byte[] check = debug.read_memory(flash_addr, this_time); +			for (int i = 0; i < this_time; i++) +				if (check[i] != image.data[image_start + i]) +					throw new IOException(String.format("Flash write failed at 0x%x (%02x != %02x)", +									    image.address + image_start + i, +									    check[i], image.data[image_start + i])); +			remain -= this_time; +			flash_addr += this_time; +			image_start += this_time; + +			action(image.data.length - remain, image.data.length); +		} +		if (!aborted) { +			action("done", 100); +			debug.set_pc(image.address); +			debug.resume(); +		} +		debug.close(); +	} + +	public void abort() { +		aborted = true; +		debug.close(); +	} + +	public void addActionListener(ActionListener l) { +		listener = l; +	} + +	public boolean check_rom_config() { +		if (rom_config == null) +			rom_config = debug.romconfig(); +		return rom_config != null && rom_config.valid(); +	} + +	public void set_romconfig (AltosRomconfig romconfig) { +		rom_config = romconfig; +	} + +	public AltosRomconfig romconfig() { +		if (!check_rom_config()) +			return null; +		return rom_config; +	} + +	public void open() throws IOException, FileNotFoundException, InterruptedException { +		input = new FileInputStream(file); +		image = new AltosHexfile(input); +		debug.open(debug_dongle); +		if (!debug.check_connection()) +			throw new IOException("Debug port not connected"); +	} + +	public AltosFlash(File in_file, AltosDevice in_debug_dongle) { +		file = in_file; +		debug_dongle = in_debug_dongle; +		debug = new AltosDebug(); +	} +}
\ No newline at end of file diff --git a/ao-tools/altosui/AltosFlashUI.java b/ao-tools/altosui/AltosFlashUI.java new file mode 100644 index 00000000..18795695 --- /dev/null +++ b/ao-tools/altosui/AltosFlashUI.java @@ -0,0 +1,209 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.table.*; +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.prefs.*; +import java.util.concurrent.LinkedBlockingQueue; + +import altosui.AltosHexfile; +import altosui.AltosFlash; + +public class AltosFlashUI +	extends JDialog +	implements Runnable, ActionListener +{ +	Container	pane; +	Box		box; +	JLabel		serial_label; +	JLabel		serial_value; +	JLabel		file_label; +	JLabel		file_value; +	JProgressBar	pbar; +	JButton		cancel; + +	File		file; +	Thread		thread; +	JFrame		frame; +	AltosDevice	debug_dongle; +	AltosFlash	flash; + +	public void actionPerformed(ActionEvent e) { +		if (e.getSource() == cancel) { +			abort(); +			dispose(); +		} else { +			String	cmd = e.getActionCommand(); +			if (cmd.equals("done")) +				; +			else if (cmd.equals("start")) { +				setVisible(true); +			} else { +				pbar.setValue(e.getID()); +				pbar.setString(cmd); +			} +		} +	} + +	public void run() { +		flash = new AltosFlash(file, debug_dongle); +		flash.addActionListener(this); +		try { +			flash.open(); +			AltosRomconfigUI romconfig_ui = new AltosRomconfigUI (frame); + +			romconfig_ui.set(flash.romconfig()); +			AltosRomconfig romconfig = romconfig_ui.showDialog(); + +			if (romconfig != null && romconfig.valid()) { +				flash.set_romconfig(romconfig); +				serial_value.setText(String.format("%d", +								   flash.romconfig().serial_number)); +				file_value.setText(file.toString()); +				setVisible(true); +				flash.flash(); +				flash = null; +			} +		} catch (FileNotFoundException ee) { +			JOptionPane.showMessageDialog(frame, +						      "Cannot open image", +						      file.toString(), +						      JOptionPane.ERROR_MESSAGE); +		} catch (IOException e) { +			JOptionPane.showMessageDialog(frame, +						      e.getMessage(), +						      file.toString(), +						      JOptionPane.ERROR_MESSAGE); +		} catch (InterruptedException ie) { +		} finally { +			abort(); +		} +		dispose(); +	} + +	public void abort() { +		if (flash != null) +			flash.abort(); +	} + +	public void build_dialog() { +		GridBagConstraints c; +		Insets il = new Insets(4,4,4,4); +		Insets ir = new Insets(4,4,4,4); + +		pane = getContentPane(); +		pane.setLayout(new GridBagLayout()); + +		c = new GridBagConstraints(); +		c.gridx = 0; c.gridy = 0; +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.LINE_START; +		c.insets = il; +		serial_label = new JLabel("Serial:"); +		pane.add(serial_label, c); + +		c = new GridBagConstraints(); +		c.gridx = 1; c.gridy = 0; +		c.fill = GridBagConstraints.HORIZONTAL; +		c.weightx = 1; +		c.anchor = GridBagConstraints.LINE_START; +		c.insets = ir; +		serial_value = new JLabel(""); +		pane.add(serial_value, c); + +		c = new GridBagConstraints(); +		c.fill = GridBagConstraints.NONE; +		c.gridx = 0; c.gridy = 1; +		c.anchor = GridBagConstraints.LINE_START; +		c.insets = il; +		file_label = new JLabel("File:"); +		pane.add(file_label, c); + +		c = new GridBagConstraints(); +		c.fill = GridBagConstraints.HORIZONTAL; +		c.weightx = 1; +		c.gridx = 1; c.gridy = 1; +		c.anchor = GridBagConstraints.LINE_START; +		c.insets = ir; +		file_value = new JLabel(""); +		pane.add(file_value, c); + +		pbar = new JProgressBar(); +		pbar.setMinimum(0); +		pbar.setMaximum(100); +		pbar.setValue(0); +		pbar.setString(""); +		pbar.setStringPainted(true); +		pbar.setPreferredSize(new Dimension(600, 20)); +		c = new GridBagConstraints(); +		c.fill = GridBagConstraints.HORIZONTAL; +		c.anchor = GridBagConstraints.CENTER; +		c.gridx = 0; c.gridy = 2; +		c.gridwidth = GridBagConstraints.REMAINDER; +		Insets ib = new Insets(4,4,4,4); +		c.insets = ib; +		pane.add(pbar, c); + +		cancel = new JButton("Cancel"); +		c = new GridBagConstraints(); +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.CENTER; +		c.gridx = 0; c.gridy = 3; +		c.gridwidth = GridBagConstraints.REMAINDER; +		Insets ic = new Insets(4,4,4,4); +		c.insets = ic; +		pane.add(cancel, c); +		cancel.addActionListener(this); +		pack(); +		setLocationRelativeTo(frame); +	} + +	public AltosFlashUI(JFrame in_frame) { +		super(in_frame, "Program Altusmetrum Device", false); + +		frame = in_frame; + +		build_dialog(); + +		debug_dongle = AltosDeviceDialog.show(frame, AltosDevice.Any); + +		if (debug_dongle == null) +			return; + +		JFileChooser	hexfile_chooser = new JFileChooser(); + +		hexfile_chooser.setDialogTitle("Select Flash Image"); +		hexfile_chooser.setFileFilter(new FileNameExtensionFilter("Flash Image", "ihx")); +		int returnVal = hexfile_chooser.showOpenDialog(frame); + +		if (returnVal != JFileChooser.APPROVE_OPTION) +			return; + +		file = hexfile_chooser.getSelectedFile(); + +		thread = new Thread(this); +		thread.start(); +	} +}
\ No newline at end of file diff --git a/ao-tools/altosui/AltosGPS.java b/ao-tools/altosui/AltosGPS.java index b3ee67e8..acb6fb2c 100644 --- a/ao-tools/altosui/AltosGPS.java +++ b/ao-tools/altosui/AltosGPS.java @@ -52,14 +52,16 @@ public class AltosGPS {  	AltosGPSSat[] cc_gps_sat;	/* tracking data */ -	void ParseGPSTime(String date, String time) throws ParseException { +	void ParseGPSDate(String date) throws ParseException {  		String[] ymd = date.split("-");  		if (ymd.length != 3)  			throw new ParseException("error parsing GPS date " + date + " got " + ymd.length, 0);  		year = AltosParse.parse_int(ymd[0]);  		month = AltosParse.parse_int(ymd[1]);  		day = AltosParse.parse_int(ymd[2]); +	} +	void ParseGPSTime(String time) throws ParseException {  		String[] hms = time.split(":");  		if (hms.length != 3)  			throw new ParseException("Error parsing GPS time " + time + " got " + hms.length, 0); @@ -73,7 +75,7 @@ public class AltosGPS {  		hour = minute = second = 0;  	} -	public AltosGPS(String[] words, int i) throws ParseException { +	public AltosGPS(String[] words, int i, int version) throws ParseException {  		AltosParse.word(words[i++], "GPS");  		nsat = AltosParse.parse_int(words[i++]);  		AltosParse.word(words[i++], "sat"); @@ -92,32 +94,44 @@ public class AltosGPS {  			locked = true;  			connected = true; -			ParseGPSTime(words[i], words[i+1]); i += 2; +			if (version > 1) +				ParseGPSDate(words[i++]); +			else +				year = month = day = 0; +			ParseGPSTime(words[i++]);  			lat = AltosParse.parse_coord(words[i++]);  			lon = AltosParse.parse_coord(words[i++]); -			alt = AltosParse.parse_int(AltosParse.strip_suffix(words[i++], "m")); -			ground_speed = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "m/s(H)")); -			course = AltosParse.parse_int(AltosParse.strip_suffix(words[i++], "°")); -			climb_rate = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "m/s(V)")); -			hdop = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "(hdop)")); -			h_error = AltosParse.parse_int(AltosParse.strip_suffix(words[i++], "(herr)")); -			v_error = AltosParse.parse_int(AltosParse.strip_suffix(words[i++], "(verr)")); +			alt = AltosParse.parse_int(words[i++]); +			if (version > 1 || (i < words.length && !words[i].equals("SAT"))) { +				ground_speed = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "m/s(H)")); +				course = AltosParse.parse_int(words[i++]); +				climb_rate = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "m/s(V)")); +				hdop = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "(hdop)")); +				h_error = AltosParse.parse_int(words[i++]); +				v_error = AltosParse.parse_int(words[i++]); +			}  		} else {  			i++;  		} -		AltosParse.word(words[i++], "SAT"); -		int tracking_channels = 0; -		if (words[i].equals("not-connected")) -			tracking_channels = 0; -		else -			tracking_channels = AltosParse.parse_int(words[i]); -		i++; -		cc_gps_sat = new AltosGPS.AltosGPSSat[tracking_channels]; -		for (int chan = 0; chan < tracking_channels; chan++) { -			cc_gps_sat[chan] = new AltosGPS.AltosGPSSat(); -			cc_gps_sat[chan].svid = AltosParse.parse_int(words[i++]); -			cc_gps_sat[chan].c_n0 = AltosParse.parse_int(words[i++]); -		} +		if (i < words.length) { +			AltosParse.word(words[i++], "SAT"); +			int tracking_channels = 0; +			if (words[i].equals("not-connected")) +				tracking_channels = 0; +			else +				tracking_channels = AltosParse.parse_int(words[i]); +			i++; +			cc_gps_sat = new AltosGPS.AltosGPSSat[tracking_channels]; +			for (int chan = 0; chan < tracking_channels; chan++) { +				cc_gps_sat[chan] = new AltosGPS.AltosGPSSat(); +				cc_gps_sat[chan].svid = AltosParse.parse_int(words[i++]); +				/* Older versions included SiRF status bits */ +				if (version < 2) +					i++; +				cc_gps_sat[chan].c_n0 = AltosParse.parse_int(words[i++]); +			} +		} else +			cc_gps_sat = new AltosGPS.AltosGPSSat[0];  	}  	public void set_latitude(int in_lat) { @@ -172,6 +186,7 @@ public class AltosGPS {  		nsat = old.nsat;  		locked = old.locked;  		connected = old.connected; +		date_valid = old.date_valid;  		lat = old.lat;		/* degrees (+N -S) */  		lon = old.lon;		/* degrees (+E -W) */  		alt = old.alt;		/* m */ diff --git a/ao-tools/altosui/AltosGreatCircle.java b/ao-tools/altosui/AltosGreatCircle.java index 878da03e..07c02c16 100644 --- a/ao-tools/altosui/AltosGreatCircle.java +++ b/ao-tools/altosui/AltosGreatCircle.java @@ -17,6 +17,8 @@  package altosui; +import altosui.AltosGPS; +  import java.lang.Math;  public class AltosGreatCircle { @@ -28,8 +30,8 @@ public class AltosGreatCircle {  	static final double rad = Math.PI / 180;  	static final double earth_radius = 6371.2 * 1000;	/* in meters */ -	AltosGreatCircle (double start_lat, double start_lon, -			  double end_lat, double end_lon) +	public AltosGreatCircle (double start_lat, double start_lon, +				 double end_lat, double end_lon)  	{  		double lat1 = rad * start_lat;  		double lon1 = rad * -start_lon; @@ -63,4 +65,13 @@ public class AltosGreatCircle {  		distance = d * earth_radius;  		bearing = course * 180/Math.PI;  	} + +	public AltosGreatCircle(AltosGPS start, AltosGPS end) { +		this(start.lat, start.lon, end.lat, end.lon); +	} + +	public AltosGreatCircle() { +		distance = 0; +		bearing = 0; +	}  } diff --git a/ao-tools/altosui/AltosHexfile.java b/ao-tools/altosui/AltosHexfile.java new file mode 100644 index 00000000..19e35ae1 --- /dev/null +++ b/ao-tools/altosui/AltosHexfile.java @@ -0,0 +1,252 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +import java.lang.*; +import java.io.*; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.LinkedList; +import java.util.Iterator; +import java.util.Arrays; + +class HexFileInputStream extends PushbackInputStream { +	public int line; + +	public HexFileInputStream(FileInputStream o) { +		super(new BufferedInputStream(o)); +		line = 1; +	} + +	public int read() throws IOException { +		int	c = super.read(); +		if (c == '\n') +			line++; +		return c; +	} + +	public void unread(int c) throws IOException { +		if (c == '\n') +			line--; +		if (c != -1) +			super.unread(c); +	} +} + +class HexRecord implements Comparable { +	public int	address; +	public int	type; +	public byte	checksum; +	public byte[]	data; + +	static final int NORMAL = 0; +	static final int EOF = 1; +	static final int EXTENDED_ADDRESS = 2; + +	enum read_state { +		marker, +		length, +		address, +		type, +		data, +		checksum, +		newline, +		white, +		done, +	} + +	boolean ishex(int c) { +		if ('0' <= c && c <= '9') +			return true; +		if ('a' <= c && c <= 'f') +			return true; +		if ('A' <= c && c <= 'F') +			return true; +		return false; +	} + +	boolean isspace(int c) { +		switch (c) { +		case ' ': +		case '\t': +			return true; +		} +		return false; +	} + +	int fromhex(int c) { +		if ('0' <= c && c <= '9') +			return c - '0'; +		if ('a' <= c && c <= 'f') +			return c - 'a' + 10; +		if ('A' <= c && c <= 'F') +			return c - 'A' + 10; +		return -1; +	} + +	public byte checksum() { +		byte	got = 0; + +		got += data.length; +		got += (address >> 8) & 0xff; +		got += (address     ) & 0xff; +		got += type; +		for (int i = 0; i < data.length; i++) +			got += data[i]; +		return (byte) (-got); +	} + +	public int compareTo(Object other) { +		HexRecord	o = (HexRecord) other; +		return address - o.address; +	} + +	public String toString() { +		return String.format("%04x: %02x (%d)", address, type, data.length); +	} + +	public HexRecord(HexFileInputStream input) throws IOException { +		read_state	state = read_state.marker; +		int		nhexbytes = 0; +		int		hex = 0; +		int		ndata = 0; +		byte		got_checksum; + +		while (state != read_state.done) { +			int c = input.read(); +			if (c < 0 && state != read_state.white) +				throw new IOException(String.format("%d: Unexpected EOF", input.line)); +			if (c == ' ') +				continue; +			switch (state) { +			case marker: +				if (c != ':') +					throw new IOException("Missing ':'"); +				state = read_state.length; +				nhexbytes = 2; +				hex = 0; +				break; +			case length: +			case address: +			case type: +			case data: +			case checksum: +				if(!ishex(c)) +					throw new IOException(String.format("Non-hex char '%c'", c)); +				hex = hex << 4 | fromhex(c); +				--nhexbytes; +				if (nhexbytes != 0) +					break; + +				switch (state) { +				case length: +					data = new byte[hex]; +					state = read_state.address; +					nhexbytes = 4; +					break; +				case address: +					address = hex; +					state = read_state.type; +					nhexbytes = 2; +					break; +				case type: +					type = hex; +					if (data.length > 0) +						state = read_state.data; +					else +						state = read_state.checksum; +					nhexbytes = 2; +					ndata = 0; +					break; +				case data: +					data[ndata] = (byte) hex; +					ndata++; +					nhexbytes = 2; +					if (ndata == data.length) +						state = read_state.checksum; +					break; +				case checksum: +					checksum = (byte) hex; +					state = read_state.newline; +					break; +				default: +					break; +				} +				hex = 0; +				break; +			case newline: +				if (c != '\n' && c != '\r') +					throw new IOException("Missing newline"); +				state = read_state.white; +				break; +			case white: +				if (!isspace(c)) { +					input.unread(c); +					state = read_state.done; +				} +				break; +			case done: +				break; +			} +		} +		got_checksum = checksum(); +		if (got_checksum != checksum) +			throw new IOException(String.format("Invalid checksum (read 0x%02x computed 0x%02x)\n", +							    checksum, got_checksum)); +	} +} + +public class AltosHexfile { +	public int	address; +	public byte[]	data; + +	public byte get_byte(int a) { +		return data[a - address]; +	} + +	public AltosHexfile(FileInputStream file) throws IOException { +		HexFileInputStream	input = new HexFileInputStream(file); +		LinkedList<HexRecord>	record_list = new LinkedList<HexRecord>(); +		boolean			done = false; + +		while (!done) { +			HexRecord	record = new HexRecord(input); + +			if (record.type == HexRecord.EOF) +				done = true; +			else +				record_list.add(record); +		} +		HexRecord[] records  = record_list.toArray(new HexRecord[0]); +		Arrays.sort(records); +		if (records.length > 0) { +			int	base = records[0].address; +			int	bound = records[records.length-1].address + +				records[records.length-1].data.length; + +			data = new byte[bound - base]; +			address = base; +			Arrays.fill(data, (byte) 0xff); + +			/* Paint the records into the new array */ +			for (int i = 0; i < records.length; i++) { +				for (int j = 0; j < records[i].data.length; j++) +					data[records[i].address - base + j] = records[i].data[j]; +			} +		} +	} +}
\ No newline at end of file diff --git a/ao-tools/altosui/AltosLine.java b/ao-tools/altosui/AltosLine.java new file mode 100644 index 00000000..86e9d4c6 --- /dev/null +++ b/ao-tools/altosui/AltosLine.java @@ -0,0 +1,30 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +public class AltosLine { +	public String	line; + +	public AltosLine() { +		line = null; +	} + +	public AltosLine(String s) { +		line = s; +	} +}
\ No newline at end of file diff --git a/ao-tools/altosui/AltosLog.java b/ao-tools/altosui/AltosLog.java index ec868b9c..f876beba 100644 --- a/ao-tools/altosui/AltosLog.java +++ b/ao-tools/altosui/AltosLog.java @@ -24,6 +24,7 @@ import java.text.ParseException;  import java.util.concurrent.LinkedBlockingQueue;  import altosui.AltosSerial;  import altosui.AltosFile; +import altosui.AltosLine;  /*   * This creates a thread to capture telemetry data and write it to @@ -31,7 +32,7 @@ import altosui.AltosFile;   */  class AltosLog implements Runnable { -	LinkedBlockingQueue<String>	input_queue; +	LinkedBlockingQueue<AltosLine>	input_queue;  	LinkedBlockingQueue<String>	pending_queue;  	int				serial;  	int				flight; @@ -64,9 +65,11 @@ class AltosLog implements Runnable {  	public void run () {  		try {  			for (;;) { -				String	line = input_queue.take(); +				AltosLine	line = input_queue.take(); +				if (line.line == null) +					continue;  				try { -					AltosTelemetry	telem = new AltosTelemetry(line); +					AltosTelemetry	telem = new AltosTelemetry(line.line);  					if (telem.serial != serial || telem.flight != flight || log_file == null) {  						close();  						serial = telem.serial; @@ -74,13 +77,14 @@ class AltosLog implements Runnable {  						open(telem);  					}  				} catch (ParseException pe) { +				} catch (AltosCRCException ce) {  				}  				if (log_file != null) { -					log_file.write(line); +					log_file.write(line.line);  					log_file.write('\n');  					log_file.flush();  				} else -					pending_queue.put(line); +					pending_queue.put(line.line);  			}  		} catch (InterruptedException ie) {  		} catch (IOException ie) { @@ -93,7 +97,7 @@ class AltosLog implements Runnable {  	public AltosLog (AltosSerial s) {  		pending_queue = new LinkedBlockingQueue<String> (); -		input_queue = new LinkedBlockingQueue<String> (); +		input_queue = new LinkedBlockingQueue<AltosLine> ();  		s.add_monitor(input_queue);  		serial = -1;  		flight = -1; diff --git a/ao-tools/altosui/AltosLogfileChooser.java b/ao-tools/altosui/AltosLogfileChooser.java new file mode 100644 index 00000000..36b51de6 --- /dev/null +++ b/ao-tools/altosui/AltosLogfileChooser.java @@ -0,0 +1,83 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.table.*; +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.prefs.*; + +import altosui.AltosPreferences; +import altosui.AltosReader; +import altosui.AltosEepromReader; +import altosui.AltosTelemetryReader; + +public class AltosLogfileChooser extends JFileChooser { +	JFrame	frame; +	String	filename; +	File	file; + +	public String filename() { +		return filename; +	} + +	public File file() { +		return file; +	} + +	public AltosReader runDialog() { +		int	ret; + +		ret = showOpenDialog(frame); +		if (ret == APPROVE_OPTION) { +			file = getSelectedFile(); +			if (file == null) +				return null; +			filename = file.getName(); +			try { +				FileInputStream in; + +				in = new FileInputStream(file); +				if (filename.endsWith("eeprom")) +					return new AltosEepromReader(in); +				else +					return new AltosTelemetryReader(in); +			} catch (FileNotFoundException fe) { +				JOptionPane.showMessageDialog(frame, +							      filename, +							      "Cannot open file", +							      JOptionPane.ERROR_MESSAGE); +			} +		} +		return null; +	} + +	public AltosLogfileChooser(JFrame in_frame) { +		frame = in_frame; +		setDialogTitle("Select Flight Record File"); +		setFileFilter(new FileNameExtensionFilter("Flight data file", +							  "eeprom", +							  "telem")); +		setCurrentDirectory(AltosPreferences.logdir()); +	} +}
\ No newline at end of file diff --git a/ao-tools/altosui/AltosParse.java b/ao-tools/altosui/AltosParse.java index a60dc694..4d82de78 100644 --- a/ao-tools/altosui/AltosParse.java +++ b/ao-tools/altosui/AltosParse.java @@ -20,10 +20,16 @@ package altosui;  import java.text.*;  import java.lang.*; +import altosui.Altos; +  public class AltosParse { +	static boolean isdigit(char c) { +		return '0' <= c && c <= '9'; +	} +  	static int parse_int(String v) throws ParseException {  		try { -			return Integer.parseInt(v); +			return Altos.fromdec(v);  		} catch (NumberFormatException e) {  			throw new ParseException("error parsing int " + v, 0);  		} @@ -31,7 +37,7 @@ public class AltosParse {  	static int parse_hex(String v) throws ParseException {  		try { -			return Integer.parseInt(v, 16); +			return Altos.fromhex(v);  		} catch (NumberFormatException e) {  			throw new ParseException("error parsing hex " + v, 0);  		} diff --git a/ao-tools/altosui/AltosReader.java b/ao-tools/altosui/AltosReader.java index 81779e2b..5be8795d 100644 --- a/ao-tools/altosui/AltosReader.java +++ b/ao-tools/altosui/AltosReader.java @@ -25,4 +25,6 @@ import altosui.AltosRecord;  public class AltosReader {  	public AltosRecord read() throws IOException, ParseException { return null; } +	public void close() { } +	public void write_comments(PrintStream out) { }  } diff --git a/ao-tools/altosui/AltosRomconfig.java b/ao-tools/altosui/AltosRomconfig.java new file mode 100644 index 00000000..22d2dbd3 --- /dev/null +++ b/ao-tools/altosui/AltosRomconfig.java @@ -0,0 +1,148 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; +import java.io.*; +import altosui.AltosHexfile; + +public class AltosRomconfig { +	public boolean	valid; +	public int	version; +	public int	check; +	public int	serial_number; +	public int	radio_calibration; + +	static int get_int(byte[] bytes, int start, int len) { +		int	v = 0; +		int	o = 0; +		while (len > 0) { +			v = v | ((((int) bytes[start]) & 0xff) << o); +			start++; +			len--; +			o += 8; +		} +		return v; +	} + +	static void put_int(int value, byte[] bytes, int start, int len) { +		while (len > 0) { +			bytes[start] = (byte) (value & 0xff); +			start++; +			len--; +			value >>= 8; +		} +	} + +	static void put_string(String value, byte[] bytes, int start) { +		for (int i = 0; i < value.length(); i++) +			bytes[start + i] = (byte) value.charAt(i); +	} + +	static final int AO_USB_DESC_STRING	= 3; + +	static void put_usb_serial(int value, byte[] bytes, int start) { +		int offset = start + 0xa; +		int string_num = 0; + +		while (offset < bytes.length && bytes[offset] != 0) { +			if (bytes[offset + 1] == AO_USB_DESC_STRING) { +				++string_num; +				if (string_num == 4) +					break; +			} +			offset += ((int) bytes[offset]) & 0xff; +		} +		if (offset >= bytes.length || bytes[offset] == 0) +			return; +		int len = ((((int) bytes[offset]) & 0xff) - 2) / 2; +		String fmt = String.format("%%0%dd", len); + +		String s = String.format(fmt, value); +		if (s.length() != len) { +			System.out.printf("weird usb length issue %s isn't %d\n", +					  s, len); +			return; +		} +		for (int i = 0; i < len; i++) { +			bytes[offset + 2 + i*2] = (byte) s.charAt(i); +			bytes[offset + 2 + i*2+1] = 0; +		} +	} + +	public AltosRomconfig(byte[] bytes, int offset) { +		version = get_int(bytes, offset + 0, 2); +		check = get_int(bytes, offset + 2, 2); +		if (check == (~version & 0xffff)) { +			switch (version) { +			case 2: +			case 1: +				serial_number = get_int(bytes, offset + 4, 2); +				radio_calibration = get_int(bytes, offset + 6, 4); +				valid = true; +				break; +			} +		} +	} + +	public AltosRomconfig(AltosHexfile hexfile) { +		this(hexfile.data, 0xa0 - hexfile.address); +	} + +	public void write(byte[] bytes, int offset) throws IOException { +		if (!valid) +			throw new IOException("rom configuration invalid"); + +		if (offset < 0 || bytes.length < offset + 10) +			throw new IOException("image cannot contain rom config"); + +		AltosRomconfig existing = new AltosRomconfig(bytes, offset); +		if (!existing.valid) +			throw new IOException("image does not contain existing rom config"); + +		switch (existing.version) { +		case 2: +			put_usb_serial(serial_number, bytes, offset); +		case 1: +			put_int(serial_number, bytes, offset + 4, 2); +			put_int(radio_calibration, bytes, offset + 6, 4); +			break; +		} +	} + +	public void write (AltosHexfile hexfile) throws IOException { +		write(hexfile.data, 0xa0 - hexfile.address); +		AltosRomconfig check = new AltosRomconfig(hexfile); +		if (!check.valid()) +			throw new IOException("writing new rom config failed\n"); +	} + +	public AltosRomconfig(int in_serial_number, int in_radio_calibration) { +		valid = true; +		version = 1; +		check = (~version & 0xffff); +		serial_number = in_serial_number; +		radio_calibration = in_radio_calibration; +	} + +	public boolean valid() { +		return valid && serial_number != 0; +	} + +	public AltosRomconfig() { +		valid = false; +	} +} diff --git a/ao-tools/altosui/AltosRomconfigUI.java b/ao-tools/altosui/AltosRomconfigUI.java new file mode 100644 index 00000000..2134975d --- /dev/null +++ b/ao-tools/altosui/AltosRomconfigUI.java @@ -0,0 +1,188 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.table.*; +import javax.swing.event.*; +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.prefs.*; + +import altosui.AltosRomconfig; + +public class AltosRomconfigUI +	extends JDialog +	implements ActionListener +{ +	Container	pane; +	Box		box; +	JLabel		serial_label; +	JLabel		radio_calibration_label; + +	JFrame		owner; +	JTextField	serial_value; +	JTextField	radio_calibration_value; + +	JButton		ok; +	JButton		cancel; + +	/* Build the UI using a grid bag */ +	public AltosRomconfigUI(JFrame in_owner) { +		super (in_owner, "Configure TeleMetrum Rom Values", true); + +		owner = in_owner; +		GridBagConstraints c; + +		Insets il = new Insets(4,4,4,4); +		Insets ir = new Insets(4,4,4,4); + +		pane = getContentPane(); +		pane.setLayout(new GridBagLayout()); + +		/* Serial */ +		c = new GridBagConstraints(); +		c.gridx = 0; c.gridy = 0; +		c.gridwidth = 3; +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.LINE_START; +		c.insets = il; +		serial_label = new JLabel("Serial:"); +		pane.add(serial_label, c); + +		c = new GridBagConstraints(); +		c.gridx = 3; c.gridy = 0; +		c.gridwidth = 3; +		c.fill = GridBagConstraints.HORIZONTAL; +		c.weightx = 1; +		c.anchor = GridBagConstraints.LINE_START; +		c.insets = ir; +		serial_value = new JTextField("0"); +		pane.add(serial_value, c); + +		/* Radio calibration value */ +		c = new GridBagConstraints(); +		c.gridx = 0; c.gridy = 1; +		c.gridwidth = 3; +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.LINE_START; +		c.insets = il; +		c.ipady = 5; +		radio_calibration_label = new JLabel("Radio Calibration:"); +		pane.add(radio_calibration_label, c); + +		c = new GridBagConstraints(); +		c.gridx = 3; c.gridy = 1; +		c.gridwidth = 3; +		c.fill = GridBagConstraints.HORIZONTAL; +		c.weightx = 1; +		c.anchor = GridBagConstraints.LINE_START; +		c.insets = ir; +		c.ipady = 5; +		radio_calibration_value = new JTextField("1186611"); +		pane.add(radio_calibration_value, c); + +		/* Buttons */ +		c = new GridBagConstraints(); +		c.gridx = 0; c.gridy = 2; +		c.gridwidth = 3; +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.CENTER; +		c.insets = il; +		ok = new JButton("OK"); +		pane.add(ok, c); +		ok.addActionListener(this); +		ok.setActionCommand("ok"); + +		c = new GridBagConstraints(); +		c.gridx = 3; c.gridy = 2; +		c.gridwidth = 3; +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.CENTER; +		c.insets = il; +		cancel = new JButton("Cancel"); +		pane.add(cancel, c); +		cancel.addActionListener(this); +		cancel.setActionCommand("cancel"); + +		pack(); +		setLocationRelativeTo(owner); +	} + +	boolean	selected; + +	/* Listen for events from our buttons */ +	public void actionPerformed(ActionEvent e) { +		String	cmd = e.getActionCommand(); + +		if (cmd.equals("ok")) { +			AltosRomconfig	romconfig = romconfig(); +			if (romconfig == null || !romconfig.valid()) { +				JOptionPane.showMessageDialog(this, +							      "Invalid serial number or radio calibration value", +							      "Invalid rom configuration", +							      JOptionPane.ERROR_MESSAGE); +				return; +			} +			selected = true; +		} +		setVisible(false); +	} + +	int serial() { +		return Integer.parseInt(serial_value.getText()); +	} + +	void set_serial(int serial) { +		serial_value.setText(String.format("%d", serial)); +	} + +	int radio_calibration() { +		return Integer.parseInt(radio_calibration_value.getText()); +	} + +	void set_radio_calibration(int calibration) { +		radio_calibration_value.setText(String.format("%d", calibration)); +	} + +	public void set(AltosRomconfig config) { +		if (config != null && config.valid()) { +			set_serial(config.serial_number); +			set_radio_calibration(config.radio_calibration); +		} +	} + +	AltosRomconfig romconfig() { +		try { +			return new AltosRomconfig(serial(), radio_calibration()); +		} catch (NumberFormatException ne) { +			return null; +		} +	} + +	public AltosRomconfig showDialog() { +		setVisible(true); +		if (selected) +			return romconfig(); +		return null; +	} +} diff --git a/ao-tools/altosui/AltosSerial.java b/ao-tools/altosui/AltosSerial.java index ba00b55e..a1fc4371 100644 --- a/ao-tools/altosui/AltosSerial.java +++ b/ao-tools/altosui/AltosSerial.java @@ -27,10 +27,12 @@ import java.util.concurrent.LinkedBlockingQueue;  import java.util.LinkedList;  import java.util.Iterator;  import altosui.AltosSerialMonitor; +import altosui.AltosLine;  import libaltosJNI.libaltos;  import libaltosJNI.altos_device;  import libaltosJNI.SWIGTYPE_p_altos_file;  import libaltosJNI.SWIGTYPE_p_altos_list; +import libaltosJNI.libaltosConstants;  /*   * This class reads from the serial port and places each received @@ -41,10 +43,13 @@ import libaltosJNI.SWIGTYPE_p_altos_list;  public class AltosSerial implements Runnable {  	SWIGTYPE_p_altos_file altos; -	LinkedList<LinkedBlockingQueue<String>> monitors; -	LinkedBlockingQueue<String> reply_queue; +	LinkedList<LinkedBlockingQueue<AltosLine>> monitors; +	LinkedBlockingQueue<AltosLine> reply_queue;  	Thread input_thread;  	String line; +	byte[] line_bytes; +	int line_count; +	boolean monitor_mode;  	public void run () {  		int c; @@ -54,24 +59,50 @@ public class AltosSerial implements Runnable {  				c = libaltos.altos_getchar(altos, 0);  				if (Thread.interrupted())  					break; -				if (c == -1) +				if (c == libaltosConstants.LIBALTOS_ERROR) { +					for (int e = 0; e < monitors.size(); e++) { +						LinkedBlockingQueue<AltosLine> q = monitors.get(e); +						q.put(new AltosLine()); +					} +					reply_queue.put (new AltosLine()); +					break; +				} +				if (c == libaltosConstants.LIBALTOS_TIMEOUT)  					continue;  				if (c == '\r')  					continue;  				synchronized(this) {  					if (c == '\n') { -						if (line != "") { -							if (line.startsWith("VERSION")) { +						if (line_count != 0) { +							try { +								line = new String(line_bytes, 0, line_count, "UTF-8"); +							} catch (UnsupportedEncodingException ue) { +								line = ""; +								for (int i = 0; i < line_count; i++) +									line = line + line_bytes[i]; +							} +							if (line.startsWith("VERSION") || line.startsWith("CRC")) {  								for (int e = 0; e < monitors.size(); e++) { -									LinkedBlockingQueue<String> q = monitors.get(e); -									q.put(line); +									LinkedBlockingQueue<AltosLine> q = monitors.get(e); +									q.put(new AltosLine (line));  								} -							} else -								reply_queue.put(line); +							} else { +//								System.out.printf("GOT: %s\n", line); +								reply_queue.put(new AltosLine (line)); +							} +							line_count = 0;  							line = "";  						}  					} else { -						line = line + (char) c; +						if (line_bytes == null) { +							line_bytes = new byte[256]; +						} else if (line_count == line_bytes.length) { +							byte[] new_line_bytes = new byte[line_count * 2]; +							System.arraycopy(line_bytes, 0, new_line_bytes, 0, line_count); +							line_bytes = new_line_bytes; +						} +						line_bytes[line_count] = (byte) c; +						line_count++;  					}  				}  			} @@ -79,24 +110,40 @@ public class AltosSerial implements Runnable {  		}  	} +	public void flush_output() { +		if (altos != null) +			libaltos.altos_flush(altos); +	} + +	public void flush_input() { +		flush_output(); +		try { +			Thread.sleep(200); +		} catch (InterruptedException ie) { +		} +		synchronized(this) { +			if (!"VERSION".startsWith(line) && +			    !line.startsWith("VERSION")) +				line = ""; +			reply_queue.clear(); +		} +	} +  	public String get_reply() throws InterruptedException { -		return reply_queue.take(); +		flush_output(); +		AltosLine line = reply_queue.take(); +		return line.line;  	} -	public void add_monitor(LinkedBlockingQueue<String> q) { +	public void add_monitor(LinkedBlockingQueue<AltosLine> q) { +		set_monitor(true);  		monitors.add(q);  	} -	public void remove_monitor(LinkedBlockingQueue<String> q) { +	public void remove_monitor(LinkedBlockingQueue<AltosLine> q) {  		monitors.remove(q); -	} - -	public void flush () { -		synchronized(this) { -			if (!"VERSION".startsWith(line) && !line.startsWith("VERSION")) -				line = ""; -			reply_queue.clear(); -		} +		if (monitors.isEmpty()) +			set_monitor(false);  	}  	public boolean opened() { @@ -104,8 +151,9 @@ public class AltosSerial implements Runnable {  	}  	public void close() { -		if (altos != null) +		if (altos != null) {  			libaltos.altos_close(altos); +		}  		if (input_thread != null) {  			try {  				input_thread.interrupt(); @@ -126,6 +174,7 @@ public class AltosSerial implements Runnable {  	}  	public void print(String data) { +//		System.out.printf("\"%s\" ", data);  		for (int i = 0; i < data.length(); i++)  			putc(data.charAt(i));  	} @@ -141,29 +190,45 @@ public class AltosSerial implements Runnable {  			throw new FileNotFoundException(device.getPath());  		input_thread = new Thread(this);  		input_thread.start(); -		print("\nE 0\n"); -		try { -			Thread.sleep(200); -		} catch (InterruptedException e) { -		} -		flush(); +		print("~\nE 0\n"); +		flush_output(); +		set_monitor(monitor_mode);  	}  	public void set_channel(int channel) { -		if (altos != null) -			printf("m 0\nc r %d\nm 1\n", channel); +		if (altos != null) { +			if (monitor_mode) +				printf("m 0\nc r %d\nm 1\n", channel); +			else +				printf("c r %d\n", channel); +			flush_output(); +		} +	} + +	void set_monitor(boolean monitor) { +		monitor_mode = monitor; +		if (altos != null) { +			if (monitor) +				printf("m 1\n"); +			else +				printf("m 0\n"); +			flush_output(); +		}  	}  	public void set_callsign(String callsign) { -		if (altos != null) +		if (altos != null) {  			printf ("c c %s\n", callsign); +			flush_output(); +		}  	}  	public AltosSerial() {  		altos = null;  		input_thread = null;  		line = ""; -		monitors = new LinkedList<LinkedBlockingQueue<String>> (); -		reply_queue = new LinkedBlockingQueue<String> (); +		monitor_mode = false; +		monitors = new LinkedList<LinkedBlockingQueue<AltosLine>> (); +		reply_queue = new LinkedBlockingQueue<AltosLine> ();  	}  } diff --git a/ao-tools/altosui/AltosState.java b/ao-tools/altosui/AltosState.java index deeb4c77..3ef00f35 100644 --- a/ao-tools/altosui/AltosState.java +++ b/ao-tools/altosui/AltosState.java @@ -64,6 +64,8 @@ public class AltosState {  	boolean	gps_ready;  	AltosGreatCircle from_pad; +	double	elevation;	/* from pad */ +	double	range;		/* total distance */  	double	gps_height; @@ -124,12 +126,7 @@ public class AltosState {  		}  		if (state == Altos.ao_flight_pad) { -			if (data.gps == null) -				System.out.printf("on pad, gps null\n"); -			else -				System.out.printf ("on pad gps lat %f lon %f locked %d nsat %d\n", -						   data.gps.lat, data.gps.lon, data.gps.locked ? 1 : 0, data.gps.nsat); -			if (data.gps != null && data.gps.locked && data.gps.nsat >= 4) { +			if (data.gps != null && data.gps.locked) {  				npad++;  				if (npad > 1) {  					/* filter pad position */ @@ -166,11 +163,18 @@ public class AltosState {  		if (data.gps != null) {  			if (gps == null || !gps.locked || data.gps.locked)  				gps = data.gps; -			if (npad > 0 && gps.locked) +			if (npad > 0 && gps.locked) {  				from_pad = new AltosGreatCircle(pad_lat, pad_lon, gps.lat, gps.lon); +			}  		} +		elevation = 0; +		range = -1;  		if (npad > 0) {  			gps_height = gps.alt - pad_alt; +			if (from_pad != null) { +				elevation = Math.atan2(height, from_pad.distance) * 180 / Math.PI; +				range = Math.sqrt(height * height + from_pad.distance * from_pad.distance); +			}  		} else {  			gps_height = 0;  		} diff --git a/ao-tools/altosui/AltosTelemetry.java b/ao-tools/altosui/AltosTelemetry.java index af29b8c0..be22dac6 100644 --- a/ao-tools/altosui/AltosTelemetry.java +++ b/ao-tools/altosui/AltosTelemetry.java @@ -23,6 +23,7 @@ import java.util.HashMap;  import altosui.AltosConvert;  import altosui.AltosRecord;  import altosui.AltosGPS; +import altosui.AltosCRCException;  /*   * Telemetry data contents @@ -53,12 +54,22 @@ import altosui.AltosGPS;   */  public class AltosTelemetry extends AltosRecord { -	public AltosTelemetry(String line) throws ParseException { +	public AltosTelemetry(String line) throws ParseException, AltosCRCException {  		String[] words = line.split("\\s+");  		int	i = 0; -		AltosParse.word (words[i++], "VERSION"); -		version = AltosParse.parse_int(words[i++]); +		if (words[i].equals("CRC") && words[i+1].equals("INVALID")) { +			i += 2; +			AltosParse.word(words[i++], "RSSI"); +			rssi = AltosParse.parse_int(words[i++]); +			throw new AltosCRCException(rssi); +		} +		if (words[i].equals("CALL")) { +			version = 0; +		} else { +			AltosParse.word (words[i++], "VERSION"); +			version = AltosParse.parse_int(words[i++]); +		}  		AltosParse.word (words[i++], "CALL");  		callsign = words[i++]; @@ -66,12 +77,19 @@ public class AltosTelemetry extends AltosRecord {  		AltosParse.word (words[i++], "SERIAL");  		serial = AltosParse.parse_int(words[i++]); -		AltosParse.word (words[i++], "FLIGHT"); -		flight = AltosParse.parse_int(words[i++]); +		if (version >= 2) { +			AltosParse.word (words[i++], "FLIGHT"); +			flight = AltosParse.parse_int(words[i++]); +		} else +			flight = 0;  		AltosParse.word(words[i++], "RSSI");  		rssi = AltosParse.parse_int(words[i++]); +		/* Older telemetry data had mis-computed RSSI value */ +		if (version <= 2) +			rssi = (rssi + 74) / 2 - 74; +  		AltosParse.word(words[i++], "STATUS");  		status = AltosParse.parse_hex(words[i++]); @@ -113,12 +131,17 @@ public class AltosTelemetry extends AltosRecord {  		AltosParse.word(words[i++], "gp:");  		ground_pres = AltosParse.parse_int(words[i++]); -		AltosParse.word(words[i++], "a+:"); -		accel_plus_g = AltosParse.parse_int(words[i++]); +		if (version >= 1) { +			AltosParse.word(words[i++], "a+:"); +			accel_plus_g = AltosParse.parse_int(words[i++]); -		AltosParse.word(words[i++], "a-:"); -		accel_minus_g = AltosParse.parse_int(words[i++]); +			AltosParse.word(words[i++], "a-:"); +			accel_minus_g = AltosParse.parse_int(words[i++]); +		} else { +			accel_plus_g = ground_accel; +			accel_minus_g = ground_accel + 530; +		} -		gps = new AltosGPS(words, i); +		gps = new AltosGPS(words, i, version);  	}  } diff --git a/ao-tools/altosui/AltosTelemetryReader.java b/ao-tools/altosui/AltosTelemetryReader.java index f1f6788c..fdedbde2 100644 --- a/ao-tools/altosui/AltosTelemetryReader.java +++ b/ao-tools/altosui/AltosTelemetryReader.java @@ -47,20 +47,27 @@ public class AltosTelemetryReader extends AltosReader {  		try {  			for (;;) {  				String line = AltosRecord.gets(input); -				if (line == null) +				if (line == null) {  					break; -				AltosTelemetry record = new AltosTelemetry(line); -				if (record == null) -					break; -				if (!saw_boost && record.state >= Altos.ao_flight_boost) -				{ -					saw_boost = true; -					boost_tick = record.tick;  				} -				records.add(record); +				try { +					AltosTelemetry record = new AltosTelemetry(line); +					if (record == null) +						break; +					if (!saw_boost && record.state >= Altos.ao_flight_boost) +					{ +						saw_boost = true; +						boost_tick = record.tick; +					} +					records.add(record); +				} catch (ParseException pe) { +					System.out.printf("parse exception %s\n", pe.getMessage()); +				} catch (AltosCRCException ce) { +					System.out.printf("crc error\n"); +				}  			}  		} catch (IOException io) { -		} catch (ParseException pe) { +			System.out.printf("io exception\n");  		}  		record_iterator = records.iterator();  		try { diff --git a/ao-tools/altosui/AltosUI.java b/ao-tools/altosui/AltosUI.java index 49d1f11a..3aaeb888 100644 --- a/ao-tools/altosui/AltosUI.java +++ b/ao-tools/altosui/AltosUI.java @@ -41,6 +41,10 @@ import altosui.AltosVoice;  import altosui.AltosFlightStatusTableModel;  import altosui.AltosFlightInfoTableModel;  import altosui.AltosChannelMenu; +import altosui.AltosFlashUI; +import altosui.AltosLogfileChooser; +import altosui.AltosCSVUI; +import altosui.AltosLine;  import libaltosJNI.*; @@ -71,6 +75,10 @@ public class AltosUI extends JFrame {  		String[] statusNames = { "Height (m)", "State", "RSSI (dBm)", "Speed (m/s)" };  		Object[][] statusData = { { "0", "pad", "-50", "0" } }; +		java.net.URL imgURL = AltosUI.class.getResource("/altus-metrum-16x16.jpg"); +		if (imgURL != null) +			setIconImage(new ImageIcon(imgURL).getImage()); +  		AltosPreferences.init(this);  		vbox = Box.createVerticalBox(); @@ -165,21 +173,19 @@ public class AltosUI extends JFrame {  			flightInfoModel[i].finish();  	} -	public void show(AltosState state) { +	public void show(AltosState state, int crc_errors) { +		if (state == null) +			return;  		flightStatusModel.set(state);  		info_reset(); -		if (state.gps_ready) -			info_add_row(0, "Ground state", "%s", "ready"); -		else -			info_add_row(0, "Ground state", "wait (%d)", -				     state.gps_waiting);  		info_add_row(0, "Rocket state", "%s", state.data.state());  		info_add_row(0, "Callsign", "%s", state.data.callsign);  		info_add_row(0, "Rocket serial", "%6d", state.data.serial);  		info_add_row(0, "Rocket flight", "%6d", state.data.flight);  		info_add_row(0, "RSSI", "%6d    dBm", state.data.rssi); +		info_add_row(0, "CRC Errors", "%6d", crc_errors);  		info_add_row(0, "Height", "%6.0f    m", state.height);  		info_add_row(0, "Max height", "%6.0f    m", state.max_height);  		info_add_row(0, "Acceleration", "%8.1f  m/s²", state.acceleration); @@ -194,6 +200,11 @@ public class AltosUI extends JFrame {  		if (state.gps == null) {  			info_add_row(1, "GPS", "not available");  		} else { +			if (state.gps_ready) +				info_add_row(1, "GPS state", "%s", "ready"); +			else +				info_add_row(1, "GPS state", "wait (%d)", +					     state.gps_waiting);  			if (state.data.gps.locked)  				info_add_row(1, "GPS", "   locked");  			else if (state.data.gps.connected) @@ -220,11 +231,19 @@ public class AltosUI extends JFrame {  			if (state.npad > 0) {  				if (state.from_pad != null) { -					info_add_row(1, "Distance from pad", "%6.0f m", state.from_pad.distance); -					info_add_row(1, "Direction from pad", "%6.0f°", state.from_pad.bearing); +					info_add_row(1, "Distance from pad", "%6d m", +						     (int) (state.from_pad.distance + 0.5)); +					info_add_row(1, "Direction from pad", "%6d°", +						     (int) (state.from_pad.bearing + 0.5)); +					info_add_row(1, "Elevation from pad", "%6d°", +						     (int) (state.elevation + 0.5)); +					info_add_row(1, "Range from pad", "%6d m", +						     (int) (state.range + 0.5));  				} else {  					info_add_row(1, "Distance from pad", "unknown");  					info_add_row(1, "Direction from pad", "unknown"); +					info_add_row(1, "Elevation from pad", "unknown"); +					info_add_row(1, "Range from pad", "unknown");  				}  				info_add_deg(1, "Pad latitude", state.pad_lat, 'N', 'S');  				info_add_deg(1, "Pad longitude", state.pad_lon, 'E', 'W'); @@ -258,10 +277,13 @@ public class AltosUI extends JFrame {  	class IdleThread extends Thread { +		boolean	started;  		private AltosState state;  		int	reported_landing; +		int	report_interval; +		long	report_time; -		public void report(boolean last) { +		public synchronized void report(boolean last) {  			if (state == null)  				return; @@ -275,7 +297,16 @@ public class AltosUI extends JFrame {  			}  			/* If the rocket isn't on the pad, then report height */ -			if (state.state > Altos.ao_flight_pad) { +			if (Altos.ao_flight_drogue <= state.state && +			    state.state < Altos.ao_flight_landed && +			    state.range >= 0) +			{ +				voice.speak("Height %d, bearing %d, elevation %d, range %d.\n", +					    (int) (state.height + 0.5), +					    (int) (state.from_pad.bearing + 0.5), +					    (int) (state.elevation + 0.5), +					    (int) (state.range + 0.5)); +			} else if (state.state > Altos.ao_flight_pad) {  				voice.speak("%d meters", (int) (state.height + 0.5));  			} else {  				reported_landing = 0; @@ -285,7 +316,7 @@ public class AltosUI extends JFrame {  			 * either we've got a landed report or we haven't heard from it in  			 * a long time  			 */ -			if (!state.ascent && +			if (state.state >= Altos.ao_flight_drogue &&  			    (last ||  			     System.currentTimeMillis() - state.report_time >= 15000 ||  			     state.state == Altos.ao_flight_landed)) @@ -295,51 +326,95 @@ public class AltosUI extends JFrame {  				else  					voice.speak("rocket may have crashed");  				if (state.from_pad != null) -					voice.speak("bearing %d degrees, range %d meters", +					voice.speak("Bearing %d degrees, range %d meters.",  						    (int) (state.from_pad.bearing + 0.5),  						    (int) (state.from_pad.distance + 0.5));  				++reported_landing;  			}  		} +		long now () { +			return System.currentTimeMillis(); +		} + +		void set_report_time() { +			report_time = now() + report_interval; +		} +  		public void run () {  			reported_landing = 0;  			state = null; +			report_interval = 10000;  			try {  				for (;;) { -					Thread.sleep(10000); +					set_report_time(); +					for (;;) { +						voice.drain(); +						synchronized (this) { +							long	sleep_time = report_time - now(); +							if (sleep_time <= 0) +								break; +							wait(sleep_time); +						} +					}  					report(false);  				}  			} catch (InterruptedException ie) { +				try { +					voice.drain(); +				} catch (InterruptedException iie) { }  			}  		} -		public void notice(AltosState new_state) { +		public synchronized void notice(AltosState new_state, boolean spoken) { +			AltosState old_state = state;  			state = new_state; +			if (!started && state.state > Altos.ao_flight_pad) { +				started = true; +				start(); +			} + +			if (state.state < Altos.ao_flight_drogue) +				report_interval = 10000; +			else +				report_interval = 20000; +			if (old_state != null && old_state.state != state.state) { +				report_time = now(); +				this.notify(); +			} else if (spoken) +				set_report_time();  		}  	} -	private void tell(AltosState state, AltosState old_state) { +	private boolean tell(AltosState state, AltosState old_state) { +		boolean	ret = false;  		if (old_state == null || old_state.state != state.state) {  			voice.speak(state.data.state());  			if ((old_state == null || old_state.state <= Altos.ao_flight_boost) &&  			    state.state > Altos.ao_flight_boost) {  				voice.speak("max speed: %d meters per second.",  					    (int) (state.max_speed + 0.5)); +				ret = true;  			} else if ((old_state == null || old_state.state < Altos.ao_flight_drogue) &&  				   state.state >= Altos.ao_flight_drogue) {  				voice.speak("max height: %d meters.",  					    (int) (state.max_height + 0.5)); +				ret = true;  			}  		}  		if (old_state == null || old_state.gps_ready != state.gps_ready) { -			if (state.gps_ready) +			if (state.gps_ready) {  				voice.speak("GPS ready"); -			else if (old_state != null) +				ret = true; +			} +			else if (old_state != null) {  				voice.speak("GPS lost"); +				ret = true; +			}  		}  		old_state = state; +		return ret;  	}  	class DisplayThread extends Thread { @@ -347,22 +422,27 @@ public class AltosUI extends JFrame {  		String		name; -		AltosRecord read() throws InterruptedException, ParseException { return null; } +		int		crc_errors; + +		void init() { } -		void close() { } +		AltosRecord read() throws InterruptedException, ParseException, AltosCRCException, IOException { return null; } + +		void close(boolean interrupted) { }  		void update(AltosState state) throws InterruptedException { }  		public void run() { +			boolean		interrupted = false;  			String		line;  			AltosState	state = null;  			AltosState	old_state = null; +			boolean		told;  			idle_thread = new IdleThread();  			info_reset();  			info_finish(); -			idle_thread.start();  			try {  				for (;;) {  					try { @@ -372,17 +452,29 @@ public class AltosUI extends JFrame {  						old_state = state;  						state = new AltosState(record, state);  						update(state); -						show(state); -						tell(state, old_state); -						idle_thread.notice(state); +						show(state, crc_errors); +						told = tell(state, old_state); +						idle_thread.notice(state, told);  					} catch (ParseException pp) {  						System.out.printf("Parse error: %d \"%s\"\n", pp.getErrorOffset(), pp.getMessage()); +					} catch (AltosCRCException ce) { +						++crc_errors; +						show(state, crc_errors);  					}  				}  			} catch (InterruptedException ee) { +				interrupted = true; +			} catch (IOException ie) { +				JOptionPane.showMessageDialog(AltosUI.this, +							      String.format("Error reading from \"%s\"", name), +							      "Telemetry Read Error", +							      JOptionPane.ERROR_MESSAGE);  			} finally { -				close(); +				close(interrupted);  				idle_thread.interrupt(); +				try { +					idle_thread.join(); +				} catch (InterruptedException ie) {}  			}  		} @@ -394,22 +486,25 @@ public class AltosUI extends JFrame {  	class DeviceThread extends DisplayThread {  		AltosSerial	serial; -		LinkedBlockingQueue<String> telem; +		LinkedBlockingQueue<AltosLine> telem; -		AltosRecord read() throws InterruptedException, ParseException { -			return new AltosTelemetry(telem.take()); +		AltosRecord read() throws InterruptedException, ParseException, AltosCRCException, IOException { +			AltosLine l = telem.take(); +			if (l.line == null) +				throw new IOException("IO error"); +			return new AltosTelemetry(l.line);  		} -		void close() { +		void close(boolean interrupted) {  			serial.close();  			serial.remove_monitor(telem);  		} -		public DeviceThread(AltosSerial s) { +		public DeviceThread(AltosSerial s, String in_name) {  			serial = s; -			telem = new LinkedBlockingQueue<String>(); +			telem = new LinkedBlockingQueue<AltosLine>();  			serial.add_monitor(telem); -			name = "telemetry"; +			name = in_name;  		}  	} @@ -418,8 +513,9 @@ public class AltosUI extends JFrame {  		if (device != null) {  			try { +				stop_display();  				serial_line.open(device); -				DeviceThread thread = new DeviceThread(serial_line); +				DeviceThread thread = new DeviceThread(serial_line, device.getPath());  				serial_line.set_channel(AltosPreferences.channel());  				serial_line.set_callsign(AltosPreferences.callsign());  				run_display(thread); @@ -457,6 +553,11 @@ public class AltosUI extends JFrame {  	void ConfigureTeleMetrum() {  		new AltosConfig(AltosUI.this);  	} + +	void FlashImage() { +		new AltosFlashUI(AltosUI.this); +	} +  	/*  	 * Open an existing telemetry file and replay it in realtime  	 */ @@ -478,8 +579,9 @@ public class AltosUI extends JFrame {  			return null;  		} -		public void close () { -			report(); +		public void close (boolean interrupted) { +			if (!interrupted) +				report();  		}  		public ReplayThread(AltosReader in_reader, String in_name) { @@ -508,8 +610,12 @@ public class AltosUI extends JFrame {  	Thread		display_thread;  	private void stop_display() { -		if (display_thread != null && display_thread.isAlive()) +		if (display_thread != null && display_thread.isAlive()) {  			display_thread.interrupt(); +			try { +				display_thread.join(); +			} catch (InterruptedException ie) {} +		}  		display_thread = null;  	} @@ -523,33 +629,12 @@ public class AltosUI extends JFrame {  	 * Replay a flight from telemetry data  	 */  	private void Replay() { -		JFileChooser	logfile_chooser = new JFileChooser(); - -		logfile_chooser.setDialogTitle("Select Flight Record File"); -		logfile_chooser.setFileFilter(new FileNameExtensionFilter("Flight data file", "eeprom", "telem")); -		logfile_chooser.setCurrentDirectory(AltosPreferences.logdir()); -		int returnVal = logfile_chooser.showOpenDialog(AltosUI.this); - -		if (returnVal == JFileChooser.APPROVE_OPTION) { -			File file = logfile_chooser.getSelectedFile(); -			if (file == null) -				System.out.println("No file selected?"); -			String	filename = file.getName(); -			try { -				FileInputStream	replay = new FileInputStream(file); -				DisplayThread	thread; -				if (filename.endsWith("eeprom")) -				    thread = new ReplayEepromThread(replay, filename); -				else -				    thread = new ReplayTelemetryThread(replay, filename); -				run_display(thread); -			} catch (FileNotFoundException ee) { -				JOptionPane.showMessageDialog(AltosUI.this, -							      filename, -							      "Cannot open telemetry file", -							      JOptionPane.ERROR_MESSAGE); -			} -		} +		AltosLogfileChooser chooser = new AltosLogfileChooser( +			AltosUI.this); +		AltosReader reader = chooser.runDialog(); +		if (reader != null) +			run_display(new ReplayThread(reader, +						     chooser.filename()));  	}  	/* Connect to TeleMetrum, either directly or through @@ -559,6 +644,14 @@ public class AltosUI extends JFrame {  		new AltosEepromDownload(AltosUI.this);  	} +	/* Load a flight log file and write out a CSV file containing +	 * all of the data in standard units +	 */ + +	private void ExportData() { +		new AltosCSVUI(AltosUI.this); +	} +  	/* Create the AltosUI menus  	 */  	private void createMenu() { @@ -589,6 +682,22 @@ public class AltosUI extends JFrame {  				});  			menu.add(item); +			item = new JMenuItem("Flash Image",KeyEvent.VK_F); +			item.addActionListener(new ActionListener() { +					public void actionPerformed(ActionEvent e) { +						FlashImage(); +					} +				}); +			menu.add(item); + +			item = new JMenuItem("Export Data",KeyEvent.VK_F); +			item.addActionListener(new ActionListener() { +					public void actionPerformed(ActionEvent e) { +						ExportData(); +					} +				}); +			menu.add(item); +  			item = new JMenuItem("Quit",KeyEvent.VK_Q);  			item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q,  								   ActionEvent.CTRL_MASK)); @@ -708,8 +817,67 @@ public class AltosUI extends JFrame {  		this.setJMenuBar(menubar);  	} + +	static String replace_extension(String input, String extension) { +		int dot = input.lastIndexOf("."); +		if (dot > 0) +			input = input.substring(0,dot); +		return input.concat(extension); +	} + +	static AltosReader open_logfile(String filename) { +		File file = new File (filename); +		try { +			FileInputStream in; + +			in = new FileInputStream(file); +			if (filename.endsWith("eeprom")) +				return new AltosEepromReader(in); +			else +				return new AltosTelemetryReader(in); +		} catch (FileNotFoundException fe) { +			System.out.printf("Cannot open '%s'\n", filename); +			return null; +		} +	} + +	static AltosCSV open_csv(String filename) { +		File file = new File (filename); +		try { +			return new AltosCSV(file); +		} catch (FileNotFoundException fe) { +			System.out.printf("Cannot open '%s'\n", filename); +			return null; +		} +	} + +	static void process_file(String input) { +		String output = replace_extension(input,".csv"); +		if (input.equals(output)) { +			System.out.printf("Not processing '%s'\n", input); +			return; +		} +		System.out.printf("Processing \"%s\" to \"%s\"\n", input, output); +		AltosReader reader = open_logfile(input); +		if (reader == null) +			return; +		AltosCSV writer = open_csv(output); +		if (writer == null) +			return; +		writer.write(reader); +		reader.close(); +		writer.close(); +	} +  	public static void main(final String[] args) { -		AltosUI altosui = new AltosUI(); -		altosui.setVisible(true); + +		/* Handle batch-mode */ +		if (args.length > 0) { +			for (int i = 0; i < args.length; i++) +				process_file(args[i]); +		} else { +			AltosUI altosui = new AltosUI(); +			altosui.setVisible(true); +		}  	}  }
\ No newline at end of file diff --git a/ao-tools/altosui/AltosVoice.java b/ao-tools/altosui/AltosVoice.java index ebe9d5a8..ac13ee14 100644 --- a/ao-tools/altosui/AltosVoice.java +++ b/ao-tools/altosui/AltosVoice.java @@ -27,6 +27,7 @@ public class AltosVoice implements Runnable {  	Voice				voice;  	LinkedBlockingQueue<String>	phrases;  	Thread				thread; +	boolean				busy;  	final static String voice_name = "kevin16"; @@ -35,15 +36,30 @@ public class AltosVoice implements Runnable {  			for (;;) {  				String s = phrases.take();  				voice.speak(s); +				synchronized(this) { +					if (phrases.isEmpty()) { +						busy = false; +						notifyAll(); +					} +				}  			}  		} catch (InterruptedException e) {  		}  	} +	public synchronized void drain() throws InterruptedException { +		while (busy) +			wait(); +	} +  	public void speak_always(String s) {  		try { -			if (voice != null) -				phrases.put(s); +			if (voice != null) { +				synchronized(this) { +					busy = true; +					phrases.put(s); +				} +			}  		} catch (InterruptedException e) {  		}  	} @@ -58,6 +74,7 @@ public class AltosVoice implements Runnable {  	}  	public AltosVoice () { +		busy = false;  		voice_manager = VoiceManager.getInstance();  		voice = voice_manager.getVoice(voice_name);  		if (voice != null) { diff --git a/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/Example.nsi b/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/Example.nsi new file mode 100644 index 00000000..3ed821eb --- /dev/null +++ b/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/Example.nsi @@ -0,0 +1,84 @@ +#
 +# InstDrv Example, (c) 2003 Jan Kiszka (Jan Kiszka@web.de)
 +#
 +
 +Name "InstDrv.dll test"
 +
 +OutFile "InstDrv-Test.exe"
 +
 +ShowInstDetails show
 +
 +ComponentText "InstDrv Plugin Usage Example"
 +
 +Page components
 +Page instfiles
 +
 +Section "Install a Driver" InstDriver
 +    InstDrv::InitDriverSetup /NOUNLOAD "{4d36e978-e325-11ce-bfc1-08002be10318}" "IrCOMM2k"
 +    Pop $0
 +    DetailPrint "InitDriverSetup: $0"
 +
 +    InstDrv::DeleteOemInfFiles /NOUNLOAD
 +    Pop $0
 +    DetailPrint "DeleteOemInfFiles: $0"
 +    StrCmp $0 "00000000" PrintInfNames ContInst1
 +
 +  PrintInfNames:
 +    Pop $0
 +    DetailPrint "Deleted $0"
 +    Pop $0
 +    DetailPrint "Deleted $0"
 +
 +  ContInst1:
 +    InstDrv::CreateDevice /NOUNLOAD
 +    Pop $0
 +    DetailPrint "CreateDevice: $0"
 +
 +    SetOutPath $TEMP
 +    File "ircomm2k.inf"
 +    File "ircomm2k.sys"
 +
 +    InstDrv::InstallDriver /NOUNLOAD "$TEMP\ircomm2k.inf"
 +    Pop $0
 +    DetailPrint "InstallDriver: $0"
 +    StrCmp $0 "00000000" PrintReboot ContInst2
 +
 +  PrintReboot:
 +    Pop $0
 +    DetailPrint "Reboot: $0"
 +
 +  ContInst2:
 +    InstDrv::CountDevices
 +    Pop $0
 +    DetailPrint "CountDevices: $0"
 +SectionEnd
 +
 +Section "Uninstall the driver again" UninstDriver
 +    InstDrv::InitDriverSetup /NOUNLOAD "{4d36e978-e325-11ce-bfc1-08002be10318}" "IrCOMM2k"
 +    Pop $0
 +    DetailPrint "InitDriverSetup: $0"
 +
 +    InstDrv::DeleteOemInfFiles /NOUNLOAD
 +    Pop $0
 +    DetailPrint "DeleteOemInfFiles: $0"
 +    StrCmp $0 "00000000" PrintInfNames ContUninst1
 +
 +  PrintInfNames:
 +    Pop $0
 +    DetailPrint "Deleted $0"
 +    Pop $0
 +    DetailPrint "Deleted $0"
 +
 +  ContUninst1:
 +    InstDrv::RemoveAllDevices
 +    Pop $0
 +    DetailPrint "RemoveAllDevices: $0"
 +    StrCmp $0 "00000000" PrintReboot ContUninst2
 +
 +  PrintReboot:
 +    Pop $0
 +    DetailPrint "Reboot: $0"
 +
 +  ContUninst2:
 +    Delete "$SYSDIR\system32\ircomm2k.sys"
 +SectionEnd
\ No newline at end of file diff --git a/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/InstDrv-Test.exe b/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/InstDrv-Test.exeBinary files differ new file mode 100644 index 00000000..615bae15 --- /dev/null +++ b/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/InstDrv-Test.exe diff --git a/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/InstDrv.c b/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/InstDrv.c new file mode 100644 index 00000000..efe866e9 --- /dev/null +++ b/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/InstDrv.c @@ -0,0 +1,704 @@ +/*
 +
 +InstDrv.dll - Installs or Removes Device Drivers
 +
 +Copyright © 2003 Jan Kiszka (Jan.Kiszka@web.de)
 +
 +This software is provided 'as-is', without any express or implied
 +warranty. In no event will the authors be held liable for any damages
 +arising from the use of this software.
 +
 +Permission is granted to anyone to use this software for any purpose,
 +including commercial applications, and to alter it and redistribute
 +it freely, subject to the following restrictions:
 +
 +1. The origin of this software must not be misrepresented; 
 +   you must not claim that you wrote the original software.
 +   If you use this software in a product, an acknowledgment in the
 +   product documentation would be appreciated but is not required.
 +2. Altered versions must be plainly marked as such,
 +   and must not be misrepresented as being the original software.
 +3. This notice may not be removed or altered from any distribution.
 +
 +*/
 +
 +
 +#include <windows.h>
 +#include <setupapi.h>
 +#include <newdev.h>
 +#include "../exdll/exdll.h"
 +
 +
 +char    paramBuf[1024];
 +GUID    devClass;
 +char    hwIdBuf[1024];
 +int     initialized = 0;
 +
 +
 +
 +void* memset(void* dst, int val, unsigned int len)
 +{
 +    while (len-- > 0)
 +        *((char *)dst)++ = val;
 +
 +    return NULL;
 +}
 +
 +
 +
 +void* memcpy(void* dst, const void* src, unsigned int len)
 +{
 +    while (len-- > 0)
 +        *((char *)dst)++ = *((char *)src)++;
 +
 +    return NULL;
 +}
 +
 +
 +
 +int HexCharToInt(char c)
 +{
 +    if ((c >= '0') && (c <= '9'))
 +        return c - '0';
 +    else if ((c >= 'a') && (c <= 'f'))
 +        return c - 'a' + 10;
 +    else if ((c >= 'A') && (c <= 'F'))
 +        return c - 'A' + 10;
 +    else
 +        return -1;
 +}
 +
 +
 +
 +BOOLEAN HexStringToUInt(char* str, int width, void* valBuf)
 +{
 +    int i, val;
 +
 +
 +    for (i = width - 4; i >= 0; i -= 4)
 +    {
 +        val = HexCharToInt(*str++);
 +        if (val < 0)
 +            return FALSE;
 +        *(unsigned int *)valBuf += val << i;
 +    }
 +
 +    return TRUE;
 +}
 +
 +
 +
 +BOOLEAN StringToGUID(char* guidStr, GUID* pGuid)
 +{
 +    int i;
 +
 +
 +    memset(pGuid, 0, sizeof(GUID));
 +
 +    if (*guidStr++ != '{')
 +        return FALSE;
 +
 +    if (!HexStringToUInt(guidStr, 32, &pGuid->Data1))
 +        return FALSE;
 +    guidStr += 8;
 +
 +    if (*guidStr++ != '-')
 +        return FALSE;
 +
 +    if (!HexStringToUInt(guidStr, 16, &pGuid->Data2))
 +        return FALSE;
 +    guidStr += 4;
 +
 +    if (*guidStr++ != '-')
 +        return FALSE;
 +
 +    if (!HexStringToUInt(guidStr, 16, &pGuid->Data3))
 +        return FALSE;
 +    guidStr += 4;
 +
 +    if (*guidStr++ != '-')
 +        return FALSE;
 +
 +    for (i = 0; i < 2; i++)
 +    {
 +        if (!HexStringToUInt(guidStr, 8, &pGuid->Data4[i]))
 +            return FALSE;
 +        guidStr += 2;
 +    }
 +
 +    if (*guidStr++ != '-')
 +        return FALSE;
 +
 +    for (i = 2; i < 8; i++)
 +    {
 +        if (!HexStringToUInt(guidStr, 8, &pGuid->Data4[i]))
 +            return FALSE;
 +        guidStr += 2;
 +    }
 +
 +    if (*guidStr++ != '}')
 +        return FALSE;
 +
 +    return TRUE;
 +}
 +
 +
 +
 +DWORD FindNextDevice(HDEVINFO devInfoSet, SP_DEVINFO_DATA* pDevInfoData, DWORD* pIndex)
 +{
 +    DWORD   buffersize = 0;
 +    LPTSTR  buffer     = NULL;
 +    DWORD   dataType;
 +    DWORD   result;
 +
 +
 +    while (1)
 +    {
 +        if (!SetupDiEnumDeviceInfo(devInfoSet, (*pIndex)++, pDevInfoData))
 +        {
 +            result = GetLastError();
 +            break;
 +        }
 +
 +      GetDeviceRegistryProperty:
 +        if (!SetupDiGetDeviceRegistryProperty(devInfoSet, pDevInfoData, SPDRP_HARDWAREID,
 +                                              &dataType, (PBYTE)buffer, buffersize,
 +                                              &buffersize))
 +        {
 +            result = GetLastError();
 +
 +            if (result == ERROR_INSUFFICIENT_BUFFER)
 +            {
 +                if (buffer != NULL)
 +                    LocalFree(buffer);
 +
 +                buffer = (LPTSTR)LocalAlloc(LPTR, buffersize);
 +
 +                if (buffer == NULL)
 +                    break;
 +
 +                goto GetDeviceRegistryProperty;
 +            }
 +            else if (result == ERROR_INVALID_DATA)
 +                continue;   // ignore invalid entries
 +            else
 +                break;      // break on other errors
 +        }
 +
 +        if (lstrcmpi(buffer, hwIdBuf) == 0)
 +        {
 +            result  = 0;
 +            break;
 +        }
 +    }
 +
 +    if (buffer != NULL)
 +        LocalFree(buffer);
 +
 +    return result;
 +}
 +
 +
 +
 +DWORD FindFirstDevice(HWND hwndParent, const GUID* pDevClass, const LPTSTR hwId,
 +                      HDEVINFO* pDevInfoSet, SP_DEVINFO_DATA* pDevInfoData,
 +                      DWORD *pIndex, DWORD flags)
 +{
 +    DWORD   result;
 +
 +
 +    *pDevInfoSet = SetupDiGetClassDevs((GUID*)pDevClass, NULL, hwndParent, flags);
 +    if (*pDevInfoSet == INVALID_HANDLE_VALUE)
 +        return GetLastError();
 +
 +    pDevInfoData->cbSize = sizeof(SP_DEVINFO_DATA);
 +    *pIndex = 0;
 +
 +    result = FindNextDevice(*pDevInfoSet, pDevInfoData, pIndex);
 +
 +    if (result != 0)
 +        SetupDiDestroyDeviceInfoList(*pDevInfoSet);
 +
 +    return result;
 +}
 +
 +
 +
 +/*
 + * InstDrv::InitDriverSetup devClass drvHWID
 + *
 + *  devClass    - GUID of the driver's device setup class
 + *  drvHWID     - Hardware ID of the supported device
 + *
 + * Return:
 + *  result      - error message, empty on success
 + */
 +void __declspec(dllexport) InitDriverSetup(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)
 +{
 +    EXDLL_INIT();
 +
 +    /* convert class GUID */
 +    popstring(paramBuf);
 +
 +    if (!StringToGUID(paramBuf, &devClass))
 +    {
 +        popstring(paramBuf);
 +        pushstring("Invalid GUID!");
 +        return;
 +    }
 +
 +    /* get hardware ID */
 +    memset(hwIdBuf, 0, sizeof(hwIdBuf));
 +    popstring(hwIdBuf);
 +
 +    initialized = 1;
 +    pushstring("");
 +}
 +
 +
 +
 +/*
 + * InstDrv::CountDevices
 + *
 + * Return:
 + *  result      - Number of installed devices the driver supports
 + */
 +void __declspec(dllexport) CountDevices(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)
 +{
 +    HDEVINFO            devInfoSet;
 +    SP_DEVINFO_DATA     devInfoData;
 +    int                 count = 0;
 +    char                countBuf[16];
 +    DWORD               index;
 +    DWORD               result;
 +
 +
 +    EXDLL_INIT();
 +
 +    if (!initialized)
 +    {
 +        pushstring("Fatal error!");
 +        return;
 +    }
 +
 +    result = FindFirstDevice(hwndParent, &devClass, hwIdBuf, &devInfoSet, &devInfoData,
 +                             &index, DIGCF_PRESENT);
 +    if (result != 0)
 +    {
 +        pushstring("0");
 +        return;
 +    }
 +
 +    do
 +    {
 +        count++;
 +    } while (FindNextDevice(devInfoSet, &devInfoData, &index) == 0);
 +
 +    SetupDiDestroyDeviceInfoList(devInfoSet);
 +
 +    wsprintf(countBuf, "%d", count);
 +    pushstring(countBuf);
 +}
 +
 +
 +
 +/*
 + * InstDrv::CreateDevice
 + *
 + * Return:
 + *  result      - Windows error code
 + */
 +void __declspec(dllexport) CreateDevice(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)
 +{
 +    HDEVINFO            devInfoSet;
 +    SP_DEVINFO_DATA     devInfoData;
 +    DWORD               result = 0;
 +    char                resultBuf[16];
 +
 +
 +    EXDLL_INIT();
 +
 +    if (!initialized)
 +    {
 +        pushstring("Fatal error!");
 +        return;
 +    }
 +
 +    devInfoSet = SetupDiCreateDeviceInfoList(&devClass, hwndParent);
 +    if (devInfoSet == INVALID_HANDLE_VALUE)
 +    {
 +        wsprintf(resultBuf, "%08X", GetLastError());
 +        pushstring(resultBuf);
 +        return;
 +    }
 +
 +    devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
 +    if (!SetupDiCreateDeviceInfo(devInfoSet, hwIdBuf, &devClass, NULL,
 +                                 hwndParent, DICD_GENERATE_ID, &devInfoData))
 +    {
 +        result = GetLastError();
 +        goto InstallCleanup;
 +    }
 +
 +    if (!SetupDiSetDeviceRegistryProperty(devInfoSet, &devInfoData, SPDRP_HARDWAREID,
 +                                          hwIdBuf, (lstrlen(hwIdBuf)+2)*sizeof(TCHAR))) 
 +    {
 +        result = GetLastError();
 +        goto InstallCleanup;
 +    }
 +
 +    if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, devInfoSet, &devInfoData))
 +        result = GetLastError();
 +
 +  InstallCleanup:
 +    SetupDiDestroyDeviceInfoList(devInfoSet);
 +
 +    wsprintf(resultBuf, "%08X", result);
 +    pushstring(resultBuf);
 +}
 +
 +
 +
 +/*
 + * InstDrv::InstallDriver infPath
 + *
 + * Return:
 + *  result      - Windows error code
 + *  reboot      - non-zero if reboot is required
 + */
 +void __declspec(dllexport) InstallDriver(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)
 +{
 +    char    resultBuf[16];
 +    BOOL    reboot;
 +
 +
 +    EXDLL_INIT();
 +    popstring(paramBuf);
 +
 +    if (!initialized)
 +    {
 +        pushstring("Fatal error!");
 +        return;
 +    }
 +
 +    if (!UpdateDriverForPlugAndPlayDevices(hwndParent, hwIdBuf, paramBuf,
 +                                           INSTALLFLAG_FORCE, &reboot))
 +    {
 +        wsprintf(resultBuf, "%08X", GetLastError());
 +        pushstring(resultBuf);
 +    }
 +    else
 +    {
 +        wsprintf(resultBuf, "%d", reboot);
 +        pushstring(resultBuf);
 +        pushstring("00000000");
 +    }
 +}
 +
 +
 +
 +/*
 + * InstDrv::DeleteOemInfFiles
 + *
 + * Return:
 + *  result      - Windows error code
 + *  oeminf      - Path of the deleted devices setup file (oemXX.inf)
 + *  oempnf      - Path of the deleted devices setup file (oemXX.pnf)
 + */
 +void __declspec(dllexport) DeleteOemInfFiles(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)
 +{
 +    HDEVINFO                devInfo;
 +    SP_DEVINFO_DATA         devInfoData;
 +    SP_DRVINFO_DATA         drvInfoData;
 +    SP_DRVINFO_DETAIL_DATA  drvInfoDetail;
 +    DWORD                   index;
 +    DWORD                   result;
 +    char                    resultBuf[16];
 +
 +
 +    if (!initialized)
 +    {
 +        pushstring("Fatal error!");
 +        return;
 +    }
 +
 +    result = FindFirstDevice(NULL, &devClass, hwIdBuf, &devInfo, &devInfoData, &index, 0);
 +    if (result != 0)
 +        goto Cleanup1;
 +
 +    if (!SetupDiBuildDriverInfoList(devInfo, &devInfoData, SPDIT_COMPATDRIVER))
 +    {
 +        result = GetLastError();
 +        goto Cleanup2;
 +    }
 +
 +    drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
 +    drvInfoDetail.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
 +
 +    if (!SetupDiEnumDriverInfo(devInfo, &devInfoData, SPDIT_COMPATDRIVER, 0, &drvInfoData))
 +    {
 +        result = GetLastError();
 +        goto Cleanup3;
 +    }
 +
 +    if (!SetupDiGetDriverInfoDetail(devInfo, &devInfoData, &drvInfoData,
 +                                    &drvInfoDetail, sizeof(drvInfoDetail), NULL))
 +    {
 +        result = GetLastError();
 +
 +        if (result != ERROR_INSUFFICIENT_BUFFER)
 +            goto Cleanup3;
 +
 +        result = 0;
 +    }
 +
 +    pushstring(drvInfoDetail.InfFileName);
 +    if (!DeleteFile(drvInfoDetail.InfFileName))
 +        result = GetLastError();
 +    else
 +    {
 +        index = lstrlen(drvInfoDetail.InfFileName);
 +        if (index > 3)
 +        {
 +            lstrcpy(drvInfoDetail.InfFileName+index-3, "pnf");
 +            pushstring(drvInfoDetail.InfFileName);
 +            if (!DeleteFile(drvInfoDetail.InfFileName))
 +                result = GetLastError();
 +        }
 +    }
 +
 +  Cleanup3:
 +    SetupDiDestroyDriverInfoList(devInfo, &devInfoData, SPDIT_COMPATDRIVER);
 +
 +  Cleanup2:
 +    SetupDiDestroyDeviceInfoList(devInfo);
 +
 +  Cleanup1:
 +    wsprintf(resultBuf, "%08X", result);
 +    pushstring(resultBuf);
 +}
 +
 +
 +
 +/*
 + * InstDrv::RemoveAllDevices
 + *
 + * Return:
 + *  result      - Windows error code
 + *  reboot      - non-zero if reboot is required
 + */
 +void __declspec(dllexport) RemoveAllDevices(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)
 +{
 +    HDEVINFO                devInfo;
 +    SP_DEVINFO_DATA         devInfoData;
 +    DWORD                   index;
 +    DWORD                   result;
 +    char                    resultBuf[16];
 +    BOOL                    reboot = FALSE;
 +    SP_DEVINSTALL_PARAMS    instParams;
 +
 +
 +    EXDLL_INIT();
 +
 +    if (!initialized)
 +    {
 +        pushstring("Fatal error!");
 +        return;
 +    }
 +
 +    result = FindFirstDevice(NULL, &devClass, hwIdBuf, &devInfo, &devInfoData, &index, 0);
 +    if (result != 0)
 +        goto Cleanup1;
 +
 +    do
 +    {
 +        if (!SetupDiCallClassInstaller(DIF_REMOVE, devInfo, &devInfoData))
 +        {
 +            result = GetLastError();
 +            break;
 +        }
 +
 +        instParams.cbSize = sizeof(instParams);
 +        if (!reboot &&
 +            SetupDiGetDeviceInstallParams(devInfo, &devInfoData, &instParams) &&
 +            ((instParams.Flags & (DI_NEEDRESTART|DI_NEEDREBOOT)) != 0))
 +        {
 +            reboot = TRUE;
 +        }
 +
 +        result = FindNextDevice(devInfo, &devInfoData, &index);
 +    } while (result == 0);
 +
 +    SetupDiDestroyDeviceInfoList(devInfo);
 +
 +  Cleanup1:
 +    if ((result == 0) || (result == ERROR_NO_MORE_ITEMS))
 +    {
 +        wsprintf(resultBuf, "%d", reboot);
 +        pushstring(resultBuf);
 +        pushstring("00000000");
 +    }
 +    else
 +    {
 +        wsprintf(resultBuf, "%08X", result);
 +        pushstring(resultBuf);
 +    }
 +}
 +
 +
 +
 +/*
 + * InstDrv::StartSystemService serviceName
 + *
 + * Return:
 + *  result      - Windows error code
 + */
 +void __declspec(dllexport) StartSystemService(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)
 +{
 +    SC_HANDLE       managerHndl;
 +    SC_HANDLE       svcHndl;
 +    SERVICE_STATUS  svcStatus;
 +    DWORD           oldCheckPoint;
 +    DWORD           result;
 +    char            resultBuf[16];
 +
 +
 +    EXDLL_INIT();
 +    popstring(paramBuf);
 +
 +    managerHndl = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
 +    if (managerHndl == NULL)
 +    {
 +        result = GetLastError();
 +        goto Cleanup1;
 +    }
 +
 +    svcHndl = OpenService(managerHndl, paramBuf, SERVICE_START | SERVICE_QUERY_STATUS);
 +    if (svcHndl == NULL)
 +    {
 +        result = GetLastError();
 +        goto Cleanup2;
 +    }
 +
 +    if (!StartService(svcHndl, 0, NULL) || !QueryServiceStatus(svcHndl, &svcStatus))
 +    {
 +        result = GetLastError();
 +        goto Cleanup3;
 +    }
 +
 +    while (svcStatus.dwCurrentState == SERVICE_START_PENDING)
 +    {
 +        oldCheckPoint = svcStatus.dwCheckPoint;
 +
 +        Sleep(svcStatus.dwWaitHint);
 +
 +        if (!QueryServiceStatus(svcHndl, &svcStatus))
 +        {
 +            result = GetLastError();
 +            break;
 +        }
 +
 +        if (oldCheckPoint >= svcStatus.dwCheckPoint)
 +        {
 +            if ((svcStatus.dwCurrentState == SERVICE_STOPPED) &&
 +                (svcStatus.dwWin32ExitCode != 0))
 +                result = svcStatus.dwWin32ExitCode;
 +            else
 +                result = ERROR_SERVICE_REQUEST_TIMEOUT;
 +        }
 +    }
 +
 +    if (svcStatus.dwCurrentState == SERVICE_RUNNING)
 +        result = 0;
 +
 +  Cleanup3:
 +    CloseServiceHandle(svcHndl);
 +
 +  Cleanup2:
 +    CloseServiceHandle(managerHndl);
 +
 +  Cleanup1:
 +    wsprintf(resultBuf, "%08X", result);
 +    pushstring(resultBuf);
 +}
 +
 +
 +
 +/*
 + * InstDrv::StopSystemService serviceName
 + *
 + * Return:
 + *  result      - Windows error code
 + */
 +void __declspec(dllexport) StopSystemService(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)
 +{
 +    SC_HANDLE       managerHndl;
 +    SC_HANDLE       svcHndl;
 +    SERVICE_STATUS  svcStatus;
 +    DWORD           oldCheckPoint;
 +    DWORD           result;
 +    char            resultBuf[16];
 +
 +
 +    EXDLL_INIT();
 +    popstring(paramBuf);
 +
 +    managerHndl = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
 +    if (managerHndl == NULL)
 +    {
 +        result = GetLastError();
 +        goto Cleanup1;
 +    }
 +
 +    svcHndl = OpenService(managerHndl, paramBuf, SERVICE_STOP | SERVICE_QUERY_STATUS);
 +    if (svcHndl == NULL)
 +    {
 +        result = GetLastError();
 +        goto Cleanup2;
 +    }
 +
 +    if (!ControlService(svcHndl, SERVICE_CONTROL_STOP, &svcStatus))
 +    {
 +        result = GetLastError();
 +        goto Cleanup3;
 +    }
 +
 +    while (svcStatus.dwCurrentState == SERVICE_STOP_PENDING)
 +    {
 +        oldCheckPoint = svcStatus.dwCheckPoint;
 +
 +        Sleep(svcStatus.dwWaitHint);
 +
 +        if (!QueryServiceStatus(svcHndl, &svcStatus))
 +        {
 +            result = GetLastError();
 +            break;
 +        }
 +
 +        if (oldCheckPoint >= svcStatus.dwCheckPoint)
 +        {
 +            result = ERROR_SERVICE_REQUEST_TIMEOUT;
 +            break;
 +        }
 +    }
 +
 +    if (svcStatus.dwCurrentState == SERVICE_STOPPED)
 +        result = 0;
 +
 +  Cleanup3:
 +    CloseServiceHandle(svcHndl);
 +
 +  Cleanup2:
 +    CloseServiceHandle(managerHndl);
 +
 +  Cleanup1:
 +    wsprintf(resultBuf, "%08X", result);
 +    pushstring(resultBuf);
 +}
 +
 +
 +
 +BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
 +{
 +    return TRUE;
 +}
 diff --git a/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/InstDrv.dsp b/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/InstDrv.dsp new file mode 100644 index 00000000..874e66c7 --- /dev/null +++ b/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/InstDrv.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="InstDrv" - Package Owner=<4>
 +# Microsoft Developer Studio Generated Build File, Format Version 6.00
 +# ** NICHT BEARBEITEN **
 +
 +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
 +
 +CFG=InstDrv - Win32 Debug
 +!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
 +!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
 +!MESSAGE 
 +!MESSAGE NMAKE /f "InstDrv.mak".
 +!MESSAGE 
 +!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
 +!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
 +!MESSAGE 
 +!MESSAGE NMAKE /f "InstDrv.mak" CFG="InstDrv - Win32 Debug"
 +!MESSAGE 
 +!MESSAGE Für die Konfiguration stehen zur Auswahl:
 +!MESSAGE 
 +!MESSAGE "InstDrv - Win32 Release" (basierend auf  "Win32 (x86) Dynamic-Link Library")
 +!MESSAGE "InstDrv - Win32 Debug" (basierend auf  "Win32 (x86) Dynamic-Link Library")
 +!MESSAGE 
 +
 +# Begin Project
 +# PROP AllowPerConfigDependencies 0
 +# PROP Scc_ProjName ""
 +# PROP Scc_LocalPath ""
 +CPP=cl.exe
 +MTL=midl.exe
 +RSC=rc.exe
 +
 +!IF  "$(CFG)" == "InstDrv - Win32 Release"
 +
 +# PROP BASE Use_MFC 0
 +# PROP BASE Use_Debug_Libraries 0
 +# PROP BASE Output_Dir "Release"
 +# PROP BASE Intermediate_Dir "Release"
 +# PROP BASE Target_Dir ""
 +# PROP Use_MFC 0
 +# PROP Use_Debug_Libraries 0
 +# PROP Output_Dir "Release"
 +# PROP Intermediate_Dir "Release"
 +# PROP Ignore_Export_Lib 1
 +# PROP Target_Dir ""
 +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "INSTDRV_EXPORTS" /YX /FD /c
 +# ADD CPP /nologo /MT /W3 /GX /O1 /I "C:\Programme\WINDDK\3790\inc\ddk\w2k" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "INSTDRV_EXPORTS" /FD /c
 +# SUBTRACT CPP /YX
 +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 +# ADD BASE RSC /l 0x407 /d "NDEBUG"
 +# ADD RSC /l 0x407 /d "NDEBUG"
 +BSC32=bscmake.exe
 +# ADD BASE BSC32 /nologo
 +# ADD BSC32 /nologo
 +LINK32=link.exe
 +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib setupapi.lib newdev.lib /nologo /entry:"_DllMainCRTStartup" /dll /machine:I386 /nodefaultlib /out:"../../Plugins/InstDrv.dll" /libpath:"C:\Programme\WINDDK\3790\lib\w2k\i386" /opt:nowin98
 +# SUBTRACT LINK32 /pdb:none
 +
 +!ELSEIF  "$(CFG)" == "InstDrv - Win32 Debug"
 +
 +# PROP BASE Use_MFC 0
 +# PROP BASE Use_Debug_Libraries 1
 +# PROP BASE Output_Dir "Debug"
 +# PROP BASE Intermediate_Dir "Debug"
 +# PROP BASE Target_Dir ""
 +# PROP Use_MFC 0
 +# PROP Use_Debug_Libraries 1
 +# PROP Output_Dir "Debug"
 +# PROP Intermediate_Dir "Debug"
 +# PROP Ignore_Export_Lib 0
 +# PROP Target_Dir ""
 +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "INSTDRV_EXPORTS" /YX /FD /GZ  /c
 +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "INSTDRV_EXPORTS" /YX /FD /GZ  /c
 +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 +# ADD BASE RSC /l 0x407 /d "_DEBUG"
 +# ADD RSC /l 0x407 /d "_DEBUG"
 +BSC32=bscmake.exe
 +# ADD BASE BSC32 /nologo
 +# ADD BSC32 /nologo
 +LINK32=link.exe
 +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"_DllMainCRTStartup" /dll /debug /machine:I386 /pdbtype:sept
 +# SUBTRACT LINK32 /nodefaultlib
 +
 +!ENDIF 
 +
 +# Begin Target
 +
 +# Name "InstDrv - Win32 Release"
 +# Name "InstDrv - Win32 Debug"
 +# Begin Group "Quellcodedateien"
 +
 +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
 +# Begin Source File
 +
 +SOURCE=.\InstDrv.c
 +# End Source File
 +# End Group
 +# Begin Group "Header-Dateien"
 +
 +# PROP Default_Filter "h;hpp;hxx;hm;inl"
 +# End Group
 +# Begin Group "Ressourcendateien"
 +
 +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
 +# End Group
 +# End Target
 +# End Project
 diff --git a/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/InstDrv.dsw b/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/InstDrv.dsw new file mode 100644 index 00000000..b3d02f0e --- /dev/null +++ b/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/InstDrv.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00
 +# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN!
 +
 +###############################################################################
 +
 +Project: "InstDrv"=.\InstDrv.dsp - Package Owner=<4>
 +
 +Package=<5>
 +{{{
 +}}}
 +
 +Package=<4>
 +{{{
 +}}}
 +
 +###############################################################################
 +
 +Global:
 +
 +Package=<5>
 +{{{
 +}}}
 +
 +Package=<3>
 +{{{
 +}}}
 +
 +###############################################################################
 +
 diff --git a/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/Readme.txt b/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/Readme.txt new file mode 100644 index 00000000..e5877aa6 --- /dev/null +++ b/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/Readme.txt @@ -0,0 +1,141 @@ +InstDrv.dll version 0.2 - Installs or Removes Device Drivers
 +------------------------------------------------------------
 +
 +
 +The plugin helps you to create NSIS scripts for installing device drivers or
 +removing them again. It can count installed device instances, create new ones
 +or delete all supported device. InstDrv works on Windows 2000 or later.
 +
 +
 +
 +InstDrv::InitDriverSetup devClass drvHWID
 +Return: result
 +
 +To start processing a driver, first call this function. devClass is the GUID
 +of the device class the driver supports, drvHWID is the device hardware ID. If
 +you don't know what these terms mean, you may want to take a look at the
 +Windows DDK. This function returns an empty string on success, otherwise an
 +error message.
 +
 +InitDriverSetup has to be called every time after the plugin dll has been
 +(re-)loaded, or if you want to switch to a different driver.
 +
 +
 +
 +InstDrv::CountDevices
 +Return: number
 +
 +This call returns the number of installed and supported devices of the driver.
 +
 +
 +
 +InstDrv::CreateDevice
 +Return: result
 +
 +To create a new deviced node which the driver has to support, use this
 +function. You may even call it multiple times for more than one instance. The
 +return value is the Windows error code (in hex). Use CreateDevice before
 +installing or updating the driver itself.
 +
 +
 +
 +InstDrv::InstallDriver infPath
 +Return: result
 +        reboot
 +
 +InstallDriver installs or updates a device driver as specified in the .inf
 +setup script. It returns a Windows error code (in hex) and, on success, a flag
 +signalling if a system reboot is required.
 +
 +
 +
 +InstDrv::DeleteOemInfFiles
 +Return: result
 +        oeminf
 +        oempnf
 +
 +DeleteOemInfFiles tries to clean up the Windows inf directory by deleting the
 +oemXX.inf and oemXX.pnf files associated with the drivers. It returns a
 +Windows error code (in hex) and, on success, the names of the deleted files.
 +This functions requires that at least one device instance is still present.
 +So, call it before you remove the devices itself. You should also call it
 +before updating a driver. This avoids that the inf directory gets slowly
 +messed up with useless old setup scripts (which does NOT really accelerate
 +Windows). The error code which comes up when no device is installed is
 +"00000103".
 +
 +
 +
 +InstDrv::RemoveAllDevices
 +Return: result
 +        reboot
 +
 +This functions deletes all devices instances the driver supported. It returns
 +a Windows error code (in hex) and, on success, a flag signalling if the system
 +needs to be rebooted. You additionally have to remove the driver binaries from
 +the system paths.
 +
 +
 +
 +InstDrv::StartSystemService serviceName
 +Return: result
 +
 +Call this function to start the provided system service. The function blocks
 +until the service is started or the system reported a timeout. The return value
 +is the Windows error code (in hex).
 +
 +
 +
 +InstDrv::StopSystemService serviceName
 +Return: result
 +
 +This function tries to stop the provided system service. It blocks until the
 +service has been shut down or the system reported a timeout. The return value
 +is the Windows error code (in hex).
 +
 +
 +
 +Example.nsi
 +
 +The example script installs or removes the virtual COM port driver of IrCOMM2k
 +(2.0.0-alpha8, see www.ircomm2k.de/english). The driver and its setup script
 +are only included for demonstration purposes, they do not work without the
 +rest of IrCOMM2k (but they also do not cause any harm).
 +
 +
 +
 +Building the Source Code
 +
 +To build the plugin from the source code, some include files and libraries
 +which come with the Windows DDK are required.
 +
 +
 +
 +History
 +
 + 0.2    - fixed bug when calling InitDriverSetup the second time
 +        - added StartSystemService and StopSystemService
 +
 + 0.1    - first release
 +
 +
 +
 +License
 +
 +Copyright © 2003 Jan Kiszka (Jan.Kiszka@web.de)
 +
 +This software is provided 'as-is', without any express or implied
 +warranty. In no event will the authors be held liable for any damages
 +arising from the use of this software.
 +
 +Permission is granted to anyone to use this software for any purpose,
 +including commercial applications, and to alter it and redistribute
 +it freely, subject to the following restrictions:
 +
 +1. The origin of this software must not be misrepresented; 
 +   you must not claim that you wrote the original software.
 +   If you use this software in a product, an acknowledgment in the
 +   product documentation would be appreciated but is not required.
 +2. Altered versions must be plainly marked as such,
 +   and must not be misrepresented as being the original software.
 +3. This notice may not be removed or altered from any distribution.
 diff --git a/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/ircomm2k.inf b/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/ircomm2k.inf new file mode 100644 index 00000000..ccda1d87 --- /dev/null +++ b/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/ircomm2k.inf @@ -0,0 +1,137 @@ +; IrCOMM2k.inf
 +;
 +; Installation file for the Virtual Infrared-COM-Port
 +;
 +; (c) Copyright 2001, 2002 Jan Kiszka 
 +;
 +
 +[Version]
 +Signature="$Windows NT$"
 +Provider=%JK%
 +Class=Ports
 +ClassGUID={4d36e978-e325-11ce-bfc1-08002be10318}
 +;DriverVer=03/26/2002,1.2.1.0
 +
 +[DestinationDirs]
 +IrCOMM2k.Copy2Drivers  = 12
 +IrCOMM2k.Copy2Winnt    = 10
 +IrCOMM2k.Copy2System32 = 11
 +IrCOMM2k.Copy2Help     = 18
 +
 +
 +;
 +; Driver information
 +;
 +
 +[Manufacturer]
 +%JK%   = JK.Mfg
 +
 +[JK.Mfg]
 +%JK.DeviceDescIrCOMM% = IrCOMM2k_inst,IrCOMM2k
 +
 +
 +;
 +; General installation section
 +;
 +
 +[IrCOMM2k_inst]
 +CopyFiles = IrCOMM2k.Copy2Drivers ;,IrCOMM2k.Copy2System32,IrCOMM2k.Copy2Help,IrCOMM2k.Copy2Winnt
 +;AddReg    = IrCOMM2k_inst_AddReg
 +
 +
 +;
 +; File sections
 +;
 +
 +[IrCOMM2k.Copy2Drivers]
 +ircomm2k.sys,,,2
 +
 +;[IrCOMM2k.Copy2System32]
 +;ircomm2k.exe,,,2
 +;ircomm2k.dll,,,2
 +
 +;[IrCOMM2k.Copy2Help]
 +;ircomm2k.hlp,,,2
 +
 +;[IrCOMM2k.Copy2Winnt]
 +;IrCOMM2k-Setup.exe,Setup.exe,,2
 +
 +
 +;
 +; Service Installation
 +;
 +
 +[IrCOMM2k_inst.Services]
 +AddService = IrCOMM2k,0x00000002,IrCOMM2k_DriverService_Inst,IrCOMM2k_DriverEventLog_Inst
 +;AddService = IrCOMM2kSvc,,IrCOMM2k_Service_Inst
 +
 +[IrCOMM2k_DriverService_Inst]
 +DisplayName    = %IrCOMM2k.DrvName%
 +ServiceType    = 1                  ; SERVICE_KERNEL_DRIVER
 +StartType      = 3                  ; SERVICE_DEMAND_START
 +ErrorControl   = 0                  ; SERVICE_ERROR_IGNORE
 +ServiceBinary  = %12%\ircomm2k.sys
 +
 +;[IrCOMM2k_Service_Inst]
 +;DisplayName    = %IrCOMM2k.SvcName%
 +;Description    = %IrCOMM2k.SvcDesc%
 +;ServiceType    = 0x00000120         ; SERVICE_WIN32_SHARE_PROCESS, SERVICE_INTERACTIVE_PROCESS
 +;StartType      = 2                  ; SERVICE_AUTO_START
 +;ErrorControl   = 0                  ; SERVICE_ERROR_IGNORE
 +;ServiceBinary  = %11%\ircomm2k.exe
 +;Dependencies   = IrCOMM2k
 +;AddReg         = IrCOMM2kSvcAddReg
 +
 +
 +[IrCOMM2k_inst.nt.HW]
 +AddReg=IrCOMM2kHwAddReg
 +
 +[IrCOMM2kHwAddReg]
 +HKR,,PortSubClass,REG_BINARY,0x00000001
 +;HKR,,TimeoutScaling,REG_DWORD,0x00000001
 +;HKR,,StatusLines,REG_DWORD,0x00000000
 +
 +;[IrCOMM2k_inst_AddReg]
 +;HKR,,EnumPropPages32,,"ircomm2k.dll,IrCOMM2kPropPageProvider"
 +;HKLM,%UNINSTALL_KEY%,DisplayIcon,0x00020000,"%windir%\IrCOMM2k-Setup.exe"
 +;HKLM,%UNINSTALL_KEY%,DisplayName,,"IrCOMM2k 1.2.1 "
 +;HKLM,%UNINSTALL_KEY%,DisplayVersion,,"1.2.1"
 +;HKLM,%UNINSTALL_KEY%,HelpLink,,"http://www.ircomm2k.de"
 +;HKLM,%UNINSTALL_KEY%,Publisher,,%JK%
 +;HKLM,%UNINSTALL_KEY%,UninstallString,0x00020000,"%windir%\IrCOMM2k-Setup.exe"
 +
 +;[IrCOMM2kSvcAddReg]
 +;HKR,Parameters,ActiveConnectOnly,REG_DWORD,0x00000000
 +
 +
 +[IrCOMM2k_DriverEventLog_Inst]
 +AddReg = IrCOMM2k_DriverEventLog_AddReg
 +
 +[IrCOMM2k_DriverEventLog_AddReg]
 +HKR,,EventMessageFile,REG_EXPAND_SZ,"%SystemRoot%\System32\IoLogMsg.dll;%SystemRoot%\System32\drivers\ircomm2k.sys"
 +HKR,,TypesSupported,REG_DWORD,7
 +
 +
 +[Strings]
 +
 +;
 +; Non-Localizable Strings
 +;
 +
 +REG_SZ         = 0x00000000
 +REG_MULTI_SZ   = 0x00010000
 +REG_EXPAND_SZ  = 0x00020000
 +REG_BINARY     = 0x00000001
 +REG_DWORD      = 0x00010001
 +SERVICEROOT    = "System\CurrentControlSet\Services"
 +UNINSTALL_KEY  = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\IrCOMM2k"
 +
 +;
 +; Localizable Strings
 +;
 +
 +JK                  = "Jan Kiszka"
 +JK.DeviceDescIrCOMM = "Virtueller Infrarot-Kommunikationsanschluss"
 +IrCOMM2k.DrvName    = "Virtueller Infrarot-Kommunikationsanschluss"
 +;IrCOMM2k.SvcName    = "Virtueller Infrarot-Kommunikationsanschluß, Dienstprogramm"
 +;IrCOMM2k.SvcDesc    = "Bildet über Infarot einen Kommunikationsanschluß nach."
 diff --git a/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/ircomm2k.sys b/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/ircomm2k.sysBinary files differ new file mode 100644 index 00000000..7882583b --- /dev/null +++ b/ao-tools/altosui/Instdrv/NSIS/Contrib/InstDrv/ircomm2k.sys diff --git a/ao-tools/altosui/Instdrv/NSIS/Plugins/InstDrv.dll b/ao-tools/altosui/Instdrv/NSIS/Plugins/InstDrv.dllBinary files differ new file mode 100644 index 00000000..482e955e --- /dev/null +++ b/ao-tools/altosui/Instdrv/NSIS/Plugins/InstDrv.dll diff --git a/ao-tools/altosui/Makefile b/ao-tools/altosui/Makefile deleted file mode 100644 index 63359fbb..00000000 --- a/ao-tools/altosui/Makefile +++ /dev/null @@ -1,98 +0,0 @@ -.SUFFIXES: .java .class - -CLASSPATH=classes:./*:/usr/share/java/* -CLASSFILES=\ -	Altos.class \ -	AltosChannelMenu.class \ -	AltosConfig.class \ -	AltosConfigUI.class \ -	AltosConvert.class \ -	AltosCSV.class \ -	AltosEepromDownload.class \ -	AltosEepromMonitor.class \ -	AltosEepromReader.class \ -	AltosEepromRecord.class \ -	AltosFile.class \ -	AltosFlightInfoTableModel.class \ -	AltosFlightStatusTableModel.class \ -	AltosGPS.class \ -	AltosGreatCircle.class \ -	AltosLog.class \ -	AltosParse.class \ -	AltosPreferences.class \ -	AltosRecord.class \ -	AltosSerialMonitor.class \ -	AltosSerial.class \ -	AltosState.class \ -	AltosTelemetry.class \ -	AltosTelemetryReader.class \ -	AltosUI.class \ -	AltosDevice.class \ -	AltosDeviceDialog.class \ -	AltosVoice.class - -#FREETTSSRC=/home/keithp/src/freetts/freetts-1.2.2 -#FREETTSLIB=$(FREETTSSRC)/lib -#FREETTSJAR=/usr/share/java/freetts.jar -#FREETTSJAR= \ -#	cmudict04.jar \ -#	cmulex.jar \ -#	cmu_time_awb.jar \ -#	cmutimelex.jar \ -#	cmu_us_kal.jar \ -#	en_us.jar \ -#	freetts.jar - -JAVAFLAGS=-Xlint:unchecked -Xlint:deprecation - -OS:=$(shell uname) - -ifeq ($(OS),Linux) -ALTOSUI_APP=altosui -endif - -ifeq ($(OS),Darwin) -ALTOSUI_APP=AltosUI.app/Contents/Resources/Java/altosui.jar -endif - -all: altosui.jar $(ALTOSUI_APP) - -$(CLASSFILES): - -.java.class: -	javac -encoding UTF8 -classpath "$(CLASSPATH)" $(JAVAFLAGS) $*.java - -altosui.jar: classes/altosui classes/libaltosJNI $(FREETTSJAR) $(CLASSFILES) Manifest.txt -	cd ./classes && jar cfm ../$@ altosui/Manifest.txt altosui/*.class libaltosJNI/*.class - -classes/altosui: -	mkdir -p classes -	ln -sf .. classes/altosui - -classes/libaltosJNI: -	mkdir -p classes -	ln -sf ../../libaltos/libaltosJNI classes/libaltosJNI - -#$(FREETTSJAR): -#	ln -s $(FREETTSLIB)/$@ . - -ifeq ($(OS),Darwin) -RESOURCES=altosui.jar $(FREETTSJAR) ../libaltos/libaltos.dylib - -$(ALTOSUI_APP): $(RESOURCES) -	mkdir -p AltosUI.app/Contents/Resources/Java -	cp $(RESOURCES) AltosUI.app/Contents/Resources/Java - -endif - -ifeq ($(OS),Linux) -altosui: -	echo "#!/bin/sh" > $@ -	echo "exec java -Djava.library.path=../libaltos -jar altosui.jar" >> $@ -	chmod +x ./altosui -endif - -clean: -	rm -f *.class altosui.jar -	rm -f AltosUI.app/Contents/Resources/Java/* -	rm -rf classes diff --git a/ao-tools/altosui/Makefile-standalone b/ao-tools/altosui/Makefile-standalone new file mode 100644 index 00000000..90621f36 --- /dev/null +++ b/ao-tools/altosui/Makefile-standalone @@ -0,0 +1,182 @@ +.SUFFIXES: .java .class + +CLASSPATH=classes:./*:/usr/share/java/* +CLASSFILES=\ +	Altos.class \ +	AltosChannelMenu.class \ +	AltosConfig.class \ +	AltosConfigUI.class \ +	AltosConvert.class \ +	AltosCRCException.class \ +	AltosCSV.class \ +	AltosCSVUI.class \ +	AltosDebug.class \ +	AltosEepromDownload.class \ +	AltosEepromMonitor.class \ +	AltosEepromReader.class \ +	AltosEepromRecord.class \ +	AltosFile.class \ +	AltosFlash.class \ +	AltosFlashUI.class \ +	AltosFlightInfoTableModel.class \ +	AltosFlightStatusTableModel.class \ +	AltosGPS.class \ +	AltosGreatCircle.class \ +	AltosHexfile.class \ +	AltosLine.class \ +	AltosLog.class \ +	AltosLogfileChooser.class \ +	AltosParse.class \ +	AltosPreferences.class \ +	AltosReader.class \ +	AltosRecord.class \ +	AltosSerialMonitor.class \ +	AltosSerial.class \ +	AltosState.class \ +	AltosTelemetry.class \ +	AltosTelemetryReader.class \ +	AltosUI.class \ +	AltosDevice.class \ +	AltosDeviceDialog.class \ +	AltosRomconfig.class \ +	AltosRomconfigUI.class \ +	AltosVoice.class + +JAVA_ICON=../../icon/altus-metrum-16x16.jpg +WINDOWS_ICON=../../icon/altus-metrum.ico + +# where altosui.jar gets installed +ALTOSLIB=/usr/share/java + +# where freetts.jar is to be found +FREETTSLIB=/usr/share/java + +# all of the freetts files +FREETTSJAR= \ +	$(FREETTSLIB)/cmudict04.jar \ +	$(FREETTSLIB)/cmulex.jar \ +	$(FREETTSLIB)/cmu_time_awb.jar \ +	$(FREETTSLIB)/cmutimelex.jar \ +	$(FREETTSLIB)/cmu_us_kal.jar \ +	$(FREETTSLIB)/en_us.jar \ +	$(FREETTSLIB)/freetts.jar + +# The current hex files +HEXLIB=../../src +HEXFILES = \ +	$(HEXLIB)/telemetrum-v1.0.ihx \ +	$(HEXLIB)/teledongle-v0.2.ihx + +JAVAFLAGS=-Xlint:unchecked -Xlint:deprecation + +ALTOSUIJAR = altosui.jar +FATJAR = fat/altosui.jar + +OS:=$(shell uname) + +LINUX_APP=altosui + +DARWIN_ZIP=Altos-Mac.zip + +WINDOWS_EXE=Altos-Windows.exe + +LINUX_TGZ=Altos-Linux.tgz + +all: altosui.jar $(LINUX_APP) +fat: altosui.jar $(LINUX_APP) $(DARWIN_ZIP) $(WINDOWS_EXE) $(LINUX_TGZ) + +$(CLASSFILES): + +.java.class: +	javac -encoding UTF8 -classpath "$(CLASSPATH)" $(JAVAFLAGS) $*.java + +altosui.jar: classes/images classes/altosui classes/libaltosJNI $(CLASSFILES) Manifest.txt +	cd ./classes && jar cfm ../$@ altosui/Manifest.txt images/* altosui/*.class libaltosJNI/*.class + +Manifest.txt: Makefile $(CLASSFILES) +	echo 'Main-Class: altosui.AltosUI' > $@ +	echo "Class-Path: $(FREETTSLIB)/freetts.jar" >> $@ + +classes/altosui: +	mkdir -p classes +	ln -sf .. classes/altosui + +classes/libaltosJNI: +	mkdir -p classes +	ln -sf ../../libaltos/libaltosJNI classes/libaltosJNI + +classes/images: +	mkdir -p classes/images +	ln -sf ../../$(JAVA_ICON) classes/images + +altosui: +	echo "#!/bin/sh" > $@ +	echo "exec java -Djava.library.path=/usr/lib/altos -jar /usr/share/java/altosui.jar" >> $@ +	chmod +x ./altosui + +fat/altosui: +	echo "#!/bin/sh" > $@ +	echo 'ME=`which "$0"`' >> $@ +	echo 'DIR=`dirname "$ME"`' >> $@ +	echo 'exec java -Djava.library.path="$$DIR" -jar "$$DIR"/altosui.jar' >> $@ +	chmod +x $@ + +fat/altosui.jar: $(CLASSFILES) $(JAVA_ICON) fat/classes/Manifest.txt +	mkdir -p fat/classes +	test -L fat/classes/altosui || ln -sf ../.. fat/classes/altosui +	mkdir -p fat/classes/images +	cp $(JAVA_ICON) fat/classes/images +	test -L fat/classes/libaltosJNI || ln -sf ../../../libaltos/libaltosJNI fat/classes/libaltosJNI +	cd ./fat/classes && jar cfm ../../$@ Manifest.txt images/* altosui/*.class libaltosJNI/*.class + +fat/classes/Manifest.txt: $(CLASSFILES) Makefile +	mkdir -p fat/classes +	echo 'Main-Class: altosui.AltosUI' > $@ +	echo "Class-Path: freetts.jar" >> $@ + +install: altosui.jar altosui +	install -m 0644 altosui.jar $(DESTDIR)/usr/share/java/altosui.jar +	install -m 0644 altosui.1 $(DESTDIR)/usr/share/man/man1/altosui.1 +	install altosui $(DESTDIR)/usr/bin/altosui + +clean: +	rm -f *.class altosui.jar +	rm -f AltosUI.app/Contents/Resources/Java/* +	rm -rf classes +	rm -rf windows linux + +distclean:	clean +	rm -f $(DARWIN_ZIP) $(WINDOWS_EXE) $(LINUX_TGZ) +	rm -rf darwin fat + +FAT_FILES=$(FATJAR) $(FREETTSJAR) $(HEXFILES) + +LINUX_FILES=$(FAT_FILES) ../libaltos/libaltos.so fat/altosui +$(LINUX_TGZ): $(LINUX_FILES) +	rm -f $@ +	mkdir -p linux/AltOS +	rm -f linux/AltOS/* +	cp $(LINUX_FILES) linux/AltOS +	cd linux && tar czf ../$@ AltOS + +DARWIN_RESOURCES=$(FATJAR) $(FREETTSJAR) ../libaltos/libaltos.dylib +DARWIN_EXTRA=$(HEXFILES) +DARWIN_FILES=$(DARWIN_RESOURCES) $(DARWIN_EXTRA) + +$(DARWIN_ZIP): $(DARWIN_FILES) +	rm -f $@ +	cp -a AltosUI.app darwin/ +	mkdir -p darwin/AltosUI.app/Contents/Resources/Java +	cp $(DARWIN_RESOURCES) darwin/AltosUI.app/Contents/Resources/Java +	mkdir -p darwin/AltOS +	cp $(DARWIN_EXTRA) darwin/AltOS +	cd darwin && zip -r ../$@ AltosUI.app AltOS + +WINDOWS_FILES = $(FAT_FILES) ../libaltos/altos.dll ../../telemetrum.inf $(WINDOWS_ICON) + +$(WINDOWS_EXE): $(WINDOWS_FILES) altos-windows.nsi +	rm -f $@ +	mkdir -p windows/AltOS +	rm -f windows/AltOS/* +	cp $(WINDOWS_FILES) windows/AltOS +	makensis altos-windows.nsi diff --git a/ao-tools/altosui/Makefile.am b/ao-tools/altosui/Makefile.am new file mode 100644 index 00000000..dd4b31e6 --- /dev/null +++ b/ao-tools/altosui/Makefile.am @@ -0,0 +1,172 @@ +JAVAROOT=classes +AM_JAVACFLAGS=-encoding UTF-8 + +CLASSPATH_ENV=CLASSPATH=".:classes:../libaltos:$(FREETTS)/*:/usr/share/java/*" + +bin_SCRIPTS=altosui + +altosui_JAVA = \ +	AltosChannelMenu.java \ +	AltosConfig.java \ +	AltosConfigUI.java \ +	AltosConvert.java \ +	AltosCRCException.java \ +	AltosCSV.java \ +	AltosCSVUI.java \ +	AltosDebug.java \ +	AltosDeviceDialog.java \ +	AltosDevice.java \ +	AltosEepromDownload.java \ +	AltosEepromMonitor.java \ +	AltosEepromReader.java \ +	AltosEepromRecord.java \ +	AltosFile.java \ +	AltosFlash.java \ +	AltosFlashUI.java \ +	AltosFlightInfoTableModel.java \ +	AltosFlightStatusTableModel.java \ +	AltosGPS.java \ +	AltosGreatCircle.java \ +	AltosHexfile.java \ +	Altos.java \ +	AltosLine.java \ +	AltosLogfileChooser.java \ +	AltosLog.java \ +	AltosParse.java \ +	AltosPreferences.java \ +	AltosReader.java \ +	AltosRecord.java \ +	AltosRomconfig.java \ +	AltosRomconfigUI.java \ +	AltosSerial.java \ +	AltosSerialMonitor.java \ +	AltosState.java \ +	AltosTelemetry.java \ +	AltosTelemetryReader.java \ +	AltosUI.java \ +	AltosVoice.java + +FREETTS_CLASS= \ +	cmudict04.jar \ +	cmulex.jar \ +	cmu_time_awb.jar \ +	cmutimelex.jar \ +	cmu_us_kal.jar \ +	en_us.jar \ +	freetts.jar + +LIBALTOS= \ +	libaltos.so \ +	libaltos.dylib \ +	altos.dll + +JAR=altosui.jar + +FATJAR=altosui-fat.jar + +# Icons +JAVA_ICON=$(top_srcdir)/icon/altus-metrum-16x16.jpg +WINDOWS_ICON=$(top_srcdir)/icon/altus-metrum.ico + +# Firmware +FIRMWARE_TD=$(top_srcdir)/src/teledongle-v0.2-$(VERSION).ihx +FIRMWARE_TM=$(top_srcdir)/src/telemetrum-v1.0-$(VERSION).ihx +FIRMWARE=$(FIRMWARE_TM) $(FIRMWARE_TD) + +# Distribution targets +LINUX_DIST=Altos-Linux-$(VERSION).tar.bz2 +MACOSX_DIST=Altos-Mac-$(VERSION).zip +WINDOWS_DIST=Altos-Windows-$(VERSION_DASH).exe + +FAT_FILES=$(FATJAR) $(FREETTS_CLASS) + +LINUX_FILES=$(FAT_FILES) libaltos.so $(FIRMWARE) +LINUX_EXTRA=altosui-fat + +MACOSX_FILES=$(FAT_FILES) libaltos.dylib +MACOSX_EXTRA=$(FIRMWARE) + +WINDOWS_FILES=$(FAT_FILES) altos.dll $(top_srcdir)/telemetrum.inf $(WINDOWS_ICON) + +all-local: classes/altosui $(JAR) $(FATJAR) altosui altosui-test + +clean-local: +	-rm -rf classes/altosui $(JAR) $(FATJAR) \ +		$(LINUX_DIST) $(MACOSX_DIST) $(WINDOWS_DIST) $(FREETTS_CLASS) \ +		$(LIBALTOS) Manifest.txt Manifest-fat.txt altos-windows.log \ +		altosui altosui-test macosx linux + +fat: $(FATJAR) $(LINUX_DIST) $(MACOSX_DIST) $(WINDOWS_DIST) + +altosuidir=$(datadir)/java + +install-altosuiJAVA: altosui.jar +	@$(NORMAL_INSTALL) +	test -z "$(altosuidir)" || $(MKDIR_P) "$(DESTDIR)$(altosuidir)" +	echo " $(INSTALL_DATA)" "$<" "'$(DESTDIR)$(altosuidir)/altosui.jar'"; \ +	$(INSTALL_DATA) "$<" "$(DESTDIR)$(altosuidir)" + +classes/altosui: +	mkdir -p classes/altosui + +$(JAR): classaltosui.stamp Manifest.txt $(JAVA_ICON) +	jar cfm $@ Manifest.txt \ +		-C $(top_srcdir)/icon altus-metrum-16x16.jpg \ +		-C classes altosui \ +		-C ../libaltos libaltosJNI + +$(FATJAR): classaltosui.stamp Manifest-fat.txt $(FREETTS_CLASS) $(LIBALTOS) $(JAVA_ICON) +	jar cfm $@ Manifest-fat.txt \ +		-C $(top_srcdir)/icon altus-metrum-16x16.jpg \ +		-C classes altosui \ +		-C ../libaltos libaltosJNI + +Manifest.txt: Makefile +	echo 'Main-Class: altosui.AltosUI' > $@ +	echo "Class-Path: $(FREETTS)/freetts.jar" >> $@ + +Manifest-fat.txt: +	echo 'Main-Class: altosui.AltosUI' > $@ +	echo "Class-Path: freetts.jar" >> $@ + +altosui: Makefile +	echo "#!/bin/sh" > $@ +	echo 'exec java  -cp "$(FREETTS)/*" -Djava.library.path="$(libdir)" -jar "$(altosuidir)/altosui.jar" "$$@"' >> $@ +	chmod +x $@ + +altosui-test: Makefile +	echo "#!/bin/sh" > $@ +	echo 'exec java -cp "$(FREETTS)/*" -Djava.library.path="../libaltos" -jar altosui.jar "$$*"' >> $@ +	chmod +x $@ + +$(LIBALTOS): +	-rm -f "$@" +	$(LN_S) ../libaltos/"$@" . + +$(FREETTS_CLASS): +	-rm -f "$@" +	$(LN_S) "$(FREETTS)"/"$@" . + +$(LINUX_DIST): $(LINUX_FILES) $(LINUX_EXTRA) +	-rm -f $@ +	-rm -rf linux +	mkdir -p linux/AltOS +	cp -p $(LINUX_FILES) linux/AltOS +	cp -p altosui-fat linux/AltOS/altosui +	chmod +x linux/AltOS/altosui +	tar cjf $@ -C linux AltOS + +$(MACOSX_DIST): $(MACOSX_FILES) $(MACOSX_EXTRA) +	-rm -f $@ +	-rm -rf macosx +	mkdir macosx +	cp -a AltosUI.app macosx/ +	mkdir -p macosx/AltOS macosx/AltosUI.app/Contents/Resources/Java +	cp -p $(FATJAR) macosx/AltosUI.app/Contents/Resources/Java/altosui.jar +	cp -p $(FREETTS_CLASS) libaltos.dylib macosx/AltosUI.app/Contents/Resources/Java +	cp -p $(MACOSX_EXTRA) macosx/AltOS +	cd macosx && zip -r ../$@ AltosUI.app AltOS + +$(WINDOWS_DIST): $(WINDOWS_FILES) altos-windows.nsi +	-rm -f $@ +	makensis -Oaltos-windows.log "-XOutFile $@" "-DVERSION=$(VERSION)" altos-windows.nsi
\ No newline at end of file diff --git a/ao-tools/altosui/Manifest.txt b/ao-tools/altosui/Manifest.txt deleted file mode 100644 index 504d0de3..00000000 --- a/ao-tools/altosui/Manifest.txt +++ /dev/null @@ -1,2 +0,0 @@ -Main-Class: altosui.AltosUI -Class-Path: /usr/share/java/freetts.jar diff --git a/ao-tools/altosui/altos-windows.nsi b/ao-tools/altosui/altos-windows.nsi new file mode 100644 index 00000000..6ebec214 --- /dev/null +++ b/ao-tools/altosui/altos-windows.nsi @@ -0,0 +1,110 @@ +!addplugindir Instdrv/NSIS/Plugins + +Name "Altus Metrum Installer" + +; Default install directory +InstallDir "$PROGRAMFILES\AltusMetrum" + +; Tell the installer where to re-install a new version +InstallDirRegKey HKLM "Software\AltusMetrum" "Install_Dir" + +LicenseText "GNU General Public License Version 2" +LicenseData "../../COPYING" + +; Need admin privs for Vista or Win7 +RequestExecutionLevel admin + +ShowInstDetails Show + +ComponentText "Altus Metrum Software and Driver Installer" + +; Pages to present + +Page license +Page components +Page directory +Page instfiles + +UninstPage uninstConfirm +UninstPage instfiles + +; And the stuff to install + +Section "Install Driver" InstDriver +	InstDrv::InitDriverSetup /NOUNLOAD {4D36E96D-E325-11CE-BFC1-08002BE10318} "Altus Metrum" +	Pop $0 +	DetailPrint "InitDriverSetup: $0" + +	InstDrv::DeleteOemInfFiles /NOUNLOAD +	InstDrv::CreateDevice /NOUNLOAD +	SetOutPath $TEMP +	File "../../telemetrum.inf" +	InstDrv::InstallDriver /NOUNLOAD "$TEMP\telemetrum.inf" +SectionEnd + +Section "AltosUI Application" +	SetOutPath $INSTDIR + +	File "altosui-fat.jar" +	File "cmudict04.jar" +	File "cmulex.jar" +	File "cmu_time_awb.jar" +	File "cmutimelex.jar" +	File "cmu_us_kal.jar" +	File "en_us.jar" +	File "freetts.jar" + +	File "*.dll" + +	File "../../icon/*.ico" + +	CreateShortCut "$SMPROGRAMS\AltusMetrum.lnk" "$INSTDIR\altosui-fat.jar" "" "$INSTDIR\altus-metrum.ico" +SectionEnd + +Section "AltosUI Desktop Shortcut" +	CreateShortCut "$DESKTOP\AltusMetrum.lnk" "$INSTDIR\altosui-fat.jar"  "" "$INSTDIR\altus-metrum.ico" +SectionEnd + +Section "TeleMetrum and TeleDongle Firmware" + +	SetOutPath $INSTDIR + +	File "../../src/telemetrum-v1.0/telemetrum-v1.0-${VERSION}.ihx" +	File "../../src/teledongle-v0.2/teledongle-v0.2-${VERSION}.ihx" + +SectionEnd + +Section "Uninstaller" + +	; Deal with the uninstaller +	 +	SetOutPath $INSTDIR + +	; Write the install path to the registry +	WriteRegStr HKLM SOFTWARE\AltusMetrum "Install_Dir" "$INSTDIR" +	 +	; Write the uninstall keys for windows +	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "DisplayName" "Altus Metrum" +	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "UninstallString" '"$INSTDIR\uninstall.exe"' +	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "NoModify" "1" +	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" "NoRepair" "1" + +	WriteUninstaller "uninstall.exe" +SectionEnd + +Section "Uninstall" +	DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltusMetrum" +	DeleteRegKey HKLM "Software\AltusMetrum" + +	Delete "$INSTDIR\*.*" +	RMDir "$INSTDIR" + +	; Remove devices +	InstDrv::InitDriverSetup /NOUNLOAD {4D36E96D-E325-11CE-BFC1-08002BE10318} "Altus Metrum" +	InstDrv::DeleteOemInfFiles /NOUNLOAD +	InstDrv::RemoveAllDevices + +	; Remove shortcuts, if any +	Delete "$SMPROGRAMS\AltusMetrum.lnk" +	Delete "$DESKTOP\AltusMetrum.lnk" +SectionEnd diff --git a/ao-tools/altosui/altosui-fat b/ao-tools/altosui/altosui-fat new file mode 100755 index 00000000..95b1c051 --- /dev/null +++ b/ao-tools/altosui/altosui-fat @@ -0,0 +1,4 @@ +#!/bin/sh +me=`which "$0"` +dir=`dirname "$me"` +exec java -cp "$dir/*" -Djava.library.path="$dir" -jar "$dir"/altosui-fat.jar  "$@" diff --git a/ao-tools/altosui/altosui.1 b/ao-tools/altosui/altosui.1 new file mode 100644 index 00000000..c3130fce --- /dev/null +++ b/ao-tools/altosui/altosui.1 @@ -0,0 +1,44 @@ +.\" +.\" Copyright © 2010 Bdale Garbee <bdale@gag.com> +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, but +.\" WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +.\" General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License along +.\" with this program; if not, write to the Free Software Foundation, Inc., +.\" 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +.\" +.\" +.TH AO-VIEW 1 "altosui" "" +.SH NAME +altosui \- Rocket flight monitor +.SH SYNOPSIS +.B "altosui" +.SH DESCRIPTION +.I altosui +connects to a TeleDongle or TeleMetrum device through a USB serial device. +It provides a user interface to monitor, record and review rocket flight data. +.SH USAGE +When connected to a TeleDongle device, altosui turns on the radio +receiver and listens for telemetry packets. It displays the received +telemetry data, and reports flight status via voice synthesis. All +received telemetry information is recorded to a file. +.P +When connected to a TeleMetrum device, altosui downloads the eeprom +data and stores it in a file. +.SH FILES +All data log files are recorded into a user-specified directory +(default ~/AltOS). Files are named using the current date, the serial +number of the reporting device, the flight number recorded in the data +and either '.telem' for telemetry data or '.eeprom' for eeprom data. +.SH "SEE ALSO" +ao-view(1), ao-load(1), ao-eeprom(1) +.SH AUTHOR +Keith Packard diff --git a/ao-tools/ao-dumplog/ao-dumplog.c b/ao-tools/ao-dumplog/ao-dumplog.c index 57c43290..6d4fa5bf 100644 --- a/ao-tools/ao-dumplog/ao-dumplog.c +++ b/ao-tools/ao-dumplog/ao-dumplog.c @@ -29,7 +29,7 @@  static const struct option options[] = {  	{ .name = "tty", .has_arg = 1, .val = 'T' },  	{ .name = "device", .has_arg = 1, .val = 'D' }, -	{ .name = "remote", .has_arg = 1, .val = 'R' }, +	{ .name = "remote", .has_arg = 0, .val = 'R' },  	{ .name = "channel", .has_arg = 1, .val = 'C' },  	{ 0, 0, 0, 0},  }; @@ -91,7 +91,7 @@ main (int argc, char **argv)  	int		invalid;  	char		serial_line[8192]; -	while ((c = getopt_long(argc, argv, "T:D:R", options, NULL)) != -1) { +	while ((c = getopt_long(argc, argv, "T:D:C:R", options, NULL)) != -1) {  		switch (c) {  		case 'T':  			tty = optarg; diff --git a/ao-tools/libaltos/.gitignore b/ao-tools/libaltos/.gitignore new file mode 100644 index 00000000..c490e6f8 --- /dev/null +++ b/ao-tools/libaltos/.gitignore @@ -0,0 +1,12 @@ +*.so +*.lo +*.la +*.java +*.class +.libs/ +classlibaltos.stamp +libaltos_wrap.c +libaltosJNI +cjnitest +libaltos.swig +swig_bindings/ diff --git a/ao-tools/libaltos/Makefile b/ao-tools/libaltos/Makefile-standalone index a251e54e..4e438050 100644 --- a/ao-tools/libaltos/Makefile +++ b/ao-tools/libaltos/Makefile-standalone @@ -7,13 +7,14 @@ ifeq ($(OS),Linux)  JAVA_CFLAGS=-I/usr/lib/jvm/java-6-openjdk/include -OS_CFLAGS=-DLINUX -DPOSIX_TTY $(JAVA_CFLAGS) +OS_LIB_CFLAGS=-DLINUX -DPOSIX_TTY $(JAVA_CFLAGS) + +OS_APP_CFLAGS=$(OS_LIB_CFLAGS)  OS_LDFLAGS=  LIBNAME=libaltos.so  EXEEXT= -  endif  # @@ -21,12 +22,13 @@ endif  #  ifeq ($(OS),Darwin) -OS_CFLAGS=\ +OS_LIB_CFLAGS=\  	-DDARWIN -DPOSIX_TTY -arch i386 -arch x86_64 \  	--sysroot=/Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5 \  	-iwithsysroot /System/Library/Frameworks/JavaVM.framework/Headers \  	-iwithsysroot /System/Library/Frameworks/IOKit.framework/Headers \  	-iwithsysroot /System/Library/Frameworks/CoreFoundation.framework/Headers +OS_APP_CFLAGS=$(OS_LIB_CFLAGS)  OS_LDFLAGS =\  	-framework IOKit -framework CoreFoundation @@ -43,7 +45,8 @@ ifneq (,$(findstring MINGW,$(OS)))  CC=gcc -OS_CFLAGS = -DWINDOWS -mconsole +OS_LIB_CFLAGS = -DWINDOWS -mconsole -DBUILD_DLL +OS_APP_CFLAGS = -DWINDOWS -mconsole  OS_LDFLAGS = -lgdi32 -luser32 -lcfgmgr32 -lsetupapi -lole32 \  	-ladvapi32 -lcomctl32 -mconsole -Wl,--add-stdcall-alias @@ -63,7 +66,7 @@ SWIG_FILE=$(SWIG_DIR)/libaltos.swig  SWIG_WRAP=$(SWIG_DIR)/libaltos_wrap.c  JNI_DIR=libaltosJNI -JNI_FILE=$(JNI_DIR)/libaltosJNI.java  +JNI_FILE=$(JNI_DIR)/libaltosJNI.java  JNI_SRCS=$(JNI_FILE) \  	$(JNI_DIR)/SWIGTYPE_p_altos_file.java \  	$(JNI_DIR)/SWIGTYPE_p_altos_list.java \ @@ -84,7 +87,7 @@ all: $(LIBNAME) $(CJNITEST) $(CLASSFILES)  .java.class:  	javac -encoding UTF8 -classpath "$(CLASSPATH)" $(JAVAFLAGS) $*.java -CFLAGS=$(OS_CFLAGS) -O0 -g -I. +CFLAGS=$(OS_LIB_CFLAGS) -O -I.  LDFLAGS=$(OS_LDFLAGS) @@ -93,16 +96,18 @@ SRCS = libaltos.c $(SWIG_WRAP)  OBJS = $(SRCS:%.c=%.o)  LIBS = $(DARWIN_LIBS) -$(CJNITEST): cjnitest.o $(OBJS) -	cc -o $@ $(CFLAGS) cjnitest.o $(OBJS) $(LIBS) +$(CJNITEST): cjnitest.c $(LIBNAME) +	$(CC) -o $@ $(OS_APP_CFLAGS) cjnitest.c $(LIBNAME) $(LIBS) $(LDFLAGS)  $(LIBNAME): $(OBJS) -	gcc -shared $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(LDFLAGS) +	$(CC) -shared $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(LDFLAGS)  clean:  	rm -f $(CLASSFILES) $(OBJS) $(LIBNAME) $(CJNITEST) cjnitest.o  	rm -rf swig_bindings libaltosJNI +distclean:	clean +  $(JNI_FILE): libaltos.i0 $(HEADERS)  	mkdir -p $(SWIG_DIR)  	mkdir -p libaltosJNI @@ -111,3 +116,11 @@ $(JNI_FILE): libaltos.i0 $(HEADERS)  	cp swig_bindings/java/*.java libaltosJNI  $(SWIG_WRAP): $(JNI_FILE) + +ifeq ($(OS),Linux) +install:	$(LIBNAME) +	install -c $(LIBNAME) $(DESTDIR)/usr/lib/altos/$(LIBNAME) + +endif + +.NOTPARALLEL: diff --git a/ao-tools/libaltos/Makefile.am b/ao-tools/libaltos/Makefile.am new file mode 100644 index 00000000..4d29d80e --- /dev/null +++ b/ao-tools/libaltos/Makefile.am @@ -0,0 +1,28 @@ +JAVAC=javac +AM_CFLAGS="-I$(JVM_INCLUDE)" +AM_JAVACFLAGS=-encoding UTF-8 + +lib_LTLIBRARIES=libaltos.la + +libaltos_la_SOURCES=\ +	libaltos.c + +HFILES=libaltos.h + +SWIG_FILE=libaltos.swig + +CLASSDIR=libaltosJNI + +$(SWIG_FILE): libaltos.i0 $(HFILES) +	sed 's;//%;%;' libaltos.i0 $(HFILES) > $(SWIG_FILE) + +all-local: classlibaltos.stamp + +classlibaltos.stamp: $(SWIG_FILE) +	swig -java -package libaltosJNI $(SWIG_FILE) +	mkdir -p libaltosJNI +	$(JAVAC) -d . $(AM_JAVACFLAGS) $(JAVACFLAGS) *.java && \ +	touch classlibaltos.stamp + +clean-local: +	-rm -rf libaltosJNI *.class *.java classlibaltos.stamp $(SWIG_FILE)
\ No newline at end of file diff --git a/ao-tools/libaltos/altos.dll b/ao-tools/libaltos/altos.dllBinary files differ new file mode 100755 index 00000000..28e9b4ad --- /dev/null +++ b/ao-tools/libaltos/altos.dll diff --git a/ao-tools/libaltos/cjnitest.c b/ao-tools/libaltos/cjnitest.c index 93d1f376..c6d6e069 100644 --- a/ao-tools/libaltos/cjnitest.c +++ b/ao-tools/libaltos/cjnitest.c @@ -30,6 +30,7 @@ main ()  			continue;  		}  		altos_puts(file,"v\nc s\n"); +		altos_flush(file);  		while ((c = altos_getchar(file, 100)) >= 0) {  			putchar (c);  		} diff --git a/ao-tools/libaltos/libaltos.c b/ao-tools/libaltos/libaltos.c index 3e8485e4..465f0ac8 100644 --- a/ao-tools/libaltos/libaltos.c +++ b/ao-tools/libaltos/libaltos.c @@ -15,12 +15,13 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -#define BUILD_DLL  #include "libaltos.h"  #include <stdio.h>  #include <stdlib.h>  #include <string.h> +#define USE_POLL +  PUBLIC int  altos_init(void)  { @@ -33,6 +34,9 @@ altos_fini(void)  }  #ifdef DARWIN + +#undef USE_POLL +  /* Mac OS X don't have strndup even if _GNU_SOURCE is defined */  static char *  altos_strndup (const char *s, size_t n) @@ -391,24 +395,40 @@ get_string(io_object_t object, CFStringRef entry, char *result, int result_len)  	return 0;  } +static int +get_number(io_object_t object, CFStringRef entry, int *result) +{ +	CFTypeRef entry_as_number; +	Boolean got_number; +	 +	entry_as_number = IORegistryEntrySearchCFProperty (object, +							   kIOServicePlane, +							   entry, +							   kCFAllocatorDefault, +							   kIORegistryIterateRecursively); +	if (entry_as_number) { +		got_number = CFNumberGetValue(entry_as_number, +					      kCFNumberIntType, +					      result); +		if (got_number) +			return 1; +	} +	return 0; +} +  struct altos_list *  altos_list_start(void)  {  	struct altos_list *list = calloc (sizeof (struct altos_list), 1);  	CFMutableDictionaryRef matching_dictionary = IOServiceMatching("IOUSBDevice"); -	UInt32 vendor = 0xfffe, product = 0x000a; -	CFNumberRef vendor_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vendor); -	CFNumberRef product_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &product);  	io_iterator_t tdIterator;  	io_object_t tdObject; -   -	CFDictionaryAddValue(matching_dictionary, CFSTR(kUSBVendorID), vendor_ref); -	CFDictionaryAddValue(matching_dictionary, CFSTR(kUSBProductID), product_ref); +	kern_return_t ret; +	int i; -	IOServiceGetMatchingServices(kIOMasterPortDefault, matching_dictionary, &list->iterator); -   -	CFRelease(vendor_ref); -	CFRelease(product_ref); +	ret = IOServiceGetMatchingServices(kIOMasterPortDefault, matching_dictionary, &list->iterator); +	if (ret != kIOReturnSuccess) +		return NULL;  	return list;  } @@ -423,8 +443,15 @@ altos_list_next(struct altos_list *list, struct altos_device *device)  		if (!object)  			return 0; +		if (!get_number (object, CFSTR(kUSBVendorID), &device->vendor) || +		    !get_number (object, CFSTR(kUSBProductID), &device->product)) +			continue; +		if (device->vendor != 0xfffe) +			continue; +		if (device->product < 0x000a || 0x0013 < device->product) +			continue;  		if (get_string (object, CFSTR("IOCalloutDevice"), device->path, sizeof (device->path)) && -		    get_string (object, CFSTR("USB Product Name"), device->product, sizeof (device->product)) && +		    get_string (object, CFSTR("USB Product Name"), device->name, sizeof (device->name)) &&  		    get_string (object, CFSTR("USB Serial Number"), serial_string, sizeof (serial_string))) {  			device->serial = atoi(serial_string);  			return 1; @@ -453,6 +480,11 @@ altos_list_finish(struct altos_list *list)  struct altos_file {  	int				fd; +#ifdef USE_POLL +	int				pipe[2]; +#else +	int				out_fd; +#endif  	unsigned char			out_data[USB_BUF_SIZE];  	int				out_used;  	unsigned char			in_data[USB_BUF_SIZE]; @@ -460,7 +492,7 @@ struct altos_file {  	int				in_read;  }; -struct altos_file * +PUBLIC struct altos_file *  altos_open(struct altos_device *device)  {  	struct altos_file	*file = calloc (sizeof (struct altos_file), 1); @@ -476,67 +508,89 @@ altos_open(struct altos_device *device)  		free(file);  		return NULL;  	} +#ifdef USE_POLL +	pipe(file->pipe); +#else +	file->out_fd = open(device->path, O_RDWR | O_NOCTTY); +	if (file->out_fd < 0) { +		perror(device->path); +		close(file->fd); +		free(file); +		return NULL; +	} +#endif  	ret = tcgetattr(file->fd, &term);  	if (ret < 0) {  		perror("tcgetattr");  		close(file->fd); +#ifndef USE_POLL +		close(file->out_fd); +#endif  		free(file);  		return NULL;  	}  	cfmakeraw(&term); +#ifdef USE_POLL +	term.c_cc[VMIN] = 1; +	term.c_cc[VTIME] = 0; +#else  	term.c_cc[VMIN] = 0;  	term.c_cc[VTIME] = 1; +#endif  	ret = tcsetattr(file->fd, TCSAFLUSH, &term);  	if (ret < 0) {  		perror("tcsetattr");  		close(file->fd); +#ifndef USE_POLL +		close(file->out_fd); +#endif  		free(file);  		return NULL;  	}  	return file;  } -void +PUBLIC void  altos_close(struct altos_file *file)  {  	if (file->fd != -1) { -		close(file->fd); +		int	fd = file->fd;  		file->fd = -1; +#ifdef USE_POLL +		write(file->pipe[1], "\r", 1); +#else +		close(file->out_fd); +		file->out_fd = -1; +#endif +		close(fd);  	}  } -void +PUBLIC void  altos_free(struct altos_file *file)  {  	altos_close(file);  	free(file);  } -int -altos_putchar(struct altos_file *file, char c) -{ -	int	ret; - -	if (file->out_used == USB_BUF_SIZE) { -		ret = altos_flush(file); -		if (ret) -			return ret; -	} -	file->out_data[file->out_used++] = c; -	if (file->out_used == USB_BUF_SIZE) -		return altos_flush(file); -	return 0; -} - -int +PUBLIC int  altos_flush(struct altos_file *file)  { +	if (file->out_used && 0) { +		printf ("flush \""); +		fwrite(file->out_data, 1, file->out_used, stdout); +		printf ("\"\n"); +	}  	while (file->out_used) {  		int	ret;  		if (file->fd < 0)  			return -EBADF; +#ifdef USE_POLL  		ret = write (file->fd, file->out_data, file->out_used); +#else +		ret = write (file->out_fd, file->out_data, file->out_used); +#endif  		if (ret < 0)  			return -errno;  		if (ret) { @@ -545,33 +599,93 @@ altos_flush(struct altos_file *file)  			file->out_used -= ret;  		}  	} +	return 0; +} + +PUBLIC int +altos_putchar(struct altos_file *file, char c) +{ +	int	ret; + +	if (file->out_used == USB_BUF_SIZE) { +		ret = altos_flush(file); +		if (ret) { +			return ret; +		} +	} +	file->out_data[file->out_used++] = c; +	ret = 0; +	if (file->out_used == USB_BUF_SIZE) +		ret = altos_flush(file); +	return 0;  } +#ifdef USE_POLL  #include <poll.h> +#endif -int -altos_getchar(struct altos_file *file, int timeout) +static int +altos_fill(struct altos_file *file, int timeout)  { -	while (file->in_read == file->in_used) { -		int	ret; +	int		ret; +#ifdef USE_POLL +	struct pollfd	fd[2]; +#endif -		altos_flush(file); +	if (timeout == 0) +		timeout = -1; +	while (file->in_read == file->in_used) {  		if (file->fd < 0) -			return -EBADF; -		if (timeout) { -			struct pollfd fd; -			int ret; -			fd.fd = file->fd; -			fd.events = POLLIN; -			ret = poll(&fd, 1, timeout); -			if (ret == 0) +			return LIBALTOS_ERROR; +#ifdef USE_POLL +		fd[0].fd = file->fd; +		fd[0].events = POLLIN|POLLERR|POLLHUP|POLLNVAL; +		fd[1].fd = file->pipe[0]; +		fd[1].events = POLLIN; +		ret = poll(fd, 2, timeout); +		if (ret < 0) { +			perror("altos_getchar"); +			return LIBALTOS_ERROR; +		} +		if (ret == 0) +			return LIBALTOS_TIMEOUT; + +		if (fd[0].revents & (POLLHUP|POLLERR|POLLNVAL)) +			return LIBALTOS_ERROR; +		if (fd[0].revents & POLLIN) +#endif +		{ +			ret = read(file->fd, file->in_data, USB_BUF_SIZE); +			if (ret < 0) { +				perror("altos_getchar"); +				return LIBALTOS_ERROR; +			} +			file->in_read = 0; +			file->in_used = ret; +#ifndef USE_POLL +			if (ret == 0 && timeout > 0)  				return LIBALTOS_TIMEOUT; +#endif  		} -		ret = read(file->fd, file->in_data, USB_BUF_SIZE); -		if (ret < 0) +	} +	if (file->in_used && 0) { +		printf ("fill \""); +		fwrite(file->in_data, 1, file->in_used, stdout); +		printf ("\"\n"); +	} +	return 0; +} + +PUBLIC int +altos_getchar(struct altos_file *file, int timeout) +{ +	int	ret; +	while (file->in_read == file->in_used) { +		if (file->fd < 0)  			return LIBALTOS_ERROR; -		file->in_read = 0; -		file->in_used = ret; +		ret = altos_fill(file, timeout); +		if (ret) +			return ret;  	}  	return file->in_data[file->in_read++];  } @@ -580,6 +694,7 @@ altos_getchar(struct altos_file *file, int timeout)  #ifdef WINDOWS +#include <stdlib.h>  #include <windows.h>  #include <setupapi.h> @@ -597,9 +712,11 @@ struct altos_file {  	unsigned char			in_data[USB_BUF_SIZE];  	int				in_used;  	int				in_read; +	OVERLAPPED			ov_read; +	BOOL				pend_read; +	OVERLAPPED			ov_write;  }; -  PUBLIC struct altos_list *  altos_list_start(void)  { @@ -624,15 +741,15 @@ altos_list_next(struct altos_list *list, struct altos_device *device)  	SP_DEVINFO_DATA dev_info_data;  	char		port[128];  	DWORD		port_len; -	char		location[256]; +	char		friendlyname[256];  	char		symbolic[256];  	DWORD		symbolic_len;  	HKEY		dev_key;  	int		vid, pid;  	int		serial;  	HRESULT 	result; -	DWORD		location_type; -	DWORD		location_len; +	DWORD		friendlyname_type; +	DWORD		friendlyname_len;  	dev_info_data.cbSize = sizeof (SP_DEVINFO_DATA);  	while(SetupDiEnumDeviceInfo(list->dev_info, list->index, @@ -666,8 +783,6 @@ altos_list_next(struct altos_list *list, struct altos_device *device)  		sscanf(symbolic + sizeof("\\??\\USB#VID_XXXX&PID_XXXX#") - 1,  		       "%d", &serial);  		if (!USB_IS_ALTUSMETRUM(vid, pid)) { -			printf("Not Altus Metrum symbolic name: %s\n", -			       symbolic);  			RegCloseKey(dev_key);  			continue;  		} @@ -682,33 +797,26 @@ altos_list_next(struct altos_list *list, struct altos_device *device)  			continue;  		} -		/* Fetch the 'location information' which is the device name, -		 * at least on XP */ -		location_len = sizeof (location); +		/* Fetch the device description which is the device name, +		 * with firmware that has unique USB ids */ +		friendlyname_len = sizeof (friendlyname);  		if(!SetupDiGetDeviceRegistryProperty(list->dev_info,  						     &dev_info_data, -						     SPDRP_LOCATION_INFORMATION, -						     &location_type, -						     (BYTE *)location, -						     sizeof(location), -						     &location_len)) +						     SPDRP_FRIENDLYNAME, +						     &friendlyname_type, +						     (BYTE *)friendlyname, +						     sizeof(friendlyname), +						     &friendlyname_len))  		{ -			printf("Failed to get location\n"); +			printf("Failed to get friendlyname\n");  			continue;  		}  		device->vendor = vid;  		device->product = pid;  		device->serial = serial; - -		if (strcasestr(location, "tele")) -			strcpy(device->name, location); -		else -			strcpy(device->name, ""); +		strcpy(device->name, friendlyname);  		strcpy(device->path, port); -		printf ("product: %04x:%04x (%s)  path: %s serial %d\n", -			device->vendor, device->product, device->name, -			device->path, device->serial);  		return 1;  	}  	result = GetLastError(); @@ -725,41 +833,72 @@ altos_list_finish(struct altos_list *list)  }  static int -altos_fill(struct altos_file *file, int timeout) +altos_queue_read(struct altos_file *file)  { -	DWORD	result;  	DWORD	got; -	COMMTIMEOUTS timeouts; - -	if (file->in_read < file->in_used) +	if (file->pend_read)  		return LIBALTOS_SUCCESS; -	file->in_read = file->in_used = 0; -	if (timeout) { -		timeouts.ReadIntervalTimeout = MAXDWORD; -		timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; -		timeouts.ReadTotalTimeoutConstant = timeout; +	if (!ReadFile(file->handle, file->in_data, USB_BUF_SIZE, &got, &file->ov_read)) { +		if (GetLastError() != ERROR_IO_PENDING) +			return LIBALTOS_ERROR; +		file->pend_read = TRUE;  	} else { -		timeouts.ReadIntervalTimeout = 0; -		timeouts.ReadTotalTimeoutMultiplier = 0; -		timeouts.ReadTotalTimeoutConstant = 0; +		file->pend_read = FALSE; +		file->in_read = 0; +		file->in_used = got;  	} -	timeouts.WriteTotalTimeoutMultiplier = 0; -	timeouts.WriteTotalTimeoutConstant = 0; +	return LIBALTOS_SUCCESS; +} -	if (!SetCommTimeouts(file->handle, &timeouts)) { -		printf("SetCommTimeouts failed %d\n", GetLastError()); -	} +static int +altos_wait_read(struct altos_file *file, int timeout) +{ +	DWORD	ret; +	DWORD	got; + +	if (!file->pend_read) +		return LIBALTOS_SUCCESS; -	if (!ReadFile(file->handle, file->in_data, USB_BUF_SIZE, &got, NULL)) { -		result = GetLastError(); -		printf ("read failed %d\n", result); +	if (!timeout) +		timeout = INFINITE; + +	ret = WaitForSingleObject(file->ov_read.hEvent, timeout); +	switch (ret) { +	case WAIT_OBJECT_0: +		if (!GetOverlappedResult(file->handle, &file->ov_read, &got, FALSE)) +			return LIBALTOS_ERROR; +		file->pend_read = FALSE; +		file->in_read = 0; +		file->in_used = got; +		break; +	case WAIT_TIMEOUT: +		return LIBALTOS_TIMEOUT; +		break; +	default:  		return LIBALTOS_ERROR; -		got = 0;  	} -	if (got) +	return LIBALTOS_SUCCESS; +} + +static int +altos_fill(struct altos_file *file, int timeout) +{ +	int	ret; + +	if (file->in_read < file->in_used)  		return LIBALTOS_SUCCESS; -	return LIBALTOS_TIMEOUT; + +	file->in_read = file->in_used = 0; + +	ret = altos_queue_read(file); +	if (ret) +		return ret; +	ret = altos_wait_read(file, timeout); +	if (ret) +		return ret; + +	return LIBALTOS_SUCCESS;  }  PUBLIC int @@ -768,13 +907,21 @@ altos_flush(struct altos_file *file)  	DWORD	put;  	char	*data = file->out_data;  	char	used = file->out_used; -	DWORD	result; +	DWORD	ret;  	while (used) { -		if (!WriteFile(file->handle, data, used, &put, NULL)) { -			result = GetLastError(); -			printf ("write failed %d\n", result); -			return LIBALTOS_ERROR; +		if (!WriteFile(file->handle, data, used, &put, &file->ov_write)) { +			if (GetLastError() != ERROR_IO_PENDING) +				return LIBALTOS_ERROR; +			ret = WaitForSingleObject(file->ov_write.hEvent, INFINITE); +			switch (ret) { +			case WAIT_OBJECT_0: +				if (!GetOverlappedResult(file->handle, &file->ov_write, &put, FALSE)) +					return LIBALTOS_ERROR; +				break; +			default: +				return LIBALTOS_ERROR; +			}  		}  		data += put;  		used -= put; @@ -786,8 +933,10 @@ altos_flush(struct altos_file *file)  PUBLIC struct altos_file *  altos_open(struct altos_device *device)  { -	struct altos_file	*file = calloc (sizeof (struct altos_file), 1); +	struct altos_file	*file = calloc (1, sizeof (struct altos_file));  	char	full_name[64]; +	DCB dcbSerialParams = {0}; +	COMMTIMEOUTS timeouts;  	if (!file)  		return NULL; @@ -796,19 +945,35 @@ altos_open(struct altos_device *device)  	strcat(full_name, device->path);  	file->handle = CreateFile(full_name, GENERIC_READ|GENERIC_WRITE,  				  0, NULL, OPEN_EXISTING, -				  FILE_ATTRIBUTE_NORMAL, NULL); +				  FILE_FLAG_OVERLAPPED, NULL);  	if (file->handle == INVALID_HANDLE_VALUE) {  		free(file);  		return NULL;  	} +	file->ov_read.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); +	file->ov_write.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);  	timeouts.ReadIntervalTimeout = MAXDWORD;  	timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; -	timeouts.ReadTotalTimeoutConstant = 100; +	timeouts.ReadTotalTimeoutConstant = 1 << 30;	/* almost forever */  	timeouts.WriteTotalTimeoutMultiplier = 0; -	timeouts.WriteTotalTimeoutConstant = 10000; -	if (!SetCommTimeouts(file->handle, &timeouts)) { -		printf("SetCommTimeouts failed %d\n", GetLastError()); +	timeouts.WriteTotalTimeoutConstant = 0; +	SetCommTimeouts(file->handle, &timeouts); + +	dcbSerialParams.DCBlength = sizeof(dcbSerialParams); +	if (!GetCommState(file->handle, &dcbSerialParams)) { +		CloseHandle(file->handle); +		free(file); +		return NULL; +	} +	dcbSerialParams.BaudRate = CBR_9600; +	dcbSerialParams.ByteSize = 8; +	dcbSerialParams.StopBits = ONESTOPBIT; +	dcbSerialParams.Parity = NOPARITY; +	if (!SetCommState(file->handle, &dcbSerialParams)) { +		CloseHandle(file->handle); +		free(file); +		return NULL;  	}  	return file; @@ -851,9 +1016,6 @@ altos_getchar(struct altos_file *file, int timeout)  {  	int	ret;  	while (file->in_read == file->in_used) { -		ret = altos_flush(file); -		if (ret) -			return ret;  		if (file->handle == INVALID_HANDLE_VALUE)  			return LIBALTOS_ERROR;  		ret = altos_fill(file, timeout); diff --git a/ao-tools/libaltos/libaltos.dylib b/ao-tools/libaltos/libaltos.dylibBinary files differ new file mode 100755 index 00000000..89aa12e7 --- /dev/null +++ b/ao-tools/libaltos/libaltos.dylib diff --git a/ao-tools/libaltos/libaltos.h b/ao-tools/libaltos/libaltos.h index fe2c483c..6e94899e 100644 --- a/ao-tools/libaltos/libaltos.h +++ b/ao-tools/libaltos/libaltos.h @@ -18,6 +18,8 @@  #ifndef _LIBALTOS_H_  #define _LIBALTOS_H_ +#include <stdlib.h> +  #if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)  # ifndef BUILD_STATIC  #  ifdef BUILD_DLL diff --git a/configure.ac b/configure.ac index fafc6b34..d376af3f 100644 --- a/configure.ac +++ b/configure.ac @@ -17,19 +17,49 @@ dnl  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.  dnl  dnl Process this file with autoconf to create configure. -AC_INIT(COPYING) - -AM_INIT_AUTOMAKE(altos, 0.1) +AC_PREREQ(2.57) +AC_INIT([altos], 0.7.1) +AC_CONFIG_SRCDIR([src/ao.h]) +AM_INIT_AUTOMAKE([foreign dist-bzip2])  AM_MAINTAINER_MODE +VERSION_DASH=`echo $VERSION | sed 's/\./-/g'` +AC_SUBST(VERSION_DASH) +  dnl ==========================================================================  AM_CONFIG_HEADER(config.h) +AC_ARG_WITH(freetts, AS_HELP_STRING([--with-freetts=PATH], +	[Set freetts class path (default /usr/share/java)]), +	[FREETTS=$withval], [FREETTS=/usr/share/java]) + +AC_SUBST(FREETTS) + +AC_ARG_WITH(jvm, AS_HELP_STRING([--with-jvm-include=PATH], +	[Set jvm include path for jni builds (default searches in /usr/lib/jvm)]), +	[JVM_INCLUDE=$withval], [JVM_INCLUDE=auto]) + +if test "x$JVM_INCLUDE" = "xauto"; then +	AC_MSG_CHECKING([JVM include files]) +	for jvm in default-java java-6-openjdk java-6-sun; do +		if test "x$JVM_INCLUDE" = "xauto"; then +			INCLUDE="/usr/lib/jvm/$jvm/include" +			if test -f "$INCLUDE"/jni.h; then +				JVM_INCLUDE="$INCLUDE" +			fi +		fi +	done +	if test "x$JVM_INCLUDE" = "xauto"; then +		AC_MSG_ERROR([no JVM include files found]) +	fi +	AC_MSG_RESULT([$JVM_INCLUDE]) +fi +  AC_PROG_CC  AC_PROG_INSTALL  AC_PROG_LN_S -AC_PROG_RANLIB +AC_PROG_LIBTOOL  PKG_PROG_PKG_CONFIG  CFLAGS="-g" @@ -92,5 +122,8 @@ ao-tools/ao-list/Makefile  ao-tools/ao-load/Makefile  ao-tools/ao-postflight/Makefile  ao-tools/ao-view/Makefile +ao-tools/libaltos/Makefile +ao-tools/altosui/Makefile  ao-utils/Makefile +src/Version  ]) diff --git a/debian/altos.desktop b/debian/altos.desktop index 4281ad3a..4345cf09 100644 --- a/debian/altos.desktop +++ b/debian/altos.desktop @@ -1,10 +1,10 @@  [Desktop Entry]  Type=Application -Name=AltOS View +Name=AltOS UI  GenericName=TeleMetrum Telemetry Viewer  Comment=View and log downlink data from TeleMetrum  Icon=/usr/share/pixmaps/altusmetrum.xpm -Exec=/usr/bin/ao-view %f +Exec=/usr/bin/altosui %f  Terminal=false  MimeType=text/plain;  Categories=Education;Science; diff --git a/debian/changelog b/debian/changelog index 6a47c8a7..2005b64f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,182 @@ +altos (0.7+53+g59798c6) unstable; urgency=low + +  [ Keith Packard ] +  * altosui: Abort flashing if debug port isn't working +  * altosui: allow flashing to be canceled from the rom config dialog +  * altosui: Hide internal rom config UI helper function +  * altosui: Remove some debug printfs from AltosRomconfig class +  * altosui: Post error dialog on invalid ROM config values. +  * altosui: build Mac OS .zip file to include paths +  * altosui: Report telemetry CRC errors in UI +  * altosui: Deal with altos bug setting radio channel while monitoring +  * altosui: Allow 'connect to device' when already connected +  * Revert "altosui: Deal with altos bug setting radio channel while +    monitoring" +  * altosui: Must flush serial line after configuring for telemetry +  * altosui: Catch I/O errors on telemetry device, report to user + + -- Bdale Garbee <bdale@gag.com>  Sat, 04 Sep 2010 00:46:12 -0400 + +altos (0.7+40+g59a40f6) unstable; urgency=low + +  [ Bdale Garbee ] +  * add distclean targets to libaltos and altosui to all Debian package +    to build, and clean up other distclean content as needed + +  [ Keith Packard ] +  * altosui: missed AltosReader.class in the Makefile +  * altos: Bounds check Skytraq GPS tracking data array +  * altosui: Remove Manifest.txt from git repo as it's built now + + -- Bdale Garbee <bdale@gag.com>  Thu, 02 Sep 2010 00:44:15 -0400 + +altos (0.7+28+gd006c5e) unstable; urgency=low + +  * add runtime dependencies for altos binary package + + -- Bdale Garbee <bdale@gag.com>  Tue, 31 Aug 2010 00:20:00 -0400 + +altos (0.7+26+gc35632e) unstable; urgency=low + +  * don't build all the "fat" jar deliverables by default + + -- Bdale Garbee <bdale@gag.com>  Mon, 30 Aug 2010 19:37:40 -0600 + +altos (0.7+23+g25764fc) unstable; urgency=low + +  [ Bdale Garbee ] +  * fix up for an 0.7 release +  * update changelogs for Debian build + +  [ Keith Packard ] +  * libaltos: AltusMetrum devices use more than one USB ID. +  * altosui: provide separate flush_input/flush_output for serial. deal +    with monitor automatically +  * altosui: discard invalid lines while reading Eeprom flight data +  * libaltos: Mac OS X cannot use 'poll(2)' on serial lines. +  * libaltos: Missing OS_LDFLAGS on cjnitest build +  * libaltos: cjnitest needs altos_flush now +  * altos: flush pending output when terminating packet mode +  * altos: Abort radio harder when terminating packet mode. +  * altos: shut down packet mode cleanly +  * libaltos: Fix windows build. +  * libaltos: Improve Makefile +  * Update telemetrum.inf to include all current USB ids. +  * libaltos: Add pre-built Mac OS X libaltos.dylib +  * libaltos: Add pre-built Windows .dll +  * altos: Windows sends USB Out packets of 0 length. Ack them. +  * libaltos: Use overlapped I/O on windows +  * altosui: Build linux, mac and windows archives on Linux +  * altosui: build debian-style altosui too +  * altosui: Devices with USB id 0x000a always get listed + +  [ Bdale Garbee ] +  * continue even if rm's don't have anything to do +  * make invocation of 'install' pathless to work on more Unix variants +  * add a .gitattributes file, configuring the Mac and Windows binary +    library + + -- Bdale Garbee <bdale@gag.com>  Mon, 30 Aug 2010 19:07:13 -0600 + +altos (0.7) unstable; urgency=low + +  * update changelogs for Debian build +  * fix up for an 0.7 release + + -- Bdale Garbee <bdale@gag.com>  Fri, 27 Aug 2010 22:25:38 -0600 + +altos (0.6+375+g0bd4cc0) unstable; urgency=low + +  * fix path to installed shared library + + -- Bdale Garbee <bdale@gag.com>  Fri, 27 Aug 2010 13:13:14 -0600 + +altos (0.6+373+gcf65c6b) unstable; urgency=low + +  [ Keith Packard ] +  * altosui: rename AltosEeprom -> AltosEepromDownload, split out Altos +    constants +  * altosui: Capture config and version info in .eeprom files +  * altosui: Merge gps date and time classes into gps class +  * altosui: Clear displayed data rows as needed. +  * altosui: Split status and info panels into separate files +  * altosui: Explicitly initialize Altos class +  * altosui: Split flight record out of telemetry class +  * altosui: Compute flight state from eeprom data +  * altosui: Add comments to Eeprom reader +  * altos: add callsign to packet mode, increase payload to 64 bytes +  * altosui: Start adding code to write csv files from eeprom/telem +    files +  * ao-dumplog: add --channel option (for use with -R option) +  * libaltos: integrate Windows support. +  * altosui: Select devices by USB vendor/product ID. +  * altos: Define USB product ID in per-product Makefile.defs file +  * altosui: Make teledongle callsign configurable +  * altosui: Add TeleMetrum configuration +  * altosui: Set callsign when fetching eeprom data over the air + +  [ Bdale Garbee ] +  * add freetts as a build dep +  * working on java packaging details + +  [ Keith Packard ] +  * altosui: Add .ihx file reading code and stub out flashing UI +  * altosui: Add debug dongle API, split flash UI out +  * ao-dumplog: Fix --remote and --channel options to actually work +  * altosui: pad TM config dialog values to avoid clipping descenders +  * libaltos: use pipe to wake up getchar on close. use mutexes +  * altosui: Add lots more cc1111 debug interface functions +  * altosui: remove debug printf from AltosHexfile +  * altosui: flush serial output before waiting for reply +  * altosui: Remove debug printf from AltosRomconfig +  * altosui: Finish device programming code +  * altos: Place rom config variables in fixed location +  * altosui: make default Manifest look for built-in freetts +  * altosui: Separate out log file choosing dialog to share with CSV +    generator +  * altosui: refactor logfile chooser dialog to share more code +  * altosui: Add ability to create CSV file from telem or eeprom files +  * altosui: disable radio monitoring while using serial line for +    debugging +  * altosui: Delay mapping Flash UI until flashing actually starts +  * altosui: fetch existing romconfig for flashing +  * altosui: always display romconfig ui while flashing +  * altosui: write USB serial number string while flashing +  * altosui: flush replies from serial link when entering debug mode +  * altos: always rebuild ao_product.c to track git version +  * altos: print GPS state flags in GPS 'g' command +  * altos: mark gps date written only after it gets into eeprom +  * altosui: Move number parsing code to Altos general class +  * altosui: Add AltosGreatCircle constructors +  * altosui: add rssi and distance/dir from pad to CSV files +  * altosui: AltosEepromReader was mis-setting boost tick +  * altosui: Add support for old (version < 3) telemetry files +  * altosui: Serial line is in UTF-8 encoding. Deal with it. +  * altosui: When parsing saved telem files, errors shouldn't abort file +  * altosui: Remove debug printf from AltosState.java +  * altosui: command line args are converted to csv format +  * altos: prepare for sdcc 2.9.1 + +  [ Bdale Garbee ] +  * add a dummy install target +  * lose the prebuild hook for now while I'm fumbling +  * add install target for libaltos +  * add an install target for altosui + +  [ Keith Packard ] +  * altosui: add elevation and range information + +  [ Bdale Garbee ] +  * fix up the wrapper's path to the jar file +  * update Debian standards version +  * fix permissions on installed jar file, switch from ao-view to +    altosui in +  * install altosui man page +  * fix man page delivery path +  * Revert "lose the prebuild hook for now while I'm fumbling" + + -- Bdale Garbee <bdale@gag.com>  Fri, 27 Aug 2010 12:40:04 -0600 +  altos (0.6+303+gb6da90b) unstable; urgency=low    * add freetts as a build dep diff --git a/debian/control b/debian/control index cc8fda94..690eb78f 100644 --- a/debian/control +++ b/debian/control @@ -4,12 +4,12 @@ Priority: extra  Maintainer: Bdale Garbee <bdale@gag.com>  Uploaders: Keith Packard <keithp@keithp.com>  Build-Depends: debhelper (>= 7), autoconf, automake, flite1-dev, gawk, libasound2-dev, libgconf2-dev, libglade2-dev, libgtk2.0-dev, libreadline-dev, libusb-1.0-0-dev, nickle, sdcc, libplplot-dev, xsltproc, fop, docbook-xml, docbook-xsl, libsndfile1-dev, swig, openjdk-6-jdk, freetts -Standards-Version: 3.9.0 +Standards-Version: 3.9.1  Homepage: http://altusmetrum.org/AltOS  Package: altos  Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, nickle, plplot9-driver-cairo +Depends: ${shlibs:Depends}, ${misc:Depends}, default-jre | java2-runtime, freetts, nickle, plplot9-driver-cairo  Suggests: slim | gdm  Replaces: altusmetrum-themes, slim-altusmetrum  Conflicts: altusmetrum-themes, slim-altusmetrum diff --git a/debian/dirs b/debian/dirs index db75fea7..7b4dffb8 100644 --- a/debian/dirs +++ b/debian/dirs @@ -1,7 +1,9 @@  etc/apt/sources.list.d  usr/bin +usr/lib/altos  usr/share/altos  usr/share/applications  usr/share/gdm/themes/altusmetrum +usr/share/java  usr/share/pixmaps  usr/share/slim/themes/altusmetrum diff --git a/doc/Makefile b/doc/Makefile index f8048dce..238cefb0 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -26,6 +26,9 @@ telemetrum-doc.pdf:	telemetrum-doc.fo  clean:  	rm -f telemetrum-doc.html telemetrum-doc.pdf telemetrum-doc.fo +distclean: +	rm -f telemetrum-doc.html telemetrum-doc.pdf telemetrum-doc.fo +  indent:		telemetrum-doc.xsl  	xmlindent -i 2 < telemetrum-doc.xsl > telemetrum-doc.new diff --git a/icon/altus-metrum-16x16.jpg b/icon/altus-metrum-16x16.jpgBinary files differ new file mode 100644 index 00000000..8d8bbc6a --- /dev/null +++ b/icon/altus-metrum-16x16.jpg diff --git a/icon/altus-metrum.ico b/icon/altus-metrum.icoBinary files differ new file mode 100644 index 00000000..e32b4f1e --- /dev/null +++ b/icon/altus-metrum.ico diff --git a/src/Makefile b/src/Makefile index 24f562e1..95d24425 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,6 +4,8 @@  #  CC=sdcc +include Version +  SUBDIRS=telemetrum-v1.0 teledongle-v0.2 telemetrum-v0.1-sky telemetrum-v0.1-sirf teledongle-v0.1 tidongle test  all: all-recursive diff --git a/src/Makefile.proto b/src/Makefile.proto index eedb878a..b23eb257 100644 --- a/src/Makefile.proto +++ b/src/Makefile.proto @@ -10,7 +10,7 @@ vpath ao-make-product.5c ..  CC=sdcc  ifndef VERSION -VERSION=$(shell git describe) +include ../Version  endif  CFLAGS=--model-small --debug --opt-code-speed @@ -35,6 +35,7 @@ ALTOS_SRC = \  	ao_panic.c \  	ao_task.c \  	ao_timer.c \ +	ao_romconfig.c \  	_bp.c  # @@ -213,7 +214,7 @@ all: ../$(PROG)  ../altitude.h: make-altitude  	nickle $< > $@ -ao_product.h: ao-make-product.5c +ao_product.h: ao-make-product.5c ../Version  	$(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@  ao_product.rel: ao_product.c ao_product.h diff --git a/src/Version.in b/src/Version.in new file mode 100644 index 00000000..aff9490b --- /dev/null +++ b/src/Version.in @@ -0,0 +1 @@ +VERSION=@VERSION@ @@ -79,7 +79,7 @@ ao_alarm(uint16_t delay);  /* Yield the processor to another task */  void -ao_yield(void) _naked; +ao_yield(void) __naked;  /* Add a task to the run queue */  void @@ -139,7 +139,7 @@ ao_timer_set_adc_interval(uint8_t interval) __critical;  /* Timer interrupt */  void -ao_timer_isr(void) interrupt 9; +ao_timer_isr(void) __interrupt 9;  /* Initialize the timer */  void @@ -198,7 +198,7 @@ ao_adc_get(__xdata struct ao_adc *packet);  /* The A/D interrupt handler */  void -ao_adc_isr(void) interrupt 1; +ao_adc_isr(void) __interrupt 1;  /* Initialize the A/D converter */  void @@ -290,6 +290,18 @@ void  ao_led_init(uint8_t enable);  /* + * ao_romconfig.c + */ + +#define AO_ROMCONFIG_VERSION	2 + +extern __code __at (0x00a0) uint16_t ao_romconfig_version; +extern __code __at (0x00a2) uint16_t ao_romconfig_check; +extern __code __at (0x00a4) uint16_t ao_serial_number; +extern __code __at (0x00a6) uint32_t ao_radio_cal; +extern __code __at (0x00aa) uint8_t ao_usb_descriptors []; + +/*   * ao_usb.c   */ @@ -313,7 +325,7 @@ ao_usb_flush(void);  /* USB interrupt handler */  void -ao_usb_isr(void) interrupt 6; +ao_usb_isr(void) __interrupt 6;  /* Enable the USB controller */  void @@ -413,7 +425,7 @@ ao_dma_abort(uint8_t id);  /* DMA interrupt routine */  void -ao_dma_isr(void) interrupt 8; +ao_dma_isr(void) __interrupt 8;  /*   * ao_mutex.c @@ -552,6 +564,7 @@ struct ao_log_record {  			uint8_t		year;  			uint8_t		month;  			uint8_t		day; +			uint8_t		extra;  		} gps_date;  		struct {  			uint16_t	d0; @@ -561,7 +574,7 @@ struct ao_log_record {  };  /* Write a record to the eeprom log */ -void +uint8_t  ao_log_data(__xdata struct ao_log_record *log) __reentrant;  /* Flush the log */ @@ -709,10 +722,10 @@ ao_dbg_init(void);  #if HAS_SERIAL_1  void -ao_serial_rx1_isr(void) interrupt 3; +ao_serial_rx1_isr(void) __interrupt 3;  void -ao_serial_tx1_isr(void) interrupt 14; +ao_serial_tx1_isr(void) __interrupt 14;  char  ao_serial_getchar(void) __critical; @@ -768,9 +781,11 @@ struct ao_gps_sat_data {  	uint8_t		c_n_1;  }; +#define AO_MAX_GPS_TRACKING	12 +  struct ao_gps_tracking_data {  	uint8_t			channels; -	struct ao_gps_sat_data	sats[12]; +	struct ao_gps_sat_data	sats[AO_MAX_GPS_TRACKING];  };  extern __xdata uint8_t ao_gps_mutex; @@ -848,7 +863,7 @@ extern __xdata uint8_t ao_radio_done;  extern __xdata uint8_t ao_radio_mutex;  void -ao_radio_general_isr(void) interrupt 16; +ao_radio_general_isr(void) __interrupt 16;  void  ao_radio_get(void); @@ -997,8 +1012,7 @@ ao_rssi_init(uint8_t rssi_led);   * each instance of a product   */ -extern const uint8_t ao_usb_descriptors []; -extern const uint16_t ao_serial_number; +extern __code __at(0x00aa) uint8_t ao_usb_descriptors [];  extern const char ao_version[];  extern const char ao_manufacturer[];  extern const char ao_product[]; diff --git a/src/ao_adc.c b/src/ao_adc.c index 50f96848..49d2519e 100644 --- a/src/ao_adc.c +++ b/src/ao_adc.c @@ -41,7 +41,7 @@ ao_adc_get(__xdata struct ao_adc *packet)  }  void -ao_adc_isr(void) interrupt 1 +ao_adc_isr(void) __interrupt 1  {  	uint8_t sequence;  	uint8_t	__xdata *a; diff --git a/src/ao_cmd.c b/src/ao_cmd.c index 4a68fba4..a54a2316 100644 --- a/src/ao_cmd.c +++ b/src/ao_cmd.c @@ -263,13 +263,12 @@ ao_cmd_register(__code struct ao_cmds *cmds)  }  void -ao_cmd(void *parameters) +ao_cmd(void)  {  	__xdata char	c;  	__xdata uint8_t cmd, cmds;  	__code struct ao_cmds * __xdata cs;  	void (*__xdata func)(void); -	(void) parameters;  	lex_echo = 1;  	for (;;) { diff --git a/src/ao_config.c b/src/ao_config.c index cbd639a5..88b52dc0 100644 --- a/src/ao_config.c +++ b/src/ao_config.c @@ -27,16 +27,6 @@ __xdata uint8_t ao_config_mutex;  #define AO_CONFIG_DEFAULT_CALLSIGN	"N0CALL"  #define AO_CONFIG_DEFAULT_ACCEL_ZERO_G	16000  #define AO_CONFIG_DEFAULT_APOGEE_DELAY	0 -/* - * For 434.550MHz, the frequency value is: - * - * 434.550e6 / (24e6 / 2**16) = 1186611.2 - * - * This value is stored in a const variable so that - * ao-load can change it during programming for - * devices that have no eeprom for config data. - */ -const uint32_t ao_radio_cal = 1186611;  #if HAS_EEPROM  static void diff --git a/src/ao_dma.c b/src/ao_dma.c index 110138b5..946666ab 100644 --- a/src/ao_dma.c +++ b/src/ao_dma.c @@ -112,7 +112,7 @@ ao_dma_abort(uint8_t id)  }  void -ao_dma_isr(void) interrupt 8 +ao_dma_isr(void) __interrupt 8  {  	uint8_t id, mask; diff --git a/src/ao_gps_report.c b/src/ao_gps_report.c index cceb79ff..7abc93f5 100644 --- a/src/ao_gps_report.c +++ b/src/ao_gps_report.c @@ -51,12 +51,12 @@ ao_gps_report(void)  		gps_log.u.gps_altitude.unused = 0xffff;  		ao_log_data(&gps_log);  		if (!date_reported && (gps_data.flags & AO_GPS_DATE_VALID)) { -			date_reported = 1;  			gps_log.type = AO_LOG_GPS_DATE;  			gps_log.u.gps_date.year = gps_data.year;  			gps_log.u.gps_date.month = gps_data.month;  			gps_log.u.gps_date.day = gps_data.day; -			ao_log_data(&gps_log); +			gps_log.u.gps_date.extra = 0; +			date_reported = ao_log_data(&gps_log);  		}  	}  } diff --git a/src/ao_gps_skytraq.c b/src/ao_gps_skytraq.c index ae8c7ef7..2d3d464c 100644 --- a/src/ao_gps_skytraq.c +++ b/src/ao_gps_skytraq.c @@ -333,14 +333,19 @@ ao_gps(void) __reentrant  			ao_gps_skip_field();	/* sats in view */  			while (ao_gps_char != '*' && ao_gps_char != '\n' && ao_gps_char != '\r') {  				i = ao_gps_tracking_next.channels; -				ao_gps_tracking_next.sats[i].svid = ao_gps_decimal(2);	/* SVID */ +				c = ao_gps_decimal(2);	/* SVID */ +				if (i < AO_MAX_GPS_TRACKING) +					ao_gps_tracking_next.sats[i].svid = c;  				ao_gps_lexchar();  				ao_gps_skip_field();	/* elevation */  				ao_gps_lexchar();  				ao_gps_skip_field();	/* azimuth */ -				if (!(ao_gps_tracking_next.sats[i].c_n_1 = ao_gps_decimal(2)))	/* C/N0 */ -					ao_gps_tracking_next.sats[i].svid = 0; -				ao_gps_tracking_next.channels = i + 1; +				c = ao_gps_decimal(2);	/* C/N0 */ +				if (i < AO_MAX_GPS_TRACKING) { +					if (!(ao_gps_tracking_next.sats[i].c_n_1 = c)) +						ao_gps_tracking_next.sats[i].svid = 0; +					ao_gps_tracking_next.channels = i + 1; +				}  			}  			if (ao_gps_char == '*') {  				uint8_t cksum = ao_gps_cksum ^ '*'; @@ -422,6 +427,7 @@ gps_dump(void) __reentrant  	printf ("Time: %02d:%02d:%02d\n", ao_gps_data.hour, ao_gps_data.minute, ao_gps_data.second);  	printf ("Lat/Lon: %ld %ld\n", ao_gps_data.latitude, ao_gps_data.longitude);  	printf ("Alt: %d\n", ao_gps_data.altitude); +	printf ("Flags: 0x%x\n", ao_gps_data.flags);  	ao_mutex_put(&ao_gps_mutex);  } diff --git a/src/ao_gps_test.c b/src/ao_gps_test.c index cdcc6f4c..edb51304 100644 --- a/src/ao_gps_test.c +++ b/src/ao_gps_test.c @@ -62,9 +62,11 @@ struct ao_gps_sat_data {  	uint8_t		c_n_1;  }; +#define AO_MAX_GPS_TRACKING	12 +  struct ao_gps_tracking_data {  	uint8_t			channels; -	struct ao_gps_sat_data	sats[12]; +	struct ao_gps_sat_data	sats[AO_MAX_GPS_TRACKING];  };  void diff --git a/src/ao_gps_test_skytraq.c b/src/ao_gps_test_skytraq.c index 7fa10eaa..4010e09c 100644 --- a/src/ao_gps_test_skytraq.c +++ b/src/ao_gps_test_skytraq.c @@ -63,9 +63,11 @@ struct ao_gps_sat_data {  	uint8_t		c_n_1;  }; +#define AO_MAX_GPS_TRACKING	12 +  struct ao_gps_tracking_data {  	uint8_t			channels; -	struct ao_gps_sat_data	sats[12]; +	struct ao_gps_sat_data	sats[AO_MAX_GPS_TRACKING];  };  void diff --git a/src/ao_log.c b/src/ao_log.c index d550d408..18bdb8c8 100644 --- a/src/ao_log.c +++ b/src/ao_log.c @@ -33,14 +33,16 @@ ao_log_csum(__xdata uint8_t *b) __reentrant  	return -sum;  } -void +uint8_t  ao_log_data(__xdata struct ao_log_record *log) __reentrant  { +	uint8_t wrote = 0;  	/* set checksum */  	log->csum = 0;  	log->csum = ao_log_csum((__xdata uint8_t *) log);  	ao_mutex_get(&ao_log_mutex); {  		if (ao_log_running) { +			wrote = 1;  			ao_ee_write(ao_log_current_pos,  				    (uint8_t *) log,  				    sizeof (struct ao_log_record)); @@ -51,6 +53,7 @@ ao_log_data(__xdata struct ao_log_record *log) __reentrant  				ao_log_running = 0;  		}  	} ao_mutex_put(&ao_log_mutex); +	return wrote;  }  void diff --git a/src/ao_packet_master.c b/src/ao_packet_master.c index 72bb908a..641b49f4 100644 --- a/src/ao_packet_master.c +++ b/src/ao_packet_master.c @@ -29,6 +29,8 @@ ao_packet_getchar(void) __critical  			ao_wake_task(&ao_packet_task);  		ao_usb_flush();  		ao_sleep(&ao_stdin_ready); +		if (!ao_packet_enable) +			break;  	}  	return c;  } @@ -121,12 +123,15 @@ ao_packet_forward(void) __reentrant  		if (c == '\r') c = '\n';  		ao_packet_putchar(c);  	} + +	/* Wait for a second if there is any pending data */ +	for (c = 0; (ao_packet_tx_used || ao_tx_packet.len) && c < 10; c++) +		ao_delay(AO_MS_TO_TICKS(100));  	ao_packet_enable = 0; -	ao_radio_abort();  	while (ao_packet_echo_task.wchan || ao_packet_task.wchan) { -		ao_wake_task(&ao_packet_echo_task); -		ao_wake_task(&ao_packet_task); -		ao_yield(); +		if (ao_packet_echo_task.wchan) +			ao_wake_task(&ao_packet_echo_task); +		ao_delay(AO_MS_TO_TICKS(10));  	}  } diff --git a/src/ao_product.c b/src/ao_product.c index 2bd0b59c..82d6298f 100644 --- a/src/ao_product.c +++ b/src/ao_product.c @@ -21,7 +21,6 @@  /* Defines which mark this particular AltOS product */ -const uint16_t ao_serial_number = AO_iSerial_NUMBER;  const char ao_version[] = AO_iVersion_STRING;  const char ao_manufacturer[] = AO_iManufacturer_STRING;  const char ao_product[] = AO_iProduct_STRING; @@ -29,7 +28,7 @@ const char ao_product[] = AO_iProduct_STRING;  #define LE_WORD(x)    ((x)&0xFF),((uint8_t) (((uint16_t) (x))>>8))  /* USB descriptors in one giant block of bytes */ -const uint8_t ao_usb_descriptors [] = +__code __at(0x00aa) uint8_t ao_usb_descriptors [] =  {  	/* Device descriptor */  	0x12, diff --git a/src/ao_radio.c b/src/ao_radio.c index 0849349e..f4a9d3b2 100644 --- a/src/ao_radio.c +++ b/src/ao_radio.c @@ -275,7 +275,7 @@ __xdata uint8_t ao_radio_done;  __xdata uint8_t ao_radio_mutex;  void -ao_radio_general_isr(void) interrupt 16 +ao_radio_general_isr(void) __interrupt 16  {  	S1CON &= ~0x03;  	if (RFIF & RFIF_IM_TIMEOUT) { diff --git a/src/ao_romconfig.c b/src/ao_romconfig.c new file mode 100644 index 00000000..f3fe61b1 --- /dev/null +++ b/src/ao_romconfig.c @@ -0,0 +1,32 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "ao.h" + +__code __at (0x00a0) uint16_t ao_romconfig_version = AO_ROMCONFIG_VERSION; +__code __at (0x00a2) uint16_t ao_romconfig_check = ~AO_ROMCONFIG_VERSION; +__code __at (0x00a4) uint16_t ao_serial_number = 0; +/* + * For 434.550MHz, the frequency value is: + * + * 434.550e6 / (24e6 / 2**16) = 1186611.2 + * + * This value is stored in a const variable so that + * ao-load can change it during programming for + * devices that have no eeprom for config data. + */ +__code __at (0x00a6) uint32_t ao_radio_cal = 1186611; diff --git a/src/ao_serial.c b/src/ao_serial.c index 3f103766..a48734c2 100644 --- a/src/ao_serial.c +++ b/src/ao_serial.c @@ -21,7 +21,7 @@ volatile __xdata struct ao_fifo	ao_usart1_rx_fifo;  volatile __xdata struct ao_fifo	ao_usart1_tx_fifo;  void -ao_serial_rx1_isr(void) interrupt 3 +ao_serial_rx1_isr(void) __interrupt 3  {  	if (!ao_fifo_full(ao_usart1_rx_fifo))  		ao_fifo_insert(ao_usart1_rx_fifo, U1DBUF); @@ -42,7 +42,7 @@ ao_serial_tx1_start(void)  }  void -ao_serial_tx1_isr(void) interrupt 14 +ao_serial_tx1_isr(void) __interrupt 14  {  	UTX1IF = 0;  	ao_serial_tx1_started = 0; diff --git a/src/ao_timer.c b/src/ao_timer.c index d1731475..c977fbc8 100644 --- a/src/ao_timer.c +++ b/src/ao_timer.c @@ -41,7 +41,7 @@ volatile __data uint8_t	ao_adc_interval = 1;  volatile __data uint8_t	ao_adc_count;  #endif -void ao_timer_isr(void) interrupt 9 +void ao_timer_isr(void) __interrupt 9  {  	++ao_tick_count;  #if HAS_ADC diff --git a/src/ao_usb.c b/src/ao_usb.c index f6e0fcf9..b4e3f1fe 100644 --- a/src/ao_usb.c +++ b/src/ao_usb.c @@ -43,7 +43,7 @@ ao_usb_set_interrupts(void)   * so when we hook that up, fix this   */  void -ao_usb_isr(void) interrupt 6 +ao_usb_isr(void) __interrupt 6  {  	USBIF = 0;  	ao_usb_iif |= USBIIF; @@ -383,8 +383,11 @@ ao_usb_pollchar(void) __critical  		if ((USBCSOL & USBCSOL_OUTPKT_RDY) == 0)  			return AO_READ_AGAIN;  		ao_usb_out_bytes = (USBCNTH << 8) | USBCNTL; -		if (ao_usb_out_bytes == 0) +		if (ao_usb_out_bytes == 0) { +			USBINDEX = AO_USB_OUT_EP; +			USBCSOL &= ~USBCSOL_OUTPKT_RDY;  			return AO_READ_AGAIN; +		}  	}  	--ao_usb_out_bytes;  	c = USBFIFO[AO_USB_OUT_EP << 1]; diff --git a/src/cc1111.h b/src/cc1111.h index e8302df2..20ed052a 100644 --- a/src/cc1111.h +++ b/src/cc1111.h @@ -40,16 +40,16 @@  #include <cc1110.h>  #include <stdint.h> -sfr at 0xA8 IEN0;		/* Interrupt Enable 0 Register */ +sfr __at 0xA8 IEN0;		/* Interrupt Enable 0 Register */ -sbit at 0xA8 RFTXRXIE;		/* RF TX/RX done interrupt enable */ -sbit at 0xA9 ADCIE;		/* ADC interrupt enable */ -sbit at 0xAA URX0IE;		/* USART0 RX interrupt enable */ -sbit at 0xAB URX1IE;		/* USART1 RX interrupt enable (shared with I2S RX) */ -sbit at 0xAB I2SRXIE;		/* I2S RX interrupt enable (shared with USART1 RX) */ -sbit at 0xAC ENCIE;		/* AES encryption/decryption interrupt enable */ -sbit at 0xAD STIE;		/* Sleep Timer interrupt enable */ -sbit at 0xAF EA;		/* Enable All */ +sbit __at 0xA8 RFTXRXIE;	/* RF TX/RX done interrupt enable */ +sbit __at 0xA9 ADCIE;		/* ADC interrupt enable */ +sbit __at 0xAA URX0IE;		/* USART0 RX interrupt enable */ +sbit __at 0xAB URX1IE;		/* USART1 RX interrupt enable (shared with I2S RX) */ +sbit __at 0xAB I2SRXIE;		/* I2S RX interrupt enable (shared with USART1 RX) */ +sbit __at 0xAC ENCIE;		/* AES encryption/decryption interrupt enable */ +sbit __at 0xAD STIE;		/* Sleep Timer interrupt enable */ +sbit __at 0xAF EA;		/* Enable All */  #define IEN0_EA			(1 << 7)  #define IEN0_STIE		(1 << 5) @@ -60,7 +60,7 @@ sbit at 0xAF EA;		/* Enable All */  #define IEN0_ADCIE		(1 << 1)  #define IEN0_RFTXRXIE		(1 << 0) -sfr at 0xB8 IEN1;		/* Interrupt Enable 1 Register */ +sfr __at 0xB8 IEN1;		/* Interrupt Enable 1 Register */  #define IEN1_P0IE		(1 << 5)	/* Port 0 interrupt enable */  #define IEN1_T4IE		(1 << 4)	/* Timer 4 interrupt enable */ @@ -70,7 +70,7 @@ sfr at 0xB8 IEN1;		/* Interrupt Enable 1 Register */  #define IEN1_DMAIE		(1 << 0)	/* DMA transfer interrupt enable */  /* IEN2 */ -sfr at 0x9A IEN2;		/* Interrupt Enable 2 Register */ +sfr __at 0x9A IEN2;		/* Interrupt Enable 2 Register */  #define IEN2_WDTIE		(1 << 5)	/* Watchdog timer interrupt enable */  #define IEN2_P1IE		(1 << 4)	/* Port 1 interrupt enable */ @@ -82,7 +82,7 @@ sfr at 0x9A IEN2;		/* Interrupt Enable 2 Register */  #define IEN2_RFIE		(1 << 0)	/* RF general interrupt enable */  /* CLKCON 0xC6 */ -sfr at 0xC6 CLKCON;		/* Clock Control */ +sfr __at 0xC6 CLKCON;		/* Clock Control */  #define CLKCON_OSC32K_RC	(1 << 7)  #define CLKCON_OSC32K_XTAL	(0 << 7) @@ -126,20 +126,20 @@ sfr at 0xC6 CLKCON;		/* Clock Control */  #define SLEEP_MODE_MASK		(3 << 0)  /* PCON 0x87 */ -sfr at 0x87 PCON;		/* Power Mode Control Register */ +sfr __at 0x87 PCON;		/* Power Mode Control Register */  #define PCON_IDLE		(1 << 0)  /*   * TCON   */ -sfr at 0x88 TCON;	/* CPU Interrupt Flag 1 */ +sfr __at 0x88 TCON;		/* CPU Interrupt Flag 1 */ -sbit at 0x8F URX1IF;	/* USART1 RX interrupt flag. Automatically cleared */ -sbit at 0x8F I2SRXIF;	/* I2S RX interrupt flag. Automatically cleared */ -sbit at 0x8D ADCIF;	/* ADC interrupt flag. Automatically cleared */ -sbit at 0x8B URX0IF;	/* USART0 RX interrupt flag. Automatically cleared */ -sbit at 0x89 RFTXRXIF;	/* RF TX/RX complete interrupt flag. Automatically cleared */ +sbit __at 0x8F URX1IF;		/* USART1 RX interrupt flag. Automatically cleared */ +sbit __at 0x8F I2SRXIF;		/* I2S RX interrupt flag. Automatically cleared */ +sbit __at 0x8D ADCIF;		/* ADC interrupt flag. Automatically cleared */ +sbit __at 0x8B URX0IF;		/* USART0 RX interrupt flag. Automatically cleared */ +sbit __at 0x89 RFTXRXIF;	/* RF TX/RX complete interrupt flag. Automatically cleared */  #define TCON_URX1IF	(1 << 7)  #define TCON_I2SRXIF	(1 << 7) @@ -150,10 +150,10 @@ sbit at 0x89 RFTXRXIF;	/* RF TX/RX complete interrupt flag. Automatically cleare  /*   * S0CON   */ -sfr at 0x98 S0CON;	/* CPU Interrupt Flag 2 */ +sfr __at 0x98 S0CON;	/* CPU Interrupt Flag 2 */ -sbit at 0x98 ENCIF_0;	/* AES interrupt 0. */ -sbit at 0x99 ENCIF_1;	/* AES interrupt 1. */ +sbit __at 0x98 ENCIF_0;	/* AES interrupt 0. */ +sbit __at 0x99 ENCIF_1;	/* AES interrupt 1. */  #define S0CON_ENCIF_1	(1 << 1)  #define S0CON_ENCIF_0	(1 << 0) @@ -161,7 +161,7 @@ sbit at 0x99 ENCIF_1;	/* AES interrupt 1. */  /*   * S1CON   */ -sfr at 0x9B S1CON;	/* CPU Interrupt Flag 3 */ +sfr __at 0x9B S1CON;	/* CPU Interrupt Flag 3 */  #define S1CON_RFIF_1	(1 << 1)  #define S1CON_RFIF_0	(1 << 0) @@ -169,15 +169,15 @@ sfr at 0x9B S1CON;	/* CPU Interrupt Flag 3 */  /*   * IRCON   */ -sfr at 0xC0 IRCON;	/* CPU Interrupt Flag 4 */ +sfr __at 0xC0 IRCON;	/* CPU Interrupt Flag 4 */ -sbit at 0xC0 DMAIF;	/* DMA complete interrupt flag */ -sbit at 0xC1 T1IF;	/* Timer 1 interrupt flag. Automatically cleared */ -sbit at 0xC2 T2IF;	/* Timer 2 interrupt flag. Automatically cleared */ -sbit at 0xC3 T3IF;	/* Timer 3 interrupt flag. Automatically cleared */ -sbit at 0xC4 T4IF;	/* Timer 4 interrupt flag. Automatically cleared */ -sbit at 0xC5 P0IF;	/* Port0 interrupt flag */ -sbit at 0xC7 STIF;	/* Sleep Timer interrupt flag */ +sbit __at 0xC0 DMAIF;	/* DMA complete interrupt flag */ +sbit __at 0xC1 T1IF;	/* Timer 1 interrupt flag. Automatically cleared */ +sbit __at 0xC2 T2IF;	/* Timer 2 interrupt flag. Automatically cleared */ +sbit __at 0xC3 T3IF;	/* Timer 3 interrupt flag. Automatically cleared */ +sbit __at 0xC4 T4IF;	/* Timer 4 interrupt flag. Automatically cleared */ +sbit __at 0xC5 P0IF;	/* Port0 interrupt flag */ +sbit __at 0xC7 STIF;	/* Sleep Timer interrupt flag */  #define IRCON_DMAIF	(1 << 0)	/* DMA complete interrupt flag */  #define IRCON_T1IF	(1 << 1)	/* Timer 1 interrupt flag. Automatically cleared */ @@ -190,15 +190,15 @@ sbit at 0xC7 STIF;	/* Sleep Timer interrupt flag */  /*   * IRCON2   */ -sfr at 0xE8 IRCON2;	/* CPU Interrupt Flag 5 */ +sfr __at 0xE8 IRCON2;	/* CPU Interrupt Flag 5 */ -sbit at 0xE8 USBIF;	/* USB interrupt flag (shared with Port2) */ -sbit at 0xE8 P2IF;	/* Port2 interrupt flag (shared with USB) */ -sbit at 0xE9 UTX0IF;	/* USART0 TX interrupt flag */ -sbit at 0xEA UTX1IF;	/* USART1 TX interrupt flag (shared with I2S TX) */ -sbit at 0xEA I2STXIF;	/* I2S TX interrupt flag (shared with USART1 TX) */ -sbit at 0xEB P1IF;	/* Port1 interrupt flag */ -sbit at 0xEC WDTIF;	/* Watchdog timer interrupt flag */ +sbit __at 0xE8 USBIF;	/* USB interrupt flag (shared with Port2) */ +sbit __at 0xE8 P2IF;	/* Port2 interrupt flag (shared with USB) */ +sbit __at 0xE9 UTX0IF;	/* USART0 TX interrupt flag */ +sbit __at 0xEA UTX1IF;	/* USART1 TX interrupt flag (shared with I2S TX) */ +sbit __at 0xEA I2STXIF;	/* I2S TX interrupt flag (shared with USART1 TX) */ +sbit __at 0xEB P1IF;	/* Port1 interrupt flag */ +sbit __at 0xEC WDTIF;	/* Watchdog timer interrupt flag */  #define IRCON2_USBIF	(1 << 0)	/* USB interrupt flag (shared with Port2) */  #define IRCON2_P2IF	(1 << 0)	/* Port2 interrupt flag (shared with USB) */ @@ -225,8 +225,8 @@ sbit at 0xEC WDTIF;	/* Watchdog timer interrupt flag */   * Priority = (IP1 << 1) | IP0. Higher priority interrupts served first   */ -sfr at 0xB9 IP1;	/* Interrupt Priority 1 */ -sfr at 0xA9 IP0;	/* Interrupt Priority 0 */ +sfr __at 0xB9 IP1;	/* Interrupt Priority 1 */ +sfr __at 0xA9 IP0;	/* Interrupt Priority 0 */  #define IP1_IPG5	(1 << 5)  #define IP1_IPG4	(1 << 4) @@ -286,13 +286,13 @@ sfr at 0xA9 IP0;	/* Interrupt Priority 0 */   */  /* Timer count */ -sfr at 0xCA T3CNT; -sfr at 0xEA T4CNT; +sfr __at 0xCA T3CNT; +sfr __at 0xEA T4CNT;  /* Timer control */ -sfr at 0xCB T3CTL; -sfr at 0xEB T4CTL; +sfr __at 0xCB T3CTL; +sfr __at 0xEB T4CTL;  #define TxCTL_DIV_1		(0 << 5)  #define TxCTL_DIV_2		(1 << 5) @@ -312,10 +312,10 @@ sfr at 0xEB T4CTL;  /* Timer 4 channel 0 compare control */ -sfr at 0xCC T3CCTL0; -sfr at 0xCE T3CCTL1; -sfr at 0xEC T4CCTL0; -sfr at 0xEE T4CCTL1; +sfr __at 0xCC T3CCTL0; +sfr __at 0xCE T3CCTL1; +sfr __at 0xEC T4CCTL0; +sfr __at 0xEE T4CCTL1;  #define TxCCTLy_IM			(1 << 6)  #define TxCCTLy_CMP_SET			(0 << 3) @@ -328,16 +328,16 @@ sfr at 0xEE T4CCTL1;  #define TxCCTLy_CMP_MODE_ENABLE		(1 << 2)  /* Timer compare value */ -sfr at 0xCD T3CC0; -sfr at 0xCF T3CC1; -sfr at 0xED T4CC0; -sfr at 0xEF T4CC1; +sfr __at 0xCD T3CC0; +sfr __at 0xCF T3CC1; +sfr __at 0xED T4CC0; +sfr __at 0xEF T4CC1;  /*   * Peripheral control   */ -sfr at 0xf1 PERCFG; +sfr __at 0xf1 PERCFG;  #define PERCFG_T1CFG_ALT_1      (0 << 6)  #define PERCFG_T1CFG_ALT_2      (1 << 6)  #define PERCFG_T1CFG_ALT_MASK   (1 << 6) diff --git a/src/teledongle-v0.1/.gitignore b/src/teledongle-v0.1/.gitignore index 96c802bd..9826814b 100644 --- a/src/teledongle-v0.1/.gitignore +++ b/src/teledongle-v0.1/.gitignore @@ -1,2 +1,2 @@ -teledongle-v0.1 +teledongle-v0.1*  ao_product.h diff --git a/src/teledongle-v0.1/Makefile.defs b/src/teledongle-v0.1/Makefile.defs index be7741d8..ceb80b7a 100644 --- a/src/teledongle-v0.1/Makefile.defs +++ b/src/teledongle-v0.1/Makefile.defs @@ -1,4 +1,4 @@ -PROG = teledongle-v0.1.ihx +PROG = teledongle-v0.1-$(VERSION).ihx  SRC = \  	$(TD_SRC) \ diff --git a/src/teledongle-v0.2/.gitignore b/src/teledongle-v0.2/.gitignore index af79a766..f6ea8c6c 100644 --- a/src/teledongle-v0.2/.gitignore +++ b/src/teledongle-v0.2/.gitignore @@ -1,2 +1,2 @@ -teledongle-v0.2 +teledongle-v0.2*  ao_product.h diff --git a/src/teledongle-v0.2/Makefile.defs b/src/teledongle-v0.2/Makefile.defs index cbec7805..ea9713b6 100644 --- a/src/teledongle-v0.2/Makefile.defs +++ b/src/teledongle-v0.2/Makefile.defs @@ -1,4 +1,4 @@ -PROG = teledongle-v0.2.ihx +PROG = teledongle-v0.2-$(VERSION).ihx  SRC = \  	$(TD_SRC) \ diff --git a/src/telemetrum-v0.1-sirf/.gitignore b/src/telemetrum-v0.1-sirf/.gitignore index 6d584f36..7698f5aa 100644 --- a/src/telemetrum-v0.1-sirf/.gitignore +++ b/src/telemetrum-v0.1-sirf/.gitignore @@ -1,2 +1,2 @@ -telemetrum-v0.1-sirf +telemetrum-v0.1-sirf*  ao_product.h diff --git a/src/telemetrum-v0.1-sirf/Makefile.defs b/src/telemetrum-v0.1-sirf/Makefile.defs index 2ce6e6ed..a7310fbc 100644 --- a/src/telemetrum-v0.1-sirf/Makefile.defs +++ b/src/telemetrum-v0.1-sirf/Makefile.defs @@ -1,4 +1,4 @@ -PROG = telemetrum-v0.1-sirf.ihx +PROG = telemetrum-v0.1-sirf-$(VERSION).ihx  SRC = \  	$(TM_BASE_SRC) \ diff --git a/src/telemetrum-v0.1-sky/.gitignore b/src/telemetrum-v0.1-sky/.gitignore index 5a9fafb5..d25d7ad9 100644 --- a/src/telemetrum-v0.1-sky/.gitignore +++ b/src/telemetrum-v0.1-sky/.gitignore @@ -1,2 +1,2 @@ -telemetrum-v0.1-sky +telemetrum-v0.1-sky*  ao_product.h diff --git a/src/telemetrum-v0.1-sky/.sdcdbrc b/src/telemetrum-v0.1-sky/.sdcdbrc new file mode 100644 index 00000000..710b4a2f --- /dev/null +++ b/src/telemetrum-v0.1-sky/.sdcdbrc @@ -0,0 +1 @@ +--directory=.. diff --git a/src/telemetrum-v0.1-sky/Makefile.defs b/src/telemetrum-v0.1-sky/Makefile.defs index 098ac547..000287ba 100644 --- a/src/telemetrum-v0.1-sky/Makefile.defs +++ b/src/telemetrum-v0.1-sky/Makefile.defs @@ -1,4 +1,4 @@ -PROG = telemetrum-v0.1-sky.ihx +PROG = telemetrum-v0.1-sky-$(VERSION).ihx  SRC = \  	$(TM_BASE_SRC) \ diff --git a/src/telemetrum-v1.0/.gitignore b/src/telemetrum-v1.0/.gitignore index 76228093..c2212151 100644 --- a/src/telemetrum-v1.0/.gitignore +++ b/src/telemetrum-v1.0/.gitignore @@ -1,2 +1,2 @@ -telemetrum-v0.2 +telemetrum-*  ao_product.h diff --git a/src/telemetrum-v1.0/.sdcdbrc b/src/telemetrum-v1.0/.sdcdbrc new file mode 100644 index 00000000..710b4a2f --- /dev/null +++ b/src/telemetrum-v1.0/.sdcdbrc @@ -0,0 +1 @@ +--directory=.. diff --git a/src/telemetrum-v1.0/Makefile.defs b/src/telemetrum-v1.0/Makefile.defs index 624ce6e8..010578df 100644 --- a/src/telemetrum-v1.0/Makefile.defs +++ b/src/telemetrum-v1.0/Makefile.defs @@ -1,4 +1,4 @@ -PROG = telemetrum-v1.0.ihx +PROG = telemetrum-v1.0-$(VERSION).ihx  SRC = \  	$(TM_BASE_SRC) \ diff --git a/src/tidongle/.gitignore b/src/tidongle/.gitignore index 3323f640..3888a0f9 100644 --- a/src/tidongle/.gitignore +++ b/src/tidongle/.gitignore @@ -1,2 +1,2 @@ -tidongle +tidongle*  ao_product.h diff --git a/src/tidongle/Makefile.defs b/src/tidongle/Makefile.defs index fdd51732..0e13cb20 100644 --- a/src/tidongle/Makefile.defs +++ b/src/tidongle/Makefile.defs @@ -1,4 +1,4 @@ -PROG = tidongle.ihx +PROG = tidongle-$(VERSION).ihx  SRC = \  	$(TI_SRC) diff --git a/telemetrum.inf b/telemetrum.inf index 8a12b857..0a81084b 100755 --- a/telemetrum.inf +++ b/telemetrum.inf @@ -12,23 +12,38 @@ DriverVer	= 08/05/2010,3.1.0.41  %Mfg% = Models, NTx86, NTamd64, NTia64
  [Models.NTx86]
 -%TeleMetrum% = TELEMETRUM, USB\VID_FFFE&PID_000A
 +%AltusMetrum% = TELEMETRUM, USB\VID_FFFE&PID_000A
 +%TeleMetrum% = TELEMETRUM, USB\VID_FFFE&PID_000B
 +%TeleDongle% = TELEMETRUM, USB\VID_FFFE&PID_000C
 +%TeleTerra% = TELEMETRUM, USB\VID_FFFE&PID_000D
  [Models.NTamd64]
  %TeleMetrum% = TELEMETRUM, USB\VID_FFFE&PID_000A
 +%TeleMetrum% = TELEMETRUM, USB\VID_FFFE&PID_000B
 +%TeleDongle% = TELEMETRUM, USB\VID_FFFE&PID_000C
 +%TeleTerra% = TELEMETRUM, USB\VID_FFFE&PID_000D
  [Models.NTia64]
  %TeleMetrum% = TELEMETRUM, USB\VID_FFFE&PID_000A
 +%TeleMetrum% = TELEMETRUM, USB\VID_FFFE&PID_000B
 +%TeleDongle% = TELEMETRUM, USB\VID_FFFE&PID_000C
 +%TeleTerra% = TELEMETRUM, USB\VID_FFFE&PID_000D
  [DestinationDirs]
  DefaultDestDir=12
  [ControlFlags]
  ExcludeFromSelect=USB\VID_FFFE&PID_000A
 +ExcludeFromSelect=USB\VID_FFFE&PID_000B
 +ExcludeFromSelect=USB\VID_FFFE&PID_000C
 +ExcludeFromSelect=USB\VID_FFFE&PID_000D
  [Strings]
  Mfg = "altusmetrum.org"
 -TeleMetrum = "TeleMetrum/TeleDongle"
 +AltusMetrum = "Unknown AltusMetrum Device"
 +TeleMetrum = "TeleMetrum"
 +TeleDongle = "TeleDongle"
 +TeleTerra = "TeleTerra"
  ;----------------------------------------------------------------------------
 | 
