usrUsbKbdInit.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:16k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* usrUsbKbdInit.c - Initialization of the USB Keyboard driver */
  2. /* Copyright 1999-2002 Wind River Systems, Inc. */
  3. /*
  4. Modification history
  5. --------------------
  6. 01d,30jan02,wef fixed DevFind routine.
  7. 01c,08dec01,wef fixed some warnings
  8. 01b,02feb01,wef Added ios functionality - allows for open, close, read,
  9.                 ioctl, etc access to the printer.
  10. 01a,23aug00,wef Created
  11. */
  12. /*
  13. DESCRIPTION
  14. This configlette initializes the USB keyboard driver.  This assumes the
  15. USB host stack has already been initialized and has a host controller
  16. driver attached.   
  17. This configlette demonstrates how a user might integrate a USB class 
  18. driver into the vxWorks file system.  usbKbdDevCreate () intalls a USB
  19. keyboard and its associated driver functions into the driver table allowing
  20. the keyboard to be accesed with standard fopen, close, read, write, etc. type
  21. calls.  
  22. There is an included test routine playWithKeyboard () that demonstrates 
  23. using the ios functionality
  24. */
  25. /* includes */
  26. #include "drv/usb/usbKeyboardLib.h"
  27. #include "usb/usbHid.h"
  28. #include "vxWorks.h"
  29. #include "iv.h"
  30. #include "ioLib.h"
  31. #include "iosLib.h"
  32. #include "tyLib.h"
  33. #include "intLib.h"
  34. #include "errnoLib.h"
  35. #include "sioLib.h"
  36. #include "stdlib.h"
  37. #include "stdio.h"
  38. #include "logLib.h"
  39. #include "selectLib.h"
  40. /* defines */
  41. #define TX_BUF_NUM 0x10000
  42. #define USB_KBD_MUTEX_TAKE(tmout)
  43.     semTake (usbKbdMutex, (int) (tmout))
  44. #define USB_KBD_MUTEX_GIVE
  45.     semGive (usbKbdMutex)
  46. #define USB_KBD_LIST_SEM_TAKE(tmout)
  47.     semTake (usbKbdListMutex, (int) (tmout))
  48. #define USB_KBD_LIST_SEM_GIVE
  49.     semGive (usbKbdListMutex)
  50. #define KBD_NAME_LEN_MAX        100
  51. #define USB_KBD_NAME "/usbKb/"
  52. #define CTRL_Z     26 /* ASCI code for ^Z */
  53. /* data types */
  54. /* typedefs */
  55.  
  56. typedef struct usb_kbd_node
  57.     {
  58.     NODE node;
  59.     struct usb_kbd_dev * pUsbKbdDev;
  60.     } USB_KBD_NODE;
  61. typedef struct usb_kbd_dev /* USB_KBD_DEV */
  62.     {
  63.     DEV_HDR             ioDev;
  64.     SIO_CHAN    *       pSioChan;
  65.     UINT16              numOpen;
  66.     UINT32              bufSize;
  67.     UCHAR *       buff;
  68.     SEL_WAKEUP_LIST     selList;
  69.     USB_KBD_NODE * pUsbKbdNode;
  70.     } USB_KBD_DEV;
  71.  
  72. /* local variables */
  73. LOCAL SEM_ID    usbKbdMutex; /* mutex semaphore */
  74. LOCAL SEM_ID    usbKbdListMutex; /* mutex semaphore to protect list */
  75. LOCAL UINT32 kbdCount = 0;
  76. LOCAL LIST      usbKbdList; /* all USB keyboards in the system */
  77. LOCAL int usbKbdDrvNum = 0; /* driver number */
  78. LOCAL BOOL enterPressed;
  79. /* forward declarations */
  80. LOCAL void usbKbdDrvAttachCallback (void * arg, SIO_CHAN *pChan, 
  81.    UINT16 attachCode);
  82. LOCAL int usbKbdRead (USB_KBD_DEV * pUsbKbdDev,UCHAR *buffer, 
  83.     UINT32 nBytes);
  84. LOCAL int usbKbdClose (USB_KBD_DEV * pUsbKbdDev);
  85. LOCAL int usbKbdWrite (USB_KBD_DEV * pUsbKbdDev, UCHAR * buffer,
  86.      UINT32 nBytes);
  87. LOCAL int usbKbdOpen (USB_KBD_DEV * pUsbKbdDev, char * name,
  88.     int flags, int mode);
  89. LOCAL int  usbKbdIoctl (USB_KBD_DEV * pUsbKbdDev, int request, void * arg);
  90. LOCAL STATUS  usbKbdDevFind (SIO_CHAN *pChan, USB_KBD_DEV ** ppUsbKbdDev);
  91. LOCAL STATUS usbKbdDevDelete (USB_KBD_DEV * pUsbKbdDev);
  92. /*******************************************************************************
  93. *
  94. * usbKbdDevCreate - create a VxWorks device for an USB keyboard
  95. *
  96. * This routine creates a device on a specified serial channel.  Each channel
  97. * to be used should have exactly one device associated with it by calling
  98. * this routine.
  99. *
  100. * For instance, to create the device "/ /0", the proper call would be:
  101. * .CS
  102. *     usbKbdDevCreate ("/usbKb/0", pSioChan);
  103. * .CE
  104. * Where pSioChan is the address of the underlying SIO_CHAN serial channel
  105. * descriptor (defined in sioLib.h).
  106. * This routine is typically called by the USB keyboard driver, when it detects 
  107. * an insertion of a USB keyboard.
  108. *
  109. * RETURNS: OK, or ERROR if the driver is not installed, or the
  110. * device already exists, or failed to allocate memory.
  111. */
  112. STATUS usbKbdDevCreate
  113.     (
  114.     char * name,         /* name to use for this device      */
  115.     SIO_CHAN * pSioChan /* pointer to core driver structure */
  116.     )
  117.     {
  118.     USB_KBD_NODE * pUsbKbdNode = NULL;   /* pointer to device node */
  119.     USB_KBD_DEV * pUsbKbdDev = NULL;     /* pointer to USB device */
  120.     /* Create the mutex semaphores */
  121.  
  122.     usbKbdMutex = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE |
  123.       SEM_INVERSION_SAFE);
  124.  
  125.     usbKbdListMutex = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE |
  126.   SEM_INVERSION_SAFE);
  127.  
  128.     /* initialize the linked list */
  129.  
  130.     lstInit (&usbKbdList);
  131.     /* Install the appropriate functions into the driver table */
  132.     usbKbdDrvNum = iosDrvInstall ((FUNCPTR) NULL, 
  133.   (FUNCPTR) usbKbdDevDelete, 
  134.   (FUNCPTR) usbKbdOpen, 
  135.   (FUNCPTR) usbKbdClose, 
  136.   (FUNCPTR) usbKbdRead, 
  137.   (FUNCPTR) usbKbdWrite, 
  138.   (FUNCPTR) usbKbdIoctl);
  139.     /*  check to see if there was room to install the driver */
  140.     if (usbKbdDrvNum <= 0)
  141.         {
  142.         errnoSet (S_ioLib_NO_DRIVER);
  143. printf ("There is no more room in the driver tablen");
  144. return (ERROR);
  145.         }
  146.     if (pSioChan == (SIO_CHAN *) ERROR)
  147. {
  148. printf ("pSioChan is ERRORn");
  149. return (ERROR);
  150. }
  151.     /* allocate memory for the device */
  152.     if ((pUsbKbdDev = (USB_KBD_DEV *) calloc (1, sizeof (USB_KBD_DEV))) == NULL)
  153. {
  154. printf ("calloc returned NULL - out of memoryn");
  155. return (ERROR);
  156. }
  157.     pUsbKbdDev->pSioChan = pSioChan;
  158.     /* allocate memory for this node, and populate it */
  159.     pUsbKbdNode = (USB_KBD_NODE *) calloc (1, sizeof (USB_KBD_NODE));
  160.     /* record useful information */
  161.     pUsbKbdNode->pUsbKbdDev = pUsbKbdDev;
  162.     pUsbKbdDev->pUsbKbdNode = pUsbKbdNode;
  163.     /* add the node to the list */
  164.     USB_KBD_LIST_SEM_TAKE (WAIT_FOREVER);
  165.     lstAdd (&usbKbdList, (NODE *) pUsbKbdNode);
  166.     USB_KBD_LIST_SEM_GIVE;
  167.  
  168.     /* allow for select support */
  169.     selWakeupListInit (&pUsbKbdDev->selList);
  170.     /* start the device in the only supported mode */
  171.     sioIoctl (pUsbKbdDev->pSioChan, SIO_MODE_SET, (void *) SIO_MODE_INT);
  172.     /* add the device to the I/O system */
  173.     return (iosDevAdd (&pUsbKbdDev->ioDev, name, usbKbdDrvNum));
  174.     }
  175. /*******************************************************************************
  176. *
  177. * usbKbdDevDelete - delete a VxWorks device for an USB keyboard
  178. *
  179. * This routine deletes a device on a specified serial channel.  
  180. *
  181. * This routine is typically called by the USB keyboard driver, when it detects 
  182. * a removal of a USB keyboard.
  183. *
  184. * RETURNS: OK, or ERROR if the driver is not installed.
  185. */
  186. LOCAL STATUS usbKbdDevDelete
  187.     (
  188.     USB_KBD_DEV * pUsbKbdDev /* keyboard device to read from */
  189.     )
  190.     {
  191.     int status = OK; /* holder for the return value */
  192.     if (usbKbdDrvNum <= 0)
  193.         {
  194.         errnoSet (S_ioLib_NO_DRIVER);
  195.         return (ERROR);
  196.         }
  197.     /* remove the device from the I/O system */
  198.     iosDevDelete (&pUsbKbdDev->ioDev);
  199.     /* remove from list */
  200.     USB_KBD_LIST_SEM_TAKE (WAIT_FOREVER);
  201.     lstDelete (&usbKbdList, (NODE *) pUsbKbdDev->pUsbKbdNode);
  202.     USB_KBD_LIST_SEM_GIVE;
  203.     /* free memory for the device */
  204.     free (pUsbKbdDev->pUsbKbdNode);
  205.     free (pUsbKbdDev);
  206.     return (status);
  207.     }
  208. /*************************************************************************
  209. *
  210. * usbKbdDevFind - find the USB_KBD_DEV device for an SIO channel
  211. *
  212. * RETURNS: OK, or ERROR
  213. */
  214.  
  215. LOCAL STATUS usbKbdDevFind
  216.     (
  217.     SIO_CHAN * pChan,          /* pointer to affected SIO_CHAN */
  218.     USB_KBD_DEV ** ppUsbKbdDev /* pointer to an USB_KBD_DEV */
  219.     )
  220.     {
  221.     USB_KBD_NODE *      pUsbKbdNode = NULL;     /* pointer to USB device node */
  222.     USB_KBD_DEV * pTempDev; /* pointer to an USB_KBD_DEV */
  223.     if (pChan == NULL)
  224.         return (ERROR);
  225.  
  226.     /* protect it from other module's routines */
  227.  
  228.     USB_KBD_LIST_SEM_TAKE (WAIT_FOREVER);
  229.  
  230.     /* loop through all the devices */
  231.  
  232.     for (pUsbKbdNode = (USB_KBD_NODE *) lstFirst (&usbKbdList);
  233.          pUsbKbdNode != NULL;
  234.          pUsbKbdNode = (USB_KBD_NODE *) lstNext ((NODE *) pUsbKbdNode))
  235.         {
  236.         pTempDev = pUsbKbdNode->pUsbKbdDev;
  237. /* return as soon as you find it */
  238. if (pTempDev->pSioChan == pChan)
  239.     {
  240.     * (UINT32 *) ppUsbKbdDev = (UINT32) pTempDev;
  241.     USB_KBD_LIST_SEM_GIVE;
  242.     return (OK);
  243.     }
  244.         }
  245.     USB_KBD_LIST_SEM_GIVE;
  246.     return (ERROR);
  247.     }
  248. /*************************************************************************
  249. *
  250. * usbKbdDrvAttachCallback - receives attach callbacks from keyboard SIO driver
  251. *
  252. * RETURNS: N/A
  253. */
  254. LOCAL void usbKbdDrvAttachCallback
  255.     (
  256.     void * arg, /* caller-defined argument */
  257.     SIO_CHAN *pChan, /* pointer to affected SIO_CHAN */
  258.     UINT16 attachCode /* defined as USB_KBD_xxxx */
  259.     )
  260.     {
  261.     USB_KBD_DEV * pUsbKbdDev=NULL; /* keyboard device */
  262.     char kbdName [KBD_NAME_LEN_MAX]; /* keyboard name */
  263.     /*  A keyboard has been attached. */
  264.     if (attachCode == USB_KBD_ATTACH)
  265. {
  266. /*  Lock this particular channel for this particular keyboard */
  267. if (usbKeyboardSioChanLock (pChan) != OK)
  268.     {
  269.     printf("usbKeyboardSioChanLock () returned ERRORn");
  270.     }
  271. else
  272.     {
  273.     /*  plugs the name /usbKb/x into the kbdName variable */
  274.     sprintf (kbdName, "%s%d", USB_KBD_NAME, kbdCount);
  275.     /*  Create the keyboard device, do all the ios stuff (drvInstall, 
  276.      *  devAdd...) 
  277.      */
  278.     if (usbKbdDevCreate (kbdName, pChan) != OK)
  279. {
  280. printf("usbKbdDevCreate() returned ERRORn");
  281. }
  282.     /* now we can increment the counter */
  283.     kbdCount++;
  284.     if (usbKbdDevFind (pChan, &pUsbKbdDev) != OK)
  285. {
  286. printf("usbKbdDevFind() returned ERRORn");
  287. return;
  288. }
  289.     printf("USB Keyboard attached as %sn", kbdName);
  290.     }
  291. }
  292.     else if (attachCode == USB_KBD_REMOVE)
  293. {
  294. /* find the related device */
  295. if (usbKbdDevFind (pChan, &pUsbKbdDev) != OK)
  296.     {
  297.     printf ("usbKbdDevFind could not find channel 0x%d", (UINT32)pChan);
  298.     return;
  299.     }
  300. /* delete the device */
  301. usbKbdDevDelete (pUsbKbdDev);
  302. if (usbKeyboardSioChanUnlock (pChan) != OK)
  303.     {
  304.     printf("usbKeyboardSioChanUnlock () returned ERRORn");
  305.     return;
  306.     }
  307. sprintf (kbdName, "%s%d", USB_KBD_NAME, kbdCount-1);
  308. printf ("USB Keyboard %s removedn", kbdName);
  309. }
  310.     }
  311. /*******************************************************************************
  312. *
  313. * usbKbdOpen - open a usbKbdDrv serial device.
  314. *
  315. * Increments a counter that holds the number of open paths to device. 
  316. */
  317. LOCAL int usbKbdOpen
  318.     (
  319.     USB_KBD_DEV * pUsbKbdDev,  /* keyboard device to read from */
  320.     char     * name, /* device name */
  321.     int flags, /* flags */
  322.     int         mode /* mode selected */
  323.     )
  324.     {
  325.     pUsbKbdDev->numOpen++;  /* increment number of open paths */
  326.     
  327.     sioIoctl (pUsbKbdDev->pSioChan, SIO_OPEN, NULL);
  328.     return ((int) pUsbKbdDev);
  329.     }
  330. /*******************************************************************************
  331. *
  332. * usbKbdDrvUnInit - shuts down an I/O USB keyboard driver
  333. *
  334. *
  335. * This is supplied to for the user, but it should be noted that iosDrvRemove()
  336. * may cause unpredictable results.
  337. *
  338. */
  339. STATUS usbKbdDrvUnInit (void)
  340.     {
  341.     if (!usbKbdDrvNum)
  342. return (OK);
  343.     /* remove the driver */
  344.     if (iosDrvRemove (usbKbdDrvNum, TRUE) != OK)
  345. {
  346. printf("iosDrvRemove () returned ERRORn");
  347. return (ERROR);
  348. }
  349.     usbKbdDrvNum = 0;
  350.     /* delete the mutex semaphores */
  351.  
  352.     if (semDelete (usbKbdMutex) == ERROR)
  353. {
  354. printf("semDelete (usbKbdMutex) returned ERRORn");
  355. return (ERROR);
  356. }
  357.     if (semDelete (usbKbdListMutex) == ERROR)
  358. {
  359. printf("semDelete (usbKbdListMutex) returned ERRORn");
  360. return (ERROR);
  361. }
  362.     /* unregister */
  363.  
  364.     if (usbKeyboardDynamicAttachUnRegister (usbKbdDrvAttachCallback, 
  365.  NULL) 
  366. != OK)
  367. {
  368. printf("usbKeyboardDynamicAttachUnRegister () returned ERRORn");
  369. return (ERROR);
  370. }
  371.  
  372.     /* shutdown */
  373.     if (usbKeyboardDevShutdown () != OK)
  374. {
  375. printf("usbKeyboardDynamicAttachUnRegister () returned ERRORn");
  376. return (ERROR);
  377. }
  378.     return (OK);
  379.     }
  380. /*******************************************************************************
  381. *
  382. * usbKbdClose - close a usbKbdDrv serial device.
  383. *
  384. * Decrements the counter of open paths to device and alerts the driver 
  385. * with an ioctl call when the count reaches zero. This scheme is used to
  386. * implement the HUPCL(hang up on last close).      
  387. */
  388. LOCAL int usbKbdClose
  389.     (
  390.     USB_KBD_DEV * pUsbKbdDev          /* keyboard device to read from */
  391.     )
  392.     {
  393.     /* if there are no open channels */
  394.     if (!(--pUsbKbdDev->numOpen))
  395. {
  396. sioIoctl (pUsbKbdDev->pSioChan, SIO_HUP, NULL);
  397. }
  398.     return ((int) pUsbKbdDev);
  399.     }
  400. /*******************************************************************************
  401. *
  402. * usbKbdIoctl - issue device control commands
  403. *
  404. * This routine issues device control commands to an USB keyboard device.
  405. *
  406. * RETURNS: depends on the function invoked.
  407. */
  408. LOCAL int usbKbdIoctl
  409.     (
  410.     USB_KBD_DEV * pUsbKbdDev, /* keyboard device to read from */
  411.     int request, /* request code */
  412.     void * arg /* some argument */
  413.     )
  414.     {
  415.     return (sioIoctl (pUsbKbdDev->pSioChan, request, arg));
  416.     }
  417. /*******************************************************************************
  418. *
  419. * usbKbdRead - read from the USB keyboard
  420. *
  421. * This routines is a no-op for a read from the USB keyboard.
  422. *
  423. * RETURNS: OK, always.
  424. */
  425. LOCAL int usbKbdRead
  426.     (
  427.     USB_KBD_DEV * pUsbKbdDev,           /* keyboard device to read from */
  428.     UCHAR *buffer, 
  429.     UINT32 nBytes    
  430.     )
  431.     {
  432.     return (pUsbKbdDev->pSioChan->pDrvFuncs->pollInput (pUsbKbdDev->pSioChan,  buffer));
  433.     }
  434. /*******************************************************************************
  435. *
  436. * usbKbdWrite - write to the USB keyboard
  437. *
  438. * USB keyboards don't like to be written to.  We don't support this feature.
  439. *
  440. * RETURNS: ENOSYS
  441. */
  442. int usbKbdWrite
  443.     (
  444.     USB_KBD_DEV * pUsbKbdDev, /* keyboard device to read from */
  445.     UCHAR * buffer, /* buffer of data to write  */
  446.     UINT32   nBytes /* number of bytes in buffer */
  447.     )
  448.     {
  449.     return (ENOSYS);
  450.     }
  451. /*****************************************************************************
  452. *
  453. * usrUsbKbdInit - initialize the USB keyboard driver
  454. *
  455. * This function initializes the USB keyboard driver and registers for attach 
  456. * callbacks.  
  457. *
  458. * RETURNS: Nothing 
  459. */
  460. void usrUsbKbdInit (void) 
  461.     {
  462.     /* Check if driver already installed */
  463.     if (usbKbdDrvNum > 0)
  464. {
  465. printf ("Keyboard already initilaized.n");
  466. }
  467.     if (usbKeyboardDevInit () == OK)
  468. {
  469.         printf ("usbKeyboardDevInit() returned OKn");
  470. if (usbKeyboardDynamicAttachRegister (usbKbdDrvAttachCallback, 
  471.       (void *) NULL) 
  472.   != OK)
  473.     {
  474.     printf ("usbKeyboardDynamicAttachRegister() returned ERRORn");
  475.     }
  476. }
  477.     else
  478.         printf ("usbKeyboardDevInit() returned ERRORn");
  479.     }
  480. /*************************************************************************
  481. *
  482. * enterThread - waits for user to press [enter]
  483. *
  484. * RETURNS:  N/A
  485. */
  486. LOCAL void enterThread ( void )
  487.     {
  488.     char bfr [256];
  489.     printf ("Press [enter] to terminate polling.n");
  490.     gets (bfr);
  491.     enterPressed = TRUE;
  492.     }
  493. /*************************************************************************
  494. *
  495. * playWithKeyboard - prints key presses to the terminal
  496. *
  497. * RETURNS: OK or ERROR
  498. */
  499. UINT16 playWithKeyboard ( void )
  500.     {
  501.     int taskId;
  502.     char inChar;
  503.     int fd = 0;
  504.     /* Poll for input or until user presses CTRL-Z on USB keyboard or
  505.      * [enter] on main keyboard. */
  506.     if ((fd = open ("/usbKb/0", 2,0)) == ERROR)
  507. return (ERROR);
  508.     /* Create thread to watch for keypress */
  509.     enterPressed = FALSE;
  510.      if((taskId = taskSpawn ("tEnter", 
  511.      5, /* priority */
  512.      0, /* task options */ 
  513.      0x4000,  /* 16k stack space */
  514.      (FUNCPTR) enterThread, 
  515.      0, 0, 0, 0, 0, 0, 0, 0, 0, 0 )) ==ERROR)
  516. {
  517. printf(" TaskSpawn Error...!n");
  518. return ERROR;
  519. }
  520.     printf ("Press CTRL-Z to terminate polling.n");
  521.     while (!enterPressed)
  522. {
  523.     if (read (fd, &inChar, 1) == OK)
  524. {
  525. printf ("ASCII %3d", inChar);
  526. if (inChar >= 32)
  527.     printf (" '%c'", inChar);
  528. printf ("n");
  529. if (inChar == CTRL_Z)
  530.     {
  531.     printf ("Stopped by CTRL-Zn");
  532.     break;
  533.     }
  534. }
  535. taskDelay (2);
  536. }
  537.     taskDelete (taskId);
  538.     return OK;
  539.     }