1 /*!
2  * @file        apm32e10x_usb.c
3  *
4  * @brief       This file contains all the functions for the USBD peripheral
5  *
6  * @version     V1.0.2
7  *
8  * @date        2022-12-31
9  *
10  * @attention
11  *
12  *  Copyright (C) 2021-2023 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 #include "apm32e10x_usb.h"
27 
28 /** @addtogroup APM32E10x_StdPeriphDriver
29   @{
30 */
31 
32 /** @addtogroup USBD_Driver
33   * @brief USBD driver modules
34   @{
35 */
36 
37 /** @defgroup USBD_Functions Functions
38   @{
39 */
40 
41 /*!
42  * @brief       Set Endpoint type
43  *
44  * @param       ep: Endpoint number
45  *
46  * @param       type: Endpoint type
47  *
48  * @retval      None
49  */
USBD_SetEPType(USBD_EP_T ep,USBD_EP_TYPE_T type)50 void USBD_SetEPType(USBD_EP_T ep, USBD_EP_TYPE_T type)
51 {
52     __IOM uint32_t reg;
53 
54     reg = USBD->EP[ep].EP;
55 
56     reg &= (uint32_t)(USBD_EP_MASK_DEFAULT);
57     reg &= ~USBD_EP_BIT_TYPE;
58     reg |= type << 9;
59 
60     USBD->EP[ep].EP = reg;
61 }
62 
63 /*!
64  * @brief       Set EP kind
65  *
66  * @param       ep: Endpoint number
67  *
68  * @retval      None
69  */
USBD_SetEPKind(USBD_EP_T ep)70 void USBD_SetEPKind(USBD_EP_T ep)
71 {
72     __IOM uint32_t reg;
73 
74     reg = USBD->EP[ep].EP;
75 
76     reg &= (uint32_t)(USBD_EP_MASK_DEFAULT);
77     reg |= USBD_EP_BIT_KIND;
78 
79     USBD->EP[ep].EP = reg;
80 }
81 
82 /*!
83  * @brief       Reset EP kind
84  *
85  * @param       ep: Endpoint number
86  *
87  * @retval      None
88  */
USBD_ResetEPKind(USBD_EP_T ep)89 void USBD_ResetEPKind(USBD_EP_T ep)
90 {
91     __IOM uint32_t reg;
92 
93     reg = USBD->EP[ep].EP;
94 
95     reg &= (uint32_t)(USBD_EP_MASK_DEFAULT);
96     reg &= ~USBD_EP_BIT_KIND;
97 
98     USBD->EP[ep].EP = reg;
99 }
100 
101 
102 /*!
103  * @brief       Reset EP CTFR bit
104  *
105  * @param       ep: Endpoint number
106  *
107  * @retval      None
108  */
USBD_ResetEPRxFlag(USBD_EP_T ep)109 void USBD_ResetEPRxFlag(USBD_EP_T ep)
110 {
111     __IOM uint32_t reg;
112 
113     reg = USBD->EP[ep].EP;
114 
115     reg &= (uint32_t)(USBD_EP_MASK_DEFAULT);
116     reg &= ~USBD_EP_BIT_CTFR;
117 
118     USBD->EP[ep].EP = reg;
119 }
120 
121 /*!
122  * @brief       Reset EP CTFT bit
123  *
124  * @param       ep: Endpoint number
125  *
126  * @retval      None
127  */
USBD_ResetEPTxFlag(USBD_EP_T ep)128 void USBD_ResetEPTxFlag(USBD_EP_T ep)
129 {
130     __IOM uint32_t reg;
131 
132     reg = USBD->EP[ep].EP;
133 
134     reg &= (uint32_t)(USBD_EP_MASK_DEFAULT);
135     reg &= ~USBD_EP_BIT_CTFT;
136 
137     USBD->EP[ep].EP = reg;
138 }
139 
140 /*!
141  * @brief       Toggle Tx DTOG
142  *
143  * @param       ep: Endpoint number
144  *
145  * @retval      None
146  */
USBD_ToggleTx(USBD_EP_T ep)147 void USBD_ToggleTx(USBD_EP_T ep)
148 {
149     __IOM uint32_t reg;
150 
151     reg = USBD->EP[ep].EP;
152 
153     reg &= (uint32_t)(USBD_EP_MASK_DEFAULT);
154     reg |= USBD_EP_BIT_TXDTOG;
155 
156     USBD->EP[ep].EP = reg;
157 }
158 
159 /*!
160  * @brief       Toggle Rx DTOG
161  *
162  * @param       ep: Endpoint number
163  *
164  * @retval      None
165  */
USBD_ToggleRx(USBD_EP_T ep)166 void USBD_ToggleRx(USBD_EP_T ep)
167 {
168     __IOM uint32_t reg;
169 
170     reg = USBD->EP[ep].EP;
171 
172     reg &= (uint32_t)(USBD_EP_MASK_DEFAULT);
173     reg |= USBD_EP_BIT_RXDTOG;
174 
175     USBD->EP[ep].EP = reg;
176 }
177 
178 /*!
179  * @brief       Reset Toggle Tx DTOG
180  *
181  * @param       ep: Endpoint number
182  *
183  * @retval      None
184  */
USBD_ResetTxToggle(USBD_EP_T ep)185 void USBD_ResetTxToggle(USBD_EP_T ep)
186 {
187     if(USBD->EP[ep].EP_B.TXDTOG)
188     {
189         USBD_ToggleTx(ep);
190     }
191 }
192 
193 /*!
194  * @brief       Reset Toggle Rx DTOG
195  *
196  * @param       ep: Endpoint number
197  *
198  * @retval      None
199  */
USBD_ResetRxToggle(USBD_EP_T ep)200 void USBD_ResetRxToggle(USBD_EP_T ep)
201 {
202     if(USBD->EP[ep].EP_B.RXDTOG)
203     {
204         USBD_ToggleRx(ep);
205     }
206 }
207 
208 /*!
209  * @brief       Set EP address
210  *
211  * @param       ep: Endpoint number
212  *
213  * @param       addr: Address
214  *
215  * @retval      None
216  */
USBD_SetEpAddr(USBD_EP_T ep,uint8_t addr)217 void USBD_SetEpAddr(USBD_EP_T ep, uint8_t addr)
218 {
219     __IOM uint32_t reg;
220 
221     reg = USBD->EP[ep].EP;
222 
223     reg &= (uint32_t)(USBD_EP_MASK_DEFAULT);
224     reg &= ~USBD_EP_BIT_ADDR;
225     reg |= addr;
226 
227     USBD->EP[ep].EP = reg;
228 }
229 
230 /*!
231  * @brief       Set EP Tx status
232  *
233  * @param       ep: Endpoint number
234  *
235  * @param       status: status
236  *
237  * @retval      None
238  */
USBD_SetEPTxStatus(USBD_EP_T ep,USBD_EP_STATUS_T status)239 void USBD_SetEPTxStatus(USBD_EP_T ep, USBD_EP_STATUS_T status)
240 {
241     __IOM uint32_t reg;
242 
243     uint32_t tmp;
244     tmp = status <<= 4;
245 
246     reg = USBD->EP[ep].EP;
247 
248     reg &= (uint32_t)(USBD_EP_MASK_DEFAULT | USBD_EP_BIT_TXSTS);
249     reg ^= (tmp & USBD_EP_BIT_TXSTS);
250 
251     USBD->EP[ep].EP = reg;
252 }
253 
254 /*!
255  * @brief       Set EP Rx status
256  *
257  * @param       ep: Endpoint number
258  *
259  * @param       status: status
260  *
261  * @retval      None
262  */
USBD_SetEPRxStatus(USBD_EP_T ep,USBD_EP_STATUS_T status)263 void USBD_SetEPRxStatus(USBD_EP_T ep, USBD_EP_STATUS_T status)
264 {
265     __IOM uint32_t reg;
266     uint32_t tmp;
267 
268     tmp = status << 12;
269 
270     reg = USBD->EP[ep].EP;
271 
272     reg &= (uint32_t)(USBD_EP_MASK_DEFAULT | USBD_EP_BIT_RXSTS);
273     reg ^= (tmp & USBD_EP_BIT_RXSTS);
274 
275     USBD->EP[ep].EP = reg;
276 }
277 
278 
279 /*!
280  * @brief       Set EP Rx and Txstatus
281  *
282  * @param       ep: Endpoint number
283  *
284  * @param       status: status
285  *
286  * @retval      None
287  */
USBD_SetEPRxTxStatus(USBD_EP_T ep,USBD_EP_STATUS_T txStatus,USBD_EP_STATUS_T rxStatus)288 void USBD_SetEPRxTxStatus(USBD_EP_T ep, USBD_EP_STATUS_T txStatus, USBD_EP_STATUS_T rxStatus)
289 {
290     __IOM uint32_t reg;
291     uint32_t tmp;
292 
293     reg = USBD->EP[ep].EP;
294 
295     reg &= (uint32_t)(USBD_EP_MASK_DEFAULT | USBD_EP_BIT_RXSTS | USBD_EP_BIT_TXSTS);
296 
297     tmp = rxStatus << 12;
298     reg ^= (tmp & USBD_EP_BIT_RXSTS);
299 
300     tmp = txStatus << 4;
301     reg ^= (tmp & USBD_EP_BIT_TXSTS);
302 
303     USBD->EP[ep].EP = reg;
304 }
305 
306 /*!
307  * @brief       Set EP Rx Count
308  *
309  * @param       ep: Endpoint number
310  *
311  * @param       cnt: Rx count
312  *
313  * @retval      None
314  */
USBD_SetEPRxCnt(USBD_EP_T ep,uint32_t cnt)315 void USBD_SetEPRxCnt(USBD_EP_T ep, uint32_t cnt)
316 {
317     __IOM uint32_t *p;
318     __IOM uint32_t block = 0;
319 
320     p = USBD_ReadEPRxCntPointer(ep);
321 
322     if(cnt > 62)
323     {
324         block = cnt >> 5;
325 
326         if(!(cnt & 0x1f))
327         {
328             block -= 1;
329         }
330 
331         *p = (block << 10) | 0x8000;
332     }
333     else
334     {
335         block = cnt >> 1;
336 
337         if(cnt & 0x01)
338         {
339             block += 1;
340         }
341 
342         *p = (block << 10);
343     }
344 }
345 
346 /*!
347  * @brief       Write a buffer of data to a selected endpoint
348  *
349  * @param       ep:   Endpoint number
350  *
351  * @retval      wBuf: The pointer to the buffer of data to be written to the endpoint
352  *
353  * @param       wLen: Number of data to be written (in bytes)
354  *
355  * @retval      None
356  */
USBD_WriteDataToEP(USBD_EP_T ep,uint8_t * wBuf,uint32_t wLen)357 void USBD_WriteDataToEP(USBD_EP_T ep, uint8_t *wBuf, uint32_t wLen)
358 {
359     uint32_t i;
360     uint32_t *addrEP;
361     uint32_t tmp;
362 
363     wLen = (wLen + 1) >> 1;
364 
365     addrEP = (uint32_t *)((uint32_t)USBD_ReadEPTxAddr(ep));
366     addrEP = (uint32_t *)(((uint32_t)addrEP << 1) + USBD_PMA_ADDR);
367 
368     for(i = 0; i < wLen; i++)
369     {
370         tmp = *wBuf++;
371         tmp = ((*wBuf++) << 8) | tmp;
372 
373         *addrEP++ = tmp;
374     }
375 }
376 
377 /*!
378  * @brief       Read a buffer of data to a selected endpoint
379  *
380  * @param       ep:   Endpoint number
381  *
382  * @retval      wBuf: The pointer to the buffer of data to be read to the endpoint
383  *
384  * @param       wLen: Number of data to be read (in bytes)
385  *
386  * @retval      None
387  */
USBD_ReadDataFromEP(USBD_EP_T ep,uint8_t * rBuf,uint32_t rLen)388 void USBD_ReadDataFromEP(USBD_EP_T ep, uint8_t *rBuf, uint32_t rLen)
389 {
390     uint32_t i;
391     uint32_t *addrEP;
392     uint32_t tmp;
393 
394     rLen = (rLen + 1) >> 1;
395 
396     addrEP = (uint32_t *)((uint32_t)USBD_ReadEPRxAddr(ep));
397     addrEP = (uint32_t *)(((uint32_t)addrEP << 1) + USBD_PMA_ADDR);
398 
399     for(i = 0; i < rLen; i++)
400     {
401         tmp = *addrEP++;
402         *rBuf++ = tmp & 0XFF;
403         *rBuf++ = (tmp >> 8) & 0xff;
404     }
405 }
406 
407 /**@} end of group USBD_Functions */
408 /**@} end of group USBD_Driver */
409 /**@} end of group APM32E10x_StdPeriphDriver */
410