From 402841ec91d6250601bea466245097a14bf45c4e Mon Sep 17 00:00:00 2001 From: "Joshua M. Doe" Date: Tue, 13 Apr 2021 13:24:46 -0400 Subject: [PATCH] saperasrc: allow for logging FPGA temp if env var GST_SAPERA_FPGA_TEMP_LOG is set --- sys/sapera/CMakeLists.txt | 4 +- sys/sapera/aq2_prm_user.h | 22 ++++++ sys/sapera/corhw_prm_user.h | 151 ++++++++++++++++++++++++++++++++++++ sys/sapera/gstsaperasrc.cpp | 104 +++++++++++++++++++++++-- 4 files changed, 275 insertions(+), 6 deletions(-) create mode 100644 sys/sapera/aq2_prm_user.h create mode 100644 sys/sapera/corhw_prm_user.h diff --git a/sys/sapera/CMakeLists.txt b/sys/sapera/CMakeLists.txt index 678915d..8e021a6 100644 --- a/sys/sapera/CMakeLists.txt +++ b/sys/sapera/CMakeLists.txt @@ -19,7 +19,9 @@ target_link_libraries (${libname} ${GSTREAMER_LIBRARY} ${GSTREAMER_BASE_LIBRARY} ${GSTREAMER_VIDEO_LIBRARY} - ${SAPERA_LIBRARIES}) + ${SAPERA_LIBRARIES} + "C:\\Program Files\\Teledyne DALSA\\Sapera\\Lib\\Win64\\corapi.lib" + ) if (WIN32) install (FILES $ DESTINATION ${PDB_INSTALL_DIR} COMPONENT pdb OPTIONAL) diff --git a/sys/sapera/aq2_prm_user.h b/sys/sapera/aq2_prm_user.h new file mode 100644 index 0000000..cf3ba70 --- /dev/null +++ b/sys/sapera/aq2_prm_user.h @@ -0,0 +1,22 @@ +#ifndef _AQ2_PRM_USER +#define _AQ2_PRM_USER + +// Device indexes for CORHW_DEVICE_PRM_GET_VOLTAGE +#define AQ2_VOLTAGE_INDEX_12V 0 +#define AQ2_VOLTAGE_INDEX_INPUT_THRESHOLD 1 +#define AQ2_VOLTAGE_INDEX_FPGA_VCCINT 2 +#define AQ2_VOLTAGE_INDEX_FPGA_VCCAUX 3 +#define AQ2_VOLTAGE_POCL0_RSENSE 4 +#define AQ2_VOLTAGE_POCL1_RSENSE 5 + +// Device indexes for CORHW_DEVICE_PRM_GET_TEMPERATURE +#define AQ2_TEMPERATURE_INDEX_FPGA 0 + +// Parameter indexes for CORHW_DEVICE_PRM_GET_LANES_STATS +#define AQ2_CLHS_LANES_CRC_ERROR_COUNT 0 +#define AQ2_CLHS_LANES_VIDEO_MSG_COUNT 1 +#define AQ2_CLHS_LANES_PACKET_BUFFER_OVERFLOW_COUNT 2 +#define AQ2_CLHS_LANES_RESEND_FLAG_COUNT 3 +#define AQ2_CLHS_LANES_8B_10B_ERROR_COUNT 4 + +#endif \ No newline at end of file diff --git a/sys/sapera/corhw_prm_user.h b/sys/sapera/corhw_prm_user.h new file mode 100644 index 0000000..fc0e185 --- /dev/null +++ b/sys/sapera/corhw_prm_user.h @@ -0,0 +1,151 @@ +////////////////////////////////////////////////////////////////////////////// +// corhw_prm_user.h (c) Teledyne DALSA 2013 +// +// Description: +// Hardware Control Parameters +// +////////////////////////////////////////////////////////////////////////////// +#ifndef _CORHW_PRM_USER_H_ +#define _CORHW_PRM_USER_H_ +#include "cordef.h" + +#ifdef _MSC_VER +#pragma pack(1) +#endif + +#ifdef __BORLANDC__ +#pragma option -a1 +#endif + +#ifndef COR_PACK + #if COR_LINUX + #define COR_PACK __attribute__((packed)) + #else + #define COR_PACK + #endif +#endif + +#define CORHW_USER_DEVICE_PRM_SET_MEMORY_TEST 0x80000007 // W +#define CORHW_USER_DEVICE_PRM_SET_DIAGNOSTIC_MODE 0x80000009 // W +#define CORHW_USER_DEVICE_PRM_RESET_LANES_STATS 0x80000011 // W + +#define CORHW_USER_DEVICE_PRM_LOAD_FIRWMARE 0x00000023 +#define CORHW_USER_DEVICE_PRM_GET_MEMORY_TEST_RESULT 0x00000025 // R +#define CORHW_USER_DEVICE_PRM_GET_VOLTAGE 0x00000026 // R +#define CORHW_USER_DEVICE_PRM_GET_TEMPERATURE 0x00000027 // R +#define CORHW_USER_DEVICE_PRM_GET_BANDWIDTH 0x00000028 // R +#define CORHW_USER_DEVICE_PRM_GET_PCI_BUS_NUMBER 0x00000029 // R +#define CORHW_USER_DEVICE_PRM_GET_IS_RESET_NEEDED 0x0000002B // R +#define CORHW_USER_DEVICE_PRM_GET_PCI_SLOT_NUMBER 0x0000002E // R +#define CORHW_USER_DEVICE_PRM_GET_PCI_FUNCTION_NUMBER 0x0000002F // R +#define CORHW_USER_DEVICE_PRM_GET_PCIE_BUS_NB_LANES 0x00000030 // R +#define CORHW_USER_DEVICE_PRM_GET_PCIE_BUS_BIT_TRANSFER_RATE 0x00000031 // R +#define CORHW_USER_DEVICE_PRM_GET_PCIE_BUS_PAYLOAD_SIZE 0x00000032 // R +#define CORHW_USER_DEVICE_PRM_GET_PCIE_BUS_REQUEST_SIZE 0x00000034 // R +#define CORHW_USER_DEVICE_PRM_GET_THEORETICAL_BANDWIDTH 0x00000037 // R +#define CORHW_USER_DEVICE_PRM_GET_LANES_STATS 0x00000038 // R +#define CORHW_USER_DEVICE_PRM_GET_EYE_DIAGRAM 0x00000039 // R +#define CORHW_USER_DEVICE_PRM_GET_NB_LANES 0x00000043 // R +#define CORHW_USER_DEVICE_PRM_GET_TRANSMISSION_ENCODING 0x00000044 // R + +#define CORHW_DEVICE_PARAMETER_MEMORY_TEST_PATTERN 0 +#define CORHW_DEVICE_PARAMETER_MEMORY_TEST_RAMP 1 +#define CORHW_DEVICE_PARAMETER_MEMORY_TEST_RESET 2 + +#define CORHW_DEVICE_PARAMETER_MEMORY_TEST_PATTERN_BOARD_00 0x10000000 +#define CORHW_DEVICE_PARAMETER_MEMORY_TEST_PATTERN_BOARD_01 0x10000001 +#define CORHW_DEVICE_PARAMETER_MEMORY_TEST_PATTERN_BOARD_02 0x10000002 +#define CORHW_DEVICE_PARAMETER_MEMORY_TEST_PATTERN_BOARD_03 0x10000003 +#define CORHW_DEVICE_PARAMETER_MEMORY_TEST_PATTERN_BOARD_04 0x10000004 +#define CORHW_DEVICE_PARAMETER_MEMORY_TEST_PATTERN_BOARD_05 0x10000005 + +typedef struct _CORHW_DEVICE_PARAMETER_SET_DIAGNOSTIC_MODE_DATA +{ + UINT32 mode; // 0=Disable 1=Enable; +} CORHW_DEVICE_PARAMETER_SET_DIAGNOSTIC_MODE_DATA, *PCORHW_DEVICE_PARAMETER_SET_DIAGNOSTIC_MODE_DATA; + +typedef struct _CORHW_DEVICE_PARAMETER_MEMORY_TEST_DATA +{ + UINT32 testNumber; + UINT32 timeoutMs; // in ms +} CORHW_DEVICE_PARAMETER_MEMORY_TEST_DATA, *PCORHW_DEVICE_PARAMETER_MEMORY_TEST_DATA; + +typedef struct _CORHW_DEVICE_PARAMETER_GET_MEMORY_TEST_RESULT_DATA +{ + DWORD nErrors; + //char szSource[CORCMD_NAME_LENGTH];// string name of the memory e.g: "DDR2" + UINT32 addressSizeInByte; + UINT32 busSizeInByte; + UINT32 memSizeInByte; + ULONG_PTR pBuffer; + ULONG_PTR pResult; +} CORHW_DEVICE_PARAMETER_GET_MEMORY_TEST_RESULT_DATA, *PCORHW_DEVICE_PARAMETER_GET_MEMORY_TEST_RESULT_DATA; + +struct MEM_TEST_RESULT +{ + UINT32 address; + UINT8 *readData; + UINT8 *expectedData; +}; + +typedef struct _CORHW_DEVICE_PARAMETER_GET_VOLTAGE_DATA +{ + DWORD min; // in mVolts + DWORD max; // in mVolts + DWORD value; // in mVolts +} CORHW_DEVICE_PARAMETER_GET_VOLTAGE_DATA, *PCORHW_DEVICE_PARAMETER_GET_VOLTAGE_DATA; + +typedef struct _CORHW_DEVICE_PARAMETER_GET_TEMPERATURE_DATA +{ + DWORD min; // in 1/1000 C + DWORD max; // in 1/1000 C + DWORD value; // in 1/1000 C +} CORHW_DEVICE_PARAMETER_GET_TEMPERATURE_DATA, *PCORHW_DEVICE_PARAMETER_GET_TEMPERATURE_DATA; + +typedef struct _CORHW_DEVICE_PARAMETER_GET_EYE_DIAGRAM_DATA_IN +{ + UINT32 type; + char* resolution; + void *fctCallback; + void *context; +} CORHW_DEVICE_PARAMETER_GET_EYE_DIAGRAM_DATA_IN, *PCORHW_DEVICE_PARAMETER_GET_EYE_DIAGRAM_DATA_IN; + +typedef struct _CORHW_DEVICE_PARAMETER_GET_EYE_DIAGRAM_DATA_OUT +{ + void *pData; + UINT32 *pSize; + UINT32 *pWidth; + UINT32 *pHeight; + UINT32 *pPercent; +} CORHW_DEVICE_PARAMETER_GET_EYE_DIAGRAM_DATA_OUT, *PCORHW_DEVICE_PARAMETER_GET_EYE_DIAGRAM_DATA_OUT; + +typedef struct _CORHW_DEVICE_PARAMETER_GET_NB_REGISTRY_PARAMETERS +{ + DWORD value; //count +} CORHW_DEVICE_PARAMETER_GET_NB_REGISTRY_PARAMETERS, *PCORHW_DEVICE_PARAMETER_GET_NB_REGISTRY_PARAMETERS; + +typedef struct _CORHW_DEVICE_PARAMETER_GET_REGISTRY_PARAMETER +{ + DWORD index; + DWORD type; //1=Byte,2=Word,4=DWORD,8=QWORD,16=String + CHAR *key; + DWORD lengthKey; + void *value; + DWORD lengthValue; +} CORHW_DEVICE_PARAMETER_GET_REGISTRY_PARAMETER, *PCORHW_DEVICE_PARAMETER_GET_REGISTRY_PARAMETER; + +typedef struct _CORHW_DEVICE_PARAMETER_SET_REGISTRY_PARAMETER +{ + DWORD type; //1=Byte,2=Word,4=DWORD,8=QWORD,16=String + CHAR *key; + DWORD lengthKey; + void *value; + DWORD lengthValue; +} CORHW_DEVICE_PARAMETER_SET_REGISTRY_PARAMETER, *PCORHW_DEVICE_PARAMETER_SET_REGISTRY_PARAMETER; + + +#ifdef _MSC_VER +#pragma pack() +#endif + +#endif \ No newline at end of file diff --git a/sys/sapera/gstsaperasrc.cpp b/sys/sapera/gstsaperasrc.cpp index c46b6b7..0a6beeb 100644 --- a/sys/sapera/gstsaperasrc.cpp +++ b/sys/sapera/gstsaperasrc.cpp @@ -36,6 +36,9 @@ #include +#include "aq2_prm_user.h" +#include "corhw_prm_user.h" + #include "gstsaperasrc.h" GST_DEBUG_CATEGORY_STATIC (gst_saperasrc_debug); @@ -180,6 +183,92 @@ gst_saperasrc_pro_callback (SapProCallbackInfo * pInfo) /* TODO: handle buffer */ } +typedef struct COR_PACK +{ + UINT32 deviceIndex; // device to access + UINT32 prmIndex; // one of CORHW_DEVICE_PRM_xxx + UINT32 prmSize; // size in bytes of the variable size input data following +} CORCMD_DEVICE_PARAMETER, *PCORCMD_DEVICE_PARAMETER; + +#define CORCMD_USER_DEVICE_PARAMETER_READ (CORMAN_CORECO_CMD + 97) + +float +gst_saperasrc_get_fpga_temperature (GstSaperaSrc * src) +{ + CORSERVER server; + CORCMD_DEVICE_PARAMETER parameters = { 0 }; + CORHW_DEVICE_PARAMETER_GET_TEMPERATURE_DATA data = { 0 }; + + if (!SapManager::GetServerHandle (src->server_index, &server)) { + GST_WARNING_OBJECT (src, "Failed to get server handle"); + return 0; + } + + parameters.prmIndex = CORHW_USER_DEVICE_PRM_GET_TEMPERATURE; + parameters.deviceIndex = AQ2_TEMPERATURE_INDEX_FPGA; //Board Specific + parameters.prmSize = sizeof (data); + + UINT32 status = + CorManControl (server, CORCMD_USER_DEVICE_PARAMETER_READ, ¶meters, + sizeof (parameters), &data, sizeof (data)); + if (status) { + GST_WARNING_OBJECT (src, "Failed to query temperature: %08X", status); + return 0; + } + + return data.value / 1000.0f; +} + +void +gst_saperasrc_log_fpga_temperature (GstSaperaSrc * src) +{ + static FILE *temperature_file = NULL; + static gint64 temp_log_last_time = 0; + + if (g_getenv ("GST_SAPERA_FPGA_TEMP_LOG")) { + if (temperature_file == NULL) { + const char *envvar = g_getenv ("GST_SAPERA_FPGA_TEMP_LOG"); + gboolean write_header; + gchar *log_filename; + if (atoi (envvar) == 1) { + GDateTime *dt = g_date_time_new_now_local (); + log_filename = + g_date_time_format (dt, "sapera_fgpa_temp_%Y%m%d_%H%M%S.csv"); + g_date_time_unref (dt); + } else { + log_filename = g_strdup (envvar); + } + + write_header = !g_file_test (log_filename, G_FILE_TEST_EXISTS); + + GST_DEBUG_OBJECT (src, "Opening FPGA temp log file (%s)", log_filename); + temperature_file = fopen (log_filename, "a"); + if (!temperature_file) { + GST_ERROR_OBJECT (src, "Failed to open log file"); + return; + } + g_free (log_filename); + + if (write_header) { + fprintf (temperature_file, "IsoTime, UnixTime, KayaFpgaTemp\n"); + } + } + + if (temperature_file && g_get_real_time () - temp_log_last_time >= 1000000) { + GDateTime *dt = g_date_time_new_now_local (); + gchar *time_str = g_date_time_format (dt, "%Y-%m-%dT%H:%M:%S, %s"); + float fg_temp = gst_saperasrc_get_fpga_temperature (src); + GST_DEBUG_OBJECT (src, "FPGA temp: %,3f", fg_temp); + fprintf (temperature_file, "%s, %.3f\n", time_str, fg_temp); + fflush (temperature_file); + g_date_time_unref (dt); + g_free (time_str); + temp_log_last_time = g_get_real_time (); + } + } +} + + gboolean gst_saperasrc_init_objects (GstSaperaSrc * src) { @@ -241,7 +330,6 @@ gst_saperasrc_create_objects (GstSaperaSrc * src) return FALSE; } } - //if (!src->sap_acq->GetParameter (CORACQ_PRM_VIDEO, &video_type)) { // gst_saperasrc_destroy_objects (src); // return FALSE; @@ -281,7 +369,7 @@ gst_saperasrc_create_objects (GstSaperaSrc * src) /* Create transfer object */ if (src->sap_xfer && !*src->sap_xfer) { if (!src->sap_xfer->Create ()) { - GST_ERROR_OBJECT (src, "Failed to create SapTransfer"); + GST_ERROR_OBJECT (src, "Failed to create SapTransfer"); gst_saperasrc_destroy_objects (src); return FALSE; } @@ -292,7 +380,7 @@ gst_saperasrc_create_objects (GstSaperaSrc * src) /* Create processing object */ if (src->sap_pro && !*src->sap_pro) { if (!src->sap_pro->Create ()) { - GST_ERROR_OBJECT (src, "Failed to create SapProcessing"); + GST_ERROR_OBJECT (src, "Failed to create SapProcessing"); gst_saperasrc_destroy_objects (src); return FALSE; } @@ -655,7 +743,8 @@ gst_saperasrc_start (GstBaseSrc * bsrc) } gst_video_info_init (&vinfo); - gst_video_info_set_format (&vinfo, gst_format, src->sap_buffers->GetWidth (), src->sap_buffers->GetHeight ()); + gst_video_info_set_format (&vinfo, gst_format, src->sap_buffers->GetWidth (), + src->sap_buffers->GetHeight ()); src->caps = gst_video_info_to_caps (&vinfo); src->width = vinfo.width; @@ -747,6 +836,10 @@ gst_saperasrc_create (GstPushSrc * psrc, GstBuffer ** buf) { GstSaperaSrc *src = GST_SAPERA_SRC (psrc); + GST_LOG_OBJECT (src, "create"); + + gst_saperasrc_log_fpga_temperature (src); + g_mutex_lock (&src->buffer_mutex); while (src->buffer == NULL) g_cond_wait (&src->buffer_cond, &src->buffer_mutex); @@ -776,4 +869,5 @@ GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, sapera, "Teledyne DALSA Sapera frame grabber source", - plugin_init, GST_PACKAGE_VERSION, GST_PACKAGE_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) + plugin_init, GST_PACKAGE_VERSION, GST_PACKAGE_LICENSE, GST_PACKAGE_NAME, + GST_PACKAGE_ORIGIN)