Jump to content

Nathan Kumar

Members
  • Posts

    1
  • Joined

  • Last visited

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

Nathan Kumar's Achievements

Newbie

Newbie (1/4)

0

Reputation

  1. Hi, I am using PCI-QUAD04 encoder board and I am able to read the value of the encoder using the windows library provided with the board. But when I try to read the encoder data using a real time OS called INtime, I running into problems. Under INtime when I try to get the base address of this PCI-QUAD04 board, I get 2 different base addresses: 1) When windows driver is installed and running, I get one set of address( Mcc Quad04 base1 = 56961, base2 = 57137 with Mcc driver active) 2) When windows driver is completely uninstalled, I get these address: base1 = = 53249, base2 = 53569 I am not able read the encoder data under INtime. Can you please help? I have attached both Windows side code and INtime side code for your perusal. Nathan The is the code on Windows side: ////////Windows example code that works correctly///////////////////////////////// /* Include files */ #include "..\cbw.h" #include "Utilities.h" #include <time.h> int Delta( const SYSTEMTIME st1, const SYSTEMTIME st2 ) { union timeunion { FILETIME fileTime; ULARGE_INTEGER ul; }; timeunion ft1; timeunion ft2; SystemTimeToFileTime( &st1, &ft1.fileTime ); SystemTimeToFileTime( &st2, &ft2.fileTime ); return max(1, (ft2.ul.QuadPart - ft1.ul.QuadPart) ); } DWORD GetTimeDifference( SYSTEMTIME &st1, SYSTEMTIME &st2 ) { FILETIME ft1, ft2; LARGE_INTEGER li1, li2, liDiff; DWORD dwDiff; SystemTimeToFileTime( &st1, &ft1 ); SystemTimeToFileTime( &st2, &ft2 ); li1.LowPart = ft1.dwLowDateTime; li1.HighPart = ft1.dwHighDateTime; li2.LowPart = ft2.dwLowDateTime; li2.HighPart = ft2.dwHighDateTime; //if ( CompareFileTime( &ft1, &ft2 ) < 0 ) { liDiff.LowPart = li2.LowPart - li1.LowPart; liDiff.HighPart = li2.HighPart - li1.HighPart; } //else { // liDiff.LowPart = li1.LowPart - li2.LowPart; // liDiff.HighPart = li1.HighPart - li2.HighPart; //} dwDiff = ( (__int64)liDiff.HighPart << 32 ) + liDiff.LowPart; dwDiff /= ( (__int64)10 * 1000 * 1000 ); // Convert from n x 100ns intervals into seconds return max(1, dwDiff); } int main( void ) { /* Variable Declarations */ int Row, Col; int ULStat = NOERRORS; int BoardNum = 0; int CounterNum, Quadrature, CountingMode, DataEncoding, IndexMode; int numCounters, defaultCtr; int InvertIndex, FlagPins, GateEnable; long LoadValue; ULONG Count[4], StatusBits[4]; ULONG BackwardBadCount[4], PreviousCount[4]; ULONG DiffCount[4], PrevForwardCount[4], ForwardCount[4]; int RegName; float RevLevel = (float)CURRENTREVNUM; const char* DirectionStr; int ctrType = CTR7266; char BoardName[BOARDNAMELEN]; int dummy; int MoreThan2inches = 0; bool bBadEncoderData = false; double inchesTravelled = 0.0; double inchesTravelledInMinute = 0.0; double booksPerMinute = 10.0; /* Declare UL Revision Level */ ULStat = cbDeclareRevision( &RevLevel ); InitUL(); // Set up error handling // get the name of the board if ( !GetNameOfBoard( BoardNum, BoardName ) ) { DisplayMessage( NOERRORS ); return 0; } ClearScreen(); printf( "Demonstration of 7266 Counter Functions using %s\n\n", BoardName ); // Determine if device is compatible with this example numCounters = FindCountersOfType( BoardNum, ctrType, &defaultCtr ); if ( numCounters == 0 ) { printf( "%s (board %u) does not have 7266 counters.\n", BoardName, BoardNum ); DisplayMessage( NOERRORS ); return 0; } printf( "Press any key to stop reading counter.\n\n" ); /* set the configurable operations of the counter Parameters: BoardNum :the number used by CB.CFG to describe this board CounterNum :the counter to be configured (0-5) Quadrature :Select type of counter input CountingMode :Slects how counter will operate IndexMode :Selects what index signal will control InvertIndex :Set to ENABLED id index signal is inverted FlagPins :Select which signals will drive Flag pins GateEnable :Set to ENABLED to use external gating signal */ double pinSpacing = 14.0;//inches for(int ctrIdx = 0; ctrIdx < numCounters; ++ctrIdx ) { CounterNum = defaultCtr + ctrIdx; Quadrature = X1_QUAD;//DONE CountingMode = NORMAL_MODE;//DONE DataEncoding = BINARY_ENCODING;//DONE IndexMode = LOAD_CTR;//INDEX_DISABLED; InvertIndex = DISABLED; FlagPins = CARRY_BORROW;//DONE GateEnable = DISABLED;//DONE /* int EXTCCONV cbC7266Config (int BoardNum, int CounterNum, int Quadrature, int CountingMode, int DataEncoding, int IndexMode, int InvertIndex, int FlagPins, int GateEnable); */ ULStat = cbC7266Config( BoardNum, CounterNum, Quadrature, CountingMode, DataEncoding, IndexMode, InvertIndex, FlagPins, GateEnable ); /* send a starting value to the counter with cbCLoad() Parameters: BoardNum :the number used by CB.CFG to describe this board RegName :the counter to be loading with the starting value LoadValue :the starting value to place in the counter */ LoadValue = 0x000000;//FFFFFF; RegName = COUNT1 + CounterNum - 1; printf( "Loading counter #%u with an initial count of %u using cbCLoad()\n", CounterNum, LoadValue ); ULStat = cbCLoad32( BoardNum, RegName, LoadValue ); LoadValue = 0xFFFFFF; RegName = PRESET1 + CounterNum - 1; printf( "Setting counter #%u maximum count to %u by loading PRESET register", CounterNum, LoadValue ); ULStat = cbCLoad32( BoardNum, RegName, LoadValue ); ForwardCount[ctrIdx] = 0l; PrevForwardCount[ctrIdx] = 0l; DiffCount[ctrIdx] = 0l; PreviousCount[ctrIdx] = 0l; BackwardBadCount[ctrIdx] = 0l; } /* use a loop to keep checking the counter value with cbCIn() */ SYSTEMTIME dateTime1; ::GetLocalTime( &dateTime1 ); GetTextCursor( &Col, &Row ); time_t startTime; double seconds; time( &startTime ); while ( !_kbhit() ) { for ( int ctrIdx = 0; ctrIdx < 1;/*numCounters*/ ++ctrIdx ) { CounterNum = defaultCtr + ctrIdx; /* Parameters: BoardNum :the number used by CB.CFG to describe this board CounterNum :the counter to be setup Count :the count value in the counter */ ULStat = cbCIn32( BoardNum, CounterNum, &Count[ctrIdx] ); /* Parameters: BoardNum :the number used by CB.CFG to describe this board CounterNum :the counter to be setup StatusBits :counter's status returned here */ ULStat = cbCStatus( BoardNum, CounterNum, &StatusBits[ctrIdx] ); bool bDiretionUp = !( StatusBits[ctrIdx] & C_UP_DOWN ); if ( StatusBits[ctrIdx] & C_UP_DOWN ) DirectionStr = "UP "; else DirectionStr = "DOWN"; SYSTEMTIME dateTime2; ::GetLocalTime( &dateTime2 ); int pulsesPerInch = 399; ForwardCount[ctrIdx] = 0x00FFFFFF - ( Count[ctrIdx] & 0x00FFFFFF ); if(PrevForwardCount[ctrIdx] != 0L && ForwardCount[ctrIdx] != PrevForwardCount[ctrIdx] && bDiretionUp ) { if( ForwardCount[ctrIdx] >= PrevForwardCount[ctrIdx] ) { DiffCount[ctrIdx] = (unsigned short)( ForwardCount[ctrIdx] - PrevForwardCount[ctrIdx] ); } else { ULONG DiffCount1 = (unsigned short)(0x00FFFFFF - PrevForwardCount[ctrIdx]) + (unsigned short)ForwardCount[ctrIdx]; if( DiffCount1 < pulsesPerInch ) { DiffCount[ctrIdx] = DiffCount1; ++BackwardBadCount[ctrIdx]; } } } double inches = DiffCount[ctrIdx] / double( pulsesPerInch ); inchesTravelled += inches; inchesTravelledInMinute += inches; time_t currentTime; time( &currentTime ); int numberOfSeconds = difftime( currentTime, startTime ); booksPerMinute = inchesTravelledInMinute / pinSpacing / numberOfSeconds * 60; MoveCursor( Col, Row + 2 + ctrIdx ); printf( "\nCounter %1u is %10d, Diff is %3u, inches = %4.3f <RCOUNT %6d>%s BPMinute = %3.0f Inches Travelled = %6.2f in %d seconds\n\n", CounterNum, ForwardCount[ctrIdx], DiffCount[ctrIdx], inches, BackwardBadCount[ctrIdx], bBadEncoderData ? "<BAD>":"<GOOD>", booksPerMinute, inchesTravelledInMinute, numberOfSeconds ); if ( inches > 2.0 ) { bBadEncoderData = true; ++MoreThan2inches; } if( numberOfSeconds > 30 && booksPerMinute > 350.0) { bBadEncoderData = true; } // /* Parameters: // BoardNum :the number used by CB.CFG to describe this board // CounterNum :the counter to be setup // Count :the count value in the counter // */ // ULStat = cbCIn32( BoardNum, CounterNum, &Count ); // // /* Parameters: // BoardNum :the number used by CB.CFG to describe this board // CounterNum :the counter to be setup // StatusBits :counter's status returned here // */ // ULStat = cbCStatus( BoardNum, CounterNum, &StatusBits ); // if ( StatusBits & C_UP_DOWN ) // DirectionStr = "UP "; // else // DirectionStr = "DOWN"; // // MoveCursor( Col, Row + 1 + ctrIdx ); // printf( "\nThe value of Counter %u is %u \n", CounterNum, Count ); // //printf( "The counter is now counting %s", DirectionStr ); PrevForwardCount[ctrIdx] = ForwardCount[ctrIdx]; PreviousCount[ctrIdx] = Count[ctrIdx]; } } dummy = _getch(); printf( "\n" ); DisplayMessage( NOERRORS ); return 0; } ///////////////////////////////////////// ////This is the code on INtime side/////////////////// //base address retrieval code // process MCC-QUAD04 encoder d board // ------------------------------------------ // check for PCI9200 vendor and device ID // if not, go process pci8010 boards if ( ( PciData->VendorID == PCI_VENDOR_ID_CBOARDS ) && ( PciData->DeviceID == PCI_DEVICE_ID_CBOARDS_QUAD04 ) ) { // check for previous board found // if so, initialize to first board if ( dNumPciMccQuad04Found == 0 ) dNumPciMccQuad04Found = PCI_MCCQUAD04_1_NUM; // else, advance to next board else dNumPciMccQuad04Found++; // install PCI application data gapciapp[dNumPciMccQuad04Found].lEnable = TRUE; gapciapp[dNumPciMccQuad04Found].dBaseAdr0 = PciData->u.type0.BaseAddresses[1];// & 0xFFFFFFFE; gapciapp[dNumPciMccQuad04Found].dBaseAdr1 = PciData->u.type0.BaseAddresses[2];// & 0xFFFFFFFE;//NULL; BoardData[0].base1 = gapciapp[dNumPciMccQuad04Found].dBaseAdr0; BoardData[0].base2 = gapciapp[dNumPciMccQuad04Found].dBaseAdr1; BoardData[0].irq = PciData->u.type0.InterruptLine; quad04_init_one( 0 ); unsigned int encoderData = 0; { byte counter_data[3]; int ret = quad04_read( 0, 0, counter_data, 3 ); encoderData = counter_data[2] << 16 | counter_data[1] << 8 | counter_data[0]; encoderData = 0x00FFFFFF - ( encoderData & 0x00FFFFFF ); } ///////////////////////////////////////////////////////////////////////////////////////////// void quad04_init_one( int NumBoards ) { int i; //int minor; dword base1; dword base2; byte data[3]; unsigned int pci9052_intreg; unsigned long counterValue = 0; if ( NumBoards >= MAX_BOARDS ) { //printk( "quad04_init_one: NumBoards = %d. Can't exceed MAX_BOARDS. edit quad04.h.\n", NumBoards ); return;// -ENODEV; } /*GETTING BASE ADDRESS 1 */ base1 = BoardData[NumBoards].base1; /*GETTING BASE ADDRESS 2 */ base2 = BoardData[NumBoards].base2; ///* Turn off interrupts */ pci9052_intreg = _inpd( INTCSR_REG ); pci9052_intreg &= ~( INTE | PCINT ); _outpd( INTCSR_REG, pci9052_intreg ); pci9052_intreg = _inpd( INTCSR_REG ); _outpd( INTCSR_REG, pci9052_intreg | INTCLR ); /* Initialize the LS7266R1 chip */ BoardData[NumBoards].mode = CONFIG_0; // (4) 24-bit counters (1/2/3/4) (default) BoardData[NumBoards].pic_A = 0x0; BoardData[NumBoards].pic_B = 0x0; _outp( PIC_A_REG, BoardData[NumBoards].pic_A ); _outp( PIC_B_REG, BoardData[NumBoards].pic_B ); BoardData[NumBoards].iscr = CONFIG_0; // default to 4 24 bit counters _outp( ISCR_REG, BoardData[NumBoards].iscr ); BoardData[NumBoards].ircr = 0x0F; // IDxSEL for all counters _outp( IRCR_REG, BoardData[NumBoards].ircr ); for ( i = 0; i < NCOUNTERS; i++ ) { Counter[NumBoards][i].open = TRUE; Counter[NumBoards][i].data_port = DATA1_REG + 2 * i; Counter[NumBoards][i].cmd_port = CMD1_REG + 2 * i; Counter[NumBoards][i].counter = i; // /* Reset/Load Register */ _outp( Counter[NumBoards][i].cmd_port, RESET_CNTR ); _outp( Counter[NumBoards][i].cmd_port, RESET_FLAGS ); _outp( Counter[NumBoards][i].cmd_port, RESET_E ); _outp( Counter[NumBoards][i].cmd_port, RESET_BP ); // // /* Be sure the prescaler is setup */ _outp( Counter[NumBoards][i].data_port, 1 ); _outp( Counter[NumBoards][i].cmd_port, TRAN_PR_PSC ); _outp( Counter[NumBoards][i].cmd_port, RESET_BP ); // /* Set Counter Mode to Normal, Binary, QuadX1 */ Counter[NumBoards][i].cmr = ( CMR1 | BIN | X1 | NORMAL ); _outp( Counter[NumBoards][i].cmd_port, Counter[NumBoards][i].cmr ); /* Enable Counter Inputs */ Counter[NumBoards][i].ior = ( IOR1 | ENABLE_AB | LOL | RCNTR );//| FLG_CB ); _outp( Counter[NumBoards][i].cmd_port, Counter[NumBoards][i].ior ); /* Disable Index */ Counter[NumBoards][i].idr = ( IDR1 | DISABLE_INDEX | LCNTRL_INDEX );//LOAD_CTR );//| _outp( Counter[NumBoards][i].cmd_port, Counter[NumBoards][i].idr ); // ///* Load Counter Preset */ _outp( Counter[NumBoards][i].cmd_port, RESET_BP ); _outp( Counter[NumBoards][i].data_port, 0xFF ); _outp( Counter[NumBoards][i].data_port, 0xFF ); _outp( Counter[NumBoards][i].data_port, 0xFF ); /* Transfer the loaded value to the counter */ _outp( Counter[NumBoards][i].cmd_port, TRAN_PR_CNTR ); /* Transfer counter to latch */ _outp( Counter[NumBoards][i].cmd_port, ( TRAN_CNTR_OL | RESET_BP ) ); //Init_7266( Counter[NumBoards][i].data_port ); //Write_7266_PR( Counter[NumBoards][i].data_port, 0x00FFFFFF ); //counterValue = Read_7266_OL( Counter[NumBoards][i].data_port ); /* Now read back the data from the output latch */ data[0] = _inp( Counter[NumBoards][i].data_port ); data[1] = _inp( Counter[NumBoards][i].data_port ); data[2] = _inp( Counter[NumBoards][i].data_port ); ////* Clear the preset */ _outp( Counter[NumBoards][i].cmd_port, RESET_BP ); _outp( Counter[NumBoards][i].data_port, 0x0 ); _outp( Counter[NumBoards][i].data_port, 0x0 ); _outp( Counter[NumBoards][i].data_port, 0x0 ); /* Reset all fags */ _outp( Counter[NumBoards][i].cmd_port, RESET_CNTR ); _outp( Counter[NumBoards][i].cmd_port, RESET_FLAGS ); _outp( Counter[NumBoards][i].cmd_port, RESET_E ); _outp( Counter[NumBoards][i].cmd_port, RESET_BP ); } NumBoards++; return; } //////////////////////////////////////////////////////////////////////////////// size_t quad04_read( int board, int chan, unsigned char *buf, size_t count ) { int i; dword base1; dword base2; byte data[12]; // counter could be 24 bit to 96 bits depending upon mode base1 = BoardData[board].base1; base2 = BoardData[board].base2; switch ( BoardData[board].mode ) { case CONFIG_0: // (4) 24-Bit counters 1/2/3/4 { _outp( Counter[board][chan].cmd_port, ( TRAN_CNTR_OL | RESET_BP ) ); // transfer counter to output latch for ( i = 0; i < 3; i++ ) { data[i] = _inp( Counter[board][chan].data_port ); buf[i] = data[i]; } return 3; } break; case CONFIG_1: // (2) 48-Bit counters 1-2/3-4 { if ( chan == 0 || chan == 1 ) { _outp( CMD1_REG, ( TRAN_CNTR_OL | RESET_BP ) ); for ( i = 0; i < 3; i++ ) { data[i] = _inp( DATA1_REG ); buf[i] = data[i]; } _outp( CMD2_REG, ( TRAN_CNTR_OL | RESET_BP ) ); for ( i = 3; i < 6; i++ ) { data[i] = _inp( DATA2_REG ); buf[i] = data[i]; } } else { _outp( CMD3_REG, ( TRAN_CNTR_OL | RESET_BP ) ); for ( i = 0; i < 3; i++ ) { data[i] = _inp( DATA3_REG ); buf[i] = data[i]; } _outp( CMD4_REG, ( TRAN_CNTR_OL | RESET_BP ) ); for ( i = 3; i < 6; i++ ) { data[i] = _inp( DATA4_REG ); buf[i] = data[i]; } } return 6; } break; case CONFIG_2: // (1) 24-bit counter, (1) 72-bit counter 1/2-3-4 { if ( chan == 0 ) { _outp( CMD1_REG, ( TRAN_CNTR_OL | RESET_BP ) ); for ( i = 0; i < 3; i++ ) { data[i] = _inp( DATA1_REG ); buf[i] = data[i]; } return 3; } else { _outp( CMD2_REG, ( TRAN_CNTR_OL | RESET_BP ) ); for ( i = 0; i < 3; i++ ) { data[i] = _inp( DATA2_REG ); buf[i] = data[i]; } _outp( CMD3_REG, RESET_BP ); for ( i = 3; i < 6; i++ ) { data[i] = _inp( DATA3_REG ); buf[i] = data[i]; } _outp( CMD4_REG, RESET_BP ); for ( i = 6; i < 8; i++ ) { data[i] = _inp( DATA4_REG ); buf[i] = data[i]; } return 9; } } break; case CONFIG_3: // (1) 96-bit counter 1-2-3-4 _outp( CMD1_REG, ( TRAN_CNTR_OL | RESET_BP ) ); for ( i = 0; i < 3; i++ ) { data[i] = _inp( DATA1_REG ); buf[i] = data[i]; } _outp( CMD2_REG, ( TRAN_CNTR_OL | RESET_BP ) ); for ( i = 3; i < 6; i++ ) { data[i] = _inp( DATA2_REG ); buf[i] = data[i]; } _outp( CMD3_REG, ( TRAN_CNTR_OL | RESET_BP ) ); for ( i = 6; i < 9; i++ ) { data[i] = _inp( DATA3_REG ); buf[i] = data[i]; } _outp( CMD4_REG, ( TRAN_CNTR_OL | RESET_BP ) ); for ( i = 9; i < 12; i++ ) { data[i] = _inp( DATA4_REG ); buf[i] = data[i]; } return 12; break; } return 0; } ////////////////////////////////////////////
×
×
  • Create New...