%% UMTS Downlink Waveform Generation
% This example shows how to generate an HSDPA FRC H-Set using 
% LTE Toolbox(TM).

% Copyright 2014-2020 The MathWorks, Inc.

%% Introduction
% The LTE Toolbox can be used to generate standard compliant
% W-CDMA/HSPA/HSPA+ uplink and downlink complex baseband waveforms
% including pre-defined configurations for standard defined measurement
% channels. For the downlink this includes the Reference Measurement
% Channels (RMC), Fixed Reference Channel (FRC) H-Sets and Test Models (TM)
% defined in TS25.101 [ <#8 1> ].
%
% This example demonstrates how the two downlink related functions,
% <matlab:doc('umtsDownlinkReferenceChannels')
% umtsDownlinkReferenceChannels> and
% <matlab:doc('umtsDownlinkWaveformGenerator')
% umtsDownlinkWaveformGenerator>, combine to support this feature. We show
% how they can generate an FRC H-Set waveform for HSDPA UE testing using
% one of the pre-defined configurations provided. We also present explicit
% MATLAB(R) code which lists all downlink generator parameters set up for
% this particular measurement channel. The FRC H-Sets are defined in
% TS25.101, Section A.7.1 [ <#8 1> ]. This code also provides a useful
% template for full waveform customization.
% 
% The <matlab:doc('umtsDownlinkWaveformGenerator')
% umtsDownlinkWaveformGenerator> function can generate custom
% W-CDMA/HSPA/HSPA+ waveforms using the physical layer channels listed
% below. Arbitrary Coded Composite Transport Channels (CCTrCH) can be
% configured too. The output waveforms are loopable for continuous playback
% in simulation or via test equipment.
% 
% Physical channels supported:
% 
% * _Dedicated Physical Channel  (DPCH)_
% * _Primary Common Pilot Channel (P-CPICH)_
% * _Secondary Common Pilot Channel (S-CPICH)_
% * _Primary Common Control Physical Channel (P-CCPCH)_
% * _Secondary Common Control Physical Channel (S-CCPCH)_
% * _Primary Synchronization Channel (P-SCH)_
% * _Secondary Synchronization Channel (S-SCH)_
% * _Paging Indicator Channel (PICH)_
% * _High Speed Physical Downlink Shared Channel (HS-PDSCH)_
% * _Shared Control Channel for HS-DSCH (HS-SCCH)_
% * _Orthogonal Channel Noise Simulator channels (OCNS)_
%
% Transport channels supported:
% 
% * _Dedicated Channel (DCH)_
% * _Broadcast Channel (BCH)_
% * _Forward Access Channel (FACH)_
% * _Paging Channel (PCH)_
% * _High Speed Downlink Shared Channel (HS-DSCH)_
% 
% The physical channel processing is defined in TS25.211 and TS25.213 [ <#8
% 2> ][ <#8 4> ]. The processing for the transport channels is defined in
% TS25.212 [ <#8 3> ].
% 
% The waveforms generated can be used for a number of applications:
% 
% * _Golden reference for transmitter implementations_
% * _Receiver testing and algorithm development_
% * _Testing RF hardware and software_
% * _Interference testing_
% 
% See <docid:lte_ug#example-ETMWaveformGenerationExample Waveform Generation and
% Transmission using LTE Toolbox with Test and Measurement Equipment> for a
% more detailed explanation of how to interface the waveforms with external
% hardware.

%% W-CDMA/HSPA/HSPA+ Waveform Generation and Parameterization Functions
% 
% The waveform generator function <matlab:doc('umtsDownlinkWaveformGenerator') umtsDownlinkWaveformGenerator> 
% requires a single hierarchical MATLAB structure which specifies the set
% of all parameters for the physical and transport channels present in the
% output waveform.
%
% The toolbox includes a function <matlab:doc('umtsDownlinkReferenceChannels') umtsDownlinkReferenceChannels>
% which can return a fully populated parameter structure for all the
% pre-configured Reference Measurement Channels (RMC), Fixed Reference
% Channel (FRC) H-Sets and Test Models (TM).
%
% By combining the two functions these standard defined measurement
% waveforms can be generated easily. The pre-configured parameters returned
% from <matlab:doc('umtsDownlinkReferenceChannels')
% umtsDownlinkReferenceChannels> can also be used as a starting point for
% parameter customization, for example changing the output filtering,
% channel power levels or even the reference CCTrCH configuration, prior to
% calling the generator function. If full waveform parameter control is
% required then this example includes MATLAB code below which lists all
% possible downlink parameters. The following diagram shows these steps.
% 
% <<../umts_dl_workflows_diagram.png>>
% 
%% H-Set1 (QPSK) Generation Using a Pre-configured Parameter Structure
% The <matlab:doc('umtsDownlinkReferenceChannels')
% umtsDownlinkReferenceChannels> function requires the H-Set number and
% modulation to be specified as shown below. Allowed H-Set values are
% ('H-Set1', 'H-Set2', 'H-Set3', 'H-Set4', 'H-Set5', 'H-Set6', 'H-Set7',
% 'H-Set8', 'H-Set10', 'H-Set12') and the choices for modulation schemes
% are 'QPSK', '16QAM' and '64QAM'. The output structure |preconfigParams|
% is the pre-built configuration for FRC H-Set1 and this can then be used
% to generate the standard defined H-Set waveform by calling the
% <matlab:doc('umtsDownlinkWaveformGenerator')
% umtsDownlinkWaveformGenerator> function.

hset = 'H-Set1';     % H-Set number
modulation = 'QPSK'; % Modulation scheme
preconfigParams = umtsDownlinkReferenceChannels(hset,modulation); % Get H-Set parameters
frcWaveform = umtsDownlinkWaveformGenerator(preconfigParams);     % Generate H-Set waveform

%% H-Set1 (QPSK) Generation Using Full Parameter List
% In this section, we will build the H-Set1 (QPSK) configuration structure
% from scratch and show that this is identical to the structure defined
% using the <matlab:doc('umtsDownlinkReferenceChannels')
% umtsDownlinkReferenceChannels> function as shown above. The
% |downlinkParams| structure defined below has the full list of the
% parameters supported by the <matlab:doc('umtsDownlinkWaveformGenerator')
% umtsDownlinkWaveformGenerator> function and so also can be used as a
% template to create custom waveforms when a large set of parameter values
% need to be changed from the structure output by
% <matlab:doc('umtsDownlinkReferenceChannels')
% umtsDownlinkReferenceChannels>.

% H-Set parameter structure definition from scratch
% General settings
downlinkParams.TotFrames = 1;                      % Number of frames to be generated
downlinkParams.PrimaryScramblingCode = 0;          % Primary scrambling code
downlinkParams.FilterType = 'RRC';                 % Enable the RRC filter
downlinkParams.OversamplingRatio = 4;              % Oversampling set to 4
downlinkParams.NormalizedPower = 'Off';            % Power normalization disabled

% Define Downlink Dedicated Physical Channel  (DPCH)
downlinkParams.DPCH.Enable = 'On';                 % Enable DPCH
downlinkParams.DPCH.SlotFormat = 11;               % DPCH slot format
downlinkParams.DPCH.SpreadingCode = 6;             % DPCH spreading code
downlinkParams.DPCH.NMulticodes = 1;               % Number of DPCH
downlinkParams.DPCH.SecondaryScramblingCode = 1;   % Secondary scrambling code
downlinkParams.DPCH.TimingOffset = 0;              % Timing Offset
downlinkParams.DPCH.Power = 0;                     % Power in dB
downlinkParams.DPCH.TPCData = 0;                   % TPC value
downlinkParams.DPCH.TFCI = 0;                      % TFCI value
downlinkParams.DPCH.DataSource = 'CCTrCH';         % DPCH data source is CCTrCH
% DPCH carries the Coded Composite Transport Channel (CCTrCH) containing
% one or more transport channels. Since DPCH source is specified as CCTrCH,
% define the CCTrCH containing DTCH and DCCH transport channels
% Build DTCH definition
TrCH(1).Name = 'DTCH';                             % Name of the transport channel
TrCH(1).CRC = '16';                                % CRC type
TrCH(1).TTI = 20;                                  % TTI in ms
TrCH(1).CodingType = 'conv3';                      % The coding type and rate
TrCH(1).RMA = 256;                                 % Rate matching attribute
TrCH(1).DataSource = 'PN9-ITU';                    % Tr channel data source
TrCH(1).ActiveDynamicPart = 1;                     % Index to active dynamic part
TrCH(1).DynamicPart(1) = struct('BlockSize',244,'BlockSetSize',244); % 1x244 blocks
% Build DCCH definition
TrCH(2).Name = 'DCCH';                             % Name of the transport channel
TrCH(2).CRC = '12';                                % CRC type
TrCH(2).TTI = 40;                                  % TTI in ms
TrCH(2).CodingType = 'conv3';                      % The coding type and rate
TrCH(2).RMA = 256;                                 % Rate matching attribute
TrCH(2).DataSource = 'PN9-ITU';                    % Tr channel data source
TrCH(2).ActiveDynamicPart = 1;                     % Index to active dynamic part
TrCH(2).DynamicPart(1) = struct('BlockSize',100,'BlockSetSize',100);   % 1x100 blocks
% Finalize CCTrCH structure array using the TrCH structures defined above
downlinkParams.DPCH.CCTrCH.Name = 'DCH';           % Name of the CCTrCH
downlinkParams.DPCH.CCTrCH.DTXPosition = 'fixed';  % DTX position
downlinkParams.DPCH.CCTrCH.TrCH = TrCH;            % Assign DTCH/DCCH to CCTrCH

% Define P-CCPCH
downlinkParams.PCCPCH.Enable = 'On';               % Enable P-CCPCH
downlinkParams.PCCPCH.Power = 0;                   % Set power to be 0dB
downlinkParams.PCCPCH.DataSource = 'CCTrCH';       % P-CCPCH data source is CCTrCH
% P-CCPCH CCTrCH carries the BCH transport channel. Since P-CCPCH source is
% CCTrCH, define CCTrCH containing BCH
clear TrCH;
TrCH(1).Name = 'BCH';                              % Name of the Tr channel
TrCH(1).CRC = '16';                                % CRC type
TrCH(1).TTI = 20;                                  % TTI in ms
TrCH(1).CodingType = 'conv2';                      % The coding type and rate
TrCH(1).RMA = 256;                                 % Rate matching attribute
TrCH(1).DataSource = 'PN9-ITU';                    % Tr channel data source
TrCH(1).ActiveDynamicPart = 1;                     % Index to active dynamic part
TrCH(1).DynamicPart(1) = struct('BlockSize',246,'BlockSetSize',246); % 1x246 block
% Finalize CCTrCH structure array using the TrCH structure defined above
downlinkParams.PCCPCH.CCTrCH.Name = 'BCH';         % Name of the CCTrCH
downlinkParams.PCCPCH.CCTrCH.DTXPosition = 'fixed';% DTX position
downlinkParams.PCCPCH.CCTrCH.TrCH = TrCH;          % Assign BCH to CCTrCH

% Define S-CCPCH, but this channel is not required for H-Set1 generation
downlinkParams.SCCPCH.Enable = 'Off';              % Disable S-CCPCH
downlinkParams.SCCPCH.SlotFormat = 7;              % Slot format number
downlinkParams.SCCPCH.SpreadingCode = 3;           % S-CCPCH spreading code
downlinkParams.SCCPCH.SecondaryScramblingCode = 3; % Secondary scrambling code
downlinkParams.SCCPCH.TimingOffset = 0;            % Timing Offset 
downlinkParams.SCCPCH.Power = 0;                   % Power in dB
downlinkParams.SCCPCH.TFCI = 0;                    % TFCI value
downlinkParams.SCCPCH.DataSource = 'CCTrCH';       % S-CCPCH data source is CCTrCH
% S-CCPCH CCTrCH can carry PCH and FACH transport channels. Since S-CCPCH
% source is CCTrCH, define CCTrCH containing PCH and FACH
% Build PCH definition
TrCH(1).Name = 'PCH';                              % Name of the Tr channel
TrCH(1).CRC = '16';                                % CRC type
TrCH(1).TTI = 10;                                  % TTI in ms
TrCH(1).CodingType = 'conv2';                      % The coding type   
TrCH(1).RMA = 256;                                 % Rate matching attribute
TrCH(1).DataSource = 'PN9-ITU';                    % Tr channel data source  
TrCH(1).ActiveDynamicPart = 1;                     % Index to active dynamic part
TrCH(1).DynamicPart(1) = struct('BlockSize',64,'BlockSetSize',64);   % 1x64 block
% Build FACH definition
TrCH(2).Name = 'FACH';                             % Name of the Tr channel
TrCH(2).CRC = '16';                                % CRC type
TrCH(2).TTI = 10;                                  % TTI in ms
TrCH(2).CodingType = 'turbo';                      % The coding type
TrCH(2).RMA = 256;                                 % Rate matching attribute
TrCH(2).DataSource = 'PN9-ITU';                    % Tr channel data source
TrCH(2).ActiveDynamicPart = 1;                     % Index to active dynamic part
TrCH(2).DynamicPart(1) = struct('BlockSize',360,'BlockSetSize',360);   % 1x360 block
% Finalize CCTrCH using the above
downlinkParams.SCCPCH.CCTrCH.Name = '';            % Name of the CCTrCH
downlinkParams.SCCPCH.CCTrCH.DTXPosition = 'fixed';% DTX position
downlinkParams.SCCPCH.CCTrCH.TrCH = TrCH;          % Assign PCH/FACH to CCTrCH

% Define P-CPICH
downlinkParams.PCPICH.Enable = 'On';               % Enable P-CPICH
downlinkParams.PCPICH.Power = 0;                   % Power in dB

% Define S-CPICH
downlinkParams.SCPICH.Enable = 'Off';              % Disable S-CPICH
downlinkParams.SCPICH.SpreadingCode = 4;           % S-CPICH spreading code
downlinkParams.SCPICH.SecondaryScramblingCode = 4; % Secondary scrambling code
downlinkParams.SCPICH.Power = 0;                   % Power in dB

% Define P-SCH
downlinkParams.PSCH.Enable = 'On';                 % Enable P-SCH
downlinkParams.PSCH.Power = 0;                     % Power in dB

% Define S-SCH
downlinkParams.SSCH.Enable = 'On';                 % Enable S-SCH
downlinkParams.SSCH.Power = 0;                     % Power in dB

% Define PICH 
downlinkParams.PICH.Enable = 'On';                 % Enable PICH
downlinkParams.PICH.SpreadingCode = 16;            % PICH spreading code
downlinkParams.PICH.TimingOffset = 0;              % Timing offset
downlinkParams.PICH.Power = 0;                     % Power in dB
downlinkParams.PICH.DataSource = 'PagingData';     % PICH data source 
downlinkParams.PICH.Np = 144;                      % Number of paging indicators

% Define HSDPA
downlinkParams.HSDPA.Enable = 'On';                % Enable HSDPA channels
downlinkParams.HSDPA.CodeGroup = 5;                % Number of HS-PDSCHs
downlinkParams.HSDPA.CodeOffset = 1;               % Code offset to first HS-PDSCH
downlinkParams.HSDPA.Modulation = 'QPSK';          % Modulation scheme
downlinkParams.HSDPA.VirtualBufferCapacity = 9600; % Buffer capacity
downlinkParams.HSDPA.InterTTIDistance = 3;         % Inter TTI interval
downlinkParams.HSDPA.NHARQProcesses = 2;           % Number of HARQ processes               
downlinkParams.HSDPA.XrvSequence = [0 2 5 6];      % The XRV sequence
downlinkParams.HSDPA.UEId = 0;                     % UE Identity     
downlinkParams.HSDPA.TransportBlockSizeId = 41;    % The transport block size id
downlinkParams.HSDPA.HSSCCHSpreadingCode = 9;      % Shared channel spreading code
downlinkParams.HSDPA.SecondaryScramblingCode = 6;  % Secondary scrambling code
downlinkParams.HSDPA.HSPDSCHPower = 0;             % HS-PDSCH power in dB
downlinkParams.HSDPA.HSSCCHPower = 0;              % HS-SCCH power in dB
downlinkParams.HSDPA.DataSource = 'HSDSCH';        % Data source is HS-DSCH
% HS-DSCH transport channel definition
downlinkParams.HSDPA.HSDSCH.BlockSize = 3202;      % The transport block size
downlinkParams.HSDPA.HSDSCH.DataSource = 'PN9-ITU';% HS-DSCH data source

% Define OCNS channels as defined in TS25.101 Table C.13
downlinkParams.OCNS.Enable = 'On';                 % Enable OCNS channels
downlinkParams.OCNS.Power = 0;                     % OCNS power scaling in dB
downlinkParams.OCNS.OCNSType = 'H-Set_6DPCH';      % OCNS definition

% The structure defined above can be used to generate the waveform:
frcWaveform2 = umtsDownlinkWaveformGenerator(downlinkParams); 

% For completeness we can see that the H-Set definition structures obtained 
% by the above two parameterization approaches are identical
if(isequal(preconfigParams,downlinkParams))
    disp(['H-Set1 configuration structures generated with and without using' ...
    ' umtsDownlinkReferenceChannels function are the same.']);
end

%% Waveform Comparison
% Compare the waveforms generated using both approaches described above and
% see that the generated waveforms are identical

if(isequal(frcWaveform,frcWaveform2))
    disp(['H-Set1 waveforms generated with and without using' ...
    ' umtsDownlinkReferenceChannels function are the same.']);
end

%% Plot Spectrum
% Plot the spectrum of the time domain signal |frcWaveform|. 
chiprate = 3.84e6;   % Chip rate of the baseband waveform
spectrumPlot = dsp.SpectrumAnalyzer('SampleRate', chiprate*downlinkParams.OversamplingRatio,...
                                    'AveragingMethod','Exponential','ForgettingFactor',0.99,...
                                    'YLimits',[-100,40]);
spectrumPlot.Title = sprintf('Spectrum of Fixed Reference Channel (FRC) %s (%s) waveform', hset, modulation);
spectrumPlot(frcWaveform);

%% Conclusion
% This example shows how to generate standard defined and custom
% W-CDMA/HSPA/HSPA+ waveforms using LTE Toolbox functions. The example also
% provides a full parameter template for full user customization of the
% pre-defined waveform configurations.

%% Selected Bibliography
% # 3GPP TS 25.101 "User Equipment (UE) radio transmission and reception (FDD)"
% # 3GPP TS 25.211 "Physical channels and mapping of transport channels onto physical channels (FDD)"
% # 3GPP TS 25.212 "Multiplexing and channel coding (FDD)"
% # 3GPP TS 25.213 "Spreading and modulation (FDD)"
