drv_usb_dev.h
12.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
/*!
\file drv_usb_dev.h
\brief USB device low level driver header file
\version 2020-08-01, V3.0.0, firmware for GD32F30x
\version 2020-12-07, V3.0.1, firmware for GD32F30x
\version 2022-06-10, V3.1.0, firmware for GD32F30x
*/
/*
Copyright (c) 2022, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/
#ifndef __DRV_USB_DEV_H
#define __DRV_USB_DEV_H
#include "usbd_conf.h"
#include "drv_usb_core.h"
enum usb_ctl_status
{
USB_CTL_IDLE = 0U, /*!< USB control transfer idle state */
USB_CTL_DATA_IN, /*!< USB control transfer data in state */
USB_CTL_LAST_DATA_IN, /*!< USB control transfer last data in state */
USB_CTL_DATA_OUT, /*!< USB control transfer data out state */
USB_CTL_LAST_DATA_OUT, /*!< USB control transfer last data out state */
USB_CTL_STATUS_IN, /*!< USB control transfer status in state*/
USB_CTL_STATUS_OUT /*!< USB control transfer status out state */
};
#define EP_IN(x) ((uint8_t)(0x80U | (x))) /*!< device IN endpoint */
#define EP_OUT(x) ((uint8_t)(x)) /*!< device OUT endpoint */
/* USB descriptor */
typedef struct _usb_desc
{
uint8_t *dev_desc; /*!< device descriptor */
uint8_t *config_desc; /*!< configure descriptor */
uint8_t *bos_desc; /*!< BOS descriptor */
void* const *strings; /*!< string descriptor */
} usb_desc;
/* USB power management */
typedef struct _usb_pm
{
uint8_t power_mode; /*!< power mode */
uint8_t power_low; /*!< power low */
uint8_t dev_remote_wakeup; /*!< remote wakeup */
uint8_t remote_wakeup_on; /*!< remote wakeup on */
} usb_pm;
/* USB control information */
typedef struct _usb_control
{
usb_req req; /*!< USB standard device request */
uint8_t ctl_state; /*!< USB control transfer state */
uint8_t ctl_zlp; /*!< zero length package */
} usb_control;
typedef struct
{
struct {
uint8_t num: 4; /*!< the endpoint number.it can be from 0 to 6 */
uint8_t pad: 3; /*!< padding between number and direction */
uint8_t dir: 1; /*!< the endpoint direction */
} ep_addr;
uint8_t ep_type; /*!< USB endpoint type */
uint8_t ep_stall; /*!< USB endpoint stall status */
uint8_t frame_num; /*!< number of frame */
uint16_t max_len; /*!< Maximum packet length */
/* transaction level variables */
uint8_t *xfer_buf; /*!< transmit buffer */
uint32_t xfer_len; /*!< transmit buffer length */
uint32_t xfer_count; /*!< transmit buffer count */
uint32_t remain_len; /*!< remain packet length */
} usb_transc;
typedef struct _usb_core_driver usb_dev;
typedef struct _usb_class_core
{
uint8_t command; /*!< device class request command */
uint8_t alter_set; /*!< alternative set */
uint8_t (*init) (usb_dev *udev, uint8_t config_index); /*!< initialize handler */
uint8_t (*deinit) (usb_dev *udev, uint8_t config_index); /*!< de-initialize handler */
uint8_t (*req_proc) (usb_dev *udev, usb_req *req); /*!< device request handler */
uint8_t (*set_intf) (usb_dev *udev, usb_req *req); /*!< device set interface callback */
uint8_t (*ctlx_in) (usb_dev *udev); /*!< device contrl in callback */
uint8_t (*ctlx_out) (usb_dev *udev); /*!< device contrl out callback */
uint8_t (*data_in) (usb_dev *udev, uint8_t ep_num); /*!< device data in handler */
uint8_t (*data_out) (usb_dev *udev, uint8_t ep_num); /*!< device data out handler */
uint8_t (*SOF) (usb_dev *udev); /*!< Start of frame handler */
uint8_t (*incomplete_isoc_in) (usb_dev *udev); /*!< Incomplete synchronization IN transfer handler */
uint8_t (*incomplete_isoc_out) (usb_dev *udev); /*!< Incomplete synchronization OUT transfer handler */
} usb_class_core;
typedef struct _usb_perp_dev
{
uint8_t config; /*!< configuration */
uint8_t dev_addr; /*!< device address */
__IO uint8_t cur_status; /*!< current status */
__IO uint8_t backup_status; /*!< backup status */
usb_transc transc_in[USBFS_MAX_TX_FIFOS]; /*!< endpoint IN transaction */
usb_transc transc_out[USBFS_MAX_TX_FIFOS]; /*!< endpoint OUT transaction */
usb_pm pm; /*!< power management */
usb_control control; /*!< USB control information */
usb_desc *desc; /*!< USB descriptors pointer */
usb_class_core *class_core; /*!< class driver */
void *class_data[USBD_ITF_MAX_NUM]; /*!< class data pointer */
void *user_data; /*!< user data pointer */
void *pdata; /*!< reserved data pointer */
} usb_perp_dev;
typedef struct _usb_core_driver
{
usb_core_basic bp; /*!< USB basic parameters */
usb_core_regs regs; /*!< USB registers */
usb_perp_dev dev; /*!< USB peripheral device */
} usb_core_driver;
/* static inline function definitions */
/*!
\brief configure the USB device to be disconnected
\param[in] udev: pointer to USB device
\param[out] none
\retval operation status
*/
__STATIC_INLINE void usb_dev_disconnect (usb_core_driver *udev)
{
udev->regs.dr->DCTL |= DCTL_SD;
}
/*!
\brief configure the USB device to be connected
\param[in] udev: pointer to USB device
\param[out] none
\retval operation status
*/
__STATIC_INLINE void usb_dev_connect (usb_core_driver *udev)
{
udev->regs.dr->DCTL &= ~DCTL_SD;
}
/*!
\brief set the USB device address
\param[in] udev: pointer to USB device
\param[in] dev_addr: device address for setting
\param[out] none
\retval operation status
*/
__STATIC_INLINE void usb_devaddr_set (usb_core_driver *udev, uint8_t dev_addr)
{
udev->regs.dr->DCFG &= ~DCFG_DAR;
udev->regs.dr->DCFG |= (uint32_t)dev_addr << 4U;
}
/*!
\brief read device all OUT endpoint interrupt register
\param[in] udev: pointer to USB device
\param[out] none
\retval interrupt status
*/
__STATIC_INLINE uint32_t usb_oepintnum_read (usb_core_driver *udev)
{
uint32_t value = udev->regs.dr->DAEPINT;
value &= udev->regs.dr->DAEPINTEN;
return (value & DAEPINT_OEPITB) >> 16U;
}
/*!
\brief read device OUT endpoint interrupt flag register
\param[in] udev: pointer to USB device
\param[in] ep_num: endpoint number
\param[out] none
\retval interrupt status
*/
__STATIC_INLINE uint32_t usb_oepintr_read (usb_core_driver *udev, uint8_t ep_num)
{
uint32_t value = udev->regs.er_out[ep_num]->DOEPINTF;
value &= udev->regs.dr->DOEPINTEN;
return value;
}
/*!
\brief read device all IN endpoint interrupt register
\param[in] udev: pointer to USB device
\param[out] none
\retval interrupt status
*/
__STATIC_INLINE uint32_t usb_iepintnum_read (usb_core_driver *udev)
{
uint32_t value = udev->regs.dr->DAEPINT;
value &= udev->regs.dr->DAEPINTEN;
return value & DAEPINT_IEPITB;
}
/*!
\brief set remote wakeup signaling
\param[in] udev: pointer to USB device
\param[out] none
\retval none
*/
__STATIC_INLINE void usb_rwkup_set (usb_core_driver *udev)
{
if (udev->dev.pm.dev_remote_wakeup) {
/* enable remote wakeup signaling */
udev->regs.dr->DCTL |= DCTL_RWKUP;
}
}
/*!
\brief reset remote wakeup signaling
\param[in] udev: pointer to USB device
\param[out] none
\retval none
*/
__STATIC_INLINE void usb_rwkup_reset (usb_core_driver *udev)
{
if (udev->dev.pm.dev_remote_wakeup) {
/* disable remote wakeup signaling */
udev->regs.dr->DCTL &= ~DCTL_RWKUP;
}
}
/* function declarations */
/* initialize USB core registers for device mode */
usb_status usb_devcore_init (usb_core_driver *udev);
/* enable the USB device mode interrupts */
usb_status usb_devint_enable (usb_core_driver *udev);
/* active the USB endpoint 0 transaction */
usb_status usb_transc0_active (usb_core_driver *udev, usb_transc *transc);
/* active the USB transaction */
usb_status usb_transc_active (usb_core_driver *udev, usb_transc *transc);
/* deactivate the USB transaction */
usb_status usb_transc_deactivate (usb_core_driver *udev, usb_transc *transc);
/* configure USB transaction to start IN transfer */
usb_status usb_transc_inxfer (usb_core_driver *udev, usb_transc *transc);
/* configure USB transaction to start OUT transfer */
usb_status usb_transc_outxfer (usb_core_driver *udev, usb_transc *transc);
/* set the USB transaction STALL status */
usb_status usb_transc_stall (usb_core_driver *udev, usb_transc *transc);
/* clear the USB transaction STALL status */
usb_status usb_transc_clrstall (usb_core_driver *udev, usb_transc *transc);
/* read device IN endpoint interrupt flag register */
uint32_t usb_iepintr_read (usb_core_driver *udev, uint8_t ep_num);
/* configures OUT endpoint 0 to receive SETUP packets */
void usb_ctlep_startout (usb_core_driver *udev);
/* active remote wakeup signaling */
void usb_rwkup_active (usb_core_driver *udev);
/* active USB core clock */
void usb_clock_active (usb_core_driver *udev);
/* USB device suspend */
void usb_dev_suspend (usb_core_driver *udev);
/* stop the device and clean up FIFOs */
void usb_dev_stop (usb_core_driver *udev);
#endif /* __DRV_USB_DEV_H */