Add output line drive and partial hardware sync
r1112 | dcl | 2006-09-07 16:48:08 +1000 (Thu, 07 Sep 2006) | 2 lines
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
#include "hctr.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <NIDAQmx.h>
|
||||
|
||||
#define DAQmxErrChk(functionCall) \
|
||||
if( DAQmxFailed(error=(functionCall)) ) \
|
||||
goto Error; \
|
||||
else
|
||||
do { if( DAQmxFailed(error=(functionCall)) ) \
|
||||
goto Error; } while(0);
|
||||
|
||||
/**
|
||||
* This structure encapsulates the data that is private to
|
||||
@@ -21,14 +22,76 @@ typedef struct counter_private_t
|
||||
uInt32 count32;
|
||||
/** extended 64-bit counter value */
|
||||
unsigned long long count64;
|
||||
/** NIDAQ device number of card */
|
||||
int device_number;
|
||||
/** NI counter number on card */
|
||||
int counter_number;
|
||||
/** true if using external sync else timer based sampling */
|
||||
bool sync;
|
||||
/** sync line number on the card */
|
||||
int sync_line_number;
|
||||
/** output line number on the card */
|
||||
int output_line_number;
|
||||
/** NIDAQ opaque task handle for digital output */
|
||||
TaskHandle taskHandle_dout;
|
||||
} COUNTER_PRIVATE;
|
||||
|
||||
typedef struct mapping_t {
|
||||
int cntr_num;
|
||||
int sync_num;
|
||||
int outp_num;
|
||||
} MAPPING;
|
||||
|
||||
MAPPING mapping[8] = {
|
||||
{ 0, 37, 36 },
|
||||
{ 1, 33, 32 },
|
||||
{ 2, 29, 28 },
|
||||
{ 3, 25, 24 },
|
||||
{ 4, 21, 20 },
|
||||
{ 5, 17, 16 },
|
||||
{ 6, 13, 12 },
|
||||
{ 7, 9, 8 }
|
||||
};
|
||||
|
||||
int hctr_ctor(const char* device_name, pHCTR* ptr)
|
||||
{
|
||||
int error = 0;
|
||||
bool flag = false;
|
||||
char text_string[] = "dev1/ctr0";
|
||||
const char *name;
|
||||
const char *text;
|
||||
|
||||
*ptr = (COUNTER_PRIVATE*) malloc(sizeof(COUNTER_PRIVATE));
|
||||
memset(*ptr, 0, sizeof(COUNTER_PRIVATE));
|
||||
|
||||
name = device_name;
|
||||
text = text_string;
|
||||
while (name && *name)
|
||||
{
|
||||
if (isspace(*name))
|
||||
++name;
|
||||
else if (*name >= '0' && *name <= '7')
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
(*ptr)->counter_number = *name - '0';
|
||||
(*ptr)->sync_line_number = mapping[(*ptr)->counter_number].sync_num;
|
||||
(*ptr)->output_line_number = mapping[(*ptr)->counter_number].outp_num;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*ptr)->device_number = *name - '0';
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
else if (tolower(*name) != *text)
|
||||
{
|
||||
/* TODO error */
|
||||
break;
|
||||
}
|
||||
++name;
|
||||
++text;
|
||||
}
|
||||
/*********************************************/
|
||||
// Create a DAQmx task to hold the counter
|
||||
/*********************************************/
|
||||
@@ -73,6 +136,140 @@ Error:
|
||||
return error;
|
||||
}
|
||||
|
||||
int make_dout_task(pHCTR ptr)
|
||||
{
|
||||
int error = 0;
|
||||
char port_range[40];
|
||||
/*********************************************/
|
||||
// Create a DAQmx task to hold the counter
|
||||
/*********************************************/
|
||||
DAQmxErrChk (DAQmxCreateTask("",&ptr->taskHandle_dout));
|
||||
|
||||
/*********************************************/
|
||||
// Create the digital channel within the task
|
||||
/*********************************************/
|
||||
snprintf(port_range, sizeof(port_range), "DEV%d/LINE%d",
|
||||
ptr->device_number, ptr->counter_number);
|
||||
DAQmxErrChk (DAQmxCreateDOChan(ptr->taskHandle_dout,
|
||||
port_range,
|
||||
"",
|
||||
DAQmx_Val_ChanPerLine));
|
||||
|
||||
/*********************************************/
|
||||
// Start the DAQmx task
|
||||
/*********************************************/
|
||||
DAQmxErrChk (DAQmxStartTask(ptr->taskHandle_dout));
|
||||
|
||||
Error:
|
||||
return error;
|
||||
}
|
||||
|
||||
int hctr_outp(pHCTR hctr, int value)
|
||||
{
|
||||
int error = 0;
|
||||
uInt8 data;
|
||||
if (value < 0) {
|
||||
if (hctr->taskHandle_dout != 0) {
|
||||
data = 0;
|
||||
DAQmxWriteDigitalLines(hctr->taskHandle_dout,
|
||||
1,
|
||||
1,
|
||||
10.0,
|
||||
DAQmx_Val_GroupByChannel,
|
||||
&data,
|
||||
NULL,
|
||||
NULL);
|
||||
/*********************************************/
|
||||
// DAQmx Stop Code
|
||||
/*********************************************/
|
||||
DAQmxStopTask(hctr->taskHandle_dout);
|
||||
DAQmxClearTask(hctr->taskHandle_dout);
|
||||
hctr->taskHandle_dout = 0;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
if (hctr->taskHandle_dout == 0)
|
||||
DAQmxErrChk (make_dout_task(hctr));
|
||||
if (value > 0)
|
||||
data = 1;
|
||||
else
|
||||
data = 0;
|
||||
#if 0
|
||||
DAQmxErrChk (
|
||||
DAQmxWriteDigitalLines(hctr->taskHandle_dout,
|
||||
1,
|
||||
1,
|
||||
10.0,
|
||||
DAQmx_Val_GroupByChannel,
|
||||
&data,
|
||||
NULL,
|
||||
NULL));
|
||||
#else
|
||||
DAQmxErrChk (
|
||||
DAQmxWriteDigitalScalarU32(hctr->taskHandle_dout,
|
||||
1,
|
||||
10.0,
|
||||
data,
|
||||
NULL));
|
||||
#endif
|
||||
Error:
|
||||
return error;
|
||||
}
|
||||
|
||||
void hctr_sync(pHCTR hctr, bool external)
|
||||
{
|
||||
int error = 0;
|
||||
char device_name[40];
|
||||
if (hctr->sync != external)
|
||||
{
|
||||
hctr->sync = external;
|
||||
/*********************************************/
|
||||
// DAQmx Stop Code
|
||||
/*********************************************/
|
||||
DAQmxStopTask(hctr->taskHandle);
|
||||
DAQmxClearTask(hctr->taskHandle);
|
||||
/*********************************************/
|
||||
// Create a DAQmx task to hold the counter
|
||||
/*********************************************/
|
||||
DAQmxErrChk (DAQmxCreateTask("",&hctr->taskHandle));
|
||||
|
||||
/*********************************************/
|
||||
// Create a DAQmx counter within the task
|
||||
/*********************************************/
|
||||
hctr->count32 = 0;
|
||||
snprintf(device_name, sizeof(device_name), "dev%d/ctr%d",
|
||||
hctr->device_number, hctr->counter_number);
|
||||
DAQmxErrChk (
|
||||
DAQmxCreateCICountEdgesChan(hctr->taskHandle,
|
||||
device_name,
|
||||
"",
|
||||
DAQmx_Val_Rising,
|
||||
hctr->count32,
|
||||
DAQmx_Val_CountUp));
|
||||
|
||||
if (external)
|
||||
{
|
||||
char str[40];
|
||||
snprintf(str, sizeof(str), "dev%d/PFI%d",
|
||||
hctr->device_number, hctr->sync_line_number);
|
||||
DAQmxErrChk (
|
||||
DAQmxCfgSampClkTiming(hctr->taskHandle,
|
||||
str,
|
||||
10000,
|
||||
DAQmx_Val_Rising,
|
||||
DAQmx_Val_ContSamps,
|
||||
10000));
|
||||
}
|
||||
/*********************************************/
|
||||
// Start the DAQmx task
|
||||
/*********************************************/
|
||||
DAQmxErrChk (DAQmxStartTask(hctr->taskHandle));
|
||||
|
||||
}
|
||||
Error:
|
||||
return;
|
||||
}
|
||||
|
||||
int hctr_dtor(pHCTR* hctr)
|
||||
{
|
||||
if( hctr && *hctr && (*hctr)->taskHandle!=0 )
|
||||
@@ -84,6 +281,15 @@ int hctr_dtor(pHCTR* hctr)
|
||||
DAQmxClearTask((*hctr)->taskHandle);
|
||||
}
|
||||
(*hctr)->taskHandle = 0;
|
||||
if( hctr && *hctr && (*hctr)->taskHandle_dout!=0 )
|
||||
{
|
||||
/*********************************************/
|
||||
// DAQmx Stop Code
|
||||
/*********************************************/
|
||||
DAQmxStopTask((*hctr)->taskHandle_dout);
|
||||
DAQmxClearTask((*hctr)->taskHandle_dout);
|
||||
}
|
||||
(*hctr)->taskHandle_dout = 0;
|
||||
free (*hctr);
|
||||
*hctr = NULL;
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user