PC-Funkuhr at printerport
=========================


Description
-----------
At Conrad electronic you can buy a relatively cheap DCF77 clock named
PC-Funkuhr. Its only drawback is that there is no support for Linux. For this
reason I built the pcf77-software.

Unfortunately there is no possibility for a user process in a non-realtime OS
like Linux to achieve timing values which are needed to read out the
PC-Funkuhr. At least I didn't succeed getting a resolution in the order of a
millisecond. 

For this reason you need two parts to read the clock: a kernel-process which
performs the low-level tasks and a user-process that converts the data read
into normal time values. In addition, the user-process may perform some other
tasks (user interface, setting system clock, checking signal quality). (Please
note that I use an ioctl-command to interface between kernel- and
user-process. Its value, LPPCFTIMER, is not an official one. I hope there are
no other ioctl's in future that want to use this value.)

Using a kernel-modul to read the clock basically has an other advantage: Also
non-Intel PCs are, in principle, able to use the PC-Funkuhr. Since I don't
have such hardware to test and adapt the software, this is just a theoretical
advantage, up to now.

You may ask whether I patch the lp-driver instead of building a special
PARPORT-driver (for kernel 2.2.X). The reason is that the clock is built into a
Centronics-printer-cable which only can get connected to a printer. So, it
looks like the printer has a built-in clock and therefor the lp-driver is the
right place to talk to it. 

Back to the above mentioned two program parts: pcf77 talks to the
patched lp-driver and translates the time information into a format which can
be used further. Normally, it prints the time read from the PC-Funkuhr to
stdout. pcf77 must be told to which port the clock is connected. It's
also possible to ask pcf77 to check all printer-ports using the -a
option. 

As user root it is possible to set the system time to the DCF time. You can
choose whether to set time immediately (using the -S option) or to smoothly
adjust system time to achieve a strictly forthgoing time (using the -s option,
which only works if your system time does not differ more than 20 seconds 
from DCF time). The option -t is the same as -s (and -T the same as -S), but
with these two options the system clock is not set to the PC-Funkuhr time if
it had trouble receiving the radio signal the night before. If the
quartz-clock in your Funkuhr is of minor quality you might prefer using the
-t/-T pair instead of -s/-S.

I tried to implement a simple quality check of the DCF signal
strength. Unfortunately I don't know very much about the DCF signal protocol, 
but the result is likely the same as with the original DOS-Software. Therefor
I decided to offer this feature with pcf77. The output in quality-check
mode looks very simple but it does its job.


In addition, here is the usage message of the program:

usage: pcf77 [options] [+FORMAT]
   reads timer information of DCF77-Clock ("PC-Funkuhr") at printer port,
   needs an appropriate patched lp-kernel-module.
   See date(1) for a description of the FORMAT-string.
options:
   -a       : autoprobe lp devices
   -c       : check quality of DCF77 radio signal
   -D       : print out difference between system and DCF time
   -h, -?   : prints this usage-message
   -m       : mail problems with the "PC-Funkuhr" to addr
   -p       : Printer Port (default: /dev/lp1)
   -q       : quiet, don't print time read from clock
   -s       : set system clock "smoothly",
              if time-difference is less than 20 seconds
   -S       : set system clock immediately
   -t       : same as -s, don't set time if "PC-Funkuhr"
              had problems receiving radio signal
   -T       : same as -S, don't set time if "PC-Funkuhr"
              had problems receiving radio signal
   -v       : print version and exit


Attention
---------
There is absolutely no guarantee, that no part of your hardware (computer,
PC-Funkuhr, printer) gets damaged if you use the programs. You will run
pcf77 and the kernel-patches completely at your own risk. 



Installation
------------
1. unpack the package into [destdir]

2. patch kernel. Change to your kernel source path (may be
/usr/src/linux). There, you type (as root):
patch -p0 < [destdir]/pcf77-0.9.2/pcf77.linux-2.6.8.diff
(Kernel >=2.2.5:) make config (choose PCF support, lp-driver as a module)
make modules
make modules_install

You should compile the printer-driver as a module, because then you
don't need to rebuild the whole kernel.


3. cd [destdir]/pcf77-0.9.2
(check for STDPORT in pcf77.h)
make
(if LPPCFTIMER is undefined, you have to copy
/usr/src/linux/include/lp.h to /usr/include/linux/lp.h!)

test it with "./pcf77 -p portname" - please note, that the printer-port
must be read/writeable; if ok, type:

make install
make install_man

4. If you want to read the time from PC-Funkuhr at boot time you have to modify
/etc/rc.d/boot (S.u.S.E., with other distributions one has to look for these
rc-files that read the hardware clock of the machine.) The following three
lines can be included _behind_ the existing hardware clock entries (please use
your port):
# read DCF clock and set system and hardware clock, send mail to root
/usr/local/bin/pcf77 -q -S -p /dev/lp2 -m root
test $? -eq 0 && hwclock --systohc

5. Having an unprecisely working system clock you may add a cron-job for root
such like this (please use your port):
31 * * * *      /usr/bin/pcf77 -s -p /dev/lp2 -m root

6. With a kernel built with the parport-driver you must ensure that
the port with your PC-Funkuhr attached to is enabled. See /etc/modules.conf
and edit the line "options parport..." if needed.

Tested configurations
-------------------------
See file TESTED.

Known Bugs
----------
A call of pcf77 at 23:59:59 on the last day of month may lead to errors
when setting system time. I didn't check time zones (does PC-Funkuhr run
outside Mid-Europe??). I think that, outside of ME(S)T, pcf77 will not
produce correct results.

I don't expect a Y2K problem with the PC-Funkuhr. However, the clock just
transmits a two-digit year so one is forced to arbitrary decide which century
it is. At present, the century-switch is hard-coded to be at a value of 90.
With just one compile-run per century (:-)) you always be able to adjust
this limit. 

There are systems with which reading the PC-Funkuhr only works if the printer
is switched off or even no printer is attached to the system via the
PC-Funkuhr. The reason for this possibly is the cabling or the protocol of the
PC-Funkuhr. If the clock is running well with DOS/Windows while there are
problems under Linux using pcf77, please drop a note!

Up to version 0.7.1 there was a bug when smoothly adjusting system time with
the -s option. Thanks to Philippe in Paris this bug could be fixed.

Contact
-------
matthias@familie-schuetze.de
If you (have to) change the code of pcf77, please drop a note.

Copyright
---------
GPL



Have a good - precise time,

             Matthias Schütze                          29 Mar 06