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