xref: /OK3568_Linux_fs/kernel/Documentation/driver-api/pps.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun======================
4*4882a593SmuzhiyunPPS - Pulse Per Second
5*4882a593Smuzhiyun======================
6*4882a593Smuzhiyun
7*4882a593SmuzhiyunCopyright (C) 2007 Rodolfo Giometti <giometti@enneenne.com>
8*4882a593Smuzhiyun
9*4882a593SmuzhiyunThis program is free software; you can redistribute it and/or modify
10*4882a593Smuzhiyunit under the terms of the GNU General Public License as published by
11*4882a593Smuzhiyunthe Free Software Foundation; either version 2 of the License, or
12*4882a593Smuzhiyun(at your option) any later version.
13*4882a593Smuzhiyun
14*4882a593SmuzhiyunThis program is distributed in the hope that it will be useful,
15*4882a593Smuzhiyunbut WITHOUT ANY WARRANTY; without even the implied warranty of
16*4882a593SmuzhiyunMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17*4882a593SmuzhiyunGNU General Public License for more details.
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun
21*4882a593SmuzhiyunOverview
22*4882a593Smuzhiyun--------
23*4882a593Smuzhiyun
24*4882a593SmuzhiyunLinuxPPS provides a programming interface (API) to define in the
25*4882a593Smuzhiyunsystem several PPS sources.
26*4882a593Smuzhiyun
27*4882a593SmuzhiyunPPS means "pulse per second" and a PPS source is just a device which
28*4882a593Smuzhiyunprovides a high precision signal each second so that an application
29*4882a593Smuzhiyuncan use it to adjust system clock time.
30*4882a593Smuzhiyun
31*4882a593SmuzhiyunA PPS source can be connected to a serial port (usually to the Data
32*4882a593SmuzhiyunCarrier Detect pin) or to a parallel port (ACK-pin) or to a special
33*4882a593SmuzhiyunCPU's GPIOs (this is the common case in embedded systems) but in each
34*4882a593Smuzhiyuncase when a new pulse arrives the system must apply to it a timestamp
35*4882a593Smuzhiyunand record it for userland.
36*4882a593Smuzhiyun
37*4882a593SmuzhiyunCommon use is the combination of the NTPD as userland program, with a
38*4882a593SmuzhiyunGPS receiver as PPS source, to obtain a wallclock-time with
39*4882a593Smuzhiyunsub-millisecond synchronisation to UTC.
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun
42*4882a593SmuzhiyunRFC considerations
43*4882a593Smuzhiyun------------------
44*4882a593Smuzhiyun
45*4882a593SmuzhiyunWhile implementing a PPS API as RFC 2783 defines and using an embedded
46*4882a593SmuzhiyunCPU GPIO-Pin as physical link to the signal, I encountered a deeper
47*4882a593Smuzhiyunproblem:
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun   At startup it needs a file descriptor as argument for the function
50*4882a593Smuzhiyun   time_pps_create().
51*4882a593Smuzhiyun
52*4882a593SmuzhiyunThis implies that the source has a /dev/... entry. This assumption is
53*4882a593SmuzhiyunOK for the serial and parallel port, where you can do something
54*4882a593Smuzhiyunuseful besides(!) the gathering of timestamps as it is the central
55*4882a593Smuzhiyuntask for a PPS API. But this assumption does not work for a single
56*4882a593Smuzhiyunpurpose GPIO line. In this case even basic file-related functionality
57*4882a593Smuzhiyun(like read() and write()) makes no sense at all and should not be a
58*4882a593Smuzhiyunprecondition for the use of a PPS API.
59*4882a593Smuzhiyun
60*4882a593SmuzhiyunThe problem can be simply solved if you consider that a PPS source is
61*4882a593Smuzhiyunnot always connected with a GPS data source.
62*4882a593Smuzhiyun
63*4882a593SmuzhiyunSo your programs should check if the GPS data source (the serial port
64*4882a593Smuzhiyunfor instance) is a PPS source too, and if not they should provide the
65*4882a593Smuzhiyunpossibility to open another device as PPS source.
66*4882a593Smuzhiyun
67*4882a593SmuzhiyunIn LinuxPPS the PPS sources are simply char devices usually mapped
68*4882a593Smuzhiyuninto files /dev/pps0, /dev/pps1, etc.
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun
71*4882a593SmuzhiyunPPS with USB to serial devices
72*4882a593Smuzhiyun------------------------------
73*4882a593Smuzhiyun
74*4882a593SmuzhiyunIt is possible to grab the PPS from an USB to serial device. However,
75*4882a593Smuzhiyunyou should take into account the latencies and jitter introduced by
76*4882a593Smuzhiyunthe USB stack. Users have reported clock instability around +-1ms when
77*4882a593Smuzhiyunsynchronized with PPS through USB. With USB 2.0, jitter may decrease
78*4882a593Smuzhiyundown to the order of 125 microseconds.
79*4882a593Smuzhiyun
80*4882a593SmuzhiyunThis may be suitable for time server synchronization with NTP because
81*4882a593Smuzhiyunof its undersampling and algorithms.
82*4882a593Smuzhiyun
83*4882a593SmuzhiyunIf your device doesn't report PPS, you can check that the feature is
84*4882a593Smuzhiyunsupported by its driver. Most of the time, you only need to add a call
85*4882a593Smuzhiyunto usb_serial_handle_dcd_change after checking the DCD status (see
86*4882a593Smuzhiyunch341 and pl2303 examples).
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun
89*4882a593SmuzhiyunCoding example
90*4882a593Smuzhiyun--------------
91*4882a593Smuzhiyun
92*4882a593SmuzhiyunTo register a PPS source into the kernel you should define a struct
93*4882a593Smuzhiyunpps_source_info as follows::
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun    static struct pps_source_info pps_ktimer_info = {
96*4882a593Smuzhiyun	    .name         = "ktimer",
97*4882a593Smuzhiyun	    .path         = "",
98*4882a593Smuzhiyun	    .mode         = PPS_CAPTUREASSERT | PPS_OFFSETASSERT |
99*4882a593Smuzhiyun			    PPS_ECHOASSERT |
100*4882a593Smuzhiyun			    PPS_CANWAIT | PPS_TSFMT_TSPEC,
101*4882a593Smuzhiyun	    .echo         = pps_ktimer_echo,
102*4882a593Smuzhiyun	    .owner        = THIS_MODULE,
103*4882a593Smuzhiyun    };
104*4882a593Smuzhiyun
105*4882a593Smuzhiyunand then calling the function pps_register_source() in your
106*4882a593Smuzhiyuninitialization routine as follows::
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun    source = pps_register_source(&pps_ktimer_info,
109*4882a593Smuzhiyun			PPS_CAPTUREASSERT | PPS_OFFSETASSERT);
110*4882a593Smuzhiyun
111*4882a593SmuzhiyunThe pps_register_source() prototype is::
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun  int pps_register_source(struct pps_source_info *info, int default_params)
114*4882a593Smuzhiyun
115*4882a593Smuzhiyunwhere "info" is a pointer to a structure that describes a particular
116*4882a593SmuzhiyunPPS source, "default_params" tells the system what the initial default
117*4882a593Smuzhiyunparameters for the device should be (it is obvious that these parameters
118*4882a593Smuzhiyunmust be a subset of ones defined in the struct
119*4882a593Smuzhiyunpps_source_info which describe the capabilities of the driver).
120*4882a593Smuzhiyun
121*4882a593SmuzhiyunOnce you have registered a new PPS source into the system you can
122*4882a593Smuzhiyunsignal an assert event (for example in the interrupt handler routine)
123*4882a593Smuzhiyunjust using::
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun    pps_event(source, &ts, PPS_CAPTUREASSERT, ptr)
126*4882a593Smuzhiyun
127*4882a593Smuzhiyunwhere "ts" is the event's timestamp.
128*4882a593Smuzhiyun
129*4882a593SmuzhiyunThe same function may also run the defined echo function
130*4882a593Smuzhiyun(pps_ktimer_echo(), passing to it the "ptr" pointer) if the user
131*4882a593Smuzhiyunasked for that... etc..
132*4882a593Smuzhiyun
133*4882a593SmuzhiyunPlease see the file drivers/pps/clients/pps-ktimer.c for example code.
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun
136*4882a593SmuzhiyunSYSFS support
137*4882a593Smuzhiyun-------------
138*4882a593Smuzhiyun
139*4882a593SmuzhiyunIf the SYSFS filesystem is enabled in the kernel it provides a new class::
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun   $ ls /sys/class/pps/
142*4882a593Smuzhiyun   pps0/  pps1/  pps2/
143*4882a593Smuzhiyun
144*4882a593SmuzhiyunEvery directory is the ID of a PPS sources defined in the system and
145*4882a593Smuzhiyuninside you find several files::
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun   $ ls -F /sys/class/pps/pps0/
148*4882a593Smuzhiyun   assert     dev        mode       path       subsystem@
149*4882a593Smuzhiyun   clear      echo       name       power/     uevent
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun
152*4882a593SmuzhiyunInside each "assert" and "clear" file you can find the timestamp and a
153*4882a593Smuzhiyunsequence number::
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun   $ cat /sys/class/pps/pps0/assert
156*4882a593Smuzhiyun   1170026870.983207967#8
157*4882a593Smuzhiyun
158*4882a593SmuzhiyunWhere before the "#" is the timestamp in seconds; after it is the
159*4882a593Smuzhiyunsequence number. Other files are:
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun * echo: reports if the PPS source has an echo function or not;
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun * mode: reports available PPS functioning modes;
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun * name: reports the PPS source's name;
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun * path: reports the PPS source's device path, that is the device the
168*4882a593Smuzhiyun   PPS source is connected to (if it exists).
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun
171*4882a593SmuzhiyunTesting the PPS support
172*4882a593Smuzhiyun-----------------------
173*4882a593Smuzhiyun
174*4882a593SmuzhiyunIn order to test the PPS support even without specific hardware you can use
175*4882a593Smuzhiyunthe pps-ktimer driver (see the client subsection in the PPS configuration menu)
176*4882a593Smuzhiyunand the userland tools available in your distribution's pps-tools package,
177*4882a593Smuzhiyunhttp://linuxpps.org , or https://github.com/redlab-i/pps-tools.
178*4882a593Smuzhiyun
179*4882a593SmuzhiyunOnce you have enabled the compilation of pps-ktimer just modprobe it (if
180*4882a593Smuzhiyunnot statically compiled)::
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun   # modprobe pps-ktimer
183*4882a593Smuzhiyun
184*4882a593Smuzhiyunand the run ppstest as follow::
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun   $ ./ppstest /dev/pps1
187*4882a593Smuzhiyun   trying PPS source "/dev/pps1"
188*4882a593Smuzhiyun   found PPS source "/dev/pps1"
189*4882a593Smuzhiyun   ok, found 1 source(s), now start fetching data...
190*4882a593Smuzhiyun   source 0 - assert 1186592699.388832443, sequence: 364 - clear  0.000000000, sequence: 0
191*4882a593Smuzhiyun   source 0 - assert 1186592700.388931295, sequence: 365 - clear  0.000000000, sequence: 0
192*4882a593Smuzhiyun   source 0 - assert 1186592701.389032765, sequence: 366 - clear  0.000000000, sequence: 0
193*4882a593Smuzhiyun
194*4882a593SmuzhiyunPlease note that to compile userland programs, you need the file timepps.h.
195*4882a593SmuzhiyunThis is available in the pps-tools repository mentioned above.
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun
198*4882a593SmuzhiyunGenerators
199*4882a593Smuzhiyun----------
200*4882a593Smuzhiyun
201*4882a593SmuzhiyunSometimes one needs to be able not only to catch PPS signals but to produce
202*4882a593Smuzhiyunthem also. For example, running a distributed simulation, which requires
203*4882a593Smuzhiyuncomputers' clock to be synchronized very tightly. One way to do this is to
204*4882a593Smuzhiyuninvent some complicated hardware solutions but it may be neither necessary
205*4882a593Smuzhiyunnor affordable. The cheap way is to load a PPS generator on one of the
206*4882a593Smuzhiyuncomputers (master) and PPS clients on others (slaves), and use very simple
207*4882a593Smuzhiyuncables to deliver signals using parallel ports, for example.
208*4882a593Smuzhiyun
209*4882a593SmuzhiyunParallel port cable pinout::
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun	pin	name	master      slave
212*4882a593Smuzhiyun	1	STROBE	  *------     *
213*4882a593Smuzhiyun	2	D0	  *     |     *
214*4882a593Smuzhiyun	3	D1	  *     |     *
215*4882a593Smuzhiyun	4	D2	  *     |     *
216*4882a593Smuzhiyun	5	D3	  *     |     *
217*4882a593Smuzhiyun	6	D4	  *     |     *
218*4882a593Smuzhiyun	7	D5	  *     |     *
219*4882a593Smuzhiyun	8	D6	  *     |     *
220*4882a593Smuzhiyun	9	D7	  *     |     *
221*4882a593Smuzhiyun	10	ACK	  *     ------*
222*4882a593Smuzhiyun	11	BUSY	  *           *
223*4882a593Smuzhiyun	12	PE	  *           *
224*4882a593Smuzhiyun	13	SEL	  *           *
225*4882a593Smuzhiyun	14	AUTOFD	  *           *
226*4882a593Smuzhiyun	15	ERROR	  *           *
227*4882a593Smuzhiyun	16	INIT	  *           *
228*4882a593Smuzhiyun	17	SELIN	  *           *
229*4882a593Smuzhiyun	18-25	GND	  *-----------*
230*4882a593Smuzhiyun
231*4882a593SmuzhiyunPlease note that parallel port interrupt occurs only on high->low transition,
232*4882a593Smuzhiyunso it is used for PPS assert edge. PPS clear edge can be determined only
233*4882a593Smuzhiyunusing polling in the interrupt handler which actually can be done way more
234*4882a593Smuzhiyunprecisely because interrupt handling delays can be quite big and random. So
235*4882a593Smuzhiyuncurrent parport PPS generator implementation (pps_gen_parport module) is
236*4882a593Smuzhiyungeared towards using the clear edge for time synchronization.
237*4882a593Smuzhiyun
238*4882a593SmuzhiyunClear edge polling is done with disabled interrupts so it's better to select
239*4882a593Smuzhiyundelay between assert and clear edge as small as possible to reduce system
240*4882a593Smuzhiyunlatencies. But if it is too small slave won't be able to capture clear edge
241*4882a593Smuzhiyuntransition. The default of 30us should be good enough in most situations.
242*4882a593SmuzhiyunThe delay can be selected using 'delay' pps_gen_parport module parameter.
243