Main Content

Bluetooth LE Modulation Characteristics, Carrier Frequency Offset and Drift Tests

This example shows how to perform Bluetooth® low energy (LE) radio frequency (RF) physical layer (PHY) transmitter tests specific to modulation characteristics, carrier frequency offset, and drift using Bluetooth® Toolbox. The test measurements compute frequency deviation, carrier frequency offset, and drift values. This example also verifies whether these test measurement values are within the limits specified by the Bluetooth RF-PHY Test Specifications [1].

Objectives of LE RF-PHY Tests

The Bluetooth RF-PHY Test Specifications [1] defined by Bluetooth Special Interest Group (SIG) includes RF-PHY tests for both transmitter and receiver. The objectives of these RF-PHY tests are to:

  • Ensure interoperability between all Bluetooth devices.

  • Ensure a basic level of system performance for all Bluetooth products.

Each test case has a specified test procedure and an expected outcome, which must be met by the implementation under test (IUT).

RF-PHY Transmitter Tests

The main aim of transmitter test measurements is to ensure that the transmitter characteristics are within the specified limits as specified in the test specifications [1]. This example includes transmitter tests relevant to modulation characteristics, carrier frequency offset, and drift. This table shows various RF-PHY transmitter tests performed in this example.

Capture1.PNG

Transmitter Test Procedure

This block diagram summarizes the test procedure for transmitter tests relevant to modulation characteristics, carrier frequency offset, and drift.

Bluetooth LE Modulation characteristics, Carrier frequency offset and drift Test Block diagram.

To simulate the transmitter tests, perform these steps.

  1. Generate Bluetooth LE test packet waveform by using the bluetoothTestWaveform function.

  2. Add frequency offset, which includes initial frequency offset, and drift to the waveform by using the comm.PhaseFrequencyOffset System object.

  3. Add thermal noise by using the comm.ThermalNoise System object.

  4. Perform filtering on the noisy waveform by using modulationTestFilter function.

  5. Perform frequency modulation by using the bluetoothTestWaveformValidate function.

  6. Perform test measurement and display the pass verdict by using helperBLEModulationTestVerdict helper function.

Generate Bluetooth LE test packets by using the bluetoothTestWaveform function. The test waveform required for different test IDs are:

Capture2.PNG

Configure the Tet Parameters

Specify the test value as "Modulation characteristics" or "Carrier frequency offset and drift".

testValue = "Modulation characteristics";

Specify the PHY transmission mode as "LE1M", "LE2M" or "LE125K".

phyMode = "LE1M";

Specify the payload length in the range [37, 255] bytes.

payloadLength = 240;

Specify the length of the frequency pulse shape in the range [1, 4].

pulseLength = 2;

Specify the modulation index of GFSK in the range [0.45, 0.55].

modulationIndex = 0.5; 

Specify number of samples per symbol, minimum of 32 samples per symbol as per the test specifications

sps = 32;

Specify the initial frequency offset in the range [-100e3, 100e3].0

initialFrequencyOffset = 23000;  % In Hz

Specify the carrier drift in the range [-50e3, 50e3].

carrierDrift = 0;             % In Hz

Configure the RF-PHY test configuration by using the bluetoothRFPHYTestConfig object.

configObject = bluetoothRFPHYTestConfig(Test=testValue, ...
    Mode=phyMode, ...
    PulseLength=pulseLength, ...
    ModulationIndex=modulationIndex, ...
    SamplesPerSymbol=sps, ...
    PayloadLength=payloadLength, ...
    InitialFrequencyOffset=initialFrequencyOffset, ...
    CarrierDrift=carrierDrift);

The constant tone extension (CTE) information field position is same for LE test packet and data packet. For CTE-based RF-PHY tests, specify the packet type as "ConnectionCTE". The default packet type is "Disabled".

configObject.PacketType = "Disabled"; 

Specify CTE length in 8 microseconds units, must be in the range [13, 20] bytes.

if (configObject.PacketType=="ConnectionCTE")
    configObject.CTELength = 13; 
end

Specify the Bluetooth LE test waveform configuration object by using bluetoothTestWaveformConfig.

testWaveformConfig = bluetoothTestWaveformConfig(Mode=phyMode, ...
    PayloadLength=configObject.PayloadLength, ...
    PacketType=configObject.PacketType, ...
    SamplesPerSymbol=sps, ...
    CTELength=configObject.CTELength, ...
    CTEType=configObject.CTEType, ...
    ModulationIndex=configObject.ModulationIndex, ...
    PulseLength=configObject.PulseLength);

Based on the PHY transmission mode, compute the sampling rate.

sampleRate = 1e6*(1+1*(phyMode=="LE2M"))*sps;

Compute the total number of bits in the Bluetooth test packet by using the bluetoothPacketDuration function.

if (configObject.PacketType=="ConnectionCTE")
  [~,testWfmSymLen] = bluetoothPacketDuration(phyMode,configObject.PacketType, ...
      configObject.PayloadLength,configObject.CTELength);
else
  [~,testWfmSymLen] = bluetoothPacketDuration(phyMode,configObject.PacketType, ...
      configObject.PayloadLength);
end

Specify the frequency drift and frequency offset.

testWfmLen = testWfmSymLen*sps;
driftRate = configObject.CarrierDrift/testWfmLen;
freqDrift = driftRate*(0:1:(testWfmLen-1))';
freqOffset = configObject.InitialFrequencyOffset + freqDrift;

Create a phase frequency offset System object by using comm.PhaseFrequencyOffset System object.

pfo = comm.PhaseFrequencyOffset(FrequencyOffset=freqOffset, ...
    SampleRate=sampleRate);

Specify the noise figure in dB.

NF = 12;

Create and configure comm.ThermalNoise System object™ to add thermal noise.

