Table of Contents

PC Protocol of Suunto D9

This document describes the transfer protocol and memory layout of these suunto diving computers:

Suunto D6 (a D9 without the air integration)

Suunto D9

Suunto changed the protocol for these models - again. One reason is that the D9 is capable in recording not only the depth, but also pressure and temperature throughout the dive. The computers also have no longer just 8kb, but 32kb of memory for the profile information.

Communication

The interface is technically still a RS232 interface, but with a USB connector. With a device driver from the USB chipset vendor FTDI it will be recognized as a standard serial port.

The RS232 should be 9600 baud, 8N1.

Transfer

The protocol for the Suunto D9 is slightly different from other Suunto computers. The first thing is that the interface is USB only. But with the standard driver is behaves like a serial port (see above). These standard drivers are available for Mac OS X and Linux, so there should be no reason to go into too much detail.

All data is send in packages to and from the computer. Every package is followed by a CRC for checksum reasons.

The package starts with a command byte, followed by the length of bytes for the parameters ($00 $03 = 3 Bytes), the actual parameters and the CRC at the end. Here are examples of the most common commands:

The DiveManager Software from Suunto does the following when reading data from a D6/D9:

GetVersion()

ReadMemory($0, $78)

ReadMemory($168, $78) (Reading the memory header)

ReadMemory($F0, $78)

After that the DiveManager reads the headers of all profiles first (by following the linked list in the headers), but always $78 bytes and later fills in the holes in the memory, if necessary. This allows the DiveManager to display a progress bar for the import.

To change the personal information, it does the following:

GetVersion()

Write($015E,$28)

Read($0168,$78)

GetVersion()

Read($0000,$78)

To reset the max. depth to zero it does the following:

GetVersion()

ResetMaxDepth()

Read($00F0,$78)

Read($0168,$78)

GetVersion()

Read($0000,$78)

Firmware versions

There have been two recalls of the Suunto D9 so far.

The first one was a hang of the D9, which is fixed in firmware version 1.2.8 and later (serial numbers 4xxxxxxxx - 450000699)

The second one (serial numbers below 62102582, an inacuracy of the clock in 0.6% of the cases) seemed to be fixed in firmware version 1.2.11 and later. This one also affects the Suunto D6 (serial numbers below 62103693)

Memory layout

The 32kb of memory is split into a $019A bytes header and the rest is a ring-buffer with the dive profiles. The ring-buffer is a stream of data, which ends at the position, that is marked in the header. At this position the computer starts writing the information from the next dive. If the write pointer reaches the value $8000, it jumps back to $019A.

Dive Profile Data

The length of the profile data can be found by looking into the profile header: the difference between the offset of the next dive to the current offset minus the size of the header ($4A).

Warning: Remember that the data is stored in a ring-buffer! The next dive pointer might actually be smaller than the current dive pointer.

To parse the profile data, you start with a time of 0:00 minutes and read to LSB 16 bit values. The first value is the current depth in cm. The second value is the tank pressure in bar * 100. Before reading the next value you increment the time by the “Sample recording interval” (Header offset $1C). Every “Temperature recording interval” (Header offset $47) there is another byte following with the temperature in degrees celcius. You stop once you've read the beginning of the next dive.

But, there is another twist: the dive profile can contain events, which are encoded into the profile information. For this you need check for the “Offset to the first marker position” (Header offset $4C). The first offset into the dive profile is $0000, you increment it with every byte you've read from the profile (4 or 5 per sample, see above). If the marker is equal to the current profile position, the next byte is an event type. You have to read all events till you will get Event $01 “Next Event Marker”. After you've read this one, you can continue normal parsing till you hit the next marker position.

Event

Type

Parameter

Function

$01

Next Event Marker

WW

set the position of the next event marker (1st: current position, 2nd: next position)