Joint Sampling Clock and Carrier Frequency Offset Tracking
This example demonstrates joint sampling clock and carrier frequency offset tracking in a WLAN receiver.
Introduction
A WLAN radio typically uses a single oscillator to derive clocks for sampling and modulation. The oscillators in the transmitter and receiver radios do not run at the exact same frequency. Due to this mismatch, carrier frequency offset (CFO) exists between the receiver and transmitter and the sampling instants at the receiver shift relative to the transmitter. This shift of sampling instants between receiver and transmitter is described as sampling clock offset (SCO). When the sampling clock at the receiver is running slower than the transmitter, this results in a larger sampling period and a positive sampling clock offset. The inclusion of pilot subcarriers in the IEEE® 802.11™ standard allows for tracking and correction of SCO and CFO impairments.
In OFDM systems SCO manifests itself as a subcarrier- and symbol-dependent phase rotation and inter-carrier interference (ICI) [ 1 ]. When the SCO is large, and a packet is long, subcarriers far away from DC will experience a substantial impairment. CFO manifests itself as ICI and a symbol-dependent phase rotation common to all subcarriers. This figure illustrates the phase rotation on subcarriers from one OFDM symbol to the next due to these impairments. Φk is the phase error for subcarrier index k, K is the number of subcarriers, ζ is the SCO, Δf is the carrier frequency offset, Tu is the period of the symbol, δ is the phase error gradient (PEG), and ω is the common phase error (CPE). The PEG and CPE can be used to estimate SCO and residual CFO.
This example shows how to demonstrate an IEEE 802.11ac™ VHT waveform with fixed SCO and CFO impairments [2], and shows the equalized constellation of the demodulated impaired waveform with and without time and phase tracking to correct for SCO and CFO to demonstrate the effectiveness of tracking.
Generate a Baseband Waveform
Create a VHT configuration object to parameterize the transmission. Use a data payload with only 500 bytes and 16-point quadrature amplitude modulation (16-QAM) to produce a small number of OFDM symbols and make the impairment easy to visualize.
cfgVHT = wlanVHTConfig; cfgVHT.ChannelBandwidth = 'CBW20'; cfgVHT.NumTransmitAntennas = 1; cfgVHT.NumSpaceTimeStreams = 1; cfgVHT.MCS = 4; % 16-QAM and 3/4 coding rate cfgVHT.APEPLength = 500; % Bytes
Create a random PSDU.
s = rng(10); % Seed the random number generator psdu = randi([0 1],cfgVHT.PSDULength*8,1,'int8');
Generate a VHT packet.
tx = wlanWaveformGenerator(psdu,cfgVHT);
Model Impairments
Model -100 parts per million (PPM) sampling clock offset between the transmitter and receiver using comm.SampleRateOffset
.
sco = -100; % Sampling clock offset in PPM
Use comm.SampleRateOffset
by specifying the desired sample rate offset. Sample rate offset is the relative offset between the sample rate of transmitter and receiver. Sampling clock offset is the relative offset between the sampling period of transmitter and receiver.
sro = -sco/(1+sco/1e6); % Sample rate offset in PPM
Model sampling clock offset, appending zeros to the waveform to allow for filter delay.
samplingClockoffset = comm.SampleRateOffset(sro); rx = samplingClockoffset([tx; zeros(100,cfgVHT.NumTransmitAntennas)]);
Add residual carrier frequency offset to the waveform. This example assumes the same oscillator is used for sampling and modulation, so that the CFO depends on the SCO and carrier frequency.
fc = 5.25e9; % Carrier frequency, Hertz cfo = (sco*1e-6)*fc; % Carrier frequency offset, Hertz fs = wlanSampleRate(cfgVHT); % Baseband sample rate rx = frequencyOffset(rx,fs,cfo); % Add frequency offset
Add noise to the waveform with 30 dBW variance.
awgnChannel = comm.AWGNChannel('NoiseMethod','Variance','Variance',10^(-30/10)); rx = awgnChannel(rx);
Front-End Synchronization and Receiver Processing
To synchronize the packet, in preparation for recovering the data field, the example performs these processing steps.
Detect the packet
Perform coarse carrier frequency offset estimation and correction
Establish symbol timing synchronization
Perform fine carrier frequency offset estimation and correction
Demodulate the L-LTF and estimate the noise power
Demodulate the VHT-LTF and estimate the channel response
Generate field indices and perform packet detection.
ind = wlanFieldIndices(cfgVHT); tOff = wlanPacketDetect(rx,cfgVHT.ChannelBandwidth);
Perform coarse frequency offset correction.
lstf = rx(tOff+(ind.LSTF(1):ind.LSTF(2)),:); coarseCFOEst = wlanCoarseCFOEstimate(lstf,cfgVHT.ChannelBandwidth); rx = frequencyOffset(rx,fs,-coarseCFOEst);
Perform symbol timing synchronization.
nonhtPreamble = rx(tOff+(ind.LSTF(1):ind.LSIG(2)),:); symOff = wlanSymbolTimingEstimate(nonhtPreamble,cfgVHT.ChannelBandwidth); tOff = tOff+symOff;
Perform fine frequency offset correction.
lltf = rx(tOff+(ind.LLTF(1):ind.LLTF(2)),:); fineCFOEst = wlanFineCFOEstimate(lltf,cfgVHT.ChannelBandwidth); rx = frequencyOffset(rx,fs,-fineCFOEst);
Perform channel estimation.
vhtltf = rx(tOff+(ind.VHTLTF(1):ind.VHTLTF(2)),:); vhtltfDemod = wlanVHTLTFDemodulate(vhtltf,cfgVHT); [chanEst,chanEstSSPilots] = wlanVHTLTFChannelEstimate(vhtltfDemod,cfgVHT);
Recovery Without Sampling Clock Offset or Residual CFO Tracking
The coarse and fine frequency offset estimation and correction removes the majority of CFO, but residual CFO remains due to the presence of impairments in the waveform. The receiver must track and correct this offset.
disp('Front-end impairment correction:');
Front-end impairment correction:
frontEndCFOEst = coarseCFOEst+fineCFOEst; disp([' Estimated CFO: ' num2str(frontEndCFOEst,'%.1f') ' Hz']);
Estimated CFO: -525209.0 Hz
residualCFO = cfo-frontEndCFOEst; disp([' Residual CFO after initial correction: ' num2str(residualCFO,'%.1f') ' Hz']);
Residual CFO after initial correction: 209.0 Hz
Use the trackingVHTDataRecover function to recover the VHT data field with optional pilot tracking to correct for timing and phase errors due to SCO and CFO. Control pilot tracking using the trackingRecoveryConfig object.
First, recover the data field is without pilot tracking. Extract the data field from the waveform using the start and end sample indices of the field at the baseband rate. If the receiver sampling rate is higher than the transmitter rate, the receiver requires more samples than the transmitter produces. To allow for this, extract Ne
additional samples from the waveform and pass to the recovery function. The maximum number of additional samples required depends on the expected SCO, baseband sampling rate, and maximum packet duration.
Create a recovery configuration with pilot tracking disabled.
cfgRec = trackingRecoveryConfig; cfgRec.PilotTimeTracking = false; cfgRec.PilotPhaseTracking = false;
Extract data field with Ne
additional samples to allow for negative SCO.
maxDuration = 5.484e-3; % Maximum packet duration in seconds maxSCO = 120; % PPM Ne = ceil(fs*maxDuration*maxSCO*1e-6); % Number of extra samples dataInd = tOff+(ind.VHTData(1):ind.VHTData(2)+Ne); dataInd = dataInd(dataInd<=length(rx)); % Only use indices within waveform data = rx(dataInd,:);
Perform demodulation and decoding.
[rxPSDUNoTrack,~,eqSymNoTrack] = trackingVHTDataRecover(data,chanEst,chanEstSSPilots,cfgVHT,cfgRec);
Plot the equalized constellation. This plot shows a rotation of all constellation points caused by residual CFO, and a spreading of constellation points due to SCO. Despite the modest AWGN added to the waveform, the impairments cause bit errors within the decoded PSDU.
ConstNoTrack = comm.ConstellationDiagram;
ConstNoTrack.Title = 'Equalized symbols with no pilot tracking';
ConstNoTrack.ReferenceConstellation = wlanReferenceSymbols(cfgVHT);
ConstNoTrack(eqSymNoTrack(:));
release(ConstNoTrack)
[~,berNoTrack] = biterr(rxPSDUNoTrack,psdu);
disp('Bit error rate:');
Bit error rate:
disp([' Without tracking: ' num2str(berNoTrack)]);
Without tracking: 0.073909
Recovery With Sampling Clock Offset Tracking and Residual CFO Tracking
Now recover the data field with time and phase pilot tracking to correct for SCO and residual CFO.
The tracking algorithm in this example estimates absolute values of and per OFDM symbol and applies a per subcarrier and symbol phase correction to the demodulated symbols to reverse the phase errors caused by SCO and CFO. The algorithm calculates the phase error between each received pilot subcarrier and the expected value per symbol averaged over PilotTrackingWindow
OFDM symbols. From this value, the algorithm calculates least-square estimates of and per symbol, and uses these estimates to apply a phase correction to each symbol and subcarrier [3,4] .
Create a recovery configuration with pilot tracking enabled.
cfgRec = trackingRecoveryConfig;
cfgRec.PilotTrackingWindow = 9; % Averaging window in OFDM symbols
Perform demodulation and decoding.
[rxPSDU,~,eqSymTrack,cpe,peg] = trackingVHTDataRecover(data,chanEst,chanEstSSPilots,cfgVHT,cfgRec);
Plot the equalized constellation. This shows a clear 16-QAM constellation with no spreading or rotation. The decoded PSDU contains no bit errors.
ConstTrack = comm.ConstellationDiagram;
ConstTrack.Title = 'Equalized symbols with time and phase pilot tracking';
ConstTrack.ReferenceConstellation = wlanReferenceSymbols(cfgVHT);
ConstTrack(eqSymTrack(:));
release(ConstTrack)
[~,berTrack] = biterr(rxPSDU,psdu);
disp([' With tracking: ' num2str(berTrack)]);
With tracking: 0
The trackingVHTDataRecover function returns measurements from which the residual CFO, and SCO can be estimated:
cpe
- The common phase error (radians) per symbolpeg
- The phase error gradient (radians per subcarrier) per symbol
Estimate the SCO and residual CFO from these measurements using a linear least-square fit of the rate of change. The trackingPlotSCOCFOEstimates function performs these measurements and plot the results.
[residualCFOEst,scoEst] = trackingPlotSCOCFOEstimates(cpe,peg,cfgVHT);
fprintf('Tracked impairments:\n');
Tracked impairments:
fprintf(' Estimated residual CFO: %3.1f Hz (%.1f Hz error)\n', ... residualCFOEst,residualCFOEst-residualCFO);
Estimated residual CFO: 1212.9 Hz (1003.9 Hz error)
fprintf(' Estimated SCO: %3.1f PPM (%.1f PPM error)\n',scoEst,scoEst-sco);
Estimated SCO: -98.3 PPM (1.7 PPM error)
cfoEst = frontEndCFOEst+residualCFOEst; % Initial + tracked CFO estimate fprintf('Estimated CFO (initial + tracked): %.1f Hz (%.1f Hz error)\n',cfoEst,cfoEst-cfo);
Estimated CFO (initial + tracked): -523996.1 Hz (1003.9 Hz error)
rng(s); % Restore the state of the random number generator
Conclusion
This example shows how you can track and correct sampling clock and carrier frequency offsets when recovering the data field of a WLAN waveform.
To see an example of pilot tracking for HE format packets see the Recovery Procedure for an 802.11ax Packet example.
References
Speth, M., S.A. Fechtel, G. Fock, and H. Meyr. “Optimum Receiver Design for Wireless Broad-Band Systems Using OFDM. I.” IEEE Transactions on Communications 47, no. 11 (November 1999): 1668–77. https://doi.org/10.1109/26.803501.
IEEE Std 802.11™-2020. IEEE Standard for Information Technology - Telecommunications and Information Exchange between Systems - Local and Metropolitan Area Networks - Specific Requirements - Part 11: Wireless LAN Medium Access Control (MAC) and Physical Layer (PHY) Specifications.
Chiueh, Tzi-Dar, Pei-Yun Tsai, Lai. I-Wei, and Tzi-Dar Chiueh. Baseband Receiver Design for Wireless MIMO-OFDM Communications. 2nd ed. Hoboken, N.J: J. Wiley & Sons, 2012.
Horlin, François, and André Bourdoux. Digital Compensation for Analog Front-Ends: A New Approach to Wireless Transceiver Design. Chichester, West Sussex ; Hoboken, NJ: J. Wiley & Sons, 2008.