Code covered by the BSD License  

Highlights from
MPC555 Motor Control Function Blockset

MPC555 Motor Control Function Blockset

by

 

20 Mar 2006 (Updated )

Additional I/O blocks for MPC555 target - specifically targetting TPU functionality

mpc555_dptram_wizard(currentsystem, currentblock, varargin)
function mpc555_dptram_wizard(currentsystem, currentblock, varargin)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% MPC555_DPTRAM_WIZARD(CURRENTSYSTEM, CURRENTBLOCK, VARARGIN)
%
% Main function for the DPTRAM Wizard
%
% This command has two modes.  Both must be used in conjunction with the
% TPU Microcode Quick Configuration Block.
%
% Both require the Motorola TPU Microcode Assembler and the Motorola TPU
% microcode source files to be copied into a location that this blockset
% can find.
%
% Usage 1:
%
% The first mode is a graphical wizard interface.  It is called with the
% syntax:
%
% MPC555_DPTRAM_WIZARD(CURRENTSYSTEM, CURRENTBLOCK)
%
% Where CURRENTSYSTEM is the system which is to be modified and
% CURRENTBLOCK is a reference to a Microcode Quick configuration Block in
% the same model.
%
% Example:   mpc555_dptram_wizard(gcs, gcb);
%
% Usage 2:
%
% The second mode is designed for automated testing.  It just compiles the
% data as it is found stored in the block - no validation or anything.  The
% block can be automatically configured with the
% MPC555_DPTRAM_WIZARD_SET command.
%
% MPC555_DPTRAM_WIZARD(SYS, BLOCK, 'COMPILE')
%
% Example:  mpc555_dptram_wizard(gcs, gcb, 'COMPILE');
%


% Check first of all that there is a target block to use to avoid wasting
% time later on.

try
    target = RTWConfigurationCB('get_target',currentblock);
    if ~isempty(target)
        sys_res = target.findConfigForClass('MPC555dkConfig.TPU');
        sys_res1 = target.findConfigForClass('MPC555dkConfig.SYSTEM_CLOCKS');
    else
        error('No target block');
    end
catch
   error('No resource configuration in this system');
end

% Get a list of each microcode function in the library directory
microcode_files = i_get_functions('UC');
% If no microcode files, throw an error and exit
if isempty(microcode_files)
    errordlg('No microcode files found');
    return;
end
microcode_files = [{''}, microcode_files];
microcode_macros = i_get_functions('ASI');

% Try and deserialise the data from the block
dptram_res = deserialise_from_block(currentblock);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Initialise non-interactive mode
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if nargin > 2    
    % Before copying files or compiling, check that that parameters that
    % have been passed in are at least vageuly plausible.
    currentsystem = bdroot(currentblock);
    i_copy_files(dptram_res, currentsystem);
    
    % Modify the appropriate files
    if length(dptram_res.Macros) ~= 0
        for n=1:length(dptram_res)
            model_ucodefulldirname = i_getucodefulldirname(currentsystem, dptram_res);
            new_macro_filename = [model_ucodefulldirname, filesep, dptram_res.Macros{n}.Name,'.asi'];
            mpc555_tpu_mask_creator_macrorewrite(new_macro_filename, dptram_res.Macros{n}.Channels);
        end
    end
    
    % Compile the microcode
    compilesuccess = i_compile_microcode(dptram_res, currentsystem);
    if compilesuccess == 1
        % If successful set the resource config appropriately
        set_in_resource_config(dptram_res, currentblock);
    else
        % Otherwise don't
        error('Microcode did not compile properly');
    end
    return;
 end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Create the window and set the appropriate properties
h = i_wizard_window();

% Create the wizard buttons on the form
h_buttons = i_wizard_buttons(h);

% Start at the first page
current_page = 1;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% HANDLE EACH PAGE
%

dptram_res.CurrentPage = 1;

i_redraw_page(h, h_buttons, dptram_res, currentblock);
i_enable_buttons(h, h_buttons, dptram_res, currentblock);

return;

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_redraw_page(h, h_buttons, dptram_res, currentblock)

h_data = dptram_res.h_data;

if ~isstruct('h_data')
    h_data.aaa = [];
    dptram_res.h_data = h_data;
end

if dptram_res.CurrentPage == 1
    % Disable the back button
    set(h_buttons.backbutton, 'Enable', 'off');
else
    % Enable the back button
    set(h_buttons.backbutton, 'Enable', 'on');
end

switch dptram_res.CurrentPage
    case 1
        i_clear_wizard_page(dptram_res.h_data);
        dptram_res.h_data = i_draw_firstpage(h);
        i_populate_firstpage(dptram_res, currentblock);
    case 2
        i_clear_wizard_page(dptram_res.h_data);
        % Get a list of each microcode function in the library directory
        microcode_files = [{''}, i_get_functions('UC')];
        dptram_res.h_data = i_draw_secondpage(h, microcode_files, dptram_res);
        i_populate_secondpage(dptram_res, microcode_files);
    case 3
        i_clear_wizard_page(dptram_res.h_data);
        microcode_macros = i_get_functions('ASI');
        dptram_res.h_data = i_draw_thirdpage(h, microcode_macros);
        populate_thirdpage_auto(dptram_res, microcode_macros);
    case num2cell(3 + (1:length(dptram_res.Macros)))         %% Macro pages
        i_clear_wizard_page(dptram_res.h_data);
        current_macro = dptram_res.CurrentPage - 3;
        macro_filename = fullfile(mpc555_mtrctrl_ucoderoot('src'), [dptram_res.Macros{current_macro}.Name,'.ASI']);
        dptram_res.h_data = mpc555_dptram_wizard_macros( 'DRAW', macro_filename , h);
        if ~isempty(dptram_res.Macros{current_macro}.Channels)
            macronumbers = mpc555_mtrctrl_invert_macrodata(dptram_res.Macros{current_macro}.Channels, macro_filename);
            for n=1:length(macronumbers)
                set(dptram_res.h_data.h_pulldown(n), 'Value', macronumbers(n)+1);
            end
        end
    case (4 + length(dptram_res.Macros))             %% Final page
        i_clear_wizard_page(dptram_res.h_data);
        set(h_buttons.nextbutton, 'String', 'Finish');
        dptram_res.h_data = i_draw_finalpage(h, dptram_res);
        i_populate_finalpage(dptram_res, currentblock);
    case (5 + length(dptram_res.Macros))
        currentsystem = bdroot(currentblock);
        i_copy_files(dptram_res, currentsystem);
        if length(dptram_res.Macros) ~= 0
            for n=1:length(dptram_res)
                model_ucodefulldirname = i_getucodefulldirname(currentsystem, dptram_res);
                new_macro_filename = [model_ucodefulldirname, filesep, dptram_res.Macros{n}.Name,'.asi'];
                mpc555_tpu_mask_creator_macrorewrite(new_macro_filename, dptram_res.Macros{n}.Channels);
            end
        end
        compilesuccess = i_compile_microcode(dptram_res, currentsystem);
        if compilesuccess == 1
            set_in_resource_config(dptram_res, currentblock);
            dptram_res.h_data = [];
            serialise_to_block(currentblock, dptram_res);
            delete(h);
        else
            dptram_res.CurrentPage = (4 + length(dptram_res.Macros));
            i_redraw_page(h, h_buttons, dptram_res);
        end
    otherwise
        i_clear_wizard_page(dptram_res.h_data);
end

end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function datagood = i_process_data(h, dptram_res)

h_data = dptram_res.h_data;

datagood = 1;

switch dptram_res.CurrentPage
    case 1
        pageonedata.str_filename = get(h_data.filenamebox, 'string');
        if length(pageonedata.str_filename) > 12
            errorbox = errordlg('Filename too long - maximum length 8.3');
            uiwait(errorbox);
            datagood = 0;
            return;
        end
        dot_position = strfind(pageonedata.str_filename, '.');
        if length(dot_position) ~= 1 || dot_position > 9 || dot_position < (length(pageonedata.str_filename) - 3)
            errorbox = errordlg('Invalid filename - should be of form 8.3');
            uiwait(errorbox);
            datagood = 0;
            return;
        end
        dptram_res.Filename = get(h_data.filenamebox, 'string');
        dptram_res.Comment  = get(h_data.commentbox, 'string');
        switch get(h_data.dptrambuttons_group, 'SelectedObject')
            case h_data.dptrambuttons(1)
                dptram_res.DPTRAMModule ='AB';
            case h_data.dptrambuttons(2)
                dptram_res.DPTRAMModule ='C';
        end
    case 2
        str_fn_names = {};
        for bank_num=1:3
            for fn_num=1:16
                str_menu_items = get(h_data.fn_names(fn_num,bank_num),'String');
                menu_selection = get(h_data.fn_names(fn_num,bank_num),'Value');
                str_fn_names{fn_num,bank_num}=str_menu_items{menu_selection};
            end
        end
        dptram_res.FNNames = str_fn_names;
    case 3
        str_macro_items = get(h_data.macro_list, 'String');
        macro_selection = get(h_data.macro_list, 'Value');
        str_macros = str_macro_items(macro_selection);
        % backup the old macros
        macrobak = dptram_res.Macros;

        % Create a new object for each macro if necessary
        dptram_res.Macros = {};
        if length(str_macros) ~= 0
           for n = 1:length(str_macros)
                dptram_res.Macros{n} = mpc555mtrctrldata.MACROSETTING;
                dptram_res.Macros{n}.Name = str_macros{n};
                for m = 1:length(macrobak)
                    if strcmp(dptram_res.Macros{n}.Name, macrobak{m}.Name)
                        dptram_res.Macros{n}.Channels = macrobak{m}.Channels;
                    end
                end
           end
        end
    %% Macro pages
    case num2cell(3 + (1:length(dptram_res.Macros)))
        current_macro = dptram_res.CurrentPage - 3;
        macro_filename = ...
            fullfile(mpc555_mtrctrl_ucoderoot('src'), [dptram_res.Macros{current_macro}.Name,'.ASI']);        
        dptram_res.Macros{current_macro}.Channels = ...
            mpc555_dptram_wizard_macros( 'EXTRACT', dptram_res.h_data, macro_filename);        
    %% Final page
    case (4 + length(dptram_res.Macros))
        dptram_res.TPU = {};
        if length(h_data.tpu_name) ~= 0
            for n=1:length(h_data.tpu_name)
                dptram_res.TPU{n} = mpc555mtrctrldata.MODULES;
                dptram_res.TPU{n}.Name = get(h_data.tpu_name(n), 'String');
                switch get(h_data.tpu_emu(n), 'Value')
                    case 1
                        dptram_res.TPU{n}.Emulation = 'ROM';
                    case 2
                        dptram_res.TPU{n}.Emulation = 'EMULATION';
                end
                switch get(h_data.tpu_bank(n), 'Value')
                    case 1
                        dptram_res.TPU{n}.Bank = 'Bank 0';
                    case 2
                        dptram_res.TPU{n}.Bank = 'Bank 1';
                    case 3
                        dptram_res.TPU{n}.Bank = 'Bank 2';
                end
            end
        end
    otherwise
        error('Something went wrong');
end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create the wizard window
%
function h = i_wizard_window()

h = figure;

% Turn off the menubar on the figure
%set(h, 'WindowStyle', 'modal');
set(h, 'Menubar', 'none');
set(h, 'Name', 'Microcode Mask Wizard');
set(h, 'NumberTitle', 'Off');
set(h, 'Resize', 'Off');

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Add the wizard buttons to the window
%
function h_buttons = i_wizard_buttons(h)

figure(h);

% Get the figure position
figureposition = get(h,'Position');

% Define the button heights and width
buttonwidth = 100;
buttonheight = 30;
buttonborder = 10;

% Create "Back" button
backbuttonposition = [figureposition(3)-3 * (buttonwidth+buttonborder), ...
    buttonborder, ...
    buttonwidth, ...
    buttonheight];
h_buttons.backbutton = uicontrol('style', 'pushbutton', ...
    'string', '<- Back', ...
    'position', backbuttonposition);

% Create "Next" button
nextbuttonposition = [figureposition(3)-2*(buttonwidth+buttonborder), ...
    buttonborder, ...
    buttonwidth, ...
    buttonheight];
h_buttons.nextbutton = uicontrol('style', 'pushbutton', ...
    'string', 'Next ->', ...
    'position', nextbuttonposition);

% Create "Cancel" button
cancelbuttonposition = [figureposition(3)-(buttonwidth+buttonborder), ...
    buttonborder, ...
    buttonwidth, ...
    buttonheight];
h_buttons.cancelbutton = uicontrol('style', 'pushbutton', ...
    'string', 'Cancel', ...
    'position', cancelbuttonposition);

% Create a hidden textbox with a number in
h_buttons.statusbox = uicontrol('style', 'edit', ...
    'string', '', ...
    'visible', 'off', ...
    'position', cancelbuttonposition);

end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Enable the buttons and wait until a button is pressed
%
function i_enable_buttons(h, h_buttons, dptram_res, currentblock)

set(h_buttons.backbutton, 'callback', {@i_back_button, h, h_buttons, dptram_res, currentblock});
set(h_buttons.nextbutton, 'callback', {@i_next_button, h, h_buttons, dptram_res, currentblock});
set(h_buttons.cancelbutton, 'callback', {@i_cancel_button, h, h_buttons, dptram_res});

% Add a callback to the close function of the window to prevent crashing
% when the close button is pressed
set(h, 'CloseRequestFcn', {@i_delete_wizard, h, h_buttons, dptram_res});
end

function i_delete_wizard(source, eventdata, h, h_buttons, dptram_res)
dptram_res.CurrentPage = 0;
set(h, 'CloseRequestFcn', 'closereq');
uiresume(h);
delete(h);
end

function i_next_button(source, eventdata, h, h_buttons, dptram_res, currentblock)
if i_process_data(h, dptram_res)
    dptram_res.CurrentPage = dptram_res.CurrentPage + 1;
end
set(h, 'CloseRequestFcn', 'closereq');
i_redraw_page(h, h_buttons, dptram_res, currentblock);
end

function i_back_button(source, eventdata, h, h_buttons, dptram_res, currentblock)
if i_process_data(h, dptram_res)
    dptram_res.CurrentPage = dptram_res.CurrentPage - 1;
end
set(h, 'CloseRequestFcn', 'closereq');
i_redraw_page(h, h_buttons, dptram_res, currentblock);
end

function i_cancel_button(source, eventdata, h, h_buttons, dptram_res)
dptram_res.CurrentPage = 0;
set(h, 'CloseRequestFcn', 'closereq');
uiresume(h);
delete(h);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Clear the GUI objects referenced in structure h_data
%
function i_clear_wizard_page(h_data)

% Get a list of the names of the object handles
objectnames = fieldnames(h_data);

for n=1:length(objectnames)
    % Check to see if the handle is still a valid handle, as it may have
    % already been deleted
    if ishandle(h_data.(objectnames{n}))
        delete(h_data.(objectnames{n}));
    end

end

end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% First page of data - get the filename, the comment and the DPTRAM size
%
function h_data = i_draw_firstpage(h)

% Get the figure position
figureposition = get(h,'Position');
figurebackground = get(h,'Color'); % Get the colour of the figure's background

ui_scalingfactor = [figureposition(3), ...
    figureposition(4), ...
    figureposition(3), ...
    figureposition(4)];

wizardtext = 'Welcome to the DPTRAM microcode mask generation wizard.  Please choose a filename, enter a comment and choose the size of your DPTRAM module';

filename_box_position = [155 figureposition(4)-120 figureposition(3)-175 20];
filename_label_position = [20 figureposition(4)-123 125 20];
wizard_label_position = [20 figureposition(4)-120 figureposition(3)-40 100];
comment_box_position = [155 figureposition(4)-240 figureposition(3)-175 100];
comment_label_position = [20 figureposition(4)-163 125 20];

ui_buttongroup_position = [155, figureposition(4)-340, ((figureposition(3)-175)/2) - 10 , 4 * 20 + 10] ./ ui_scalingfactor;
ui_dptramgroup_position = [155+(figureposition(3)-175)/2, figureposition(4)-340, ...
    ((figureposition(3)-175)/2) - 10 , 4 * 20 + 10] ./ ui_scalingfactor;

radiobutton1_position=[10 ,10 + 2 * 20, 140, 20]; % 2k Radio Button
radiobutton2_position=[10 ,10 + 1 * 20, 140, 20]; % 4k Radio Button
radiobutton3_position=[10 ,10 + 0 * 20, 140, 20]; % 8k Radio Button

h_data.wizardlabel = uicontrol('Style', 'text', ...
    'String', wizardtext, ...
    'BackgroundColor', figurebackground, ...
    'Position', wizard_label_position );


h_data.filenamebox = uicontrol('Style', 'edit', ...
    'Position', filename_box_position );

h_data.filenamelabel = uicontrol('Style', 'text', ...
    'String', 'ASCII Mask file name:', ...
    'BackgroundColor', figurebackground, ...
    'Position', filename_label_position );

% Create the comment box
h_data.commentbox = uicontrol('Style', 'edit', ...
    'String', 'Comment here', ...
    'Max', 10, ...
    'Position', comment_box_position );

h_data.commentboxlabel = uicontrol('Style', 'text', ...
    'String', 'Comment:', ...
    'BackgroundColor', figurebackground, ...
    'Position', comment_label_position );


% Contents of UIBUTTONGROUP
% Define the position of the uibuttongroup box

% Create the UIbuttongroup
h_data.radiobuttons_group = ...
    uibuttongroup('Position', ui_buttongroup_position, ...
    'Title', 'DPTRAM Size', ...
    'BackgroundColor', figurebackground);

% Create the 2k Radio button
h_data.radiobuttons(1) = uicontrol('Style', 'radiobutton', ...
    'Position', radiobutton1_position, ...
    'Parent', h_data.radiobuttons_group, ...
    'BackgroundColor', figurebackground, ...
    'String', '2k DPTRAM');
% Create the 4k Radio button
h_data.radiobuttons(2) = uicontrol('Style', 'radiobutton', ...
    'Position', radiobutton2_position, ...
    'Parent', h_data.radiobuttons_group, ...
    'BackgroundColor', figurebackground, ...
    'String', '4k DPTRAM');
% Create the 8k Radio button
h_data.radiobuttons(3) = uicontrol('Style', 'radiobutton', ...
    'Position', radiobutton3_position, ...
    'Parent', h_data.radiobuttons_group, ...
    'BackgroundColor', figurebackground, ...
    'String', '8k DPTRAM');

% Make the 8k Radio button selected
set(h_data.radiobuttons_group, 'SelectedObject', h_data.radiobuttons(3));

% Create the second UIbutton group
h_data.dptrambuttons_group = ...
    uibuttongroup('Position', ui_dptramgroup_position, ...
    'Title', 'DPTRAM Module', ...
    'BackgroundColor', figurebackground);

% Create the DPTRAM_AB button
h_data.dptrambuttons(1) = uicontrol('Style', 'radiobutton', ...
    'Position', radiobutton1_position, ...
    'Parent', h_data.dptrambuttons_group, ...
    'BackgroundColor', figurebackground, ...
    'String', 'DPTRAM AB');
% Create the DPTRAM_C button
h_data.dptrambuttons(2) = uicontrol('Style', 'radiobutton', ...
    'Position', radiobutton2_position, ...
    'Parent', h_data.dptrambuttons_group, ...
    'BackgroundColor', figurebackground, ...
    'String', 'DPTRAM C');

set(h_data.dptrambuttons_group,'SelectionChangeFcn',{@i_select_modules, h_data});

% Make the AB DPTRAM button selected
set(h_data.dptrambuttons_group, 'SelectedObject', h_data.dptrambuttons(1));
eventdata.NewValue = h_data.dptrambuttons(1);
% We have to manually run the callback because it won't happen if set in
% the code
i_select_modules(0, eventdata, h_data);

end


function i_select_modules(source, eventdata, h_data)

% Determine which item has been selected
switch eventdata.NewValue
    case h_data.dptrambuttons(1)
        set(h_data.radiobuttons(1), 'Enable', 'off');
        set(h_data.radiobuttons(2), 'Enable', 'off');
        set(h_data.radiobuttons(3), 'Enable', 'on');
        set(h_data.radiobuttons_group, 'SelectedObject', h_data.radiobuttons(3));
    case h_data.dptrambuttons(2)
        set(h_data.radiobuttons(1), 'Enable', 'off');
        set(h_data.radiobuttons(2), 'Enable', 'on');
        set(h_data.radiobuttons(3), 'Enable', 'off');
        set(h_data.radiobuttons_group, 'SelectedObject', h_data.radiobuttons(2));        
end
end

function i_populate_firstpage(dptram_res, currentblock)

    h_data = dptram_res.h_data;
    
    switch dptram_res.DPTRAMModule
        case 'AB'
            num_banks = 3;
        case 'C'
            num_banks = 2;
    end
    
    set(h_data.radiobuttons_group, 'SelectedObject', h_data.radiobuttons(num_banks));
    set(h_data.commentbox, 'String', dptram_res.Comment);
    set(h_data.filenamebox, 'String', dptram_res.Filename);
    
    switch dptram_res.DPTRAMModule
        case 'AB'
            set(h_data.dptrambuttons_group, 'SelectedObject', h_data.dptrambuttons(1));
        case 'C'
            set(h_data.dptrambuttons_group, 'SelectedObject', h_data.dptrambuttons(2));
    end
    
    try
        target = RTWConfigurationCB('get_target',currentblock);
        if ~isempty(target)
            sys_res1 = target.findConfigForClass('MPC555dkConfig.SYSTEM_CLOCKS');
        else
            error('No target block');
        end
    catch
        error('No resource configuration in this system');
    end

    % Disable option for DPTRAM C if necessary
    if ~mpc555_module_available(sys_res1.MPC5xx_Variant, 'DPTRAM_C')
        set(h_data.dptrambuttons_group, 'SelectedObject', h_data.dptrambuttons(1));
        set(h_data.dptrambuttons(2), 'Enable', 'off');
    end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Second page of data - choose the microcode functions
%
function h_data = i_draw_secondpage(h, microcode_files, dptram_res)

if strcmp(dptram_res.DPTRAMModule, 'AB')
    pageonedata.num_banks = 3;
else
    pageonedata.num_banks = 2;
end

% Get the figure position
figureposition = get(h,'Position');
figurebackground = get(h,'Color'); % Get the colour of the figure's background

ui_scalingfactor = [figureposition(3), ...
    figureposition(4), ...
    figureposition(3), ...
    figureposition(4)];

wizardtext = 'Choose the microcode functions you wish to be available';
wizard_label_position = [20 figureposition(4)-120 figureposition(3)-40 100];
h_data.wizardlabel = uicontrol('Style', 'text', ...
    'String', wizardtext, ...
    'BackgroundColor', figurebackground, ...
    'Position', wizard_label_position );

row_spacing = 20;
fn_label_x_position = 20;

% Draw the labels for each function number
for fn_row = 1:16
    ypos = 6 + row_spacing * (17) - row_spacing * (fn_row - 1);
    h_data.fn_labels(fn_row) = ...
        uicontrol('Style', 'text',...
        'Position', [fn_label_x_position,ypos,80,20],...
        'String', ['Function ',num2str(fn_row-1)],...
        'BackgroundColor', figurebackground);
end

% Draw the labels for each bank number
bank_positions = [100 250 400];
for bank_num = 1:3
    xpos = bank_positions(bank_num);
    ypos = 6 + row_spacing * 18;
    h_data.bank_labels(bank_num) = ...
        uicontrol('Style', 'text',...
        'Position', [xpos,ypos,130,20],...
        'String', ['Bank ',num2str(bank_num-1)],...
        'BackgroundColor', figurebackground);
end

% Create the editable text boxes
for bank_num = 1:3
    bankenabled = 'on';
    if pageonedata.num_banks == 1 && bank_num > 1
        bankenabled = 'off';
    end
    if pageonedata.num_banks == 2 && bank_num > 2
        bankenabled = 'off';
    end
    for fn_row = 1:16
        ypos = 10 + row_spacing * (17) - row_spacing * (fn_row - 1);
        h_data.fn_names(fn_row,bank_num) = ...
            uicontrol('Style', 'popupmenu', ...
            'String', microcode_files, ...
            'BackgroundColor', 'w', ...
            'Enable', bankenabled, ...
            'Position', [bank_positions(bank_num),ypos,130,20]);
    end
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Extract data from the second page of the wizard
%
function pagetwodata = i_data_secondpage(h_data)

for bank_num=1:3
    for fn_num=1:16
        str_menu_items = get(h_data.fn_names(fn_num,bank_num),'String');
        menu_selection = get(h_data.fn_names(fn_num,bank_num),'Value');
        pagetwodata.str_fn_names{fn_num,bank_num}=str_menu_items{menu_selection};
    end
end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Write data back to the second page of the wizard
%
function i_populate_secondpage(dptram_res, microcode_files)

h_data = dptram_res.h_data;
% Try to Fill in function names
if ~(size(dptram_res.FNNames,1) == 16 && size(dptram_res.FNNames,2) == 3)
    return;
end

for banknum=1:3
    for function_row=1:16
        % microcode_files contains the list of possible values for each
        % popupmenu
        for current_name = 1:length(microcode_files)
            % If the TPU function name from the external structure is
            % equal to one available in the current available list,
            % assign it as appropriate
            if strcmp(upper(microcode_files{current_name}), upper(dptram_res.FNNames(function_row, banknum)))
                set(h_data.fn_names(function_row, banknum), 'Value', current_name);
            end
        end
    end
end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Third page of data - choose which macro files are to be used
%
function h_data = i_draw_thirdpage(h, microcode_macros)

% Get the figure position
figureposition = get(h,'Position');
figurebackground = get(h,'Color'); % Get the colour of the figure's background

ui_scalingfactor = [figureposition(3), ...
    figureposition(4), ...
    figureposition(3), ...
    figureposition(4)];

wizardtext = 'Choose the microcode macro files to be used.  Hold CTRL to select multiple files.  The default selection should be adequate.';
wizard_label_position = [20 figureposition(4)-120 figureposition(3)-40 100];
h_data.wizardlabel = uicontrol('Style', 'text', ...
    'String', wizardtext, ...
    'BackgroundColor', figurebackground, ...
    'Position', wizard_label_position );

macro_list_position = [20 80 figureposition(3)-40 figureposition(4)-150];
macro_clear_position = [20 50 figureposition(3)-40 20];
% And create the macro listbox              
h_data.macro_list = uicontrol('Style', 'List', ...
                               'String', microcode_macros, ...
                               'Min', 0, ...
                               'Max', 2, ...
                               'Value', [], ...
                               'Position', macro_list_position);

% Create the pushbutton for clearing the macro listbox
h_data.pushbutton_clear_macro = uicontrol('Style', 'pushbutton', ...
        'Position', macro_clear_position, ...
        'Callback', {@i_callback_clear_macros, h_data}, ...
        'String', 'Clear');
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Extract data from the third page of the wizard
%
function pagethreedata = i_data_thirdpage(h_data)
str_macro_items = get(h_data.macro_list, 'String');
macro_selection = get(h_data.macro_list, 'Value');
pagethreedata.str_macros = str_macro_items(macro_selection);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Write data back to third page of the wizard
%
function populate_thirdpage(h_data, pagethreedata, microcode_macros)
    % Try to fill in macro names
    matching = [];
    for current_macro = 1:length(pagethreedata.str_macros)
        matching = [matching, strmatch(pagethreedata.str_macros{current_macro}, microcode_macros, 'exact')];
    end
    set(h_data.macro_list, 'Value', matching);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Guess the data to be used in the third page
%
function populate_thirdpage_auto(dptram_res, microcode_macros)

h_data = dptram_res.h_data;
pagetwodata.str_fn_names = dptram_res.FNNames;

if ~isequal(size(dptram_res.FNNames), [16,3])
    return
end

macrosrequired = [];

for bank_num=1:3
    for fn_num=1:16
        current_function = pagetwodata.str_fn_names{fn_num,bank_num};
        
        % If the function is not nameless and there are macros to be used
        if ~strcmp(current_function, '') && (length(microcode_macros) ~= 0)
           % Set "longestprefix" to special value of zero
           longestprefix = 0;
           % Iterate through all of the macros
           for n=1:length(microcode_macros)
              % Search for the longest macro name
              if strfind(upper(current_function), upper(microcode_macros{n})) 
                if longestprefix == 0 || (length(microcode_macros{n}) > length(microcode_macros{longestprefix}))
                    longestprefix = n;
                end
              end
           end
           % If there is a valid prefix
           if longestprefix ~=0
               % Add the index to the number of macros required if it's not
               % a duplicate
               if isempty(find(eq(macrosrequired,longestprefix),1))
                   macrosrequired = [macrosrequired, longestprefix]; 
               end
           end
        end
    end
end

macrosrequired = sort(macrosrequired);

set(h_data.macro_list, 'Value', macrosrequired);

end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Check which DPTRAM size has been selected
%
function [num_banks, str_dptram_size] = i_get_dptram_size(h_radiobuttons_group, h_radiobuttons)
dptram_radio_button = get(h_radiobuttons_group,'SelectedObject');
switch dptram_radio_button
    case h_radiobuttons(1)
        num_banks=1;
        str_dptram_size='2k';
    case h_radiobuttons(2)
        num_banks=2;
        str_dptram_size='4k';
    case h_radiobuttons(3)
        num_banks=3;
        str_dptram_size='8k';
    otherwise
end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function to handle callback on third button
%
function i_callback_clear_macros(source, eventdata, h_data)
    set(h_data.macro_list, 'Value', []);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Final page of data - choosing which TPU module to enable EMU mode on
%
function h_data = i_draw_finalpage(h, dptram_res)

% Get the figure position
figureposition = get(h,'Position');
figurebackground = get(h,'Color'); % Get the colour of the figure's background

ui_scalingfactor = [figureposition(3), ...
    figureposition(4), ...
    figureposition(3), ...
    figureposition(4)];

wizardtext = 'TPU microcode compilation has been successful.  Please specify which mode each TPU will operate in, and which DPTRAM bank you wish each to use.';

wizard_label_position = [20 figureposition(4)-120 figureposition(3)-40 100];

h_data.wizardlabel = uicontrol('Style', 'text', ...
    'String', wizardtext, ...
    'BackgroundColor', figurebackground, ...
    'Position', wizard_label_position );


switch dptram_res.DPTRAMModule
    case 'AB'
        number_of_tpus = 2;
        tpu_names = {'TPU_A', 'TPU_B'};
        bank_array = {'Bank 0', 'Bank 1', 'Bank 2'};
    case 'C'
        number_of_tpus = 1;
        tpu_names = {'TPU_C'};
        bank_array = {'Bank 0', 'Bank 1'};
    otherwise
        error('Wrong DPTRAM module');
end

tpu_name_label_position = [(figureposition(3)-100)/(number_of_tpus+2) (figureposition(4)/2 + 20) 100 20];
tpu_emu_label_position = [(figureposition(3)-100)/(number_of_tpus+2) (figureposition(4)/2 - 10) 100 20];
tpu_bank_label_position = [(figureposition(3)-100)/(number_of_tpus+2) (figureposition(4)/2 - 40) 100 20];

h_data.label1 = uicontrol('Style', 'text', ...
    'String', 'TPU Module', ...
    'BackgroundColor', figurebackground, ...
    'Position', tpu_name_label_position );

h_data.label2 = uicontrol('Style', 'text', ...
    'String', 'Microcode Location', ...
    'BackgroundColor', figurebackground, ...
    'Position', tpu_emu_label_position );

h_data.label3 = uicontrol('Style', 'text', ...
    'String', 'Bank Number', ...
    'BackgroundColor', figurebackground, ...
    'Position', tpu_bank_label_position );


for current_tpu = 1:number_of_tpus
    current_tpu_name = tpu_names{current_tpu};

    tpu_name_position = [(current_tpu+1)*(figureposition(3)-100)/(number_of_tpus+2) (figureposition(4)/2 + 20) 100 20];
    tpu_emu_position = [(current_tpu+1)*(figureposition(3)-100)/(number_of_tpus+2) (figureposition(4)/2 - 10) 100 20];
    tpu_bank_position = [(current_tpu+1)*(figureposition(3)-100)/(number_of_tpus+2) (figureposition(4)/2 - 40) 100 20];

    h_data.tpu_name(current_tpu) = uicontrol('Style', 'text', ...
        'String', current_tpu_name, ...
        'BackgroundColor', figurebackground, ...
        'Position', tpu_name_position );

    h_data.tpu_emu(current_tpu) = uicontrol('Style', 'popupmenu', ...
        'String', {'ROM','EMULATION'}, ...
        'Value', 1, ...
        'BackgroundColor', 'w', ...
        'Position', tpu_emu_position );

    h_data.tpu_bank(current_tpu) = uicontrol('Style', 'popupmenu', ...
        'String', bank_array, ...
        'Value', 1, ...
        'BackgroundColor', 'w', ...
        'Position', tpu_bank_position );
end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Get data from final page of data
%
function finalpagedata = i_data_finalpage(h_data)

for n=1:length(h_data.tpu_name)
    finalpagedata.tpu(n).name = get(h_data.tpu_name(n), 'String');
    finalpagedata.tpu(n).emu = get(h_data.tpu_emu(n), 'Value');
    finalpagedata.tpu(n).bank = get(h_data.tpu_bank(n), 'Value');
end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Get data from final page of data
%
function i_populate_finalpage(dptram_res, currentblock)

h_data = dptram_res.h_data;

% Get a handle to the configuration block
target = RTWConfigurationCB('get_target',currentblock);
if ~isempty(target)
    sys_res = target.findConfigForClass('MPC555dkConfig.TPU');
else
    error('No target block');
end

switch dptram_res.DPTRAMModule
    case 'AB'
        tpu_list = {'TPU_A', 'TPU_B'};
    case 'C'
        tpu_list = {'TPU_C'};
end

% For each required TPU
for n=1:length(tpu_list)
    tpuN = eval(['sys_res.',tpu_list{n}]);
    % Check whether Emulation Mode is enabled
    switch tpuN.Emulation_Mode
        case 'Use ROM TPU Functions (0)'
            set(h_data.tpu_emu(n), 'Value', 1);
        case 'Use Emulation Mode (1)'
            set(h_data.tpu_emu(n), 'Value', 2);
    end
    % Check which Bank has been chosen
    switch tpuN.Memory_Bank_Select
        case 'Bank 0'
            set(h_data.tpu_bank(n), 'Value', 1);
        case 'Bank 1'
            set(h_data.tpu_bank(n), 'Value', 2);
        case 'Bank 2'
            set(h_data.tpu_bank(n), 'Value', 3);
    end
end

end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function to get the list of microcode files in the microcode source
% directory and return a cell array
%
function microcode_files = i_get_functions(file_extension)
% Get a list of all microcode files in the microcode source directory
ucodesrcdir = mpc555_mtrctrl_ucoderoot('src');
directory_listing = dir([ucodesrcdir,filesep,'*.', file_extension]);
% Move the filenames into a cell structure
microcode_files = {};
% If no microcode files, throw an error and exit
if isempty(directory_listing)
    return;
end
% Transfer each into a cell
for current_filename = 1:length(directory_listing)
    microcode_files = [microcode_files, {directory_listing(current_filename).name}];
end
% Remove the filename extension for neatness sake
for current_filename = 1:length(microcode_files)
    current_filename_string = microcode_files{current_filename};
    current_filename_length = length(current_filename_string);
    microcode_files{current_filename} = ...
        current_filename_string( 1:current_filename_length -...
        (1 + length( file_extension ) ) );
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Get the full directory name for the microcode files
%
function [model_ucodefulldirname, model_path] = i_getucodefulldirname(currentsystem, dptram_res)

% Make a note of the directory of the model
model_root = bdroot(currentsystem);
model_fullname = get_param(model_root, 'Filename');
model_path = fileparts(model_fullname);

% Define a name for the directory which will contain the TPU microcode
model_ucodedirname = [model_root,'_tpu_ucode_',dptram_res.DPTRAMModule];
model_ucodefulldirname = [model_path, filesep, model_ucodedirname];

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Copy the appropriate files
%
function i_copy_files(dptram_res, currentsystem)

% Take a copy of the working directory
current_directory = pwd;
% Define a name for the directory which will contain the TPU microcode
model_ucodefulldirname = i_getucodefulldirname(currentsystem, dptram_res);

switch dptram_res.DPTRAMModule
    case 'AB'
        pageonedata.num_banks = 3;
    case 'C'
        pageonedata.num_banks = 2;
end

pagetwodata.str_fn_names = dptram_res.FNNames;
pagethreedata.str_macros = {};

if length(dptram_res.Macros) ~= 0
    for n = 1:length(dptram_res.Macros)
        pagethreedata.str_macros{n} = dptram_res.Macros{n}.Name;
    end
end

% Check to see if this directory exists or not
if ~exist(model_ucodefulldirname, 'dir')
    mkdir(model_ucodefulldirname);
end

% Copy the appropriate microcode source files into the new directory

% Need to copy the link channel include file
linkchan_copied = 0;
for bank_num=1:pageonedata.num_banks
    for fn_num=16:-1:1
        if ~strcmp('',pagetwodata.str_fn_names{fn_num,bank_num})
            original_file = [mpc555_mtrctrl_ucoderoot('src'),filesep,pagetwodata.str_fn_names{fn_num,bank_num},'.UC'];
            copyfile(original_file, model_ucodefulldirname, 'f');
            %% If the link channel file hasn't been copied we should check
            %% to see if the function needs it and copy it
            %% This is a hack until I write a parser to search each and
            %% every .UC file for the include directive!
            if ~linkchan_copied
               for aaa = {'ITC', 'NITC', 'PPWA', 'SPWM'}
                  if strcmp( aaa{:}, upper(pagetwodata.str_fn_names{fn_num,bank_num}))
                     original_linkchan = [mpc555_mtrctrl_ucoderoot('src'),filesep,'LINKCHAN.UC']; 
                     copyfile(original_linkchan, model_ucodefulldirname, 'f');
                     linchan_copied = 1;
                  end
               end
            end %% End of including link channel
        end %% End of strcmp
    end
end

% Do the same for the selected macro files
if length(pagethreedata.str_macros) ~= 0
   for current_macro = 1:length(pagethreedata.str_macros)
       original_file = [mpc555_mtrctrl_ucoderoot('src'),filesep,pagethreedata.str_macros{current_macro},'.asi'];
       new_macro_filename = [model_ucodefulldirname, filesep, pagethreedata.str_macros{current_macro},'.asi'];
       if ~exist(new_macro_filename, 'file')
           copyfile(original_file, model_ucodefulldirname);
       end
   end
end

% Set the attributes so the files are WRITEABLE
fileattrib(fullfile(model_ucodefulldirname, '*'), '+w');
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Compile the microcode
%
function compilesuccess = i_compile_microcode(dptram_res, currentsystem)

str_fn_names = dptram_res.FNNames;

switch dptram_res.DPTRAMModule
    case 'AB'
        str_dptram_size = '8k';
        num_banks = 3;
    case 'C'
        str_dptram_size = '4k';
        num_banks = 2;
end

str_filenamebox = dptram_res.Filename;
str_commentbox = dptram_res.Comment;

str_macros = {};
if length(dptram_res.Macros) ~= 0
    for n=1:length(dptram_res.Macros)
        str_macros{n} = dptram_res.Macros{n}.Name;
    end
end

[model_ucodefulldirname, model_path] = i_getucodefulldirname(currentsystem, dptram_res);
current_directory = pwd;

% Now build up the statement
cell_array_functions = {};
for bank_num=1:num_banks
    for fn_num=1:16
        if ~strcmp('',str_fn_names{fn_num,bank_num})
            cell_array_functions = ... 
                [cell_array_functions, {str_fn_names{fn_num,bank_num}}, {fn_num-1}, {bank_num-1}];
        end
    end
end

% Change directory to the new directory
cd(model_ucodefulldirname);
% Generate the file
file_data = mpc555_tpu_microcode_mask(2, str_dptram_size, str_filenamebox, ...
                                      str_commentbox, str_macros, ...
                                      cell_array_functions{:});

