finish bluetooth.m; get physLayer stuff
parent
aef290e8ee
commit
611d2d5634
BIN
.bluetooth.m.swo
BIN
.bluetooth.m.swo
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
octave-workspace
|
|
@ -269,7 +269,7 @@ function setPDUField_4()
|
|||
tS2.payload = cat(2, tS2.advA, tS2.scanRspData);
|
||||
|
||||
[tS2.advA_hexStr, tS1.advA_hexStr] = mat2hexStr(tS2.advA);
|
||||
[tS2.scanRspData_hexStr, tS1.scapRspData_hexStr] = mat2hexStr(tS2.advscanRspData);
|
||||
[tS2.scanRspData_hexStr, tS1.scapRspData_hexStr] = mat2hexStr(tS2.scanRspData);
|
||||
|
||||
payload_struct(1) = tS1;
|
||||
payload_struct(2) = tS2
|
||||
|
|
BIN
octave-workspace
BIN
octave-workspace
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,14 @@
|
|||
% GFSK Parameters (Volume 6, Part A, Section 3.1 of Core_V4.0.pdf)
|
||||
samp_rate = 2e6;
|
||||
symb_rate = 1e6;
|
||||
samps_per_symb = samp_rate/symb_rate;
|
||||
time_bw_prod = 0.5; % Can vary between 0.45 and 0.55 depending on device.
|
||||
symb_span = 5;
|
||||
freq_sep = 360e3;
|
||||
gauss_taps = gauss_pulse_create(time_bw_prod,symb_span,samps_per_symb);
|
||||
|
||||
% Defined Advertising Channel Parameters
|
||||
adv_preamble = [0,1,0,1,0,1,0,1]; % (Volume 6, Part B, Section 2.1.1 of Core_V4.0.pdf)
|
||||
adv_accessaddress = [0,1,1,0,1,0,1,1,0,1,1,1,1,1,0,1,1,0,0,1,0,0,0,1,0,1,1,1,0,0,0,1]; % (Volume 6, Part B, Section 2.1.1 of Core_V4.0.pdf)
|
||||
|
||||
preamble_proto = conv(fskmod(([adv_preamble,adv_accessaddress]),2,freq_sep,samps_per_symb,samp_rate),gauss_taps);
|
|
@ -0,0 +1,179 @@
|
|||
function z = fskdemod(y,M,freq_sep,nSamp,varargin)
|
||||
%FSKDEMOD Frequency shift keying demodulation
|
||||
% Z = FSKDEMOD(Y,M,FREQ_SEP,NSAMP) noncoherently demodulates the complex
|
||||
% envelope Y of a signal using the frequency shift keying method. M is the
|
||||
% alphabet size and must be an integer power of 2. FREQ_SEP is the frequency
|
||||
% separation, and must be positive. NSAMP is the required samples per symbol
|
||||
% and must be an integer greater than 1. For two dimensional signals, the
|
||||
% function treats each column of data as one channel.
|
||||
%
|
||||
% Z = FSKDEMOD(Y,M,FREQ_SEP,NSAMP,Fs) specifies the sampling frequency (Hz).
|
||||
% The default sampling frequency is 1.
|
||||
%
|
||||
% Z = FSKDEMOD(Y,M,FREQ_SEP,NSAMP,Fs,SYMBOL_ORDER) specifies how the
|
||||
% function assigns binary words to corresponding integers. If SYMBOL_ORDER
|
||||
% is set to 'bin' (default), then the function uses a natural binary-coded
|
||||
% ordering. If SYMBOL_ORDER is set to 'gray', then the function uses a
|
||||
% Gray-coded ordering.
|
||||
%
|
||||
% See also FSKMOD, PSKDEMOD, QAMDEMOD, PAMDEMOD, OQPSKDEMOD.
|
||||
|
||||
% Copyright 1996-2012 The MathWorks, Inc.
|
||||
|
||||
|
||||
% Error checks -----------------------------------------------------------------
|
||||
if (nargin < 4)
|
||||
error(message('comm:fskdemod:numarg1'));
|
||||
end
|
||||
|
||||
if (nargin > 6)
|
||||
error(message('comm:fskdemod:numarg2'));
|
||||
end
|
||||
|
||||
% Check that M is a positive integer
|
||||
if (~isreal(M) || ~isscalar(M) || M<2 || (ceil(M)~=M) || ~isnumeric(M))
|
||||
error(message('comm:fskdemod:Mreal'));
|
||||
end
|
||||
|
||||
% Check that M is of the form 2^K
|
||||
if(~isnumeric(M) || ceil(log2(M)) ~= log2(M))
|
||||
error(message('comm:fskdemod:Mpow2'));
|
||||
end
|
||||
|
||||
% Check that the FREQ_SEP is greater than 0
|
||||
if( ~isnumeric(freq_sep) || ~isscalar(freq_sep) || freq_sep<=0 )
|
||||
error(message('comm:fskdemod:freqSep'));
|
||||
end
|
||||
|
||||
% Check that NSAMP is an integer greater than 1
|
||||
if((~isnumeric(nSamp) || (ceil(nSamp) ~= nSamp)) || (nSamp <= 1))
|
||||
error(message('comm:fskdemod:nSampPos'));
|
||||
end
|
||||
|
||||
% Check Fs
|
||||
if (nargin >= 5)
|
||||
Fs = varargin{1};
|
||||
if (isempty(Fs))
|
||||
Fs = 1;
|
||||
elseif (~isreal(Fs) || ~isscalar(Fs) || ~isnumeric(Fs) || Fs<=0 )
|
||||
error(message('comm:fskdemod:FsReal'));
|
||||
end
|
||||
else
|
||||
Fs = 1;
|
||||
end
|
||||
|
||||
% Check that the maximum transmitted frequency does not exceed Fs/2
|
||||
maxFreq = ((M-1)/2) * freq_sep;
|
||||
if (maxFreq > Fs/2)
|
||||
error(message('comm:fskdemod:maxFreq'));
|
||||
end
|
||||
|
||||
% Check SYMBOL_ORDER
|
||||
if(nargin==4 || nargin==5 )
|
||||
Symbol_Ordering = 'bin'; %default
|
||||
else
|
||||
Symbol_Ordering = varargin{2};
|
||||
if (~ischar(Symbol_Ordering)) || (~strcmpi(Symbol_Ordering,'GRAY')) && (~strcmpi(Symbol_Ordering,'BIN'))
|
||||
error(message('comm:fskdemod:SymbolOrder'));
|
||||
end
|
||||
end
|
||||
|
||||
% End of error checks ----------------------------------------------------------
|
||||
|
||||
|
||||
% Assure that Y, if one dimensional, has the correct orientation
|
||||
wid = size(y,1);
|
||||
if(wid ==1)
|
||||
y = y(:);
|
||||
end
|
||||
[nRows, nChan] = size(y);
|
||||
|
||||
% Preallocate memory
|
||||
z = zeros(nRows/nSamp, nChan);
|
||||
|
||||
% Define the frequencies used for the demodulator.
|
||||
freqs = (-(M-1)/2 : (M-1)/2) * freq_sep;
|
||||
|
||||
% Use the frequencies to generate M complex tones which will be multiplied with
|
||||
% each received FSK symbol. The tones run down the columns of the "tones"
|
||||
% matrix.
|
||||
t = (0 : 1/Fs : nSamp/Fs - 1/Fs)';
|
||||
phase = 2*pi*t*freqs;
|
||||
tones = exp(-1i*phase);
|
||||
|
||||
% For each FSK channel, multiply the complex received signal with the M complex
|
||||
% tones. Then perform an integrate and dump over each symbol period, find the
|
||||
% magnitude, and choose the transmitted symbol corresponding to the maximum
|
||||
% magnitude.
|
||||
for iChan = 1 : nChan % loop for each FSK channel
|
||||
|
||||
for iSym = 1 : nRows/nSamp
|
||||
|
||||
% Load the samples for the current symbol
|
||||
yTemp = y( (iSym-1)*nSamp+1 : iSym*nSamp, iChan);
|
||||
|
||||
% Replicate the received FSK signal to multiply with the M tones
|
||||
yTemp = yTemp(:, ones(M,1));
|
||||
|
||||
% Multiply against the M tones
|
||||
yTemp = yTemp .* tones;
|
||||
|
||||
% Perform the integrate and dump, then get the magnitude. Use a
|
||||
% subfunction for the integrate and dump, to omit the error checking.
|
||||
yMag = abs(intanddump(yTemp, nSamp));
|
||||
|
||||
% Choose the maximum and assign an integer value to it. Subtract 1 from the
|
||||
% output of MAX because the integer outputs are zero-based, not one-based.
|
||||
[~, maxIdx] = max(yMag, [], 2);
|
||||
|
||||
z(iSym,iChan) = maxIdx - 1;
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
% Restore the output signal to the original orientation
|
||||
if(wid == 1)
|
||||
z = z';
|
||||
end
|
||||
|
||||
% Gray decode if necessary
|
||||
if (strcmpi(Symbol_Ordering,'GRAY'))
|
||||
[~,gray_map] = gray2bin(z,'fsk',M); % Gray decode
|
||||
% --- Assure that X, if one dimensional, has the correct orientation --- %
|
||||
if(size(z,1) == 1)
|
||||
temp = zeros(size(z));
|
||||
temp(:) = gray_map(z+1);
|
||||
z(:) = temp(:);
|
||||
else
|
||||
z = gray_map(z+1);
|
||||
end
|
||||
end
|
||||
|
||||
% EOF -- fskdemod.m
|
||||
|
||||
|
||||
% ------------------------------------------------------------------------------
|
||||
function y = intanddump(x, Nsamp)
|
||||
%INTANDDUMP Integrate and dump.
|
||||
% Y = INTANDDUMP(X, NSAMP) integrates the signal X for 1 symbol period, then
|
||||
% outputs one value into Y. NSAMP is the number of samples per symbol.
|
||||
% For two-dimensional signals, the function treats each column as 1
|
||||
% channel.
|
||||
%
|
||||
|
||||
% --- Assure that X, if one dimensional, has the correct orientation --- %
|
||||
wid = size(x,1);
|
||||
if(wid ==1)
|
||||
x = x(:);
|
||||
end
|
||||
|
||||
[xRow, xCol] = size(x);
|
||||
x = mean(reshape(x, Nsamp, xRow*xCol/Nsamp), 1);
|
||||
y = reshape(x, xRow/Nsamp, xCol);
|
||||
|
||||
% --- restore the output signal to the original orientation --- %
|
||||
if(wid == 1)
|
||||
y = y.';
|
||||
end
|
||||
|
||||
% EOF --- intanddump.m
|
|
@ -0,0 +1,192 @@
|
|||
function y = fskmod(x,M,freq_sep,nSamp,varargin)
|
||||
%FSKMOD Frequency shift keying modulation
|
||||
% Y = FSKMOD(X,M,FREQ_SEP,NSAMP) outputs the complex envelope of the
|
||||
% modulation of the message signal X using frequency shift keying modulation. M
|
||||
% is the alphabet size and must be an integer power of two. The message
|
||||
% signal must consist of integers between 0 and M-1. FREQ_SEP is the desired
|
||||
% separation between successive frequencies, in Hz. NSAMP denotes the number
|
||||
% of samples per symbol and must be an integer greater than 1. For two
|
||||
% dimensional signals, the function treats each column as one channel.
|
||||
%
|
||||
% Y = FSKMOD(X,M,FREQ_SEP,NSAMP,FS) specifies the sampling frequency (Hz).
|
||||
% The default sampling frequency is 1.
|
||||
%
|
||||
% Y = FSKMOD(X,M,FREQ_SEP,NSAMP,FS,PHASE_CONT) specifies the phase continuity
|
||||
% across FSK symbols. PHASE_CONT can be either 'cont' for continuous phase,
|
||||
% or 'discont' for discontinuous phase. The default is 'cont'.
|
||||
%
|
||||
% Y = FSKMOD(X,M,FREQ_SEP,NSAMP,Fs,PHASE_CONT,SYMBOL_ORDER) specifies how the
|
||||
% function assigns binary words to corresponding integers. If SYMBOL_ORDER is
|
||||
% set to 'bin' (default), then the function uses a natural binary-coded
|
||||
% ordering. If SYMBOL_ORDER is set to 'gray', then the function uses a
|
||||
% Gray-coded ordering.
|
||||
%
|
||||
% See also FSKDEMOD, PSKMOD, QAMMOD, PAMMOD, OQPSKMOD.
|
||||
|
||||
% Copyright 1996-2012 The MathWorks, Inc.
|
||||
|
||||
|
||||
% Error checks -----------------------------------------------------------------
|
||||
if (nargin < 4)
|
||||
error(message('comm:fskmod:numarg1'));
|
||||
end
|
||||
|
||||
if (nargin > 7)
|
||||
error(message('comm:fskmod:numarg2'));
|
||||
end
|
||||
|
||||
% Check X
|
||||
if (~isreal(x) || any(any(ceil(x) ~= x)) || ~isnumeric(x))
|
||||
error(message('comm:fskmod:xreal1'));
|
||||
end
|
||||
|
||||
% Check that M is a positive integer
|
||||
if (~isreal(M) || ~isscalar(M) || M<2 || (ceil(M)~=M) || ~isnumeric(M))
|
||||
error(message('comm:fskmod:Mreal'));
|
||||
end
|
||||
|
||||
% Check that M is of the form 2^K
|
||||
if(~isnumeric(M) || ceil(log2(M)) ~= log2(M))
|
||||
error(message('comm:fskmod:Mpow2'));
|
||||
end
|
||||
|
||||
%Check that all X are integers within [0,M-1]
|
||||
if ((min(min(x)) < 0) || (max(max(x)) > (M-1)))
|
||||
error(message('comm:fskmod:xreal2'));
|
||||
end
|
||||
|
||||
% Check that the FREQ_SEP is greater than 0
|
||||
if( ~isnumeric(freq_sep) || ~isscalar(freq_sep) || freq_sep<=0 )
|
||||
error(message('comm:fskmod:freqSep'));
|
||||
end
|
||||
|
||||
% Check that NSAMP is an integer greater than 1
|
||||
if((~isnumeric(nSamp) || (ceil(nSamp) ~= nSamp)) || (nSamp <= 1))
|
||||
error(message('comm:fskmod:nSampPos'));
|
||||
end
|
||||
|
||||
% Check Fs
|
||||
if (nargin >= 5)
|
||||
Fs = varargin{1};
|
||||
if (isempty(Fs))
|
||||
Fs = 1;
|
||||
elseif (~isreal(Fs) || ~isscalar(Fs) || ~isnumeric(Fs) || Fs<=0)
|
||||
error(message('comm:fskmod:FsReal'));
|
||||
end
|
||||
else
|
||||
Fs = 1;
|
||||
end
|
||||
samptime = 1/Fs;
|
||||
|
||||
% Check that the maximum transmitted frequency does not exceed Fs/2
|
||||
maxFreq = ((M-1)/2) * freq_sep;
|
||||
if (maxFreq > Fs/2)
|
||||
error(message('comm:fskmod:maxFreq'));
|
||||
end
|
||||
|
||||
% Check if the phase is continuous or discontinuous
|
||||
if (nargin >= 6)
|
||||
phase_type = varargin{2};
|
||||
%check the phase_type string
|
||||
if ~( strcmpi(phase_type,'cont') || strcmpi(phase_type,'discont') )
|
||||
error(message('comm:fskmod:phaseCont'));
|
||||
end
|
||||
|
||||
else
|
||||
phase_type = 'cont';
|
||||
end
|
||||
|
||||
if (strcmpi(phase_type, 'cont'))
|
||||
phase_cont = 1;
|
||||
else
|
||||
phase_cont = 0;
|
||||
end
|
||||
|
||||
% Check SYMBOL_ORDER
|
||||
if(nargin >= 4 && nargin <= 6 )
|
||||
Symbol_Ordering = 'bin'; % default
|
||||
else
|
||||
Symbol_Ordering = varargin{3};
|
||||
if (~ischar(Symbol_Ordering)) || (~strcmpi(Symbol_Ordering,'GRAY')) && (~strcmpi(Symbol_Ordering,'BIN'))
|
||||
error(message('comm:fskmod:SymbolOrder'));
|
||||
end
|
||||
end
|
||||
|
||||
% End of error checks ----------------------------------------------------------
|
||||
|
||||
|
||||
% Assure that X, if one dimensional, has the correct orientation
|
||||
wid = size(x,1);
|
||||
if (wid == 1)
|
||||
x = x(:);
|
||||
end
|
||||
|
||||
% Gray encode if necessary
|
||||
if (strcmpi(Symbol_Ordering,'GRAY'))
|
||||
[~,gray_map] = bin2gray(x,'fsk',M); % Gray encode
|
||||
[~,index]=ismember(x,gray_map);
|
||||
x=index-1;
|
||||
end
|
||||
|
||||
% Obtain the total number of channels
|
||||
[nRows, nChan] = size(x);
|
||||
|
||||
% Initialize the phase increments and the oscillator phase for modulator with
|
||||
% discontinuous phase.
|
||||
phaseIncr = (0:nSamp-1)' * (-(M-1):2:(M-1)) * 2*pi * freq_sep/2 * samptime;
|
||||
% phIncrSym is the incremental phase over one symbol, across all M tones.
|
||||
phIncrSym = phaseIncr(end,:);
|
||||
% phIncrSamp is the incremental phase over one sample, across all M tones.
|
||||
phIncrSamp = phaseIncr(2,:); % recall that phaseIncr(1,:) = 0
|
||||
OscPhase = zeros(nChan, M);
|
||||
|
||||
% phase = nSamp*# of symbols x # of channels
|
||||
Phase = zeros(nSamp*nRows, nChan);
|
||||
|
||||
% Special case for discontinuous-phase FSK: can use a table look-up for speed
|
||||
if ( (~phase_cont) && ...
|
||||
( floor(nSamp*freq_sep/2 * samptime) == nSamp*freq_sep/2 * samptime ) )
|
||||
exp_phaseIncr = exp(1i*phaseIncr);
|
||||
y = reshape(exp_phaseIncr(:,x+1),nRows*nSamp,nChan);
|
||||
else
|
||||
for iChan = 1:nChan
|
||||
prevPhase = 0;
|
||||
for iSym = 1:nRows
|
||||
% Get the initial phase for the current symbol
|
||||
if (phase_cont)
|
||||
ph1 = prevPhase;
|
||||
else
|
||||
ph1 = OscPhase(iChan, x(iSym,iChan)+1);
|
||||
end
|
||||
|
||||
% Compute the phase of the current symbol by summing the initial phase
|
||||
% with the per-symbol phase trajectory associated with the given M-ary
|
||||
% data element.
|
||||
Phase(nSamp*(iSym-1)+1:nSamp*iSym,iChan) = ...
|
||||
ph1*ones(nSamp,1) + phaseIncr(:,x(iSym,iChan)+1);
|
||||
|
||||
% Update the oscillator for a modulator with discontinuous phase.
|
||||
% Calculate the phase modulo 2*pi so that the phase doesn't grow too
|
||||
% large.
|
||||
if (~phase_cont)
|
||||
OscPhase(iChan,:) = ...
|
||||
rem(OscPhase(iChan,:) + phIncrSym + phIncrSamp, 2*pi);
|
||||
end
|
||||
|
||||
% If in continuous mode, the starting phase for the next symbol is the
|
||||
% ending phase of the current symbol plus the phase increment over one
|
||||
% sample.
|
||||
prevPhase = Phase(nSamp*iSym,iChan) + phIncrSamp(x(iSym,iChan)+1);
|
||||
end
|
||||
end
|
||||
y = exp(1i*Phase);
|
||||
end
|
||||
|
||||
% Restore the output signal to the original orientation
|
||||
if(wid == 1)
|
||||
y = y.';
|
||||
end
|
||||
|
||||
% EOF --- fskmod.m
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Purpose: Creates the filter taps for the gaussian pulse shaping
|
||||
% filter.
|
||||
%
|
||||
% Inputs: * bt - time bandwidth product of gaussian pulse
|
||||
% shape
|
||||
% * symb_span - pulse overlap (integer number of
|
||||
% symbols)
|
||||
% * samps_per_symb - number of samples per symbol
|
||||
%
|
||||
% Output: * filt_taps - the filter taps for the created gaussian
|
||||
% pulse shape
|
||||
%
|
||||
% Notes: * Error checking not yet implemented.
|
||||
%
|
||||
% Author: William C. Headley
|
||||
%
|
||||
% Last Updated: 8/18/2016
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
function filt_taps = gauss_pulse_create(bt, symb_span, samps_per_symb)
|
||||
range = samps_per_symb*symb_span/2;
|
||||
alpha = sqrt(log(2))/sqrt(2) * (1/bt);
|
||||
|
||||
indices = -range:range;
|
||||
|
||||
filt_taps = sqrt(pi)/alpha * exp(-(pi/alpha * indices/samps_per_symb).^2);
|
||||
filt_taps = filt_taps/sum(filt_taps);
|
||||
end
|
|
@ -0,0 +1,39 @@
|
|||
%
|
||||
% Copyright 2001 Free Software Foundation, Inc.
|
||||
%
|
||||
% This file is part of GNU Radio
|
||||
%
|
||||
% GNU Radio is free software; you can redistribute it and/or modify
|
||||
% it under the terms of the GNU General Public License as published by
|
||||
% the Free Software Foundation; either version 3, or (at your option)
|
||||
% any later version.
|
||||
%
|
||||
% GNU Radio is distributed in the hope that it will be useful,
|
||||
% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
% GNU General Public License for more details.
|
||||
%
|
||||
% You should have received a copy of the GNU General Public License
|
||||
% along with GNU Radio; see the file COPYING. If not, write to
|
||||
% the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
% Boston, MA 02110-1301, USA.
|
||||
%
|
||||
|
||||
function v = read_complex_binary (filename, count)
|
||||
narginchk (1,2);
|
||||
|
||||
if (nargin < 2)
|
||||
count = Inf;
|
||||
end
|
||||
|
||||
f = fopen (filename, 'rb');
|
||||
if (f < 0)
|
||||
v = 0;
|
||||
else
|
||||
t = fread (f, [2, count], 'float');
|
||||
fclose (f);
|
||||
v = t(1,:) + t(2,:)*1i;
|
||||
[r, c] = size (v);
|
||||
v = reshape (v, c, r);
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue