Commit 2414e7a2 authored by Stewart Thomas's avatar Stewart Thomas
Browse files

Adds support scripts and BOM

parent 1b1868b0
% EXAMPLE OF READING IN S1P FILE FORMAT
dir = 'C:\Users\sthoma11\Desktop\';
fname = 'hw2problem3.s1p';
H = dlmread([dir, fname], ' ', 3, 0);
f = H(:, 1);
db = H(:, 2);
angdeg = H(:, 3);
mag = 10 .^ (db ./ 20);
Gre = mag .* cos(pi*angdeg/180);
Gim = mag .* sin(angdeg*pi/180);
Gamma = Gre + 1j*Gim;
Zl = 50 * (1 + Gamma)./(1 - Gamma);
figure(1);clf;
smithchart()
h = plot(Gamma);
set(h, 'linewidth', 2)
n = length(f);
fc = f(n/2);
fprintf('The impedance at %3.2f MHz is %.2f + %.2fj Ohms\n', fc*1e-6, real(Zl(n/2)), imag(Zl(n/2)));
% implement matching
l1 = 10e-9;
l2 = 28e-9;
c1 = 10e-12;
Rl1 = (2 * pi * f * l1) ./ (20);
Rl2 = (2 * pi * f * l2) ./ (20);
Rc1 = 1 ./ (2 * pi * f * c1);
Zl1 = Rl1 + 1j*2*pi*f*l1;
Zl2 = Rl2 + 1j*2*pi*f*l2;
Zc2 = Rc1 + 1 ./ (1j * 2 * pi * f * c1);
% For ignoring Q
%Zl1 = 0 + 1j*2*pi*f*l1;
%Zl2 = 0 + 1j*2*pi*f*l2;
%Zc2 = 0 + 1 ./ (1j * 2 * pi * f * c1);
% add shunt l
Zm1 = 1 ./ ( (1 ./ Zl) + ( 1 ./ Zl1) );
gm1 = (Zm1 - 50) ./ (Zm1 + 50);
plot(gm1)
% add series l
Zm2 = Zl2 + Zm1;
gm2 = (Zm2 - 50) ./ (Zm2 + 50);
plot(gm2)
h = plot(gm2(n/2));
set(h, 'linewidth', 4, 'marker', 'o', 'color', 'r', 'linestyle', 'none');
legend(h, 'Matched 915 MHz')
clear all;
syms('r');
fmhz = 915;
s = fmhz / 300;
dBm = 27;
pt = 10^(dBm/10); % mW
dbi = 8; % ant. gain (dBi)
eqn = fmhz/300 == pt * 10^(dbi/10) / (4 * pi * (r)^2);
soln = solve(eqn, r);
dist = eval( soln(soln > 0));
fprintf('********\nMaximum permissible exposure:\n')
fprintf('Distance is %.3f cm\n', dist);
fprintf('or rather, %.3f feet\n', dist * 0.0328084 );
eqn = fmhz/1500 == pt * 10^(dbi/10) / (4 * pi * (r)^2);
soln = solve(eqn, r);
dist = eval( soln(soln > 0));
fprintf('********\nLimits for general population:\n')
fprintf('Distance is %.3f cm\n', dist);
fprintf('or rather, %.3f feet\n', dist * 0.0328084 );
\ No newline at end of file
% EXAMPLE OF READING IN S1P FILE FORMAT
dir = 'C:\Users\sthoma11\vnaJ.3.1\export\';
fname = 'VNA_160906_152229.s1p';
H = dlmread([dir, fname], ' ', 3, 0);
f = H(:, 1);
db = H(:, 2);
angdeg = H(:, 3);
mag = 10 .^ (db ./ 20);
Gre = mag .* cos(pi*ang/180);
Gim = mag .* sin(ang*pi/180);
Gamma = complex(Gre, Gim);
plot(real(Gamma), imag(Gamma));
xlim([-1, 1]);
ylim([-1, 1]);
axis equal;
\ No newline at end of file
addpath('C:\Program Files\bladeRF\matlab');
%dev = bladeRF();
%bladeRF_rx_gui;
clear;
fprintf('\nWelcome to the BladeRF Power Exhibitor 9000\nShould you have any questions, please do not consult the help file.\nThis MATLAB program has not been tested or validated by the FCC to be safe for human consumption. Or use.\nHappy Hacking!\n -Rick Ley\n\n');
fprintf('**********\n');
try
dev = bladeRF();
catch ME
if(strfind(ME.message, 'error (-7)'))
fprintf(ME.message);
fprintf('\n ***\n## Did you remember to plug it in? ##\n');
return;
end
end
%%
% equation is: output power = -15 + vga1 + vga2
fc = 915e6;
fs = 10e6;
bw = 1e6;
vga1 = -15;
vga2 = 25;
%pw = 0.88274 * vga2 + (vga1 -14.1670);
while(1)
pw = input('Enter power in dBm (leave blank to exit):');
%pw = str2num(strPow);
if isempty(pw)
break;
end
if (pw < -28) || (pw > -8)
fprintf('I''m sorry, but that is out of range.\nPlease provide a power level bewteen -28 and -8 dBm\n');
continue;
end
% calculate new power level
vga2 = (pw - (vga1 -14.1670))/0.88274;
dev.tx.stop();
dev.tx.frequency = fc;
dev.tx.samplerate = fs;
dev.tx.bandwidth = bw;
dev.tx.vga1 = vga1; % max of -4, min of -25
dev.tx.vga2 = vga2; % max of 25, min of 0
dev.tx.config.num_buffers = 64;
dev.tx.config.buffer_size = 16384;
dev.tx.config.num_transfers = 16;
dev.tx.start();
dev.transmit(ones(fs,1));
end
%%
fprintf('**********\n');
fprintf('**********\n');
fprintf('Thanks, and remember to drink your Ovaltine!\n\n')
dev.tx.stop();
clear('dev');
% A simple bladeRF demo GUI that receives and plots samples
%
% Once the GUI starts, select a device from the dropdown of available
% devices, and then click "start" to begin streaming samples.
%
% The various GUI widgets may be used to change the plot mode, frequency,
% gains, correction values, sample rate, and LPF bandwidth.
%
% Note that stream settings may only be changed whe the device is not
% actively streaming.
%
% Copyright (c) 2015 Nuand LLC
%
% Permission is hereby granted, free of charge, to any person obtaining a copy
% of this software and associated documentation files (the "Software"), to deal
% in the Software without restriction, including without limitation the rights
% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
% copies of the Software, and to permit persons to whom the Software is
% furnished to do so, subject to the following conditions:
%
% The above copyright notice and this permission notice shall be included in
% all copies or substantial portions of the Software.
%
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
% THE SOFTWARE.
%
function varargout = bladeRF_fft(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @bladeRF_fft_OpeningFcn, ...
'gui_OutputFcn', @bladeRF_fft_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
end
function set_bandwidth_selection(bandwidth_widget, value)
strings = bandwidth_widget.String;
for n = 1:length(strings)
if value == (str2num(strings{n}) * 1e6)
bandwidth_widget.Value = n;
end
end
end
function set_lnagain_selection(lnagain_widget, value)
strings = lnagain_widget.String;
for n = 1:length(strings)
if strcmpi(strings{n}, value)
lnagain_widget.Value = n;
end
end
end
function update_plot_selection(hObject, handles)
plots = get_plots(hObject);
id = handles.displaytype.Value;
if id < 1 || id > length(plots)
error('Bug: Got invalid display type ID');
end
for n = 1:length(plots)
if n == id
for l = 1:length(plots{n}.lines)
plots{n}.lines(l).Visible = 'on';
%fprintf('plot %s ch %d = %s\n', plots{n}.name, l, plots{n}.lines(l).Visible);
end
else
for l = 1:length(plots{n}.lines)
plots{n}.lines(l).Visible = 'off';
%fprintf('plot %s ch %d = %s\n', plots{n}.name, l, plots{n}.lines(l).Visible);
end
end
end
num_samples = get_num_samples(hObject);
% Reset data so we don't see "random" junk when switching displays
switch plots{id}.name
case { 'FFT (dB)', 'FFT (linear)' }
x = linspace(double(plots{id}.xmin), double(plots{id}.xmax), num_samples);
plots{id}.lines(1).XData = x;
plots{id}.lines(1).YData = zeros(num_samples, 1) - plots{id}.ymin;
case 'Time (2-Channel)'
x = linspace(double(plots{id}.xmin), double(plots{id}.xmax), num_samples);
plots{id}.lines(1).XData = x;
plots{id}.lines(1).YData = zeros(num_samples, 1);
plots{id}.lines(2).XData = x;
plots{id}.lines(2).YData = zeros(num_samples, 1);
case 'Time (XY)'
plots{id}.lines(1).XData = zeros(num_samples, 1);
plots{id}.lines(1).YData = zeros(num_samples, 1);
end
% Update the axes limits for this plot
handles.axes1.XLim = [plots{id}.xmin plots{id}.xmax];
handles.axes1.YLim = [plots{id}.ymin plots{id}.ymax];
% Update the axis labels
xlabel(handles.axes1, plots{id}.xlabel);
ylabel(handles.axes1, plots{id}.ylabel);
end
% Get the handle to the GUI's root object
function [root] = get_root_object(hObject)
if strcmp(hObject.Type, 'root')
root = hObject;
else
root = get_root_object(hObject.Parent);
end
end
% Get the state of the 'Print Overruns' flag
function [print_overruns] = get_print_overruns(hObject)
root = get_root_object(hObject);
print_overruns = getappdata(root, 'print_overruns');
if isempty(print_overruns)
error('Failed to access app data: print_overruns');
end
end
% Set the state of the 'Print Overruns' flag
function set_print_overruns(hObject, value)
root = get_root_object(hObject);
setappdata(root, 'print_overruns', value);
end
% Get the number of samples that are retrieved from the device per RX
function [num_samples] = get_num_samples(hObject)
root = get_root_object(hObject);
num_samples = getappdata(root, 'num_samples');
if isempty(num_samples)
error('Failed to access app data: num_samples');
end
end
% Get the array of plots
function [plots] = get_plots(hObject)
root = get_root_object(hObject);
plots = getappdata(root, 'plots');
if isempty(plots)
error('Failed to access app data: plot');
end
end
% Apply updates to plot configuration
function set_plots(hObject, plots)
root = get_root_object(hObject);
setappdata(root, 'plots', plots);
end
% Get the frame rate configuration
function [fps] = get_framerate(hObject)
root = get_root_object(hObject);
fps = getappdata(root, 'framerate');
end
% Set the fraem rate configuration
function set_framerate(hObject, fps)
root = get_root_object(hObject);
setappdata(root, 'framerate', fps);
end
function update_plot_axes(hObject, handles)
plots = get_plots(hObject);
Fc = handles.bladerf.rx.frequency;
Fs = handles.bladerf.rx.samplerate;
num_samples = get_num_samples(hObject);
% Update the axes limits of all plots
for id = 1:length(plots)
switch plots{id}.name
case 'FFT (dB)'
plots{id}.xmin = (Fc - Fs/2);
plots{id}.xmax = (Fc + Fs/2);
plots{id}.ymin = -110;
plots{id}.ymax = 0;
% Ensure the X values are updated, as these are not updated every read
if id == handles.displaytype.Value
x = linspace(double(plots{id}.xmin), double(plots{id}.xmax), num_samples);
plots{id}.lines(1).XData = x;
end
case 'FFT (linear)'
plots{id}.xmin = (Fc - Fs/2);
plots{id}.xmax = (Fc + Fs/2);
plots{id}.ymin = 0;
plots{id}.ymax = 1;
% Ensure the X values are updated, as these are not updated every read
if id == handles.displaytype.Value
x = linspace(double(plots{id}.xmin), double(plots{id}.xmax), num_samples);
plots{id}.lines(1).XData = x;
end
case 'Time (2-Channel)'
plots{id}.xmin = 0;
plots{id}.xmax = (num_samples - 1) / Fs;
plots{id}.ymin = -1.2;
plots{id}.ymax = 1.2;
case 'Time (XY)'
plots{id}.xmin = -1.2;
plots{id}.xmax = 1.2;
plots{id}.ymin = -1.2;
plots{id}.ymax = 1.2;
otherwise
error('Invalid plot type encountered');
end
% Update the current plot axes
if id == handles.displaytype.Value
handles.axes1.XLim = [plots{id}.xmin plots{id}.xmax];
handles.axes1.YLim = [plots{id}.ymin plots{id}.ymax];
end
end
set_plots(hObject, plots);
end
function [plot_info] = init_plot_type(hObject, handles, type)
plot_info.name = type;
blue = [0 0 1];
red = [1 0 0];
num_samples = get_num_samples(hObject);
x = zeros(num_samples, 1);
y = zeros(num_samples, 1);
switch type
case { 'FFT (dB)', 'FFT (linear)' }
plot_info.xlabel = 'Frequency (MHz)';
plot_info.ylabel = 'Power (dB)';
plot_info.lines(1) = line(x, y);
plot_info.lines(1).Color = blue;
plot_info.lines(1).Marker = 'none';
plot_info.lines(1).LineStyle = '-';
case 'Time (2-Channel)'
plot_info.xlabel = 'Time (s)';
plot_info.ylabel = 'Sample Values (I: Blue, Q: Red)';
plot_info.lines(1) = line(x, y);
plot_info.lines(1).Color = blue;
plot_info.lines(1).Marker = 'none';
plot_info.lines(1).LineStyle = '-';
plot_info.lines(2) = line(x, y);
plot_info.lines(2).Color = red;
plot_info.lines(2).Marker = 'none';
plot_info.lines(2).LineStyle = '-';
case 'Time (XY)'
plot_info.xlabel = 'I Value';
plot_info.ylabel = 'Q Value';
plot_info.lines(1) = line(x, y);
plot_info.lines(1).Color = blue;
plot_info.lines(1).Marker = '.';
plot_info.lines(1).LineStyle = 'none';
plot_info.lines(1).Visible = 'off';
otherwise
error('Invalid plot type encountered');
end
end
% Update GUI fields with parameter values from device
function read_device_parameters(hObject, handles)
handles.vga1.String = num2str(handles.bladerf.rx.vga1);
handles.vga2.String = num2str(handles.bladerf.rx.vga2);
set_lnagain_selection(handles.lnagain, handles.bladerf.rx.lna);
handles.corr_dc_i.String = num2str(handles.bladerf.rx.corrections.dc_i);
handles.corr_dc_q.String = num2str(handles.bladerf.rx.corrections.dc_q);
handles.corr_gain.String = num2str(handles.bladerf.rx.corrections.gain);
handles.corr_phase.String = num2str(handles.bladerf.rx.corrections.phase);
handles.frequency.String = num2str(handles.bladerf.rx.frequency);
handles.samplerate.String = num2str(handles.bladerf.rx.samplerate);
set_bandwidth_selection(handles.bandwidth, handles.bladerf.rx.bandwidth);
handles.num_buffers.String = num2str(handles.bladerf.rx.config.num_buffers);
handles.buffer_size.String = num2str(handles.bladerf.rx.config.buffer_size);
handles.num_transfers.String = num2str(handles.bladerf.rx.config.num_transfers);
guidata(hObject, handles);
end
function bladeRF_fft_OpeningFcn(hObject, ~, handles, varargin)
% Choose default command line output for bladeRF_fft
handles.output = hObject;
% UIWAIT makes bladeRF_fft wait for user response (see UIRESUME)
% uiwait(handles.figure1);
handles.bladerf = bladeRF('*:instance=0');
read_device_parameters(hObject, handles);
handles.bladerf.rx.config.num_buffers = 64;
handles.bladerf.rx.config.buffer_size = 16384;
handles.bladerf.rx.config.timeout_ms = 5000;
handles.print_overruns.Value = 0;
setappdata(hObject.Parent, 'print_overruns', 0);
setappdata(hObject.Parent, 'run', 0);
% Number of samples we'll read from the device at each iteraion
setappdata(hObject.Parent, 'num_samples', 40960);
% Default frame rate
setappdata(hObject.Parent, 'framerate', 15);
handles.framerate.String = '15';
% Create plot information for each type of lot
type_strs = handles.displaytype.String;
plots = cell(1, length(type_strs));
for n = 1:length(plots)
plots{n} = init_plot_type(hObject.Parent, handles, type_strs{n});
end
setappdata(hObject.Parent, 'plots', plots);
update_plot_axes(hObject, handles);
update_plot_selection(hObject.Parent, handles);
% Set Power:
fc = 915e6;
fs = 10e6;
bw = 1e6;
vga1 = -15;
vga2 = 25;
pw = -8;
vga2 = (pw - (vga1 -14.1670))/0.88274;
handles.bladerf.tx.stop();
handles.bladerf.tx.frequency = fc;
handles.bladerf.tx.samplerate = fs;
handles.bladerf.tx.bandwidth = bw;
handles.bladerf.tx.vga1 = vga1; % max of -4, min of -25
handles.bladerf.tx.vga2 = vga2; % max of 25, min of 0
handles.bladerf.tx.config.num_buffers = 64;
handles.bladerf.tx.config.buffer_size = 16384;
handles.bladerf.tx.config.num_transfers = 16;
handles.bladerf.tx.start();
handles.bladerf.transmit(ones(fs,1));
%% DONE
% Update handles structure
guidata(hObject, handles);
end
function varargout = bladeRF_fft_OutputFcn(~, ~, handles)
varargout{1} = handles.output;
end
function displaytype_Callback(hObject, ~, handles)
update_plot_selection(hObject.Parent.Parent, handles);
end
function displaytype_CreateFcn(hObject, ~, ~)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))</