Files
sics/site_ansto/hardsup/Monitor/hware.c
Douglas Clowes c59a3979be Implement simulated counter hardware and more string literal changes
r3637 | dcl | 2012-07-11 15:08:50 +1000 (Wed, 11 Jul 2012) | 1 line
2012-11-15 17:32:39 +11:00

1000 lines
28 KiB
C

/* vim: ts=8 sts=2 sw=2 cindent
*/
#include "hware.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#ifndef SIMULATE_HARDWARE
#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;
#ifdef REGISTER_LEVEL_PROGRAMMING
static bool initPCI(pHWARE ptr, const char *name);
static void initCard(pHWARE ptr);
static void initChan(pHWARE ptr);
static CARD* card[10];
#else
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 }
};
#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 <= '9')
{
if (flag)
{
hware->channel_number = *name - '0';
}
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;
if(!initPCI(hware, local_name))
{
printf("Error accessing the PCI device \"%s\". Exiting.\n",
local_name);
error = 1;
goto Error;
}
initCard(hware);
}
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;
initChan(hware);
#else
do {
char local_name[40];
hware->sync_line_number = mapping[hware->channel_number].sync_num;
hware->output_line_number = mapping[hware->channel_number].outp_num;
/*********************************************/
// Create a DAQmx task
/*********************************************/
DAQmxErrChk (DAQmxCreateTask("",&hware->taskHandle));
DAQmxErrChk (DAQmxCreateTask("",&hware->taskHandle_dout));
/*********************************************/
// Create a DAQmx device within the task
/*********************************************/
DAQmxErrChk (
DAQmxCreateCICountEdgesChan(hware->taskHandle,
device_name,
"",
DAQmx_Val_Rising,
hware->count32,
DAQmx_Val_CountUp));
/*********************************************/
// Create the digital output channel within the task
/*********************************************/
snprintf(local_name, sizeof(local_name),
"dev%d/line%d",
hware->card_number,
hware->channel_number);
DAQmxErrChk (
DAQmxCreateDOChan(hware->taskHandle_dout,
local_name,
"",
DAQmx_Val_ChanPerLine));
/*********************************************/
// Start the DAQmx task
/*********************************************/
DAQmxErrChk (DAQmxStartTask(hware->taskHandle));
DAQmxErrChk (DAQmxStartTask(hware->taskHandle_dout));
hware_outp(hware, 0);
} while (0);
#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;
}
/*
* Select the filter
*/
int hware_filter(pHWARE hware, int value)
{
int error = 0;
#ifdef REGISTER_LEVEL_PROGRAMMING
CARD* pci = hware->card;
int src = 0;
if (value > 0 && value < 7)
src = value;
switch (hware->channel_number)
{
case 0:
pci->tio_1->IO_Pin_38_39_Configuration_Register.writeIO_Filter_39_Select(src);
break;
case 1:
pci->tio_1->IO_Pin_34_35_Configuration_Register.writeIO_Filter_35_Select(src);
break;
case 2:
pci->tio_1->IO_Pin_30_31_Configuration_Register.writeIO_Filter_31_Select(src);
break;
case 3:
pci->tio_1->IO_Pin_26_27_Configuration_Register.writeIO_Filter_27_Select(src);
break;
case 4:
pci->tio_2->IO_Pin_22_23_Configuration_Register.writeIO_Filter_23_Select(src);
break;
case 5:
pci->tio_2->IO_Pin_18_19_Configuration_Register.writeIO_Filter_19_Select(src);
break;
case 6:
pci->tio_2->IO_Pin_14_15_Configuration_Register.writeIO_Filter_15_Select(src);
break;
case 7:
pci->tio_2->IO_Pin_10_11_Configuration_Register.writeIO_Filter_11_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
data = 0;
DAQmxWriteDigitalLines(hware->taskHandle_dout,
1,
1,
10.0,
DAQmx_Val_GroupByChannel,
&data,
NULL,
NULL);
}
else
{
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 RLP
#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);
}
bool initPCI(pHWARE hware, const char* name)
{
CARD* pci = hware->card;
pci->bus = acquireBoard((tChar*) name);
if(pci->bus == NULL)
{
return false;
}
//Intitialise Mite Chip.
initMite(pci->bus);
return true;
}
void initCard(pHWARE hware)
{
CARD* pci = hware->card;
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);
}
void initChan(pHWARE hware)
{
CARD* pci = hware->card;
/*
* Set up the channel 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
#endif
#else /* SIMULATE_HARDWARE */
#include <sys/time.h>
typedef struct device_private_t
{
/** extended 64-bit counter value */
unsigned long long count64;
/* TODO time and count */
int source; /* count rate to be simulated */
struct timeval last_time;
} DEVICE_PRIVATE;
int hware_ctor(const char* device_name, pHWARE* ptr)
{
pHWARE hware = NULL;
hware = (DEVICE_PRIVATE*) malloc(sizeof(DEVICE_PRIVATE));
*ptr = hware;
memset(hware, 0, sizeof(DEVICE_PRIVATE));
/* TODO time and count */
hware->source = 1000; /* initial count rate */
gettimeofday(&hware->last_time, NULL);
#if 0 /* DEBUG */
printf("hware_ctor: %s at %p\n", device_name, *ptr);
#endif
return 0;
}
int hware_read(pHWARE hware, unsigned long long* value)
{
struct timeval this_time;
double delta_time;
long long delta_count = 0;
/* TODO time and count */
gettimeofday(&this_time, NULL);
delta_time = (this_time.tv_sec + 1e-6 * this_time.tv_usec) -
(hware->last_time.tv_sec + 1e-6 * hware->last_time.tv_usec);
delta_count = (long long)(0.5 + delta_time * hware->source);
hware->count64 += delta_count;
hware->last_time = this_time;
*value = hware->count64;
return 0;
}
int hware_source(pHWARE hware, int value)
{
#if 0 /* DEBUG */
int old_source = hware->source;
#endif
switch (value)
{
case 0:
hware->source = 10000;
break;
case 1:
hware->source = 20000000;
break;
case 2:
hware->source = 100000;
break;
case 3:
hware->source = 80000000;
break;
default:
if (value < 1000)
hware->source = 1000;
else
hware->source = value;
break;
}
#if 0 /* DEBUG */
printf("hware_source: %d moves %d to %d at %p\n", value, old_source, hware->source, hware);
#endif
return 0;
}
int hware_filter(pHWARE hware, int value)
{
/* nothing to do */
return 0;
}
int hware_outp(pHWARE hware, int value)
{
/* nothing to do */
return 0;
}
void hware_sync(pHWARE hware, bool external)
{
/* nothing to do */
}
int hware_dtor(pHWARE* ptr)
{
if (ptr && *ptr)
{
/* release the storage */
free(*ptr);
*ptr = NULL;
}
return 0;
}
bool hware_failed(int error)
{
return false;
}
void hware_errmsg(char* buff, int len)
{
if (buff)
strncpy(buff, "Simulated error message", len);
}
#endif