📄 cseries.c
字号:
--*/
{
LONG count;
PAGED_CODE();
Print(DeviceExtension, DBG_SS_TRACE, ("CSerSetBaudRate called\n"));
//
// Before we mess with the baud rate, put the mouse in prompt mode.
//
CSerSetReportRate(DeviceExtension, 0);
for (count = sizeofel(CserBaudRateTable) - 1; count >= 0; count--) {
if (BaudRate >= CserBaudRateTable[count].BaudRate) {
//
// Set the baud rate.
//
SerialMouseWriteString(DeviceExtension, CserBaudRateTable[count].Command);
SerialMouseSetBaudRate(DeviceExtension, CserBaudRateTable[count].BaudRate);
//
// Delay to allow the UART and the mouse to synchronize
// correctly.
//
SerialMouseWait(DeviceExtension,
-CSER_BAUDRATE_DELAY
);
break;
}
}
return;
}
PPROTOCOL_HANDLER
CSerSetProtocol(
PDEVICE_EXTENSION DeviceExtension,
UCHAR NewProtocol
)
/*++
Routine Description:
Change the mouse protocol.
Note: Not all the protocols are implemented in this driver.
Arguments:
Port - Pointer to the serial port.
Return Value:
Address of the protocol handler function. See the interrupt service
routine.
--*/
{
PAGED_CODE();
Print(DeviceExtension, DBG_SS_TRACE, ("CSerSetProtocol called\n"));
ASSERT(NewProtocol < CSER_PROTOCOL_MAX);
//
// Set the protocol.
//
SerialMouseWriteChar(DeviceExtension, Protocol[NewProtocol].Command);
SerialMouseSetLineCtrl(DeviceExtension, &Protocol[NewProtocol].LineCtrl);
Print(DeviceExtension, DBG_SS_INFO, ("NewProtocol: %u\n", NewProtocol & 0xFF));
return Protocol[NewProtocol].Handler;
}
BOOLEAN
CSerDetect(
PDEVICE_EXTENSION DeviceExtension,
PULONG HardwareButtons
)
/*++
Routine Description:
Detection of a CSeries type mouse. The main steps are:
- Power up the mouse.
- Cycle through the available baud rates and try to get an answer
from the mouse.
At the end of the routine, a default baud rate and report rate are set.
Arguments:
Port - Pointer to the serial port.
HardwareButtons - Returns the number of hardware buttons detected.
Return Value:
TRUE if a CSeries type mouse is detected, otherwise FALSE.
--*/
{
UCHAR status, numButtons;
ULONG count;
BOOLEAN detected = FALSE;
Print(DeviceExtension, DBG_SS_TRACE, ("CSerDetect called\n"));
//
// Power up the mouse if necessary.
//
CSerPowerUp(DeviceExtension);
//
// Set the line control register to a format that the mouse can
// understand (see below: the line is set after the report rate).
//
SerialMouseSetLineCtrl(DeviceExtension, &Protocol[CSER_PROTOCOL_MM].LineCtrl);
//
// Cycle through the different baud rates to detect the mouse.
//
for (count = 0; count < sizeofel(BaudRateDetect); count++) {
SerialMouseSetBaudRate(DeviceExtension, BaudRateDetect[count]);
//
// Put the mouse in prompt mode.
//
CSerSetReportRate(DeviceExtension, 0);
//
// Set the MM protocol. This way we get the mouse to talk to us in a
// specific format. This avoids receiving errors from the line
// register.
//
CSerSetProtocol(DeviceExtension, CSER_PROTOCOL_MM);
//
// Try to get the status byte.
//
SerialMouseWriteChar(DeviceExtension, CSER_STATUS_COMMAND);
//
// In case something is already there...
//
SerialMouseFlushReadBuffer(DeviceExtension);
SerialMouseSetReadTimeouts(DeviceExtension, 50);
//
// Read back the status character.
//
if (NT_SUCCESS(SerialMouseReadChar(DeviceExtension, &status)) &&
(status == CSER_STATUS)) {
detected = TRUE;
Print(DeviceExtension, DBG_SS_INFO,
("Detected mouse at %u baud\n",
BaudRateDetect[count]
));
break;
}
}
if (detected) {
//
// Get the number of buttons back from the mouse.
//
SerialMouseWriteChar(DeviceExtension, CSER_QUERY_BUTTONS_COMMAND);
//
// In case something is already there...
//
SerialMouseFlushReadBuffer(DeviceExtension);
//
// Read back the number of buttons.
//
SerialMouseSetReadTimeouts(DeviceExtension, CSER_STATUS_DELAY);
if (NT_SUCCESS(SerialMouseReadChar(DeviceExtension, &numButtons))) {
numButtons &= 0x0F;
Print(DeviceExtension, DBG_SS_NOISE,
("Successfully read number of buttons (%1u)\n", numButtons));
if (numButtons == 2 || numButtons == 3) {
*HardwareButtons = numButtons;
} else {
*HardwareButtons = MOUSE_NUMBER_OF_BUTTONS;
}
} else {
*HardwareButtons = MOUSE_NUMBER_OF_BUTTONS;
}
//
// Make sure that all subsequent reads are blocking and do not timeout
//
SerialMouseSetReadTimeouts(DeviceExtension, 0);
}
//
// Put the mouse back in a default mode. The protocol is already set.
//
CSerSetBaudRate(DeviceExtension, CSER_DEFAULT_BAUDRATE);
CSerSetReportRate(DeviceExtension, CSER_DEFAULT_REPORTRATE);
Print(DeviceExtension, DBG_SS_INFO,
("Detected: %s\n", detected ? "true" : "false"));
Print(DeviceExtension, DBG_SS_INFO, ("Status byte: %#x\n", status));
return detected;
}
BOOLEAN
CSerHandlerMM(
IN PDEVICE_EXTENSION DeviceExtension,
IN PMOUSE_INPUT_DATA CurrentInput,
IN PHANDLER_DATA HandlerData,
IN UCHAR Value,
IN UCHAR LineState)
/*++
Routine Description:
This is the protocol handler routine for the MM protocol.
Arguments:
CurrentInput - Pointer to the report packet.
Value - The input buffer value.
LineState - The serial port line state.
Return Value:
Returns TRUE if the handler has a completed report.
--*/
{
BOOLEAN retval = FALSE;
Print(DeviceExtension, DBG_HANDLER_TRACE, ("MMHandler, enter\n"));
if ((Value & CSER_SYNCH_BIT) && (HandlerData->State != STATE0)) {
HandlerData->Error++;
Print(DeviceExtension, DBG_HANDLER_ERROR,
("Synch error. State: %u\n",
HandlerData->State
));
HandlerData->State = STATE0;
}
else if (!(Value & CSER_SYNCH_BIT) && (HandlerData->State == STATE0)) {
HandlerData->Error++;
Print(DeviceExtension, DBG_HANDLER_ERROR,
("Synch error. State: %u\n",
HandlerData->State
));
goto LExit;
}
//
// Check for a line state error.
//
Print(DeviceExtension, DBG_HANDLER_INFO,
("State%u\n", HandlerData->State));
HandlerData->Raw[HandlerData->State] = Value;
switch (HandlerData->State) {
case STATE0:
case STATE1:
HandlerData->State++;
break;
case STATE2:
HandlerData->State = STATE0;
//
// Buttons formatting.
//
CurrentInput->RawButtons =
(HandlerData->Raw[STATE0] & CSER_BUTTON_LEFT) >> CSER_BUTTON_LEFT_SR;
CurrentInput->RawButtons |=
(HandlerData->Raw[STATE0] & CSER_BUTTON_RIGHT) << CSER_BUTTON_RIGHT_SL;
CurrentInput->RawButtons |=
(HandlerData->Raw[STATE0] & CSER_BUTTON_MIDDLE) << CSER_BUTTON_MIDDLE_SL;
//
// Displacement formatting.
//
CurrentInput->LastX = (HandlerData->Raw[STATE0] & SIGN_X) ?
HandlerData->Raw[STATE1] :
-(LONG)HandlerData->Raw[STATE1];
//
// Note: The Y displacement is positive to the south.
//
CurrentInput->LastY = (HandlerData->Raw[STATE0] & SIGN_Y) ?
-(LONG)HandlerData->Raw[STATE2] :
HandlerData->Raw[STATE2];
Print(DeviceExtension, DBG_HANDLER_NOISE,
("Displacement X: %ld\n",
CurrentInput->LastX
));
Print(DeviceExtension, DBG_HANDLER_NOISE,
("Displacement Y: %ld\n",
CurrentInput->LastY
));
Print(DeviceExtension, DBG_HANDLER_NOISE,
("Raw Buttons: %0lx\n",
CurrentInput->RawButtons
));
//
// The report is complete. Tell the interrupt handler to send it.
//
retval = TRUE;
break;
default:
Print(DeviceExtension, DBG_HANDLER_ERROR,
("MM Handler failure: incorrect state value.\n"));
ASSERT(FALSE);
}
LExit:
Print(DeviceExtension, DBG_HANDLER_TRACE, ("MMHandler, exit\n"));
return retval;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -