renamed from hctr.[hc] to be consistent with digital input driver
r1202 | dcl | 2006-10-30 12:21:49 +1100 (Mon, 30 Oct 2006) | 2 lines
This commit is contained in:
838
site_ansto/hardsup/Monitor/hware.c
Normal file
838
site_ansto/hardsup/Monitor/hware.c
Normal file
@@ -0,0 +1,838 @@
|
||||
/* vim: ts=8 sts=2 sw=2 cindent
|
||||
*/
|
||||
#include "hware.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define DEFAULT_DEVICE "dev1/ctr0"
|
||||
|
||||
#ifdef REGISTER_LEVEL_PROGRAMMING
|
||||
#define DEVICE_ID_NUMBER "0x1310"
|
||||
#define DAQmxFailed(e) ((e) != 0)
|
||||
#define DAQmxGetExtendedErrorInfo(b, l) snprintf(b, l, "BAD")
|
||||
#include <osiBus.h>
|
||||
#include <tTIO.h>
|
||||
typedef unsigned long uInt32;
|
||||
/**
|
||||
* This structure contains the data for the PCI-6602 card
|
||||
*/
|
||||
typedef struct card_t
|
||||
{
|
||||
iBus* bus;
|
||||
tAddressSpace Bar1;
|
||||
tAddressSpace Bar2;
|
||||
tTIO *tio_1;
|
||||
tTIO *tio_2;
|
||||
unsigned char dio_mask;
|
||||
unsigned char dev_mask;
|
||||
} CARD;
|
||||
#else
|
||||
#include <NIDAQmx.h>
|
||||
|
||||
#define DAQmxErrChk(functionCall) \
|
||||
do { if( DAQmxFailed(error=(functionCall)) ) \
|
||||
goto Error; } while(0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This structure encapsulates the data that is private to
|
||||
* the implementation of the device
|
||||
*/
|
||||
typedef struct device_private_t
|
||||
{
|
||||
/** extended 64-bit counter value */
|
||||
unsigned long long count64;
|
||||
/** NIDAQ device number of card */
|
||||
int card_number;
|
||||
/** NI channel number on card */
|
||||
int channel_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;
|
||||
/** Actual physical counter value, as returned by read function */
|
||||
uInt32 count32;
|
||||
#ifdef REGISTER_LEVEL_PROGRAMMING
|
||||
CARD* card;
|
||||
#else
|
||||
/** NIDAQ opaque task handle */
|
||||
TaskHandle taskHandle;
|
||||
/** NIDAQ opaque task handle for digital output */
|
||||
TaskHandle taskHandle_dout;
|
||||
#endif
|
||||
} DEVICE_PRIVATE;
|
||||
|
||||
typedef struct mapping_t {
|
||||
int cntr_num;
|
||||
int sync_num;
|
||||
int outp_num;
|
||||
} MAPPING;
|
||||
|
||||
static 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 }
|
||||
};
|
||||
|
||||
#ifdef REGISTER_LEVEL_PROGRAMMING
|
||||
static void initMite(iBus *bus);
|
||||
|
||||
static CARD* card[10];
|
||||
#else
|
||||
static int make_dout_task(pHWARE ptr);
|
||||
#endif
|
||||
|
||||
int hware_ctor(const char* device_name, pHWARE* ptr)
|
||||
{
|
||||
pHWARE hware = NULL;
|
||||
#ifdef REGISTER_LEVEL_PROGRAMMING
|
||||
CARD* pci = NULL;
|
||||
#endif
|
||||
int error = 0;
|
||||
bool flag = false;
|
||||
char text_string[] = DEFAULT_DEVICE;
|
||||
const char *name;
|
||||
const char *text;
|
||||
|
||||
hware = (DEVICE_PRIVATE*) malloc(sizeof(DEVICE_PRIVATE));
|
||||
*ptr = hware;
|
||||
memset(hware, 0, sizeof(DEVICE_PRIVATE));
|
||||
|
||||
name = device_name;
|
||||
text = text_string;
|
||||
while (name && *name)
|
||||
{
|
||||
if (isspace(*name))
|
||||
++name;
|
||||
else if (*name >= '0' && *name <= '7')
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
hware->channel_number = *name - '0';
|
||||
hware->sync_line_number = mapping[hware->channel_number].sync_num;
|
||||
hware->output_line_number = mapping[hware->channel_number].outp_num;
|
||||
}
|
||||
else
|
||||
{
|
||||
hware->card_number = *name - '0';
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
else if (tolower(*name) != *text)
|
||||
{
|
||||
/* TODO error */
|
||||
printf("Device name error: %s (%d,%d)\n",
|
||||
device_name,
|
||||
hware->channel_number,
|
||||
hware->card_number);
|
||||
break;
|
||||
}
|
||||
++name;
|
||||
++text;
|
||||
}
|
||||
|
||||
#ifdef REGISTER_LEVEL_PROGRAMMING
|
||||
if (card[hware->card_number] == NULL)
|
||||
{
|
||||
char local_name[40] = "PXI6::1::INSTR";
|
||||
FILE* fd = fopen("/proc/nirlpk/lsdaq", "r");
|
||||
if (fd)
|
||||
{
|
||||
bool found = false;
|
||||
int count = 0;
|
||||
char line[100];
|
||||
while (fgets(line, 100, fd))
|
||||
{
|
||||
if (strstr(line, DEVICE_ID_NUMBER))
|
||||
{
|
||||
++count;
|
||||
name = strstr(line, "PXI");
|
||||
if (name && count == hware->card_number)
|
||||
{
|
||||
found = true;
|
||||
strcpy(local_name, name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
// TODO error
|
||||
}
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
card[hware->card_number] = (CARD*) malloc(sizeof(CARD));
|
||||
memset(card[hware->card_number], 0, sizeof(CARD));
|
||||
pci = card[hware->card_number];
|
||||
hware->card = pci;
|
||||
|
||||
pci->bus = acquireBoard((tChar*) local_name /* "PXI6::1::INSTR" */);
|
||||
|
||||
if(pci->bus == NULL)
|
||||
{
|
||||
printf("Error accessing the PCI device \"%s\". Exiting.\n",
|
||||
local_name);
|
||||
error = 1;
|
||||
goto Error;
|
||||
}
|
||||
|
||||
//Intitialise Mite Chip.
|
||||
|
||||
initMite(pci->bus);
|
||||
|
||||
pci->Bar1 = pci->bus->createAddressSpace(kPCI_BAR1);
|
||||
pci->Bar2 = pci->bus->createAddressSpace(kPCI_BAR1);
|
||||
pci->tio_1 = new tTIO(pci->Bar1);
|
||||
pci->tio_2 = new tTIO(pci->Bar2);
|
||||
pci->tio_2->setAddressOffset(0x800);
|
||||
//
|
||||
//Set all counter outputs to 'input' so we don't accidentally double drive an IO pin
|
||||
pci->tio_1->IO_Pin_8_9_Configuration_Register.writeIO_Pin_8_Select(0); //0='input'
|
||||
pci->tio_1->IO_Pin_12_13_Configuration_Register.writeIO_Pin_12_Select(0); //0='input'
|
||||
pci->tio_1->IO_Pin_16_17_Configuration_Register.writeIO_Pin_16_Select(0); //0='input'
|
||||
pci->tio_1->IO_Pin_20_21_Configuration_Register.writeIO_Pin_20_Select(0); //0='input'
|
||||
pci->tio_1->IO_Pin_24_25_Configuration_Register.writeIO_Pin_24_Select(0); //0='input'
|
||||
pci->tio_1->IO_Pin_28_29_Configuration_Register.writeIO_Pin_28_Select(0); //0='input'
|
||||
pci->tio_1->IO_Pin_32_33_Configuration_Register.writeIO_Pin_32_Select(0); //0='input'
|
||||
pci->tio_1->IO_Pin_36_37_Configuration_Register.writeIO_Pin_36_Select(0); //0='input'
|
||||
|
||||
pci->tio_2->IO_Pin_8_9_Configuration_Register.writeIO_Pin_8_Select(0); //0='input'
|
||||
pci->tio_2->IO_Pin_12_13_Configuration_Register.writeIO_Pin_12_Select(0); //0='input'
|
||||
pci->tio_2->IO_Pin_16_17_Configuration_Register.writeIO_Pin_16_Select(0); //0='input'
|
||||
pci->tio_2->IO_Pin_20_21_Configuration_Register.writeIO_Pin_20_Select(0); //0='input'
|
||||
pci->tio_2->IO_Pin_24_25_Configuration_Register.writeIO_Pin_24_Select(0); //0='input'
|
||||
pci->tio_2->IO_Pin_28_29_Configuration_Register.writeIO_Pin_28_Select(0); //0='input'
|
||||
pci->tio_2->IO_Pin_32_33_Configuration_Register.writeIO_Pin_32_Select(0); //0='input'
|
||||
pci->tio_2->IO_Pin_36_37_Configuration_Register.writeIO_Pin_36_Select(0); //0='input'
|
||||
|
||||
//Bind the first TIO to counters 0-3 on the IO connector, and
|
||||
//bind the second TIO to counters 4-7
|
||||
pci->tio_1->Clock_Configuration_Register.writeCntr_Swap(0);
|
||||
pci->tio_2->Clock_Configuration_Register.writeCntr_Swap(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
pci = card[hware->card_number];
|
||||
hware->card = pci;
|
||||
}
|
||||
|
||||
// Mark the counter on this card as in-use
|
||||
if (pci->dev_mask & (1 << hware->channel_number))
|
||||
{
|
||||
// TODO error
|
||||
}
|
||||
pci->dev_mask |= 1 << hware->channel_number;
|
||||
|
||||
/*
|
||||
* Set up the counter object
|
||||
*/
|
||||
switch (hware->channel_number)
|
||||
{
|
||||
case 0:
|
||||
//Disarm
|
||||
pci->tio_1->G0_Command_Register.writeG0_Disarm(1);
|
||||
//load initial value of zero
|
||||
pci->tio_1->G0_Load_A_Registers.writeG0_Load_A(0x00000000);
|
||||
pci->tio_1->G0_Command_Register.writeG0_Load(1);
|
||||
//set source to external default source pin
|
||||
pci->tio_1->G0_Input_Select_Register.writeG0_Source_Select(1);
|
||||
//set gate to no gate
|
||||
pci->tio_1->G0_Input_Select_Register.writeG0_Gate_Select(30);
|
||||
pci->tio_1->G0_Mode_Register.writeG0_Gate_Polarity(1);
|
||||
pci->tio_1->G0_Mode_Register.writeG0_Trigger_Mode_For_Edge_Gate(3);
|
||||
//set counting direction to up
|
||||
pci->tio_1->G0_Command_Register.writeG0_Up_Down(1);
|
||||
//arm counter
|
||||
pci->tio_1->G0_Command_Register.writeG0_Arm(1);
|
||||
break;
|
||||
case 1:
|
||||
//Disarm
|
||||
pci->tio_1->G1_Command_Register.writeG1_Disarm(1);
|
||||
//load initial value of zero
|
||||
pci->tio_1->G1_Load_A_Registers.writeG1_Load_A(0x00000000);
|
||||
pci->tio_1->G1_Command_Register.writeG1_Load(1);
|
||||
//set source to external default source pin
|
||||
pci->tio_1->G1_Input_Select_Register.writeG1_Source_Select(1);
|
||||
//set gate to no gate
|
||||
pci->tio_1->G1_Input_Select_Register.writeG1_Gate_Select(30);
|
||||
pci->tio_1->G1_Mode_Register.writeG1_Gate_Polarity(1);
|
||||
pci->tio_1->G1_Mode_Register.writeG1_Trigger_Mode_For_Edge_Gate(3);
|
||||
//set counting direction to up
|
||||
pci->tio_1->G1_Command_Register.writeG1_Up_Down(1);
|
||||
//arm counter
|
||||
pci->tio_1->G1_Command_Register.writeG1_Arm(1);
|
||||
break;
|
||||
case 2:
|
||||
//Disarm
|
||||
pci->tio_1->G2_Command_Register.writeG2_Disarm(1);
|
||||
//load initial value of zero
|
||||
pci->tio_1->G2_Load_A_Registers.writeG2_Load_A(0x00000000);
|
||||
pci->tio_1->G2_Command_Register.writeG2_Load(1);
|
||||
//set source to external default source pin
|
||||
pci->tio_1->G2_Input_Select_Register.writeG2_Source_Select(1);
|
||||
//set gate to no gate
|
||||
pci->tio_1->G2_Input_Select_Register.writeG2_Gate_Select(30);
|
||||
pci->tio_1->G2_Mode_Register.writeG2_Gate_Polarity(1);
|
||||
pci->tio_1->G2_Mode_Register.writeG2_Trigger_Mode_For_Edge_Gate(3);
|
||||
//set counting direction to up
|
||||
pci->tio_1->G2_Command_Register.writeG2_Up_Down(1);
|
||||
//arm counter
|
||||
pci->tio_1->G2_Command_Register.writeG2_Arm(1);
|
||||
break;
|
||||
case 3:
|
||||
//Disarm
|
||||
pci->tio_1->G3_Command_Register.writeG3_Disarm(1);
|
||||
//load initial value of zero
|
||||
pci->tio_1->G3_Load_A_Registers.writeG3_Load_A(0x00000000);
|
||||
pci->tio_1->G3_Command_Register.writeG3_Load(1);
|
||||
//set source to external default source pin
|
||||
pci->tio_1->G3_Input_Select_Register.writeG3_Source_Select(1);
|
||||
//set gate to no gate
|
||||
pci->tio_1->G3_Input_Select_Register.writeG3_Gate_Select(30);
|
||||
pci->tio_1->G3_Mode_Register.writeG3_Gate_Polarity(1);
|
||||
pci->tio_1->G3_Mode_Register.writeG3_Trigger_Mode_For_Edge_Gate(3);
|
||||
//set counting direction to up
|
||||
pci->tio_1->G3_Command_Register.writeG3_Up_Down(1);
|
||||
//arm counter
|
||||
pci->tio_1->G3_Command_Register.writeG3_Arm(1);
|
||||
break;
|
||||
case 4:
|
||||
//Disarm
|
||||
pci->tio_2->G0_Command_Register.writeG0_Disarm(1);
|
||||
//load initial value of zero
|
||||
pci->tio_2->G0_Load_A_Registers.writeG0_Load_A(0x00000000);
|
||||
pci->tio_2->G0_Command_Register.writeG0_Load(1);
|
||||
//set source to external default source pin
|
||||
pci->tio_2->G0_Input_Select_Register.writeG0_Source_Select(1);
|
||||
//set gate to no gate
|
||||
pci->tio_2->G0_Input_Select_Register.writeG0_Gate_Select(30);
|
||||
pci->tio_2->G0_Mode_Register.writeG0_Gate_Polarity(1);
|
||||
pci->tio_2->G0_Mode_Register.writeG0_Trigger_Mode_For_Edge_Gate(3);
|
||||
//set counting direction to up
|
||||
pci->tio_2->G0_Command_Register.writeG0_Up_Down(1);
|
||||
//arm counter
|
||||
pci->tio_2->G0_Command_Register.writeG0_Arm(1);
|
||||
break;
|
||||
case 5:
|
||||
//Disarm
|
||||
pci->tio_2->G1_Command_Register.writeG1_Disarm(1);
|
||||
//load initial value of zero
|
||||
pci->tio_2->G1_Load_A_Registers.writeG1_Load_A(0x00000000);
|
||||
pci->tio_2->G1_Command_Register.writeG1_Load(1);
|
||||
//set source to external default source pin
|
||||
pci->tio_2->G1_Input_Select_Register.writeG1_Source_Select(1);
|
||||
//set gate to no gate
|
||||
pci->tio_2->G1_Input_Select_Register.writeG1_Gate_Select(30);
|
||||
pci->tio_2->G1_Mode_Register.writeG1_Gate_Polarity(1);
|
||||
pci->tio_2->G1_Mode_Register.writeG1_Trigger_Mode_For_Edge_Gate(3);
|
||||
//set counting direction to up
|
||||
pci->tio_2->G1_Command_Register.writeG1_Up_Down(1);
|
||||
//arm counter
|
||||
pci->tio_2->G1_Command_Register.writeG1_Arm(1);
|
||||
break;
|
||||
case 6:
|
||||
//Disarm
|
||||
pci->tio_2->G2_Command_Register.writeG2_Disarm(1);
|
||||
//load initial value of zero
|
||||
pci->tio_2->G2_Load_A_Registers.writeG2_Load_A(0x00000000);
|
||||
pci->tio_2->G2_Command_Register.writeG2_Load(1);
|
||||
//set source to external default source pin
|
||||
pci->tio_2->G2_Input_Select_Register.writeG2_Source_Select(1);
|
||||
//set gate to no gate
|
||||
pci->tio_2->G2_Input_Select_Register.writeG2_Gate_Select(30);
|
||||
pci->tio_2->G2_Mode_Register.writeG2_Gate_Polarity(1);
|
||||
pci->tio_2->G2_Mode_Register.writeG2_Trigger_Mode_For_Edge_Gate(3);
|
||||
//set counting direction to up
|
||||
pci->tio_2->G2_Command_Register.writeG2_Up_Down(1);
|
||||
//arm counter
|
||||
pci->tio_2->G2_Command_Register.writeG2_Arm(1);
|
||||
break;
|
||||
case 7:
|
||||
//Disarm
|
||||
pci->tio_2->G3_Command_Register.writeG3_Disarm(1);
|
||||
//load initial value of zero
|
||||
pci->tio_2->G3_Load_A_Registers.writeG3_Load_A(0x00000000);
|
||||
pci->tio_2->G3_Command_Register.writeG3_Load(1);
|
||||
//set source to external default source pin
|
||||
pci->tio_2->G3_Input_Select_Register.writeG3_Source_Select(1);
|
||||
//set gate to no gate
|
||||
pci->tio_2->G3_Input_Select_Register.writeG3_Gate_Select(30);
|
||||
pci->tio_2->G3_Mode_Register.writeG3_Gate_Polarity(1);
|
||||
pci->tio_2->G3_Mode_Register.writeG3_Trigger_Mode_For_Edge_Gate(3);
|
||||
//set counting direction to up
|
||||
pci->tio_2->G3_Command_Register.writeG3_Up_Down(1);
|
||||
//arm counter
|
||||
pci->tio_2->G3_Command_Register.writeG3_Arm(1);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
/*********************************************/
|
||||
// Create a DAQmx task
|
||||
/*********************************************/
|
||||
DAQmxErrChk (DAQmxCreateTask("",&hware->taskHandle));
|
||||
|
||||
/*********************************************/
|
||||
// Create a DAQmx device within the task
|
||||
/*********************************************/
|
||||
DAQmxErrChk (
|
||||
DAQmxCreateCICountEdgesChan(hware->taskHandle,
|
||||
device_name,
|
||||
"",
|
||||
DAQmx_Val_Rising,
|
||||
hware->count32,
|
||||
DAQmx_Val_CountUp));
|
||||
|
||||
/*********************************************/
|
||||
// Start the DAQmx task
|
||||
/*********************************************/
|
||||
DAQmxErrChk (DAQmxStartTask(hware->taskHandle));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
Error:
|
||||
free(hware);
|
||||
*ptr = NULL;
|
||||
return error;
|
||||
}
|
||||
|
||||
int hware_read(pHWARE hware, unsigned long long* value)
|
||||
{
|
||||
int error = 0;
|
||||
uInt32 counterValue1;
|
||||
*value = hware->count64;
|
||||
#ifdef REGISTER_LEVEL_PROGRAMMING
|
||||
uInt32 counterValue2;
|
||||
CARD* pci = hware->card;
|
||||
|
||||
//read counter value
|
||||
//Use this method to read the value of an armed counter
|
||||
//during non-buffered counting. Since the value of the counter may
|
||||
//change during the read, we make sure that the value is stable.
|
||||
switch (hware->channel_number)
|
||||
{
|
||||
case 0:
|
||||
counterValue1 = pci->tio_1->G0_Save_Registers.readRegister();
|
||||
counterValue2 = pci->tio_1->G0_Save_Registers.readRegister();
|
||||
if (counterValue1 != counterValue2)
|
||||
counterValue1 = pci->tio_1->G0_Save_Registers.readRegister();
|
||||
break;
|
||||
case 1:
|
||||
counterValue1 = pci->tio_1->G1_Save_Registers.readRegister();
|
||||
counterValue2 = pci->tio_1->G1_Save_Registers.readRegister();
|
||||
if (counterValue1 != counterValue2)
|
||||
counterValue1 = pci->tio_1->G1_Save_Registers.readRegister();
|
||||
break;
|
||||
case 2:
|
||||
counterValue1 = pci->tio_1->G2_Save_Registers.readRegister();
|
||||
counterValue2 = pci->tio_1->G2_Save_Registers.readRegister();
|
||||
if (counterValue1 != counterValue2)
|
||||
counterValue1 = pci->tio_1->G2_Save_Registers.readRegister();
|
||||
break;
|
||||
case 3:
|
||||
counterValue1 = pci->tio_1->G3_Save_Registers.readRegister();
|
||||
counterValue2 = pci->tio_1->G3_Save_Registers.readRegister();
|
||||
if (counterValue1 != counterValue2)
|
||||
counterValue1 = pci->tio_1->G3_Save_Registers.readRegister();
|
||||
break;
|
||||
case 4:
|
||||
counterValue1 = pci->tio_2->G0_Save_Registers.readRegister();
|
||||
counterValue2 = pci->tio_2->G0_Save_Registers.readRegister();
|
||||
if (counterValue1 != counterValue2)
|
||||
counterValue1 = pci->tio_2->G0_Save_Registers.readRegister();
|
||||
break;
|
||||
case 5:
|
||||
counterValue1 = pci->tio_2->G1_Save_Registers.readRegister();
|
||||
counterValue2 = pci->tio_2->G1_Save_Registers.readRegister();
|
||||
if (counterValue1 != counterValue2)
|
||||
counterValue1 = pci->tio_2->G1_Save_Registers.readRegister();
|
||||
break;
|
||||
case 6:
|
||||
counterValue1 = pci->tio_2->G2_Save_Registers.readRegister();
|
||||
counterValue2 = pci->tio_2->G2_Save_Registers.readRegister();
|
||||
if (counterValue1 != counterValue2)
|
||||
counterValue1 = pci->tio_2->G2_Save_Registers.readRegister();
|
||||
break;
|
||||
case 7:
|
||||
counterValue1 = pci->tio_2->G3_Save_Registers.readRegister();
|
||||
counterValue2 = pci->tio_2->G3_Save_Registers.readRegister();
|
||||
if (counterValue1 != counterValue2)
|
||||
counterValue1 = pci->tio_2->G3_Save_Registers.readRegister();
|
||||
break;
|
||||
}
|
||||
hware->count64 += counterValue1 - hware->count32;
|
||||
hware->count32 = counterValue1;
|
||||
*value = hware->count64;
|
||||
#else
|
||||
/*********************************************/
|
||||
// DAQmx Read Code
|
||||
/*********************************************/
|
||||
DAQmxErrChk (DAQmxReadCounterScalarU32(hware->taskHandle,
|
||||
1.0,
|
||||
&counterValue1,
|
||||
NULL));
|
||||
hware->count64 += counterValue1 - hware->count32;
|
||||
hware->count32 = counterValue1;
|
||||
*value = hware->count64;
|
||||
Error:
|
||||
#endif
|
||||
return error;
|
||||
} /* hware_read */
|
||||
|
||||
/*
|
||||
* Select the source
|
||||
*/
|
||||
int hware_source(pHWARE hware, int value)
|
||||
{
|
||||
int error = 0;
|
||||
#ifdef REGISTER_LEVEL_PROGRAMMING
|
||||
CARD* pci = hware->card;
|
||||
int src = 1;
|
||||
if (value == 3)
|
||||
//set source to internal time base 3, the 80Mhz internal clock
|
||||
src = 30;
|
||||
else if (value == 2)
|
||||
//set source to internal time base 2, the l00Khz internal clock
|
||||
src = 18;
|
||||
else if (value == 1)
|
||||
//set source to internal time base 1, the 20Mhz internal clock
|
||||
src = 0;
|
||||
else
|
||||
//set source to external default source pin
|
||||
src = 1;
|
||||
switch (hware->channel_number)
|
||||
{
|
||||
case 0:
|
||||
pci->tio_1->G0_Input_Select_Register.writeG0_Source_Select(src);
|
||||
break;
|
||||
case 1:
|
||||
pci->tio_1->G1_Input_Select_Register.writeG1_Source_Select(src);
|
||||
break;
|
||||
case 2:
|
||||
pci->tio_1->G2_Input_Select_Register.writeG2_Source_Select(src);
|
||||
break;
|
||||
case 3:
|
||||
pci->tio_1->G3_Input_Select_Register.writeG3_Source_Select(src);
|
||||
break;
|
||||
case 4:
|
||||
pci->tio_2->G0_Input_Select_Register.writeG0_Source_Select(src);
|
||||
break;
|
||||
case 5:
|
||||
pci->tio_2->G1_Input_Select_Register.writeG1_Source_Select(src);
|
||||
break;
|
||||
case 6:
|
||||
pci->tio_2->G2_Input_Select_Register.writeG2_Source_Select(src);
|
||||
break;
|
||||
case 7:
|
||||
pci->tio_2->G3_Input_Select_Register.writeG3_Source_Select(src);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
// TODO
|
||||
// DAQmxGetDevCIPhysicalChans
|
||||
// DAQmxSetCICountEdgesTerm
|
||||
//Error:
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the output line corresponding to the counter
|
||||
*/
|
||||
int hware_outp(pHWARE hware, int value)
|
||||
{
|
||||
int error = 0;
|
||||
#ifdef REGISTER_LEVEL_PROGRAMMING
|
||||
CARD* pci = hware->card;
|
||||
u16 data;
|
||||
if (value < 0)
|
||||
{
|
||||
// set the disabled line to input
|
||||
value = 0;
|
||||
pci->dio_mask &= ~(1 << hware->channel_number);
|
||||
pci->tio_1->DIO_Control_Register.writeDIO_Pins_Dir(pci->dio_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
pci->dio_mask |= 1 << hware->channel_number;
|
||||
pci->tio_1->DIO_Control_Register.writeDIO_Pins_Dir(pci->dio_mask);
|
||||
data = pci->tio_1->DIO_Output_Register.readDIO_Parallel_Data_Out();
|
||||
printf("data %04x", data);
|
||||
if (value > 0)
|
||||
data |= 1 << hware->channel_number;
|
||||
else
|
||||
data &= ~(1 << hware->channel_number);
|
||||
pci->tio_1->DIO_Output_Register.writeDIO_Parallel_Data_Out(data);
|
||||
printf(" => %04x", data);
|
||||
data = pci->tio_1->DIO_Output_Register.readDIO_Parallel_Data_Out();
|
||||
printf(" => %04x\n", data);
|
||||
}
|
||||
#else
|
||||
uInt8 data;
|
||||
if (value < 0)
|
||||
{
|
||||
// set the disabled line to logic low
|
||||
if (hware->taskHandle_dout != 0) {
|
||||
data = 0;
|
||||
DAQmxWriteDigitalLines(hware->taskHandle_dout,
|
||||
1,
|
||||
1,
|
||||
10.0,
|
||||
DAQmx_Val_GroupByChannel,
|
||||
&data,
|
||||
NULL,
|
||||
NULL);
|
||||
/*********************************************/
|
||||
// DAQmx Stop Code
|
||||
/*********************************************/
|
||||
DAQmxStopTask(hware->taskHandle_dout);
|
||||
DAQmxClearTask(hware->taskHandle_dout);
|
||||
hware->taskHandle_dout = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hware->taskHandle_dout == 0)
|
||||
DAQmxErrChk (make_dout_task(hware));
|
||||
if (value > 0)
|
||||
data = 1;
|
||||
else
|
||||
data = 0;
|
||||
DAQmxErrChk (
|
||||
DAQmxWriteDigitalScalarU32(hware->taskHandle_dout,
|
||||
1,
|
||||
10.0,
|
||||
data,
|
||||
NULL));
|
||||
}
|
||||
Error:
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up to read the counter synchronized to an external signal
|
||||
*/
|
||||
void hware_sync(pHWARE hware, bool external)
|
||||
{
|
||||
#if REGISTER_LEVEL_PROGRAMMING
|
||||
//CARD* pci = hware->card;
|
||||
// TODO
|
||||
#else
|
||||
int error = 0;
|
||||
char device_name[40];
|
||||
if (hware->sync != external)
|
||||
{
|
||||
hware->sync = external;
|
||||
/*********************************************/
|
||||
// DAQmx Stop Code
|
||||
/*********************************************/
|
||||
DAQmxStopTask(hware->taskHandle);
|
||||
DAQmxClearTask(hware->taskHandle);
|
||||
/*********************************************/
|
||||
// Create a DAQmx task to hold the counter
|
||||
/*********************************************/
|
||||
DAQmxErrChk (DAQmxCreateTask("",&hware->taskHandle));
|
||||
|
||||
/*********************************************/
|
||||
// Create a DAQmx counter within the task
|
||||
/*********************************************/
|
||||
hware->count32 = 0;
|
||||
snprintf(device_name, sizeof(device_name), "dev%d/ctr%d",
|
||||
hware->card_number, hware->channel_number);
|
||||
DAQmxErrChk (
|
||||
DAQmxCreateCICountEdgesChan(hware->taskHandle,
|
||||
device_name,
|
||||
"",
|
||||
DAQmx_Val_Rising,
|
||||
hware->count32,
|
||||
DAQmx_Val_CountUp));
|
||||
|
||||
if (external)
|
||||
{
|
||||
char str[40];
|
||||
snprintf(str, sizeof(str), "dev%d/PFI%d",
|
||||
hware->card_number, hware->sync_line_number);
|
||||
DAQmxErrChk (
|
||||
DAQmxCfgSampClkTiming(hware->taskHandle,
|
||||
str,
|
||||
10000,
|
||||
DAQmx_Val_Rising,
|
||||
DAQmx_Val_ContSamps,
|
||||
10000));
|
||||
}
|
||||
/*********************************************/
|
||||
// Start the DAQmx task
|
||||
/*********************************************/
|
||||
DAQmxErrChk (DAQmxStartTask(hware->taskHandle));
|
||||
|
||||
}
|
||||
Error:
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Shut down the channel
|
||||
*/
|
||||
int hware_dtor(pHWARE* ptr)
|
||||
{
|
||||
if (ptr && *ptr)
|
||||
{
|
||||
pHWARE hware = *ptr;
|
||||
#ifdef REGISTER_LEVEL_PROGRAMMING
|
||||
CARD* pci = hware->card;
|
||||
switch (hware->channel_number)
|
||||
{
|
||||
case 0:
|
||||
pci->tio_1->G0_Command_Register.writeG0_Disarm(1);
|
||||
break;
|
||||
case 1:
|
||||
pci->tio_1->G1_Command_Register.writeG1_Disarm(1);
|
||||
break;
|
||||
case 2:
|
||||
pci->tio_1->G2_Command_Register.writeG2_Disarm(1);
|
||||
break;
|
||||
case 3:
|
||||
pci->tio_1->G3_Command_Register.writeG3_Disarm(1);
|
||||
break;
|
||||
case 4:
|
||||
pci->tio_2->G0_Command_Register.writeG0_Disarm(1);
|
||||
break;
|
||||
case 5:
|
||||
pci->tio_2->G1_Command_Register.writeG1_Disarm(1);
|
||||
break;
|
||||
case 6:
|
||||
pci->tio_2->G2_Command_Register.writeG2_Disarm(1);
|
||||
break;
|
||||
case 7:
|
||||
pci->tio_2->G3_Command_Register.writeG3_Disarm(1);
|
||||
break;
|
||||
}
|
||||
|
||||
pci->dev_mask &= ~(1 << hware->channel_number);
|
||||
if (pci->dev_mask == 0)
|
||||
{
|
||||
delete pci->tio_1;
|
||||
delete pci->tio_2;
|
||||
pci->bus->destroyAddressSpace(pci->Bar1);
|
||||
pci->bus->destroyAddressSpace(pci->Bar2);
|
||||
|
||||
releaseBoard(pci->bus);
|
||||
card[hware->card_number] = NULL;
|
||||
free(pci);
|
||||
}
|
||||
#else
|
||||
if (hware->taskHandle != 0)
|
||||
{
|
||||
/*********************************************/
|
||||
// DAQmx Stop Code
|
||||
/*********************************************/
|
||||
DAQmxStopTask(hware->taskHandle);
|
||||
DAQmxClearTask(hware->taskHandle);
|
||||
hware->taskHandle = 0;
|
||||
}
|
||||
if (hware->taskHandle_dout!=0)
|
||||
{
|
||||
/*********************************************/
|
||||
// DAQmx Stop Code
|
||||
/*********************************************/
|
||||
DAQmxStopTask(hware->taskHandle_dout);
|
||||
DAQmxClearTask(hware->taskHandle_dout);
|
||||
hware->taskHandle_dout = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* release the storage */
|
||||
free(hware);
|
||||
*ptr = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool hware_failed(int error)
|
||||
{
|
||||
if (DAQmxFailed(error))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void hware_errmsg(char* buff, int len)
|
||||
{
|
||||
*buff = '\0';
|
||||
DAQmxGetExtendedErrorInfo(buff, len);
|
||||
}
|
||||
|
||||
#ifdef REGISTER_LEVEL_PROGRAMMING
|
||||
//
|
||||
//Tell the MITE to link the BAR1 address to the DAQ Board
|
||||
//You must initialize the MITE before you write to the rest of the PCI board
|
||||
void initMite(iBus *bus)
|
||||
{
|
||||
tAddressSpace Bar0;
|
||||
u32 physicalBar1;
|
||||
|
||||
//Skip MITE initialization for PCMCIA boards
|
||||
//(which do not have a MITE DMA controller)
|
||||
if(!bus->get(kIsPciPxiBus,0)) return;
|
||||
|
||||
Bar0 = bus->createAddressSpace(kPCI_BAR0);
|
||||
|
||||
//Get the physical address of the DAQ board
|
||||
physicalBar1 = bus->get(kBusAddressPhysical,kPCI_BAR1);
|
||||
|
||||
// ***** 6602/6608 specific MITE initialization *****
|
||||
// Hit the IO Window Base/Size Register 1 (IOWBSR1) in the MITE. We set the
|
||||
// address, enable the window and set the size of the window:
|
||||
Bar0.write32(0xC4, (physicalBar1 & 0xffffff00L) | 0x8C);
|
||||
|
||||
// Write to the IO Window Control Register 1 (IOWCR1) to make the IO window
|
||||
// go to RAM memory space instead of the config space
|
||||
Bar0.write32(0xF4, 0);
|
||||
|
||||
// ***** End of 6602/6608 specific code *****
|
||||
|
||||
bus->destroyAddressSpace(Bar0);
|
||||
}
|
||||
#else
|
||||
int make_dout_task(pHWARE 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->card_number, ptr->channel_number);
|
||||
DAQmxErrChk (DAQmxCreateDOChan(ptr->taskHandle_dout,
|
||||
port_range,
|
||||
"",
|
||||
DAQmx_Val_ChanPerLine));
|
||||
|
||||
/*********************************************/
|
||||
// Start the DAQmx task
|
||||
/*********************************************/
|
||||
DAQmxErrChk (DAQmxStartTask(ptr->taskHandle_dout));
|
||||
return error;
|
||||
|
||||
Error:
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user