⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driver.c

📁 研华工控卡PCL836的一些例程序
💻 C
📖 第 1 页 / 共 3 页
字号:
        return ((ULONG) LostBaseAddr);

    // check input param correct ?
    if (counter > MaxCounterNumber)
        return((ULONG) InvalidCounterChannel);

    // get base address
    usBase = usBaseAddr[DeviceNumber];

    usCtrByte = (counter%3) << 6;
    usCtrByte |= 0x39;

    // stop counting by setting counter chan for mode 5
    if (counter < 3)  // configure 8254 chip 1
    {
       outportb(usBase+3, usCtrByte);
       outportb(usBase+counter, 0x0);       /* write low byte */
       outportb(usBase+counter, 0x0);       /* write high byte */
    }
    else              // configure 8254 chip 2
    {
       outportb(usBase+7, usCtrByte);
       outportb(usBase+(counter%3)+4, 0x0);  /* write low byte */
       outportb(usBase+(counter%3)+4, 0x0);  /* write high byte */
    }

    // disable frequency output control reg.
    usCtrByte = 0x01;
    usCtrByte = usCtrByte << counter;

    usFoutCtrReg[DeviceNumber] &= (~usCtrByte);

    outportb(usBase+24, usFoutCtrReg[DeviceNumber]);

    return 0L;
}

//------------------------------------------------------------------
// Function    : CounterEventStart
// PURPOSE     : Configures the specified counter for an event-counting
//               operation and starts the counter.
//               The function uses 8254 mode 0 and initialize counter is
//               0xffff
// Parameters  : DeviceNumber(IN), counter(IN)
// Return      : NULL (success)
//				 ErrorCode (failure)
// Call/Called procedure cross reference :
// Call        Called		     Explanation
//------------------------------------------------------------------
ULONG CounterEventStart(USHORT DeviceNumber, USHORT counter)
{
    USHORT usBase;
    USHORT usCtrByte, usLowByte, usHighByte, usCurrentCount;

    // Is DeviceNumber out of range ?
    if (DeviceNumber > MaxBoardNumber)
        return ((ULONG) InvalidDeviceNumber);

    // Is BaseAddr valid ?
    if (usBaseAddr[DeviceNumber] == NULL)
        return ((ULONG) LostBaseAddr);

    // check input param correct ?
    if (counter > MaxCounterNumber)
        return((ULONG) InvalidCounterChannel);

    // get base address
    usBase = usBaseAddr[DeviceNumber];

    // initial Global variables for event counter
    ulOverflow[DeviceNumber][counter] = 0;
    usFirstCount[DeviceNumber][counter] = 1;

    // configure counter for external clocking
    outportb(usBase+counter+18, usModeCtrReg[DeviceNumber][counter]);

    // set control byte for  control register & set initial value
    usCtrByte = (counter%3) << 6;
    usCtrByte |= 0x30;

    if (counter < 3)  // configure 8254 chip 3
    {
       outportb(usBase+11, usCtrByte);
       outportb(usBase+counter+8, 0xff);       /* write low byte */
       outportb(usBase+counter+8, 0xff);       /* write high byte */
    }
    else              // configure 8254 chip 4
    {
       outportb(usBase+15, usCtrByte);
       outportb(usBase+(counter%3)+12, 0xff);  /* write low byte */
       outportb(usBase+(counter%3)+12, 0xff);  /* write high byte */
    }

    // Read first counter
    usCtrByte = (counter%3) << 6;
    usCtrByte |= 0;      /* set control byte for read mode */

    if (counter < 3)  // configure 8254 chip 3
    {
       outportb(usBase+11, usCtrByte);
       usLowByte  = inportb(usBase+counter+8);      /* read low byte */
       usHighByte = inportb(usBase+counter+8);      /* read high byte */
    }
    else              // configure 8254 chip 4
    {
       outportb(usBase+15, usCtrByte);
       usLowByte  = inportb(usBase+(counter%3)+12); /* read low byte */
       usHighByte = inportb(usBase+(counter%3)+12); /* read high byte */
    }

    usHighByte <<= 8;
    usCurrentCount = usHighByte | usLowByte;

    usPreCount[DeviceNumber][counter] = usCurrentCount;

    return ((ULONG) NULL);
}

//------------------------------------------------------------------
// Function    : CounterEventRead
// PURPOSE     : Reads the current counter total without disturbing
//               the counting process and returns the count and
//               overflow conditions. 
//               When your counter overs 32-BIT , its overflow will be
//               set to 1.
// Parameters  : DeviceNumber(IN), counter(IN), overflow(OUT), count(OUT)
// Return      : NULL (success)
//				 ErrorCode (failure)
// Call/Called procedure cross reference :
// Call        Called		     Explanation
//------------------------------------------------------------------
ULONG CounterEventRead(USHORT DeviceNumber,USHORT counter,
    USHORT *overflow, ULONG *count)
{
    USHORT usBase;
    USHORT usCtrByte, usLowByte, usHighByte, usCurrentCount;
    ULONG  c_data, carry;

    // Is DeviceNumber out of range ?
    if (DeviceNumber > MaxBoardNumber)
        return ((ULONG) InvalidDeviceNumber);

    // Is BaseAddr valid ?
    if (usBaseAddr[DeviceNumber] == NULL)
        return ((ULONG) LostBaseAddr);

    // check input param correct ?
    if (counter > MaxCounterNumber)
        return((ULONG) InvalidCounterChannel);

    // get base address
    usBase = usBaseAddr[DeviceNumber];

    // Read value
    usCtrByte = (counter%3) << 6;
    usCtrByte |= 0;      /* set control byte for read mode */

    if (counter < 3)  // configure 8254 chip 3
    {
       outportb(usBase+11, usCtrByte);
       usLowByte  = inportb(usBase+counter+8);      /* read low byte */
       usHighByte = inportb(usBase+counter+8);      /* read high byte */
    }
    else              // configure 8254 chip 4
    {
       outportb(usBase+15, usCtrByte);
       usLowByte  = inportb(usBase+(counter%3)+12); /* read low byte */
       usHighByte = inportb(usBase+(counter%3)+12); /* read high byte */
    }

    usHighByte <<= 8;
    usCurrentCount = usHighByte | usLowByte;

	// still wait for first valid count
    if(usFirstCount[DeviceNumber][counter])
	{
        if (usPreCount[DeviceNumber][counter] == usCurrentCount)
		{
			*count = 0;
            *overflow = 0;
			return 0L;
		}
		else
		{
            usFirstCount[DeviceNumber][counter] = 0;  // set not first counter
            usPreCount[DeviceNumber][counter] = 65535;  // initial previous count
		}
	}

    c_data = ((ULONG)65536 - (ULONG)usCurrentCount); /* convert to up count */

    /* check if 16-bit counter register of 8253 is over flow ?    */
    if(usPreCount[DeviceNumber][counter] < usCurrentCount)  // over flow
        ulOverflow[DeviceNumber][counter] += 1;   /* increament overflow by 1 */

    carry = ((ULONG)ulOverflow[DeviceNumber][counter]) << 16; /* shift overflow 16 bits */
    c_data |= carry;        /* convert 16-bit to 32-bit */

    // check 32bit overflow ?
    *overflow = 0;  		// clear overflow flag
    if (ulOverflow[DeviceNumber][counter] > 63335L)
        *overflow = 1;

    *count = c_data;    // return data

    usPreCount[DeviceNumber][counter] = usCurrentCount;   // save data

    return 0L;
}

//------------------------------------------------------------------
// Function    : CounterFreqStart
// PURPOSE     : Configures the specified counter for frequency
//               measurement and starts the counter.
// Parameters  : DeviceNumber(IN), counter(IN)
// Return      : NULL (success)
//				 ErrorCode (failure)
// Call/Called procedure cross reference :
// Call        Called		     Explanation
//------------------------------------------------------------------
ULONG CounterFreqStart(USHORT DeviceNumber,USHORT counter)
{
    USHORT usBase;

    // Is DeviceNumber out of range ?
    if (DeviceNumber > MaxBoardNumber)
        return ((ULONG) InvalidDeviceNumber);

    // Is BaseAddr valid ?
    if (usBaseAddr[DeviceNumber] == NULL)
        return ((ULONG) LostBaseAddr);

    // check input param correct ?
    if (counter > MaxCounterNumber)
        return((ULONG) InvalidCounterChannel);

    // get base address
    usBase = usBaseAddr[DeviceNumber];

    /* configure counter for external clocking */
    outportb(usBase+counter+18, usModeCtrReg[DeviceNumber][counter]);

    return 0L;
}

