diff --git a/site_ansto/hardsup/Monitor/Makefile b/site_ansto/hardsup/Monitor/Makefile index 4c434447..f398f57d 100644 --- a/site_ansto/hardsup/Monitor/Makefile +++ b/site_ansto/hardsup/Monitor/Makefile @@ -3,28 +3,41 @@ SHELL = /bin/sh CC = gcc CXX = g++ LD = $(CXX) -LIBS = nidaqmx -LIBFLAGS = -l$(LIBS) -TARGET = Monitor -PULSER = Pulser - -OBJS = $(TARGET).o params.o utility.o sock.o display.o cntr.o hctr.o - CDEBUG = -ggdb3 -Wall LDFLAGS += -g +TARGETS = Monitor -CFLAGS += $(CDEBUG) -CXXFLAGS += $(CDEBUG) +OBJS = Monitor.o params.o utility.o sock.o display.o cntr.o hctr.o +ifeq ($(MAKECMDGOALS),rlp) +OBJECTS = +LIBS = +LIBFLAGS = +DDK_DIR = /home/dcl/nitest/nimhddk_linux26 +OBJECTS += $(DDK_DIR)/osiBus.o +OBJECTS += $(DDK_DIR)/Linux26/osiUserCode.o +TIO_DIR = /home/dcl/nitest/NI660x +OBJECTS += $(TIO_DIR)/tTIO.o +IFLAGS = -I$(DDK_DIR) +IFLAGS += -I$(TIO_DIR)/ChipObjects/ +CXXFLAGS += -DkLittleEndian=1 -DREGISTER_LEVEL_PROGRAMMING=1 +LIBFLAGS += $(OBJECTS) +CXXFLAGS += $(IFLAGS) +else +LIBS = nidaqmx +LIBFLAGS = $(foreach lib,$(LIBS),-l$(lib)) +endif -all: $(TARGET) $(PULSER) +all: $(TARGETS) + +rlp: all clean: - rm -f $(OBJS) $(TARGET) $(PULSER).o $(PULSER) core + rm -f $(OBJS) Monitor Pulser.o Pulser core -$(TARGET) : $(OBJS) +Monitor : $(OBJS) $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBFLAGS) -ggdb3 -$(TARGET).o: $(TARGET).c $(TARGET).h params.h utility.h sock.h cntr.h +Monitor.o: Monitor.c Monitor.h params.h utility.h sock.h cntr.h cntr.o: cntr.c cntr.h params.h sock.h @@ -38,10 +51,13 @@ sock.o: sock.c sock.h utility.h display.h cntr.h utility.o: utility.c utility.h -$(PULSER) : $(PULSER).o - $(LD) $(LDFLAGS) -o $@ $(PULSER).o $(LIBFLAGS) -ggdb3 +Pulser : Pulser.c + $(CXX) -o $@ $< $(CXXFLAGS) $(CDEBUG) $(LDFLAGS) $(LIBFLAGS) %.o : %.c - $(CXX) -c -o $@ $< $(CXXFLAGS) + $(CXX) -c -o $@ $< $(CXXFLAGS) $(CDEBUG) + +%.o : %.cpp + $(CXX) -c -o $@ $< $(CXXFLAGS) $(CDEBUG) # vim: noexpandtab ts=8 sts=8 diff --git a/site_ansto/hardsup/Monitor/Monitor.c b/site_ansto/hardsup/Monitor/Monitor.c index 229f3c88..0ead96da 100644 --- a/site_ansto/hardsup/Monitor/Monitor.c +++ b/site_ansto/hardsup/Monitor/Monitor.c @@ -119,7 +119,7 @@ int main(int argc, char* argv[]) return usage(argc, argv, "no port"); if (isdigit(argv[idx][0])) { - port = 10 * (atoi(argv[idx]) / 10); + port = atoi(argv[idx]); ++idx; } else diff --git a/site_ansto/hardsup/Monitor/cntr.c b/site_ansto/hardsup/Monitor/cntr.c index 1c0d6160..72ae697b 100644 --- a/site_ansto/hardsup/Monitor/cntr.c +++ b/site_ansto/hardsup/Monitor/cntr.c @@ -15,8 +15,6 @@ goto Error; \ else -COUNTER counter; - /* * get a pointer to the current sample */ @@ -288,6 +286,9 @@ int cntr_start(COUNTER *cp) cp->terminal_due = false; cp->state = counter_running; cp->previous_time = cp->current_time; + dbg_printf(0, "Setting input line to %d\n", pp->source); + HCTR_TEST(hctr_source(cp->private_data, pp->source)); + cp->source = pp->source; HCTR_TEST(hctr_read(cp->private_data, &cp->count64)); sp = cur_sample(cp); sp->timestamp = cp->current_time; @@ -327,6 +328,9 @@ int cntr_stop(COUNTER *cp) value = -1; dbg_printf(0, "Setting output line to %d\n", value); HCTR_TEST(hctr_outp(cp->private_data, value)); + dbg_printf(0, "Setting input line to %d\n", pp->source); + HCTR_TEST(hctr_source(cp->private_data, pp->source)); + cp->source = pp->source; return error; Error: cntr_errmsg(errBuff, sizeof(errBuff)); @@ -584,6 +588,13 @@ int cntr_poll(COUNTER* cp) cntr_sample(cp); } + /* set the source line */ + if (cp->source != pp->source) + { + cp->source = pp->source; + HCTR_TEST(hctr_source(cp->private_data, cp->source)); + } + /* drive the output line */ if (cp->output_line != pp->output_line) { diff --git a/site_ansto/hardsup/Monitor/cntr.h b/site_ansto/hardsup/Monitor/cntr.h index 544ca090..8e571820 100644 --- a/site_ansto/hardsup/Monitor/cntr.h +++ b/site_ansto/hardsup/Monitor/cntr.h @@ -91,6 +91,8 @@ typedef struct counter_t uint64 count64; /** Control parameters */ PARAMETERS params; + /** active value of parameter source */ + int source; /** active value of parameter output_line */ int output_line; struct counter_private_t* private_data; @@ -102,7 +104,7 @@ void cntr_send(COUNTER* cp, int n); void cntr_read(COUNTER* cp, int n); void cntr_print(COUNTER* cp, FILE* fd); void cntr_report(COUNTER* cp); -int cntr_init(COUNTER** cp, char* name); +int cntr_init(COUNTER** cpp, char* name); int cntr_start(COUNTER* cp); int cntr_stop(COUNTER* cp); int cntr_pause(COUNTER* cp); diff --git a/site_ansto/hardsup/Monitor/display.c b/site_ansto/hardsup/Monitor/display.c index ae538925..511122b0 100644 --- a/site_ansto/hardsup/Monitor/display.c +++ b/site_ansto/hardsup/Monitor/display.c @@ -204,6 +204,12 @@ void put_form(int n) add_option(&buffer, "Sample", "1", pp->range_mode == 1); add_option(&buffer, "Poll", "2", pp->range_mode == 2); add_select_end(&buffer); + add_select_begin(&buffer, "Source", "source"); + add_option(&buffer, "External", "0", pp->source == 0); + add_option(&buffer, "Clock_1 20MHz", "1", pp->source == 1); + add_option(&buffer, "Clock_2 100KHz", "2", pp->source == 2); + add_option(&buffer, "Clock_3 80MHz", "3", pp->source == 3); + add_select_end(&buffer); add_select_begin(&buffer, "Output Line", "output"); add_option(&buffer, "Disabled", "disabled", pp->output_line == 0); add_option(&buffer, "Enabled", "enabled", pp->output_line == 1); diff --git a/site_ansto/hardsup/Monitor/hctr.c b/site_ansto/hardsup/Monitor/hctr.c index 595b9211..3c370b1c 100644 --- a/site_ansto/hardsup/Monitor/hctr.c +++ b/site_ansto/hardsup/Monitor/hctr.c @@ -1,13 +1,38 @@ +/* vim: ts=8 sts=2 sw=2 cindent + */ #include "hctr.h" -#include + #include #include +#include #include + +#ifdef REGISTER_LEVEL_PROGRAMMING +#define DAQmxFailed(e) ((e) != 0) +#define DAQmxGetExtendedErrorInfo(b, l) snprintf(b, l, "BAD") +#include +#include +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 #define DAQmxErrChk(functionCall) \ do { if( DAQmxFailed(error=(functionCall)) ) \ goto Error; } while(0) +#endif /** * This structure encapsulates the data that is private to @@ -15,11 +40,6 @@ */ 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; /** NIDAQ device number of card */ @@ -32,8 +52,16 @@ typedef struct counter_private_t 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 } COUNTER_PRIVATE; typedef struct mapping_t { @@ -42,7 +70,7 @@ typedef struct mapping_t { int outp_num; } MAPPING; -MAPPING mapping[8] = { +static MAPPING mapping[8] = { { 0, 37, 36 }, { 1, 33, 32 }, { 2, 29, 28 }, @@ -53,15 +81,28 @@ MAPPING mapping[8] = { { 7, 9, 8 } }; +#ifdef REGISTER_LEVEL_PROGRAMMING +static void initMite(iBus *bus); + +static CARD* card[10]; +#else +static int make_dout_task(pHCTR ptr); +#endif + int hctr_ctor(const char* device_name, pHCTR* ptr) { + pHCTR hctr = NULL; +#ifdef REGISTER_LEVEL_PROGRAMMING + CARD* pci = NULL; +#endif int error = 0; bool flag = false; char text_string[] = "dev1/ctr0"; const char *name; const char *text; - *ptr = (COUNTER_PRIVATE*) malloc(sizeof(COUNTER_PRIVATE)); + hctr = (COUNTER_PRIVATE*) malloc(sizeof(COUNTER_PRIVATE)); + *ptr = hctr; memset(*ptr, 0, sizeof(COUNTER_PRIVATE)); name = device_name; @@ -87,11 +128,252 @@ int hctr_ctor(const char* device_name, pHCTR* ptr) else if (tolower(*name) != *text) { /* TODO error */ + printf("Device name error: %s (%d,%d)\n", + device_name, + (*ptr)->counter_number, + (*ptr)->device_number); break; } ++name; ++text; } + +#ifdef REGISTER_LEVEL_PROGRAMMING + if (card[hctr->device_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, "0x1310")) + { + ++count; + name = strstr(line, "PXI"); + if (name && count == hctr->device_number) + { + found = true; + strcpy(local_name, name); + break; + } + } + if (!found) + { + // TODO error + } + } + fclose(fd); + } + + card[hctr->device_number] = (CARD*) malloc(sizeof(CARD)); + memset(card[hctr->device_number], 0, sizeof(CARD)); + pci = card[hctr->device_number]; + hctr->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[hctr->device_number]; + hctr->card = pci; + } + + // Mark the counter on this card as in-use + if (pci->dev_mask & (1 << hctr->counter_number)) + { + // TODO error + } + pci->dev_mask |= 1 << hctr->counter_number; + + /* + * Set up the counter object + */ + switch (hctr->counter_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 to hold the counter /*********************************************/ @@ -112,6 +394,7 @@ int hctr_ctor(const char* device_name, pHCTR* ptr) // Start the DAQmx task /*********************************************/ DAQmxErrChk (DAQmxStartTask((*ptr)->taskHandle)); +#endif return 0; Error: @@ -123,53 +406,175 @@ Error: int hctr_read(pHCTR hctr, unsigned long long* value) { int error = 0; - uInt32 ctr; + *value = 0; + uInt32 counterValue1; +#ifdef REGISTER_LEVEL_PROGRAMMING + uInt32 counterValue2; + CARD* pci = hctr->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 (hctr->counter_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; + } +#else DAQmxErrChk (DAQmxReadCounterScalarU32(hctr->taskHandle, 1.0, - &ctr, + &counterValue1, NULL)); - hctr->count64 += ctr - hctr->count32; - hctr->count32 = ctr; - *value = hctr->count64; - return 0; Error: + if (error) + counterValue1 = hctr->count32; +#endif + hctr->count64 += counterValue1 - hctr->count32; + hctr->count32 = counterValue1; + *value = hctr->count64; return error; } -int make_dout_task(pHCTR ptr) +/* + * Select the source + */ +int hctr_source(pHCTR hctr, int value) { 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)); - return error; - -Error: +#ifdef REGISTER_LEVEL_PROGRAMMING + CARD* pci = hctr->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 (hctr->counter_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 hctr_outp(pHCTR hctr, int value) { int error = 0; +#ifdef REGISTER_LEVEL_PROGRAMMING + CARD* pci = hctr->card; + u16 data; + if (value < 0) + { + // set the disabled line to input + value = 0; + pci->dio_mask &= ~(1 << hctr->counter_number); + pci->tio_1->DIO_Control_Register.writeDIO_Pins_Dir(pci->dio_mask); + } + else + { + pci->dio_mask |= 1 << hctr->counter_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 << hctr->counter_number; + else + data &= ~(1 << hctr->counter_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) { + if (value < 0) + { + // set the disabled line to logic low if (hctr->taskHandle_dout != 0) { data = 0; DAQmxWriteDigitalLines(hctr->taskHandle_dout, @@ -187,38 +592,36 @@ int hctr_outp(pHCTR hctr, int value) 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 + { + if (hctr->taskHandle_dout == 0) + DAQmxErrChk (make_dout_task(hctr)); + if (value > 0) + data = 1; + else + data = 0; + DAQmxErrChk ( + DAQmxWriteDigitalScalarU32(hctr->taskHandle_dout, + 1, + 10.0, + data, + NULL)); + } Error: +#endif return error; } +/* + * Set up to read the counter synchronized to an external signal + */ void hctr_sync(pHCTR hctr, bool external) { +#if REGISTER_LEVEL_PROGRAMMING + CARD* pci = hctr->card; + // TODO +#else int error = 0; char device_name[40]; if (hctr->sync != external) @@ -268,31 +671,85 @@ void hctr_sync(pHCTR hctr, bool external) } Error: +#endif return; } +/* + * Shut down the counter + */ int hctr_dtor(pHCTR* hctr) { - if( hctr && *hctr && (*hctr)->taskHandle!=0 ) + if (hctr && *hctr) { - /*********************************************/ - // DAQmx Stop Code - /*********************************************/ - DAQmxStopTask((*hctr)->taskHandle); - DAQmxClearTask((*hctr)->taskHandle); +#ifdef REGISTER_LEVEL_PROGRAMMING + CARD* pci = (*hctr)->card; + switch ((*hctr)->counter_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 << (*hctr)->counter_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[(*hctr)->device_number] = NULL; + free(pci); + } +#else + if ((*hctr)->taskHandle!=0) + { + /*********************************************/ + // DAQmx Stop Code + /*********************************************/ + DAQmxStopTask((*hctr)->taskHandle); + DAQmxClearTask((*hctr)->taskHandle); + (*hctr)->taskHandle = 0; + } + if ((*hctr)->taskHandle_dout!=0) + { + /*********************************************/ + // DAQmx Stop Code + /*********************************************/ + DAQmxStopTask((*hctr)->taskHandle_dout); + DAQmxClearTask((*hctr)->taskHandle_dout); + (*hctr)->taskHandle_dout = 0; + } + +#endif + + /* release the storage */ + free(*hctr); + *hctr = NULL; } - (*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; } @@ -310,3 +767,64 @@ void hctr_errmsg(char* buff, int len) 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(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)); + return error; + +Error: + return error; +} +#endif diff --git a/site_ansto/hardsup/Monitor/hctr.h b/site_ansto/hardsup/Monitor/hctr.h index e0d10575..3023be99 100644 --- a/site_ansto/hardsup/Monitor/hctr.h +++ b/site_ansto/hardsup/Monitor/hctr.h @@ -42,7 +42,18 @@ int hctr_ctor(const char* device_name, pHCTR* ptr); int hctr_read(pHCTR hctr, unsigned long long* value); /** - * Enables external sync on designated (up/down) line + * Select the source + * + * \param value source selector + * 3 Timebase 3 (80Mhz on PCI-6602) + * 2 Timebase 2 (100Khz on PCI-6602) + * 1 Timebase 1 (20Mhz on PCI-6602) + * else default external pin + */ +int hctr_source(pHCTR hctr, int value); + +/** + * Enables external output on designated DIO line * * \param hctr pointer to opaque private data structure * \param value to be written to the associated line diff --git a/site_ansto/hardsup/Monitor/params.c b/site_ansto/hardsup/Monitor/params.c index b0324792..94eb399c 100644 --- a/site_ansto/hardsup/Monitor/params.c +++ b/site_ansto/hardsup/Monitor/params.c @@ -17,6 +17,7 @@ #define CMD_RANGE_MODE 12 #define CMD_OUTPUT 13 #define CMD_SYNC 14 +#define CMD_SOURCE 15 #define TXT_DIRECTION "DIRECTION" #define TXT_SCAN "SCAN" @@ -32,6 +33,7 @@ #define TXT_RANGE_MODE "RANGE_MODE" #define TXT_OUTPUT "OUTPUT" #define TXT_SYNC "SYNC" +#define TXT_SOURCE "SOURCE" static struct param_command_t { int cmd; @@ -51,6 +53,7 @@ static struct param_command_t { {CMD_RANGE_MODE, TXT_RANGE_MODE}, {CMD_OUTPUT, TXT_OUTPUT}, {CMD_SYNC, TXT_SYNC}, + {CMD_SOURCE, TXT_SOURCE}, {0, NULL} }; #define NUM_CMDS ((int) (sizeof(param_command)/sizeof(param_command[0]))) @@ -158,6 +161,16 @@ bool param_set(pPARAMETERS pp, char* name, char* value) pp->range_low = 0.0; dbg_printf(0, "=>%g\n", pp->range_low); break; + case CMD_SAMPLE: + result = true; + dbg_printf(0, "Sample=%d", pp->sample_period); + pp->sample_period = strtol(value, NULL, 10); + if (pp->sample_period < 1) + pp->sample_period = 1; + else if (pp->sample_period > 1000) + pp->sample_period = 1000; + dbg_printf(0, "=>%d\n", pp->sample_period); + break; case CMD_SCAN: result = true; dbg_printf(0, "Scan=%d", pp->poll_period); @@ -168,15 +181,15 @@ bool param_set(pPARAMETERS pp, char* name, char* value) pp->poll_period = 1000; dbg_printf(0, "=>%d\n", pp->poll_period); break; - case CMD_SAMPLE: + case CMD_SOURCE: result = true; - dbg_printf(0, "Sample=%d", pp->sample_period); - pp->sample_period = strtol(value, NULL, 10); - if (pp->sample_period < 1) - pp->sample_period = 1; - else if (pp->sample_period > 1000) - pp->sample_period = 1000; - dbg_printf(0, "=>%d\n", pp->sample_period); + dbg_printf(0, "Source=%d", pp->source); + pp->source = strtol(value, NULL, 10); + if (pp->source < 1) + pp->source = 0; + else if (pp->source > 1000) + pp->source = 0; + dbg_printf(0, "=>%d\n", pp->source); break; case CMD_SYNC: result = true; @@ -189,7 +202,7 @@ bool param_set(pPARAMETERS pp, char* name, char* value) break; case CMD_TERMINAL: result = true; - dbg_printf(0, "Sample=%llu", pp->terminal_count); + dbg_printf(0, "Terminal=%llu", pp->terminal_count); pp->terminal_count = strtoull(value, NULL, 10); dbg_printf(0, "=>%llu\n", pp->terminal_count); break; @@ -328,17 +341,29 @@ bool param_get_cmd(pPARAMETERS pp, char* cmd, int n) "GET %s=%g", name, pp->range_low); break; + case CMD_SAMPLE: + result = true; + snprintf(buffer.body, sizeof(buffer.body), + "GET %s=%d", name, + pp->sample_period); + break; case CMD_SCAN: result = true; snprintf(buffer.body, sizeof(buffer.body), "GET %s=%d", name, pp->poll_period); break; - case CMD_SAMPLE: + case CMD_SOURCE: result = true; snprintf(buffer.body, sizeof(buffer.body), "GET %s=%d", name, - pp->sample_period); + pp->source); + break; + case CMD_SYNC: + result = true; + snprintf(buffer.body, sizeof(buffer.body), + "GET %s=%s", name, + pp->sync ? "External" : "Internal"); break; case CMD_TERMINAL: result = true; diff --git a/site_ansto/hardsup/Monitor/params.h b/site_ansto/hardsup/Monitor/params.h index 28d787c6..26433ad2 100644 --- a/site_ansto/hardsup/Monitor/params.h +++ b/site_ansto/hardsup/Monitor/params.h @@ -41,6 +41,8 @@ typedef struct parameter_t int output_line; /** hardware_sync false:internal, true:external */ bool sync; + /** source 0:default, 1:timebase_1, 2:timebase_2, 3:timebase_3 */ + int source; } PARAMETERS, *pPARAMETERS;