PPSClockSync adjusts the frequency of the destination device based on the PPS from the ppsSource
(pi ServoController, srcTimestamp time.Time, dstEventTimestamp time.Time, dstDevice DeviceController)
| 229 | |
| 230 | // PPSClockSync adjusts the frequency of the destination device based on the PPS from the ppsSource |
| 231 | func PPSClockSync(pi ServoController, srcTimestamp time.Time, dstEventTimestamp time.Time, dstDevice DeviceController) error { |
| 232 | phcOffset := dstEventTimestamp.Sub(srcTimestamp) |
| 233 | |
| 234 | err := validatePPSEvent(dstEventTimestamp, dstDevice) |
| 235 | if err != nil { |
| 236 | return fmt.Errorf("error validating event: %w", err) |
| 237 | } |
| 238 | freqAdj, servoState := pi.Sample(int64(phcOffset), uint64(dstEventTimestamp.UnixNano())) // unix nano is never negative |
| 239 | |
| 240 | log.Printf("%s offset %10d servo %s freq %+7.0f", dstDevice.File().Name(), int64(phcOffset), servoState.String(), freqAdj) |
| 241 | |
| 242 | switch servoState { |
| 243 | case servo.StateJump: |
| 244 | if err := dstDevice.AdjFreq(-freqAdj); err != nil { |
| 245 | return fmt.Errorf("failed to adjust freq to %v: %w", -freqAdj, err) |
| 246 | } |
| 247 | if err := dstDevice.Step(-phcOffset); err != nil { |
| 248 | pi.Unlock() |
| 249 | return fmt.Errorf("failed to step clock by %v: %w", -phcOffset, err) |
| 250 | } |
| 251 | case servo.StateLocked: |
| 252 | if err := dstDevice.AdjFreq(-freqAdj); err != nil { |
| 253 | pi.Unlock() |
| 254 | return fmt.Errorf("failed to adjust freq to %v: %w", -freqAdj, err) |
| 255 | } |
| 256 | case servo.StateInit: |
| 257 | return nil |
| 258 | default: |
| 259 | return fmt.Errorf("skipping clock update: servo state is %v", servoState) |
| 260 | } |
| 261 | return nil |
| 262 | } |
| 263 | |
| 264 | // PPSSinkFromDevice configures the targetDevice to be a PPS sink and report PPS timestamp events |
| 265 | func PPSSinkFromDevice(targetDevice DeviceController, pinIndex uint) (*PPSSink, error) { |
searching dependent graphs…