SP209 API Usage

The sp209api_transition_t type

Captured samples are packetized and transfered between device and your application using a data type called sp209api_transition_t. This data type allows for more optimal - compressed - transfer of captured samples. You can think of this data type as a way of timestamping each transition recorded by the device. Here is how it works: Each time the logic level on one or more channels changes, a new transition is created, and the time difference (delta_samples) between this transition and the previous one is recorded.

Trigger configuration

In order to describe a particular trigger configuration, the sp209api_trigger_description_t structure is used. it can be passed as a parameter to SP209’s API as it can be seen in the examples below. The definition of each member of this structure is described in the header file sp209api_types.h

Please note that the trigger capabilities of the API are somewhat limited compared to what’s possible with ScanaStudio, nevertheless, it allows basic triggering options.

Usage examples

Below are some C/C++ example code snippets.

Note: in order to run those examples, it’s necessary to include the following files:

  1. ihwapi_common_types.h
  2. sp209api_types.h
  3. sp209api.h

Also, please note those examples are created, run, and tested under Qt environment, that being said, we used standard C++ compliant syntax, without any fancy Qt specific functions

Listing the number of open devices

sp209api_handle h;
int devices_count = 0;

sp209api_create_new_handle(&h,sp209api_device_model_t::SP209API_MODEL_209);
sp209api_create_device_list(h);
sp209api_get_devices_count(h, &devices_count);
sp209api_free_device_list(h);

Here is a more complex example that also gets device descriptor:

#define DBG   std::cout << "\n\r" << " "
sp209api_handle h;
device_descriptor_t d;
int devices_count = 0;

sp209api_create_new_handle(&h,sp209api_device_model_t::SP209API_MODEL_209);
sp209api_create_device_list(h);
sp209api_get_devices_count(h, &devices_count);
if (devices_count > 0)
{
    sp209api_get_device_descriptor(h,0,&d);
    DBG << "New device, serial number = " << d.sn << ", description = " << d.desc ;
}
sp209api_free_device_list(h);
DBG << "New device, serial number = " << d.sn << ", description = " << d.desc;

Open a device

#define DBG   std::cout << "\n\r" << " "
sp209api_handle h;
device_descriptor_t d;
int devices_count = 0;
ihwapi_err_code_t e;

sp209api_create_new_handle(&h,sp209api_device_model_t::SP209API_MODEL_209I);
sp209api_create_device_list(h);
sp209api_get_devices_count(h,&devices_count);
DBG << "Found " << devices_count << " devices" ;
if (devices_count > 0)
{
    sp209api_get_device_descriptor(h,0,&d);
    DBG << "New device, serial number = " << d.sn << ", description = " << d.desc ;
    e = sp209api_device_open(h,d,SP209API_VARIANT_STD);
    if (e == IHWAPI_OK)
    {
        DBG << "Device is open";
    }
    else
    {
        DBG << "Device not open! error code = " << e ;
    }

}
sp209api_free_device_list(h);
sp209api_free(h);

Capture samples

The following examples show how to open a seek for a device, open it, and capture some samples. Then, the first 10 transitions on channel 1 are dumped to the console.

#define DBG   std::cout << "\n\r" << " "
int main()
{
    sp209api_handle h;
    device_descriptor_t d;
    ihwapi_err_code_t e = IHWAPI_DEVICE_NOT_OPEN;
    sp209api_settings_t settings;
    uint16_t devices_count = 0;
    int64_t samples_count = 0;
    int64_t post_trig_samples = 0;
    sp209api_trs_t trs;



    sp209api_create_new_handle(&h,sp209api_device_model_t::SP209API_MODEL_209I);
    sp209api_create_device_list(h);
    sp209api_get_devices_count(h,&devices_count);
    DBG << "Found " << devices_count << " devices" ;
    if (devices_count > 0)
    {
        sp209api_get_device_descriptor(h,0,&d);
        DBG << "New device, serial number = " << d.sn << ", description = " << d.desc ;
        e = sp209api_device_open(h,d,SP209API_VARIANT_STD);
        if (e == IHWAPI_OK)
        {
            DBG << "Device is open";
        }
        else
        {
            DBG << "Device not open! error code = " << e ;
        }

    }
    sp209api_free_device_list(h);

    if (e == IHWAPI_OK)
    {
        memset(&settings,0,sizeof (settings));
        settings.sampling_depth = 250e3;
        settings.post_trig_depth = settings.sampling_depth * 0.9;
        settings.thresh_cfg[0] = SP209API_X_TH_3V3;
        settings.thresh_cfg[1] = SP209API_X_TH_3V3;
        settings.thresh_cfg[2] = SP209API_X_TH_3V3;
        sp209api_trigger_description_t trg;
        trg.type = sp209api_trigger_type_t::SP209API_TRG_NOTRIG;
        trg.channel = 1;
        e = sp209api_launch_new_capture_simple_trigger(h,trg,settings);
        bool cfg_done = false;
        if (e == IHWAPI_OK)
        {
            while(cfg_done == false)
            {
                sp209api_get_config_done_flag(h,&cfg_done);
                msleep(200);
            }
            DBG << "Device Config done, new capture launched";
        }
        else
        {
            DBG << "Launch New capture error = " << e;

        }
    }



    if (e == IHWAPI_OK)
    {
        DBG << "Waiting for trigger..." << endl;
        bool trig_flag = false;
        while (trig_flag == false)
        {
            sp209api_get_triggered_flag(h,&trig_flag);
            msleep(200);
        }
        DBG << "Trigg'd";
        bool capt_done = false;
        while(capt_done == false)
        {
            sp209api_get_capture_done_flag(h,&capt_done);
            msleep(200);
        }

        const uint8_t ch = 1;
        sp209api_get_available_samples(h,&samples_count,&post_trig_samples);
        sp209api_trs_reset(h,ch);
        trs.sampple_index = 0;
        DBG << "Capture done, total captured samples = " << samples_count;
        bool is_not_last = true;
        int trs_count = 0;
        while ((is_not_last) && (trs_count < 10))
        {
            sp209api_trs_get_next(h,ch,&trs);
            DBG << "TRS @" << trs.sampple_index << "[" << int(trs.value) << "]";
            sp209api_trs_is_not_last(h,ch,&is_not_last);
        }
    }

    if (e == IHWAPI_OK)
    {
        DBG << "Closing device";
        sp209api_device_power_off(h); //All done, power off.
    }

    sp209api_free(h);
    DBG << "Done" << std::endl;
    return 0;
}

