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