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