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

📄 isr.c

📁 ir 驱动程序源代码,make成功了,有兴趣的朋友可以看看
💻 C
📖 第 1 页 / 共 2 页
字号:
                DeviceData->ConsecutiveFFs++;
            
            } else {
            
                //
                // Reset!
                //
                DeviceData->ConsecutiveFFs = 0;
            }
        
            bytesDequeued++;

        }
        
    }

    lsr.AsUChar = READ_HARDWARE_UCHAR(DeviceData,
                                      CIRCC2_LINE_STATUS_R);


    //
    // End of IR data or have we trashed the FIFO? If we 
    //  trashed the FIFO then the safest thing to do is
    //  just abort the keypress and start over, which we'll
    //  do...
    //
    if ((DeviceData->ConsecutiveFFs >= DeviceData->NumFFsForDataEnd) ||
        lsr.OverRun) {

            
        //
        // Indeed. Let's start this over...
        //
        DeviceData->ConsecutiveFFs = 0;
        
        //
        // Enqueue one more byte, this time indicate that
        //  we are indeed at the end fo the line with TRUE 
        //  for DataEnd...
        //
        SmscIrEnqueueFifoByte(DeviceData,
                              0xFF,
                              TRUE); 

            
        //
        // Once the receiver starts to collect IR
        //  data, it collects the samples from the actual
        //  IR stream and then continues to fill the FIFO 
        //  with FFs to indicate silence until we shut it 
        //  up. How do we shut it up, you ask? By disabling
        //  the IR receiver and then enabling it again, of 
        //  course...
        //
        // We'll reenable the receiver before we get out of here...
        //
        lcb.AsUChar = 0;
        WRITE_HARDWARE_UCHAR(DeviceData,
                             CIRCC2_LINE_CONTROL_B,
                             lcb.AsUChar);

        //
        // Dump any potential leftovers from the FIFO. 
        //
        lca.AsUChar = 0;
        lca.FifoReset = TRUE;
        
        WRITE_HARDWARE_UCHAR(DeviceData,
                             CIRCC2_LINE_CONTROL_A,
                             lca.AsUChar);

        //
        // If we're in priority mode we'll need to read
        //  the carrier measure register
        //
        if (DeviceData->InPriorityMode) {

            mbc.AsUChar = 0;
            mbc.RegisterBlockSelect = 5;
            WRITE_HARDWARE_UCHAR(DeviceData,
                                 CIRCC2_MASTER_BLOCK_CONTROL,
                                 mbc.AsUChar);

            carrierMeasure 
                    = READ_HARDWARE_UCHAR(DeviceData,
                                          CIRCC2_CARRIER_CAPTURE_MEASURE);

            if (carrierMeasure != 0) {
                
                DeviceData->CarrierMeasure = carrierMeasure;
                
            }

            //
            // Reset the carrier capture control
            //
            captureControl.AsUChar = 0;    
            captureControl.CaptureReset = TRUE;
            WRITE_HARDWARE_UCHAR(DeviceData,
                                 CIRCC2_CARRIER_CAPTURE_CONTROL,
                                 captureControl.AsUChar);

        }

        mbc.AsUChar = 0;
        mbc.ErrorReset = TRUE;
        WRITE_HARDWARE_UCHAR(DeviceData,
                             CIRCC2_MASTER_BLOCK_CONTROL,
                             mbc.AsUChar);
        mbc.AsUChar = 0;
        mbc.MasterInterruptEnable = TRUE;
        WRITE_HARDWARE_UCHAR(DeviceData,
                             CIRCC2_MASTER_BLOCK_CONTROL,
                             mbc.AsUChar);

             
    }

    //
    // Re-enable the FIFO interrupt
    //
    intEnable.AsUChar = 0;
    intEnable.Fifo    = TRUE;
    WRITE_HARDWARE_UCHAR(DeviceData,
                         CIRCC2_INTERRUPT_ENABLE,
                         intEnable.AsUChar);

    //
    // Set the device to receive.
    //
    lcb.AsUChar = 0;
    lcb.SCEModeBits = SCE_MODE_RECEIVE;
    WRITE_HARDWARE_UCHAR(DeviceData,
                         CIRCC2_LINE_CONTROL_B,
                         lcb.AsUChar);

    //
    // DPC required.
    //
    return TRUE;

}


