Updating the KLN89B

My epic saga of updating a plane's very old GPS's data in a very modern way

Update: better date parsing in updates. Proper handling for dates crossing a year boundary. This update only concerns PC-side code, AVR code untouched.

I bought a Cessna 150 recently. It had a very nice set of avionics in it (for a C-150), including an IFR-certified GPS. It was an old one (from 1996), but worked well: KLN89B. The GPS has a very nice installation manual, which explains all the connectors on the back and protocols used. It also has a removable memory card for updating the GPS data (as up-to-date data is legally required for IFR flight). The complicated part is that the memory card is a proprietary one, for which no reader exists. It has a weird 2 x 20 pin 1.27mm connector and a strange shape. So how does one write the new data to it if no reader exists? Well, you do not. The data card was removable because back in the day (1990s) Honeywell ran a program where they would mail you a new card with the new data, and you’d mail them back the old one.

So, how does one update the GPS data now that this program no longer exists? Well, it is complicated. The back of the GPS has a connector which has a TX/RX pair for a RS232 port that can be used to update the data on the card, using the GPS itself as a gigantic card reader driven by a DOS program on the computer. At the time of the initial installation of the GPS into the plane, there can be a special connector installed in the panel to allow this update from a laptop connected to it inside the plane. My new plane lacked this option. Getting it installed now would be very expensive (avionics shop) or illegal (DIY).

There is another option. The GPS itself is removable from the panel (legally) as it is installed in a slide-out tray. There exists a special docking station to enable it to be used “at home” and the update can be done there using a long chain of special (and expensive) cables. For extra credit, the updater tools run on DOS or Windows only (they do not run on wine in Linux). Needless to say this option is a huge pain-in-the-rear. To make matters even more complicated, “to prevent piracy,” each GPS unit has a 32-bit “key” which is given to Honeywell when you buy the database update. Said update will only install unto the GPS unit whose key it matches. The key is shown in the settings page #3 of the GPS, as you can see above. Fun tidbit: as you'll see later, you can customize yours as you see in the photo above. This may have all been acceptable in 1996, but a modern solution is needed in 2016.

Finding an extra data card for the KLN89B was not easy. The list price for it is $591 (!!!), but nobody has it in stock, since it has not been made since 1996 (?). I found one on ebay for $100 or so and bought it. Now that I had an extra one, I could take it apart! Unsurprisingly, $591 data card contained $3 in parts (OK, well, maybe $20 in 1996). It had two 1MB Intel NOR flash chips (TE28F008SA-100), with an unpopulated space for a third and a single 3-to-8 bit decoder with inverted outputs (74HC138D). Given the datasheets, I was able to work out the pinout of the data card, as you can see here now. This table assumes the card is on the table, with the metal part up and the connector facing you.

(aka A21)
(aka A20)
(aka nCE)
The chips were wired together in such a way that this memory card could simply be treated externally as a 3Mx8 NOR flash chip. The memory is 5V, and requires external 12V supply to write or erase. I had no 5V boards around with enough pins to drive this, so I wired it to an STM32F411 dev board which did. The board is indeed 3.3V, but I figured that the memory will still work fine for read at a lower voltage if I was slow with it. This proved to be correct and I was able to dump the contents of the card a few times over and verify that they matched each time. I used my Cortex debugger (a yet-to-be-published project: CortexProg) to do this, and, since I was taking it slow with the memory, the speed was about 800 bytes a second. The entire card took 45 minutes to dump each time at this stage.

Given that I could read the card, I knew it was time to lay out a board for a proper reader/writer for it. I would have loved to use an ARM chip, but I found none that had 5V I/O and USB support. Adding enough level shifters to shift 32 signals would be a huge pain, so I just decided to use a 5V chip - AT90USB646. It costs a LOT more than an ARM chip with enough IO and USB, but it has the advantage of doing 5V I/O. I laid out the board based on the pinout of the memory card, added a 12V boost converter, and off it went to be manufactured. I ordered the parts online and waited.

While waiting, I turned my attention to the supply part of the database updates. Honeywell still provides update data, but in digital form only - no card mail-in options available. I took a look at the latest update I got from Honeywell. It was a Windows EXE file. Great... Well, I took a look at it with a hex editor and there is clearly a ZIP file in there. I grabbed it and extracted it. It contained the DOS updater program called “netload.exe”, a text file called readme.txt, a file called ”netload.cfg” containing just the string “database.dat” and also a file called “database.dat”. (Turns out that the EXE is just an SFX archive and it was safe to run). Woohoo! We’re golden - we have the database. Right?

