PalmOS Interface for Suunto Diving Computer
Design a PalmOS application to download the data stored on a Suunto Cobra diving
computer, and present that data in a meaningful format to the user.
I am an avid scuba diver, and as such, rely on a Suunto diving computer for my
safety while underwater. Traditionally, divers have relied on printed dive tables to
estimate a safe diving “profile” each time they enter the water. These tables, which are
standardized for the average diver, use the deepest portion of the dive and the total dive
time to approximate the percentage of nitrogen absorbed by a diver’s body tissues. This
tissue concentration limits the time a diver can spend on a single dive, as well as
subsequent dives (the tables account for a surface interval between dives.) Before each
dive, the diver consults the tables, using his expectation of his diving behavior to
calculate how long he can safely stay underwater. Following each dive, it is the
responsibility of the diver to log his actual diving statistics (depth, time, air consumption,
etc.) and use these numbers to calculate subsequent dive profiles.
There are two major flaws with the above methods. First, there is a great deal of
potential for human error. It is not unheard of for divers to misread their tables or exceed
their safe dive time, errors which can result in decompression illness, damaged lungs, or
death. On the opposite end of the spectrum, divers who follow the dive tables rigorously
spend a great deal less time underwater than they might safely be able to spend with a
more interactive method. The primary cause of this is the fact that the dive tables assume
that the entirety of a dive is spent at the greatest depth of the dive. Therefore, if a diver
spends the majority of his dive at 40 ft, but he swims down to 50 feet to get a closer look
at something, his profile will be calculated as though he spent the entire dive at 50 ft.
This would reduce his safe dive time from 48 to 36 minutes, a 25% reduction.
Dive computers help to solve both of the problems above. All dive computers
monitor the time of a dive and measure the depth at periodic intervals. Using this
information they update the diver’s profile while he is diving. Additionally, higher end
computers are integrated into the diver’s air supply. These computers not only calculate
safe nitrogen levels, they also monitor the air consumption of the diver, further reducing
the human error factor (even if a traditional diver uses the dive tables rigorously, they still
need to monitor their air pressure to avoid an emergency). Particularly good computer’s
go a step further and allow the diver to download dive information to their computer.
This information replaces the traditional pen and paper dive log. In addition to the
“global” dive data (total time, greatest depth, etc.) many computers store and download
the periodic data they use to track the dive, allowing the diver to review the entire dive.
The dive computer which I use, and therefore based this project upon, is a Suunto
Cobra. It is an air-integrated computer with download capabilities and configurable
periodic logging. Suunto provides Windows software for downloading data from the
computer, however they support no other operating systems. While this makes recording
dive logs very convenient, it is rare that someone has a computer on a dive boat or at the
beach. Therefore I felt it would take the convenience a step further to support
downloading to a palm device.
Suunto Cobra dive computer, with serial download cable
The computer discussed above.
Suunto Dive Manager software (SDM)
The software provided by Suunto, which I attempted to emulate.
Kyocera 7135 Smartphone
A PalmOS 4.1 device with an integrated cellular phone.
Aggsoft’s Advanced Serial Port Monitor (ASPM)
A serial port “sniffer”. This proved to be an invaluable tool for debugging serial
Metrowerks CodeWarrior for PalmOS v.8.0 Demo
The standard IDE for PalmOS development.
PalmOS SDK v.5.4
Palm’s most current SDK.
PalmOS Emulator v3.5
An emulator which supports Palm devices through PalmOS 4.x.
PalmOS Simulator v5.4
A simulator for PalmOS 5 devices.
Oscilloscope, multimeter, LEDS, etc.
The usual assortment of useful hardware, used here to evaluate the Suunto serial
4.0 Original Project Plan
4 Initiate contact with Suunto and other resources, background
research, collect materials
5 Reverse engineer Suunto com protocol
6 Attempt to decode Suunto data protocol
7 Begin Palm software development: establish communication, data
Midterm goal: have a PC simulation of communication and data parsing
8 Parse and display data in text format on Palm
9 'Pretty' display (or schedule buffer if behind schedule)
10 Final presentation
5.0 Post Mortem
Not surprisingly, Suunto is not very forthcoming with regards to information
about their protocol. So I began trying to decode their protocol manually. SDM
performs two different serial functions. The first is an interface test to ensure the
computer and serial cable are configured correctly. Using two computers connected by a
null modem cable and hyperterm it was easy to see that SDM sends “#41#54#0D”
(AT<CR>), a standard modem command. I was surprised to find that I could not elicit a
response from the cable duplicating the same command using hyperterm. I started to
search for more powerful serial com software and was lucky to stumble upon ASPM. In
addition to the common hyperterm-like configure, send, and receive abilities, ASPM
gives the user manual control of the control signals of the serial port. It also shows
incoming signals, but they are frequently asserted for too short a period to make that of
much use. Of far more use, however, was the fact that it has a “spy” mode, in which it
shows all data going in and out of a port, removing the need for a second computer.
Using ASPM, I was quickly able to determine that the cable would only respond
if the DTR signal was asserted and the RTS signal was unasserted. I was now able to
easily reproduce the interface test. The next step was to replicate the download function
of SDM. Again ASPM proved incredibly useful. Using it I was able to view an entire
download from the Cobra to SDM. Starting at the beginning, SDM sent
“#05#00#24#01#20”. It is pretty easy to determine that the last character is an XOR
checksum of the preceding characters. However, when I tried to send this string to the
computer using ASPM, I did not get a response.
Taking a closer look at the actual SDM transaction, I found that SDM was
toggling the RTS signal. Whereas the signal was unasserted for the entire interface test,
for the download it was asserted on TX and unasserted on RX. Even armed with this
knowledge I was unable to elicit a response from the computer, so I went looking for an
answer on the trusty world-wide-web. The result was better than I had hoped. I found a
site that had not appeared on my previous searches which detailed not just the protocol,
but the entire memory map of the Suunto. As this site documents, the timing of the
toggle of RTS is critical to the protocol. Armed with this knowledge, I felt prepared to
move from the PC to the Palm.
Palm development was an entirely new endeavor for me. Fortunately,
Metrowerks provides a tutorial which gives a very good overview of the Palm GUI and
its objects, and a reasonable introduction to the OS. In addition, the Palm SDK contains
both an overview (Palm OS Companion) and a reference (Palm OS Reference). Palm
also provides a simulator and an emulator for testing code. Initially I was using the
Emulator, as it supports PalmOS 4.1, which is what runs on the Kyocera 7135, my
intended target device.
While I used a great deal of the Palm documentation for the skeleton of the
application (the GUI objects and event handlers) I relied on the chapters on serial
communications1 for the meat of the application.
Palm provides two serial managers, aptly named the “Serial Manager” and the
“Old Serial Manager”. While both are supported on the OS(s) I was targeting, I initially
chose to work with the Serial Manager for the obvious reason that it is newer. I found no
reason to switch to the Old Serial Manager, even after encountering problems.
According to the Palm OS Companion, the devices support five external serial signals:
SG (ground), TX, RX, CTS, and RTS. Some devices also support DTR, but for most
“the DTR signal is always high.”2 For the devices I used (through the emulator and
simulator) the signal was in fact always low. Presumably they meant to say that it is
always active since RS232 is an active-low protocol.
Palm OS Companion2 pp89-130 and Palm OS Reference pp1497-1536
Palm OS Companion2 p90
Since the only signals used by the Cobra interface are TX, RX, DTR, and RTS,
and since I needed DTR to always be active to power the interface, everything seemed in
order. This quickly turned out to be false.
The Palm serial manager does not provide direct control over the control signals
on the serial port, so I was not able to call any sort of “enableRTS()” function. They do
however have some port configuration parameters (srmSettingsFlagRTSAutoM and
srmSettingsFlagRTSInactive)3 which sound like they would provide the functionality I
needed. I initially assumed that by not setting the RTSAuto flag, and toggling the
RTSInactive flag, I would be able to exert manual control of the signal. Unfortunately,
this was not the case. In fact, I was not able to get any mixture of settings to allow
control of the RTS. I eventually wrote a separate application, SerTest.prc, to allow
runtime manipulation of the configuration flags. It showed that toggling RTSInactive on
the emulator changed the internal settings of the device, but it had no effect on the output
of the signal. At this point I changed from the emulator to the simulator, hoping that I
would get better results with PalmOS 5 (and abandoning my hopes of getting it to run on
my 7135.) Ironically running the same test on the simulator had an opposite effect.
Toggling RTSAuto turned the signal on and off, but not the internal status. Toggling
RTSInactive seemed to have no effect at all, so I had to rely on the RTSAuto setting to
remain active while set and inactive while unset.
Now the only thing holding me back from downloading the data was the RTS
timing. I was able to estimate an optimal timing by running the code below and
capturing the results in ASPM:
for (InitTime=MS50; InitTime <= MS50 * 10; InitTime += MS50)
for (SettleTime=MS50; SettleTime <= MS50 * 10; SettleTime += MS50)
for (WaitTime=MS50*10; WaitTime <= MS50 * 20; WaitTime += (MS50*2))
In this code MS50 is the number of system ticks executed in 50ms and flail waits for the
specified number of system ticks. This code does not get any incoming characters.
Instead I just watched for a response in ASPM. Each correct response I marked a a hit
and each corrupt or no response was marked as a miss. I the unrolled the loops and found
which settings for each Flail() call seemed to result in the most hits. For my code, the
best settings were 100ms, 500ms, and 1s for InitTime, SettleTime, and WaitTime,
respectively. Of course WaitTime actually became the timeout for the serial rx function.
At this point I was able to send and receive packets to and from the Cobra.
Unfortunately, for lack of time, development was halted to focus on my final
presentation. Therefore, the code currently performs a memory dump of the first 240
Palm OS Reference p1506&p1508
bytes of memory from the Cobra (for simplicity I grab memory in x10 chunks, but going
beyond xE0 would result in a byte overflow of the address byte leading to an infinite
loop, so the highest byte rx’d is xF0 (actually evaluating this now, the code leads to
overlaps at the start and end of each subsequent block, but hey, too late to debug now)).
6.0 Further Work
Clearly the first thing to be done is to fix the bug I just identified. Additionally
the code does not check the CRC of incoming packets or attempt to retransmit on
failures. Once the data transmission is robust, parsing the data would have to be done.
This could either be done by downloading the entire memory, as implemented now, or
using the additional Suunto protocol commands to download log “pages” on dive at a
time. The data could then be interpreted and either presented to the user, or my
preference, output in UDCF(Universal Dive Computer Format) to be displayed by a dive
log application such as Ruiz’s Dive Log.
I think it would also be worth pursuing a means of making the control of the RTS
signal more reliable. This would most likely involve hacking direct access to the serial
registers on the 68328 processor.
This project was more applied than theory, so there are no groundbreaking
conclusions to be made. I do believe it is a good case study into the tradeoffs between
power and convenience when using an off-the-shelf solution such as the Palm. I usually
code at a firmware level, so direct access to registers is a luxury I often take for granted
while longing for a GUI and an API. One thing I have found to be consistent throughout
is the unreliability of documentation. Nothing should be assumed without being tested,
particularly something critical, such as full serial port control proved to be in this
instance. I am happy to report that this has sparked a new interest for me, and I am next
planning to write a Palm app to communicate with a compact GPS receiver to provide
real-time positioning data.
8.0 Additional References