Capture samples with trigger

And finally, let’s look at an example to capture some samples with a trigger condition.

In this example, we wait for a change on channel 1, which is defined by the lines:

trg.type = sp209api_trigger_type_t::SP209API_TRG_CHANGE; trg.channel = 1;

Here is the complete example:


#define DBG   std::cout << "\n\r" << " "

int main()
{
    sp209api_handle h;
    device_descriptor_t d;
    ihwapi_err_code_t e = IHWAPI_DEVICE_NOT_OPEN;
    sp209api_settings_t settings;
    uint16_t devices_count = 0;
    int64_t samples_count = 0;
    int64_t post_trig_samples = 0;
    sp209api_trs_t trs;



    sp209api_create_new_handle(&h,sp209api_device_model_t::SP209API_MODEL_209I);
    sp209api_create_device_list(h);
    sp209api_get_devices_count(h,&devices_count);
    DBG << "Found " << devices_count << " devices" ;
    if (devices_count > 0)
    {
        sp209api_get_device_descriptor(h,0,&d);
        DBG << "New device, serial number = " << d.sn << ", description = " << d.desc ;
        e = sp209api_device_open(h,d,SP209API_VARIANT_STD);
        if (e == IHWAPI_OK)
        {
            DBG << "Device is open";
        }
        else
        {
            DBG << "Device not open! error code = " << e ;
        }

    }
    sp209api_free_device_list(h);

    if (e == IHWAPI_OK)
    {
        memset(&settings,0,sizeof (settings));
        settings.sampling_depth = 250e3;
        settings.post_trig_depth = settings.sampling_depth * 0.9;
        settings.thresh_cfg[0] = SP209API_X_TH_3V3;
        settings.thresh_cfg[1] = SP209API_X_TH_3V3;
        settings.thresh_cfg[2] = SP209API_X_TH_3V3;
        sp209api_trigger_description_t trg;
        trg.type = sp209api_trigger_type_t::SP209API_TRG_CHANGE;
        trg.channel = 1;
        e = sp209api_launch_new_capture_simple_trigger(h,trg,settings);
        bool cfg_done = false;
        if (e == IHWAPI_OK)
        {
            while(cfg_done == false)
            {
                sp209api_get_config_done_flag(h,&cfg_done);
                msleep(200);
            }
            DBG << "Device Config done, new capture launched";
        }
        else
        {
            DBG << "Launch New capture error = " << e;

        }
    }



    if (e == IHWAPI_OK)
    {
        DBG << "Waiting for trigger..." << endl;
        bool trig_flag = false;
        while (trig_flag == false)
        {
            sp209api_get_triggered_flag(h,&trig_flag);
            msleep(200);
        }
        DBG << "Trigg'd";
        bool capt_done = false;
        while(capt_done == false)
        {
            sp209api_get_capture_done_flag(h,&capt_done);
            msleep(200);
        }

        const uint8_t ch = 1;
        sp209api_get_available_samples(h,&samples_count,&post_trig_samples);
        sp209api_trs_reset(h,ch);
        trs.sampple_index = 0;
        DBG << "Capture done, total captured samples = " << samples_count;
        bool is_not_last = true;
        while (is_not_last)
        {
            sp209api_trs_get_next(h,ch,&trs);
            DBG << "TRS @" << trs.sampple_index << "[" << int(trs.value) << "]";
            sp209api_trs_is_not_last(h,ch,&is_not_last);
        }
    }

    if (e == IHWAPI_OK)
    {
        DBG << "Closing device";
        sp209api_device_power_off(h); //All done, power off.
    }

    sp209api_free(h);
    DBG << "Done" << std::endl;
    return 0;
}