BOOLEAN
__forceinline
SmscIrProcessTxInterrupt(
    PSMSCIR_DATA DeviceData,
    PBIRCC2_INTERRUPT_ID_OR_ENABLE TxIntId
    ) {

    BIRCC2_LINE_CONTROL    txLc;
    BIRCC2_INTERRUPT_ID_OR_ENABLE txIntEnable;


    //
    // Store away the interrupt mask
    //
    DeviceData->TxIntId.AsUChar |= TxIntId->AsUChar;

    if (TxIntId->Fifo) {
     
        //
        // Shut off the FIFO interrupt.
        //
        txIntEnable.AsUChar = 0;
        WRITE_TRANSMIT_UCHAR(DeviceData,
                             BIRCC2_INTERRUPT_ENABLE_ADDR,
                             txIntEnable.AsUChar);
        //
        // Need a DPC
        //
        return TRUE;

    }

    //
    // No FIFO interrupt...Check for an underrun
    //
    if (TxIntId->TxComplete) {
 
        txLc.AsUChar = READ_TRANSMIT_UCHAR(DeviceData,
                                           BIRCC2_LINE_CONTROL_ADDR);
        if (txLc.FifoNotEmpty &&
            !txLc.TxEnable) {
                
            //
            // Underrun...Provoke the DPC into continuing the
            //  processing...
            //
            DeviceData->TxIntId.Fifo = TRUE;

            
            //
            // And reset the FIFO
            //
            txLc.FifoReset = TRUE;
            WRITE_TRANSMIT_UCHAR(DeviceData,
                                 BIRCC2_LINE_CONTROL_ADDR,
                                 txLc.AsUChar);

        }

        return TRUE;

    }
    return FALSE;


}


__forceinline
VOID 
SmscIrEnqueueFifoByte(
    IN PSMSCIR_DATA FdoData,
    UCHAR Byte,
    IN BOOLEAN DataEnd
    ) {
/*++

Routine Description:

    Called from the ISR to move the byte taken from
    the FIFO into the circular buffer

Arguments:

    FdoData     - The device extension

    Byte        - The byte to store

    DataEnd     - Is this a data end?

--*/

    FdoData->CurrentFifoBufferSize++;
    
    FdoData->FifoBuffer[FdoData->NextFifoIndex++] = Byte;

    if (FdoData->NextFifoIndex == SMSCIR_FIFO_BUFFER_SIZE) {
        FdoData->NextFifoIndex = 0;
    }

    if (FdoData->CurrentFifoBufferSize > SMSCIR_FIFO_BUFFER_SIZE) {
        FdoData->CurrentFifoBufferSize = SMSCIR_FIFO_BUFFER_SIZE;
        FdoData->CurrentFifoIndex = (FdoData->NextFifoIndex != 0) 
                                           ? FdoData->NextFifoIndex-1  
                                                   : SMSCIR_FIFO_BUFFER_SIZE-1;
    }

    //
    // If this is a data end, then we'll set the watermark
    //  for the data end event. When the dequeue code comes
    //  in it will use this to know how to mark the 
    //  DataEnd member of the RECEIVE IOCTL.
    //
    if (DataEnd) {

        if (FdoData->BytesToDataEnd) {
            SmscIrTracePrint(
                    TRACE_LEVEL_INFORMATION,
                    SMSCDBG_RECEIVE_INFO,
                    ("SmscIrEnqueueFifoByte: DataEnd was already present. "\
                     "Previous KeyUp missed\n"));
        }

        FdoData->BytesToDataEnd = FdoData->CurrentFifoBufferSize;

    }

}


ULONG 
SmscIrFifoBytesRemaining(
    IN PSMSCIR_DATA DeviceData
    ) {
/*++

Routine Description:

    Returns the number of bytes remaining in the FIFO buffer


    *Interrupt Lock* held by caller on entry

Arguments:

    DeviceData     - The device extension

--*/

    if (DeviceData->BytesToDataEnd) {
        return DeviceData->BytesToDataEnd;
    } else {
        return DeviceData->CurrentFifoBufferSize;
    }

}



