📄 smscir.h
字号:
}BIRCC2_LINE_CONTROL, *PBIRCC2_LINE_CONTROL;
//
// BIRCC2_DOWN_COUNTER_CONTROL_ADDR
//
typedef struct _BIRCC2_DOWN_COUNTER_CONTROL {
union {
struct {
UCHAR DownCounterEnable : 1;
UCHAR Reserved : 7;
};
UCHAR AsUChar;
};
}BIRCC2_DOWN_COUNTER_CONTROL, *PBIRCC2_DOWN_COUNTER_CONTROL;
//
// BIRCC2_TX_CHANNEL_ENABLES_ADDR
//
typedef struct _BIRCC2_TX_CHANNEL_ENABLES {
union {
struct {
UCHAR TxChannel0Enable : 1;
UCHAR TxChannel1Enable : 1;
UCHAR TxChannel2Enable : 1;
UCHAR TxChannel3Enable : 1;
UCHAR TxEmitter0Present : 1;
UCHAR TxEmitter1Present : 1;
UCHAR TxEmitter2Present : 1;
UCHAR TxEmitter3Present : 1;
};
UCHAR AsUChar;
};
}BIRCC2_TX_CHANNEL_ENABLES, *PBIRCC2_TX_CHANNEL_ENABLES;
//
// BIRCC2_MODE_ADDR
//
typedef struct _BIRCC2_MODE {
union {
struct {
UCHAR CarrierOff : 1;
UCHAR RawMode : 1;
UCHAR Reserved : 6;
};
UCHAR AsUChar;
};
}BIRCC2_MODE, *PBIRCC2_MODE;
#include <poppack.h>
//
// Returns TRUE if the given bit is set in the byte, FALSE
// otherwise
//
#define BIT_ON(_BYTE_, _BIT_) (((_BYTE_) & (1 << (_BIT_))) ? TRUE : FALSE)
//
// This macro will turn the carrier frequency
// divider value in the CIRCC2_CONSUMER_IR_CARRIER
// register into a carrier frequency in Hz
//
#define SMSCIR_CFD_TO_HZ(_CFD_) (1600000/((_CFD_)+1))
//
// Turn a usec Period value into an Frequency in KHz
//
#define SMSCIR_USEC_P_TO_KHZ_F(_PERIOD_) (1000/(_PERIOD_))
//
// Now we need to be able to take a KHz frequency and turn
// it into a CFD (CIRCC2_CONSUMER_IR_CARRIER) value.
//
#define SMSCIR_KHZ_TO_CFD(_KHZ_) ((1600/(_KHZ_))-1)
//
// Macro to convert the value in CIRCC2_CARRIER_CAPTURE_MEASURE to
// a kHZ frequency
//
#define SMSCIR_C_C_MEASURE_TO_KHZ_F(_CCM_) ((1600 / ((_CCM_) / 2)) * 1000)
//
// See runtables. for an explanation of this struct's usage
//
typedef struct _SAMPLE_RUN {
LONG Result;
LONG BitsConsumed;
BOOLEAN On;
}SAMPLE_RUN, *PSAMPLE_RUN;
//
// Some config constants
//
#define DEVCAPS_NUM_RECEIVE_PORTS 2
#define DEVCAPS_LEARNING_INDEX 1
#define DEVCAPS_LEARNING_MASK 2
#define DEVCAPS_TRANSMIT_PORTS 4
//
// Receive thresholds are negative, we'll set
// this to fill the FIFO entirely before interrupting
// to let us know
//
#define FIFO_THRESHOLD_FOR_RECEIVE ((UCHAR)-31)
//
// +0 for transmit numbers. We'll set this so that we
// have to full the FIFO entirely before blasting
//
#define FIFO_THRESHOLD_FOR_TRANSMIT 0
//
// The class driver wants samples at a rate of 20kHz.
// According to Table 2.3, this requires a bit
// rate divider of 4.
//
#define SMSCIR_BIT_RATE_DIVIDER 4
//
// The number of consecutive FFs that we need to
// see before we mark it as a data end by default
//
#define SMSCIR_NUM_FFS_FOR_DATA_END 250
//
// Size of the FIFO on the CIRCC2 device
//
#define SMSCIR_FIFO_SIZE 32
//
// The maximum buffer size that we're willing to use
// as a local for FIFO data storage
//
#define SMSCIR_MAX_LOCAL_BUFFER_SIZE (SMSCIR_FIFO_SIZE * 2)
//
// Sampling period to use by default for IR port drivers
//
#define IR_SAMPLE_PERIOD 50
//
// Size of the circular buffer used to hold bytes pulled out
// of the RX fifo
//
#define SMSCIR_FIFO_BUFFER_SIZE 0x1000
//
// Buffer size that we'll use as our circular buffer of
// RLC data for the class driver
//
#define RLC_RECEIVER_BUFFER_LENGTH 0x3000
//
// Period for our blasting deadman timer (in millisec)
//
#define SMSCIR_DEADMAN_TIMER_PERIOD 1500
//
// We support wake from various different protocols.
// First we'll define a structure that contains
// all the information we'll need to program the
// device. We;ll then define constants for the
// fields for currently supported protocols.
//
typedef struct _SMSCIR_ARM_FOR_WAKE_DATA {
//
// CIRCC2_CONSUMER_IR_CARRIER for this protocol
//
UCHAR CarrierDivider;
//
// CIRCC2_CONSUMER_IR_BIT_RATE for this protocol
//
UCHAR BitRateDivider;
//
// CIRCC2_CUSTOM_CODE
//
UCHAR CustomCode;
//
// CIRCC2_CUSTOM_CODE_PRIME
//
UCHAR CustomCodePrime;
//
// CIRCC2_DATA_CODE
//
UCHAR DataCode;
//
// CIRCC2_CONSUMER_PROTOCOL_SELECT
//
UCHAR ProtocolSelect;
//
// CIRCC2_HEADER_VALUE_AND_MASK
//
UCHAR HeaderValueAndMask;
//
// CIRCC2_DATA_VALUE_1
//
UCHAR DataValue1;
//
// CIRCC2_DATA_MASK_1
//
UCHAR DataMask1;
//
// CIRCC2_DATA_VALUE_2
//
UCHAR DataValue2;
//
// CIRCC2_DATA_MASK_2
//
UCHAR DataMask2;
//
// CIRCC2_DATA_VALUE_3
//
UCHAR DataValue3;
//
// CIRCC2_DATA_MASK_3
//
UCHAR DataMask3;
//
// CIRCC2_DATA_VALUE_4
//
UCHAR DataValue4;
//
// CIRCC2_DATA_MASK_4
//
UCHAR DataMask4;
//
// CIRCC2_DATA_VALUE_5
//
UCHAR DataValue5;
//
// CIRCC2_DATA_MASK_5
//
UCHAR DataMask5;
}SMSCIR_ARM_FOR_WAKE_DATA, *PSMSCIR_ARM_FOR_WAKE_DATA;
//
// Constants for the fields in the SMSCIR_ARM_FOR_WAKE_DATA
// for known protocols to wake via the POWER button.
//
//
/////////////////////
// RC6 WAKE FIELDS //
/////////////////////
#define SMSCIR_RC6_CARRIER_DIVIDER 0x2B // 2:1
#define SMSCIR_RC6_BIT_RATE_DIVIDER 0x2B // 2:2
#define SMSCIR_RC6_CUSTOM_CODE 0x80 // 2:3
#define SMSCIR_RC6_CUSTOM_CODE_PRIME 0x0F // 2:4
#define SMSCIR_RC6_DATA_CODE 0x00 // 2:5
#define SMSCIR_RC6_PROTOCOL_SELECT 0x03 // 2:6
#define SMSCIR_RC6_HEADER_VALUE_AND_MASK 0x0C // 6:0
#define SMSCIR_RC6_DATA_VALUE_1 0x04 // 6:1
#define SMSCIR_RC6_DATA_MASK_1 0x80 // 6:2
#define SMSCIR_RC6_DATA_VALUE_2 0x0C // 6:3
#define SMSCIR_RC6_DATA_MASK_2 0x00 // 6:4
#define SMSCIR_RC6_DATA_VALUE_3 0x00 // 6:5
#define SMSCIR_RC6_DATA_MASK_3 0xFF // 6:6
#define SMSCIR_RC6_DATA_VALUE_4 0x00 // 7:0
#define SMSCIR_RC6_DATA_MASK_4 0x00 // 7:1
#define SMSCIR_RC6_DATA_VALUE_5 0x00 // 7:2
#define SMSCIR_RC6_DATA_MASK_5 0x00 // 7:3
/////////////////////
// RC5 WAKE FIELDS //
/////////////////////
#define SMSCIR_RC5_CARRIER_DIVIDER 0x2B // 2:1
#define SMSCIR_RC5_BIT_RATE_DIVIDER 0x58 // 2:2
#define SMSCIR_RC5_CUSTOM_CODE 0x00 // 2:3
#define SMSCIR_RC5_CUSTOM_CODE_PRIME 0x00 // 2:4
#define SMSCIR_RC5_DATA_CODE 0x00 // 2:5
#define SMSCIR_RC5_PROTOCOL_SELECT 0x02 // 2:6
#define SMSCIR_RC5_HEADER_VALUE_AND_MASK 0xF0 // 6:0
#define SMSCIR_RC5_DATA_VALUE_1 0x0C // 6:1
#define SMSCIR_RC5_DATA_MASK_1 0xC0 // 6:2
#define SMSCIR_RC5_DATA_VALUE_2 0x00 // 6:3
#define SMSCIR_RC5_DATA_MASK_2 0x00 // 6:4
#define SMSCIR_RC5_DATA_VALUE_3 0x00 // 6:5
#define SMSCIR_RC5_DATA_MASK_3 0x00 // 6:6
#define SMSCIR_RC5_DATA_VALUE_4 0x00 // 7:0
#define SMSCIR_RC5_DATA_MASK_4 0x00 // 7:1
#define SMSCIR_RC5_DATA_VALUE_5 0x00 // 7:2
#define SMSCIR_RC5_DATA_MASK_5 0x00 // 7:3
/////////////////////
// NEC WAKE FIELDS //
/////////////////////
#define SMSCIR_NEC_CARRIER_DIVIDER 0x29 // 2:1
#define SMSCIR_NEC_BIT_RATE_DIVIDER 0x37 // 2:2
#define SMSCIR_NEC_CUSTOM_CODE 0x45 // 2:3
#define SMSCIR_NEC_CUSTOM_CODE_PRIME 0xBA // 2:4
#define SMSCIR_NEC_DATA_CODE 0x12 // 2:5
#define SMSCIR_NEC_PROTOCOL_SELECT 0x80 // 2:6
#define SMSCIR_NEC_HEADER_VALUE_AND_MASK 0x00 // 6:0
#define SMSCIR_NEC_DATA_VALUE_1 0x00 // 6:1
#define SMSCIR_NEC_DATA_MASK_1 0x00 // 6:2
#define SMSCIR_NEC_DATA_VALUE_2 0x00 // 6:3
#define SMSCIR_NEC_DATA_MASK_2 0x00 // 6:4
#define SMSCIR_NEC_DATA_VALUE_3 0x00 // 6:5
#define SMSCIR_NEC_DATA_MASK_3 0x00 // 6:6
#define SMSCIR_NEC_DATA_VALUE_4 0x00 // 7:0
#define SMSCIR_NEC_DATA_MASK_4 0x00 // 7:1
#define SMSCIR_NEC_DATA_VALUE_5 0x00 // 7:2
#define SMSCIR_NEC_DATA_MASK_5 0x00 // 7:3
//
// Location of configured wake key in the registry
//
#define SMSCIR_POWER_KEY_SUBKEY L"PowerKey"
#define SMSCIR_POWER_KEY_VALUE L"PowerKey"
//
// A container that holds RLC data to be returned
// to the class driver or a "priority" user mode
// reader. It holds not only the RLC data to return,
// but also the current receive requent and the
// list of queued receive requests
//
typedef struct _SMSCIR_RLC_RECEIVER {
//
// Is this the priority receiver?
//
BOOLEAN IsPriorityReceiver;
//
// Buffer to hold the RLC data produced by the device/driver
//
UCHAR RLCBuffer[RLC_RECEIVER_BUFFER_LENGTH];
//
// CurrentBufferSize is the amount of RLC data held by the receiver
//
ULONG CurrentBufferSize;
//
// We need to keep track of the point in the buffer
// where a DataEnd exists. When copying out of the
// receiver, we'll use this (if set) to determine the
// amount of bytes to copy out and give to the caller in
// place of the CurrentBufferSize
//
ULONG BytesToDataEnd;
//
// The RLCBuffer is circular, so this is where the next data should
// be queued starting from
//
ULONG NextIndex;
//
// When copying data out of the receiver, this is the place to look
//
ULONG CurrentIndex;
//
// Spinlock for the receiver
//
KSPIN_LOCK ListSpinLock;
//
// Number of readers. Currently only support ONE reader.
//
LONG OpenCount;
//
// Queue of pending readers
//
WDFQUEUE PendingReceiveQueue;
//
// The currently active reader. Stays active until the
// buffer is exhausted or a data end occurs
//
WDFREQUEST CurrentIrReceiveRequest;
//
// Data buffer for the CurrentIrReceiveRequest
//
PUCHAR ReceiveBuffer;
//
// Size of the data buffer for the CurrentIrReceiveRequest
//
ULONG ReceiveBufferSize;
//
// Amount of data copied into the CurrentIrReceiveRequest
//
ULONG ReceiveCurrentOffset;
union {
//
// The parameters passed to the CurrentIrReceiveRequest.
// Which one is used is based on the IsPriorityReceiver
// flag
//
PIR_RECEIVE_PARAMS ReceiveParams;
PIR_PRIORITY_RECEIVE_PARAMS PriorityReceiveParams;
};
//
// Every time we calculate RLC, we save the last piece and
// don't give it to the reader immediately. See isr_dpc.c
//
LONG LastRLCPieceOfPreviousPacket;
//
// Backpointer to the device extension
//
struct _SMSCIR_DATA* DeviceData;
//
// Should we ignore the first period of silence?
//
BOOLEAN IgnoreFirstSilence;
}SMSCIR_RLC_RECEIVER, *PSMSCIR_RLC_RECEIVER;
#define SMSCIR_INITIALIZE_RECEIVER(__PRCV__, __DEVDATA__, __ISPRIORITY__) { \
(__PRCV__)->IsPriorityReceiver = (__ISPRIORITY__); \
(__PRCV__)->DeviceData = (__DEVDATA__); \
(__PRCV__)->OpenCount = 0; \
(__PRCV__)->CurrentBufferSize = 0; \
(__PRCV__)->CurrentIndex = 0; \
(__PRCV__)->NextIndex = 0; \
KeInitializeSpinLock(&(__PRCV__)->ListSpinLock); \
} \
#define SMSCIR_RESET_RECEIVER(__PRCV__) { \
(__PRCV__)->CurrentBufferSize = 0; \
(__PRCV__)->BytesToDataEnd = 0; \
(__PRCV__)->CurrentIndex = 0; \
(__PRCV__)->NextIndex = 0; \
(__PRCV__)->LastRLCPieceOfPreviousPacket = 0; \
(__PRCV__)->IgnoreFirstSilence = FALSE; \
} \
//
// Data structure used for blasting.
//
// When we receive a TRANSMIT request from the user, it
// will be in RLC format. The first thing we'll need to/
// do is unpack that RLC data into data that is appropriate
// for our FIFO. This FIFO data will be described by a list
// of SMSCIR_TX_FIFO_DATA structures
//
typedef struct _SMSCIR_TX_FIFO_DATA {
LIST_ENTRY ListEntry;
//
// Length of the FifoBuffer field. This will always
// be a multiple of the FIFO size
//
ULONG FifoBufferLength;
//
// How much of FifoBuffer we've blasted so far
//
ULONG CurrentOffset;
//
// Number of times to repeat blasting the data in
// FifoBuffer
//
ULONG RepeatCount;
//
// Number of times we've repeated the data in FifoBuffer
//
ULONG TimesRepeated;
//
// The RLC data converted into ON/OFF bit samples
//
UCHAR FifoBuffer[1];
}SMSCIR_TX_FIFO_DATA, *PSMSCIR_TX_FIFO_DATA;
//
// The device extension
//
typedef struct _SMSCIR_DATA {
//
// Our WDFDRIVER object
//
WDFDRIVER WdfDriverObject;
//
// Need a pointer to our interrupt object so that
// we can acquire our interrupt spinlock
//
WDFINTERRUPT Interrupt;
//
// Base address for the ports we used to communicate
// with our device
//
PUCHAR BaseAddress;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -