Gardner Timing Recovery for Repeated Symbols I am implementing the Gardner Timing Error Detection algorithm for a QPSK signal. I understand the concepts behind it but I am curious as to what effect repeated signals can have on the phase lock.

If a symbol is repeated (maybe twice, maybe one hundred times) would the error not accumulate out of control? As I understand it the Gardner method looks at peaks and zero crossings to determine the timing error. If for, example, a symbol is repeated many times, would the algorithm not spiral out of control? If the symbol never changes, the algorithm would keep determining that there was symbol error and push the loop filter further and further from the true symbol timing; only fixing itself after a new lock in time when symbol transitions start occurring again.

Am I correct in thinking this will happen? If so, is it mitigated by the assumption that real world data will never (or very infrequently) repeat symbols more than a couple times in a row?

Thank you,
Your Gardner Loop would properly "Flywheel" in the absence of symbol transitions. So it would slowly drift off of synchronization, but would not spiral out of control as you describe. This is ideal for a control system with "missing updates"; to have the contributions for those updates with no additional information to contribute 0 to the accumulated error, resulting in a "flywheel" behavior. There are other detectors used to discriminate the control term in loops (such as a digital phase-frequency detector used in PLL implementations (such as this device: Maxim Phase Frequency Detector) that produce maximum error in the absence of transitions, and these systems would move off of lock at the maximum speed possible - this would be bad for timing recovery where we expect to have missing bits! 

See my picture below demonstrating the operation of the Gardner Loop. In the absence of transitions, the Timing Error Detector would be zero on average as the Late and Early samples would be the same, and therefore $Late - Early = 0$.



Here is another post I made earlier with more information on the Gardner Loop:

Location of Matched Filter