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

📄 dpc.c

📁 ir 驱动程序源代码,make成功了,有兴趣的朋友可以看看
💻 C
📖 第 1 页 / 共 4 页
字号:

            if (lastSampleOn == curSample->On) {

                //
                // This is the previous on or off sample
                //  overflowing into the next byte.
                //
                // Add the current sample value into the
                //  previous result. Note that this will ONLY
                //  happen when bitsConsumed == 8. What it means
                //  is that we've overflown from the last bits
                //  of the previous byte into the first bits
                //  of this byte.
                //
                ASSERT(bitsConsumed == 8);
                resultPtr[samples-1] += curSample->Result;

            } else {

                resultPtr[samples++] = curSample->Result;

            }

            //
            // Subtract the number of bits that this run
            //  consumed from the sample...
            //
            bitsConsumed -= curSample->BitsConsumed;
            lastSampleOn = curSample->On;
            curSample++;

        }

    }


    //
    // Store away the last piece of this
    //  report...
    //
    lastRLCPiece = resultPtr[samples-1];
    
    //
    // We possibly won't be passing that to the class driver...
    //
    resultLen = ((samples-1) * sizeof(LONG));
    

    //
    // Was the last piece of the previous calculation
    //  the same sign as the first piece of this 
    //  report?
    //
    if ((RLCReceiver->LastRLCPieceOfPreviousPacket < 0 && resultPtr[0] < 0) ||
        (RLCReceiver->LastRLCPieceOfPreviousPacket > 0 && resultPtr[0] > 0)) {
        
        //
        // join pieces
        //
        resultPtr[0] += RLCReceiver->LastRLCPieceOfPreviousPacket;

        //
        // Watch out for the case where we only had one sample. If
        //  we did then the last RLC piece needs to be modified
        //
        if (samples == 1) {
            lastRLCPiece = resultPtr[0];
        }

    } else if (RLCReceiver->LastRLCPieceOfPreviousPacket) {
        
        //
        // Nope, it was different. We need to 
        //  adjust the result pointer to be the 
        //  beginning of the buffer, give the last
        //  piece of the previous calculation to the user,
        //  and bump the amount of bytes we'll be sending...
        //
        // Note that this does not take into account the
        //  "lastRLCPiece" that we've saved off above, that's
        //  the last piece of THIS packet (which we may add 
        //  back in if this is a data end)
        //
        resultPtr = &RLCReceiver->DeviceData->RLCResultBuffer[0];
        resultPtr[0] = RLCReceiver->LastRLCPieceOfPreviousPacket;
        resultLen += sizeof(LONG);
        
    }

    //
    // For some unknown reason, we get a 50 uSec period of
    // silence from the SIO1049 the first time we turn on the 
    // learning receiver.  If we hit this, skip it.
    //
    if ( RLCReceiver->IgnoreFirstSilence &&
            resultLen >= sizeof(LONG) ) {

        
        if ( resultPtr[0] < 0 ) {
            resultPtr++;
            resultLen -= sizeof(LONG);
            }
        //
        // Turn off this flag even if we don't get the silence.
        // We're trying to skip the _first_ period of silence, 
        // not every period of silence.
        //
        RLCReceiver->IgnoreFirstSilence = FALSE;
        
        }
    
    if (!DataEnd) {

        //
        // Not done yet? Store away the last piece, we'll get to it in the 
        //  next pass.
        //
        RLCReceiver->LastRLCPieceOfPreviousPacket = lastRLCPiece;

    } else {

        //
        // DONE! Up the count of samples taken, this causes it to 
        //  include the lastRLCPiece in our return...
        //
        resultLen += sizeof(LONG);

        //
        // Start over...
        //
        RLCReceiver->LastRLCPieceOfPreviousPacket = 0;



    }


    SmscIrEnqueueRLCData(RLCReceiver,
                         (PUCHAR)resultPtr,
                         resultLen,
                         DataEnd);


}