fid = fopen(str_filenamebox, 'W');  % Open file for writing
fwrite(fid, file_data);
fclose(fid);

% Output the generated file to the display
command_string=['TYPE ', str_filenamebox];
system(command_string);

% And attempt to run the TPU Microcode Assembler
command_string=['"', mpc555_mtrctrl_ucoderoot('tpumasm'),filesep,'TPUMASM', '" ', str_filenamebox];
[s,w] = system(command_string);
disp(w);

% Change directory to the new directory
cd(current_directory);

% If an error occured at this stage, output a messagebox and return
if s ~= 0    
    errorhandle = msgbox(w);
    uiwait(errorhandle);
    compilesuccess = 0;
    return;
else
    % Move the compiled file into the model directory
    s19filename = [str_filenamebox(1:length(str_filenamebox)-3),'S19'];
    s19filenewname = [str_filenamebox(1:length(str_filenamebox)-4),'_tpu_microcode.S19'];
    s19filefullname = [model_ucodefulldirname, filesep, s19filename];
    s19filenewfullname = [model_path, filesep, s19filenewname];
    movefile(s19filefullname, s19filenewfullname);
    compilesuccess = 1;
end

end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function to serialise the data collected in the wizard to the block mask
%
function serialise_to_block(currentblock, dptram_res)

%%% SAFETY CHECK %%%
if ~strcmp(get_param(currentblock, 'referenceblock'), 'mpc555_mtrctrl/DPTRAM Configuration Wizard')
    return;
end
set_param(currentblock, 'userdata', dptram_res);
set_param(currentblock, 'userdatapersistent', 'on');

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function to deserialise the data from the block mask if saved
%
function dptram_res = deserialise_from_block(currentblock)

%%% SAFETY CHECK %%%
if ~strcmp(get_param(currentblock, 'referenceblock'), 'mpc555_mtrctrl/DPTRAM Configuration Wizard')
    dptram_res = '';
    return;
end

dptram_res = get_param(currentblock, 'userdata');

if isempty(dptram_res)
   dptram_res = mpc555mtrctrldata.DPTRAMDATA; 
end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function to set up the resource config block
%
function set_in_resource_config(dptram_res, currentblock)

% Get a handle to the configuration block
target = RTWConfigurationCB('get_target',currentblock);
if ~isempty(target)
    sys_res = target.findConfigForClass('MPC555dkConfig.TPU');
    sys_res1 = target.findConfigForClass('MPC555dkConfig.SYSTEM_CLOCKS');
else
    error('No target block');
end

valid_fns = mpc5xx_tpu_function_types;
str_fn_names = dptram_res.FNNames;

str_filenamebox = dptram_res.Filename;

s19filename = [str_filenamebox(1:length(str_filenamebox)-3),'S19'];
s19filenewname = [str_filenamebox(1:length(str_filenamebox)-4),'_tpu_microcode.S19'];


switch dptram_res.DPTRAMModule
    case 'AB'
        dptramab = sys_res.TPU_EMULATION.TPU_DPTRAM_AB;
        dptramab.TPU_EMU_S19Download = 'Download custom code';
        dptramab.TPU_EMU_Mask_File = s19filenewname;
        for bank = 0:2
            for fn_num=0:15
                if strcmp(str_fn_names{fn_num+1,bank+1}, 'PMA_PMM')
                    str_fn_names{fn_num+1,bank+1} = 'PMA';
                end
                if ~strcmp('', str_fn_names{fn_num+1,bank+1})
                    fn_idx = strmatch(lower(str_fn_names{fn_num+1,bank+1}), lower(valid_fns), 'exact');
                    str_fn_names{fn_num+1,bank+1} = valid_fns{fn_idx};
                end
                eval(['dptramab.TPU_Function_Mask_Bank_',num2str(bank),'.TPU_Function_',dec2hex(fn_num),'= str_fn_names{fn_num+1,bank+1};']);
            end
        end
    case 'C'
        dptramc = sys_res.TPU_EMULATION.TPU_DPTRAM_C;
        dptramc.TPU_EMU_S19Download = 'Download custom code';
        dptramab.TPU_EMU_Mask_File = s19filenewname;
        for bank = 0:1
            for fn_num=0:15
                if strcmp(str_fn_names{fn_num+1,bank+1}, 'PMA_PMM')
                    str_fn_names{fn_num+1,bank+1} = 'PMA';
                end
                if ~strcmp('', str_fn_names{fn_num+1,bank+1})
                    fn_idx = strmatch(lower(str_fn_names{fn_num+1,bank+1}), lower(valid_fns), 'exact');
                    str_fn_names{fn_num+1,bank+1} = valid_fns{fn_idx};
                end
                eval(['dptramc.TPU_Function_Mask_Bank_',num2str(bank),'.TPU_Function_',dec2hex(fn_num),'= str_fn_names{fn_num+1,bank+1};']);
            end
        end
end

% For each TPU module that we have data for
for n=1:length(dptram_res.TPU)
    % Check which TPU module we are using
    switch dptram_res.TPU{n}.name
        case 'TPU_A'
            tpuN = sys_res.TPU_A;
        case 'TPU_B'
            tpuN = sys_res.TPU_B;
        case 'TPU_C'
            tpuN = sys_res.TPU_C;
    end

    % Set emulation mode
    switch dptram_res.TPU{n}.emu
        case 'ROM'
            tpuN.Emulation_Mode = 'Use ROM TPU Functions (0)';
        case 'EMULATION'
            tpuN.Emulation_Mode = 'Use Emulation Mode (1)';
    end
    
    % Set the bank
    switch dptram_res.TPU{n}.bank
        case 'Bank 0'
            tpuN.Memory_Bank_Select = 'Bank 0';
        case 'Bank 1'
            tpuN.Memory_Bank_Select = 'Bank 1';
        case 'Bank 2'
            tpuN.Memory_Bank_Select = 'Bank 2';
    end
end

end

Contact us