//------------------------------------------------------------------
// Function    : CounterFreqRead
// PURPOSE     : Reads the frequency measurement.
// Parameters  : DeviceNumber(IN), counter(IN), FreqLevel(IN), freq(OUT)
//               FreqLevel
//                 = MAX1K_65K(0),     RANGE=   1 -- 65KHZ (need    1s)
//                 = MAX10K_650K(1),   RANGE= 10K -- 650KHZ(need 100ms)
//                 = MAX100K_6500K(2), RANGE=100K -- 6.5MHZ(need  10ms)
//
// Return      : NULL (success)
//				 ErrorCode (failure)
// Call/Called procedure cross reference :
// Call        Called		     Explanation
//------------------------------------------------------------------
ULONG CounterFreqRead(USHORT DeviceNumber,USHORT counter,
    USHORT FreqLevel, FLOAT * freq)
{
    USHORT usBase;
    USHORT usDelay;
    USHORT usCtrByte, usCtr1Byte;
    USHORT usLow1Byte, usHigh1Byte, usCurrentCount1;
    USHORT usLow2Byte, usHigh2Byte, usCurrentCount2;
    FLOAT  fSampleRate;

    usLow1Byte = 0;
    usHigh1Byte = 0;
    usLow2Byte = 0;
    usHigh2Byte = 0;

    // Is DeviceNumber out of range ?
    if (DeviceNumber > MaxBoardNumber)
        return ((ULONG) InvalidDeviceNumber);

    // Is BaseAddr valid ?
    if (usBaseAddr[DeviceNumber] == NULL)
        return ((ULONG) LostBaseAddr);

    // check input param correct ?
    if (counter > MaxCounterNumber)
        return((ULONG) InvalidCounterChannel);

    // get base address
    usBase = usBaseAddr[DeviceNumber];

    // Prepare some thing for BIOS function call
    switch(FreqLevel)
    {
        case MAX1_65K:
            usDelay = 1000;
            fSampleRate = 1;
            break;
        case MAX10K_650K:
            usDelay = 100;
            fSampleRate = 10;
            break;
        case MAX100K_6500K:
            usDelay = 10;
            fSampleRate = 100;
            break;
        default:
            usDelay = 1000;
            fSampleRate = 1;
            break;
    }

    // first :  set control byte for  control register
    usCtrByte = (counter%3) << 6;
    usCtr1Byte = usCtrByte | 0x30;

    if (counter < 3)  // configure 8254 chip 3
    {
       outportb(usBase+11, usCtr1Byte);
       outportb(usBase+counter+8, 0xff);       /* write low byte */
       outportb(usBase+counter+8, 0xff);       /* write high byte */
    }
    else              // configure 8254 chip 4
    {
       outportb(usBase+15, usCtr1Byte);
       outportb(usBase+(counter%3)+12, 0xff);  /* write low byte */
       outportb(usBase+(counter%3)+12, 0xff);  /* write high byte */
    }

    // delay 1/2 time
    delay(usDelay/2);

    // second: read counter
    usCtr1Byte = usCtrByte | 0;      /* set control byte for read mode */

    if (counter < 3)  // configure 8254 chip 3
    {
       outportb(usBase+11, usCtr1Byte);
       usLow1Byte  = inportb(usBase+counter+8);      /* read low byte */
       usHigh1Byte = inportb(usBase+counter+8);      /* read high byte */
    }
    else              // configure 8254 chip 4
    {
       outportb(usBase+15, usCtr1Byte);
       usLow1Byte  = inportb(usBase+(counter%3)+12); /* read low byte */
       usHigh1Byte = inportb(usBase+(counter%3)+12); /* read high byte */
    }

    // second: delay time 1/2
    delay(usDelay/2);

    // third: read counter again
    usCtr1Byte = usCtrByte | 0;      /* set control byte for read mode */

    if (counter < 3)  // configure 8254 chip 3
    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -