📄 combi.c
字号:
return;
}
XmtBuff.bLength = 1; //set length of protocol
XmtBuff.p=&DeviceStatus.bProtocol; //aim XmtBuff at it
USB_control_read(); //initiate transfer
}
/*
**
** FUNCTION: GetConfiguration
**
** PURPOSE: Implements the Get Configuration command
**
** PARAMETERS: none
**
** DESCRIPTION:
** This routine is entered whenever a Get Configuration Request is received.
**
*/
void GetConfiguration(void)
{
if (ENDPOINT_A0_FIFO[USB_bmRequestType] != DEVICE_TO_HOST | STANDARD | DEVICE)
{
SET_EP0_MODE(USB_MODE_STALL_IN_OUT);
return;
}
XmtBuff.bLength = 1; //configuration is 1-byte long
XmtBuff.p=&DeviceStatus.bConfiguration; //point at it
USB_control_read(); //initiate transfer
}
/*
**
** FUNCTION: USB_Stall_In_Out
**
** PURPOSE: sets the SIE mode to stall IN/OUT packets on endpoint 0
**
** PARAMETERS: none
**
** DESCRIPTION:
**
**
*/
void USB_Stall_In_Out(void)
{
SET_EP0_MODE(USB_MODE_STALL_IN_OUT);
}
#pragma memory ORG @ 0x880
const void (* StandardFunctionTable[])(void)=
{
GetStatus,ClearFeature,USB_Stall_In_Out,SetFeature,
USB_Stall_In_Out,SetAddress,GetDescriptor,USB_Stall_In_Out,
GetConfiguration,SetConfiguration,GetStatus
};
/*
** define a lookup table of function pointers to class requests
*/
const void (* ClassFunctionTable[])(void)=
{
USB_Stall_In_Out, GetReport, GetIdle,GetProtocol,
USB_Stall_In_Out, USB_Stall_In_Out, USB_Stall_In_Out,USB_Stall_In_Out,
USB_Stall_In_Out, USB_Stall_In_Out, SetIdle,SetProtocol
};
/*
**
** FUNCTION: HandleSetup
**
** PURPOSE: Services Setup packets
**
** PARAMETERS: none
**
** DESCRIPTION:
** This routine is entered whenever an SETUP packet has come in on endpoint 0.
** it performss some preliminary validation on the packet, then
** parses the packet and calls the appropriate routine to handle the packet.
**
*/
void HandleSetup(void)
{
EP_A0_MODE = USB_MODE_NAK_IN_OUT; //unlock mode register
/*
** Setups are always 10 bytes, with DATAVALID = 1 and DATATOGGLE = 0
*/
if ( (EP_A0_COUNTER & (DATAVALID | DATATOGGLE | COUNT_MASK)) ==
(DATAVALID | 10))
{
if (ENDPOINT_A0_FIFO[USB_bmRequestType] & CLASS)
{
if (ENDPOINT_A0_FIFO[USB_bRequest] <= USB_SET_PROTOCOL) //class request, use class table
{
(*ClassFunctionTable[ENDPOINT_A0_FIFO[USB_bRequest]])();
return;
}
}
else
{
if (ENDPOINT_A0_FIFO[USB_bRequest] <= USB_GET_INTERFACE) //standard request, use standard table
{
(*StandardFunctionTable[ENDPOINT_A0_FIFO[USB_bRequest]])();
return;
}
}
}
SET_EP0_MODE(USB_MODE_STALL_IN_OUT); //invalid request, stall
}
//**************************************************************************************8
//PS2 routines
/*
**
** FUNCTION: ps2main
**
** PURPOSE: main processing loop for PS/2
**
** PARAMETERS: none
**
** DESCRIPTION:
** ps2main spins in an infinite loop waiting for an event that needs servicing.
*/
void ps2main(void)
{
char bInputByte; //storage for byte received from host
ReInitialize(); //reinitialize all ps2 variables to default states
SetDefault(); //set the host-settable parameters to the default states
EI(); //enable interrupts
ps2BAT(); //send the BAT code
/*
** only now can we enable the 128 usec interrupt, which will start filling the optics queue
** with data. ProcessOptics must be called at regular intervals from this point on, to prevent
** the optics queue from overflowing.
*/
GLOBAL_INTERRUPT = MILLISECOND_ENABLE | MICROSECOND_ENABLE;
while (1)
{
RESET_COP(); //always tickle watchdog
ProcessOptics(); //empty optics queue
bInputByte = GetByte(); //see if host has sent us anything
if (!(CC.C)) //if carry is clear, a byte indeed arrived)
{
ProcessCommand(bInputByte); //so go handle it
continue;
}
if (Ps2Xmt.bXmtLen) //anything to send?
{
PutNextByte(); //send a byte.
continue;
}
if (MsecStatus.b1msFlags & ONE_MSEC_FLAG) //1 msec expired?
{
MsecStatus.b1msFlags &= ~ONE_MSEC_FLAG;
Ps2MouseTask(); //do mouse stuff
}
}
}
/*
**
** FUNCTION: Ps2MouseTask
**
** PURPOSE: handles ps2 mouse data packet management
**
** PARAMETERS: none
**
** DESCRIPTION:
**
*/
void Ps2MouseTask(void)
{
if (!(MsecStatus.b1msCounter & 3)) //4 msec expired?
Mouse.bChange |= DebounceButtons(); //yes, debounce switches
if (!--bIntervalCount) //if the mouse interval counter has expired,
{
ResetInterval(); //reset the interval
if (MouseParms.bStream && MouseParms.bEnabled)
SendMouseData(); //if the mouse is enabled and in stream mode, send a packet
}
}
/*
**
** FUNCTION: Reinitialize
**
** PURPOSE: Reinitializes ps2 variables to their default states
**
** PARAMETERS: none
**
** DESCRIPTION:
**
*/
void ReInitialize(void)
{
DI(); //disable ints
USB_STATUS = (PS2_PULLUP_MASK | PS2_INTERRUPT_MODE_MASK |FORCE_NEG_OPEN_POS_OPEN);
RESET_COP(); //reset watchdog
ClearRam();
OpticsQueue.headP = bOpticsArray;
OpticsQueue.tailP = bOpticsArray;
PROCESSOR_STATUS &= ~(WATCHDOG_RESET_MASK //clear source of reset
| POWER_ON_RESET_MASK | USB_BUS_RESET_MASK);
USB_DEVICE_A = 0; //reset device address
EP_A0_MODE = USB_MODE_DISABLE; //disable endpoints from responding
EP_A1_MODE = USB_MODE_DISABLE;
EP_A2_MODE = USB_MODE_DISABLE;
GLOBAL_INTERRUPT = MILLISECOND_ENABLE; //enable only 1msec interrupt
return;
}
/*
**
** FUNCTION: ResetInterval
**
** PURPOSE: Resets the mouse report interval
**
** PARAMETERS: none
**
** DESCRIPTION: This routine resets the mouse's report interval to the value last
** sent by the host. The report interval is counted down in the main loop
** to provide a time base for sending mouse data packets.
**
*/
void ResetInterval(void)
{
bIntervalCount = MouseParms.bReportInterval;
}
/*
**
** FUNCTION: GetByte
**
** PURPOSE: tries to get a byte from the host
**
** PARAMETERS:
**
** DESCRIPTION: GetByte checks to see if the host is requesting-to-send data, and if so,
** clocks in a data byte from the host. It returns the received byte
** and implicitly sets the carry to 0 if the reception occurred without errors.
** GetByte turns off the 1msec interrupt during ps2 clocking so as not to
** impose the potential for clock jitter due to that interrupt.
**
**
*/
char GetByte (void)
{
char dummy;
if (HOST_RTS) //host not requesting to send
{
GLOBAL_INTERRUPT = MICROSECOND_ENABLE; //shut off msec interrupt
dummy = ps2_receive(); //get data. ps2_receive sets the carry
//to 1 if there was a problem in reception.
GLOBAL_INTERRUPT = MILLISECOND_ENABLE | MICROSECOND_ENABLE;
return(dummy); //return data (and carry bit too)
}
CC.C = 1; //couldn't get data, so set carry to one and exit
return(0);
}
/*
**
** FUNCTION: ps2BAT
**
** PURPOSE: delays for 500 msec, then sends the AA 00 initialization string
**
** PARAMETERS: none
**
** DESCRIPTION:
**
**
*/
void ps2BAT(void)
{
while (bBatDelay--) //count down number of msec in bBatDelay
{
while (!(MsecStatus.b1msFlags & ONE_MSEC_FLAG)) //eat up a msec
RESET_COP();
MsecStatus.b1msFlags &= ~ONE_MSEC_FLAG;
}
Ps2Xmt.bMsgBuff[0] = 0xAA; //send AA 00 to host
Ps2Xmt.bMsgBuff[1] = 00;
Ps2Xmt.bMsgLen = 2;
Ps2Xmt.bXmtLen = 2;
}
/*
**
** FUNCTION: PutNextByte
**
** PURPOSE: attempts to send the next byte in the transmit queue to the host
**
** PARAMETERS: none
**
** DESCRIPTION: This routine sends the next byte of the message buffer to the host.
**
**
*/
void PutNextByte(void)
{
if (HOST_RTS || HOST_INHIBIT) //host is requesting to send data, quit
return;
GLOBAL_INTERRUPT = MICROSECOND_ENABLE;
ps2_send(Ps2Xmt.bMsgBuff[Ps2Xmt.bMsgLen-Ps2Xmt.bXmtLen]); //send the byte
GLOBAL_INTERRUPT = MILLISECOND_ENABLE | MICROSECOND_ENABLE;
if (!CC.C)
Ps2Xmt.bXmtLen--;
}
/*
**
** FUNCTION: Put
**
** PURPOSE: sends a byte to the host
**
** PARAMETERS: data -- byte to send
**
** DESCRIPTION: Put attempts to send a byte to the host. It is called to send an ACK, ERROR, or RESEND
** to the host. In accordance with the IBM spec, these responses are not held for retransmission
** in the event that the host requests to send a byte before we can send the response itself.
** Thus, this routine waits for host inhibit to go away, then sends the byte. If the host
** requests-to-send before this happens, it simply returns without sending the byte.
**
**
*/
void Put(char data)
{
if(HOST_RTS)
return;
while (!HOST_RTS)
{
//we could sit in this loop for a long time, if the host is inhibiting us. This is ok.
//the 128 us interrupt is running and the optics queue might overflow, but that will
//be fixed up upon return to the main loop (see code in ProcessOptics). This is harmless --
//the mouse is supposed to be disabled by the host prior to executing commands, so
//we aren't required to be accumulating samples at this point, anyway.
if (!HOST_INHIBIT)
{
GLOBAL_INTERRUPT = MICROSECOND_ENABLE;
ps2_send(data); //send the byte
GLOBAL_INTERRUPT = MILLISECOND_ENABLE | MICROSECOND_ENABLE;
return; //ps2_send will set carry for us
}
RESET_COP();
}
}
/*
**
** FUNCTION: Reset
**
** PURPOSE: executes a reset
**
** PARAMETERS:
**
** DESCRIPTION: Reset simply gets into a loop waiting for the watchdog to perform a reset.
**
**
*/
void Reset(void)
{
GLOBAL_INTERRUPT = 0;
while (1); //death by watchdog
}
/*
**
** FUNCTION: Resend
**
** PURPOSE: Resends the last transmission from the mouse
**
** PARAMETERS: None
**
** DESCRIPTION: A copy of the last transmission is always left intact in the message buffer.
** To resend it , we simply need to reset the message length.
**
**
*/
void Resend(void)
{
Ps2Xmt.bXmtLen = Ps2Xmt.bMsgLen;
}
/*
**
** FUNCTION: SetDefault
**
** PURPOSE: Sets the mouse parameters to the default settings
**
** PARAMETERS:
**
** DESCRIPTION:
**
**
*/
void SetDefault(void)
{
MouseParms.bReportRate = 100; //100 reports per second
MouseParms.bReportInterval = 10; //is equal to a report every 10 msec
MouseParms.bScale = SC_1_1; //1-to-1 scaling
MouseParms.bStream = 1; //stream mode on
MouseParms.bResolution = RES_4MM; //4 MM resolution
MouseParms.bEnabled = 0; //not enabled
MouseParms.bZmouse = 0; //z-wheel off.
}
/*
**
** FUNCTION: Disable
**
** PURPOSE: Disables the mouse
**
** PARAMETERS:
**
** DESCRI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -