I can use a Costas Loop, modified for QPSK/4QAM and recover the frequency and phase successfully when using a pattern of all 1s or all 0s or a pattern that is repetitive for each I and Q data rail (in LTspice).
When using other more random like data streams, I can't get a lock on the phase or frequency. I can follow the math through fine if I set the I and Q rails (m1 and m2) to one.
So I guess I'm trying to understand how this loop works when the data are not repetitive, and more random like.
Here is the block diagram: