📄 combi.c
字号:
/*
**
** FILE: combi.c
**
**
** purpose: USB firmware for Cypress USB/PS2 mouse reference design
**
**
** revision history:
** 6/27/00 bth : modified ps2 scaling algorithm
** 7/11/00 sea : modified ps2 resolution constants and
** ps2_send() start bit inhibit response
**
*/
#pragma option INSTRUCTIONTIMING //needed for Cypress debugger to work properly
#pragma option f0 //do not insert page breaks in listing file
#pragma option REGSAVEOFF; //do not automatically save AC and IX in interrupts
#pragma option NOINIT;
#define DEBUG
#include "chip.h"
#include "usbdefs.h"
#include "ps2defs.h"
#define BIT0 1
#define BIT1 2
#define BIT2 4
#define BIT3 8
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80
//*************************************************************************************************
//USER_DEFINES
/*
**
** the following defines can be changed to accomodate different I/O pinouts. It is assumed that
** all 6 quadrature inputs (optics) are connected to the same port.
**
*/
#define OPTICS_PORT PORT0 //optics port
#define OPTICS_MASK 0x3f //mask of all optics inputs
/*
** for each set of x,y, and z optics, define a macro that will move the corresponding 2 quadrature bits
** into bit1 and bit0. For instance, in the reference design
** the y- quadrature inputs are at bits 3 and 2, so the macro shifts the bits by 2 and
** masks them.
*/
#define GET_X_OPTICS(x) ((x >> 0) & 0x3) //no shift necessary
#define GET_Y_OPTICS(x) ((x >> 2) & 0x3) //shift bits [3:2] into [1:0]
#define GET_Z_OPTICS(x) ((x >> 4) & 0x3) //shift bits [5:4] into [1:0]
/*
** define each switch's port and bit position
*/
#define LEFT_SWITCH_PORT PORT0
#define LEFT_SWITCH_MASK BIT7
#define RIGHT_SWITCH_PORT PORT1
#define RIGHT_SWITCH_MASK BIT0
#define MIDDLE_SWITCH_PORT PORT1
#define MIDDLE_SWITCH_MASK BIT1
/*
**define masks for the port pin functions. This information is used to establish the mode
**settings for the GPIO pins
**
*/
#define PORT0_OPTICS_MASK 0b00111111 //optics pins [5:0] on port 0
#define PORT1_OPTICS_MASK 0b00000000 //no optics on port 1
#define PORT0_LED_MASK 0b01000000 //led drive at pin [6] on port 0
#define PORT1_LED_MASK 0b00000000 //no led drive on port 1
#define PORT0_SWITCH_MASK 0b10000000 //switch input at pin [7] on port 0
#define PORT1_SWITCH_MASK 0b00000011 //switch inputs at [1:0] on port 1
//comment the following lines if you do not want PS2 resolution and scaling commands to be implemented
//in the code.
#define ENABLE_RESOLUTION
#define ENABLE_SCALING
//END OF USER DEFINES
//*************************************************************************************************
//*************************************************************************************************
//COMMON DECLARATIONS USED BY BOTH INTERFACES
#include "macros.h" //include macro definitions
/*
** define port data and mode initial values for the 3 operating states -- normal, suspend, and suspend with remote
** wakeup -- based on the masks provided by the user
*/
/*
**normal operating mode
*/
#define PORT0_INIT PORT0_SWITCH_MASK
#define PORT1_INIT PORT1_SWITCH_MASK
#define PORT0_MODE1_INIT PORT0_SWITCH_MASK
#define PORT1_MODE1_INIT PORT1_SWITCH_MASK
#define PORT0_MODE0_INIT PORT0_LED_MASK
#define PORT1_MODE0_INIT PORT1_LED_MASK
/*
** suspend mode (no remote wakeup)
*/
#define PORT0_SUSPEND PORT0_LED_MASK
#define PORT1_SUSPEND PORT1_LED_MASK
#define PORT0_MODE1_SUSPEND PORT0_LED_MASK
#define PORT1_MODE1_SUSPEND PORT1_LED_MASK
#define PORT0_MODE0_SUSPEND PORT0_SWITCH_MASK
#define PORT1_MODE0_SUSPEND PORT1_SWITCH_MASK
/*
** remote wakeup
*/
#define PORT0_RW (PORT0_LED_MASK | PORT0_SWITCH_MASK)
#define PORT1_RW (PORT1_LED_MASK | PORT1_SWITCH_MASK)
#define PORT0_MODE1_RW (PORT0_SWITCH_MASK | PORT0_LED_MASK)
#define PORT1_MODE1_RW (PORT1_SWITCH_MASK | PORT1_LED_MASK)
#define PORT0_MODE0_RW 0
#define PORT1_MODE0_RW 0
#define LEFT_SWITCH_ASSERTED (!(LEFT_SWITCH_PORT & LEFT_SWITCH_MASK))
#define MIDDLE_SWITCH_ASSERTED (!(MIDDLE_SWITCH_PORT & MIDDLE_SWITCH_MASK))
#define RIGHT_SWITCH_ASSERTED (!(RIGHT_SWITCH_PORT & RIGHT_SWITCH_MASK))
/*
** switches are debounced in a routine that is called every 4 msec. 10
** successive stable samples are required for a switch change to be reported.
*/
#define DEBOUNCE_COUNT 10 //10 identical samples must be taken to recognize switch changes
/*
** define a structure containing variables updated in the 1-msec interrupt
*/
typedef struct
{
char b1msCounter; //incremented inside 1msec interrupt for general timing
char b1msFlags; //flag set inside 1msec interrupt
}ONE_MSEC_STATUS;
#define ONE_MSEC_FLAG 1
/*
** Quadrature inputs are sampled inside the 128 usec interrupt and placed in a queue for later
** processing in the main loop.
**
*/
typedef struct
{
char near *headP; //head of queue
char near *tailP; //tail of queue
char bLen; //length of queue
}QUEUE_STRUCT;
/*
** current state of each quadrature pair is stored to compare with the next sample.
**
*/
typedef struct
{
char bXstate; //current state of X optics
char bYstate; //current state of Y optics
char bZstate; //current state of Z optics
}OPTICS_STATE;
/*
** the order of the bytes in this structure is important! These bytes are in the
** proper order for a packet returned to a USB host in response to a Get_Report command.
*/
typedef struct
{
char bChange; //set to 1 if mouse state has changed
char bButtons; //current state of mouse buttons
signed char bXcount; //current accumulation of X counts
signed char bYcount; //current accumulation of Y counts
signed char bZcount; //current accumulation of Z counts
}MOUSE_STATE;
/*
** global variables used by both USB and PS2 interfaces
*/
QUEUE_STRUCT OpticsQueue; //optics queue
ONE_MSEC_STATUS MsecStatus; //status of 1msec interrupt
OPTICS_STATE Optics; //current state of optics
MOUSE_STATE Mouse; //current state of mouse (buttons, x,y,z)
char bLastButtons;
char bDebounceCount;
char bOpticsArray[16]; //16-byte array used for optics queue data
const signed char quad_table[] =
/*
;***
; Quadrature state table. This table assists processing of quadrature state
; transitions. The table index is calculated as:
; [(last_state)*4 + current_state],
; and the table entry at that point is 1, 0 or -1 indicating increment, hold
; or decrement the count, respectively.
;***
*/
{
0, //;State 0 => state 0 (NoChange)
1, //; => state 1 (Increment)
0xff, //; => state 2 (Decrement)
0, //; => state 3 (Fault)
0xff, //;State 1 => state 0 (Decrement)
0, //; => state 1 (NoChange)
0, //; => state 2 (Fault)
1, //; => state 3 (Increment)
1, //;State 2 => state 0 (Increment)
0, //; => state 1 (Fault)
0, //; => state 2 (NoChange)
0xff, //; => state 3 (Decrement)
0, //;State 3 => state 0 (Fault)
0xff, //; => state 1 (Decrement)
1, //; => state 2 (Increment)
0 //; => state 3 (NoChange)
};
const signed char z_quad_table[] =
/*
;***
; Quadrature state table. This table assists processing of quadrature state
; transitions. The table index is calculated as:
; [(last_state)*4 + current_state],
; and the table entry at that point is 1, 0 or -1 indicating increment, hold
; or decrement the count, respectively.
;***
*/
{
0, //;State 0 => state 0 (NoChange)
0, //; => state 1 (NoChange)
0, //; => state 2 (NoChange)
0, //; => state 3 (Fault)
0, //;State 1 => state 0 (NoChange)
0, //; => state 1 (NoChange)
0, //; => state 2 (NoChange)
1, //; => state 3 (Increment)
1, //;State 2 => state 0 (Increment)
0, //; => state 1 (Fault)
0, //; => state 2 (NoChange)
0xff, //; => state 3 (Decrement)
0, //;State 3 => state 0 (Fault)
0xff, //; => state 1 (Decrement)
0, //; => state 2 (NoChange)
0 //; => state 3 (NoChange)
};
/*
** function prototypes for shared functions
*/
void main(void);
void ClearRam(void);
void Delay(char delay);
//void delay(void);
//*************************************************************************************************
//USB DECLARATIONS
#include "usb_desc.h" //include usb descriptors
#define SET_EP0_MODE(x) EP_A0_MODE = x //set mode register for EP0
/*
** define a structure that will maintain the parameters of multibyte data that is returned
** to the host in response to successive IN commands on endpoint 0 (descriptors, status, reports, etc).
*/
typedef struct
{
char bLength; //length of data remaining to be returned
far char *p; //pointer to the data
char dummy; //padding -- compiler bug doesn't allocate enough space for a far *
}TRANSMIT_STRUCT;
/*
** define a structure that contains the current USB device status
*/
typedef struct
{
char bConfiguration; //configured or not
char bRemoteWakeup; //remote wakeup enabled or not
char bDeviceStatus; //spare, do not remove! this byte is a placeholder
//for the 2nd byte of device status.
char bEP1Stall; //endpoint 1 stalled or not
char bEPStatus; //spare, do not remove! this byte is a placeholder
//for the 2nd byte of device status
char bAddress; //current address
char bProtocol; //boot protocol or report protocol
}DEVICE_STATUS;
/*
** define a structure for mouse transmit status
*/
typedef struct
{
char bIdlePeriod; //current idle period setting
char bIdleCounter; //counter for idle period
}
MOUSE_STATUS;
MOUSE_STATUS MouseStatus; //status of mouse
TRANSMIT_STRUCT XmtBuff; //EP0 transmit buffer parameters
DEVICE_STATUS DeviceStatus; //device status
char bSuspendCounter; //counter for keeping track of suspend interval
//declare the following registers global. They are used by ISRs to avoid compiler issues.
char byte_count;
char byte_count1;
char bWakeupCount;
/*
** USB function prototypes
*/
void UsbReInitialize(void);
void MouseTask(void);
void Suspend(void);
void usbmain(void);
void HandleSetup(void);
void HandleIn(void);
void USB_control_read(void);
char LoadEP0Fifo(void);
void ClearRemoteWakeup(void);
void SetRemoteWakeup(void);
void SetConfiguration(void);
void SetAddress(void);
void ClearEndpointStall(void);
void SetEndpointStall(void);
void GetDeviceStatus(void);
void GetDescriptor(void);
void GetInterfaceStatus(void);
void GetEndpointStatus(void);
void SetIdle(void);
void SetProtocol(void);
void GetReport(void);
void GetIdle(void);
void GetProtocol(void);
void GetConfiguration(void);
void USB_Stall_In_Out(void);
char BusInactive(void);
//*************************************************************************************************
//PS2 DECLARATIONS
/*
** define a structure that contains all mouse parameters that can be set via host commands
*/
typedef struct
{
char bReportRate;
char bReportInterval;
char bScale;
char bStream;
char bResolution;
char bEnabled;
char bZmouse;
char bWrap;
}MOUSEPARMS;
/*
** define a structure to hold messages to be sent back to the host. This can be either a mouse packet
** or a response to a command (device id, BAT response, etc).
*/
typedef struct
{
char bMsgBuff[5]; //array of bytes
char bMsgLen; //initial length of message
char bXmtLen; //length of bytes remaining to send
}PS2_XMT_STRUCT;
int16 bBatDelay; //bat delay, in msec.
char ConsecutiveSetSamples; //keeps track of number of consecutive set-sample commands
//received from the host (for enabling z-mice)
char bIntervalCount; //interval count, in msec, for reporting mouse packets
MOUSEPARMS MouseParms; //mouse parameters
PS2_XMT_STRUCT Ps2Xmt; //transmit buffer
char ksc_delay; //storage for assembly routines
char ps2_temp0; //storage for assembly routines
/*
** function prototypes for PS2 routines
*/
void ps2BAT(void);
void ps2_send(char data);
char ps2_receive(void);
void Reset(void);
void Resend(void);
void SetDefault(void);
void Disable(void);
void Enable(void);
char SetSampleRate(char p);
void ReadDeviceType(void);
void SetRemoteMode(void);
void SetWrapMode(void);
void ReadData(void);
void SetStreamMode(void);
void StatusRequest(void);
char SetResolution(char p);
void SetScaling(void);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -