usb_hid.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. /******************************************************************************
  2. *
  3. * Freescale Semiconductor Inc.
  4. * (c) Copyright 2004-2010 Freescale Semiconductor, Inc.
  5. * ALL RIGHTS RESERVED.
  6. *
  7. ******************************************************************************
  8. *
  9. * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
  10. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  11. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  12. * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  13. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  14. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  15. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  16. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  17. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  18. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  19. * THE POSSIBILITY OF SUCH DAMAGE.
  20. *
  21. **************************************************************************//*!
  22. *
  23. * @file usb_hid.c
  24. *
  25. * @author
  26. *
  27. * @version
  28. *
  29. * @date
  30. *
  31. * @brief The file contains USB stack HID layer implementation.
  32. *
  33. *****************************************************************************/
  34. /******************************************************************************
  35. * Includes
  36. *****************************************************************************/
  37. #include "usb_hid.h" /* USB HID Class Header File */
  38. #include "usb_devapi.h" /* USB device Header File */
  39. /*****************************************************************************
  40. * Constant and Macro's
  41. *****************************************************************************/
  42. /****************************************************************************
  43. * Global Variables
  44. ****************************************************************************/
  45. /* HID endpoint info array */
  46. static USB_CLASS_HID_ENDPOINT_DATA g_hid_endpoint_data;
  47. /* HID Class Callback Function Pointer */
  48. static USB_CLASS_CALLBACK g_hid_class_callback=NULL;
  49. /* HID Class Vendor Callback Function Pointer */
  50. static USB_REQ_FUNC g_vendor_req_callback=NULL;
  51. /* HID Class requests Callback Function Pointer */
  52. static USB_CLASS_SPECIFIC_HANDLER_FUNC g_param_callback = NULL;
  53. /*****************************************************************************
  54. * Local Types - None
  55. *****************************************************************************/
  56. /*****************************************************************************
  57. * Local Functions Prototypes
  58. *****************************************************************************/
  59. #ifndef COMPOSITE_DEV
  60. static uint_8 USB_Other_Requests(uint_8 controller_ID,
  61. USB_SETUP_STRUCT * setup_packet,
  62. uint_8_ptr *data,
  63. USB_PACKET_SIZE *size);
  64. #endif
  65. static uint_8 USB_Map_Ep_To_Struct_Index(uint_8 controller_ID,
  66. uint_8 ep_num);
  67. /*****************************************************************************
  68. * Local Variables - None
  69. *****************************************************************************/
  70. uint_8 g_class_request_params[2]; /* for get/set idle and protocol requests*/
  71. /*****************************************************************************
  72. * Local Functions
  73. *****************************************************************************/
  74. /**************************************************************************//*!
  75. *
  76. * @name USB_Map_Ep_To_Struct_Index
  77. *
  78. * @brief The funtion maps the endpoint number to the index of the endpoint
  79. * data structure
  80. *
  81. * @param controller_ID : Controller ID
  82. * @param ep_num : Endpoint number
  83. *
  84. * @return index : mapped index
  85. *
  86. ******************************************************************************
  87. * Returns the index of the endpoint info array for the particular endpoint
  88. * number
  89. *****************************************************************************/
  90. static uint_8 USB_Map_Ep_To_Struct_Index (
  91. uint_8 controller_ID, /* [IN] Controller ID */
  92. uint_8 ep_num /* Endpoint Number */
  93. )
  94. {
  95. uint_8 index = 0;
  96. USB_ENDPOINTS *ep_desc_data = (USB_ENDPOINTS *)
  97. USB_Desc_Get_Endpoints(controller_ID);
  98. /* map the endpoint num to the index of the endpoint structure */
  99. for(index = 0; index < ep_desc_data->count; index++)
  100. {
  101. if(ep_desc_data->ep[index].ep_num == ep_num)
  102. {
  103. break;
  104. }
  105. }
  106. return index;
  107. }
  108. /**************************************************************************//*!
  109. *
  110. * @name USB_Service_Hid
  111. *
  112. * @brief The function is a callback function of HID endpoint
  113. *
  114. * @param event : Pointer to USB Event Structure
  115. *
  116. * @return None
  117. *
  118. ******************************************************************************
  119. * This function is called from lower layer when data is transfer is completed
  120. * on HID endpoint (non control endpoint)
  121. *****************************************************************************/
  122. void USB_Service_Hid (
  123. PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */
  124. )
  125. {
  126. uint_8 index;
  127. uint_8 producer, consumer;
  128. USB_ENDPOINTS *ep_desc_data = (USB_ENDPOINTS *)
  129. USB_Desc_Get_Endpoints(event->controller_ID);
  130. /* map the endpoint num to the index of the endpoint structure */
  131. index = USB_Map_Ep_To_Struct_Index(event->controller_ID, event->ep_num);
  132. producer = g_hid_endpoint_data.ep[index].bin_producer;
  133. /* if there are no errors de-queue the queue and decrement the no. of
  134. transfers left, else send the same data again */
  135. if(event->errors == 0)
  136. {
  137. /* de-queue if the send is complete without an error */
  138. g_hid_endpoint_data.ep[index].bin_consumer++;
  139. }
  140. else
  141. {
  142. /* notify the application of the error */
  143. g_hid_class_callback(event->controller_ID, USB_APP_ERROR,
  144. (uint_8*)(&(event->errors)));
  145. }
  146. consumer = g_hid_endpoint_data.ep[index].bin_consumer;
  147. if(consumer != producer)
  148. {
  149. /*if bin is not empty */
  150. USB_CLASS_HID_QUEUE queue;
  151. /* send the next packet in queue */
  152. queue = g_hid_endpoint_data.ep[index].
  153. queue[consumer % MAX_QUEUE_ELEMS];
  154. (void)USB_Class_Send_Data(queue.controller_ID, queue.channel,
  155. queue.app_buff, queue.size);
  156. }
  157. /* notify the app of the send complete */
  158. g_hid_class_callback(event->controller_ID, USB_APP_SEND_COMPLETE, 0);
  159. }
  160. /**************************************************************************//*!
  161. *
  162. * @name USB_Class_Hid_Event
  163. *
  164. * @brief The function initializes HID endpoint
  165. *
  166. * @param controller_ID : Controller ID
  167. * @param event : Event Type
  168. * @param val : Pointer to configuration Value
  169. *
  170. * @return None
  171. *
  172. ******************************************************************************
  173. * The funtion initializes the HID endpoints when Enumeration complete event is
  174. * received
  175. *****************************************************************************/
  176. void USB_Class_Hid_Event (
  177. uint_8 controller_ID, /* [IN] Controller ID */
  178. uint_8 event, /* [IN] Event Type */
  179. void* val /* [IN] Pointer to configuration Value */
  180. )
  181. {
  182. uint_8 index;
  183. if(event == USB_APP_ENUM_COMPLETE)
  184. {
  185. uint_8 index_num = 0;
  186. uint_8 count = 0,ep_count = 0;
  187. USB_ENDPOINTS *ep_desc_data;
  188. #ifdef COMPOSITE_DEV
  189. DEV_ARCHITECTURE_STRUCT_PTR dev_arc_ptr;
  190. CLASS_ARC_STRUCT_PTR dev_class_ptr;
  191. dev_arc_ptr = (DEV_ARCHITECTURE_STRUCT *)USB_Desc_Get_Class_Architecture(controller_ID);
  192. for(count = 0; count < dev_arc_ptr->cl_count; count++)
  193. {
  194. dev_class_ptr = (CLASS_ARC_STRUCT_PTR)dev_arc_ptr->value[count];
  195. /* Initializes sub_classes */
  196. ep_count = dev_class_ptr->value[0];
  197. if(dev_class_ptr->class_type == 0x03/*HID_CC*/)
  198. break;
  199. index_num +=dev_class_ptr->value[0];
  200. }
  201. /* get the endpoints from the descriptor module */
  202. ep_desc_data = (USB_ENDPOINTS *)USB_Desc_Get_Endpoints(controller_ID);
  203. #else
  204. /* get the endpoints from the descriptor module */
  205. ep_desc_data = (USB_ENDPOINTS *)USB_Desc_Get_Endpoints(controller_ID);
  206. ep_count = ep_desc_data->count;
  207. #endif
  208. /* deinitialize all endpoints in case they were initialized */
  209. for(count=index_num;count<ep_count+index_num;count++)
  210. {
  211. USB_EP_STRUCT_PTR ep_struct_ptr=
  212. (USB_EP_STRUCT_PTR) (&ep_desc_data->ep[count]);
  213. (void)_usb_device_deinit_endpoint(&controller_ID,
  214. ep_struct_ptr->ep_num, ep_struct_ptr->direction);
  215. }
  216. /* intialize all non control endpoints */
  217. for(count=index_num;count<ep_count+index_num;count++)
  218. {
  219. USB_EP_STRUCT_PTR ep_struct=
  220. (USB_EP_STRUCT_PTR)&ep_desc_data->ep[count];
  221. (void)_usb_device_init_endpoint(&controller_ID, ep_struct->ep_num,
  222. ep_struct->size, ep_struct->direction, ep_struct->type,
  223. TRUE);
  224. /* register callback service for the endpoint */
  225. (void)_usb_device_register_service(controller_ID,
  226. (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num),
  227. USB_Service_Hid);
  228. /* set the EndPoint Status as Idle in the device layer */
  229. (void)_usb_device_set_status(&controller_ID,
  230. (uint_8)(USB_STATUS_ENDPOINT | HID_ENDPOINT |
  231. (ep_struct->direction << USB_COMPONENT_DIRECTION_SHIFT)),
  232. USB_STATUS_IDLE);
  233. }
  234. }
  235. else if((event == USB_APP_BUS_RESET) || (event == USB_APP_CONFIG_CHANGED))
  236. {
  237. /* clear producer and consumer on reset */
  238. for(index = 0; index < g_hid_endpoint_data.count; index++)
  239. {
  240. g_hid_endpoint_data.ep[index].bin_consumer = 0x00;
  241. g_hid_endpoint_data.ep[index].bin_producer = 0x00;
  242. g_hid_endpoint_data.ep[index].queue_num = 0x00;
  243. }
  244. }
  245. if(g_hid_class_callback != NULL)
  246. {
  247. /* notify the application of the event */
  248. g_hid_class_callback(controller_ID, event, val);
  249. }
  250. }
  251. /**************************************************************************//*!
  252. *
  253. * @name USB_Other_Requests
  254. *
  255. * @brief The funtion provides flexibilty to add class and vendor specific
  256. * requests
  257. *
  258. * @param controller_ID : Controller ID
  259. * @param setup_packet : Setup packet received
  260. * @param data : Data to be send back
  261. * @param size : Size to be returned
  262. *
  263. * @return status:
  264. * USB_OK : When Successfull
  265. * Others : When Error
  266. *
  267. ******************************************************************************
  268. * Handles HID Class requests and forwards vendor specific request to the
  269. * application
  270. *****************************************************************************/
  271. #ifndef COMPOSITE_DEV
  272. static uint_8 USB_Other_Requests
  273. #else
  274. uint_8 USB_HID_Other_Requests
  275. #endif
  276. (
  277. uint_8 controller_ID, /* [IN] Controller ID */
  278. USB_SETUP_STRUCT * setup_packet, /*[IN] Setup packet received */
  279. uint_8_ptr *data, /* [OUT] Data to be send back */
  280. USB_PACKET_SIZE *size /* [OUT] Size to be returned*/
  281. )
  282. {
  283. uint_8 index;
  284. uint_8 status = USBERR_INVALID_REQ_TYPE;
  285. uint_8 rpt_buf[REPORT_SIZE];/* buffer to send in case of get report req */
  286. *((uint_32_ptr)rpt_buf) = 0;
  287. if((setup_packet->request_type & USB_REQUEST_CLASS_MASK) ==
  288. USB_REQUEST_CLASS_CLASS)
  289. {
  290. /* class request so handle it here */
  291. /* index == 0 for get/set idle, index == 1 for get/set protocol */
  292. index = (uint_8)((setup_packet->request - 2) &
  293. USB_HID_REQUEST_TYPE_MASK);
  294. status = USB_OK;
  295. /* point to the data which comes after the setup packet */
  296. *data = ((uint_8*)setup_packet) + USB_SETUP_PKT_SIZE;
  297. *size = 0;
  298. /* handle the class request */
  299. switch(setup_packet->request)
  300. {
  301. case USB_HID_GET_REPORT_REQUEST :
  302. /*set the data pointer to the buffer to send */
  303. *data = &rpt_buf[0];
  304. if(*size > REPORT_SIZE) *size = REPORT_SIZE;
  305. break;
  306. case USB_HID_SET_REPORT_REQUEST :
  307. for(index = 0; index < REPORT_SIZE; index++)
  308. { /* copy the data sent by host in the buffer */
  309. rpt_buf[index] = *(*data + index);
  310. }
  311. break;
  312. case USB_HID_GET_IDLE_REQUEST :
  313. /* point to the current idle rate */
  314. *data = &g_class_request_params[index];
  315. *size = CLASS_REQ_DATA_SIZE;
  316. break;
  317. case USB_HID_SET_IDLE_REQUEST :
  318. /* set the idle rate sent by the host */
  319. g_class_request_params[index] =(uint_8)((setup_packet->value
  320. & MSB_MASK) >> HIGH_BYTE_SHIFT);
  321. break;
  322. case USB_HID_GET_PROTOCOL_REQUEST :
  323. /* point to the current protocol code
  324. 0 = Boot Protocol
  325. 1 = Report Protocol*/
  326. *data = &g_class_request_params[index];
  327. *size = CLASS_REQ_DATA_SIZE;
  328. break;
  329. case USB_HID_SET_PROTOCOL_REQUEST :
  330. /* set the protocol sent by the host
  331. 0 = Boot Protocol
  332. 1 = Report Protocol*/
  333. g_class_request_params[index] = (uint_8)(setup_packet->value);
  334. break;
  335. default :
  336. break;
  337. }
  338. if(g_param_callback != NULL)
  339. {
  340. /*
  341. handle callback if the application has supplied it
  342. set the size of the transfer from the setup packet
  343. */
  344. *size = (USB_PACKET_SIZE)setup_packet->length;
  345. /* notify the application of the class request.
  346. give control to the application */
  347. status = g_param_callback(setup_packet->request,/* request type */
  348. setup_packet->value,
  349. data,/* pointer to the data */
  350. size);/* size of the transfer */
  351. }
  352. }
  353. else if((setup_packet->request_type & USB_REQUEST_CLASS_MASK) ==
  354. USB_REQUEST_CLASS_VENDOR)
  355. {
  356. /* vendor specific request */
  357. if(g_vendor_req_callback != NULL)
  358. {
  359. status = g_vendor_req_callback(controller_ID, setup_packet,data,
  360. size);
  361. }
  362. }
  363. return status;
  364. }
  365. /*****************************************************************************
  366. * Global Functions
  367. *****************************************************************************/
  368. /**************************************************************************//*!
  369. *
  370. * @name USB_Class_HID_Init
  371. *
  372. * @brief The funtion initializes the Device and Controller layer
  373. *
  374. * @param controller_ID : Controller ID
  375. * @param hid_class_callback : HID Class Callback
  376. * @param vendor_req_callback : Vendor Request Callback
  377. * @param param_callback : Class requests Callback
  378. *
  379. * @return status:
  380. * USB_OK : When Successfull
  381. * Others : When Error
  382. *
  383. ******************************************************************************
  384. *This function initializes the HID Class layer and layers it is dependent on
  385. *****************************************************************************/
  386. uint_8 USB_Class_HID_Init (
  387. uint_8 controller_ID, /* [IN] Controller ID */
  388. USB_CLASS_CALLBACK hid_class_callback, /* [IN] HID Class Callback */
  389. USB_REQ_FUNC vendor_req_callback, /* [IN] Vendor Request Callback */
  390. USB_CLASS_SPECIFIC_HANDLER_FUNC param_callback
  391. /* [ IN] HID Class requests Callback */
  392. )
  393. {
  394. uint_8 index,status = USB_OK;
  395. USB_ENDPOINTS *ep_desc_data = (USB_ENDPOINTS *)
  396. USB_Desc_Get_Endpoints(controller_ID);
  397. #ifndef COMPOSITE_DEV
  398. /* Initialize the device layer*/
  399. status = _usb_device_init(controller_ID, NULL,
  400. (uint_8)(ep_desc_data->count+1), TRUE);
  401. if(status == USB_OK)
  402. {
  403. /* Initialize the generic class functions */
  404. status = USB_Class_Init(controller_ID,USB_Class_Hid_Event,
  405. USB_Other_Requests);
  406. if(status == USB_OK)
  407. {
  408. #endif
  409. g_hid_endpoint_data.count = ep_desc_data->count;
  410. for(index = 0; index < ep_desc_data->count; index++)
  411. {
  412. g_hid_endpoint_data.ep[index].endpoint =
  413. ep_desc_data->ep[index].ep_num;
  414. g_hid_endpoint_data.ep[index].type =
  415. ep_desc_data->ep[index].type;
  416. g_hid_endpoint_data.ep[index].bin_consumer = 0x00;
  417. g_hid_endpoint_data.ep[index].bin_producer = 0x00;
  418. }
  419. /* save the HID class callback pointer */
  420. g_hid_class_callback = hid_class_callback;
  421. /* save the vendor request callback pointer */
  422. g_vendor_req_callback = vendor_req_callback;
  423. /* Save the callback to ask application for class specific params*/
  424. g_param_callback = param_callback;
  425. #ifndef COMPOSITE_DEV
  426. }
  427. }
  428. #endif
  429. return status;
  430. }
  431. /**************************************************************************//*!
  432. *
  433. * @name USB_Class_HID_DeInit
  434. *
  435. * @brief The funtion de-initializes the Device and Controller layer
  436. *
  437. * @param controller_ID : Controller ID
  438. *
  439. * @return status:
  440. * USB_OK : When Successfull
  441. * Others : When Error
  442. *
  443. ******************************************************************************
  444. *This function de-initializes the HID Class layer
  445. *****************************************************************************/
  446. uint_8 USB_Class_HID_DeInit
  447. (
  448. uint_8 controller_ID /* [IN] Controller ID */
  449. )
  450. {
  451. uint_8 status = USB_OK;
  452. #ifdef COMPOSITE_DEV
  453. UNUSED(controller_ID)
  454. #endif
  455. /* free the HID class callback pointer */
  456. g_hid_class_callback = NULL;
  457. /* free the vendor request callback pointer */
  458. g_vendor_req_callback = NULL;
  459. /* free the callback to ask application for class specific params*/
  460. g_param_callback = NULL;
  461. #ifndef COMPOSITE_DEV
  462. /* Call common class deinit function */
  463. status = USB_Class_DeInit(controller_ID);
  464. if(status == USB_OK)
  465. /* Call device deinit function */
  466. status = _usb_device_deinit();
  467. #endif
  468. return status;
  469. }
  470. /**************************************************************************//*!
  471. *
  472. * @name USB_Class_HID_Send_Data
  473. *
  474. * @brief This fucntion is used by Application to send data through HID class
  475. *
  476. * @param controller_ID : Controller ID
  477. * @param ep_num : Endpoint number
  478. * @param app_buff : Buffer to send
  479. * @param size : Length of the transfer
  480. *
  481. * @return status:
  482. * USB_OK : When Successfull
  483. * Others : When Error
  484. *
  485. ******************************************************************************
  486. * This function is used by Application to send data through HID class
  487. *****************************************************************************/
  488. uint_8 USB_Class_HID_Send_Data (
  489. uint_8 controller_ID, /* [IN] Controller ID */
  490. uint_8 ep_num, /* [IN] Endpoint Number */
  491. uint_8_ptr app_buff, /* [IN] Buffer to Send */
  492. USB_PACKET_SIZE size /* [IN] Length of the Transfer */
  493. )
  494. {
  495. uint_8 index;
  496. //volatile uint_8 producer, consumer;
  497. uint_8 producer, consumer;
  498. uint_8 status = USB_OK;
  499. USB_ENDPOINTS *ep_desc_data = (USB_ENDPOINTS *)
  500. USB_Desc_Get_Endpoints(controller_ID);
  501. /* map the endpoint num to the index of the endpoint structure */
  502. index = USB_Map_Ep_To_Struct_Index(controller_ID, ep_num);
  503. producer = g_hid_endpoint_data.ep[index].bin_producer;
  504. consumer = g_hid_endpoint_data.ep[index].bin_consumer;
  505. if((uint_8)(producer - consumer) != (uint_8)(MAX_QUEUE_ELEMS))
  506. {
  507. /* the bin is not full*/
  508. uint_8 queue_num = (uint_8)(producer % MAX_QUEUE_ELEMS);
  509. /* queue the send request */
  510. /* put all send request parameters in the endpoint data structure */
  511. g_hid_endpoint_data.ep[index].queue[queue_num].controller_ID =
  512. controller_ID;
  513. g_hid_endpoint_data.ep[index].queue[queue_num].channel = ep_num;
  514. g_hid_endpoint_data.ep[index].queue[queue_num].app_buff = app_buff;
  515. g_hid_endpoint_data.ep[index].queue[queue_num].size = size;
  516. /* increment producer bin by 1*/
  517. g_hid_endpoint_data.ep[index].bin_producer++;
  518. producer++;
  519. if((uint_8)(producer - consumer) == (uint_8)1)
  520. {
  521. /* send the IO if there is only one element in the queue */
  522. status = USB_Class_Send_Data(controller_ID, ep_num, app_buff,size);
  523. }
  524. }
  525. else /* bin is full */
  526. {
  527. status = USBERR_DEVICE_BUSY;
  528. }
  529. return status;
  530. }