ULONG 
SmscIrDequeueFifoData(
    IN PSMSCIR_DATA DeviceData,
    __out_bcount(MaxLen) PUCHAR Buffer,
    ULONG MaxLen,
    __out PBOOLEAN DataEnd
    ) {
/*++

Routine Description:

    Called from the DPC to remove multiple bytes from
    the FIFO circular buffer

    *Interrupt Lock* held by caller on entry
    
Arguments:

    DeviceData - The device extension

    Buffer - Buffer to copy the data into
             
    MaxLen - Size of the Buffer parameter, in bytes

    DataEnd - Is this a data end?

Return Value:

    Actual number of bytes copied

--*/
    ULONG bufferSize;
    ULONG amountToCopy;
    ULONG nextIndex;
#if DBG
    ULONG prevValue;
#endif

    *DataEnd = FALSE;

    if (0 == DeviceData->CurrentFifoBufferSize){
        return 0;
    } else {

        if (DeviceData->BytesToDataEnd) {
            bufferSize = DeviceData->BytesToDataEnd;
        } else {
            bufferSize = DeviceData->CurrentFifoBufferSize;
        }

        amountToCopy = bufferSize < MaxLen ? bufferSize : MaxLen;

        if ((DeviceData->CurrentFifoIndex + amountToCopy) 
                                            > SMSCIR_FIFO_BUFFER_SIZE) {
            ULONG amountToCopyFirst 
                     = SMSCIR_FIFO_BUFFER_SIZE - DeviceData->CurrentFifoIndex;
            RtlCopyMemory(
                    Buffer, 
                    DeviceData->FifoBuffer + DeviceData->CurrentFifoIndex,
                    amountToCopyFirst);
            //
            // Prefast will complain about this calculation, but it is 
            //  correct.
            //
#pragma prefast (suppress:411, "Calculation is correct and as designed")
            RtlCopyMemory(Buffer + amountToCopyFirst, 
                          DeviceData->FifoBuffer,
                          amountToCopy - amountToCopyFirst);
            DeviceData->CurrentFifoIndex = amountToCopy - amountToCopyFirst;
        } else {
            RtlCopyMemory(
                    Buffer, 
                    DeviceData->FifoBuffer + DeviceData->CurrentFifoIndex,
                    amountToCopy);

            nextIndex = DeviceData->CurrentFifoIndex + amountToCopy;

            if (nextIndex == SMSCIR_FIFO_BUFFER_SIZE) {

                DeviceData->CurrentFifoIndex = 0;

            } else {

                DeviceData->CurrentFifoIndex = nextIndex;

            }

        }

        if (DeviceData->BytesToDataEnd) {
            
#if DBG
            prevValue = DeviceData->BytesToDataEnd;
#endif

            DeviceData->BytesToDataEnd -= amountToCopy;

#if DBG
            //
            // Make sure we didn't wrap under...
            //
            ASSERT(DeviceData->BytesToDataEnd < prevValue);
#endif

            *DataEnd = (BOOLEAN)(DeviceData->BytesToDataEnd == 0);

        }

#if DBG
        prevValue = DeviceData->CurrentFifoBufferSize;
#endif
        DeviceData->CurrentFifoBufferSize -= amountToCopy;

#if DBG
        //
        // Make sure we didn't wrap under...
        //
        ASSERT(DeviceData->CurrentFifoBufferSize < prevValue);
#endif


        return amountToCopy;
    }
}





NTSTATUS
SmscIrEvtInterruptDisable(
    IN WDFINTERRUPT Interrupt,
    IN WDFDEVICE    Device
    ) {
/*++

Routine Description.

    Called here to disable interrupts on the device. 

Arguments:

    Interrupt  - Our interrupt object

    Device     - The device to enable interrupts on

--*/
    MASTER_BLOCK_CONTROL mbc;
    PSMSCIR_DATA         deviceData;
    
    UNREFERENCED_PARAMETER(Interrupt);

    SmscIrTracePrint(TRACE_LEVEL_VERBOSE, 
                     SMSCDBG_INIT_INFO, 
                     ("SmscIrEvtInterruptDisable: Entered"));

    deviceData = (PSMSCIR_DATA)GetIrData(Device);

    //
    // Just disabling master interrupts is enough
    //  to quiesce the device and allow our driver
    //  to go away safely.
    //
    mbc.AsUChar = 0;
    WRITE_HARDWARE_UCHAR(deviceData,
                         CIRCC2_MASTER_BLOCK_CONTROL,
                         mbc.AsUChar);

    SmscIrTracePrint(TRACE_LEVEL_VERBOSE, 
                     SMSCDBG_INIT_INFO, 
                     ("SmscIrEvtInterruptDisable: Exited"));
    return STATUS_SUCCESS;

}


⌨️ 快捷键说明

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