106 lines
2.4 KiB
C
106 lines
2.4 KiB
C
#include "hctr.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <NIDAQmx.h>
|
|
|
|
#define DAQmxErrChk(functionCall) \
|
|
if( DAQmxFailed(error=(functionCall)) ) \
|
|
goto Error; \
|
|
else
|
|
|
|
/**
|
|
* This structure encapsulates the data that is private to
|
|
* the implementation of the NI DAQ counter interface
|
|
*/
|
|
typedef struct counter_private_t
|
|
{
|
|
/** NIDAQ opaque task handle */
|
|
TaskHandle taskHandle;
|
|
/** Actual physical counter value, as returned by NIDAQ
|
|
* read function */
|
|
uInt32 count32;
|
|
/** extended 64-bit counter value */
|
|
unsigned long long count64;
|
|
} COUNTER_PRIVATE;
|
|
|
|
int hctr_ctor(const char* device_name, pHCTR* ptr)
|
|
{
|
|
int error = 0;
|
|
*ptr = (COUNTER_PRIVATE*) malloc(sizeof(COUNTER_PRIVATE));
|
|
memset(*ptr, 0, sizeof(COUNTER_PRIVATE));
|
|
|
|
/*********************************************/
|
|
// Create a DAQmx task to hold the counter
|
|
/*********************************************/
|
|
DAQmxErrChk (DAQmxCreateTask("",&(*ptr)->taskHandle));
|
|
|
|
/*********************************************/
|
|
// Create a DAQmx counter within the task
|
|
/*********************************************/
|
|
DAQmxErrChk (
|
|
DAQmxCreateCICountEdgesChan((*ptr)->taskHandle,
|
|
device_name,
|
|
"",
|
|
DAQmx_Val_Rising,
|
|
(*ptr)->count32,
|
|
DAQmx_Val_CountUp));
|
|
|
|
/*********************************************/
|
|
// Start the DAQmx task
|
|
/*********************************************/
|
|
DAQmxErrChk (DAQmxStartTask((*ptr)->taskHandle));
|
|
|
|
return 0;
|
|
Error:
|
|
free(*ptr);
|
|
*ptr = NULL;
|
|
return error;
|
|
}
|
|
|
|
int hctr_read(pHCTR hctr, unsigned long long* value)
|
|
{
|
|
int error = 0;
|
|
uInt32 ctr;
|
|
DAQmxErrChk (DAQmxReadCounterScalarU32(hctr->taskHandle,
|
|
1.0,
|
|
&ctr,
|
|
NULL));
|
|
hctr->count64 += ctr - hctr->count32;
|
|
hctr->count32 = ctr;
|
|
*value = hctr->count64;
|
|
return 0;
|
|
Error:
|
|
return error;
|
|
}
|
|
|
|
int hctr_dtor(pHCTR* hctr)
|
|
{
|
|
if( hctr && *hctr && (*hctr)->taskHandle!=0 )
|
|
{
|
|
/*********************************************/
|
|
// DAQmx Stop Code
|
|
/*********************************************/
|
|
DAQmxStopTask((*hctr)->taskHandle);
|
|
DAQmxClearTask((*hctr)->taskHandle);
|
|
}
|
|
(*hctr)->taskHandle = 0;
|
|
free (*hctr);
|
|
*hctr = NULL;
|
|
return 0;
|
|
}
|
|
|
|
bool hctr_failed(int error)
|
|
{
|
|
if (DAQmxFailed(error))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
void hctr_errmsg(char* buff, int len)
|
|
{
|
|
*buff = '\0';
|
|
DAQmxGetExtendedErrorInfo(buff, len);
|
|
}
|
|
|