xref: /linux/Documentation/driver-api/pps.rst (revision 0ea5c948cb64bab5bc7a5516774eb8536f05aa0d)
1c92992fcSMauro Carvalho Chehab.. SPDX-License-Identifier: GPL-2.0
228aedd7eSMauro Carvalho Chehab
328aedd7eSMauro Carvalho Chehab======================
428aedd7eSMauro Carvalho ChehabPPS - Pulse Per Second
528aedd7eSMauro Carvalho Chehab======================
628aedd7eSMauro Carvalho Chehab
728aedd7eSMauro Carvalho ChehabCopyright (C) 2007 Rodolfo Giometti <giometti@enneenne.com>
828aedd7eSMauro Carvalho Chehab
928aedd7eSMauro Carvalho ChehabThis program is free software; you can redistribute it and/or modify
1028aedd7eSMauro Carvalho Chehabit under the terms of the GNU General Public License as published by
1128aedd7eSMauro Carvalho Chehabthe Free Software Foundation; either version 2 of the License, or
1228aedd7eSMauro Carvalho Chehab(at your option) any later version.
1328aedd7eSMauro Carvalho Chehab
1428aedd7eSMauro Carvalho ChehabThis program is distributed in the hope that it will be useful,
1528aedd7eSMauro Carvalho Chehabbut WITHOUT ANY WARRANTY; without even the implied warranty of
1628aedd7eSMauro Carvalho ChehabMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1728aedd7eSMauro Carvalho ChehabGNU General Public License for more details.
1828aedd7eSMauro Carvalho Chehab
1928aedd7eSMauro Carvalho Chehab
2028aedd7eSMauro Carvalho Chehab
2128aedd7eSMauro Carvalho ChehabOverview
2228aedd7eSMauro Carvalho Chehab--------
2328aedd7eSMauro Carvalho Chehab
2428aedd7eSMauro Carvalho ChehabLinuxPPS provides a programming interface (API) to define in the
2528aedd7eSMauro Carvalho Chehabsystem several PPS sources.
2628aedd7eSMauro Carvalho Chehab
2728aedd7eSMauro Carvalho ChehabPPS means "pulse per second" and a PPS source is just a device which
2828aedd7eSMauro Carvalho Chehabprovides a high precision signal each second so that an application
2928aedd7eSMauro Carvalho Chehabcan use it to adjust system clock time.
3028aedd7eSMauro Carvalho Chehab
3128aedd7eSMauro Carvalho ChehabA PPS source can be connected to a serial port (usually to the Data
3228aedd7eSMauro Carvalho ChehabCarrier Detect pin) or to a parallel port (ACK-pin) or to a special
3328aedd7eSMauro Carvalho ChehabCPU's GPIOs (this is the common case in embedded systems) but in each
3428aedd7eSMauro Carvalho Chehabcase when a new pulse arrives the system must apply to it a timestamp
3528aedd7eSMauro Carvalho Chehaband record it for userland.
3628aedd7eSMauro Carvalho Chehab
3728aedd7eSMauro Carvalho ChehabCommon use is the combination of the NTPD as userland program, with a
3828aedd7eSMauro Carvalho ChehabGPS receiver as PPS source, to obtain a wallclock-time with
3928aedd7eSMauro Carvalho Chehabsub-millisecond synchronisation to UTC.
4028aedd7eSMauro Carvalho Chehab
4128aedd7eSMauro Carvalho Chehab
4228aedd7eSMauro Carvalho ChehabRFC considerations
4328aedd7eSMauro Carvalho Chehab------------------
4428aedd7eSMauro Carvalho Chehab
4528aedd7eSMauro Carvalho ChehabWhile implementing a PPS API as RFC 2783 defines and using an embedded
4628aedd7eSMauro Carvalho ChehabCPU GPIO-Pin as physical link to the signal, I encountered a deeper
4728aedd7eSMauro Carvalho Chehabproblem:
4828aedd7eSMauro Carvalho Chehab
4928aedd7eSMauro Carvalho Chehab   At startup it needs a file descriptor as argument for the function
5028aedd7eSMauro Carvalho Chehab   time_pps_create().
5128aedd7eSMauro Carvalho Chehab
5228aedd7eSMauro Carvalho ChehabThis implies that the source has a /dev/... entry. This assumption is
5328aedd7eSMauro Carvalho ChehabOK for the serial and parallel port, where you can do something
5428aedd7eSMauro Carvalho Chehabuseful besides(!) the gathering of timestamps as it is the central
5528aedd7eSMauro Carvalho Chehabtask for a PPS API. But this assumption does not work for a single
5628aedd7eSMauro Carvalho Chehabpurpose GPIO line. In this case even basic file-related functionality
5728aedd7eSMauro Carvalho Chehab(like read() and write()) makes no sense at all and should not be a
5828aedd7eSMauro Carvalho Chehabprecondition for the use of a PPS API.
5928aedd7eSMauro Carvalho Chehab
6028aedd7eSMauro Carvalho ChehabThe problem can be simply solved if you consider that a PPS source is
6128aedd7eSMauro Carvalho Chehabnot always connected with a GPS data source.
6228aedd7eSMauro Carvalho Chehab
6328aedd7eSMauro Carvalho ChehabSo your programs should check if the GPS data source (the serial port
6428aedd7eSMauro Carvalho Chehabfor instance) is a PPS source too, and if not they should provide the
6528aedd7eSMauro Carvalho Chehabpossibility to open another device as PPS source.
6628aedd7eSMauro Carvalho Chehab
6728aedd7eSMauro Carvalho ChehabIn LinuxPPS the PPS sources are simply char devices usually mapped
6828aedd7eSMauro Carvalho Chehabinto files /dev/pps0, /dev/pps1, etc.
6928aedd7eSMauro Carvalho Chehab
7028aedd7eSMauro Carvalho Chehab
7128aedd7eSMauro Carvalho ChehabPPS with USB to serial devices
7228aedd7eSMauro Carvalho Chehab------------------------------
7328aedd7eSMauro Carvalho Chehab
7428aedd7eSMauro Carvalho ChehabIt is possible to grab the PPS from an USB to serial device. However,
7528aedd7eSMauro Carvalho Chehabyou should take into account the latencies and jitter introduced by
7628aedd7eSMauro Carvalho Chehabthe USB stack. Users have reported clock instability around +-1ms when
7728aedd7eSMauro Carvalho Chehabsynchronized with PPS through USB. With USB 2.0, jitter may decrease
7828aedd7eSMauro Carvalho Chehabdown to the order of 125 microseconds.
7928aedd7eSMauro Carvalho Chehab
8028aedd7eSMauro Carvalho ChehabThis may be suitable for time server synchronization with NTP because
8128aedd7eSMauro Carvalho Chehabof its undersampling and algorithms.
8228aedd7eSMauro Carvalho Chehab
8328aedd7eSMauro Carvalho ChehabIf your device doesn't report PPS, you can check that the feature is
8428aedd7eSMauro Carvalho Chehabsupported by its driver. Most of the time, you only need to add a call
8528aedd7eSMauro Carvalho Chehabto usb_serial_handle_dcd_change after checking the DCD status (see
8628aedd7eSMauro Carvalho Chehabch341 and pl2303 examples).
8728aedd7eSMauro Carvalho Chehab
8828aedd7eSMauro Carvalho Chehab
8928aedd7eSMauro Carvalho ChehabCoding example
9028aedd7eSMauro Carvalho Chehab--------------
9128aedd7eSMauro Carvalho Chehab
9228aedd7eSMauro Carvalho ChehabTo register a PPS source into the kernel you should define a struct
9328aedd7eSMauro Carvalho Chehabpps_source_info as follows::
9428aedd7eSMauro Carvalho Chehab
9528aedd7eSMauro Carvalho Chehab    static struct pps_source_info pps_ktimer_info = {
9628aedd7eSMauro Carvalho Chehab	    .name         = "ktimer",
9728aedd7eSMauro Carvalho Chehab	    .path         = "",
9828aedd7eSMauro Carvalho Chehab	    .mode         = PPS_CAPTUREASSERT | PPS_OFFSETASSERT |
9928aedd7eSMauro Carvalho Chehab			    PPS_ECHOASSERT |
10028aedd7eSMauro Carvalho Chehab			    PPS_CANWAIT | PPS_TSFMT_TSPEC,
10128aedd7eSMauro Carvalho Chehab	    .echo         = pps_ktimer_echo,
10228aedd7eSMauro Carvalho Chehab	    .owner        = THIS_MODULE,
10328aedd7eSMauro Carvalho Chehab    };
10428aedd7eSMauro Carvalho Chehab
10528aedd7eSMauro Carvalho Chehaband then calling the function pps_register_source() in your
10628aedd7eSMauro Carvalho Chehabinitialization routine as follows::
10728aedd7eSMauro Carvalho Chehab
10828aedd7eSMauro Carvalho Chehab    source = pps_register_source(&pps_ktimer_info,
10928aedd7eSMauro Carvalho Chehab			PPS_CAPTUREASSERT | PPS_OFFSETASSERT);
11028aedd7eSMauro Carvalho Chehab
11128aedd7eSMauro Carvalho ChehabThe pps_register_source() prototype is::
11228aedd7eSMauro Carvalho Chehab
11328aedd7eSMauro Carvalho Chehab  int pps_register_source(struct pps_source_info *info, int default_params)
11428aedd7eSMauro Carvalho Chehab
11528aedd7eSMauro Carvalho Chehabwhere "info" is a pointer to a structure that describes a particular
11628aedd7eSMauro Carvalho ChehabPPS source, "default_params" tells the system what the initial default
11728aedd7eSMauro Carvalho Chehabparameters for the device should be (it is obvious that these parameters
11828aedd7eSMauro Carvalho Chehabmust be a subset of ones defined in the struct
11928aedd7eSMauro Carvalho Chehabpps_source_info which describe the capabilities of the driver).
12028aedd7eSMauro Carvalho Chehab
12128aedd7eSMauro Carvalho ChehabOnce you have registered a new PPS source into the system you can
12228aedd7eSMauro Carvalho Chehabsignal an assert event (for example in the interrupt handler routine)
12328aedd7eSMauro Carvalho Chehabjust using::
12428aedd7eSMauro Carvalho Chehab
12528aedd7eSMauro Carvalho Chehab    pps_event(source, &ts, PPS_CAPTUREASSERT, ptr)
12628aedd7eSMauro Carvalho Chehab
12728aedd7eSMauro Carvalho Chehabwhere "ts" is the event's timestamp.
12828aedd7eSMauro Carvalho Chehab
12928aedd7eSMauro Carvalho ChehabThe same function may also run the defined echo function
13028aedd7eSMauro Carvalho Chehab(pps_ktimer_echo(), passing to it the "ptr" pointer) if the user
13128aedd7eSMauro Carvalho Chehabasked for that... etc..
13228aedd7eSMauro Carvalho Chehab
13328aedd7eSMauro Carvalho ChehabPlease see the file drivers/pps/clients/pps-ktimer.c for example code.
13428aedd7eSMauro Carvalho Chehab
13528aedd7eSMauro Carvalho Chehab
13628aedd7eSMauro Carvalho ChehabSYSFS support
13728aedd7eSMauro Carvalho Chehab-------------
13828aedd7eSMauro Carvalho Chehab
13928aedd7eSMauro Carvalho ChehabIf the SYSFS filesystem is enabled in the kernel it provides a new class::
14028aedd7eSMauro Carvalho Chehab
14128aedd7eSMauro Carvalho Chehab   $ ls /sys/class/pps/
14228aedd7eSMauro Carvalho Chehab   pps0/  pps1/  pps2/
14328aedd7eSMauro Carvalho Chehab
14428aedd7eSMauro Carvalho ChehabEvery directory is the ID of a PPS sources defined in the system and
14528aedd7eSMauro Carvalho Chehabinside you find several files::
14628aedd7eSMauro Carvalho Chehab
14728aedd7eSMauro Carvalho Chehab   $ ls -F /sys/class/pps/pps0/
14828aedd7eSMauro Carvalho Chehab   assert     dev        mode       path       subsystem@
14928aedd7eSMauro Carvalho Chehab   clear      echo       name       power/     uevent
15028aedd7eSMauro Carvalho Chehab
15128aedd7eSMauro Carvalho Chehab
15228aedd7eSMauro Carvalho ChehabInside each "assert" and "clear" file you can find the timestamp and a
15328aedd7eSMauro Carvalho Chehabsequence number::
15428aedd7eSMauro Carvalho Chehab
15528aedd7eSMauro Carvalho Chehab   $ cat /sys/class/pps/pps0/assert
15628aedd7eSMauro Carvalho Chehab   1170026870.983207967#8
15728aedd7eSMauro Carvalho Chehab
15828aedd7eSMauro Carvalho ChehabWhere before the "#" is the timestamp in seconds; after it is the
15928aedd7eSMauro Carvalho Chehabsequence number. Other files are:
16028aedd7eSMauro Carvalho Chehab
16128aedd7eSMauro Carvalho Chehab * echo: reports if the PPS source has an echo function or not;
16228aedd7eSMauro Carvalho Chehab
16328aedd7eSMauro Carvalho Chehab * mode: reports available PPS functioning modes;
16428aedd7eSMauro Carvalho Chehab
16528aedd7eSMauro Carvalho Chehab * name: reports the PPS source's name;
16628aedd7eSMauro Carvalho Chehab
16728aedd7eSMauro Carvalho Chehab * path: reports the PPS source's device path, that is the device the
16828aedd7eSMauro Carvalho Chehab   PPS source is connected to (if it exists).
16928aedd7eSMauro Carvalho Chehab
17028aedd7eSMauro Carvalho Chehab
17128aedd7eSMauro Carvalho ChehabTesting the PPS support
17228aedd7eSMauro Carvalho Chehab-----------------------
17328aedd7eSMauro Carvalho Chehab
17428aedd7eSMauro Carvalho ChehabIn order to test the PPS support even without specific hardware you can use
17528aedd7eSMauro Carvalho Chehabthe pps-ktimer driver (see the client subsection in the PPS configuration menu)
17628aedd7eSMauro Carvalho Chehaband the userland tools available in your distribution's pps-tools package,
17728aedd7eSMauro Carvalho Chehabhttp://linuxpps.org , or https://github.com/redlab-i/pps-tools.
17828aedd7eSMauro Carvalho Chehab
17928aedd7eSMauro Carvalho ChehabOnce you have enabled the compilation of pps-ktimer just modprobe it (if
18028aedd7eSMauro Carvalho Chehabnot statically compiled)::
18128aedd7eSMauro Carvalho Chehab
18228aedd7eSMauro Carvalho Chehab   # modprobe pps-ktimer
18328aedd7eSMauro Carvalho Chehab
18428aedd7eSMauro Carvalho Chehaband the run ppstest as follow::
18528aedd7eSMauro Carvalho Chehab
18628aedd7eSMauro Carvalho Chehab   $ ./ppstest /dev/pps1
18728aedd7eSMauro Carvalho Chehab   trying PPS source "/dev/pps1"
18828aedd7eSMauro Carvalho Chehab   found PPS source "/dev/pps1"
18928aedd7eSMauro Carvalho Chehab   ok, found 1 source(s), now start fetching data...
19028aedd7eSMauro Carvalho Chehab   source 0 - assert 1186592699.388832443, sequence: 364 - clear  0.000000000, sequence: 0
19128aedd7eSMauro Carvalho Chehab   source 0 - assert 1186592700.388931295, sequence: 365 - clear  0.000000000, sequence: 0
19228aedd7eSMauro Carvalho Chehab   source 0 - assert 1186592701.389032765, sequence: 366 - clear  0.000000000, sequence: 0
19328aedd7eSMauro Carvalho Chehab
19428aedd7eSMauro Carvalho ChehabPlease note that to compile userland programs, you need the file timepps.h.
19528aedd7eSMauro Carvalho ChehabThis is available in the pps-tools repository mentioned above.
19628aedd7eSMauro Carvalho Chehab
19728aedd7eSMauro Carvalho Chehab
19828aedd7eSMauro Carvalho ChehabGenerators
19928aedd7eSMauro Carvalho Chehab----------
20028aedd7eSMauro Carvalho Chehab
20128aedd7eSMauro Carvalho ChehabSometimes one needs to be able not only to catch PPS signals but to produce
20228aedd7eSMauro Carvalho Chehabthem also. For example, running a distributed simulation, which requires
203*55ed837dSPandith Ncomputers' clock to be synchronized very tightly.
204*55ed837dSPandith N
205*55ed837dSPandith N
206*55ed837dSPandith NParallel port generator
207*55ed837dSPandith N------------------------
208*55ed837dSPandith N
209*55ed837dSPandith NOne way to do this is to invent some complicated hardware solutions but it
210*55ed837dSPandith Nmay be neither necessary nor affordable. The cheap way is to load a PPS
211*55ed837dSPandith Ngenerator on one of the computers (master) and PPS clients on others
212*55ed837dSPandith N(slaves), and use very simple cables to deliver signals using parallel
213*55ed837dSPandith Nports, for example.
21428aedd7eSMauro Carvalho Chehab
21528aedd7eSMauro Carvalho ChehabParallel port cable pinout::
21628aedd7eSMauro Carvalho Chehab
21728aedd7eSMauro Carvalho Chehab	pin	name	master      slave
21828aedd7eSMauro Carvalho Chehab	1	STROBE	  *------     *
21928aedd7eSMauro Carvalho Chehab	2	D0	  *     |     *
22028aedd7eSMauro Carvalho Chehab	3	D1	  *     |     *
22128aedd7eSMauro Carvalho Chehab	4	D2	  *     |     *
22228aedd7eSMauro Carvalho Chehab	5	D3	  *     |     *
22328aedd7eSMauro Carvalho Chehab	6	D4	  *     |     *
22428aedd7eSMauro Carvalho Chehab	7	D5	  *     |     *
22528aedd7eSMauro Carvalho Chehab	8	D6	  *     |     *
22628aedd7eSMauro Carvalho Chehab	9	D7	  *     |     *
22728aedd7eSMauro Carvalho Chehab	10	ACK	  *     ------*
22828aedd7eSMauro Carvalho Chehab	11	BUSY	  *           *
22928aedd7eSMauro Carvalho Chehab	12	PE	  *           *
23028aedd7eSMauro Carvalho Chehab	13	SEL	  *           *
23128aedd7eSMauro Carvalho Chehab	14	AUTOFD	  *           *
23228aedd7eSMauro Carvalho Chehab	15	ERROR	  *           *
23328aedd7eSMauro Carvalho Chehab	16	INIT	  *           *
23428aedd7eSMauro Carvalho Chehab	17	SELIN	  *           *
23528aedd7eSMauro Carvalho Chehab	18-25	GND	  *-----------*
23628aedd7eSMauro Carvalho Chehab
23728aedd7eSMauro Carvalho ChehabPlease note that parallel port interrupt occurs only on high->low transition,
23828aedd7eSMauro Carvalho Chehabso it is used for PPS assert edge. PPS clear edge can be determined only
23928aedd7eSMauro Carvalho Chehabusing polling in the interrupt handler which actually can be done way more
24028aedd7eSMauro Carvalho Chehabprecisely because interrupt handling delays can be quite big and random. So
24128aedd7eSMauro Carvalho Chehabcurrent parport PPS generator implementation (pps_gen_parport module) is
24228aedd7eSMauro Carvalho Chehabgeared towards using the clear edge for time synchronization.
24328aedd7eSMauro Carvalho Chehab
24428aedd7eSMauro Carvalho ChehabClear edge polling is done with disabled interrupts so it's better to select
24528aedd7eSMauro Carvalho Chehabdelay between assert and clear edge as small as possible to reduce system
24628aedd7eSMauro Carvalho Chehablatencies. But if it is too small slave won't be able to capture clear edge
24728aedd7eSMauro Carvalho Chehabtransition. The default of 30us should be good enough in most situations.
24828aedd7eSMauro Carvalho ChehabThe delay can be selected using 'delay' pps_gen_parport module parameter.
249