%% Mixed PUCCH Format Transmission and Reception
% This example shows the transmission and reception of Physical Uplink Control Channel (PUCCH) Formats 1 and 2, including the case where the same physical resource is shared between transmissions of Format 1 and Format 2 simultaneously from two different User Equipments (UEs) using the LTE Toolbox™.
%% Introduction
% This example configures two User Equipments (UEs) to transmit a Physical Uplink Control Channel (PUCCH) Format 1 signal from the first UE and a PUCCH Format 2 signal from the second UE. Appropriate Demodulation Reference Signals (DRS) are also generated. The transmitted signals are passed through two different fading channels and added, together with Additive White Gaussian Noise (AWGN), simulating the reception of the signals from the two UEs at an eNodeB. Each signal (i.e. that belonging to each UE) is then synchronized, SC-FDMA demodulated, equalized, PUCCH demodulated and then finally decoded. A plot is produced showing that the channels can be estimated independently for the two different signals, even though they share the same physical Resource Elements (REs).
%% UE 1 Configuration
% The first UE is configured using a structure ue1.

ue1.NULRB = 6;                  % Number of resource blocks
ue1.NSubframe = 0;              % Subframe number
ue1.NCellID = 10;               % Physical layer cell identity
ue1.RNTI = 61;                  % Radio network temporary identifier
ue1.CyclicPrefixUL = 'Normal';  % Cyclic prefix
ue1.Hopping = 'Off';            % Frequency hopping
ue1.Shortened = 0;              % Reserve last symbols for SRS transmission
ue1.NTxAnts = 1;                % Number of transmit antennas

%
%% UE 2 Configuration
% Similarly a configuration structure is used to configure the second UE, ue2. This structure is identical to the configuration of ue1 with two exceptions:
% No Shortened field as this does not apply to PUCCH Format 2.
% A different Radio Network Temporary Identifier (RNTI) value (not used here as it is only relevant for Physical Uplink Shared Channel (PUSCH) transmission, but different UEs would have different RNTI).

ue2.NULRB = 6;                  % Number of resource blocks    
ue2.NSubframe = 0;              % Subframe number
ue2.NCellID = 10;               % Physical layer cell identity
ue2.RNTI = 77;                  % Radio network temporary identifier   
ue2.CyclicPrefixUL = 'Normal';  % Cyclic prefix
ue2.Hopping = 'Off';            % Frequency hopping
ue2.NTxAnts = 1;                % Number of transmit antennas

%
%% PUCCH 1 Configuration
% For the first UE, a PUCCH of Format 1 is used, so an appropriate configuration structure pucch1 is created. The parameter CyclicShifts specifies the number of cyclic shifts used by PUCCH Format 1 in resource blocks where a mixture of PUCCH Format 1 and PUCCH Format 2 are to be transmitted. The parameter ResourceSize specifies the size of the resources used by PUCCH Format 2, effectively determining the starting position of PUCCH Format 1 transmissions; here we specify ResourceIdx=0 which will use the first PUCCH Format 1 resource.

pucch1.ResourceIdx = 0;   % PUCCH resource index
pucch1.DeltaShift = 1;    % Delta shift
pucch1.CyclicShifts = 1;  % Number of cyclic shifts
pucch1.ResourceSize = 0;  % Size of resources allocated to PUCCH Format 2

%
%% PUCCH 2 Configuration
% For the second UE, a PUCCH of Format 2 is used, so an appropriate configuration structure pucch2 is created. The values of parameters CyclicShifts and ResourceSize are the same as in the PUCCH Format 1 configuration. The value of ResourceIdx is set to the first PUCCH Format 2 resource, meaning that the physical resource blocks now configured for PUCCH Format 1 and PUCCH Format 2 will be the same.

pucch2.ResourceIdx = 0;   % PUCCH resource index
pucch2.CyclicShifts = 1;  % Number of cyclic shifts
pucch2.ResourceSize = 0;  % Size of resources allocated to PUCCH Format 2

%
%% Channel Propagation Model Configuration
% The propagation channel that the two UEs will transmit through is configured using a structure channel. The sampling rate of the channel is configured to match the sampling rate at the output of the first UE; note that the same sampling rate is used at the output of the second UE because ue1.NULRB and ue2.NULRB are the same. When we use this channel configuration for each UE, the Seed parameter of the structure will be set differently for each UE so that different propagation conditions result.

channel.NRxAnts = 4;                % Number of receive antennas       
channel.DelayProfile = 'ETU';       % Delay profile
channel.DopplerFreq = 300.0;        % Doppler frequency   
channel.MIMOCorrelation = 'Low';    % MIMO correlation
channel.InitTime = 0.0;             % Initialization time
channel.NTerms = 16;                % Oscillators used in fading model
channel.ModelType = 'GMEDS';        % Rayleigh fading model type
channel.InitPhase = 'Random';       % Random initial phases
channel.NormalizePathGains = 'On';  % Normalize delay profile power 
channel.NormalizeTxAnts = 'On';     % Normalize for transmit antennas

