Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 23 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,18 @@ include(FetchContent)
# json-c Library
FetchContent_Declare(
json_c
GIT_REPOSITORY https://github.com/json-c/json-c
GIT_REPOSITORY https://github.com/json-c/json-c.git
GIT_TAG 2372e9518e6ba95b48d37ec162bc7d93b297b52f
FIND_PACKAGE_ARGS NAMES json-c
)

set(BUILD_SHARED_LIBS OFF)
set(JSON_C_BUILD_APPS OFF)
set(JSON_C_BUILD_SHARED_LIBS OFF)
FetchContent_MakeAvailable(json_c)

# zlib Library
FetchContent_Declare(
zlib
GIT_REPOSITORY https://github.com/madler/zlib.git
GIT_TAG v1.3.1
FIND_PACKAGE_ARGS NAMES zlib
)

set(ZLIB_BUILD_TESTING OFF)
Expand Down Expand Up @@ -131,11 +129,16 @@ set_target_properties(tslitex PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/$<0:>
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/$<0:>)

target_link_libraries(tslitex PUBLIC litepcie)
target_link_libraries(tslitex PRIVATE json-c-static zlibstatic)
target_link_libraries(tslitex
PUBLIC
"$<LINK_LIBRARY:WHOLE_ARCHIVE,litepcie>"
PRIVATE
json-c-static
zlibstatic
)

if(APPLE)
target_link_libraries(tslitex PRIVATE "-framework IOKit")
target_link_libraries(tslitex PRIVATE "$<LINK_LIBRARY:FRAMEWORK,IOKit>")
endif()

