% Q1	Hand calculate the maximal-length sequence of length 2^4 – 1, 
% defined by the taps: [1, 4 ] ( = [ 1 0 0 0 1 1 ]).  Show your work 
% on paper.  Draw the LFSR including the combinational logic.
% 
% Q2	Write a matlab function “function prbs = pnGen( m, taps )”.  Use
% it to  compute the same sequence generated in Q1.  Verify its operation
% with the following lines of code:

m = 4;
taps = [ 1 4 ];
prbs = pnGen( m, taps )

m = 9;
taps = [ 9 5 ];
s = pnGen( m, taps );

% Q3: Show the result of the next plot command:
% Q4: How high are the highest peaks?  
% Q5: How high are the other values?  
% Q6: How far apart are the peaks?
pn = 1 - 2 * s;
pn_repeat = repmat( pn(:), 10, 1 );
x = xcorr( pn, pn_repeat );
figure(1); plot( x );

% Q7: Show the result of the next plot command:
% Q8: How high are the highest peaks?  
% Q9: How high are the other values?  
% Q10: How far apart are the peaks?
m = 11;
taps = [ 11 9 ];
s = pnGen( m, taps );

pn = 1 - 2 * s;
pn_repeat = repmat( pn(:), 10, 1 );
x = xcorr( pn, pn_repeat );
figure(2); plot( x );


% Demonstrate CDMA
M = 256;

% bit sequence #1
bits = [ 1 1 0 0 1 0 1 0 0 1 ];
mapped = 1 - 2 * bits;
bits_over = repmat( mapped, M, 1 );
bits_oversamp = bits_over(:);
figure(3); plot(bits_oversamp);
[ Pb, fb ] = pwelch(bits_oversamp, [], [], [], 1e6, 'twosided' );
figure(4); plot( fb - max(fb)/2 - (fb(2)-fb(1))/2, 10*log10(fftshift(Pb)) );

% PN sequence #1: Note that transitions are M/4 times as often as in
% bits_oversamp
pn_over = repmat( pn_repeat', 4, 1 );
pn_oversamp = pn_over(:);
figure(5); plot( pn_oversamp );
[ Pp, fp ] = pwelch( pn_oversamp, [], [], [], 1e6, 'twosided' );
figure(6); plot( fp - max(fp)/2 - (fp(2)-fp(1))/2, 10*log10(fftshift(Pp)) );


% bit sequence #2
bits2 = [1 0 1 0 1 0 1 0 1 0];
mapped2 = 1 - 2 * bits2;
bits_over2 = repmat( mapped2, M, 1 );
bits_oversamp2 = bits_over2(:);
figure(11); plot(bits_oversamp2);
[ Pb, fb ] = pwelch(bits_oversamp2, [], [], [], 1e6, 'twosided' );
figure(12); plot( fb - max(fb)/2 - (fb(2)-fb(1))/2, 10*log10(fftshift(Pb)) );

% PN sequence #2.  note that PN transitions M/8 times as often as
% bits_oversamp2
pn_over2 = repmat( pn_repeat', 8, 1 );
pn_oversamp2 = pn_over2(:);
figure(13); plot( pn_oversamp2 );
[ Pp, fp ] = pwelch( pn_oversamp2, [], [], [], 1e6, 'twosided' );
figure(14); plot( fp - max(fp)/2 - (fp(2)-fp(1))/2, 10*log10(fftshift(Pp)) );

% Q11: How do the spectra differ in plots 4 and 12?  
% Q12: Compute by hand where the nulls in each spectrum should fall.  Do
% they land there in the plots?

% Q13: How do the spectra differ in plots 4 and 12?  
% Q14: Compute by hand where the nulls in each spectrum should fall.  Do
% they land there in the plots?


% Spread each bit stream and add both spread signals together to transmit
% over a channel
inds = 1:M*10;
cdma_data = bits_oversamp( inds ) .* pn_oversamp( inds ) + ...
            bits_oversamp2( inds ) .* pn_oversamp2( inds );
        
            
% Q15: What does the following plot tell you about how you might 
% synchronize the PN codes for despreading?             
figure( 40); plot( xcorr( cdma_data, pn_oversamp( 1 : M ) ) );            

% Q16: How does the CDMA signal look when despread by PN1?
x1 = cdma_data .* pn_oversamp( inds );
[ Px1, fx1 ] = pwelch( x1, [], [], [], 1e6, 'twosided' );
figure( 21 ); plot( fx1 - max(fx1)/2 - (fx1(2)-fx1(1))/2, 10*log10(fftshift(Px1)) );


bits
bits2

mf = ones( M, 1 );
mfout_oversamp = conv( mf, x1 );
mfout = mfout_oversamp( M:M:end );
hd1 = ( mfout' < 0 )
% Q17: How close does hd1 come to extracting "bits" from the CDMA stream?

% Q18: How does the CDMA signal look when despread by PN1?
x2 = cdma_data .* pn_oversamp2( inds );
[ Px2, fx2 ] = pwelch( x2, [], [], [], 1e6, 'twosided' );
figure( 22 ); plot( fx2 - max(fx2)/2 - (fx2(2)-fx2(1))/2, 10*log10(fftshift(Px2)) );

mfout_oversamp2 = conv( mf, x2 );
mfout2 = mfout_oversamp2( M:M:end );
hd2 = ( mfout2' < 0 )

% Q19: How close does hd2 come to extracting "bits2" from the CDMA stream?