% Set sampling rate
info = lteSCFDMAInfo(ue1);
channel.SamplingRate = info.SamplingRate;

%
%% Noise Configuration
% The SNR is given by \mathrm{SNR}=E_s/N_0 where E_s is the energy of the signal of interest and N_0 is the noise power. The power of the noise to be added can be determined so that E_s and N_0 are normalized after the SC-FDMA demodulation to achieve the desired SNR SNRdB. The noise added before SC-FDMA demodulation will be amplified by the IFFT. The amplification is the square root of the size of the IFFT. In this simulation this is taken into consideration by dividing the desired noise power by this value. In addition, because real and imaginary parts of the noise are created separately before being combined into complex additive white Gaussian noise, the noise amplitude must be scaled by 1/\sqrt{2} so the generated noise power is 1.

SNRdB = 21.0;

% Normalize noise power
SNR = 10^(SNRdB/20);
N = 1/(SNR*sqrt(double(info.Nfft)))/sqrt(2.0);

% Configure random number generators
rng('default');

%
%% Channel Estimation Configuration
% The channel estimator is configured using a structure cec. Here cubic interpolation will be used with an averaging window of 12-by-1 REs. This configures the channel estimator to use a special mode which ensures the ability to despread and orthogonalize the different overlapping PUCCH transmissions.

cec = struct;                     % Channel estimation config structure
cec.PilotAverage = 'UserDefined'; % Type of pilot averaging
cec.FreqWindow = 12;              % Frequency averaging window in REs (special mode)
cec.TimeWindow = 1;               % Time averaging window in REs (Special mode)     
cec.InterpType = 'cubic';         % Cubic interpolation

%
%% PUCCH Format 1 Generation
% Now all the necessary configuration is complete, the PUCCH Format 1 and its DRS are generated. The PUCCH Format 1 carries the HARQ indicators hi1 and in this case there are 2 indicators, meaning that the transmission will be of Format 1b. The PUCCH Format 1 DRS carries no data.

