1 /*!
2     \file    usbh_core.h
3     \brief   USB host core state machine header file
4 
5     \version 2020-08-04, V1.1.0, firmware for GD32VF103
6 */
7 
8 /*
9     Copyright (c) 2020, GigaDevice Semiconductor Inc.
10 
11     Redistribution and use in source and binary forms, with or without modification,
12 are permitted provided that the following conditions are met:
13 
14     1. Redistributions of source code must retain the above copyright notice, this
15        list of conditions and the following disclaimer.
16     2. Redistributions in binary form must reproduce the above copyright notice,
17        this list of conditions and the following disclaimer in the documentation
18        and/or other materials provided with the distribution.
19     3. Neither the name of the copyright holder nor the names of its contributors
20        may be used to endorse or promote products derived from this software without
21        specific prior written permission.
22 
23     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
32 OF SUCH DAMAGE.
33 */
34 
35 #ifndef __USBH_CORE_H
36 #define __USBH_CORE_H
37 
38 #include "usbh_conf.h"
39 #include "drv_usb_host.h"
40 
41 #define MSC_CLASS                                       0x08U
42 #define HID_CLASS                                       0x03U
43 #define MSC_PROTOCOL                                    0x50U
44 #define CBI_PROTOCOL                                    0x01U
45 
46 #define USBH_MAX_ERROR_COUNT                            3U
47 
48 #define USBH_DEV_ADDR_DEFAULT                           0U
49 #define USBH_DEV_ADDR                                   1U
50 
51 typedef enum
52 {
53     USBH_OK = 0U,
54     USBH_BUSY,
55     USBH_FAIL,
56     USBH_NOT_SUPPORTED,
57     USBH_UNRECOVERED_ERROR,
58     USBH_SPEED_UNKNOWN_ERROR,
59     USBH_APPLY_DEINIT
60 } usbh_status;
61 
62 /* USB host global operation state */
63 typedef enum
64 {
65     HOST_DEFAULT = 0U,
66     HOST_DETECT_DEV_SPEED,
67     HOST_DEV_ATTACHED,
68     HOST_DEV_DETACHED,
69     HOST_ENUM,
70     HOST_SET_WAKEUP_FEATURE,
71     HOST_CHECK_CLASS,
72     HOST_CLASS_ENUM,
73     HOST_CLASS_HANDLER,
74     HOST_USER_INPUT,
75     HOST_SUSPENDED,
76     HOST_WAKEUP,
77     HOST_ERROR
78 } usb_host_state;
79 
80 /* USB host enumeration state */
81 typedef enum
82 {
83     ENUM_DEFAULT = 0U,
84     ENUM_GET_DEV_DESC,
85     ENUM_SET_ADDR,
86     ENUM_GET_CFG_DESC,
87     ENUM_GET_CFG_DESC_SET,
88     ENUM_GET_STR_DESC,
89 #ifdef USB_MTP
90     ENUM_GET_MTP_STR,
91 #endif
92     ENUM_SET_CONFIGURATION,
93     ENUM_DEV_CONFIGURED
94 } usbh_enum_state;
95 
96 /* USB host control transfer state */
97 typedef enum
98 {
99     CTL_IDLE = 0U,
100     CTL_SETUP,
101     CTL_SETUP_WAIT,
102     CTL_DATA_IN,
103     CTL_DATA_IN_WAIT,
104     CTL_DATA_OUT,
105     CTL_DATA_OUT_WAIT,
106     CTL_STATUS_IN,
107     CTL_STATUS_IN_WAIT,
108     CTL_STATUS_OUT,
109     CTL_STATUS_OUT_WAIT,
110     CTL_ERROR,
111     CTL_FINISH
112 } usbh_ctl_state;
113 
114 /* user action state */
115 typedef enum
116 {
117     USBH_USER_NO_RESP = 0U,
118     USBH_USER_RESP_OK = 1U,
119 } usbh_user_status;
120 
121 typedef enum
122 {
123     USBH_PORT_EVENT = 1U,
124     USBH_URB_EVENT,
125     USBH_CONTROL_EVENT,
126     USBH_CLASS_EVENT,
127     USBH_STATE_CHANGED_EVENT,
128 }usbh_os_event;
129 
130 /* control transfer information */
131 typedef struct _usbh_control
132 {
133     uint8_t               pipe_in_num;
134     uint8_t               pipe_out_num;
135     uint8_t               max_len;
136     uint8_t               error_count;
137 
138     uint8_t               *buf;
139     uint16_t              ctl_len;
140     uint16_t              timer;
141 
142     usb_setup             setup;
143     usbh_ctl_state        ctl_state;
144 } usbh_control;
145 
146 /* USB interface descriptor set */
147 typedef struct _usb_desc_itf_set
148 {
149     usb_desc_itf itf_desc;
150     usb_desc_ep  ep_desc[USBH_MAX_EP_NUM];
151 } usb_desc_itf_set;
152 
153 /* USB configure descriptor set */
154 typedef struct _usb_desc_cfg_set
155 {
156     usb_desc_config   cfg_desc;
157     usb_desc_itf_set  itf_desc_set[USBH_MAX_INTERFACES_NUM][USBH_MAX_ALT_SETTING];
158 } usb_desc_cfg_set;
159 
160 /* USB device property */
161 typedef struct
162 {
163     uint8_t                   data[USBH_DATA_BUF_MAX_LEN]; /* if DMA is used, the data array must be located in the first position */
164     uint8_t                   cur_itf;
165     uint8_t                   addr;
166 
167     uint32_t                  speed;
168 
169     usb_desc_dev              dev_desc;
170     usb_desc_cfg_set          cfg_desc_set;
171 
172 #if (USBH_KEEP_CFG_DESCRIPTOR == 1U)
173     uint8_t                   cfgdesc_rawdata[USBH_CFGSET_MAX_LEN];
174 #endif /* (USBH_KEEP_CFG_DESCRIPTOR == 1U) */
175 } usb_dev_prop;
176 
177 struct _usbh_host;
178 
179 /* device class callbacks */
180 typedef struct
181 {
182     uint8_t       class_code;       /*!< USB class type */
183 
184     usbh_status (*class_init)      (struct _usbh_host *phost);
185     void        (*class_deinit)    (struct _usbh_host *phost);
186     usbh_status (*class_requests)  (struct _usbh_host *phost);
187     usbh_status (*class_machine)   (struct _usbh_host *phost);
188     usbh_status (*class_sof)       (struct _usbh_host *puhost);
189 
190     void         *class_data;
191 } usbh_class;
192 
193 /* user callbacks */
194 typedef struct
195 {
196     void (*dev_init)                    (void);
197     void (*dev_deinit)                  (void);
198     void (*dev_attach)                  (void);
199     void (*dev_reset)                   (void);
200     void (*dev_detach)                  (void);
201     void (*dev_over_currented)          (void);
202     void (*dev_speed_detected)          (uint32_t dev_speed);
203     void (*dev_devdesc_assigned)        (void *dev_desc);
204     void (*dev_address_set)             (void);
205 
206     void (*dev_cfgdesc_assigned)        (usb_desc_config *cfg_desc,
207                                          usb_desc_itf *itf_desc,
208                                          usb_desc_ep *ep_desc);
209 
210     void (*dev_mfc_str)                 (void *mfc_str);
211     void (*dev_prod_str)                (void *prod_str);
212     void (*dev_seral_str)               (void *serial_str);
213     void (*dev_enumerated)              (void);
214     usbh_user_status (*dev_user_input)  (void);
215     int  (*dev_user_app)                (void);
216     void (*dev_not_supported)           (void);
217     void (*dev_error)                   (void);
218 } usbh_user_cb;
219 
220 /* host information */
221 typedef struct _usbh_host
222 {
223     usb_host_state                      cur_state;                          /*!< host state machine value */
224     usb_host_state                      backup_state;                       /*!< backup of previous state machine value */
225     usbh_enum_state                     enum_state;                         /*!< enumeration state machine */
226     usbh_control                        control;                            /*!< USB host control state machine */
227     usb_dev_prop                        dev_prop;                           /*!< USB device property */
228 
229     usbh_class                          *uclass[USBH_MAX_SUPPORTED_CLASS];  /*!< USB host supported class */
230     usbh_class                          *active_class;                      /*!< USB active class */
231     usbh_user_cb                        *usr_cb;                            /*!< USB user callback */
232 
233     uint8_t                              class_num;                         /*!< USB class number */
234 
235     void                                *data;                              /*!< used for... */
236 } usbh_host;
237 
238 /*!
239     \brief      get USB URB state
240     \param[in]  pudev: pointer to USB core instance
241     \param[in]  pp_num: pipe number
242     \param[out] none
243     \retval     none
244 */
usbh_urbstate_get(usb_core_driver * pudev,uint8_t pp_num)245 static inline usb_urb_state usbh_urbstate_get (usb_core_driver *pudev, uint8_t pp_num)
246 {
247     return pudev->host.pipe[pp_num].urb_state;
248 }
249 
250 /*!
251     \brief      get USB transfer data count
252     \param[in]  pudev: pointer to USB core instance
253     \param[in]  pp_num: pipe number
254     \param[out] none
255     \retval     none
256 */
usbh_xfercount_get(usb_core_driver * pudev,uint8_t pp_num)257 static inline uint32_t usbh_xfercount_get (usb_core_driver *pudev, uint8_t pp_num)
258 {
259     return pudev->host.backup_xfercount[pp_num];
260 }
261 
262 /* function declarations */
263 /* USB host stack initializations */
264 void usbh_init (usbh_host *puhost, usbh_user_cb *user_cb);
265 /* USB host register device class */
266 usbh_status usbh_class_register (usbh_host *puhost, usbh_class *puclass);
267 /* de-initialize USB host */
268 usbh_status usbh_deinit (usbh_host *puhost);
269 /* USB host core main state machine process */
270 void usbh_core_task (usbh_host *puhost);
271 /* handle the error on USB host side */
272 void usbh_error_handler (usbh_host *puhost, usbh_status err_type);
273 
274 #endif /* __USBH_CORE_H */
275