///////////////////////////////////////////////////////////////////////////////////////////// //* *// //* This is a serial mouse driver for eCos, writen by lihui *// //* *// //* The default setting is set mouse on com2("/dev/ser1"), and mouse type is MS *// //* *// ///////////////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_BYTES 128 /* number of bytes for buffer */ #define SCALE 3 /* default scaling factor for acceleration */ #define THRESH 5 /* default threshhold for acceleration */ /* states for the mouse*/ #define IDLE 0 /* start of byte sequence */ #define XSET 1 /* setting x delta */ #define YSET 2 /* setting y delta */ #define XADD 3 /* adjusting x delta */ #define YADD 4 /* adjusting y delta */ /* values in the bytes returned by the mouse for the buttons*/ #define MS_LEFT_BUTTON 2 #define MS_RIGHT_BUTTON 1 /* Bit fields in the bytes sent by the mouse.*/ #define TOP_FIVE_BITS 0xf8 #define BOTTOM_THREE_BITS 0x07 #define TOP_BIT 0x80 #define SIXTH_BIT 0x40 #define BOTTOM_TWO_BITS 0x03 #define THIRD_FOURTH_BITS 0x0c #define BOTTOM_SIX_BITS 0x3f /* Mouse button bits*/ #define MWBUTTON_L 04 #define MWBUTTON_M 02 #define MWBUTTON_R 01 /* Mouse Port */ #define PORT "/dev/ser1" static int state; /* IDLE, XSET, ... */ static int buttons; /* current mouse buttons pressed*/ static int availbuttons; /* which buttons are available */ static long xd; /* change in x */ static long yd; /* change in y */ static int left; /* because the button values change */ static int middle; /* between mice, the buttons are */ static int right; /* redefined */ static unsigned char *bp; /* buffer pointer */ static int nbytes; /* number of bytes left */ static unsigned char buffer[MAX_BYTES]; /* data bytes read */ Cyg_ErrNo error; /* error output*/ cyg_io_handle_t handle; /* mouse device handle */ cyg_serial_info_t info; /* serial port config info */ cyg_uint32 len; /* data length */ //unsigned char buf[6]; //cyg_uint32 iBlock=1; /* Set NonBlocking mode */ /* local routines*/ static cyg_io_handle_t MOU_Open(); static void MOU_Close(void); static int MOU_GetButtonInfo(void); static void MOU_GetDefaultAccel(int *pscale,int *pthresh); static int MOU_Read(long *dx, long *dy, long *dz, int *bptr); static int ParseMS(int); /* routine to interpret MS mouse */ /* * Open up the mouse device. * Returns the fd if successful, or negative if unsuccessful. */ static cyg_io_handle_t MOU_Open() { char *type; char *port; /* microsoft mouse*/ left = MS_LEFT_BUTTON; right = MS_RIGHT_BUTTON; middle = 0; /* eCos mouse open */ error=cyg_io_lookup(PORT, &handle); len=sizeof(info); /* set serial port configuration */ error=cyg_io_get_config(handle,CYG_IO_GET_CONFIG_SERIAL_INFO,&info,&len); info.baud=CYGNUM_SERIAL_BAUD_1200; info.stop=CYGNUM_SERIAL_STOP_1; info.word_length=CYGNUM_SERIAL_WORD_LENGTH_8; error=cyg_io_set_config(handle,CYG_IO_SET_CONFIG_SERIAL_INFO, &info, &len); /* set nonblocking mode */ //len=sizeof(cyg_uint32); //error=cyg_io_set_config(handle,CYG_IO_SET_CONFIG_SERIAL_READ_BLOCKING,&iBlock,&len); if (error < 0) { printf("Error %d opening serial mouse type %s on port %s.\n", errno, type, port); return -1; } /* initialize data*/ availbuttons = left | middle | right; state = IDLE; nbytes = 0; buttons = 0; xd = 0; yd = 0; return handle; err: //close(mouse_fd); handle = 0; return -1; } /* * Close the mouse device. */ static void MOU_Close(void) { if (handle > 0) { //close(mouse_fd); } handle = 0; } /* * Get mouse buttons supported */ static int MOU_GetButtonInfo(void) { return availbuttons; } /* * Get default mouse acceleration settings */ static void MOU_GetDefaultAccel(int *pscale,int *pthresh) { *pscale = SCALE; *pthresh = THRESH; } /* * Attempt to read bytes from the mouse and interpret them. * Returns -1 on error, 0 if either no bytes were read or not enough * was read for a complete state, or 1 if the new state was read. * When a new state is read, the current buttons and x and y deltas * are returned. This routine does not block. */ static int MOU_Read(long *dx, long *dy, long *dz, int *bptr) { int b; cyg_uint32 tmp; /* * If there are no more bytes left, then read some more, * waiting for them to arrive. On a signal or a non-blocking * error, return saying there is no new state available yet. */ if (nbytes <= 0) { bp = buffer; tmp=3; error = cyg_io_read(handle, bp, &tmp); nbytes=tmp; if (nbytes < 0) { if (error == EINTR || error == EAGAIN) return 0; } } /* * Loop over all the bytes read in the buffer, parsing them. * When a complete state has been read, return the results, * leaving further bytes in the buffer for later calls. */ while (nbytes-- > 0) { if (ParseMS((int) *bp++)) { *dx = xd; *dy = yd; *dz = 0; b = 0; if(buttons & left) b |= MWBUTTON_L; if(buttons & right) b |= MWBUTTON_R; if(buttons & middle) b |= MWBUTTON_M; *bptr = b; return 1; } } return 0; } /* * Input routine for Microsoft mouse. * Returns nonzero when a new mouse state has been completed. */ static int ParseMS(int byte) { switch (state) { case IDLE: if (byte & SIXTH_BIT) { buttons = (byte >> 4) & BOTTOM_TWO_BITS; yd = ((byte & THIRD_FOURTH_BITS) << 4); xd = ((byte & BOTTOM_TWO_BITS) << 6); state = XADD; } break; case XADD: xd |= (byte & BOTTOM_SIX_BITS); state = YADD; break; case YADD: yd |= (byte & BOTTOM_SIX_BITS); state = IDLE; if (xd > 127) xd -= 256; if (yd > 127) yd -= 256; return 1; } return 0; } int main() { long x, y, z; int b; printf("Open Mouse\n"); if( MOU_Open(0) < 0) printf("open failed mouse\n" ); while(1) { if(MOU_Read(&x, &y, &z, &b) == 1) { printf("%d,%d,%d\n", x, y, b); } } return 0; }