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

📄 smscir.h

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

    //
    // See pnp.c or READ/WRITE_HARDWARE_UCHAR
    //
    BOOLEAN                PortIsMapped;


    //
    // Resource information for TRANSMIT
    //
    PUCHAR                 TransmitBaseAddress;
    BOOLEAN                TransmitPortIsMapped;



    //
    // Has the class driver sent us the handshake IOCTL
    //  yet? Informational use only.
    // 
    BOOLEAN                HandshakeAccepted;

    //
    // When the device is in priority mode (due to the 
    //  receiving of an ENTER_PRIORITY_MODE IOCTL) 
    //  normal receives are starved while priority receives
    //  are processed. Once we exit priority mode (because
    //  of an EXIT_PRIORITY_MODE IOCTL) we cancel any
    //  outstanding priority receivers and switch back
    //  to normal receive mode.
    //
    BOOLEAN                InPriorityMode;

    //
    // The individual receiver containers
    // 
    SMSCIR_RLC_RECEIVER    Receiver;
    SMSCIR_RLC_RECEIVER    PriorityReceiver;
    
    //
    // The number of consecutive FFs (i.e. silence) we have seen 
    //  from the device after a receive has started. We use this
    //  to determine when a data end event occurs
    //
    ULONG                  ConsecutiveFFs;

    //
    // The number of FFs we need to see before we 
    //  consider the sample to be over. Defaults to 
    //  SMSCIR_NUM_FFS_FOR_DATA_END
    //
    ULONG                  NumFFsForDataEnd;


    //
    // There are several IOCTLs that we wish to process serially.
    //  Instead of taking out a lock to protect them against
    //  either the same IOCTL or other IOCTLs we wish to serialize
    //  against, we take request from our default parallel queue
    //  and forward them into our serial queue.
    //
    WDFQUEUE               SerialQueue;


    //
    // We need to loop in our ISR pulling data bytes out of
    //  our FIFO. Once we take a byte from the FIFO, we'll
    //  enqueue it onto a circular buffer one byte at a time
    //  The DPC will then run, take the raw FIFO data, RLC
    //  it, then enqueue it onto the currently active receiver.
    //
    // Note that we need to carry about the "BytesToDataEnd"
    //  field with us everywhere, the watermark is queued in 
    //  the FIFO buffer, then queued into the receiver buffer
    //  (see isr_dpc.c). 
    //
    UCHAR                  FifoBuffer[SMSCIR_FIFO_BUFFER_SIZE];
    ULONG                  CurrentFifoBufferSize;
    ULONG                  NextFifoIndex;
    ULONG                  CurrentFifoIndex;
    ULONG                  BytesToDataEnd;


    //
    // When we pull data from the CIRCC2 FIFO, we copy it
    //  into a SMSCIR_MAX_LOCAL_BUFFER_SIZE sized UCHAR array.
    //  When we RLC this data, we use this storage as the 
    //  worker buffer. The reason for the size is that in the
    //  worst case every byte will represent 8 on/off samples
    //  PLUS one more space for the previous sample (see isr_dpc.c)
    //
    LONG                   RLCResultBuffer[SMSCIR_MAX_LOCAL_BUFFER_SIZE * 9];

    //
    // If we're doing a learning operation (a.k.a. if we're in priority
    //  mode) then we'll need to return the carrier of the sampled
    //  IR to the reader. We'll get this info from the carrier measure
    //  register on the device, which we'll store here
    //
    UCHAR                  CarrierMeasure;

    //
    // When it comes time to blast, we're going to pre-convert the user
    //  data into something applicable for our device. We'll build
    //  the converted data into SMSCIR_TX_FIFO_DATA structures linked
    //  together via the TxFifoDataList field and protected by the 
    //  TxFifoDataLock. The structure currently being blasted is 
    //  both pointed to by CurrentTxFifoData and at the head
    //  of the TxFifoDataList
    //
    PSMSCIR_TX_FIFO_DATA   CurrentTxFifoData;
    LIST_ENTRY             TxFifoDataList;
    KSPIN_LOCK             TxFifoDataLock;
    
    //
    // We pend the user's blasting request so that we can do it 
    //  asynchronously. The pended reques tis here
    //
    WDFREQUEST             CurrentTxRequest;
    ULONG                  BytesTransmitted;

    //
    // Shadow copy of the last interrupt ID we received from the 
    //  transmitter
    //
    BIRCC2_INTERRUPT_ID_OR_ENABLE TxIntId;

    //
    // Blasting can have a tendency to underrun on a heavily loaded
    //  system. If an underrun occurs we can't necessarily detect
    //  it, so we must keep some sort of deadman in order to reset
    //  the device should something go wrong. When we first 
    //  start blasting we start the deadman and when the blasting
    //  is completed we end it. For every piece that we blast we
    //  update LastBlastSentTime in the DPC. If the device doesn't
    //  interrupt within X amount of time after that the deadman
    //  timer will notice and reset the transmitter (and potentially
    //  reset the receiver)
    //
    WDFTIMER               DeadManTimer;
    LARGE_INTEGER          LastBlastSentTime;


    //
    // The key used to wake the sytem via the CIR block is configurable.
    //  ArmForWakeData contains the information about which key will
    //  be used to wake the sytem
    //
    SMSCIR_ARM_FOR_WAKE_DATA ArmForWakeData;


}SMSCIR_DATA, *PSMSCIR_DATA;

WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(SMSCIR_DATA, GetIrData)



//
// Here we define the functions that we use to write to the device
// in a non-processor architecture specific way. We call the correct
// function based on whether the port is in memory or port space.  This is
// determined when we claim our resources.
//
// You might be concerned about the overhead incurred by using these functions.
// Note that we've declared them as "forceinline" which should result in code
// generation that's equivalent to a macro.  While this function adds a test
// for every read/write operation, that's the price we pay for not knowing
// until run-time whether our registers are in port or memory space.  Note that
// you can't directly call the appropriate function via a pointer, because
// you don't know if WRITE_REGISTER_UCHAR (for example) is implemented as a
// function or a macro on any given processor architecture (it's a macro on
// IA64, by the way).
//
__forceinline
VOID
WRITE_HARDWARE_UCHAR(PSMSCIR_DATA DevData, UCHAR Register, UCHAR Value)  {

    if(DevData->PortIsMapped) {
        WRITE_REGISTER_UCHAR(DevData->BaseAddress+Register, Value);
    } else  {
        WRITE_PORT_UCHAR(DevData->BaseAddress+Register, Value);
    }
}

__forceinline
UCHAR
READ_HARDWARE_UCHAR(PSMSCIR_DATA DevData, UCHAR Register)  {
    if(DevData->PortIsMapped) {
        return (READ_REGISTER_UCHAR(DevData->BaseAddress+Register));
    } else  {
        return (READ_PORT_UCHAR(DevData->BaseAddress+Register));
    }
}


__forceinline
VOID
WRITE_TRANSMIT_UCHAR(PSMSCIR_DATA DevData, UCHAR Register, UCHAR Value)  {

    if(DevData->TransmitPortIsMapped) {
        WRITE_REGISTER_UCHAR(DevData->TransmitBaseAddress+Register, Value);
    } else  {
        WRITE_PORT_UCHAR(DevData->TransmitBaseAddress+Register, Value);
    }
}

__forceinline
UCHAR
READ_TRANSMIT_UCHAR(PSMSCIR_DATA DevData, UCHAR Register)  {
    if(DevData->TransmitPortIsMapped) {
        return (READ_REGISTER_UCHAR(DevData->TransmitBaseAddress+Register));
    } else  {
        return (READ_PORT_UCHAR(DevData->TransmitBaseAddress+Register));
    }
}

__forceinline
VOID
WRITE_TRANSMIT_BUFFER_UCHAR(PSMSCIR_DATA DevData, 
                            UCHAR Register, 
                            PUCHAR Buffer,
                            ULONG Count){

    if(DevData->TransmitPortIsMapped) {

        ULONG i;
        //
        // Memory mapped I/O...Need to fake it.
        //
        for (i = 0; i < Count; i++) {
            WRITE_REGISTER_UCHAR(DevData->TransmitBaseAddress+Register, 
                                 Buffer[i]);
        }
    } else {
        WRITE_PORT_BUFFER_UCHAR(DevData->TransmitBaseAddress+Register, 
                                Buffer,
                                Count);
    }

}


//
// Handy Dandy Time Macros
//

#define ABSOLUTE(wait) (wait)

#define RELATIVE(wait) (-(wait))

#define NANOSECONDS(nanos) \
(((signed __int64)(nanos)) / 100L)

#define MICROSECONDS(micros) \
(((signed __int64)(micros)) * NANOSECONDS(1000L))

#define MILLISECONDS(milli) \
(((signed __int64)(milli)) * MICROSECONDS(1000L))

#define SECONDS(seconds) \
(((signed __int64)(seconds)) * MILLISECONDS(1000L))


//
// Shared globals
//
extern UNICODE_STRING SmscIrRegistryPath;
extern SAMPLE_RUN SmscIrSampleTable[256][8];

//
// Prototypes
//

//
// usbir.c
//
NTSTATUS 
DriverEntry(
    PDRIVER_OBJECT DriverObject, 
    PUNICODE_STRING RegistryPath
    );

VOID 
SmscIrEvtDriverUnload(
    WDFDRIVER Driver
    );

//
// io.c
//

VOID
SmscIrEvtIoDeviceControl(
    IN WDFQUEUE  Queue,
    IN WDFREQUEST  Request,
    IN size_t  OutputBufferLength,
    IN size_t  InputBufferLength,
    IN ULONG  IoControlCode
    );

VOID
SmscIrEvtDeviceFileCreate(
    IN WDFDEVICE            Device,
    IN WDFREQUEST           Request,
    IN WDFFILEOBJECT        FileObject
    );

VOID
SmscIrEvtFileClose(
    IN WDFFILEOBJECT    FileObject
    );

VOID
SmscIrEvtIoDeviceControlSerial(
    IN WDFQUEUE  Queue,
    IN WDFREQUEST  Request,
    IN size_t  OutputBufferLength,
    IN size_t  InputBufferLength,
    IN ULONG  IoControlCode
    );

VOID
IrHandshake(
    PSMSCIR_DATA DeviceData,
    WDFREQUEST Request
    );

VOID
IrReceive(
    PSMSCIR_DATA DeviceData,
    WDFREQUEST Request, 
    SIZE_T OutputBufferLength
    );

VOID
IrPriorityReceive(
    PSMSCIR_DATA DeviceData,
    WDFREQUEST Request, 
    SIZE_T OutputBufferLength
    );

VOID
IrTransmit(
    PSMSCIR_DATA DeviceData,
    WDFREQUEST Request, 
    SIZE_T OutputBufferLength, 
    SIZE_T InputBufferLength
    );

VOID
IrReceiveInProgressCancel(
    IN WDFREQUEST  Request
    );

VOID
IrPriorityReceiveInProgressCancel(
    IN WDFREQUEST  Request
    );


VOID
IrUserOpen(
    PSMSCIR_DATA DeviceData,
    WDFREQUEST Request
    );

VOID
IrUserClose(
    PSMSCIR_DATA DeviceData,
    WDFREQUEST Request
    );

VOID
IrEnterPriorityMode(
    PSMSCIR_DATA DeviceData,
    WDFREQUEST Request, 
    SIZE_T InputBufferLength
    );
VOID
IrExitPriorityMode(
    PSMSCIR_DATA DeviceData,
    WDFREQUEST Request
    );

VOID
IrGetDevCaps(
    PSMSCIR_DATA DeviceData,
    WDFREQUEST Request, 
    SIZE_T OutputBufferLength
    );

VOID
IrGetEmitters(
    PSMSCIR_DATA DeviceData,
    WDFREQUEST Request, 
    SIZE_T OutputBufferLength
    );

VOID
IrFlashReceiver(
    PSMSCIR_DATA DeviceData,
    WDFREQUEST Request, 
    SIZE_T InputBufferLength
    );

VOID
IrResetDevice(
    PSMSCIR_DATA DeviceData,
    WDFREQUEST Request
    );

//
// pnp.c
//
NTSTATUS
SmscIrEvtDeviceAdd(
    IN WDFDRIVER Driver,
    IN PWDFDEVICE_INIT DeviceInit
    );

NTSTATUS
SmscIrEvtDevicePrepareHardware(
    IN WDFDEVICE    Device,
    IN WDFCMRESLIST ResourceList,
    IN WDFCMRESLIST ResourceListTranslated
    );

NTSTATUS
SmscIrEvtDeviceReleaseHardware(
    IN WDFDEVICE    Device,
    IN WDFCMRESLIST ResourceListTranslated
    );

NTSTATUS
SmscIrEvtDeviceD0Entry(
    IN  WDFDEVICE Device,
    IN  WDF_POWER_DEVICE_STATE PreviousState
    );

NTSTATUS
SmscIrEvtDeviceD0Exit(
    IN  WDFDEVICE Device,
    IN  WDF_POWER_DEVICE_STATE TargetState
    );

//
// isr.c
//
NTSTATUS
SmscIrEvtInterruptEnable(
    IN WDFINTERRUPT Interrupt,
    IN WDFDEVICE    Device
    );

BOOLEAN
SmscIrEvtInterruptIsr(
    IN WDFINTERRUPT Interrupt,
    IN ULONG        MessageID
    );

ULONG 
SmscIrFifoBytesRemaining(
    IN PSMSCIR_DATA DeviceData
    );

ULONG 
SmscIrDequeueFifoData(
    IN PSMSCIR_DATA DeviceData,
    __out_bcount(MaxLen) PUCHAR Buffer,
    ULONG MaxLen,
    __out PBOOLEAN DataEnd
    );


NTSTATUS
SmscIrEvtInterruptDisable(
    IN WDFINTERRUPT Interrupt,
    IN WDFDEVICE    Device
    );


//
// Dpc.c
//
VOID
SmscIrEvtInterruptDpc(
    IN WDFINTERRUPT Interrupt,
    IN WDFOBJECT    Object
    );

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

ULONG 
SmscIrDequeueRLCData(
    PSMSCIR_RLC_RECEIVER RLCReceiver,
    __out_bcount(MaxLen) PUCHAR Buffer,
    ULONG MaxLen,
    __out PBOOLEAN DataEnd
    );

VOID
SmscIrProcessPendingReceives(
    IN PSMSCIR_RLC_RECEIVER RLCReceiver,
    __out WDFREQUEST *CompleteWithSuccess,
    __out WDFREQUEST *CompleteWithFailure,
    __out PNTSTATUS FailureStatus
    );

NTSTATUS
IrSetupNextRequest(
    IN PSMSCIR_RLC_RECEIVER RLCReceiver,
    OUT WDFREQUEST *CompleteWithFailure,
    OUT PNTSTATUS FailureStatus
    );

VOID
SmscIrContinueBlasting(
    IN PSMSCIR_DATA DeviceData,
    OUT WDFREQUEST *TxRequestToComplete,
    OUT PNTSTATUS CompletionStatus
    );

VOID
SmscIrEvtDeadManTimerForTransmit(
    IN WDFTIMER Timer
    );

//
// Wake.c
//
VOID
SmscIrSetWakeKeyInfo(
    IN PSMSCIR_DATA DeviceData
    );

NTSTATUS
SmscIrEvtDeviceWakeArm(
    IN WDFDEVICE Device
    );

BOOLEAN
SmscIrDeviceWokeSystem(
    IN PSMSCIR_DATA DeviceData
    );


#endif // ndef SmscIrH

⌨️ 快捷键说明

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