VOID 
__forceinline
SmscIrEnqueueRLCData(
    PSMSCIR_RLC_RECEIVER RLCReceiver,
    __in_bcount(Length) PUCHAR RLCData,
    ULONG Length,
    IN BOOLEAN DataEnd
    ) {

/*++

Routine Description:

    This routine puts the given RLC data into the 
    circular buffer that the class driver requests
    are satisfied from

    RLCReceiver is *LOCKED* by caller on entry 

Arguments:

    RLCReceiver - The holder for either regular IR 
                    receivers or priority IR receivers

    RLCData        - The RLC data
             
    ReportLength  - Number of bytes to enqueue
    
    DataEnd       - Is this a data end?

--*/
    ULONG amountToCopy;

    ASSERT(Length < RLC_RECEIVER_BUFFER_LENGTH);

    if (!RLCReceiver->OpenCount) {
        return;
    }

    RLCReceiver->CurrentBufferSize += Length;
    
    if (RLCReceiver->NextIndex+Length > RLC_RECEIVER_BUFFER_LENGTH) {
        // Wrap past end of buffer
        RtlCopyMemory(RLCReceiver->RLCBuffer + RLCReceiver->NextIndex,
                      RLCData,
                      RLC_RECEIVER_BUFFER_LENGTH - RLCReceiver->NextIndex);
        //
        // Prefast will complain about this calculation, but it is 
        //  correct.
        //
        amountToCopy = (RLC_RECEIVER_BUFFER_LENGTH - RLCReceiver->NextIndex);
#pragma prefast (suppress:412, "Calculation is correct and as designed")
        RtlCopyMemory(RLCReceiver->RLCBuffer,
                      RLCData+amountToCopy,
                      Length-amountToCopy);
        RLCReceiver->NextIndex = (Length - amountToCopy);
    } else {
        RtlCopyMemory(RLCReceiver->RLCBuffer + RLCReceiver->NextIndex, 
                      RLCData,
                      Length);
        RLCReceiver->NextIndex = 
            (RLCReceiver->NextIndex + Length == RLC_RECEIVER_BUFFER_LENGTH) ?
                                             0 : RLCReceiver->NextIndex+Length;
    }

    if (RLCReceiver->CurrentBufferSize > RLC_RECEIVER_BUFFER_LENGTH) {
        RLCReceiver->CurrentBufferSize = RLC_RECEIVER_BUFFER_LENGTH;
        RLCReceiver->CurrentIndex = (RLCReceiver->NextIndex != 0) ?
                                              RLCReceiver->NextIndex-1 :
                                                  RLC_RECEIVER_BUFFER_LENGTH-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 (RLCReceiver->BytesToDataEnd) {
            SmscIrTracePrint(
                    TRACE_LEVEL_INFORMATION,
                    SMSCDBG_RECEIVE_INFO,
                    ("SmscIrEnqueueRLCData: DataEnd was already present. "
                     "Previous KeyUp missed"));
        }

        RLCReceiver->BytesToDataEnd = RLCReceiver->CurrentBufferSize;

    }

}


ULONG 
SmscIrDequeueRLCData(
    PSMSCIR_RLC_RECEIVER RLCReceiver,
    __out_bcount(MaxLen) PUCHAR Buffer,
    ULONG MaxLen,
    __out PBOOLEAN DataEnd
    ) {
/*++

Routine Description:

    This routine pulls RLC data out of the given receiver
    and stores it in the given buffer

    RLCReceiver is *LOCKED* by caller on entry 

Arguments:

   
    RLCReceiver - The holder for either regular IR 
                    receivers or priority IR receivers

    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;
#if DBG
    ULONG prevValue;
#endif

    *DataEnd = FALSE;

    if (0 == RLCReceiver->CurrentBufferSize){
        return 0;
    } else {


        if (RLCReceiver->BytesToDataEnd) {
            bufferSize = RLCReceiver->BytesToDataEnd;
        } else {
            bufferSize = RLCReceiver->CurrentBufferSize;
        }

        amountToCopy = bufferSize < MaxLen ? bufferSize : MaxLen;

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

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

            RLCReceiver->BytesToDataEnd -= amountToCopy;

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

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

        }

#if DBG
        prevValue = RLCReceiver->CurrentBufferSize;
#endif
        RLCReceiver->CurrentBufferSize -= amountToCopy;

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

        return amountToCopy;
    }
}

NTSTATUS
IrSetupNextRequest(
    IN PSMSCIR_RLC_RECEIVER RLCReceiver,
    OUT WDFREQUEST *CompleteWithFailure,
    OUT PNTSTATUS FailureStatus
    ) {
/*++

Routine Description:

    This routine dequeues the next pending request from the receiver
    queue and makes it the active/current request

    RLCReceiver is *LOCKED* by caller on entry 

Arguments:

    RLCReceiver         - Circular buffer for this IR data

    CompleteWithFailure - In case of error, the request to complete 
                          with *FailureStatus by the caller once the 
                          lock is dropped

    FailureStatus       - If *CompleteWithFailure != NULL, failure
                          status of request.

--*/
    NTSTATUS   status;
    WDFREQUEST nextRequest;

    status = WdfIoQueueRetrieveNextRequest(RLCReceiver->PendingReceiveQueue,
                                           &nextRequest);

    if (NT_SUCCESS(status)) {
                
        //
        // We have to get slightly different parameters
        //  based on this being a priority IR data buffer or not
        //
        if (!RLCReceiver->IsPriorityReceiver) {
                
            status = IrSetupCurrentReceive(RLCReceiver,
                                           nextRequest);
        } else {

            status = IrSetupCurrentPriorityReceive(RLCReceiver,
                                                   nextRequest);

        }

⌨️ 快捷键说明

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