The watch was originally introduced in 1995 (I think), and had some very interesting and unique features at the time. It was the third iteration of the Timex Datalink line, after Datalink 50 and Datalink 70. The line of watches were able to store phone numbers, appointments, to-do lists, anniversaries and alarms. The number (50, 70, 150) in the Datalink line model numbers referred to the approximate amount of phone numbers the watch could store. Compared with the older Datalink 70 model, the Datalink 150 doubled the amount of EEPROM available for the data (from 1kB to 2kB), but also added support for what Timex called wristapps.
The wristapps were small pieces of software, which were loaded in the RAM of the watch, and which could actually be executed. This allowed extending the features of the watch, such as adding a stopwatch or a countdown timer mode. A number of wristapps were delivered with the watch, but Timex also sold additional ones. The wristapp was stored always in a fixed location in RAM, so only one wristapp could ever be loaded at one time. Also, there was only 804 bytes total in the user RAM area, which was also shared by the melody configuration. The melody defined what the watch beeps sounded like (alarm, appointment notification, etc). With the default melody, the maximum wristapp size was about 760 bytes.
The data were transmitted to the watch optically by pointing the watch at a CRT monitor of a PC and running a proprietary piece of software (on Windows), which displayed a flashing line pattern representing the data to be transmitted. The watch would receive the data through a photodetector eye located in the watch face.
A CRT really is required, as the upload process exploits the raster scanning of the CRT to cause sudden changes in brightness. Active matrix LCDs don't scan, and would be too slow anyway. However, LCD monitors were not unheard of even at that time (in laptop computers), and Timex sold a separate notebook adapter to allow using the watches with laptop computers. The notebook adapter connected to the serial port of the computer, and used a flashing LED to transfer the data.
Trying to use the watch these days is quite difficult. A CRT is hard to come by, and even if you had one, the software doesn't run on modern version of Windows (i.e. XP or later). The software does work in some versions of NT, but only with the notebook adapter, which appears to be quite expensive today. Finally, the closed source nature of the software isn't ideal either.
Between 1996 and 2002, Tommy Johnson, Karl R. Hakimian, David Fries, Frank Denis, Steaphan Greene, Harold Zatz (and possibly others) reverse engineered the watch transfer protocol and wrote an open source implementation of the data transferring software, called simply datalink. This work is the most important piece in using the watch with modern computers. This work is available on GitHub.
The open source datalink software has three methods for getting the data to the watch. There is an SVGAlib based CRT flasher for Linux PCs, an OpenGL based CRT flasher for SGI machines and a RS232 UART based LED flasher for Unixlike OSs. None of these really work with modern machines, unfortunately. The first two fail due to the requirement of a CRT (not sure if svgalib still works either). The LED flasher requires an RS232 port, which is also quite rare. Although it might still be possible to use that approach with a USB based RS232 adapter.
Clearly flashing an LED was the way to go. However, I wanted to offload the timing generation to external hardware instead of essentially bit-banging it as the datalink software LED flasher does. This called for a microcontroller, which would at least partially understand the transfer protocol.
I wanted to be sure of the correct timing in the data framing. For this purpose, I installed the original Timex Datalink software on a Windows 95 virtual machine, and took screenshots of the output it was producing. Since the software used the standard 640x480 VGA modeline, I could determine the row numbers on which the output was produced to determine the proper timing to use with the LED.
Sync frame containing bytes 0x55 0x55 as sent by the Datalink software on Windows 95 |
The way the transmission works is the following:
- A frame may contain zero, one or two bytes.
- Bits are transmitted least significant bit first (the order in the raster scan: top to bottom)
- A bit value 0 is transmitted as a white line, a bit value 1 is transmitted as a black line.
- Transmission of the first byte is started by a white line on row 79 (1-indexed)
- The bits of the first byte follow on lines 94, 109, 124, 140, 155, 171, 186, 202 (1-indexed)
- Transmission of the second byte is started by a white line on row 264 (1-indexed)
- The bits of the second byte follow on lines 279, 295, 310, 326, 341, 357, 372, 388 (1-indexed)
- If only one byte is transferred in the frame, it is in the place of the first byte.
- When zero bytes are transferred in the frame, the frame is entirely blank.
The 640x480 VGA timing is such that each row takes 31.778 us, of which the visible part takes 25.422 us. The bits follow each other with an average bit period of 15.45 rows, which equals about 491 us. When the bit is a 0, the signal is asserted for the entire visible part of the row, i.e. for 25.422 us.
The gap between the bytes is almost exactly 3 bit periods. Thus from the start of the first byte to the end of the second byte, there are a total of 21 bit periods, i.e. 10.310 ms. A full frame takes 16.683 ms, which means that there is an additional delay of 6.373 ms between the end of the second byte of a frame and the beginning of the first byte of the next frame.
Rounding and consolidating the numbers give for example the following practical framing scheme, which is within the margins accepted by the watch:
- Bit period 490us
- Value 0: 30us signal asserted, followed by 460us signal deasserted
- Value 1: 490us signal deasserted
- A frame has exactly 34 bit periods, and consists of the following bits
- Start bit of first byte (sent as value 0 if at least one byte in this frame)
- Bit 0 of first byte
- Bit 1 of first byte
- Bit 2 of first byte
- Bit 3 of first byte
- Bit 4 of first byte
- Bit 5 of first byte
- Bit 6 of first byte
- Bit 7 of first byte
- Dummy bit (always sent as value 1)
- Dummy bit (always sent as value 1)
- Dummy bit (always sent as value 1)
- Start bit of second byte (sent as value 0 if two bytes in this frame)
- Bit 0 of second byte
- Bit 1 of second byte
- Bit 2 of second byte
- Bit 3 of second byte
- Bit 4 of second byte
- Bit 5 of second byte
- Bit 6 of second byte
- Bit 7 of second byte
- Dummy bit (always sent as value 1)
- Dummy bit (always sent as value 1)
- Dummy bit (always sent as value 1)
- Dummy bit (always sent as value 1)
- Dummy bit (always sent as value 1)
- Dummy bit (always sent as value 1)
- Dummy bit (always sent as value 1)
- Dummy bit (always sent as value 1)
- Dummy bit (always sent as value 1)
- Dummy bit (always sent as value 1)
- Dummy bit (always sent as value 1)
- Dummy bit (always sent as value 1)
- Dummy bit (always sent as value 1)
To initialize data transmission, the watch must receive a number of preamble frames containing the bytes 0x55,0x55. This makes the watch sync to the stream and start beeping. Then, right before actual data transmission starts, about 25 start of transmission frames, containing the bytes 0xaa,0xaa, are transmitted. I'm not sure of the exact number required, but 25 seems to work well. The actual data transmission then starts.
The data is transmitted in packets. Each packet begins with a byte describing the length of the packet in bytes and ends with two CRC bytes. The transmitted length value includes the CRC bytes and the length byte itself. After each packet, a few empty frames (about 10, but again exact number not known) must be transmitted, during which the watch accepts the previous data and emits a beep. An empty frame is one with no data bytes, and thus is a blank screen. The CRC bytes are already calculated by the datalink utility, so the uploader only needs to understand the packet length to add the empty frames after each packet.
To further understand the data format itself, John Toebes has a description of the download protocol and the packet formats. Though I'm not sure if he's correct about the sync bits part. Toebes is also the author of the assembler for these devices, and his site is the best all-round resource regarding the watches. Even more detail is found in the source code of the datalink utility.
I hacked an implementation together using an STM32 BluePill board (STM32F103C8 uC). Since code space or efficiency were not critical, I used FreeRTOS to make the software a bit faster to develop. You can find my implementation on GitHub. The project uses the uC USB capability for receiving the data, presenting as a USB CDC device. It then blinks an LED connected to PB9.
Datalink uploader |
No comments:
Post a Comment