% Frequency-scan playback hop example.
% Optional compiler setup:
setenv('MW_MINGW64_LOC','C:\msys64\mingw64'); mex -setup

% Load h2_api.dll.
if ~libisloaded('h2_api')
    loadlibrary('.\h2_api\h2_api.dll', '.\h2_api\h2_api_matlab.h', ...
        'alias', 'h2_api', 'includepath', '.\h2_api');
end

libfunctions('h2_api');

% Open device.
Device = libpointer('voidPtrPtr');
DevNum = uint8(0);
Status = 0;
chn = libpointer('uint16Ptr', uint16(0));

% Allocate channel buffer.
CHANNEL_COUNT = 8;
CHANNEL_STRUCT_BYTES = 16;
ch_buf = zeros(1, CHANNEL_COUNT * CHANNEL_STRUCT_BYTES, 'uint8');
ch = libpointer('uint8Ptr', ch_buf);

% Create device_info.
deviceinfo.model = 0;
deviceinfo.uid_l64 = 0;
deviceinfo.uid_h32 = 0;
deviceinfo.hardware_version = 0;
deviceinfo.mfw_version = 0;
deviceinfo.ffw_version = 0;
deviceinfo.pmu_version = 0;
deviceinfo.agu_version = 0;
deviceinfo.bus_version = 0;
deviceinfo.eio_version = 0;
deviceinfo.bus_bandwidth = 0;
deviceinfo_p = libstruct('device_info', deviceinfo);

% Generate pulse waveform.
samplerate = 125e6;
data = sim_generatewaveform_pulse();

data_p = libpointer('int16Ptr', data);
wave_points = uint32(length(data) / 2);    % IQ point count, same as data.size() / 2 in C++

USE_ETH = false;

if USE_ETH
    ETH_STANDARD = uint8(1);

    ethsettings.eth_interface = ETH_STANDARD;
    ethsettings.eth_is_ipv6 = uint8(0);
    ethsettings.eth_ip_address = zeros(1, 16, 'uint8');
    ethsettings.eth_ip_address(1:4) = uint8([192 168 1 100]);
    ethsettings.eth_remote_port = uint16(5000);
    ethsettings.eth_read_timeout = int32(5000);

    ethsettings_p = libstruct('eth_setting', ethsettings);
    Status = calllib('h2_api', 'device_open_eth', Device, ethsettings_p, ch, chn, deviceinfo_p);
    fprintf('device_open_eth: Status = %d\n', Status);
else
    Status = calllib('h2_api', 'device_open_usb', Device, DevNum, ch, chn, deviceinfo_p);
    fprintf('device_open_usb: Status = %d\n', Status);
end

fprintf('channel count = %d\n', chn.Value);
get(deviceinfo_p);

% Configure frequency scan RF.
start_freq = 1.0e9;
stop_freq  = 2.0e9;
step_freq  = 100e6;
level      = single(0.0);
dwell      = single(10e-3);    % 100 us per frequency point

Status = calllib('h2_api', 'tx_config_fscan', ch, start_freq, stop_freq, step_freq, level, dwell);
fprintf('tx_config_fscan: Status = %d\n', Status);

% Configure trigger input.
TRIGGER_SOURCE_BUS = uint8(0);
TRIGGER_EDGE_RISING = uint8(0);
TRIGGER_ACTION_HOP = uint8(2);   % HOP: each bus trigger switches to next frequency point

txtrigger.source = TRIGGER_SOURCE_BUS;
txtrigger.edge   = TRIGGER_EDGE_RISING;    % For bus trigger, edge is invalid, but struct field is kept.
txtrigger.action = TRIGGER_ACTION_HOP;
txtrigger.count  = int32(0);               % In HOP mode, count is invalid according to the cpp comment.
txtrigger_p = libstruct('tx_trigger', txtrigger);

Status = calllib('h2_api', 'channel_config_trigger', ch, txtrigger_p);
fprintf('channel_config_trigger: Status = %d\n', Status);

% Download waveform.
waveid = libpointer('uint16Ptr', uint16(0));

Status = calllib('h2_api', 'tx_clear_waveform', Device);
fprintf('tx_clear_waveform: Status = %d\n', Status);

Status = calllib('h2_api', 'tx_download_waveform', Device, data_p, wave_points, waveid);
fprintf('tx_download_waveform: Status = %d\n', Status);
fprintf('waveid = %d\n', waveid.Value);

% Configure playback.
waveforms = int16(1);
waveform = int16(waveid.Value);
repeat = int32(-1);
srate = double(samplerate);

waveform_p = libpointer('int16Ptr', waveform);
repeat_p = libpointer('int32Ptr', repeat);
srate_p = libpointer('doublePtr', srate);

Status = calllib('h2_api', 'tx_config_playback', ch, waveform_p, repeat_p, srate_p, waveforms);
fprintf('tx_config_playback: Status = %d\n', Status);

% Enable RF and baseband output.
STATE_ON = uint8(1);

Status = calllib('h2_api', 'tx_config_output', ch, STATE_ON, STATE_ON);
fprintf('tx_config_output: Status = %d\n', Status);

% Start channel.
Status = calllib('h2_api', 'channel_start', ch);
fprintf('channel_start: Status = %d\n', Status);

% Send repeated bus triggers.
for i = 1:1000
    Status = calllib('h2_api', 'channel_trigger_bus', ch);
    fprintf('channel_trigger_bus[%d]: Status = %d\n', i, Status);
    pause(0.1);
end

% Close device.
Status = calllib('h2_api', 'device_close', Device);
fprintf('device_close: Status = %d\n', Status);

clear Device ch chn deviceinfo_p ethsettings_p txtrigger_p data_p waveid waveform_p repeat_p srate_p;

if libisloaded('h2_api')
    unloadlibrary('h2_api');
end

disp('Uninstall complete');