target_include_directories(tslitex PUBLIC include)
Expand All @@ -155,10 +158,20 @@ set_target_properties(tslitex_static PROPERTIES

set_target_properties(tslitex_static PROPERTIES POSITION_INDEPENDENT_CODE 1)

target_link_libraries(tslitex_static PUBLIC litepcie)
target_link_libraries(tslitex_static PRIVATE json-c-static zlibstatic)
target_link_libraries(tslitex_static
PUBLIC
"$<LINK_LIBRARY:WHOLE_ARCHIVE,litepcie>"
PRIVATE
json-c-static
zlibstatic
)

target_include_directories(tslitex_static PUBLIC include)

if(APPLE)
target_link_libraries(tslitex_static PRIVATE "$<LINK_LIBRARY:FRAMEWORK,IOKit>")
endif()

file(COPY ${TS_LIB_HEADERS} DESTINATION ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/include)

####
Expand Down
13 changes: 8 additions & 5 deletions bindings/python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,19 @@ add_custom_command(
)

add_custom_target(pydeps
DEPENDS tslitex/tslitex.c
${CMAKE_CURRENT_BINARY_DIR}/lib/include/thunderscope.h
tslitex_static
DEPENDS
tslitex/tslitex.c
${CMAKE_CURRENT_BINARY_DIR}/lib/include/thunderscope.h
tslitex_static
)

set(PY_BIND_LIBS tslitex_static)

if(WIN32)
list(APPEND PY_BIND_LIBS setupapi)
list(APPEND PY_BIND_LIBS litepcie json-c-static zlibstatic)
list(APPEND PY_BIND_LIBS setupapi)
list(APPEND PY_BIND_LIBS litepcie json-c-static zlibstatic)
else()
list(APPEND PY_BIND_LIBS litepcie json-c z)
endif()
list(JOIN PY_BIND_LIBS "\", \"" PY_EXT_LIBS)

Expand Down
6 changes: 6 additions & 0 deletions bindings/python/tslitex.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ cdef extern from "thunderscope.h":
uint8_t power_state
uint8_t pll_state
uint8_t afe_state
uint8_t local_osc_clk
uint8_t ref_in_clk
uint8_t pll_lock
uint8_t pll_low
uint8_t pll_high
uint8_t pll_alt
sysHealth_t sys_health

ctypedef tsScopeState_s tsScopeState_t
Expand Down
141 changes: 138 additions & 3 deletions example/thunderscope_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

#ifdef _WIN32
#include <Windows.h>
#else
#include <csignal>
#endif

#define OPTPARSE_IMPLEMENTATION
Expand Down Expand Up @@ -95,10 +97,28 @@ uint32_t _SPI_CONTROL_START = (1 << 0);
uint32_t _SPI_CONTROL_LENGTH = (1 << 8);
uint32_t _SPI_STATUS_DONE = (1 << 0);

static volatile bool g_program_loop = true;

/* Main */
/*------*/

#ifdef _WIN32
BOOL WINAPI SigHandler(DWORD ctrlType)
{
if(ctrlType == CTRL_C_EVENT)
{
g_program_loop = false;
return TRUE;
}
return FALSE;
}
#else
extern "C" void SigHandler(int s)
{
g_program_loop = false;
}
#endif

void configure_frontend_ldo(file_t fd, uint32_t enable) {
uint32_t control_value = litepcie_readl(fd, CSR_FRONTEND_CONTROL_ADDR);
control_value &= ~(1 * AFE_CONTROL_LDO_EN);
Expand Down Expand Up @@ -306,7 +326,7 @@ static void test_io(file_t fd, bool isBeta)
}

static void test_capture(file_t fd, uint32_t idx, uint8_t channelBitmap, uint16_t bandwidth,
uint32_t volt_scale_uV, int32_t offset_uV, uint8_t ac_couple, uint8_t term, bool watch_bitslip, bool is12bit)
uint32_t volt_scale_uV, int32_t offset_uV, uint8_t ac_couple, uint8_t term, bool watch_bitslip, bool is12bit, bool inRefClk, bool outRefClk, uint32_t refclkFreq)
{
uint8_t numChan = 0;
tsHandle_t tsHdl = thunderscopeOpen(idx, false);
Expand All @@ -317,6 +337,17 @@ static void test_capture(file_t fd, uint32_t idx, uint8_t channelBitmap, uint16_
uint64_t sampleLen = 0;
uint32_t sampleRate = 1000000000;

if(inRefClk)
{
printf("Setting Ref In Clock @ %u Hz\n", refclkFreq);
printf("\t Result: %i\n", thunderscopeRefClockSet(tsHdl, TS_REFCLK_IN, refclkFreq));
}
else if(outRefClk)
{
printf("Setting Ref Out Clock @ %u Hz\n", refclkFreq);
printf("\t Result: %i\n", thunderscopeRefClockSet(tsHdl, TS_REFCLK_OUT, refclkFreq));
}

//Setup and Enable Channels
tsChannelParam_t chConfig = {0};
uint8_t channel = 0;
Expand Down Expand Up @@ -378,7 +409,7 @@ static void test_capture(file_t fd, uint32_t idx, uint8_t channelBitmap, uint16_
auto startTime = std::chrono::steady_clock::now();
if(sampleBuffer != NULL)
{
for(uint32_t loop=0; loop < 8; loop++)
for(uint32_t loop=0; loop < 150; loop++)
{
uint32_t readReq = (TS_SAMPLE_BUFFER_SIZE * 0x100);
//Collect Samples
Expand All @@ -396,12 +427,15 @@ static void test_capture(file_t fd, uint32_t idx, uint8_t channelBitmap, uint16_

if(watch_bitslip)
{
tsScopeState_t scopeState = {0};
bitslip_count = litepcie_readl(fd, CSR_ADC_HMCAD1520_BITSLIP_COUNT_ADDR);
printf("Bitslip Snapshot: %lu\r\n", bitslip_count);
dbg_monitor = litepcie_readl(fd, CSR_ADC_HMCAD1520_FRAME_DEBUG_ADDR);
printf("FRAME Debug: 0x%08x\r\n", dbg_monitor);
dbg_monitor = litepcie_readl(fd, CSR_ADC_HMCAD1520_RANGE_ADDR);
printf("RANGE: 0x%08x\r\n", dbg_monitor);
thunderscopeStatusGet(tsHdl, &scopeState);
printf("Scope State Flags: 0x%08x\r\n", scopeState.flags);
}
}
}
Expand Down Expand Up @@ -576,6 +610,61 @@ static void flash_test(char* arg, file_t fd)
}
}

static void test_clock(uint32_t idx, bool refoutclk, bool refinclk, uint32_t refclkfreq)
{
tsHandle_t tsHdl = thunderscopeOpen(idx, false);
bool firstStatus = false;

if(tsHdl)
{
#ifdef _WIN32
SetConsoleCtrlHandler(SigHandler, TRUE);
#else
struct sigaction signalHandler;
signalHandler.sa_handler = SigHandler;
sigemptyset(&signalHandler.sa_mask);
signalHandler.sa_flags = 0;
sigaction(SIGINT, &signalHandler, NULL);
#endif
if(refinclk)
{
printf("Setting Ref In Clock @ %u Hz\n", refclkfreq);
printf("\t Result: %i\n", thunderscopeRefClockSet(tsHdl, TS_REFCLK_IN, refclkfreq));
}
else if(refoutclk)
{
printf("Setting Ref Out Clock @ %u Hz\n", refclkfreq);
printf("\t Result: %i\n", thunderscopeRefClockSet(tsHdl, TS_REFCLK_OUT, refclkfreq));
}

while (g_program_loop)
{
tsScopeState_t state = {0};
thunderscopeStatusGet(tsHdl, &state);
// if(!firstStatus)
// {
// printf("\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A");
// firstStatus = true;
// }
printf("-------\r\n");
printf("PLL Status:\r\n");
printf("\tPLL LOCK - %01x\r\n", state.pll_lock);
printf("\tPLL HIGH - %01x\r\n", state.pll_high);
printf("\tPLL LOW - %01x\r\n", state.pll_low);
printf("\tPLL ALT - %01x\r\n", state.pll_alt);
printf("INPUT Clock Status:\r\n");
printf("\tLocal Valid - %01x\r\n", state.local_osc_clk);
printf("\tREF IN Valid - %01x\r\n", state.ref_in_clk);
printf("\r\n-- PRESS CTRL+C TO STOP --\r\n");

std::cout.flush();
std::this_thread::sleep_until(awake_time());
}

thunderscopeClose(tsHdl);
}
}

static void print_help(void)
{
printf("TS Test Util Usage:\r\n");
Expand All @@ -592,6 +681,9 @@ static void print_help(void)
printf("\t\t -o <uvolts> Channel Offset [microvolt]\r\n");
printf("\t\t -a AC Couple\r\n");
printf("\t\t -t 50 Ohm termination\r\n");
printf("\t refclk - run the PLL source with different clock configurations\r\n");
printf("\t\t -i <hz> Set the Ref IN Clock frequency\r\n");
printf("\t\t -r <hz> Set the Ref OUT Clock frequency\r\n");
}

/* Main */
Expand All @@ -615,13 +707,18 @@ int main(int argc, char** argv)
uint8_t term = 0;
bool bitslip = false;
bool mode12bit = false;
bool refInClk = false;
bool refOutClk = false;
uint32_t refclkFreq = 0;

struct optparse_long argList[] = {
{"dev", 'd', OPTPARSE_REQUIRED},
{"chan", 'c', OPTPARSE_REQUIRED},
{"bw", 'b', OPTPARSE_REQUIRED},
{"voltsuv", 'v', OPTPARSE_REQUIRED},
{"offsetuv", 'o', OPTPARSE_REQUIRED},
{"refinclk", 'i', OPTPARSE_REQUIRED},
{"refoutclk",'r', OPTPARSE_REQUIRED},
{"ac", 'a', OPTPARSE_NONE},
{"term", 't', OPTPARSE_NONE},
{"bits", 's', OPTPARSE_NONE},
Expand Down Expand Up @@ -659,6 +756,16 @@ int main(int argc, char** argv)
offset_uV = strtol(options.optarg, NULL, 0);
argCount+=2;
break;
case 'i':
refInClk = true;
refclkFreq = strtol(options.optarg, NULL, 0);
argCount+=2;
break;
case 'r':
refOutClk = true;
refclkFreq = strtol(options.optarg, NULL, 0);
argCount+=2;
break;
case 'a':
ac_couple = 1;
argCount++;
Expand Down Expand Up @@ -689,6 +796,29 @@ int main(int argc, char** argv)
exit(EXIT_FAILURE);
}

if(0 == strcmp(arg, "list"))
{
uint32_t i = 0;
tsDeviceInfo_t infos;
while(TS_STATUS_OK == thunderscopeListDevices(i, &infos))
{
if(i==0)
{
printf("Found ThunderScope(s):\n");
}
printf("\t%3d | Serial Number: %s\n", i, infos.serial_number);
printf("\t | HW Rev: 0x%x\n", infos.hw_id);
printf("\t | GW Rev: 0x%x\n", infos.gw_id);
printf("\t | LiteX Rev: 0x%x\n", infos.litex);
i++;
}
if(i == 0)
{
printf("No devices present\n");
}
exit(EXIT_SUCCESS);
}

if(0 == strcmp(arg, "clk"))
{
mcp_clkgen_conf_t test_conf[1024];
Expand Down Expand Up @@ -788,13 +918,18 @@ int main(int argc, char** argv)
// Setup Channel, record samples to buffer, save buffer to file
else if(0 == strcmp(arg, "capture"))
{
test_capture(fd, idx, channelBitmap, bandwidth, volt_scale_uV, offset_uV, ac_couple, term, bitslip, mode12bit);
test_capture(fd, idx, channelBitmap, bandwidth, volt_scale_uV, offset_uV, ac_couple, term, bitslip, mode12bit, refInClk, refOutClk, refclkFreq);
}
// Flash test
else if(0 == strcmp(arg, "flash"))
{
flash_test(argv[argCount+1], fd);
}
// Test REF Clock Modes
else if(0 == strcmp(arg, "clock"))
{
test_clock(idx, refOutClk, refInClk, refclkFreq);
}
//Print Help
else
{
Expand Down
7 changes: 4 additions & 3 deletions example/tsControl.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ def reset_fields(self):
# Create the main application window
root = tk.Tk()
root.title("Thunderscope Channel Tester")
root.geometry("600x450") # Set the window size
root.geometry("650x650") # Set the window size

# Create an instance of TsDelegate
delegate = TsDelegate(root)
Expand Down Expand Up @@ -262,9 +262,10 @@ def create_status_tab(notebook, delegate):
# Define the keys from tsScopeState_t
keys = [
"adc_sample_rate", "adc_sample_bits", "adc_sample_resolution", "adc_lost_buffer_count",
"flags", "adc_state", "power_state", "pll_state", "afe_state",
"flags", "adc_state", "adc_sync", "power_state", "pll_state", "afe_state",
"sys_health.temp_c", "sys_health.vcc_int", "sys_health.vcc_aux",
"sys_health.vcc_bram", "sys_health.frontend_power_good", "sys_health.acq_power_good"
"sys_health.vcc_bram", "sys_health.frontend_power_good", "sys_health.acq_power_good",
"local_osc_clk", "ref_in_clk", "pll_lock", "pll_low", "pll_high", "pll_alt"
]

# Create labels and fields for each key
Expand Down
10 changes: 10 additions & 0 deletions include/thunderscope.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ int32_t thunderscopeChannelConfigGet(tsHandle_t ts, uint32_t channel, tsChannelP
*/
int32_t thunderscopeChannelConfigSet(tsHandle_t ts, uint32_t channel, tsChannelParam_t* conf);

/**
* @brief Set the mode and frequency for the external Reference Clock
*
* @param ts Handle to the Thunderscope device
* @param mode Set the Clock IN/OUT mode
* @param refclk_freq Set the input clock frequency if in IN mode, or output frequency if in OUT mode
* @return int32_t TS_STATUS_OK if the reference clock was configured
*/
int32_t thunderscopeRefClockSet(tsHandle_t ts, tsRefClockMode_t mode, uint32_t refclk_freq);

/**
* @brief Get the status for the Thunderscope device
*
Expand Down
Loading
Loading