1 /*!
2 * @file usbd_core.c
3 *
4 * @brief USB protocol core handler
5 *
6 * @version V1.0.1
7 *
8 * @date 2022-09-20
9 *
10 * @attention
11 *
12 * Copyright (C) 2020-2022 Geehy Semiconductor
13 *
14 * You may not use this file except in compliance with the
15 * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16 *
17 * The program is only for reference, which is distributed in the hope
18 * that it will be useful and instructional for customers to develop
19 * their software. Unless required by applicable law or agreed to in
20 * writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21 * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23 * and limitations under the License.
24 */
25
26 /* Includes */
27 #include "usbd_core.h"
28 #include "usbd_stdReq.h"
29
30 /** @addtogroup USB_Driver_Library USB Driver Library
31 @{
32 */
33
34 /** @addtogroup Core_Device Core Device
35 @{
36 */
37
38 /** @addtogroup Standrad
39 @{
40 */
41
42 /** @addtogroup Core
43 @{
44 */
45
46 /** @defgroup Core_Macros Macros
47 @{
48 */
49
50 /**@} end of group Core_Macros */
51
52 /** @defgroup Core_Enumerations Enumerations
53 @{
54 */
55
56 /**@} end of group Core_Enumerations */
57
58 /** @defgroup Core_Structures Structures
59 @{
60 */
61
62 /**@} end of group Core_Structures */
63
64 /** @defgroup Core_Variables Variables
65 @{
66 */
67
68 /* USB information */
69 USBD_Info_T g_usbDev;
70
71 /**@} end of group Core_Variables */
72
73 /** @defgroup Core_Functions Functions
74 @{
75 */
76
77 /*!
78 * @brief Endpoint 0 Setup process
79 *
80 * @param None
81 *
82 * @retval None
83 */
USBD_SetupProcess(void)84 void USBD_SetupProcess(void)
85 {
86 uint8_t reqType;
87 uint8_t dataBuf[8];
88 USBD_DevReqData_T* pReqData = &g_usbDev.reqData;
89 uint16_t xferLen = USBD_ReadEPRxCnt(USBD_EP_0);
90
91 if (xferLen)
92 {
93 USBD_ReadDataFromEP(USBD_EP_0, (uint8_t*)dataBuf, xferLen);
94 }
95 else
96 {
97 return;
98 }
99
100 pReqData->byte.bmRequestType.byte = dataBuf[0];
101 pReqData->byte.bRequest = dataBuf[1];
102 pReqData->byte.wValue[0] = dataBuf[2];
103 pReqData->byte.wValue[1] = dataBuf[3];
104 pReqData->byte.wIndex[0] = dataBuf[4];
105 pReqData->byte.wIndex[1] = dataBuf[5];
106 pReqData->byte.wLength[0] = dataBuf[6];
107 pReqData->byte.wLength[1] = dataBuf[7];
108
109 reqType = pReqData->byte.bmRequestType.bit.type;
110
111 if (reqType == USBD_REQ_TYPE_STANDARD)
112 {
113 USBD_StandardReqeust();
114 }
115 else if (reqType == USBD_REQ_TYPE_CLASS)
116 {
117 if (g_usbDev.classReqHandler)
118 {
119 g_usbDev.classReqHandler(pReqData);
120 }
121 }
122 else if (reqType == USBD_REQ_TYPE_VENDOR)
123 {
124 if (g_usbDev.vendorReqHandler)
125 {
126 g_usbDev.vendorReqHandler(pReqData);
127 }
128 }
129 else
130 {
131 USBD_SetEPTxRxStatus(USBD_EP_0, USBD_EP_STATUS_STALL, USBD_EP_STATUS_STALL);
132 }
133 }
134
135
136 /*!
137 * @brief Endpoint 0 USB Control in process
138 *
139 * @param None
140 *
141 * @retval None
142 */
USBD_CtrlInProcess(void)143 void USBD_CtrlInProcess(void)
144 {
145 uint32_t tmp;
146
147 if (g_usbDev.ctrlState == USBD_CTRL_STATE_DATA_IN)
148 {
149 if (g_usbDev.inBuf[0].packNum)
150 {
151 tmp = USB_MIN(g_usbDev.inBuf[0].bufLen, g_usbDev.inBuf[0].maxPackSize);
152
153 USBD_WriteDataToEP(USBD_EP_0, g_usbDev.inBuf[0].pBuf, tmp);
154 USBD_SetEPTxCnt(USBD_EP_0, tmp);
155 USBD_SetEPTxRxStatus(USBD_EP_0, USBD_EP_STATUS_VALID, USBD_EP_STATUS_NAK);
156
157 g_usbDev.inBuf[0].pBuf += tmp;
158 g_usbDev.inBuf[0].bufLen -= tmp;
159 g_usbDev.inBuf[0].packNum--;
160 }
161 else
162 {
163 if (g_usbDev.inBuf[USBD_EP_0].zeroPackFill)
164 {
165 USBD_SetEPTxCnt(USBD_EP_0, 0);
166 USBD_SetEPTxStatus(USBD_EP_0, USBD_EP_STATUS_VALID);
167 g_usbDev.inBuf[USBD_EP_0].zeroPackFill = 0;
168 }
169 else
170 {
171 if (g_usbDev.rxStatusHandler)
172 {
173 g_usbDev.rxStatusHandler();
174 }
175
176 g_usbDev.ctrlState = USBD_CTRL_STATE_WAIT_STATUS_OUT;
177 USBD_SetEPTxRxStatus(USBD_EP_0, USBD_EP_STATUS_NAK, USBD_EP_STATUS_VALID);
178 }
179
180 }
181 }
182 else if (g_usbDev.ctrlState == USBD_CTRL_STATE_WAIT_STATUS_IN)
183 {
184 if (g_usbDev.reqData.byte.bRequest == USBD_SET_ADDRESS)
185 {
186 USBD_SetDeviceAddr(g_usbDev.reqData.byte.wValue[0]);
187 }
188 }
189 }
190
191 /*!
192 * @brief Endpoint 0 USB Control out process
193 *
194 * @param None
195 *
196 * @retval None
197 */
USBD_CtrlOutProcess(void)198 void USBD_CtrlOutProcess(void)
199 {
200 uint32_t len;
201
202 if (g_usbDev.ctrlState == USBD_CTRL_STATE_DATA_OUT)
203 {
204 if (g_usbDev.outBuf[0].packNum)
205 {
206 len = USB_MIN(g_usbDev.outBuf[0].bufLen, g_usbDev.outBuf[0].maxPackSize);
207
208 USBD_ReadDataFromEP(USBD_EP_0, g_usbDev.outBuf[0].pBuf, len);
209
210 g_usbDev.outBuf[0].bufLen -= len;
211 g_usbDev.outBuf[0].pBuf += len;
212 g_usbDev.outBuf[0].packNum--;
213
214 if (g_usbDev.outBuf[0].packNum)
215 {
216 USBD_CtrlOutData(g_usbDev.outBuf[0].pBuf, g_usbDev.outBuf[0].bufLen);
217 }
218 else
219 {
220 USBD_CtrlTxStatus();
221 }
222 }
223 else
224 {
225 if (g_usbDev.txStatusHandler)
226 {
227 g_usbDev.txStatusHandler();
228 }
229
230 USBD_CtrlTxStatus();
231 }
232 }
233 }
234
235 /*!
236 * @brief Send data or status in control in transation
237 *
238 * @param buf: Buffer pointer
239 *
240 * @param len: Buffer length
241 *
242 * @retval None
243 */
USBD_CtrlInData(uint8_t * buf,uint32_t len)244 void USBD_CtrlInData(uint8_t* buf, uint32_t len)
245 {
246 uint16_t maxPackSize = g_usbDev.inBuf[0].maxPackSize;
247 uint16_t reqLen = *(uint16_t*)g_usbDev.reqData.byte.wLength;
248
249 if (len)
250 {
251 if ((len < reqLen) && ((len % maxPackSize) == 0))
252 {
253 g_usbDev.inBuf[USBD_EP_0].zeroPackFill = 1;
254 }
255
256 if (len >= g_usbDev.inBuf[0].maxPackSize)
257 {
258 /* Send a packet */
259 USBD_WriteDataToEP(USBD_EP_0, buf, g_usbDev.inBuf[0].maxPackSize);
260 USBD_SetEPTxCnt(USBD_EP_0, g_usbDev.inBuf[0].maxPackSize);
261 USBD_SetEPTxRxStatus(USBD_EP_0, USBD_EP_STATUS_VALID, USBD_EP_STATUS_NAK);
262
263 /* deal with buffer */
264 g_usbDev.inBuf[0].bufLen = len - g_usbDev.inBuf[0].maxPackSize;
265 g_usbDev.inBuf[0].pBuf = buf + g_usbDev.inBuf[0].maxPackSize;
266 g_usbDev.inBuf[0].packNum = (g_usbDev.inBuf[0].bufLen + (maxPackSize - 1)) / maxPackSize;
267
268 g_usbDev.ctrlState = USBD_CTRL_STATE_DATA_IN;
269 }
270 else
271 {
272 USBD_WriteDataToEP(USBD_EP_0, buf, len);
273 USBD_SetEPTxCnt(USBD_EP_0, len);
274 USBD_SetEPTxRxStatus(USBD_EP_0, USBD_EP_STATUS_VALID, USBD_EP_STATUS_NAK);
275
276 g_usbDev.ctrlState = g_usbDev.reqData.byte.bmRequestType.bit.dir ? \
277 USBD_CTRL_STATE_DATA_IN : \
278 USBD_CTRL_STATE_WAIT_STATUS_IN;
279 }
280 }
281 else
282 {
283 USBD_SetEPTxCnt(USBD_EP_0, 0);
284 USBD_SetEPTxStatus(USBD_EP_0, USBD_EP_STATUS_VALID);
285
286 g_usbDev.ctrlState = g_usbDev.reqData.byte.bmRequestType.bit.dir ? \
287 USBD_CTRL_STATE_DATA_IN : \
288 USBD_CTRL_STATE_WAIT_STATUS_IN;
289 }
290 }
291
292 /*!
293 * @brief Read data or status in control out transation
294 *
295 * @param buf: Buffer pointer
296 *
297 * @param len: Buffer length
298 *
299 * @retval None
300 */
USBD_CtrlOutData(uint8_t * buf,uint32_t len)301 void USBD_CtrlOutData(uint8_t* buf, uint32_t len)
302 {
303 uint16_t maxPackSize = g_usbDev.outBuf[USBD_EP_0].maxPackSize;
304
305 if (len)
306 {
307 g_usbDev.outBuf[USBD_EP_0].pBuf = buf;
308 g_usbDev.outBuf[USBD_EP_0].bufLen = len;
309 g_usbDev.outBuf[USBD_EP_0].packNum = (len + (maxPackSize - 1)) / maxPackSize;
310
311 len = USB_MIN(g_usbDev.outBuf[0].bufLen, maxPackSize);
312
313 USBD_SetEPTxRxStatus(USBD_EP_0, USBD_EP_STATUS_NAK, USBD_EP_STATUS_VALID);
314
315 g_usbDev.ctrlState = USBD_CTRL_STATE_DATA_OUT;
316 }
317 else
318 {
319 g_usbDev.ctrlState = USBD_CTRL_STATE_WAIT_STATUS_OUT;
320 }
321
322 USBD_SetEPTxRxStatus(USBD_EP_0, USBD_EP_STATUS_NAK, USBD_EP_STATUS_VALID);
323 }
324
325 /*!
326 * @brief USB Data in process except endpoint 0
327 *
328 * @param ep : endpoint Number except endpoint 0
329 *
330 * @retval None
331 */
USBD_DataInProcess(USBD_EP_T ep)332 void USBD_DataInProcess(USBD_EP_T ep)
333 {
334 uint16_t len;
335
336 if (g_usbDev.inBuf[ep].packNum)
337 {
338 len = g_usbDev.inBuf[ep].bufLen > g_usbDev.inBuf[ep].maxPackSize ? \
339 g_usbDev.inBuf[ep].maxPackSize : g_usbDev.inBuf[ep].bufLen;
340
341
342 USBD_WriteDataToEP(ep, g_usbDev.inBuf[ep].pBuf, len);
343 USBD_SetEPTxCnt(ep, len);
344 USBD_SetEPTxStatus(ep, USBD_EP_STATUS_VALID);
345
346 g_usbDev.inBuf[ep].pBuf += len;
347 g_usbDev.inBuf[ep].bufLen -= len;
348 g_usbDev.inBuf[ep].packNum--;
349 }
350 else
351 {
352 if (g_usbDev.inEpHandler)
353 {
354 g_usbDev.inEpHandler(ep);
355 }
356 }
357 }
358
359 /*!
360 * @brief USB Data out process except endpoint 0
361 *
362 * @param ep : endpoint Number except endpoint 0
363 *
364 * @retval None
365 */
USBD_DataOutProcess(USBD_EP_T ep)366 void USBD_DataOutProcess(USBD_EP_T ep)
367 {
368 if (g_usbDev.outBuf[ep].packNum)
369 {
370 g_usbDev.outBuf[ep].xferCnt = USBD_ReadEPRxCnt(ep);
371
372 if ((g_usbDev.outBuf[ep].xferCnt != 0) && (g_usbDev.outBuf[ep].pBuf != NULL))
373 {
374 USBD_ReadDataFromEP(ep, g_usbDev.outBuf[ep].pBuf, g_usbDev.outBuf[ep].xferCnt);
375
376 g_usbDev.outBuf[ep].bufLen -= g_usbDev.outBuf[ep].xferCnt;
377 g_usbDev.outBuf[ep].pBuf += g_usbDev.outBuf[ep].xferCnt;
378 g_usbDev.outBuf[ep].packNum--;
379 }
380 if (g_usbDev.outBuf[ep].packNum)
381 {
382 USBD_SetEPRxStatus(ep, USBD_EP_STATUS_VALID);
383 }
384 }
385
386 if (g_usbDev.outEpHandler && !g_usbDev.outBuf[ep].packNum)
387 {
388 g_usbDev.outEpHandler(ep);
389 }
390 }
391
392 /*!
393 * @brief Transfer data to host(except endpoint 0)
394 *
395 * @param ep: Endpoint number except endpoint 0
396 *
397 * @param buf: Buffer pointer
398 *
399 * @param len: Buffer length
400 *
401 * @retval None
402 */
USBD_TxData(uint8_t ep,uint8_t * buf,uint32_t len)403 void USBD_TxData(uint8_t ep, uint8_t* buf, uint32_t len)
404 {
405 uint16_t maxPackSize = g_usbDev.inBuf[ep].maxPackSize;
406
407 if (len >= maxPackSize)
408 {
409 USBD_WriteDataToEP(ep, buf, maxPackSize);
410 USBD_SetEPTxCnt(ep, maxPackSize);
411 USBD_SetEPTxStatus(ep, USBD_EP_STATUS_VALID);
412
413 g_usbDev.inBuf[ep].pBuf = buf + maxPackSize;
414 g_usbDev.inBuf[ep].bufLen = len - maxPackSize;
415 g_usbDev.inBuf[ep].packNum = (g_usbDev.inBuf[ep].bufLen + (maxPackSize - 1)) / maxPackSize;
416 }
417 else
418 {
419 USBD_WriteDataToEP(ep, buf, len);
420 USBD_SetEPTxCnt(ep, len);
421 USBD_SetEPTxStatus(ep, USBD_EP_STATUS_VALID);
422
423 g_usbDev.inBuf[ep].packNum = 0;
424 g_usbDev.inBuf[ep].bufLen = 0;
425 }
426 }
427
428 /*!
429 * @brief Receive data from host(except endpoint 0)
430 *
431 * @param ep: Endpoint number except endpoint 0
432 *
433 * @param buf: Buffer pointer
434 *
435 * @param len: Buffer length
436 *
437 * @retval None
438 */
USBD_RxData(uint8_t ep,uint8_t * buf,uint32_t len)439 void USBD_RxData(uint8_t ep, uint8_t* buf, uint32_t len)
440 {
441 uint16_t maxPackSize = g_usbDev.outBuf[ep].maxPackSize;
442
443 g_usbDev.outBuf[ep].pBuf = buf;
444 g_usbDev.outBuf[ep].bufLen = len;
445 g_usbDev.outBuf[ep].packNum = (len + (maxPackSize - 1)) / maxPackSize;
446
447 USBD_SetEPRxCnt(ep, USB_MIN(len, maxPackSize));
448
449 USBD_SetEPRxStatus(ep, USBD_EP_STATUS_VALID);
450 }
451
452 /**@} end of group Core_Functions */
453 /**@} end of group Core */
454 /**@} end of group Standard */
455 /**@} end of group Core_Device */
456 /**@} end of group USB_Driver_Library */
457