2016-07-12 02:12:58 +00:00
|
|
|
//
|
|
|
|
// DigitalPhaseLockedLoop.hpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 11/07/2016.
|
2018-05-13 19:19:52 +00:00
|
|
|
// Copyright 2016 Thomas Harte. All rights reserved.
|
2016-07-12 02:12:58 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef DigitalPhaseLockedLoop_hpp
|
|
|
|
#define DigitalPhaseLockedLoop_hpp
|
|
|
|
|
2016-07-13 00:23:56 +00:00
|
|
|
#include <memory>
|
2016-07-28 15:32:14 +00:00
|
|
|
#include <vector>
|
2017-07-26 00:20:55 +00:00
|
|
|
|
2017-09-23 02:39:23 +00:00
|
|
|
#include "../../../ClockReceiver/ClockReceiver.hpp"
|
2016-07-13 00:23:56 +00:00
|
|
|
|
2016-07-12 02:12:58 +00:00
|
|
|
namespace Storage {
|
|
|
|
|
2017-07-27 11:40:02 +00:00
|
|
|
class DigitalPhaseLockedLoop {
|
2016-07-12 02:12:58 +00:00
|
|
|
public:
|
|
|
|
/*!
|
|
|
|
Instantiates a @c DigitalPhaseLockedLoop.
|
|
|
|
|
|
|
|
@param clocks_per_bit The expected number of cycles between each bit of input.
|
2016-07-13 00:23:56 +00:00
|
|
|
@param length_of_history The number of historic pulses to consider in locking to phase.
|
2016-07-12 02:12:58 +00:00
|
|
|
*/
|
2017-11-11 20:28:40 +00:00
|
|
|
DigitalPhaseLockedLoop(int clocks_per_bit, std::size_t length_of_history);
|
2016-07-12 02:12:58 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
Runs the loop, impliedly posting no pulses during that period.
|
|
|
|
|
|
|
|
@c number_of_cycles The time to run the loop for.
|
|
|
|
*/
|
2017-07-28 02:05:29 +00:00
|
|
|
void run_for(const Cycles cycles);
|
2016-07-12 02:12:58 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
Announces a pulse at the current time.
|
|
|
|
*/
|
|
|
|
void add_pulse();
|
|
|
|
|
|
|
|
/*!
|
|
|
|
A receiver for PCM output data; called upon every recognised bit.
|
|
|
|
*/
|
|
|
|
class Delegate {
|
|
|
|
public:
|
2016-07-13 01:42:23 +00:00
|
|
|
virtual void digital_phase_locked_loop_output_bit(int value) = 0;
|
2016-07-12 02:12:58 +00:00
|
|
|
};
|
2017-03-26 18:34:47 +00:00
|
|
|
void set_delegate(Delegate *delegate) {
|
2016-12-03 16:59:28 +00:00
|
|
|
delegate_ = delegate;
|
2016-07-12 02:12:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2017-10-18 02:13:37 +00:00
|
|
|
Delegate *delegate_ = nullptr;
|
2016-07-13 00:23:56 +00:00
|
|
|
|
2017-07-16 20:49:04 +00:00
|
|
|
void post_phase_offset(int phase, int offset);
|
2016-07-13 00:23:56 +00:00
|
|
|
|
2017-07-16 20:49:04 +00:00
|
|
|
std::vector<int> offset_history_;
|
2017-11-11 20:28:40 +00:00
|
|
|
std::size_t offset_history_pointer_ = 0;
|
2017-10-18 02:13:37 +00:00
|
|
|
int offset_ = 0;
|
2017-07-16 20:49:04 +00:00
|
|
|
|
2017-10-18 02:13:37 +00:00
|
|
|
int phase_ = 0;
|
|
|
|
int window_length_ = 0;
|
|
|
|
bool window_was_filled_ = false;
|
2016-07-13 00:23:56 +00:00
|
|
|
|
2017-10-18 02:13:37 +00:00
|
|
|
int clocks_per_bit_ = 0;
|
|
|
|
int tolerance_ = 0;
|
2016-07-12 02:12:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* DigitalPhaseLockedLoop_hpp */
|