thermalNoise = comm.ThermalNoise(NoiseMethod="Noise figure", ...
    SampleRate=sampleRate, ...
    NoiseFigure=NF);

Specify the test sequence Id by using the getTestSequenceIds function.

testSequenceIds = getTestSequenceIds(configObject);

Specify the FM demodulation filter using the modulationTestFilter function.

filterDesign = modulationTestFilter(phyMode,sampleRate);

Compute the number of test sequences.

numTestSequences = length(testSequenceIds);

Preallocate memory to filtered waveform.

filteredTestWfm = zeros(testWfmLen,numTestSequences);

Simulate Transmitter Tests

Simulate each Bluetooth LE test waveform for each test sequence.

for countTestSequences = 1:numTestSequences
    % Generate a Bluetooth LE test waveform with respect to specific
    % payload type
    testWaveformConfig.PayloadType = testSequenceIds(countTestSequences);
    testWfm = bluetoothTestWaveform(testWaveformConfig);

    % Pass the waveform through phase frequency offset
    wfmFreqOffset = pfo(testWfm);

    % Pass waveform through thermal noise
    wfmChannel = thermalNoise(wfmFreqOffset);

    % Perform filtering of the noisy waveform
    filteredTestWfm(:,countTestSequences) =  conv(wfmChannel,filterDesign.Numerator.',"same");
end

Validate the filtered waveform by using the bluetoothTestWaveformValidate function. Based on the test, the bluetoothTestWaveformValidate function computes either frequency deviation, or frequency drift and initial frequency offset.

if ((testValue == "Carrier frequency offset and drift") && (configObject.PacketType=="Disabled"))
    [testWfm,fOut1,fOut2] = bluetoothTestWaveformValidate(filteredTestWfm,configObject);
    fOut3 = [];
else
    [testWfm,fOut1,fOut2,fOut3] = bluetoothTestWaveformValidate(filteredTestWfm,configObject);
end

The helperBLEModulationTestVerdict helper function verifies whether the measurements are within the specified limits, and displays the verdict on the command window.

helperBLEModulationTestVerdict(configObject,testSequenceIds,testWfm,fOut1,fOut2,fOut3)

Figure contains 2 axes objects. Axes object 1 with title Frequency Demodulated Waveform for Sequence: 11110000, xlabel Samples, ylabel Frequency (in Hz) contains 3 objects of type line. These objects represent FM Demodulated Waveform, Average Frequency Deviation, Sequence Center Frequency. Axes object 2 with title Frequency Demodulated Waveform for Sequence: 10101010, xlabel Samples, ylabel Frequency (in Hz) contains 3 objects of type line. These objects represent FM Demodulated Waveform, Average Frequency Deviation, Sequence Center Frequency.

Test sequence: 11110000
    Measured average frequency deviation = 250.0201 kHz
    Expected average frequency deviation = 225 kHz to 275 kHz
    Result: Pass
Test sequence: 10101010
    Expected 99.9% of all maximum frequency deviation > 185000 kHz
    Result: Pass
Ratio of frequency deviations between two test sequences = 0.83511
Expected Ratio > 0.8 
    Result: Pass

This example demonstrated the Bluetooth LE transmitter test measurements specific to modulation characteristics, carrier frequency offset and, drift. The simulation results verify that these computed test measurement values are within the limits specified by Bluetooth RF-PHY Test Specifications [1].

Appendix

The helpers used in this example are:

Selected Bibliography

  1. Bluetooth Special Interest Group (SIG), Inc. “Bluetooth® Technology Website – The Official Website for the Bluetooth Wireless Technology. Get up to Date Specifications, News, and Development Info.” Accessed May 24, 2023. https://www.bluetooth.com/.

  2. Bluetooth Special Interest Group (SIG), Inc. “Core Specification – Bluetooth® Technology Website.” Accessed May 24, 2023. https://www.bluetooth.com/specifications/specs/core-specification-5-3/.

Local Functions

function Hd = modulationTestFilter(phyMode,Fsamp)
% Design FM demodulation filter
multFactor = 1;
if (phyMode=="LE2M")
    multFactor = 2;
end

Fpass = 550000*multFactor;           % Passband Frequency
Fstop = 2000000*multFactor;          % Stopband Frequency
Dpass = 0.028774368332;              % Passband Ripple
Dstop = 0.0063095734448;             % Stopband Attenuation
dens  = 20;                          % Density Factor

% Calculate the order from the parameters using FIRPMORD.
[N, Fo, Ao, W] = firpmord([Fpass, Fstop]/(Fsamp/2), [1 0], [Dpass, Dstop]);

% Calculate the coefficients using the FIRPM function.
b  = firpm(N, Fo, Ao, W, {dens});
Hd = dfilt.dffir(b);
end

function testSequenceIds = getTestSequenceIds(configObject)
switch configObject.TestID
    case {"RF-PHY/TRM/BV-06-C","RF-PHY/TRM/BV-12-C"}
        % Carrier frequency offset and drift test without CTE,
        % uncoded PHY
        testSequenceIds = 2;
    case {"RF-PHY/TRM/BV-09-C","RF-PHY/TRM/BV-11-C"}
        % Modulation Test uncoded PHY
        testSequenceIds = [1,2];
    case {"RF-PHY/TRM/BV-13-C","RF-PHY/TRM/BV-14-C"}
        % Carrier frequency offset and drift test without CTE
        % for coded PHY "LE125K" and Modulation Characteristics
        % for Coded PHY "LE125K"
        testSequenceIds = 4;
    case {"RF-PHY/TRM/BV-16-C","RF-PHY/TRM/BV-17-C"}
        % Carrier frequency Offset and Drift Test with CTE,
        % Coded PHY
        testSequenceIds = 1;
end
end

See Also

Functions

Objects

Related Topics