tx_bits_matrix(1:Nc,2) = tx_bits(2:Nb:Nb*Nc);
if (strcmp(modulation,'dqpsk'))
+
+
+ if 1
% map to (Nc,1) DQPSK symbols
for c=1:Nc
if ((msb == 1) && (lsb == 1))
tx_symbols(c) = -j*prev_tx_symbols(c);
endif
+ end
+ else
+ % map to pi/4 DQPSK from spra341 Eq (6) & (7)
+
+ for c=1:Nc
+
+ msb = tx_bits_matrix(c,1); lsb = tx_bits_matrix(c,2);
+ a = 2*msb - 1;
+ b = 2*lsb - 1;
+ p = prev_tx_symbols(c);
+ inphase = (real(p)*a - imag(p)*b)*0.707;
+ quadrature = (imag(p)*a + real(p)*b)*0.707;
+ tx_symbols(c) = inphase + j*quadrature;
+ end
end
+
else
% QPSK mapping
tx_symbols = -1 + 2*tx_bits_matrix(:,1) - j + 2j*tx_bits_matrix(:,2);
ber = bit_errors/Ntest_bits;
sync = 0;
- if (ber < 0.1)
+ if (ber < 0.2)
sync = 1;
endif
endfunction
freq(Nc+1) = exp(j*2*pi*Fcentre/Fs);
-global phase_tx = ones(Nc+1,1);
+% Spread initial FDM carrier phase out as far as possible.
+% This really helped PAPR. We don't need to adjust rx
+% phase a DPSK takes care of that
+
+global phase_tx = exp(j*2*pi*(0:Nc)/(Nc+1));
global phase_rx = ones(Nc+1,1);
% Freq offset estimator states
EbNo_dB = 7.3;
Foff_hz = -100;
modulation = 'dqpsk';
+hpa_clip = 10;
% ------------------------------------------------------------
rx_fdm_log = [];
rx_baseband_log = [];
rx_bits_offset = zeros(Nc*Nb*2);
-prev_tx_symbols = sqrt(2)*ones(Nc+1,1)*exp(j*pi/4);
+prev_tx_symbols = sqrt(2)*ones(Nc+1,1);
prev_tx_symbols(Nc+1) = 1;
-prev_rx_symbols = sqrt(2)*ones(Nc+1,1)*exp(j*pi/4);
+prev_rx_symbols = sqrt(2)*ones(Nc+1,1);
foff_log = [];
tx_baseband_log = [];
tx_fdm_log = [];
sync_log = [];
+bit_errors_log = [];
Ndelay = M+20;
rx_fdm_delay = zeros(Ndelay,1);
tx_baseband = tx_filter(tx_symbols);
tx_baseband_log = [tx_baseband_log tx_baseband];
[tx_fdm pilot] = fdm_upconvert(tx_baseband);
- tx_fdm_log = [tx_fdm_log tx_fdm];
tx_pwr = 0.9*tx_pwr + 0.1*real(tx_fdm)*real(tx_fdm)'/(M);
% -------------------
% Channel simulation
% -------------------
+ % HPA non-linearity
+
+ i = find(abs(tx_fdm) > hpa_clip);
+ tx_fdm(i) = hpa_clip*exp(j*angle(tx_fdm(i)));
+ tx_fdm_log = [tx_fdm_log tx_fdm];
+
+ rx_fdm = tx_fdm;
+
% frequency offset
for i=1:M
Foff = Foff_hz;
freq_offset = exp(j*2*pi*Foff/Fs);
phase_offset *= freq_offset;
- rx_fdm(i) = phase_offset*real(tx_fdm(i));
+ rx_fdm(i) = phase_offset*real(rx_fdm(i));
end
% AWGN noise
if (test_frame_sync == 1)
total_bit_errors = total_bit_errors + bit_errors;
total_bits = total_bits + Ntest_bits;
+ bit_errors_log = [bit_errors_log bit_errors];
+ else
+ bit_errors_log = [bit_errors_log -1];
end
end
% Print Stats
% ---------------------------------------------------------------------
-peak = max(real(tx_fdm_log));
-ber = total_bit_errors/total_bits;
-printf("Eb/No (meas): %2.2f (%2.2f) dB %d bits %d errors BER: (%1.4f) Pk/rms: %1.2f\n",
+ber = total_bit_errors / total_bits;
+
+% Peak to Average Power Ratio from http://www.dsplog.com
+
+papr = max(tx_fdm_log.*conj(tx_fdm_log)) / mean(tx_fdm_log.*conj(tx_fdm_log));
+papr_dB = 10*log10(papr);
+
+printf("Eb/No (meas): %2.2f (%2.2f) dB %d bits %d errors BER: (%1.4f) PAPR: %1.2f dB SNR: %2.1f dB\n",
EbNo_dB, 10*log10(0.25*tx_pwr*Fs/(Rs*Nc*noise_pwr)),
- total_bits, total_bit_errors, ber, peak/std(real(tx_fdm_log)) );
+ total_bits, total_bit_errors, ber, papr_dB, SNR );
% ---------------------------------------------------------------------
% Plots
clf;
subplot(211)
plot(real(tx_fdm_log));
+title('FDM Tx Signal');
subplot(212)
-stem(sync_log)
+Nfft=Fs;
+S=fft(rx_fdm_log,Nfft);
+SdB=20*log10(abs(S));
+plot(SdB(1:Fs/4))
+title('FDM Tx Spectrum');
+figure(4)
+clf;
+subplot(211)
+stem(sync_log)
+title('BPSK Sync')
+subplot(212)
+stem(bit_errors_log);
+title('Bit Errors for test data')
% TODO
% + handling sample slips, extra plus/minus samples