Moving protocol documentation to its own file

This commit is contained in:
Simon Larsson
2020-05-30 14:40:21 +02:00
parent 1b23ace6b0
commit 2aeac2e358
2 changed files with 305 additions and 56 deletions
+299
View File
@@ -0,0 +1,299 @@
This document is based on [the protocol documentation by Tommy Johnson]
(https://web.archive.org/web/20030803072005/http://csgrad.cs.vt.edu/~tjohnson/timex/).
I have added and corrected some information. There may be more differences
between watch versions, but most information for the model 70 should be
correct.
Sound and app packets are not yet documented.
## Physical level
Data is sent as a series of pulses. When sent using th CRT, each byte
appears as 1-9 horizontal lines, with 2 bytes being sent each frame. A
CRT draws its image sequentially as it receives the video signal, with
each line fading shortly after being drawn, so to a light sensor it
appears as a short pulse. LCDs in general receives an entire frame and
draws all pixels almost at the same time, which is why LCDs do not work
for data transfer.
Timex solved this problem by offering a "Notebook Adapter" which
essentialy is a serially attached unit which transcodes data into the
appropriate pulses for the watch to receive. This gives us a very nice
advantage: it is super simple to log data from the program.
Bytes are sent least significant bit first, one start bit, no stop bit. A
one is indicated by the absence of a pulse, a zero is a pulse. This means
the byte 0x5a would look like pnpnppnpn (where p indicates a pulse, and n
the absence of a pulse).
Some measurements were done by probing the video signal. Pulses are
approximately 32 µs long. Pulses are sent at an interval of approximately
480 µs. Some configuration files mentioned 2048 baud, which would mean
approximately 488 µs. So this sort of makes sense.
Data transfer using CRT is done at 640x480@60Hz. At this resolution and
frequency, the horizontal refresh frequency is 31.46875 kHz, so one line
is drawn approximately every 31.78 µs. using the above timings, we can
quantify the above measurement and conclude that one bit is one line and
a bit is sent every 15 lines. The watch seems to be a bit flexible on
this though.
Data bytes are separated by approximately 2 ms, and packets are separated
by approximately 240 ms. The interpacket delay is also present after
each block of synchronization bytes.
## Synchronization
When initiating transfer, first 200 bytes of 0x55 is sent. During this
time the watch will beep and give the user some time to align the watch.
The exact number here is not important.
After that 50 bytes of 0xAA is sent. The original protocol documentation
says 40 bytes, but I got 50 bytes from the software and I have not
verified if the exact number is important.
## Strings
Strings are encoded in a special charset, which I call the Timex charset.
From the old protocol documentation:
```char set for labels is: (6 bits per char)
0-9 : digits
10-36: letters
37-63: symbols:
space !"#$%&'()*+,-./;\
divide =
bell (image, not sound)
?```
Since only 6 bits are used per character, the 24 bits of 4 characters can
be packed into 3 bytes.
First byte:
- High 2 bits contin low bits of second character
- Low 6 bits contain first character
Second byte:
- High 4 bits contain low bits of third character
- Low 4 bits contain high bits of second character
Third byte:
- High 6 bits contain last character
- Low 2 bits contain high bits of third character
Unused bits are set to ones.
If the above explanation, maybe some pseudo code can clear it up:
```
byte0 = (ch2&0x03)<<6) | (ch1&0x3F)
byte1 = (ch3&0x0F)<<4) | ((ch2>>2)&0x0F)
byte2 = (ch4&0x3F)<<2) | ((ch3&0x30)>>4)
```
## Data packets
Data is separated into packets. Each packet has a framing consisting of
packet length, data type and checksum as follows:
| Byte no. | Description |
| -------- | -------------------------------- |
| 1 | Packet lengh (including framing) |
| 2 | Packet type |
| 3->len-2 | Payload (if any) |
| len-1 | High byte of checksum |
| len | Low byte of checksum |
Checksum is CRC-16/ARC.
When describing packet contents below, only the payload bytes are
considered. Therefore, "byte 1" would mean the third byte of the packet.
### Packet types
Note that names are made up and not official Timex names.
List is ordered by in which order the watch expects the packets. I will
probably add more info on order later.
| ID | Name | Description |
| ---- | ------ | ----------------------------------- |
| 0x20 | START1 | Data transfer start |
| 0x30 | TIME | Time information |
| 0x31 | TZNAME | Time zone name |
| 0x32 | TIMETZ | Time information and time zone name |
| 0x60 | START2 | Marks start of DATA1 packets |
| 0x61 | DATA1 | Contains lots of data |
| 0x62 | END1 | Marks end of DATA1 packets |
| 0x50 | ALARM | Alarm data |
| 0x70 | SALARM | Sent after silent alarms |
| 0x21 | END2 | End of data transfer |
### 0x20 - START1
| Byte | Description |
| ---- | ----------- |
| 1 | Always 0x00 |
| 2 | Always 0x00 |
| 3 | Version |
Version is 0x01 for model 70, 0x03 for model 150 and 0x04 for model 150s.
Example packet: 0x07 0x20 0x00 0x00 0x01 0xc0 0x7f
### 0x30 - TIME
| Byte | Description |
| ---- | -------------------------------- |
| 1 | Timezone ID (1 or 2) |
| 2 | Hour |
| 3 | Minute |
| 4 | Month |
| 5 | Day of month |
| 6 | Year (mod 100) |
| 7 | Day of week (0=monday, 6=sunday) |
| 8 | Seconds |
| 9 | 12h format (1) or 24h format (2) |
### 0x31 - TZNAME
| Byte | Description |
| ---- | -------------------------------- |
| 1 | Timezone ID (1 or 2) |
| 2 | Character 1 of timezone name |
| 3 | Character 2 of timezone name |
| 4 | Character 3 of timezone name |
Insert spaces on unused characters.
Example: 0x02 0x0e 0x1c 0x1d - timezone 2 named EST
### 0x32 - ALARM2
Alarm packet for model 150 and 150s. To be documented.
### 0x60 - START2
| Byte | Description |
| ---- | --------------------------------- |
| 1 | Number of DATA1 packets to follow |
### 0x61 - DATA1
| Byte | Description |
| ---- | ---------------------------------- |
| 1 | Sequence ID (starts at 1) |
| 2->3 | Start index of appointments |
| 4->5 | Start index of TODOs |
| 6->7 | Start index of phone numbers |
| 8->9 | Start index of anniversaries |
| 10 | Number of appointments |
| 11 | Number of TODOs |
| 12 | Number of phone numbers |
| 13 | Number of anniversaries |
| 14 | Unknown, see below |
| 15 | Early alarm, in 5 minute intervals |
Sequence ID is incremented for each DATA1 packet sent.
Indices are counted zero inexed from first address byte (2). This means
the first data is always located at index 0x0e.
The unknown byte was documented as 0x60, but I seem to
get 0x14 instead. Requires some investigating.
Byte 15 indicates how long before the specified time the alarm will sound
(I believe).
Check if the following DATA1 packets contain data start indexes etc too,
or if their payloads are just concatenated.
The following data in the payload are records of the following
format:
These 4 record types are found in DATA1 packets:
Appointment record
| Byte | Description |
| ------ | ---------------------------------- |
| 1 | Record length |
| 2 | Month |
| 3 | Day |
| 4 | Time (see below) |
| 5->len | Packed string |
Time is encoded in 15 minute intervals since midnight, such that 08:45 is
8*4+3=35.
Todo record
| Byte | Description |
| ------ | ---------------------------------- |
| 1 | Record length |
| 2 | Priority |
| 3->len | Packed string |
Phone number record
| Byte | Description |
| ------ | ---------------------------------- |
| 1 | Record length |
| 2-6 | Phone number (BCD, 2 digits per byte, little endian) |
| 7->len | Packed string |
Anniversary record
| Byte | Description |
| ------ | ---------------------------------- |
| 1 | Record length |
| 2 | Month |
| 3 | Day |
| 4->len | Packed string |
### 0x62 - END1
No payload
### 0x50 - ALARM
| Byte | Description |
| ----- | ---------------------------------- |
| 1 | Alarm ID (starts at 1) |
| 2 | Hour |
| 3 | Minute |
| 4 | Month (0 for every month) |
| 5 | Day (0 for every day) |
| 6->13 | Label, unpacked |
| 14 | 1 if audible, otherwise 0 |
### 0x70 - SALARM
Didn't know what to call this. Sent after silent alarms
| Byte | Description |
| ---- | ---------------------------------- |
| 1 | Always 0 |
| 2 | ID of preceding alarm + 0x61 |
| 3 | Always 0 |
### 0x21 - END2
No payload
+6 -56
View File
@@ -33,28 +33,15 @@ the first sync bytes sent). After "U" is received, all bytes are sent
over the IR LED. To get back to the initial state, device power must be
cycled. This is done by pulling CTS low for a few hundred milliseconds.
Since I do not have access to an actual adapter, I have no way of
verifying the timings of the device. It's a safe bet, though, that they
will be very similar to those from the CRT.
A one is indicated by the absence of a pulse, a zero is a pulse of about
32 µs. Pulses are sent at an interval of approximately 480 µs, with some
jitter. Some configuration files mentioned 2048 baud, which would mean
approximately 488 µs. So this sort of makes sense.
Bytes are sent least significant bit first, one start bit, no stop bit.
This means the byte 0x5a would look like pnpnppnpn (where p indicates
a pulse, and n the absence of a pulse).
There are some requirements on both the spacing between bytes, and the
spacing between packages. Using the Notebook Adapter and original
software, this is done by the PC and the adapter just naively sends the
data along. Byte spacing seems to be on the order of 2 ms and package
spacing on the order of 240 ms.
When a byte is sent to the adapter, it replies with the same byte. I'm
assuming it's done to keep things in sync.
Since I do not have access to an actual adapter, I have no way of
verifying the timings of the device. It's a safe bet, though, that they
will be very similar to those from the CRT. It is also possible the
data could be sent somewhat faster since it does not need to be phase
locked to the CRT refresh.
## The Blaster
@@ -77,40 +64,3 @@ others. Connect an IR LED to pin 12 with a suitable resistor in series
and you're golden. Experiment with distance and LED frequency to get it
just right. Some LEDs are very focused and offers only a narrow beam, so
if you have the option, try to find one with a wide beam.
## Additions/corrections to the github document
Start package contains 0x00 0x00 0x01 for the original Data Link (70?),
but for model 150 it contains 0x00 0x00 0x03, and for 150s it contains
0x00 0x00 0x04.
```
zero or more packet type TIME 0x30
byte 1 - timezone (the watch has two timezones, 1 or 2)
byte 2 - hour
byte 3 - minute
byte 4 - month
byte 5 - day of month
byte 6 - year (last 2 digits)
byte 7 - day of week (0=monday, 6=sunday)
byte 8 - Pretty certain this is seconds
byte 9 - 12h format (1) or 24h format (2)
one package type 0x31 for each time zone - TZNAME
Contains names of timezones, unpacked, timex charset
byte 1 - Time zone number (1 or 2)
byte 2-4 - Name of time zone (e.g. 0x0e 0x1c 0x1d for EST)
```
Checksum seems to be CRC-16/ARC.
For appointment packets, time is indicated in quarters of an hour since
midnight, if that makes more sense. So for instance 08:45 would be
8*4+3=35 quarters.
For the 150 models, the protocol seems slightly different. For instance,
there is a 0x32 package for sending time, combining the 0x30 and 0x31
packets. Also, the 0x70 packet sent after inaudible alarms is omitted.
There might be more differences I've yet to uncover. Also proocol for
apps and sounds are yet to be documented.