% PUCCH 1 modulation/coding
hi1 = [0; 1];  % Create HARQ indicators
disp('hi1:');
disp(hi1.');
pucch1Sym = ltePUCCH1(ue1, pucch1, hi1);    

% PUCCH 1 DRS creation
pucch1DRSSym = ltePUCCH1DRS(ue1, pucch1);

%
%% PUCCH Format 2 Generation
% The PUCCH Format 2 DRS carries the HARQ indicators hi2 and in this case there are 2 indicators, meaning that the transmission will be of Format 2b. The PUCCH Format 2 itself carries coded Channel Quality Information (CQI). The information cqi here is coded and then modulated.

% PUCCH 2 DRS modulation
hi2 = [1; 1];  % Create HARQ indicators
disp('hi2:');
disp(hi2.');
pucch2DRSSym = ltePUCCH2DRS(ue2, pucch2, hi2);

% PUCCH 2 coding
cqi = [0; 1; 1; 0; 0; 1];  % Create channel quality information
disp('cqi:');
disp(cqi.');
codedcqi = lteUCIEncode(cqi);

% PUCCH 2 modulation
pucch2Sym = ltePUCCH2(ue2, pucch2, codedcqi);

%
%% PUCCH Index Generation
% The indices for the PUCCH and PUCCH DRS transmissions are created

pucch1Indices = ltePUCCH1Indices(ue1, pucch1);    
pucch2Indices = ltePUCCH2Indices(ue2, pucch2);        

pucch1DRSIndices = ltePUCCH1DRSIndices(ue1, pucch1);  
pucch2DRSIndices = ltePUCCH2DRSIndices(ue2, pucch2);

%
%% Transmission for UE 1
% The overall signal for the first UE is now transmitted. The steps are to map the PUCCH Format 1 and corresponding DRS signal into an empty resource grid, perform SC-FDMA modulation and then transmit through a fading propagation channel.

% Create resource grid
grid1 = lteULResourceGrid(ue1);
grid1(pucch1Indices) = pucch1Sym;
grid1(pucch1DRSIndices) = pucch1DRSSym;

% SC-FDMA modulation
txwave1 = lteSCFDMAModulate(ue1, grid1);

% Channel modeling. An additional 25 samples added to the end of the
% waveform to cover the range of delays expected from the channel modeling
% (a combination of implementation delay and channel delay spread)
channel.Seed = 13;
rxwave1 = lteFadingChannel(channel,[txwave1; zeros(25,1)]);

%
%% Transmission for UE 2
% The overall signal for the second UE is now transmitted. Note that a different random seed channel.Seed is used compared to that used for the first UE. This ensures that different propagations are used for the two transmissions.

% Create resource grid
grid2 = lteULResourceGrid(ue2);
grid2(pucch2Indices) = pucch2Sym;            
grid2(pucch2DRSIndices) = pucch2DRSSym; 

% SC-FDMA modulation
txwave2 = lteSCFDMAModulate(ue2, grid2);

% Channel modeling. An additional 25 samples added to the end of the
% waveform to cover the range of delays expected from the channel modeling
% (a combination of implementation delay and channel delay spread)
channel.Seed = 15;
rxwave2 = lteFadingChannel(channel, [txwave2; zeros(25, 1)]);

%
%% Reception at the Base Station
% The input to the base station receiver is modeled by adding the two faded signals together with Gaussian noise with power as described above.

rxwave = rxwave1 + rxwave2;         

% Add noise
noise = N*complex(randn(size(rxwave)), randn(size(rxwave)));
rxwave = rxwave + noise;

%
%% Synchronization and SC-FDMA Demodulation for UE 1
% The uplink frame timing estimate for UE1 is calculated using the PUCCH 1 DRS signals and then used to demodulate the SC-FDMA signal. The resulting grid rxgrid1 is a 3 dimensional matrix. The number of rows represents the number of subcarriers. The number of columns equals the number of SC-FDMA symbols in a subframe. The number of subcarriers and symbols is the same for the returned grid from lteSCFDMADemodulate as the grid passed into lteSCFDMAModulate. The number of planes (3rd dimension) in the grid corresponds to the number of receive antennas.

% Synchronization
offset1 = lteULFrameOffsetPUCCH1(ue1, pucch1, rxwave);

% SC-FDMA demodulation
rxgrid1 = lteSCFDMADemodulate(ue1, rxwave(1+offset1:end, :));

%
%% Channel Estimation and Equalization for UE 1
% An estimate of the channel between each transmitter and the base station receiver is obtained and used to equalize its effects. To create an estimation of the channel lteULChannelEstimatePUCCH1 is used. The channel estimation function is configured by the structure cec. The function returns a 3-D matrix of complex weights which are applied to each resource element by the channel in the transmitted grid. The 1st dimension is the subcarrier, the 2nd dimension is the SC-FDMA symbol and the 3rd dimension is the receive antenna. The effect of the channel on the received resource grid is equalized using lteEqualizeMMSE. This function uses the estimate of the channel (H1) to equalize the received resource grid (rxGrid1).

% Channel estimation
[H1, n0] = lteULChannelEstimatePUCCH1(ue1, pucch1, cec, rxgrid1);

% Extract REs corresponding to the PUCCH from the given subframe across all
% receive antennas and channel estimates
[pucchrx1, pucchH1] = lteExtractResources(pucch1Indices, rxgrid1, H1);

% Equalization
eqgrid1 = lteULResourceGrid(ue1);   
eqgrid1(pucch1Indices) = lteEqualizeMMSE(pucchrx1, pucchH1, n0);

%
%% PUCCH 1 Decoding
% Finally the PUCCH Format 1 channel is decoded and the useful HARQ indicator bits are extracted.

rxhi1 = ltePUCCH1Decode(ue1, pucch1, length(hi1), ...
    eqgrid1(pucch1Indices));
disp('rxhi1:');
disp(rxhi1.');

%
%% Receiver for UE 2
% The uplink frame timing estimate for UE2 is calculated using the PUCCH 2 DRS signals and then used to demodulate the SC-FDMA signal. In this case, the Hybrid ARQ indicators as conveyed on the PUCCH Format 2 DRS are also found. The resulting grid rxgrid2 is a 3 dimensional matrix. To create an estimation of the channel lteULChannelEstimatePUCCH2 is used. The effect of the channel on the received resource grid is equalized using lteEqualizeMMSE. Finally the PUCCH Format 2 channel is decoded and the useful CQI information bits are extracted.

% Synchronization (and PUCCH 2 DRS demodulation/decoding)
[offset2,rxhi2] = lteULFrameOffsetPUCCH2(ue2,pucch2,rxwave,length(hi2));
disp('rxhi2:');
disp(rxhi2.');
    
% SC-FDMA demodulation
rxgrid2 = lteSCFDMADemodulate(ue2, rxwave(1+offset2:end, :));

% Channel estimation
[H2, n0] = lteULChannelEstimatePUCCH2(ue2, pucch2, cec, rxgrid2, rxhi2);

% Extract REs corresponding to the PUCCH from the given subframe across all
% receive antennas and channel estimates
[pucchrx2, pucchH2] = lteExtractResources(pucch2Indices, rxgrid2, H2);

% Equalization
eqgrid2 = lteULResourceGrid(ue2);  
eqgrid2(pucch2Indices) = lteEqualizeMMSE(pucchrx2, pucchH2, n0);

% PUCCH 2 demodulation
rxcodedcqi = ltePUCCH2Decode(ue2, pucch2, eqgrid2(pucch2Indices));

% PUCCH 2 decoding
rxcqi = lteUCIDecode(rxcodedcqi, length(cqi));
disp('rxcqi:');
disp(rxcqi.');

%
%% Display Estimated Channels
% A plot is produced showing that the channels can be estimated independently for the two different signals, even although they share the same physical REs. The PUCCH Format 1 channel estimate is shown in red and the PUCCH Format 2 channel estimate is shown in blue.

hPUCCHMixedFormatDisplay(H1, eqgrid1, H2, eqgrid2);

%
%% Appendix
% This example uses the helper function:
% hPUCCHMixedFormatDisplay.m
% Copyright 2009-2018 The MathWorks, Inc.