1 /******************************************************************************* 2 * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions. 3 * 4 * SPDX-License-Identifier: MIT 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 * 24 * PolarFire SoC MSS USB Driver Stack 25 * USB Logical Layer (USB-LL) 26 * USBH-HID class driver. 27 * 28 * USBH-HID driver public API. 29 * 30 */ 31 32 /*=========================================================================*//** 33 @mainpage PolarFire SoC MSS USB driver (USBH-HID) 34 35 ============================================================================== 36 Introduction 37 ============================================================================== 38 The Human Interface Devices host driver implements the USB host controller as 39 per the USB HID class specified by the USB-IF. This driver enables easy 40 detection and data transfers with the attached USB HID devices. 41 The HID Class is used for low bandwidth data exchange. 42 43 This driver implements the HID class using USB Interrupt Transfer. One 44 Control and one BULK IN endpoints are used to implement HID class. This driver 45 uses the USBH driver interface functions to implement the USB HID host. 46 47 ============================================================================== 48 Hardware Flow Dependencies 49 ============================================================================== 50 The configuration of USB Device mode features of the MSS USB is covered by 51 this software stack. There are no dependencies on the hardware flow when 52 configuring the PolarFire SoC MSS USB. 53 The base address and register addresses are defined in this driver as 54 constants. The interrupt number assignment for the MSS USB peripherals are 55 defined as constants in the MPFS HAL. You must ensure that the latest MPFS HAL 56 is included in the project settings of the SoftConsole tool chain and that it 57 is generated into your project. 58 59 ============================================================================== 60 Theory of Operation 61 ============================================================================== 62 The following steps are involved in the operation of USBH-HID driver: 63 - Configuration 64 - Initialization 65 - Application call-back interface 66 - Class Specific requests 67 - Data transfer 68 69 -------------------------------- 70 Configuration 71 -------------------------------- 72 The MSS USB driver must first be configured in the USB Host mode using the 73 MSS_USB_HOST_MODE to use this driver. No other configuration is necessary. 74 75 -------------------------------- 76 Initialization 77 -------------------------------- 78 The HID class driver must be initialized using the MSS_USBH_HID_init() function. 79 A pointer to the structure of type mss_usbh_hid_user_cb_t must be provided as 80 parameter with this function. This pointer is used to call the application 81 call-back functions by the USBH-HID driver. These call-back functions can be 82 used by the application to provide error/status messages to the user or for 83 performing application specific handling of the events. 84 85 -------------------------------- 86 Application call-back interface 87 -------------------------------- 88 Application call-back interface 89 After the USBH-Class driver is assigned to the attached device by the USBH 90 driver, as indicated by usbh_class_allocate call-back, this driver can take 91 over the communication with the attached device. This driver will then extend 92 the enumeration process by requesting the class specific information from the 93 device. During this process it will also call the call-back functions to 94 indicate the progress of the enumeration process. These call-back functions 95 must be implemented by application. These call-back functions can be used to 96 take application specific action on specific event or can be used to provide 97 error/status messages to the user. A type mss_usbh_hid_user_cb_t is provided 98 by this driver which has all these call-back functions as its elements. 99 Implementing these call-back functions is optional. 100 101 -------------------------------- 102 Data transfer 103 -------------------------------- 104 All data is exchanged between the host and the device in the form of reports. 105 The format of the report is defined by the report descriptor defined by the 106 device based on device need. USB HOST will request the report descriptor 107 using interrupt transfers. Every HID device needs to have one input report 108 in its report descriptor. An interrupt IN endpoint is required for reading 109 reports from USB device. The interrupt OUT endpoint is optional. 110 The HID class uses Interrupt Transfer mode, a maximum of 64 bytes can be 111 transferred in a single frame (i.e., 64 Kbyte/s per endpoint when operating 112 in Full-Speed mode).The USB Host driver needs to make sure that the data is 113 polled periodically. 114 115 This driver only needs to perform the USB IN transfers on the Interrupt 116 endpoint. The period at which this transfer is repeated is defined by the 117 device endpoint descriptor during the enumeration process. The application 118 must call the USBH_HID_Handle() function periodically to read the report from 119 the HID device. The application must register the call back function which 120 will be called by the USBH driver when the report is received. 121 122 *//*=========================================================================*/ 123 124 #ifndef __MSS_USB_HOST_HID_H_ 125 #define __MSS_USB_HOST_HID_H_ 126 127 #include <stdint.h> 128 #include "mss_usb_config.h" 129 130 #ifdef __cplusplus 131 extern "C" { 132 #endif 133 134 #ifdef MSS_USB_HOST_ENABLED 135 136 /*-------------------------------------------------------------------------*//** 137 Types exported from USBH-HID driver 138 ============================ 139 */ 140 141 /*-------------------------------------------------------------------------*//** 142 The mss_usbh_HID_err_code_t provides a type to identify the error occurred 143 during retrieving configuration and other class specific descriptors from the 144 attached HID class device. This type can be used with hidh_error call-back 145 function element of mss_usbh_hid_user_cb_t type to identify the exact cause 146 of the error. The meaning of the constants is as described below 147 148 | Constant | Description | 149 |-------------------------------|----------------------------------------------| 150 | USBH_HID_EP_NOT_VALID | Indicates that the endpoint information | 151 | | retrieved from the attached device was not | 152 | | consistent with the HID class. | 153 | | | 154 | USBH_HID_CLR_CEP_STALL_ERROR | Indicates that the host controller was not | 155 | | able to clear the stall condition on the | 156 | | attached device even after multiple retries. | 157 158 */ 159 typedef enum mss_usbh_hid_err_code 160 { 161 USBH_HID_NO_ERROR = 0, 162 USBH_HID_EP_NOT_VALID = -1, 163 USBH_HID_CLR_CEP_STALL_ERROR = -2, 164 USBH_HID_WRONG_DESCR = -3, 165 166 } mss_usbh_hid_err_code_t; 167 168 /*-------------------------------------------------------------------------*//** 169 The mss_usbh_HID_state_t provides a type for the states of operation of the 170 USBH-HID driver. Most of the states are internally used by the USBH-HID driver 171 during the enumeration process. The USBH-HID driver is ready to perform data 172 transfers with the attached device when the driver is in state 173 USBH_HID_DEVICE_READY. The USBH_HID_ERROR state indicates that the error was 174 detected either during enumeration or during the normal data transfer 175 operations with the attached device even after retries. 176 */ 177 typedef enum mss_usbh_hid_state 178 { 179 USBH_HID_IDLE, 180 USBH_HID_GET_CLASS_DESCR, 181 USBH_HID_WAIT_GET_CLASS_DESCR, 182 183 USBH_HID_SET_CONFIG, 184 USBH_HID_WAIT_SET_CONFIG, 185 USBH_HID_WAIT_DEV_SETTLE, 186 187 USBH_HID_REQ_GET_REPORT_DESC, 188 USBH_HID_WAIT_REQ_GET_REPORT_DESC, 189 USBH_HID_REQ_SET_IDLE, 190 USBH_HID_WAIT_REQ_SET_IDLE, 191 192 USBH_HID_REQ_GET_HID_DESC, 193 USBH_HID_WAIT_GET_HID_DESC, 194 195 USBH_HID_DEVICE_READY, 196 197 USBH_HID_REQ_SET_PROTOCOL, 198 USBH_HID_WAIT_REQ_SET_PROTOCOL, 199 USBH_HID_DEVICE_RETRY, 200 USBH_HID_ERROR 201 202 } mss_usbh_hid_state_t; 203 204 /*------------------------Public data structures-----------------------------*/ 205 /*-------------------------------- USBH-HID----------------------------------*/ 206 /*----------------------------------------------------------------------------*/ 207 208 /*-------------------------------------------------------------------------*//** 209 The mss_usbh_hid_user_cb_t provides the prototype for all the call-back 210 functions which must be implemented by the user application. The user 211 application must define and initialize a structure of this type and provide 212 the address of that structure as parameter to the MSS_USBH_HID_init() function. 213 214 hidh_valid_config 215 The function pointed by the hidh_valid_config function pointer will be called 216 to indicate that a valid HID class configuration was found on the attached 217 device and the device is configured for this configuration. 218 219 hidh_tdev_ready 220 The function pointed by the hidh_tdev_ready function pointer is called when 221 this driver is able to retrieve all the HID class specific information 222 (including sector size and sector number) from the attached device and is 223 ready to perform the data transfers. 224 225 hidh_driver_released 226 The function pointed by the hidh_driver_released function pointer is called to 227 indicate to the application that this driver is released by the USBH driver. 228 This could be either because the HID class device is now detached or there is 229 permanent error with the USBH driver. 230 231 hidh_error 232 The function pointed by the hidh_error function pointer is called to indicate 233 that there was an error while retrieving the class specific descriptor 234 information from the attached HID class device. The error_code parameter 235 indicates the exact cause of the error. 236 237 hidh_decode 238 The function pointed by the hidh_decode function pointer is called to indicate 239 that there is a new report received from the attached HID class device. The 240 data parameter indicates the location of received data present in the internal 241 buffer. 242 243 */ 244 typedef struct mss_usbh_hid_user_cb 245 { 246 void (*hidh_valid_config)(void); 247 void (*hidh_tdev_ready)(void); 248 void (*hidh_driver_released)(void); 249 void (*hidh_error)(int8_t error_code); 250 void (*hidh_decode)(uint8_t *data); 251 252 } mss_usbh_hid_user_cb_t; 253 254 255 /*----------------------------------------------------------------------------*/ 256 /*----------------------MSS USBH-HID Public APIs------------------------------*/ 257 /*----------------------------------------------------------------------------*/ 258 259 260 /*-------------------------------------------------------------------------*//** 261 The MSS_USBH_HID_init() function must be used by the application to initialize 262 the USBH-HID driver. This function must be called before any other function of 263 the USBH-HID driver. 264 265 @param user_cb 266 The user_cb parameter provides a pointer to the structure of type 267 mss_usbh_hid_user_cb_t. This pointer is used to call the application 268 call-back functions by the USBH-HID driver. These call-back functions can 269 be used by the application to provide error/status messages to the user or 270 for performing the application specific handling of the events. 271 272 @return 273 This function does not return a value. 274 275 Example: 276 @code 277 MSS_USBH_init(&MSS_USBH_user_cb); 278 MSS_USBH_HID_init(&MSS_USBH_HID_user_cb); 279 MSS_USBH_register_class_driver(MSS_USBH_HID_get_handle()); 280 @endcode 281 */ 282 void 283 MSS_USBH_HID_init 284 ( 285 mss_usbh_hid_user_cb_t* user_sb 286 ); 287 288 /***************************************************************************//** 289 The MSS_USBH_HID_task() function is the main task of the USBH-HID driver. 290 This function monitors the events from the USBH driver as well as the user 291 application and makes decisions. This function must be called repeatedly by 292 the application to allow the USBH-HID driver to perform the housekeeping 293 tasks.A timer/scheduler can be used to call this function at regular intervals 294 or it can be called from the main continuous foreground loop of the 295 application. 296 297 @param 298 This function does not take any parameters. 299 300 @return 301 This function does not return a value. 302 303 Example: 304 @code 305 @endcode 306 */ 307 void 308 MSS_USBH_HID_task 309 ( 310 void 311 ); 312 313 /***************************************************************************//** 314 The MSS_USBH_HID_get_handle() function must be used by the application to get 315 the handle from the USBH-HID driver. This handle must then be used to register 316 this driver with the USBH driver. 317 318 @param 319 This function does not take any parameters. 320 321 @return 322 This function returns a pointer to the class-handle structure. 323 324 Example: 325 @code 326 MSS_USBH_init(&MSS_USBH_user_cb); 327 MSS_USBH_HID_init(&MSS_USBH_HID_user_cb); 328 MSS_USBH_register_class_driver(MSS_USBH_HID_get_handle()); 329 @endcode 330 */ 331 void* 332 MSS_USBH_HID_get_handle 333 ( 334 void 335 ); 336 337 /***************************************************************************//** 338 The MSS_USBH_HID_get_state() function can be used to find out the current 339 state of the USBH-HID driver. This information can be used by the application 340 to check the readiness of the USBH-HID driver to start the data transfers. The 341 USBH-HID driver can perform data transfers only when it is in the 342 USBH_HID_DEVICE_READY state. 343 344 @param 345 This function does not take any parameters. 346 347 @return 348 This function returns a value of type mss_usbh_hid_state_t indicating the 349 current state of the USBH-HID driver. 350 351 Example: 352 @code 353 if (USBH_HID_DEVICE_READY == MSS_USBH_HID_get_state()) 354 { 355 *result = MSS_USBH_HID_get_sector_count(); 356 return RES_OK; 357 } 358 else if (USBH_HID_DEVICE_READY < MSS_USBH_HID_get_state()) 359 { 360 *result = 0u; 361 return RES_NOTRDY; 362 } 363 @endcode 364 */ 365 mss_usbh_hid_state_t 366 MSS_USBH_HID_get_state 367 ( 368 void 369 ); 370 371 #endif /* MSS_USB_HOST_ENABLED */ 372 373 #ifdef __cplusplus 374 } 375 #endif 376 377 #endif /* __MSS_USB_HOST_HID_H_ */ 378 379