Turns out: NO. The database in this file looked like complete garbage, except the last 50 or so bytes. Snooping the serial bus during the update being sent to the GPS showed that the data sent over the UART is not encrypted and mostly matches the data card, so the decryption MUST happen on the PC. Well, what else is there to do other than to fire up IDA and start looking at disassembly. I had two separate utilities that I knew that decrypted the file. The DOS updater and the Windows updater. Having both proved instrumental in figuring out that decryption method. The DOS updater was convenient as it was small and thus made it easier to find the parts I cared about. However, 16-bit x86 Borland-compiler-produced code is a huge pain to read. The Windows app was larger, but it had logging and this helped too. Long story short: after three days of hard work I was able to decrypt the update. The key turned out to be the actual 32-bit GPS “key” and the “encryption” method was laughably simple: use the key as the starting value for CRC-32. To decrypt each byte, subtract from it the lower 8 bits of the current CRC. After the byte is decrypted, update the CRC for it. I am not joking, this is it. The file also had some checksums to verify integrity. I REALLY wanted to be able to do this as well. The code was a mess and took a few more days, but soon I was able to calculate and verify the checksums same as the updater programs did. Sweet! Fun tidbit: you can decrypt the file without knowing whose GPS it was for and what their “key” is. Honeywell engineers were nice enough to leave the decryption key right in the file footer.

The database file I produced after I decrypted “database.dat” almost matched the dump of the memory card. 8 bytes out of 2MB did not match. In my decrypted file at offset 0x42 I had 8 bytes of 0xFF. The card has something else. First 4 bytes were the GPS “key” and second were some mysterious word. Looking at old updates that I flashed to the card and then dumped, as well as someone else’s card, I was able to deduce that this second word DOES change based on the GPS “key” but does not based on the update data itself. UART snooping proved that the PC does not send this data to the unit, instead the unit writes it there somehow by itself. Uh oh! Well, since it never changes based on the update data, I can just copy it from the card before writing the update data, and then put it back afterwards. Cool point: I later checked what happens if I leave these bytes as 0xFF or modify them otherwise. The GPS’s settings page #3 shows its “key” as whatever the word at 0x42 is. I guess the “key” is a property of the card and not of the GPS. However, if the word at 0x42 is 0xFFFFFFFF, the GPS shows another key. Perhaps this is its personal key that it shows when presented with a blank card? The second word seemed to have no effect on the GPS. Just out of abundance of caution I decided to still back it up and restore it when I write my updater tool. Now the flash contents after using my tool always exactly match those created by using the GPS-in-the-very-expensive-dock-over-slow-RS232 method.

The boards arrived soon and I built two. Luckily I had used an AT90USB64 on a previous project, so I already had a small USB stack I could use. It took one evening to get the board to communicate with the PC and another to get it to be able to read, write, and erase the memory card. I settled on using the HID class since then my updater utility could operate without drivers on Windows and Linux. It is true that communication could be a lot faster over bulk endpoints with a custom driver, but driverlessness seems more important to me. It took a few tweaks here and there, but in the end I was able to read the card at 40KB/s and write to it at 30KB/s. This is perfectly OK, considering the official method tops out at 4650 B/s and requires a $200 dock, a $90 cable, and two separate trips to the airport since the dock requires 120VAC and cannot be run in the car. It is prettier to watch too :). The green light is on when the board is powered, and the blue blinks hypnotically while the flash is being accessed.

The BOM is as follows:

  • ZX62R-B-5P(30) USB connector
  • Amphenol 20021121-00040T4LF 20x2 1.27mm header
  • Atmel AT90USB646-AU microcontroller
  • Microchip MIC2288YD5-TR step-up
  • ON semi schottky diode MBRM140T3G
  • Abracon ABL-16.000MHz-B4Y crystal
  • all remaining components in 0805 size:
    • Kemet L0806C100KPWST 10uH inductor
    • a green LED
    • a blue LED
    • 2.2uF cap
    • 43.2 Kohm resistor 1%
    • 5 Kohm resistor 1%
    • 2x 18pF caps
    • 3x 22uF caps
    • 2x 1uF cap
    • 91 Ohm resistor
    • 140 Ohm resistor.

I am releasing today the sources and schematics for all of this, in case you or someone else you know has a KLN89B GPS in your/their plane, you may now do GPS updates quickly and efficiently using just a normal laptop with a modern OS. The license on the software and hardware design is as follows: I make no warranties about this code or hardware design. I make no promises that it is fit for any purpose. Usage of this code and of these hardware designs is at your own risk and you may not hold me responsible for any consequences, be they direct, indirect, or coincidental. You may use this software and hardware designs for non-commercial purposes. This license and the copyright notices in the code may not be removed from the code and must be supplied with all binaries produced from said code. All commercial use is forbidden. If you would like a commercial-use license, contact me at me@dmitry.gr. I also have 8 unpopulated PCBs here, in case you’d like to assemble one and do not want to lay out your own and wait. I am happy to provide them in return for a $10 paypal donation. Code can be downloaded here: => [LINK] <=. If you'd like complete binaries, both for AVR and for PC (linux-x86, linux-amd64, windows), I am making them available here: => [LINK] <= The binaries are made to be easy to use. For the most common case (update the memory card) you can just extract the update you got from Honeywell and drag the "database.dat" icon onto the "updater.exe" icon. Under linux you can run updater and pass the "database.dat" path ot it. The executable has other options you're free to explore (like backing up your card) by running it with the "-h" parameter.

Please note: I am in no way saying that you can, should, or are allowed to fly with a card updated in this way (even though the bits in it are identical). I am not claiming that I plan to or am flying with such a card. All experimentation was performed on a card and a GPS that is not used for IFR flight. No, I do not plan to sell finished units, and I strongly discourage anyone else from trying to do such a thing.

© 2012-2023