1 //*****************************************************************************
2 //
3 //! @file am_hal_usb.c
4 //!
5 //! @brief Functions for USB module
6 //!
7 //! @addtogroup usb_4p USB Functionality
8 //! @ingroup apollo4p_hal
9 //! @{
10 //
11 //*****************************************************************************
12 
13 //*****************************************************************************
14 //
15 // Copyright (c) 2023, Ambiq Micro, Inc.
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are met:
20 //
21 // 1. Redistributions of source code must retain the above copyright notice,
22 // this list of conditions and the following disclaimer.
23 //
24 // 2. Redistributions in binary form must reproduce the above copyright
25 // notice, this list of conditions and the following disclaimer in the
26 // documentation and/or other materials provided with the distribution.
27 //
28 // 3. Neither the name of the copyright holder nor the names of its
29 // contributors may be used to endorse or promote products derived from this
30 // software without specific prior written permission.
31 //
32 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
36 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 // POSSIBILITY OF SUCH DAMAGE.
43 //
44 // This is part of revision release_sdk_4_4_0-3c5977e664 of the AmbiqSuite Development Package.
45 //
46 //*****************************************************************************
47 
48 #include <stdlib.h>
49 #include <stdio.h>
50 #include <string.h>
51 
52 #include "am_mcu_apollo.h"
53 #include "am_util_delay.h"
54 
55 //*****************************************************************
56 //
57 //! @name USB State
58 //! @{
59 //
60 //*****************************************************************
61 #define AM_HAL_MAGIC_USB 0xEA9E06
62 
63 #define USBn(n) ((USB_Type*)(USB_BASE + (n * (USB_BASE - USB_BASE))))
64 
65 #define AM_HAL_USB_CHK_HANDLE(h)                                         \
66 ((h) &&                                                                  \
67 ((am_hal_handle_prefix_t *)(h))->s.bInit &&                              \
68 (((am_hal_handle_prefix_t *)(h))->s.magic == AM_HAL_MAGIC_USB))
69 
70 #define AM_HAL_USB_ENTER_CRITICAL NVIC_DisableIRQ(USB0_IRQn)
71 #define AM_HAL_USB_EXIT_CRITICAL  NVIC_EnableIRQ(USB0_IRQn)
72 //*****************************************************************************
73 //! @}
74 //*****************************************************************************
75 
76 //*****************************************************************************
77 //
78 //! @name Endpoint Masks
79 //!
80 //! maximum endpoint number is six (EP0 ~ EP5)
81 //! @{
82 //
83 //*****************************************************************************
84 #define AM_HAL_USB_EP_MASK       0x3F
85 #define AM_HAL_USB_CHK_EP(n)     ((n & ~AM_HAL_USB_EP_MASK) > 0)
86 #define AM_HAL_USB_CHK_EP_NUM(n) ((n & 0x7F) > 5)
87 #define AM_HAL_USB_CHK_USB(n)    (n & ~0xF)
88 //*****************************************************************************
89 //! @}
90 //*****************************************************************************
91 
92 //*****************************************************************************
93 //
94 //! @name Endpoint Numbers
95 //!
96 //! Five endpoint number are available except EP0
97 //! @{
98 //
99 //*****************************************************************************
100 #define AM_HAL_USB_EP0_NUMBER    0x0
101 #define AM_HAL_USB_EP1_NUMBER    0x1
102 #define AM_HAL_USB_EP2_NUMBER    0x2
103 #define AM_HAL_USB_EP3_NUMBER    0x3
104 #define AM_HAL_USB_EP4_NUMBER    0x4
105 #define AM_HAL_USB_EP5_NUMBER    0x5
106 #define AM_HAL_USB_EP_MAX_NUMBER AM_HAL_USB_EP5_NUMBER
107 //*****************************************************************************
108 //! @}
109 //*****************************************************************************
110 
111 //
112 //! USB workaround and feature macros
113 //
114 #undef AM_HAL_USB_FEATURE_EP_READ_TIMEOUT
115 #define AM_HAL_USB_TIMEOUT 2
116 
117 #define SWAP_WORD(a)  (a << 24) | ((a << 8) & 0xff0000) | ((a >> 8) & 0xff00) | (a >> 24)
118 
119 #undef AM_HAL_USB_FEATURE_ZERO_LENGTH_PACKET
120 
121 //
122 //! input xtal variable used when computing hfrc2 clock in USB highspeed mode
123 //
124 static uint32_t g_ui32XtalFreq = 32000000;
125 
126 //*****************************************************************************
127 //
128 //! Endpoint State
129 //
130 //*****************************************************************************
131 typedef enum
132 {
133     AM_HAL_USB_EP0_STATE_IDLE,
134     AM_HAL_USB_EP0_STATE_SETUP,
135     AM_HAL_USB_EP0_STATE_DATA_RX,
136     AM_HAL_USB_EP0_STATE_DATA_TX,
137     AM_HAL_USB_EP0_STATE_STATUS_RX,
138     AM_HAL_USB_EP0_STATE_STATUS_TX,
139     AM_HAL_USB_EP0_STATE_NUM
140 }
141 am_hal_usb_ep0_state_e;
142 
143 //*****************************************************************************
144 //
145 //! Endpoint Transfer Info
146 //
147 //*****************************************************************************
148 typedef struct
149 {
150     uint8_t *buf;
151     uint16_t len;
152     uint16_t remaining;
153 #ifdef AM_HAL_USB_FEATURE_EP_READ_TIMEOUT
154     bool xfer_started;
155     uint8_t timeout;
156 #endif
157     struct
158     {
159         uint8_t busy:1;
160         uint8_t zlp:1;
161         uint8_t dir:1;
162     } flags;
163 }
164 am_hal_usb_ep_xfer_t;
165 
166 //*****************************************************************************
167 //
168 //! USB Register State
169 //
170 //*****************************************************************************
171 typedef struct
172 {
173     bool bValid;
174     uint32_t regCFG0;
175     uint32_t regCFG1;
176     uint32_t regCFG2;
177     struct
178     {
179         uint32_t regIDX0;
180         uint32_t regIDX1;
181         uint32_t regIDX2;
182     } regEndPoints[AM_HAL_USB_EP_MAX_NUMBER];
183 }
184 am_hal_usb_register_state_t;
185 
186 //*****************************************************************************
187 //
188 //! USB state data structure
189 //
190 //*****************************************************************************
191 typedef struct
192 {
193     am_hal_handle_prefix_t prefix;
194     am_hal_usb_register_state_t sRegState;
195 
196     uint32_t ui32Allocated;
197 
198     am_hal_usb_dev_speed_e eDevSpeed;
199     am_hal_usb_dev_state_e eDevState;
200     am_hal_usb_ep0_state_e eEP0State;
201 
202     uint16_t ep0_maxpacket;
203     uint16_t epin_maxpackets[AM_HAL_USB_EP_MAX_NUMBER];
204     uint16_t epout_maxpackets[AM_HAL_USB_EP_MAX_NUMBER];
205 
206     am_hal_usb_ep_xfer_t ep0_xfer;
207     am_hal_usb_ep_xfer_t ep_xfers[AM_HAL_USB_EP_MAX_NUMBER][2];
208 
209 #ifdef AM_HAL_USB_TEST_MODE_ENABLED
210     bool bInTestMode;
211 #endif
212 
213     uint32_t ui32Module;
214 
215     //! Device event callback functions
216     am_hal_usb_dev_evt_callback dev_evt_callback;
217     //! EP0 setup received callback
218     am_hal_usb_ep0_setup_received_callback ep0_setup_callback;
219     //! Endpoint transfer complete callback
220     am_hal_usb_ep_xfer_complete_callback ep_xfer_complete_callback;
221 }
222 am_hal_usb_state_t;
223 
224 static am_hal_usb_state_t g_am_hal_usb_states[AM_REG_USB_NUM_MODULES];
225 
226 //*****************************************************************************
227 //
228 // CFG0 registers
229 //
230 //*****************************************************************************
231 //
232 //! @name FADDR register macros
233 //! @{
234 //
235 //*****************************************************************************
236 #define FADDR_FuncAddr(pUSB)                   *((volatile uint8_t *)&(pUSB->CFG0)) & USB_CFG0_FuncAddr_Msk >> USB_CFG0_FuncAddr_Pos
237 #define FADDR_FuncAddr_Set(pUSB, addr)         do { \
238                                                    *((volatile uint8_t *)&(pUSB->CFG0)) &= ~USB_CFG0_FuncAddr_Msk; \
239                                                    *((volatile uint8_t *)&(pUSB->CFG0)) |= (addr) << USB_CFG0_FuncAddr_Pos; \
240                                                } while (0)
241 
242 #define FADDR_Update(pUSB)                     (*((volatile uint8_t *)&(pUSB->CFG0)) & USB_CFG0_Update_Msk)
243 //*****************************************************************************
244 //! @}
245 //*****************************************************************************
246 
247 //*****************************************************************************
248 //
249 //! @name POWER register macros
250 //! @{
251 //
252 //*****************************************************************************
253 #define POWER_IsoUpdate_Set(pUSB)              *((volatile uint8_t *)&(pUSB->CFG0) + 1) |=  (USB_CFG0_ISOUpdate_Msk >> 8)
254 #define POWER_IsoUpdate_Clear(pUSB)            *((volatile uint8_t *)&(pUSB->CFG0) + 1) &= ~(USB_CFG0_ISOUpdate_Msk >> 8)
255 #define POWER_AMSPECIFIC_Set(pUSB)             *((volatile uint8_t *)&(pUSB->CFG0) + 1) |=  (USB_CFG0_AMSPECIFIC_Msk >> 8)
256 #define POWER_AMSPECIFIC_Clear(pUSB)           *((volatile uint8_t *)&(pUSB->CFG0) + 1) &= ~(USB_CFG0_AMSPECIFIC_Msk >> 8)
257 #define POWER_HSEnab_Set(pUSB)                 *((volatile uint8_t *)&(pUSB->CFG0) + 1) |=  (USB_CFG0_HSEnab_Msk >> 8)
258 #define POWER_HSEnab_Clear(pUSB)               *((volatile uint8_t *)&(pUSB->CFG0) + 1) &= ~(USB_CFG0_HSEnab_Msk >> 8)
259 #define POWER_HSMode(pUSB)                     *((volatile uint8_t *)&(pUSB->CFG0) + 1) &   (USB_CFG0_HSMode_Msk >> 8)
260 #define POWER_Reset(pUSB)                      *((volatile uint8_t *)&(pUSB->CFG0) + 1) &   (USB_CFG0_Reset_Msk >> 8)
261 #define POWER_Resume_Set(pUSB)                 *((volatile uint8_t *)&(pUSB->CFG0) + 1) |=  (USB_CFG0_Resume_Msk >> 8)
262 #define POWER_Resume_Clear(pUSB)               *((volatile uint8_t *)&(pUSB->CFG0) + 1) &= ~(USB_CFG0_Resume_Msk >> 8)
263 #define POWER_SuspendMode(pUSB)                *((volatile uint8_t *)&(pUSB->CFG0) + 1) &   (USB_CFG0_Suspen_Msk >> 8)
264 #define POWER_EnableSuspendM_Set(pUSB)         *((volatile uint8_t *)&(pUSB->CFG0) + 1) |=  (USB_CFG0_Enabl_Msk >> 8)
265 
266 #define INTRIN_Get(pUSB)                       *((volatile uint16_t *)&(pUSB->CFG0) + 1) & AM_HAL_USB_EP_MASK
267 #define INTRIN_Clear(pUSB)                     INTRIN_Get(pUSB)
268 //*****************************************************************************
269 //! @}
270 //*****************************************************************************
271 
272 //*****************************************************************************
273 //
274 // CFG1 registers
275 //
276 //*****************************************************************************
277 
278 //*****************************************************************************
279 //
280 //! @name INTROUT register
281 //! @{
282 //
283 //*****************************************************************************
284 #define INTROUT_Get(pUSB)                      *((volatile uint8_t *)&(pUSB->CFG1)) & AM_HAL_USB_EP_MASK
285 #define INTROUT_Clear(pUSB)                    INTROUT_Get(pUSB)
286 //*****************************************************************************
287 //! @}
288 //*****************************************************************************
289 
290 //*****************************************************************************
291 //
292 //! @name INTRINE register
293 //! @{
294 //
295 //*****************************************************************************
296 #define INTRINE_Enable(pUSB, v)                *((volatile uint16_t *)&(pUSB->CFG1) + 1) |= ((v) & AM_HAL_USB_EP_MASK)
297 #define INTRINE_Disable(pUSB, v)               *((volatile uint16_t *)&(pUSB->CFG1) + 1) &= (~(v) & AM_HAL_USB_EP_MASK)
298 #define INTRINE_Get(pUSB)                      *((volatile uint16_t *)&(pUSB->CFG1) + 1) & AM_HAL_USB_EP_MASK
299 //*****************************************************************************
300 //! @}
301 //*****************************************************************************
302 
303 //*****************************************************************************
304 //
305 // CFG2 registers
306 //
307 //*****************************************************************************
308 
309 //*****************************************************************************
310 //
311 //! @name INTROUTE register
312 //! @{
313 //
314 //*****************************************************************************
315 #define INTROUTE_Enable(pUSB, v)               *((volatile uint8_t *)&(pUSB->CFG2)) |= ((v) & AM_HAL_USB_EP_MASK)
316 #define INTROUTE_Disable(pUSB, v)              *((volatile uint8_t *)&(pUSB->CFG2)) &= (~(v) & AM_HAL_USB_EP_MASK)
317 #define INTROUTE_Get(pUSB)                     *((volatile uint8_t *)&(pUSB->CFG2)) & AM_HAL_USB_EP_MASK
318 //*****************************************************************************
319 //! @}
320 //*****************************************************************************
321 
322 //*****************************************************************************
323 //
324 //! @name INTRUSB register
325 //! @{
326 //
327 //*****************************************************************************
328 #define INTRUSB_Get(pUSB)                      *((volatile uint8_t *)&(pUSB->CFG2) + 2) & 0xF
329 #define INTRUSB_Clear(pUSB)                    INTRUSB_Get(pUSB)
330 //*****************************************************************************
331 //! @}
332 //*****************************************************************************
333 
334 //*****************************************************************************
335 //
336 //! @name INTRUSBE register
337 //! @{
338 //
339 //*****************************************************************************
340 #define INTRUSBE_SOF_Enable(pUSB)              *((volatile uint8_t *)&(pUSB->CFG2) + 3) |=  ((uint8_t)(USB_CFG2_SOFE_Msk >> USB_CFG2_SuspendE_Pos))
341 #define INTRUSBE_SOF_Disable(pUSB)             *((volatile uint8_t *)&(pUSB->CFG2) + 3) &= ~((uint8_t)(USB_CFG2_SOFE_Msk >> USB_CFG2_SuspendE_Pos))
342 #define INTRUSBE_Reset_Enable(pUSB)            *((volatile uint8_t *)&(pUSB->CFG2) + 3) |=  ((uint8_t)(USB_CFG2_ResetE_Msk >> USB_CFG2_SuspendE_Pos))
343 #define INTRUSBE_Reset_Disable(pUSB)           *((volatile uint8_t *)&(pUSB->CFG2) + 3) &= ~((uint8_t)(USB_CFG2_ResetE_Msk >> USB_CFG2_SuspendE_Pos))
344 #define INTRUSBE_Resume_Enable(pUSB)           *((volatile uint8_t *)&(pUSB->CFG2) + 3) |=  ((uint8_t)(USB_CFG2_ResumeE_Msk >> USB_CFG2_SuspendE_Pos))
345 #define INTRUSBE_Resume_Disable(pUSB)          *((volatile uint8_t *)&(pUSB->CFG2) + 3) &= ~((uint8_t)(USB_CFG2_ResumeE_Msk >> USB_CFG2_SuspendE_Pos))
346 #define INTRUSBE_Suspend_Enable(pUSB)          *((volatile uint8_t *)&(pUSB->CFG2) + 3) |=  ((uint8_t)(USB_CFG2_SuspendE_Msk >> USB_CFG2_SuspendE_Pos))
347 #define INTRUSBE_Suspend_Disable(pUSB)         *((volatile uint8_t *)&(pUSB->CFG2) + 3) &= ~((uint8_t)(USB_CFG2_SuspendE_Msk >> USB_CFG2_SuspendE_Pos))
348 
349 #define INTRUSBE_Enable(pUSB, v)               *((volatile uint8_t *)&(pUSB->CFG2) + 3) |= ((v) & 0xF)
350 #define INTRUSBE_Disable(pUSB, v)              *((volatile uint8_t *)&(pUSB->CFG2) + 3) &= (~(v) & 0xF)
351 
352 #define INTRUSBE_Get(pUSB)                     *((volatile uint8_t *)&(pUSB->CFG2) + 3) & 0xF
353 //*****************************************************************************
354 //! @}
355 //*****************************************************************************
356 
357 // CFG3 registers
358 
359 //
360 //! Frame Number register
361 //
362 #define FRAME_NUM(pUSB)                        (pUSB->CFG3 & USB_CFG3_FRMNUM_Msk) >> USB_CFG3_FRMNUM_Pos
363 
364 //
365 //! Endpoint index register
366 //
367 #define EP_INDEX_Set(pUSB, idx)                 pUSB->CFG3 &= ~USB_CFG3_ENDPOINT_Msk; \
368                                                 pUSB->CFG3 |= (idx) << USB_CFG3_ENDPOINT_Pos
369 
370 //*****************************************************************************
371 //
372 //! @name Test Mode register
373 //! @{
374 //
375 //*****************************************************************************
376 #define TESTMODE_TestSE0NAK_Set(pUSB)           pUSB->CFG3 |= USB_CFG3_TestSE0NAK_Msk
377 #define TESTMODE_TestJ_Set(pUSB)                pUSB->CFG3 |= USB_CFG3_TestJ_Msk
378 #define TESTMODE_TestK_Set(pUSB)                pUSB->CFG3 |= USB_CFG3_TestK_Msk
379 #define TESTMODE_TestPacket_Set(pUSB)           pUSB->CFG3 |= USB_CFG3_TestPacket_Msk
380 #define TESTMODE_ForceHS_Set(pUSB)              pUSB->CFG3 |= USB_CFG3_ForceHS_Msk
381 #define TESTMODE_ForceFS_Set(pUSB)              pUSB->CFG3 |= USB_CFG3_ForceFS_Msk
382 //*****************************************************************************
383 //! @}
384 //*****************************************************************************
385 
386 //
387 // IDX0 registers
388 //
389 
390 //*****************************************************************************
391 //
392 //! @name EP0 CSR0 register
393 //! @{
394 //
395 //*****************************************************************************
396 #define CSR0_ServicedSetupEnd_Set(pUSB)         pUSB->IDX0 |=  USB_IDX0_IncompTxServiceSetupEnd_Msk
397 #define CSR0_ServicedOutPktRdy_Set(pUSB)        pUSB->IDX0 |=  USB_IDX0_ClrDataTogServicedOutPktRdy_Msk
398 #define CSR0_ServicedOutPktRdy(pUSB)            pUSB->IDX0 & USB_IDX0_ClrDataTogServicedOutPktRdy_Msk
399 #define CSR0_SendStall_Set(pUSB)                pUSB->IDX0 |=  USB_IDX0_SentStallSendStall_Msk
400 #define CSR0_SetupEnd(pUSB)                    (pUSB->IDX0 &   USB_IDX0_SendStallSetupEnd_Msk)
401 
402 #define CSR0_DataEnd_Set(pUSB)                  pUSB->IDX0 |=  USB_IDX0_FlushFIFODataEnd_Msk
403 #define CSR0_SentStall(pUSB)                   (pUSB->IDX0 &   USB_IDX0_UnderRunSentStall_Msk)
404 #define CSR0_SentStall_Clear(pUSB)              pUSB->IDX0 &= ~USB_IDX0_UnderRunSentStall_Msk
405 #define CSR0_InPktRdy(pUSB)                    (pUSB->IDX0 &   USB_IDX0_FIFONotEmptyInPktRdy_Msk)
406 #define CSR0_InPktRdy_Set(pUSB)                 pUSB->IDX0 |=  USB_IDX0_FIFONotEmptyInPktRdy_Msk
407 #define CSR0_OutPktRdy(pUSB)                   (pUSB->IDX0 &   USB_IDX0_InPktRdyOutPktRdy_Msk)
408 #define CSR0_OutPktRdy_Set(pUSB)                pUSB->IDX0 |=  USB_IDX0_InPktRdyOutPktRdy_Msk
409 #define CSR0_ServicedOutPktRdyAndDataEnd_Set(pUSB)    pUSB->IDX0 |=  (USB_IDX0_ClrDataTogServicedOutPktRdy_Msk | USB_IDX0_FlushFIFODataEnd_Msk)
410 #define CSR0_InPktRdyAndDataEnd_Set(pUSB)             pUSB->IDX0 |= (USB_IDX0_FIFONotEmptyInPktRdy_Msk | USB_IDX0_FlushFIFODataEnd_Msk)
411 #define CSR0_ServicedOutPktRdyAndSendStall_Set(pUSB)  pUSB->IDX0 |= (USB_IDX0_ClrDataTogServicedOutPktRdy_Msk | USB_IDX0_SentStallSendStall_Msk)
412 //*****************************************************************************
413 //! @}
414 //*****************************************************************************
415 
416 //*****************************************************************************
417 //
418 //! @name INMAXP register
419 //! @{
420 //
421 //*****************************************************************************
422 #define INMAXP_MaxPayload(pUSB)                (pUSB->IDX0 &   USB_IDX0_MAXPAYLOAD_Msk) >> USB_IDX0_MAXPAYLOAD_Pos
423 #define INMAXP_MaxPayload_Set(pUSB, maxp)       pUSB->IDX0 &= ~USB_IDX0_MAXPAYLOAD_Msk; \
424                                                 pUSB->IDX0 |=  (maxp) << USB_IDX0_MAXPAYLOAD_Pos
425 #define INMAXP_PktSplitOption(pUSB)            (pUSB->IDX0 &   USB_IDX0_PKTSPLITOPTION_Msk) >> USB_IDX0_PKTSPLITOPTION_Pos
426 #define INMAXP_PktSplitOption_Set(pUSB, split)  pUSB->IDX0 &= ~USB_IDX0_PKTSPLITOPTION_Msk; \
427                                                 pUSB->IDX0 |=  (split) << USB_IDX0_PKTSPLITOPTION_Pos
428 //*****************************************************************************
429 //! @}
430 //*****************************************************************************
431 
432 //*****************************************************************************
433 //
434 //! @name INCSRL register
435 //! @{
436 //
437 //*****************************************************************************
438 #define INCSRL_IncompTx(pUSB)                  (pUSB->IDX0 &   USB_IDX0_IncompTxServiceSetupEnd_Msk)
439 #define INCSRL_IncompTx_Clear(pUSB)             pUSB->IDX0 &= ~USB_IDX0_IncompTxServiceSetupEnd_Msk
440 #define INCSRL_ClrDataTog_Set(pUSB)             pUSB->IDX0 |=  USB_IDX0_ClrDataTogServicedOutPktRdy_Msk
441 #define INCSRL_SentStall(pUSB)                 (pUSB->IDX0 &   USB_IDX0_SentStallSendStall_Msk)
442 #define INCSRL_SentStall_Clear(pUSB)            pUSB->IDX0 &= ~USB_IDX0_SentStallSendStall_Msk
443 #define INCSRL_SendStall_Set(pUSB)              pUSB->IDX0 |=  USB_IDX0_SendStallSetupEnd_Msk
444 #define INCSRL_SendStall_Clear(pUSB)            pUSB->IDX0 &= ~USB_IDX0_SendStallSetupEnd_Msk
445 #define INCSRL_FlushFIFO_Set(pUSB)              pUSB->IDX0 |=  USB_IDX0_FlushFIFODataEnd_Msk
446 #define INCSRL_UnderRun(pUSB)                  (pUSB->IDX0 &   USB_IDX0_UnderRunSentStall_Msk)
447 #define INCSRL_UnderRun_Clear(pUSB)             pUSB->IDX0 &= ~USB_IDX0_UnderRunSentStall_Msk
448 #define INCSRL_FIFONotEmpty(pUSB)              (pUSB->IDX0 &   USB_IDX0_FIFONotEmptyInPktRdy_Msk)
449 #define INCSRL_FIFONotEmpty_Clear(pUSB)         pUSB->IDX0 &= ~USB_IDX0_FIFONotEmptyInPktRdy_Msk
450 #define INCSRL_InPktRdy(pUSB)                  (pUSB->IDX0 &   USB_IDX0_InPktRdyOutPktRdy_Msk)
451 #define INCSRL_InPktRdy_Set(pUSB)               pUSB->IDX0 |=  USB_IDX0_InPktRdyOutPktRdy_Msk
452 //*****************************************************************************
453 //! @}
454 //*****************************************************************************
455 
456 //*****************************************************************************
457 //
458 //! @name INCSRU register
459 //! @{
460 //
461 //*****************************************************************************
462 #define INCSRU_AutoSet(pUSB)                   (pUSB->IDX0 &   USB_IDX0_AutoSet_Msk)
463 #define INCSRU_AutoSet_Set(pUSB)                pUSB->IDX0 |=  USB_IDX0_AutoSet_Msk
464 #define INCSRU_ISO_Set(pUSB)                    pUSB->IDX0 |=  USB_IDX0_ISO_Msk
465 #define INCSRU_ISO_Clear(pUSB)                  pUSB->IDX0 &= ~USB_IDX0_ISO_Msk
466 #define INCSRU_Mode_Set(pUSB)                   pUSB->IDX0 |=  USB_IDX0_Mode_Msk
467 #define INCSRU_Mode_Clear(pUSB)                 pUSB->IDX0 &= ~USB_IDX0_Mode_Msk
468 #define INCSRU_DMAReqEnab_Set(pUSB)             pUSB->IDX0 |=  USB_IDX0_DMAReqEnab_Msk
469 #define INCSRU_DMAReqEnab_Clear(pUSB)           pUSB->IDX0 &= ~USB_IDX0_DMAReqEnab_Msk
470 #define INCSRU_FrcDataTog_Set(pUSB)             pUSB->IDX0 |=  USB_IDX0_FrcDataTog_Msk
471 #define INCSRU_FrcDataTog_Clear(pUSB)           pUSB->IDX0 &= ~USB_IDX0_FrcDataTog_Msk
472 
473 #define INCSRU_DMAReqMode_Set(pUSB)             pUSB->IDX0 |=  USB_IDX0_DMAReqMode_Msk
474 #define INCSRU_DMAReqMode_Clear(pUSB)           pUSB->IDX0 &= ~USB_IDX0_DMAReqMode_Msk
475 #define INCSRU_DPktBufDis_Set(pUSB)             pUSB->IDX0 |=  USB_IDX0_DPktBufDis_Msk
476 #define INCSRU_DPktBufDis_Clear(pUSB)           pUSB->IDX0 &= ~USB_IDX0_DPktBufDis_Msk
477 //*****************************************************************************
478 //! @}
479 //*****************************************************************************
480 
481 //
482 // IDX1 registers
483 //
484 
485 //*****************************************************************************
486 //
487 //! @name OUTMAXP register
488 //! @{
489 //
490 //*****************************************************************************
491 #define OUTMAXP_MaxPayload(pUSB)               (pUSB->IDX1 & USB_IDX1_MAXPAYLOAD_Msk) >> USB_IDX1_MAXPAYLOAD_Pos
492 #define OUTMAXP_MaxPayload_Set(pUSB, maxp)      pUSB->IDX1 &= ~USB_IDX1_MAXPAYLOAD_Msk; \
493                                                 pUSB->IDX1 |= (maxp) << USB_IDX1_MAXPAYLOAD_Pos
494 
495 #define OUTMAXP_PktSplitOption(pUSB)           (pUSB->IDX1 & USB_IDX1_PKTSPLITOPTION_Msk) >> USB_IDX1_PKTSPLITOPTION_Pos
496 #define OUTMAXP_PktSplitOption_Set(pUSB, split) pUSB->IDX1 &= ~USB_IDX1_PKTSPLITOPTION_Msk; \
497                                                 pUSB->IDX1 |= (split) << USB_IDX1_PKTSPLITOPTION_Pos
498 //*****************************************************************************
499 //! @}
500 //*****************************************************************************
501 
502 //*****************************************************************************
503 //
504 //! @name OUTCSRL register
505 //! @{
506 //
507 //*****************************************************************************
508 #define OUTCSRL_ClrDataTog_Set(pUSB)            pUSB->IDX1 |=  USB_IDX1_ClrDataTog_Msk
509 #define OUTCSRL_SentStall(pUSB)                (pUSB->IDX1 &   USB_IDX1_SentStall_Msk)
510 #define OUTCSRL_SentStall_Clear(pUSB)           pUSB->IDX1 &= ~USB_IDX1_SentStall_Msk
511 #define OUTCSRL_SendStall_Set(pUSB)             pUSB->IDX1 |=  USB_IDX1_SendStall_Msk
512 #define OUTCSRL_SendStall_Clear(pUSB)           pUSB->IDX1 &= ~USB_IDX1_SendStall_Msk
513 #define OUTCSRL_FlushFIFO_Set(pUSB)             pUSB->IDX1 |=  USB_IDX1_FlushFIFO_Msk
514 #define OUTCSRL_DataError(pUSB)                (pUSB->IDX1 &   USB_IDX1_DataError_Msk)
515 #define OUTCSRL_OverRun(pUSB)                  (pUSB->IDX1 &   USB_IDX1_OverRun_Msk)
516 #define OUTCSRL_OverRun_Clear(pUSB)             pUSB->IDX1 &= ~USB_IDX1_OverRun_Msk
517 #define OUTCSRL_FIFOFull(pUSB)                 (pUSB->IDX1 &   USB_IDX1_FIFOFull_Msk)
518 #define OUTCSRL_OutPktRdy(pUSB)                (pUSB->IDX1 &   USB_IDX1_OutPktRdy_Msk)
519 #define OUTCSRL_OutPktRdy_Clear(pUSB)           pUSB->IDX1 &= ~USB_IDX1_OutPktRdy_Msk
520 //*****************************************************************************
521 //! @}
522 //*****************************************************************************
523 
524 //*****************************************************************************
525 //
526 //! @name OUTCSRU register
527 //! @{
528 //
529 //*****************************************************************************
530 #define OUTCSRU_AutoClear_Set(pUSB)             pUSB->IDX1 |=  USB_IDX1_AutoClear_Msk
531 #define OUTCSRU_AutoClear_Clear(pUSB)           pUSB->IDX1 &= ~USB_IDX1_AutoClear_Msk
532 #define OUTCSRU_ISO_Set(pUSB)                   pUSB->IDX1 |=  USB_IDX1_ISO_Msk
533 #define OUTCSRU_ISO_Clear(pUSB)                 pUSB->IDX1 &= ~USB_IDX1_ISO_Msk
534 #define OUTCSRU_DMAReqEnab_Set(pUSB)            pUSB->IDX1 |=  USB_IDX1_DMAReqEnab_Msk
535 #define OUTCSRU_DMAReqEnab_Clear(pUSB)          pUSB->IDX1 &= ~USB_IDX1_DMAReqEnab_Msk
536 #define OUTCSRU_DisNye_Set(pUSB)                pUSB->IDX1 |=  USB_IDX1_DisNye_Msk
537 #define OUTCSRU_DisNye_Clear(pUSB)              pUSB->IDX1 &= ~USB_IDX1_DisNye_Msk
538 #define OUTCSRU_PIDErr(pUSB)                   (pUSB->IDX1 &   USB_IDX1_DisNye_Msk)
539 #define OUTCSRU_DMAReqMode_Set(pUSB)            pUSB->IDX1 |=  USB_IDX1_DMAReqMode_Msk
540 #define OUTCSRU_DMAReqMode_Clear(pUSB)          pUSB->IDX1 &= ~USB_IDX1_DMAReqMode_Msk
541 #define OUTCSRU_DPktBufDis_Set(pUSB)            pUSB->IDX1 |=  USB_IDX1_DPktBufDis_Msk
542 #define OUTCSRU_DPktBufDis_Clear(pUSB)          pUSB->IDX1 &= ~USB_IDX1_DPktBufDis_Msk
543 #define OUTCSRU_IncompRx(pUSB)                 (pUSB->IDX1 &   USB_IDX1_IncompRx_Msk)
544 #define OUTCSRU_IncompRx_Clear(pUSB)            pUSB->IDX1 &= ~USB_IDX1_IncompRx_Msk
545 //*****************************************************************************
546 //! @}
547 //*****************************************************************************
548 
549 //
550 // IDX2 register
551 //
552 
553 #define OUTCOUNT(pUSB)                         (pUSB->IDX2 & USB_IDX2_ENDPTOUTCOUNT_Msk) >> USB_IDX2_ENDPTOUTCOUNT_Pos
554 
555 //! EP0 count register
556 #define COUNT0(pUSB)                           (pUSB->IDX2 & USB_IDX2_ENDPTOUTCOUNT_Msk) >> USB_IDX2_ENDPTOUTCOUNT_Pos
557 
558 //*****************************************************************************
559 //
560 //! @name Dynamic FIFO size
561 //! @{
562 //
563 //*****************************************************************************
564 #define EP_FIFO_SZ_8                            0x0
565 #define EP_FIFO_SZ_16                           0x1
566 #define EP_FIFO_SZ_32                           0x2
567 #define EP_FIFO_SZ_64                           0x3
568 #define EP_FIFO_SZ_128                          0x4
569 #define EP_FIFO_SZ_256                          0x5
570 #define EP_FIFO_SZ_512                          0x6
571 #define EP_FIFO_SZ_1024                         0x7
572 #define EP_FIFO_SZ_2048                         0x8
573 #define EP_FIFO_SZ_4096                         0x9
574 //*****************************************************************************
575 //! @}
576 //*****************************************************************************
577 
578 // Double packet buffering
579 #define FIFO_DOUBLE_PKTBUF                      0x1
580 #define FIFO_SINGLE_PKTBUF                      0x0
581 
582 #define InFIFOsz(pUSB)                         (pUSB->IDX2 & USB_IDX2_INFIFOSZ_Msk) >> USB_IDX2_INFIFOSZ_Pos
583 #define InFIFOsz_Set(pUSB, dp, sz)              pUSB->IDX2 &= ~USB_IDX2_INFIFOSZ_Msk; \
584                                                 pUSB->IDX2 |= ((dp) << 4 | (sz)) << USB_IDX2_INFIFOSZ_Pos
585 
586 #define OutFIFOsz(pUSB)                        (pUSB->IDX2 & USB_IDX2_OUTFIFOSZ_Msk) >> USB_IDX2_OUTFIFOSZ_Pos
587 #define OutFIFOsz_Set(pUSB, dp, sz)             pUSB->IDX2 &= ~USB_IDX2_OUTFIFOSZ_Msk; \
588                                                 pUSB->IDX2 |= ((dp) << 4 | (sz)) << USB_IDX2_OUTFIFOSZ_Pos
589 
590 #define InFIFOadd(pUSB)                        (pUSB->FIFOADD & USB_FIFOADD_INFIFOADD_Msk) >> USB_FIFOADD_INFIFOADD_Pos
591 #define InFIFOadd_Set(pUSB, addr)               pUSB->FIFOADD &= ~USB_FIFOADD_INFIFOADD_Msk; \
592                                                 pUSB->FIFOADD |= (addr) << USB_FIFOADD_INFIFOADD_Pos;
593 
594 #define OutFIFOadd(pUSB)                       (pUSB->FIFOADD & USB_FIFOADD_OUTFIFOADD_Msk) >> USB_FIFOADD_OUTFIFOADD_Pos
595 #define OutFIFOadd_Set(pUSB, addr)              pUSB->FIFOADD &= ~USB_FIFOADD_OUTFIFOADD_Msk; \
596                                                 pUSB->FIFOADD |= (addr) << USB_FIFOADD_OUTFIFOADD_Pos
597 
598 // Endpoint FIFO registers
599 #define FIFOx_ADDR(pUSB, x)                    ((volatile uint32_t *)(&(pUSB->FIFO0) + x))
600 
601 // HWVers register
602 #define HWVERS_RC(pUSB)                        (pUSB->HWVERS & USB_HWVERS_RC_Msk)   >> USB_HWVERS_RC_Pos
603 #define HWVERS_xx(pUSB)                        (pUSB->HWVERS & USB_HWVERS_xx_Msk)   >> USB_HWVERS_xx_Pos
604 #define HWVERS_yyy(pUSB)                       (pUSB->HWVERS & USB_HWVERS_yyy_Msk)  >> USB_HWVERS_yyy_Pos
605 #define HWVERS(pUSB)                            pUSB->HWVERS
606 
607 // EPINFO register
608 #define EPINFO_OutEndPoints(pUSB)              (pUSB->INFO & USB_INFO_OutEndPoints_Msk) >> USB_INFO_OutEndPoints_Pos
609 #define EPINFO_InEndPoints(pUSB)               (pUSB->INFO & USB_INFO_InEndPoints_Msk) >> USB_INFO_InEndPoints_Pos
610 
611 // RAMINFO register
612 #define RAMINFO_RamBits(pUSB)                  (pUSB->INFO & USB_INFO_RamBits_Msk)      >> USB_INFO_RamBits_Pos
613 
614 //
615 //! Endpoint direction type
616 //
617 typedef enum
618 {
619     AM_HAL_USB_EP_DIR_OUT     = 0,
620     AM_HAL_USB_EP_DIR_IN      = 1,
621     AM_HAL_USB_EP_DIR_IN_MASK = 0x80
622 }
623 am_hal_usb_ep_dir_e;
624 
625 #define AM_HAL_USB_EP_XFER_MASK      0x3
626 
627 //
628 //! Endpoint transfer type
629 //
630 typedef enum
631 {
632     AM_HAL_USB_EP_XFER_CONTROL = 0 ,
633     AM_HAL_USB_EP_XFER_ISOCHRONOUS ,
634     AM_HAL_USB_EP_XFER_BULK        ,
635     AM_HAL_USB_EP_XFER_INTERRUPT
636 }
637 am_hal_usb_ep_xfer_type_e;
638 
639 //
640 // Endpoint address and attribute operation functions
641 //
642 //*****************************************************************************
643 //
644 // Get Endpoint Direction
645 //
646 //*****************************************************************************
647 static inline am_hal_usb_ep_dir_e
am_hal_usb_ep_dir(uint8_t addr)648 am_hal_usb_ep_dir(uint8_t addr)
649 {
650     return (addr & AM_HAL_USB_EP_DIR_IN_MASK) ? AM_HAL_USB_EP_DIR_IN : AM_HAL_USB_EP_DIR_OUT;
651 }
652 
653 //*****************************************************************************
654 //
655 // Get Endpoint Number
656 //
657 //*****************************************************************************
658 static inline uint8_t
am_hal_usb_ep_number(uint8_t addr)659 am_hal_usb_ep_number(uint8_t addr)
660 {
661     return (uint8_t)(addr & (~AM_HAL_USB_EP_DIR_IN_MASK));
662 }
663 
664 //*****************************************************************************
665 //
666 // Get Endpoint Address Type
667 //
668 //*****************************************************************************
669 static inline uint8_t
am_hal_usb_ep_addr(uint8_t num,uint8_t dir)670 am_hal_usb_ep_addr(uint8_t num, uint8_t dir)
671 {
672     return (uint8_t)(num | (dir ?  AM_HAL_USB_EP_DIR_IN_MASK : 0));
673 }
674 
675 //*****************************************************************************
676 //
677 // Get Endpoint Transfer Type
678 //
679 //*****************************************************************************
680 static inline am_hal_usb_ep_xfer_type_e
am_hal_usb_ep_xfer_type(uint8_t attr)681 am_hal_usb_ep_xfer_type(uint8_t attr)
682 {
683     return (am_hal_usb_ep_xfer_type_e)(attr & AM_HAL_USB_EP_XFER_MASK);
684 }
685 
686 //*****************************************************************************
687 //
688 // Initialization function.
689 //
690 //*****************************************************************************
691 uint32_t
am_hal_usb_initialize(uint32_t ui32Module,void ** ppHandle)692 am_hal_usb_initialize(uint32_t ui32Module, void **ppHandle)
693 {
694     //
695     // Check that the request module is in range.
696     //
697 #ifndef AM_HAL_DISABLE_API_VALIDATION
698     if ( ui32Module >= AM_REG_USB_NUM_MODULES )
699     {
700         return AM_HAL_STATUS_OUT_OF_RANGE;
701     }
702 #endif // AM_HAL_DISABLE_API_VALIDATION
703 
704     //
705     // Check for valid arguments.
706     //
707     if ( !ppHandle )
708     {
709         return AM_HAL_STATUS_INVALID_ARG;
710     }
711 
712     //
713     // Check if the handle is unallocated.
714     //
715     if ( g_am_hal_usb_states[ui32Module].prefix.s.bInit )
716     {
717         return AM_HAL_STATUS_INVALID_OPERATION;
718     }
719 
720     //
721     // Initialize the handle.
722     //
723     g_am_hal_usb_states[ui32Module].prefix.s.bInit   = true;
724     g_am_hal_usb_states[ui32Module].prefix.s.magic   = AM_HAL_MAGIC_USB;
725     g_am_hal_usb_states[ui32Module].ui32Module       = ui32Module;
726     g_am_hal_usb_states[ui32Module].sRegState.bValid = false;
727 
728     //
729     // Return the handle.
730     //
731     *ppHandle = (void *)&g_am_hal_usb_states[ui32Module];
732 
733     //
734     // Return the status.
735     //
736     return AM_HAL_STATUS_SUCCESS;
737 } // am_hal_usb_initialize()
738 
739 //*****************************************************************************
740 //
741 // De-Initialization function.
742 //
743 //*****************************************************************************
744 uint32_t
am_hal_usb_deinitialize(void * pHandle)745 am_hal_usb_deinitialize(void *pHandle)
746 {
747     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
748 
749     //
750     // Check the handle.
751     //
752 #ifndef AM_HAL_DISABLE_API_VALIDATION
753     if ( !AM_HAL_USB_CHK_HANDLE(pHandle) )
754     {
755         return AM_HAL_STATUS_INVALID_HANDLE;
756     }
757 #endif // AM_HAL_DISABLE_API_VALIDATION
758 
759     //
760     // Reset the handle.
761     //
762     pState->prefix.s.bInit = false;
763     pState->prefix.s.magic = 0;
764     pState->ui32Module     = 0;
765 
766     //
767     // Return the status.
768     //
769     return AM_HAL_STATUS_SUCCESS;
770 }
771 
772 //*****************************************************************************
773 //
774 // Power control functions.
775 //
776 //*****************************************************************************
777 uint32_t
am_hal_usb_power_control(void * pHandle,am_hal_sysctrl_power_state_e ePowerState,bool bRetainState)778 am_hal_usb_power_control(void *pHandle,
779                          am_hal_sysctrl_power_state_e ePowerState,
780                          bool bRetainState)
781 {
782     uint8_t i;
783     uint32_t ui32Status;
784     am_hal_usb_state_t *pState = (am_hal_usb_state_t *) pHandle;
785     uint32_t ui32Module = pState->ui32Module;
786 
787     USB_Type *pUSB = USBn(ui32Module);
788 
789 #ifndef AM_HAL_DISABLE_API_VALIDATION
790     if ( ui32Module >= AM_REG_USB_NUM_MODULES )
791     {
792         return AM_HAL_STATUS_OUT_OF_RANGE;
793     }
794 
795     //
796     // Check to make sure this is a valid handle.
797     //
798     if ( !AM_HAL_USB_CHK_HANDLE(pHandle) )
799     {
800         return AM_HAL_STATUS_INVALID_HANDLE;
801     }
802 #endif // AM_HAL_DISABLE_API_VALIDATION
803 
804     //
805     // Decode the requested power state and update SCARD operation accordingly.
806     //
807     switch (ePowerState)
808     {
809         case AM_HAL_SYSCTRL_WAKE:
810             //
811             // Make sure we don't try to restore an invalid state.
812             //
813             if ( bRetainState && !pState->sRegState.bValid )
814             {
815                 return AM_HAL_STATUS_INVALID_OPERATION;
816             }
817 
818             //
819             // Enable power control.
820             //
821             if ((ui32Status = am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_PERIPH_USB)) != AM_HAL_STATUS_SUCCESS)
822             {
823                 return ui32Status;
824             }
825 
826             if ((ui32Status = am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_PERIPH_USBPHY)) != AM_HAL_STATUS_SUCCESS)
827             {
828                 return ui32Status;
829             }
830 
831             //
832             // Add the USB SRAM trim settings
833             //
834             pUSB->SRAMCTRL = _VAL2FLD(USB_SRAMCTRL_WABL, 1)     |
835                              _VAL2FLD(USB_SRAMCTRL_WABLM, 1)    |
836                              _VAL2FLD(USB_SRAMCTRL_RAWL, 1)     |
837                              _VAL2FLD(USB_SRAMCTRL_RAWLM, 2)    |
838                              _VAL2FLD(USB_SRAMCTRL_EMAW, 0)     |
839                              _VAL2FLD(USB_SRAMCTRL_EMAS, 0)     |
840                              _VAL2FLD(USB_SRAMCTRL_EMA, 3)      |
841                              _VAL2FLD(USB_SRAMCTRL_RET1N, 1);
842 
843             if ( bRetainState )
844             {
845                 AM_HAL_USB_ENTER_CRITICAL;
846 
847                 //
848                 // Restore the CFG register
849                 //
850                 pUSB->CFG0 = pState->sRegState.regCFG0;
851                 pUSB->CFG1 = pState->sRegState.regCFG1;
852                 pUSB->CFG2 = pState->sRegState.regCFG2;
853 
854                 for (i = AM_HAL_USB_EP1_NUMBER; i <= AM_HAL_USB_EP5_NUMBER; i++)
855                 {
856                     EP_INDEX_Set(pUSB, i);
857                     pUSB->IDX0 = pState->sRegState.regEndPoints[i-1].regIDX0;
858                     pUSB->IDX1 = pState->sRegState.regEndPoints[i-1].regIDX1;
859                     pUSB->IDX2 = pState->sRegState.regEndPoints[i-1].regIDX2;
860                 }
861 
862                 pState->sRegState.bValid = false;
863 
864                 AM_HAL_USB_EXIT_CRITICAL;
865             }
866             break;
867 
868         case AM_HAL_SYSCTRL_NORMALSLEEP:
869         case AM_HAL_SYSCTRL_DEEPSLEEP:
870             if ( bRetainState )
871             {
872                 AM_HAL_USB_ENTER_CRITICAL;
873 
874                 pState->sRegState.regCFG0 = pUSB->CFG0;
875                 pState->sRegState.regCFG1 = pUSB->CFG1;
876                 pState->sRegState.regCFG2 = pUSB->CFG2;
877 
878                 for (i = AM_HAL_USB_EP1_NUMBER; i <= AM_HAL_USB_EP5_NUMBER; i++)
879                 {
880                     EP_INDEX_Set(pUSB, i);
881                     pState->sRegState.regEndPoints[i - 1].regIDX0 = pUSB->IDX0;
882                     pState->sRegState.regEndPoints[i - 1].regIDX1 = pUSB->IDX1;
883                     pState->sRegState.regEndPoints[i - 1].regIDX2 = pUSB->IDX2;
884                 }
885 
886                 pState->sRegState.bValid = true;
887 
888                 AM_HAL_USB_EXIT_CRITICAL;
889             }
890 
891             //
892             // Clear all interrupts before sleeping as having a pending SCARD
893             // interrupt burns power.
894             //
895 
896             am_hal_usb_intr_usb_clear(pState);
897             am_hal_usb_intr_ep_in_clear(pState);
898             am_hal_usb_intr_ep_out_clear(pState);
899 
900             //
901             // Disable power control.
902             //
903             if ((ui32Status = am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_USB)) == AM_HAL_STATUS_SUCCESS)
904             {
905                 ui32Status = am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_USBPHY);
906             }
907             break;
908 
909         default:
910             return AM_HAL_STATUS_INVALID_ARG;
911     }
912 
913     //
914     // Return the status.
915     //
916     return ui32Status;
917 }
918 
919 //*****************************************************************************
920 //
921 // start the remote wakeup
922 //
923 //*****************************************************************************
924 uint32_t
am_hal_usb_start_remote_wakeup(void * pHandle)925 am_hal_usb_start_remote_wakeup(void *pHandle)
926 {
927     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
928 
929 #ifndef AM_HAL_DISABLE_API_VALIDATION
930     if (!AM_HAL_USB_CHK_HANDLE(pHandle) )
931     {
932         return AM_HAL_STATUS_INVALID_HANDLE;
933     }
934 #endif
935 
936     USB_Type *pUSB = USBn(pState->ui32Module);
937 
938     // Wrong USB device state
939     if (pState->eDevState != AM_HAL_USB_DEV_STATE_SUSPENDED)
940     {
941         return AM_HAL_STATUS_INVALID_OPERATION;
942     }
943     else
944     {
945         INTRUSBE_Resume_Enable(pUSB);
946     }
947 
948     return AM_HAL_STATUS_SUCCESS;
949 }
950 
951 //*****************************************************************************
952 //
953 // stop the remote wakeup
954 //
955 //*****************************************************************************
956 uint32_t
am_hal_usb_end_remote_wakeup(void * pHandle)957 am_hal_usb_end_remote_wakeup(void *pHandle)
958 {
959     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
960 
961 #ifndef AM_HAL_DISABLE_API_VALIDATION
962     if (!AM_HAL_USB_CHK_HANDLE(pHandle) )
963     {
964         return AM_HAL_STATUS_INVALID_HANDLE;
965     }
966 #endif
967 
968     USB_Type *pUSB = USBn(pState->ui32Module);
969 
970     //
971     // Should clear this bit after 10 ms (a maximum of 15 ms) to end Resume signaling
972     //
973     INTRUSBE_Resume_Disable(pUSB);
974 
975     return AM_HAL_STATUS_SUCCESS;
976 }
977 
978 //*****************************************************************************
979 //
980 // set the USB device address
981 //
982 //*****************************************************************************
983 uint32_t
am_hal_usb_set_addr(void * pHandle,uint8_t ui8DevAddr)984 am_hal_usb_set_addr(void *pHandle, uint8_t ui8DevAddr)
985 {
986     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
987 
988 #ifndef AM_HAL_DISABLE_API_VALIDATION
989         if (!AM_HAL_USB_CHK_HANDLE(pHandle) )
990         {
991             return AM_HAL_STATUS_INVALID_HANDLE;
992         }
993 #endif
994 
995     USB_Type *pUSB = USBn(pState->ui32Module);
996 
997     FADDR_FuncAddr_Set(pUSB, ui8DevAddr);
998 
999     return AM_HAL_STATUS_SUCCESS;
1000 }
1001 
1002 //
1003 // Upper layer function like USB power control module
1004 // will use this API to set USB device state
1005 // from 'SUSPENDING' to 'SUSPENDED' or
1006 // from 'RESUMING' to 'RESUMED'
1007 //
1008 //*****************************************************************************
1009 //
1010 // set the USB device state
1011 //
1012 //*****************************************************************************
1013 uint32_t
am_hal_usb_set_dev_state(void * pHandle,am_hal_usb_dev_state_e eDevState)1014 am_hal_usb_set_dev_state(void *pHandle, am_hal_usb_dev_state_e eDevState)
1015 {
1016     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
1017 
1018 #ifndef AM_HAL_DISABLE_API_VALIDATION
1019     if (!AM_HAL_USB_CHK_HANDLE(pHandle) )
1020     {
1021         return AM_HAL_STATUS_INVALID_HANDLE;
1022     }
1023 #endif
1024 
1025     AM_CRITICAL_BEGIN
1026     pState->eDevState = eDevState;
1027     AM_CRITICAL_END
1028 
1029     return AM_HAL_STATUS_SUCCESS;
1030 }
1031 
1032 //*****************************************************************************
1033 //
1034 // get the current USB speed
1035 //
1036 //*****************************************************************************
1037 am_hal_usb_dev_speed_e
am_hal_get_usb_dev_speed(void * pHandle)1038 am_hal_get_usb_dev_speed(void *pHandle)
1039 {
1040     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
1041 
1042 #ifndef AM_HAL_DISABLE_API_VALIDATION
1043     if (!AM_HAL_USB_CHK_HANDLE(pHandle) )
1044     {
1045         return AM_HAL_USB_SPEED_UNKNOWN;
1046     }
1047 #endif
1048 
1049     return pState->eDevSpeed;
1050 }
1051 
1052 //*****************************************************************************
1053 //
1054 // set the USB speed
1055 //
1056 //*****************************************************************************
1057 uint32_t
am_hal_usb_set_dev_speed(void * pHandle,am_hal_usb_dev_speed_e eSpeed)1058 am_hal_usb_set_dev_speed(void *pHandle, am_hal_usb_dev_speed_e eSpeed)
1059 {
1060     am_hal_usb_state_t *pState = (am_hal_usb_state_t *) pHandle;
1061 
1062 #ifndef AM_HAL_DISABLE_API_VALIDATION
1063     if (!AM_HAL_USB_CHK_HANDLE(pHandle) || eSpeed == AM_HAL_USB_SPEED_UNKNOWN)
1064     {
1065         return AM_HAL_STATUS_INVALID_HANDLE;
1066     }
1067 #endif
1068 
1069     USB_Type *pUSB = USBn(pState->ui32Module);
1070     switch (eSpeed)
1071     {
1072         case AM_HAL_USB_SPEED_FULL:
1073         case AM_HAL_USB_SPEED_LOW:
1074             POWER_HSEnab_Clear(pUSB);
1075             pUSB->CLKCTRL_b.PHYREFCLKSEL = USB_CLKCTRL_PHYREFCLKSEL_HFRC24;
1076             break;
1077         case AM_HAL_USB_SPEED_HIGH:
1078             POWER_HSEnab_Set(pUSB);
1079             pUSB->CLKCTRL_b.PHYREFCLKSEL = USB_CLKCTRL_PHYREFCLKSEL_HFRC248;
1080 
1081             break;
1082         default:
1083             return AM_HAL_STATUS_INVALID_ARG;
1084 
1085     }
1086 
1087     pState->eDevSpeed = eSpeed;
1088 
1089     return AM_HAL_STATUS_SUCCESS;
1090 }
1091 
1092 //*****************************************************************************
1093 //
1094 // soft connect to the USB host
1095 //
1096 //*****************************************************************************
1097 uint32_t
am_hal_usb_attach(void * pHandle)1098 am_hal_usb_attach(void *pHandle)
1099 {
1100     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
1101 
1102 #ifndef AM_HAL_DISABLE_API_VALIDATION
1103     if (!AM_HAL_USB_CHK_HANDLE(pHandle) )
1104     {
1105         return AM_HAL_STATUS_INVALID_HANDLE;
1106     }
1107 #endif
1108 
1109     USB_Type *pUSB = USBn(pState->ui32Module);
1110 
1111     // Do soft connection to the USB host
1112     POWER_AMSPECIFIC_Set(pUSB);
1113 
1114     return AM_HAL_STATUS_SUCCESS;
1115 }
1116 
1117 //*****************************************************************************
1118 //
1119 // soft disconnect to the USB host
1120 //
1121 //*****************************************************************************
1122 uint32_t
am_hal_usb_detach(void * pHandle)1123 am_hal_usb_detach(void *pHandle)
1124 {
1125     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
1126 
1127 #ifndef AM_HAL_DISABLE_API_VALIDATION
1128     if (!AM_HAL_USB_CHK_HANDLE(pHandle) )
1129     {
1130         return AM_HAL_STATUS_INVALID_HANDLE;
1131     }
1132 #endif
1133 
1134     USB_Type *pUSB = USBn(pState->ui32Module);
1135 
1136     // Do soft disconnection from the USB Host
1137     POWER_AMSPECIFIC_Clear(pUSB);
1138 
1139     return AM_HAL_STATUS_SUCCESS;
1140 }
1141 
1142 //*****************************************************************************
1143 //
1144 // get the USB frame number
1145 //
1146 //*****************************************************************************
1147 uint32_t
am_hal_get_frame_number(void * pHandle)1148 am_hal_get_frame_number(void *pHandle)
1149 {
1150     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
1151 
1152 #ifndef AM_HAL_DISABLE_API_VALIDATION
1153     if (!AM_HAL_USB_CHK_HANDLE(pHandle) )
1154     {
1155         return AM_HAL_STATUS_INVALID_HANDLE;
1156     }
1157 #endif
1158 
1159     USB_Type *pUSB = USBn(pState->ui32Module);
1160 
1161     return FRAME_NUM(pUSB);
1162 }
1163 
1164 #ifdef AM_HAL_USB_GET_HW_INFO_ENABLED
1165 
1166 //*****************************************************************************
1167 //
1168 // get the hardware information
1169 //
1170 //*****************************************************************************
1171 uint32_t
am_hal_usb_get_hw_infor(void * pHandle,am_hal_usb_hw_info * sHWInfo)1172 am_hal_usb_get_hw_infor(void *pHandle, am_hal_usb_hw_info *sHWInfo)
1173 {
1174     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
1175 
1176 #ifndef AM_HAL_DISABLE_API_VALIDATION
1177     if (!AM_HAL_USB_CHK_HANDLE(pHandle) )
1178     {
1179         return AM_HAL_STATUS_INVALID_HANDLE;
1180     }
1181 #endif
1182     USB_Type *pUSB = USBn(pState->ui32Module);
1183 
1184     sHWInfo->ui8Major       = HWVERS_xx(pUSB);
1185     sHWInfo->ui16Minor      = HWVERS_yyy(pUSB);
1186     sHWInfo->ui8OutEpNum    = EPINFO_OutEndPoints(pUSB);
1187     sHWInfo->ui8InEpNum     = EPINFO_InEndPoints(pUSB);
1188     sHWInfo->ui8RamBits     = RAMINFO_RamBits(pUSB);
1189 
1190     return AM_HAL_STATUS_SUCCESS;
1191 }
1192 
1193 #endif
1194 
1195 //*****************************************************************************
1196 //
1197 // Unload FIFO to buffer
1198 //
1199 //*****************************************************************************
1200 static inline void
am_hal_usb_fifo_unloading(USB_Type * pUSB,uint8_t ui8EpNum,uint8_t * pucBuf,uint32_t ui32Count)1201 am_hal_usb_fifo_unloading(USB_Type *pUSB, uint8_t ui8EpNum, uint8_t *pucBuf, uint32_t ui32Count)
1202 {
1203     uint32_t Read32bitCount;
1204     uint32_t Read32bitRemain;
1205 
1206     Read32bitCount   = ui32Count / sizeof(uint32_t);
1207     Read32bitRemain  = ui32Count - Read32bitCount * sizeof(uint32_t);
1208 
1209     for (int i = 0; i < Read32bitCount; i++)
1210     {
1211         *((uint32_t *)pucBuf + i) = *FIFOx_ADDR(pUSB, ui8EpNum);
1212     }
1213 
1214     if (Read32bitRemain)
1215     {
1216         uint8_t *pui8FIFO;
1217 
1218         pui8FIFO = ((uint8_t *)FIFOx_ADDR(pUSB, ui8EpNum));
1219 
1220         for (int i = 0; i < Read32bitRemain; i++)
1221         {
1222             pucBuf[Read32bitCount*sizeof(uint32_t) + i] = *pui8FIFO;
1223         }
1224     }
1225 }
1226 
1227 //*****************************************************************************
1228 //
1229 // Load the FIFO with Data
1230 //
1231 //*****************************************************************************
1232 static inline void
am_hal_usb_fifo_loading(USB_Type * pUSB,uint8_t ui8EpNum,uint8_t * pucBuf,uint32_t ui32Count)1233 am_hal_usb_fifo_loading(USB_Type *pUSB, uint8_t ui8EpNum, uint8_t *pucBuf, uint32_t ui32Count)
1234 {
1235     uint32_t Write32bitCount;
1236     uint32_t Write32bitRemain;
1237 
1238     Write32bitCount   = ui32Count / sizeof(uint32_t);
1239     Write32bitRemain  = ui32Count - Write32bitCount * sizeof(uint32_t);
1240 
1241     for (int i = 0; i < Write32bitCount; i++)
1242     {
1243         *FIFOx_ADDR(pUSB, ui8EpNum) = *((uint32_t *)pucBuf + i);
1244     }
1245 
1246     if (Write32bitRemain)
1247     {
1248         volatile uint8_t *pui8FIFO = ((volatile uint8_t *)FIFOx_ADDR(pUSB, ui8EpNum));
1249 
1250         for (int i = 0; i < Write32bitRemain; i++)
1251         {
1252             *pui8FIFO = pucBuf[Write32bitCount*sizeof(uint32_t) + i];
1253         }
1254     }
1255 }
1256 
1257 #ifdef AM_HAL_USB_TEST_MODE_ENABLED
1258 
1259 static const uint8_t
1260 test_packet[] =
1261 {
1262     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1263     0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
1264     0xAA, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
1265     0xEE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1266     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xBF, 0xDF,
1267     0xEF, 0xF7, 0xFB, 0xFD, 0xFC, 0x7E, 0xBF, 0xDF,
1268     0xEF, 0xF7, 0xFB, 0xFD, 0x7E
1269 };
1270 
1271 //*****************************************************************************
1272 //
1273 // set the USB test mode flag
1274 //
1275 //*****************************************************************************
1276 uint32_t
am_hal_usb_enter_test_mode(const void * pHandle)1277 am_hal_usb_enter_test_mode(const void *pHandle)
1278 {
1279     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
1280 
1281 #ifndef AM_HAL_DISABLE_API_VALIDATION
1282     if (!AM_HAL_USB_CHK_HANDLE(pHandle) )
1283     {
1284         return AM_HAL_STATUS_INVALID_HANDLE;
1285     }
1286 #endif
1287 
1288     pState->bInTestMode = true;
1289 
1290     return AM_HAL_STATUS_SUCCESS;
1291 }
1292 
1293 //*****************************************************************************
1294 //
1295 // do the USB test
1296 //
1297 //*****************************************************************************
1298 uint32_t
am_hal_usb_test_mode(const void * pHandle,const am_hal_usb_test_mode_e eTestMode)1299 am_hal_usb_test_mode(const void *pHandle, const am_hal_usb_test_mode_e eTestMode)
1300 {
1301     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
1302 
1303 #ifndef AM_HAL_DISABLE_API_VALIDATION
1304     if (!AM_HAL_USB_CHK_HANDLE(pHandle) )
1305     {
1306         return AM_HAL_STATUS_INVALID_HANDLE;
1307     }
1308 #endif
1309 
1310     USB_Type *pUSB = USBn(pState->ui32Module);
1311 
1312     // bInTestMode is setting when host send
1313     // SetFeature(TEST_TMODE)
1314     if (pState->bInTestMode)
1315     {
1316         switch ( eTestMode )
1317         {
1318             case AM_HAL_USB_TEST_SE0_NAK:
1319                 TESTMODE_TestSE0NAK_Set(pUSB);
1320                 break;
1321             case AM_HAL_USB_TEST_J:
1322                 TESTMODE_TestJ_Set(pUSB);
1323                 break;
1324             case AM_HAL_USB_TEST_K:
1325                 TESTMODE_TestK_Set(pUSB);
1326                 break;
1327             case AM_HAL_USB_TEST_PACKET:
1328                 EP_INDEX_Set(pUSB, 0x0);
1329                 am_hal_usb_fifo_loading(pUSB, 0x0, (uint8_t *)test_packet, sizeof(test_packet));
1330                 CSR0_InPktRdy_Set(pUSB);
1331                 TESTMODE_TestPacket_Set(pUSB);
1332                 break;
1333         }
1334     }
1335     return AM_HAL_STATUS_SUCCESS;
1336 }
1337 
1338 #endif
1339 
1340 //*****************************************************************************
1341 //
1342 // enable the SOF interrupt
1343 //
1344 //*****************************************************************************
1345 uint32_t
am_hal_usb_enable_sof_intr(void * pHandle)1346 am_hal_usb_enable_sof_intr(void *pHandle)
1347 {
1348     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
1349 
1350 #ifndef AM_HAL_DISABLE_API_VALIDATION
1351     if (!AM_HAL_USB_CHK_HANDLE(pHandle) )
1352     {
1353         return AM_HAL_STATUS_INVALID_HANDLE;
1354     }
1355 #endif
1356 
1357     USB_Type *pUSB = USBn(pState->ui32Module);
1358     INTRUSBE_SOF_Enable(pUSB);
1359 
1360     return AM_HAL_STATUS_SUCCESS;
1361 }
1362 
1363 //*****************************************************************************
1364 //
1365 // disable the SOF interrupt
1366 //
1367 //*****************************************************************************
1368 uint32_t
am_hal_usb_disable_sof_intr(void * pHandle)1369 am_hal_usb_disable_sof_intr(void *pHandle)
1370 {
1371     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
1372 
1373 #ifndef AM_HAL_DISABLE_API_VALIDATION
1374     if (!AM_HAL_USB_CHK_HANDLE(pHandle) )
1375     {
1376         return AM_HAL_STATUS_INVALID_HANDLE;
1377     }
1378 #endif
1379 
1380     USB_Type *pUSB = USBn(pState->ui32Module);
1381     INTRUSBE_SOF_Disable(pUSB);
1382 
1383     return AM_HAL_STATUS_SUCCESS;
1384 }
1385 
1386 //
1387 // Endpoints related operation functions
1388 //
1389 
1390 //*****************************************************************************
1391 //
1392 // Reset USB Transfer
1393 //
1394 //*****************************************************************************
1395 static inline void
am_hal_usb_xfer_reset(am_hal_usb_ep_xfer_t * pXfer)1396 am_hal_usb_xfer_reset(am_hal_usb_ep_xfer_t *pXfer)
1397 {
1398     memset((void *)pXfer, 0x0, sizeof(*pXfer));
1399 }
1400 
1401 //*****************************************************************************
1402 //
1403 // Reset EP0 State
1404 //
1405 //*****************************************************************************
1406 static inline void
am_hal_usb_ep0_state_reset(am_hal_usb_state_t * pState)1407 am_hal_usb_ep0_state_reset(am_hal_usb_state_t *pState)
1408 {
1409     pState->eEP0State = AM_HAL_USB_EP0_STATE_IDLE;
1410     am_hal_usb_xfer_reset(&pState->ep0_xfer);
1411 }
1412 
1413 //*****************************************************************************
1414 //
1415 // Complete the USB Transfer
1416 //
1417 //*****************************************************************************
1418 static void
am_hal_usb_xfer_complete(am_hal_usb_state_t * pState,am_hal_usb_ep_xfer_t * pXfer,uint8_t ui8EpAddr,uint16_t ui16XferLen,am_hal_usb_xfer_code_e eXferCode,void * param)1419 am_hal_usb_xfer_complete(am_hal_usb_state_t *pState, am_hal_usb_ep_xfer_t *pXfer,
1420                          uint8_t ui8EpAddr, uint16_t ui16XferLen,
1421                          am_hal_usb_xfer_code_e eXferCode, void *param)
1422 {
1423     /* The transaction we're about to issue the callback for is still marked 'busy'.
1424      * This isn't normally a problem in thread models, where the ISR callback just
1425      * sets a bit for later. Pure-ISR USB implementations will generally want to
1426      * immediately reissue endpoint transactions./
1427      *
1428      * So, reset the transfer first, then issue the callback.
1429      */
1430 
1431     if (pState && pXfer)
1432     {
1433         am_hal_usb_xfer_reset(pXfer);
1434         pState->ep_xfer_complete_callback(ui8EpAddr, ui16XferLen, eXferCode, param);
1435     }
1436 }
1437 
1438 //*****************************************************************************
1439 //
1440 // stall the endpoint
1441 //
1442 //*****************************************************************************
1443 uint32_t
am_hal_usb_ep_stall(void * pHandle,uint8_t ui8EpAddr)1444 am_hal_usb_ep_stall(void *pHandle, uint8_t ui8EpAddr)
1445 {
1446     uint8_t ui8EpNum, ui8EpDir;
1447     am_hal_usb_state_t *pState;
1448     USB_Type *pUSB;
1449 
1450 #ifndef AM_HAL_DISABLE_API_VALIDATION
1451     if (!AM_HAL_USB_CHK_HANDLE(pHandle) )
1452     {
1453         return AM_HAL_STATUS_INVALID_HANDLE;
1454     }
1455     if (AM_HAL_USB_CHK_EP_NUM(ui8EpAddr))
1456     {
1457         return AM_HAL_STATUS_INVALID_ARG;
1458     }
1459 #endif
1460 
1461     ui8EpNum = am_hal_usb_ep_number(ui8EpAddr);
1462     ui8EpDir = am_hal_usb_ep_dir(ui8EpAddr);
1463 
1464     pState = (am_hal_usb_state_t *)pHandle;
1465     pUSB = USBn(pState->ui32Module);
1466 
1467     AM_HAL_USB_ENTER_CRITICAL;
1468     // Select the EP registers by INDEX
1469     EP_INDEX_Set(pUSB, ui8EpNum);
1470 
1471     if (ui8EpNum == AM_HAL_USB_EP0_NUMBER)
1472     {
1473         // EP0 stall setting
1474         // It happens when upper layer USB stack can't proccess some
1475         // Request, now it should be 'AM_HAL_USB_EP0_STATE_SETUP'
1476         // An EP0 interrupt will generate, SentStall bit should be clear in
1477         // ep0 interrupt handler
1478         CSR0_ServicedOutPktRdyAndSendStall_Set(pUSB);
1479     }
1480     else
1481     {
1482         // Non zero endpoint stall setting
1483         // In next EP interrupt handling function to clear 'SentStall' bit
1484         // keep this 'SendStall' bit set until upper layer stack need to
1485         // clear it.
1486         switch ( ui8EpDir )
1487         {
1488             case AM_HAL_USB_EP_DIR_IN:
1489                 INCSRL_SendStall_Set(pUSB);
1490                 break;
1491             case AM_HAL_USB_EP_DIR_OUT:
1492                 OUTCSRL_SendStall_Set(pUSB);
1493                 break;
1494         }
1495     }
1496 
1497     AM_HAL_USB_EXIT_CRITICAL;
1498 
1499     return AM_HAL_STATUS_SUCCESS;
1500 }
1501 
1502 //*****************************************************************************
1503 //
1504 // clear the endpoint stall
1505 //
1506 //*****************************************************************************
1507 uint32_t
am_hal_usb_ep_clear_stall(void * pHandle,uint8_t ui8EpAddr)1508 am_hal_usb_ep_clear_stall(void *pHandle, uint8_t ui8EpAddr)
1509 {
1510     uint8_t ui8EpNum, ui8EpDir;
1511     am_hal_usb_state_t *pState;
1512     USB_Type *pUSB;
1513 
1514 #ifndef AM_HAL_DISABLE_API_VALIDATION
1515     if (!AM_HAL_USB_CHK_HANDLE(pHandle) )
1516     {
1517         return AM_HAL_STATUS_INVALID_HANDLE;
1518     }
1519     if (AM_HAL_USB_CHK_EP_NUM(ui8EpAddr))
1520     {
1521         return AM_HAL_STATUS_INVALID_ARG;
1522     }
1523 #endif
1524 
1525     ui8EpNum = am_hal_usb_ep_number(ui8EpAddr);
1526     ui8EpDir = am_hal_usb_ep_dir(ui8EpAddr);
1527 
1528     pState   = (am_hal_usb_state_t *)pHandle;
1529     pUSB     = USBn(pState->ui32Module);
1530 
1531     // EP0 stall clearing, do nothing
1532     if (ui8EpNum == AM_HAL_USB_EP0_NUMBER)
1533     {
1534         return AM_HAL_STATUS_SUCCESS;
1535     }
1536 
1537     AM_HAL_USB_ENTER_CRITICAL;
1538     EP_INDEX_Set(pUSB, ui8EpNum);
1539     if (ui8EpDir == AM_HAL_USB_EP_DIR_IN)
1540     {
1541         INCSRL_SendStall_Clear(pUSB);
1542 
1543         // See 8.1.3 IN endpoint error handling
1544         INCSRL_ClrDataTog_Set(pUSB);
1545     }
1546     else
1547     {
1548         OUTCSRL_SendStall_Clear(pUSB);
1549         // See 8.2.3 Out endpoint error handling
1550         OUTCSRL_ClrDataTog_Set(pUSB);
1551     }
1552     AM_HAL_USB_EXIT_CRITICAL;
1553 
1554     return AM_HAL_STATUS_SUCCESS;
1555 }
1556 
1557 //*****************************************************************************
1558 //
1559 // Return Size Mapping from Index
1560 //
1561 //*****************************************************************************
1562 static uint32_t
am_hal_usb_fifo_size(uint8_t ui8FifoSZ)1563 am_hal_usb_fifo_size(uint8_t ui8FifoSZ)
1564 {
1565     static uint32_t ui32SizeMapping[] =
1566     {
1567         8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096
1568     };
1569     return ui32SizeMapping[ui8FifoSZ];
1570 }
1571 
1572 //*****************************************************************************
1573 //
1574 // Return FIFO Size by Packet Size
1575 //
1576 //*****************************************************************************
1577 static uint8_t
am_hal_usb_fifo_size_by_maxpacket(uint16_t ui16PktSize)1578 am_hal_usb_fifo_size_by_maxpacket(uint16_t ui16PktSize)
1579 {
1580     uint8_t exp2 = 0;
1581     uint16_t tmp = ui16PktSize / 8;
1582 
1583     tmp = tmp >> 1;
1584     while (tmp)
1585     {
1586         exp2++;
1587         tmp = tmp >> 1;
1588     }
1589     return exp2;
1590 }
1591 
1592 //*****************************************************************************
1593 //
1594 // Return FICO Endpoint Sddress
1595 //
1596 //*****************************************************************************
1597 static uint32_t
am_hal_usb_ep_fifo_addr(uint32_t * ui32Allocated,uint16_t ui16PktSize)1598 am_hal_usb_ep_fifo_addr(uint32_t *ui32Allocated, uint16_t ui16PktSize)
1599 {
1600     // first 64 bytes is allocated to EP0
1601     uint32_t tmp = *ui32Allocated;
1602 #ifdef AM_HAL_USB_FEATURE_DOUBLE_PKT_FIFO
1603      *ui32Allocated += 2*ui16PktSize / 8;
1604 #else
1605      *ui32Allocated += ui16PktSize / 8;
1606 #endif
1607 
1608     return tmp;
1609 }
1610 
1611 //*****************************************************************************
1612 //
1613 // Reset FIFO Endpoint
1614 //
1615 //*****************************************************************************
1616 static inline void
am_hal_usb_ep_fifo_reset(uint32_t * ui32Allocated)1617 am_hal_usb_ep_fifo_reset(uint32_t *ui32Allocated)
1618 {
1619     *ui32Allocated = 8;
1620 }
1621 
1622 //*****************************************************************************
1623 //
1624 // initialize the endpoint
1625 //
1626 //*****************************************************************************
1627 uint32_t
am_hal_usb_ep_init(void * pHandle,uint8_t ui8EpAddr,uint8_t ui8EpAttr,uint16_t ui16MaxPacket)1628 am_hal_usb_ep_init(void *pHandle, uint8_t ui8EpAddr, uint8_t ui8EpAttr, uint16_t ui16MaxPacket)
1629 {
1630     uint8_t sz;
1631     uint8_t ui8EpNum, ui8EpDir;
1632     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
1633     USB_Type *pUSB = USBn(pState->ui32Module);
1634 
1635 #ifndef AM_HAL_DISABLE_API_VALIDATION
1636     if (!AM_HAL_USB_CHK_HANDLE(pHandle))
1637     {
1638         return AM_HAL_STATUS_INVALID_HANDLE;
1639     }
1640     if (AM_HAL_USB_CHK_EP_NUM(ui8EpAddr))
1641     {
1642         return AM_HAL_STATUS_INVALID_ARG;
1643     }
1644 
1645     // Normally USB stack endpoint descriptor should define
1646     // 64  bytes max packet for full speed
1647     // 512 bytes max packet for high speed
1648     bool hspeed = POWER_HSMode(pUSB);
1649 
1650     if ((ui16MaxPacket > am_hal_usb_fifo_size(EP_FIFO_SZ_64)) && !hspeed)
1651     {
1652         return AM_HAL_STATUS_INVALID_ARG;
1653     }
1654 #endif
1655 
1656     ui8EpNum = am_hal_usb_ep_number(ui8EpAddr);
1657     ui8EpDir = am_hal_usb_ep_dir(ui8EpAddr);
1658 
1659     EP_INDEX_Set(pUSB, ui8EpNum);
1660 
1661     if (ui8EpNum == 0x0)
1662     {
1663         INTRINE_Enable(pUSB, 0x1 << 0x0);
1664         pState->ep0_maxpacket = ui16MaxPacket;
1665         return AM_HAL_STATUS_SUCCESS;
1666     }
1667 
1668     switch ( ui8EpDir )
1669     {
1670         case AM_HAL_USB_EP_DIR_IN:
1671             INMAXP_MaxPayload_Set(pUSB, ui16MaxPacket);
1672             pState->epin_maxpackets[ui8EpNum - 1] = ui16MaxPacket;
1673 
1674             if (am_hal_usb_ep_xfer_type(ui8EpAttr) == AM_HAL_USB_EP_XFER_ISOCHRONOUS)
1675             {
1676                 INCSRU_ISO_Set(pUSB);
1677             }
1678             else
1679             {
1680                 INCSRU_ISO_Clear(pUSB);
1681             }
1682 
1683             INCSRL_ClrDataTog_Set(pUSB);
1684 
1685             if (INCSRL_FIFONotEmpty(pUSB))
1686             {
1687                 INCSRL_FlushFIFO_Set(pUSB);
1688             }
1689 
1690 #ifdef AM_HAL_USB_FEATURE_SHARING_FIFO_WITH_OUT_EP
1691             // Only for FIFO is used for both IN and OUT transaction
1692             // IN EP share the same FIFO with OUT EP
1693             // Not recommend to use this feature.
1694             INCSRU_Mode_Set(pUSB);
1695 #endif
1696 
1697             // EP IN FIFO setting
1698             sz = am_hal_usb_fifo_size_by_maxpacket(ui16MaxPacket);
1699 #ifdef AM_HAL_USB_FEATURE_DOUBLE_PKT_FIFO
1700             InFIFOsz_Set(pUSB, FIFO_DOUBLE_PKTBUF, sz);
1701             InFIFOadd_Set(pUSB, am_hal_usb_ep_fifo_addr(&pState->ui32Allocated, ui16MaxPacket));
1702 #else       // Single-packet buffering
1703             InFIFOsz_Set(pUSB, FIFO_SINGLE_PKTBUF, sz);
1704             InFIFOadd_Set(pUSB, am_hal_usb_ep_fifo_addr(&pState->ui32Allocated, ui16MaxPacket));
1705 #endif
1706             break;
1707         case AM_HAL_USB_EP_DIR_OUT:
1708             OUTMAXP_MaxPayload_Set(pUSB, ui16MaxPacket);
1709             pState->epout_maxpackets[ui8EpNum - 1] = ui16MaxPacket;
1710 
1711             if (am_hal_usb_ep_xfer_type(ui8EpAttr) == AM_HAL_USB_EP_XFER_ISOCHRONOUS)
1712             {
1713                 OUTCSRU_ISO_Set(pUSB);
1714             }
1715             else
1716             {
1717                 // Enable bulk protocol
1718                 OUTCSRU_ISO_Clear(pUSB);
1719 #ifdef AM_HAL_USB_FEATURE_NO_NYET
1720                 // Disable NYET for test purpose (only effective for highspeed)
1721                 OUTCSRU_DisNye_Set(pUSB);
1722 #endif
1723             }
1724 
1725             OUTCSRL_ClrDataTog_Set(pUSB);
1726 
1727             if (OUTCSRL_OutPktRdy(pUSB))
1728             {
1729                 OUTCSRL_FlushFIFO_Set(pUSB);
1730             }
1731 
1732             // EP OUT FIFO setting
1733             sz = am_hal_usb_fifo_size_by_maxpacket(ui16MaxPacket);
1734 #ifdef AM_HAL_USB_DOUBLE_PKT_FIFO
1735             OutFIFOsz_Set(pUSB, FIFO_DOUBLE_PKTBUF, sz);
1736             OutFIFOadd_Set(pUSB, am_hal_usb_ep_fifo_addr(&pState->ui32Allocated, ui16MaxPacket));
1737 #else       // Single-packet buffering
1738             OutFIFOsz_Set(pUSB, FIFO_SINGLE_PKTBUF, sz);
1739             OutFIFOadd_Set(pUSB, am_hal_usb_ep_fifo_addr(&pState->ui32Allocated, ui16MaxPacket));
1740 #endif
1741             break;
1742     }
1743     return AM_HAL_STATUS_SUCCESS;
1744 }
1745 
1746 //*****************************************************************************
1747 //
1748 // submit a USB Endpoint 0 transfer
1749 //
1750 //*****************************************************************************
1751 static uint32_t
am_hal_usb_ep0_xfer(am_hal_usb_state_t * pState,uint8_t ui8EpNum,uint8_t ui8EpDir,uint8_t * pui8Buf,uint16_t ui16Len)1752 am_hal_usb_ep0_xfer(am_hal_usb_state_t *pState, uint8_t ui8EpNum, uint8_t ui8EpDir, uint8_t *pui8Buf, uint16_t ui16Len)
1753 {
1754     uint32_t status;
1755     uint16_t maxpacket;
1756     USB_Type *pUSB = USBn(pState->ui32Module);
1757 
1758     AM_HAL_USB_ENTER_CRITICAL;
1759 
1760     // Select the endpoint by index register
1761     EP_INDEX_Set(pUSB, ui8EpNum);
1762 
1763     if (pState->ep0_xfer.flags.busy == 0x1)
1764     {
1765         status = AM_HAL_STATUS_IN_USE;
1766     }
1767     else
1768     {
1769         status = AM_HAL_STATUS_SUCCESS;
1770         pState->ep0_xfer.flags.busy = 0x1;
1771     }
1772 
1773     if (status == AM_HAL_STATUS_IN_USE)
1774     {
1775         AM_HAL_USB_EXIT_CRITICAL;
1776         return status;
1777     }
1778 
1779     maxpacket = pState->ep0_maxpacket;
1780 
1781     pState->ep0_xfer.flags.dir = ui8EpDir;
1782     pState->ep0_xfer.buf = pui8Buf;
1783     pState->ep0_xfer.len = ui16Len;
1784 
1785     switch ( pState->eEP0State )
1786     {
1787         case AM_HAL_USB_EP0_STATE_SETUP:
1788             if (ui16Len == 0x0)
1789             {
1790                 // Upper layer USB stack just use zero length packet to confirm no data stage
1791                 // some requests like CLEAR_FEARURE, SET_ADDRESS, SET_CONFIGRATION, etc.
1792                 // end the control transfer from device side
1793                 CSR0_ServicedOutPktRdyAndDataEnd_Set(pUSB);
1794 
1795                 // Move to the status stage and second EP0 interrupt
1796                 // Will indicate request is completed
1797                 pState->eEP0State =
1798                     (ui8EpDir == AM_HAL_USB_EP_DIR_IN) ? AM_HAL_USB_EP0_STATE_STATUS_TX : AM_HAL_USB_EP0_STATE_STATUS_RX;
1799 
1800             }
1801             else
1802             {
1803                 // Enter the data stage if the request have the data stage
1804                 // some requests like GET_*_DESCRIPTOR
1805                 CSR0_ServicedOutPktRdy_Set(pUSB);
1806 
1807                 switch ( ui8EpDir )
1808                 {
1809                     // Read requests handling
1810                     case AM_HAL_USB_EP_DIR_IN:
1811                         // Load the first packet
1812                         if (ui16Len < maxpacket)
1813                         {
1814                             pState->ep0_xfer.remaining = 0x0;
1815                             pState->eEP0State = AM_HAL_USB_EP0_STATE_STATUS_TX;
1816                             am_hal_usb_fifo_loading(pUSB, 0x0, pui8Buf, ui16Len);
1817 
1818                             CSR0_InPktRdyAndDataEnd_Set(pUSB);
1819                         }
1820                         else
1821                         {
1822                             pState->ep0_xfer.remaining = ui16Len - maxpacket;
1823                             pState->eEP0State = AM_HAL_USB_EP0_STATE_DATA_TX;
1824                             am_hal_usb_fifo_loading(pUSB, 0x0, pui8Buf, maxpacket);
1825 
1826                             // The remaining packets will be loaded in the ep0 interrupt handler function
1827                             CSR0_InPktRdy_Set(pUSB);
1828 
1829                         }
1830                         break;
1831                     case AM_HAL_USB_EP_DIR_OUT:
1832                         // Write requests handling
1833                         // Waiting the host sending the data to the device
1834                         pState->ep0_xfer.remaining = ui16Len;
1835                         pState->eEP0State = AM_HAL_USB_EP0_STATE_DATA_RX;
1836 
1837                         break;
1838                 }
1839             }
1840             break;
1841         default:
1842             AM_HAL_USB_EXIT_CRITICAL;
1843             return AM_HAL_STATUS_FAIL;
1844     }
1845 
1846     AM_HAL_USB_EXIT_CRITICAL;
1847 
1848     return AM_HAL_STATUS_SUCCESS;
1849 }
1850 
1851 //*****************************************************************************
1852 //
1853 // submit a USB Non-Endpoint 0 transfer
1854 //
1855 //*****************************************************************************
1856 
1857 static uint32_t
am_hal_usb_non_ep0_xfer(am_hal_usb_state_t * pState,uint8_t ui8EpNum,uint8_t ui8EpDir,uint8_t * pui8Buf,uint16_t ui16Len)1858 am_hal_usb_non_ep0_xfer(am_hal_usb_state_t *pState, uint8_t ui8EpNum, uint8_t ui8EpDir, uint8_t *pui8Buf, uint16_t ui16Len)
1859 {
1860     uint32_t status;
1861     uint16_t maxpacket;
1862 
1863     // Non EP0 transfer handling
1864     am_hal_usb_ep_xfer_t *pXfer = &pState->ep_xfers[ui8EpNum - 1][ui8EpDir];
1865     USB_Type *pUSB = USBn(pState->ui32Module);
1866 
1867     AM_HAL_USB_ENTER_CRITICAL;
1868 
1869     // Select the endpoint by index register
1870     EP_INDEX_Set(pUSB, ui8EpNum);
1871 
1872     // Need to protect it by disabling interrupt
1873     // USB EP interrupt hander will update it.
1874     if (pXfer->flags.busy == 0x1)
1875     {
1876         status = AM_HAL_STATUS_IN_USE;
1877     }
1878     else
1879     {
1880         status = AM_HAL_STATUS_SUCCESS;
1881         pXfer->flags.busy = 0x1;
1882     }
1883 
1884     if (status == AM_HAL_STATUS_IN_USE)
1885     {
1886         AM_HAL_USB_EXIT_CRITICAL;
1887         return status;
1888     }
1889 
1890     pXfer->flags.dir = ui8EpDir;
1891 
1892     // Note: does not use automatic Bulk packet splitting option
1893     switch (ui8EpDir)
1894     {
1895         case  AM_HAL_USB_EP_DIR_IN:
1896             // Handling IN endpoint transfer
1897             maxpacket  = pState->epin_maxpackets[ui8EpNum - 1];
1898 
1899             if (ui16Len < maxpacket)
1900             {
1901                 am_hal_usb_fifo_loading(pUSB, ui8EpNum, pui8Buf, ui16Len);
1902                 pXfer->remaining = 0x0;
1903             }
1904             else
1905             {
1906                 am_hal_usb_fifo_loading(pUSB, ui8EpNum, pui8Buf, maxpacket);
1907                 pXfer->remaining = ui16Len - maxpacket;
1908             }
1909 
1910             if (ui16Len == maxpacket)
1911             {
1912                 pXfer->flags.zlp = 1;
1913             }
1914 
1915             pXfer->buf = pui8Buf;
1916             pXfer->len = ui16Len;
1917             INCSRL_InPktRdy_Set(pUSB);
1918             INTRINE_Enable(pUSB, 0x1 << ui8EpNum);
1919             break;
1920         case AM_HAL_USB_EP_DIR_OUT:
1921             // Handling OUT endpoint transfer
1922             maxpacket  = pState->epout_maxpackets[ui8EpNum - 1];
1923 
1924 #ifdef AM_HAL_USB_FEATURE_EP_READ_TIMEOUT
1925             pXfer->xfer_started = false;
1926             pXfer->timeout = AM_HAL_USB_TIMEOUT;
1927 #endif
1928 
1929             pXfer->buf = pui8Buf;
1930             pXfer->len = ui16Len;
1931             pXfer->remaining = ui16Len;
1932 
1933             //
1934             // clear OutPktRdy bit before enabling the interrupt
1935             //
1936             OUTCSRL_OutPktRdy_Clear(pUSB);
1937 
1938             //
1939             // enable out endpoint interrupt for this EP.
1940             //
1941             INTROUTE_Enable(pUSB, 0x1 << ui8EpNum);
1942             break;
1943     }
1944 
1945     AM_HAL_USB_EXIT_CRITICAL;
1946 
1947     return AM_HAL_STATUS_SUCCESS;
1948 }
1949 
1950 //*****************************************************************************
1951 //
1952 // submit a USB transfer
1953 //
1954 //*****************************************************************************
1955 uint32_t
am_hal_usb_ep_xfer(void * pHandle,uint8_t ui8EpAddr,uint8_t * pui8Buf,uint16_t ui16Len)1956 am_hal_usb_ep_xfer(void *pHandle, uint8_t ui8EpAddr, uint8_t *pui8Buf, uint16_t ui16Len)
1957 {
1958     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
1959 
1960 #ifndef AM_HAL_DISABLE_API_VALIDATION
1961     if (!AM_HAL_USB_CHK_HANDLE(pHandle))
1962     {
1963         return AM_HAL_STATUS_INVALID_HANDLE;
1964     }
1965     if (AM_HAL_USB_CHK_EP_NUM(ui8EpAddr))
1966     {
1967         return AM_HAL_STATUS_INVALID_ARG;
1968     }
1969 #endif
1970 
1971     uint8_t ui8EpNum = am_hal_usb_ep_number(ui8EpAddr);
1972     uint8_t ui8EpDir = am_hal_usb_ep_dir(ui8EpAddr);
1973 
1974     // Handling EP0 setup control transfer
1975     if (ui8EpNum == AM_HAL_USB_EP0_NUMBER)
1976     {
1977         return am_hal_usb_ep0_xfer(pState, ui8EpNum, ui8EpDir, pui8Buf, ui16Len);
1978     }
1979     else
1980     {
1981         return am_hal_usb_non_ep0_xfer(pState, ui8EpNum, ui8EpDir, pui8Buf, ui16Len);
1982     }
1983 }
1984 
1985 //*****************************************************************
1986 //
1987 // USB Interrupt handling functions
1988 //
1989 //*****************************************************************
1990 //*****************************************************************************
1991 //
1992 // get all USB related interrupt status
1993 //
1994 //*****************************************************************************
1995 uint32_t
am_hal_usb_intr_status_get(void * pHandle,uint32_t * ui32IntrUsbStatus,uint32_t * ui32IntrInStatus,uint32_t * ui32IntrOutStatus)1996 am_hal_usb_intr_status_get(void *pHandle, uint32_t *ui32IntrUsbStatus, uint32_t *ui32IntrInStatus, uint32_t *ui32IntrOutStatus)
1997 {
1998     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
1999 
2000 #ifndef AM_HAL_DISABLE_API_VALIDATION
2001     if (!AM_HAL_USB_CHK_HANDLE(pHandle))
2002     {
2003         return AM_HAL_STATUS_INVALID_HANDLE;
2004     }
2005 #endif
2006     USB_Type *pUSB = USBn(pState->ui32Module);
2007    *ui32IntrUsbStatus = INTRUSB_Get(pUSB);
2008    *ui32IntrInStatus  = INTRIN_Get(pUSB);
2009    *ui32IntrOutStatus = INTROUT_Get(pUSB);
2010 
2011    return AM_HAL_STATUS_SUCCESS;
2012 }
2013 
2014 //*****************************************************************************
2015 //
2016 // enable the IN endpoints' interrupt
2017 //
2018 //*****************************************************************************
2019 uint32_t
am_hal_usb_intr_ep_in_enable(void * pHandle,uint32_t ui32IntMask)2020 am_hal_usb_intr_ep_in_enable(void *pHandle, uint32_t ui32IntMask)
2021 {
2022     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
2023 
2024 #ifndef AM_HAL_DISABLE_API_VALIDATION
2025     if (!AM_HAL_USB_CHK_HANDLE(pHandle))
2026     {
2027         return AM_HAL_STATUS_INVALID_HANDLE;
2028     }
2029     if (AM_HAL_USB_CHK_EP(ui32IntMask))
2030     {
2031         return AM_HAL_STATUS_INVALID_ARG;
2032     }
2033 #endif
2034     USB_Type *pUSB = USBn(pState->ui32Module);
2035     INTRINE_Enable(pUSB, ui32IntMask);
2036 
2037     return AM_HAL_STATUS_SUCCESS;
2038 }
2039 
2040 //*****************************************************************************
2041 //
2042 // disable the IN endpoints' interrupt
2043 //
2044 //*****************************************************************************
2045 uint32_t
am_hal_usb_intr_ep_in_disable(void * pHandle,uint32_t ui32IntMask)2046 am_hal_usb_intr_ep_in_disable(void *pHandle, uint32_t ui32IntMask)
2047 {
2048     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
2049 
2050 #ifndef AM_HAL_DISABLE_API_VALIDATION
2051     if (!AM_HAL_USB_CHK_HANDLE(pHandle))
2052     {
2053         return AM_HAL_STATUS_INVALID_HANDLE;
2054     }
2055     if (AM_HAL_USB_CHK_EP(ui32IntMask))
2056     {
2057         return AM_HAL_STATUS_INVALID_ARG;
2058     }
2059 #endif
2060     USB_Type *pUSB = USBn(pState->ui32Module);
2061 
2062     INTRINE_Disable(pUSB, ui32IntMask);
2063 
2064     return AM_HAL_STATUS_SUCCESS;
2065 }
2066 
2067 //*****************************************************************************
2068 //
2069 // clear the IN endpoints' interrupt status
2070 //
2071 //*****************************************************************************
2072 uint32_t
am_hal_usb_intr_ep_in_clear(void * pHandle)2073 am_hal_usb_intr_ep_in_clear(void *pHandle)
2074 {
2075     volatile uint32_t tmp = 0;
2076     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
2077     USB_Type *pUSB = USBn(pState->ui32Module);
2078 
2079 #ifndef AM_HAL_DISABLE_API_VALIDATION
2080     if (!AM_HAL_USB_CHK_HANDLE(pHandle))
2081     {
2082         return AM_HAL_STATUS_INVALID_HANDLE;
2083     }
2084 #endif
2085 
2086     tmp = INTRIN_Clear(pUSB);
2087     (void)tmp;
2088 
2089     return AM_HAL_STATUS_SUCCESS;
2090 }
2091 
2092 //*****************************************************************************
2093 //
2094 //! get the IN endpoints' interrupt status
2095 //
2096 //*****************************************************************************
2097 uint32_t
am_hal_usb_intr_ep_in_status_get(void * pHandle,uint32_t * pui32IntStatus,bool bEnabledOnly)2098 am_hal_usb_intr_ep_in_status_get(void *pHandle, uint32_t *pui32IntStatus, bool bEnabledOnly)
2099 {
2100     uint32_t ui32IntStatus = 0;
2101     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
2102     USB_Type *pUSB = USBn(pState->ui32Module);
2103 
2104 #ifndef AM_HAL_DISABLE_API_VALIDATION
2105    if (!AM_HAL_USB_CHK_HANDLE(pHandle))
2106     {
2107        return AM_HAL_STATUS_INVALID_HANDLE;
2108     }
2109 #endif
2110 
2111     ui32IntStatus = INTRIN_Get(pUSB);
2112 
2113     if (bEnabledOnly)
2114     {
2115         ui32IntStatus &= INTRINE_Get(pUSB);
2116     }
2117 
2118     *pui32IntStatus = ui32IntStatus;
2119 
2120    return AM_HAL_STATUS_SUCCESS;
2121 }
2122 
2123 //*****************************************************************************
2124 //
2125 // enable the OUT endpoints' interrupt
2126 //
2127 //*****************************************************************************
2128 uint32_t
am_hal_usb_intr_ep_out_enable(void * pHandle,uint32_t ui32IntMask)2129 am_hal_usb_intr_ep_out_enable(void *pHandle, uint32_t ui32IntMask)
2130 {
2131     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
2132     USB_Type *pUSB = USBn(pState->ui32Module);
2133 
2134 #ifndef AM_HAL_DISABLE_API_VALIDATION
2135     if (!AM_HAL_USB_CHK_HANDLE(pHandle))
2136     {
2137         return AM_HAL_STATUS_INVALID_HANDLE;
2138     }
2139     if (AM_HAL_USB_CHK_EP(ui32IntMask))
2140     {
2141         return AM_HAL_STATUS_INVALID_ARG;
2142     }
2143 #endif
2144 
2145     INTROUTE_Enable(pUSB, ui32IntMask);
2146 
2147     return AM_HAL_STATUS_SUCCESS;
2148 }
2149 
2150 //*****************************************************************************
2151 //
2152 // disable the endpoints' interrupt
2153 //
2154 //*****************************************************************************
2155 uint32_t
am_hal_usb_intr_ep_out_disable(void * pHandle,uint32_t ui32IntMask)2156 am_hal_usb_intr_ep_out_disable(void *pHandle, uint32_t ui32IntMask)
2157 {
2158     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
2159     USB_Type *pUSB = USBn(pState->ui32Module);
2160 
2161 #ifndef AM_HAL_DISABLE_API_VALIDATION
2162     if (!AM_HAL_USB_CHK_HANDLE(pHandle))
2163     {
2164         return AM_HAL_STATUS_INVALID_HANDLE;
2165     }
2166     if (AM_HAL_USB_CHK_EP(ui32IntMask))
2167     {
2168         return AM_HAL_STATUS_INVALID_ARG;
2169     }
2170 #endif
2171 
2172     INTROUTE_Disable(pUSB, ui32IntMask);
2173 
2174     return AM_HAL_STATUS_SUCCESS;
2175 }
2176 
2177 //*****************************************************************************
2178 //
2179 // clear the OUT endpoints' interrupt status
2180 //
2181 //*****************************************************************************
2182 uint32_t
am_hal_usb_intr_ep_out_clear(void * pHandle)2183 am_hal_usb_intr_ep_out_clear(void *pHandle)
2184 {
2185     volatile uint32_t tmp = 0;
2186     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
2187     USB_Type *pUSB = USBn(pState->ui32Module);
2188 
2189 #ifndef AM_HAL_DISABLE_API_VALIDATION
2190     if (!AM_HAL_USB_CHK_HANDLE(pHandle))
2191     {
2192         return AM_HAL_STATUS_INVALID_HANDLE;
2193     }
2194 #endif
2195 
2196     tmp = INTROUT_Clear(pUSB);
2197     (void)tmp;
2198 
2199     return AM_HAL_STATUS_SUCCESS;
2200 }
2201 
2202 //*****************************************************************************
2203 //
2204 // get the OUT endpoints' interrupt status
2205 //
2206 //*****************************************************************************
2207 uint32_t
am_hal_usb_intr_ep_out_status_get(void * pHandle,uint32_t * pui32IntStatus,bool bEnabledOnly)2208 am_hal_usb_intr_ep_out_status_get(void *pHandle, uint32_t *pui32IntStatus, bool bEnabledOnly)
2209 {
2210     uint32_t ui32IntStatus = 0;
2211     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
2212     USB_Type *pUSB = USBn(pState->ui32Module);
2213 
2214 #ifndef AM_HAL_DISABLE_API_VALIDATION
2215     if (!AM_HAL_USB_CHK_HANDLE(pHandle))
2216     {
2217         return AM_HAL_STATUS_INVALID_HANDLE;
2218     }
2219 #endif
2220 
2221     ui32IntStatus = INTROUT_Get(pUSB);
2222 
2223     if (bEnabledOnly)
2224     {
2225         ui32IntStatus &= INTROUTE_Get(pUSB);
2226     }
2227 
2228     *pui32IntStatus = ui32IntStatus;
2229 
2230     return AM_HAL_STATUS_SUCCESS;
2231 }
2232 
2233 //*****************************************************************************
2234 //
2235 // enable the USB bus's interrupts
2236 //
2237 //*****************************************************************************
2238 uint32_t
am_hal_usb_intr_usb_enable(void * pHandle,uint32_t ui32IntMask)2239 am_hal_usb_intr_usb_enable(void *pHandle, uint32_t ui32IntMask)
2240 {
2241     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
2242     USB_Type *pUSB = USBn(pState->ui32Module);
2243 
2244 #ifndef AM_HAL_DISABLE_API_VALIDATION
2245     if (!AM_HAL_USB_CHK_HANDLE(pHandle))
2246     {
2247         return AM_HAL_STATUS_INVALID_HANDLE;
2248     }
2249     if (AM_HAL_USB_CHK_USB(ui32IntMask))
2250     {
2251         return AM_HAL_STATUS_INVALID_ARG;
2252     }
2253 #endif
2254 
2255     INTRUSBE_Enable(pUSB, ui32IntMask);
2256 
2257     return AM_HAL_STATUS_SUCCESS;
2258 }
2259 
2260 //*****************************************************************************
2261 //
2262 // disable the USB bus's interrupts
2263 //
2264 //*****************************************************************************
2265 uint32_t
am_hal_usb_intr_usb_disable(void * pHandle,uint32_t ui32IntMask)2266 am_hal_usb_intr_usb_disable(void *pHandle, uint32_t ui32IntMask)
2267 {
2268     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
2269     USB_Type *pUSB = USBn(pState->ui32Module);
2270 
2271 #ifndef AM_HAL_DISABLE_API_VALIDATION
2272     if (!AM_HAL_USB_CHK_HANDLE(pHandle))
2273     {
2274         return AM_HAL_STATUS_INVALID_HANDLE;
2275     }
2276     if (AM_HAL_USB_CHK_USB(ui32IntMask))
2277     {
2278         return AM_HAL_STATUS_INVALID_ARG;
2279     }
2280 #endif
2281 
2282     INTRUSBE_Disable(pUSB, ui32IntMask);
2283 
2284     return AM_HAL_STATUS_SUCCESS;
2285 }
2286 
2287 //*****************************************************************************
2288 //
2289 // clear the USB bus interrupts
2290 //
2291 //*****************************************************************************
2292 uint32_t
am_hal_usb_intr_usb_clear(void * pHandle)2293 am_hal_usb_intr_usb_clear(void *pHandle)
2294 {
2295     volatile uint32_t tmp = 0;
2296     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
2297     USB_Type *pUSB = USBn(pState->ui32Module);
2298 
2299 #ifndef AM_HAL_DISABLE_API_VALIDATION
2300     if (!AM_HAL_USB_CHK_HANDLE(pHandle))
2301     {
2302         return AM_HAL_STATUS_INVALID_HANDLE;
2303     }
2304 #endif
2305 
2306     tmp = INTRUSB_Clear(pUSB);
2307     (void)tmp;
2308 
2309     return AM_HAL_STATUS_SUCCESS;
2310 }
2311 
2312 //*****************************************************************************
2313 //
2314 // get the USB bus interrupt status
2315 //
2316 //*****************************************************************************
2317 uint32_t
am_hal_usb_intr_usb_status_get(void * pHandle,uint32_t * pui32IntStatus,bool bEnabledOnly)2318 am_hal_usb_intr_usb_status_get(void *pHandle, uint32_t *pui32IntStatus, bool bEnabledOnly)
2319 {
2320     uint32_t ui32IntStatus = 0;
2321     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
2322     USB_Type *pUSB = USBn(pState->ui32Module);
2323 
2324 #ifndef AM_HAL_DISABLE_API_VALIDATION
2325     if (!AM_HAL_USB_CHK_HANDLE(pHandle))
2326     {
2327         return AM_HAL_STATUS_INVALID_HANDLE;
2328     }
2329 #endif
2330 
2331     ui32IntStatus = INTRUSB_Get(pUSB);
2332 
2333     if (bEnabledOnly)
2334     {
2335         ui32IntStatus &= INTRUSBE_Get(pUSB);
2336     }
2337 
2338     *pui32IntStatus = ui32IntStatus;
2339 
2340     return AM_HAL_STATUS_SUCCESS;
2341 }
2342 
2343 //*****************************************************************************
2344 //
2345 // register a USB bus event callback function
2346 //
2347 //*****************************************************************************
2348 uint32_t
am_hal_usb_register_dev_evt_callback(void * pHandle,const am_hal_usb_dev_evt_callback cb)2349 am_hal_usb_register_dev_evt_callback(void *pHandle, const am_hal_usb_dev_evt_callback cb)
2350 {
2351     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
2352 
2353 #ifndef AM_HAL_DISABLE_API_VALIDATION
2354     if (!AM_HAL_USB_CHK_HANDLE(pHandle))
2355     {
2356         return AM_HAL_STATUS_INVALID_HANDLE;
2357     }
2358 #endif
2359 
2360     if (cb != NULL)
2361     {
2362         pState->dev_evt_callback = cb;
2363     }
2364     else
2365     {
2366         return AM_HAL_STATUS_INVALID_ARG;
2367     }
2368 
2369     return AM_HAL_STATUS_SUCCESS;
2370 }
2371 
2372 //*****************************************************************************
2373 //
2374 // register a setup requst callback function
2375 //
2376 //*****************************************************************************
2377 uint32_t
am_hal_usb_register_ep0_setup_received_callback(void * pHandle,const am_hal_usb_ep0_setup_received_callback cb)2378 am_hal_usb_register_ep0_setup_received_callback(void *pHandle, const am_hal_usb_ep0_setup_received_callback cb)
2379 {
2380     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
2381 
2382 #ifndef AM_HAL_DISABLE_API_VALIDATION
2383     if (!AM_HAL_USB_CHK_HANDLE(pHandle))
2384     {
2385         return AM_HAL_STATUS_INVALID_HANDLE;
2386     }
2387 #endif
2388 
2389     if (cb != NULL)
2390     {
2391         pState->ep0_setup_callback = cb;
2392     }
2393     else
2394     {
2395         return AM_HAL_STATUS_INVALID_ARG;
2396     }
2397 
2398     return AM_HAL_STATUS_SUCCESS;
2399 }
2400 
2401 //*****************************************************************************
2402 //
2403 // register a transfer completion callback function
2404 //
2405 //*****************************************************************************
2406 uint32_t
am_hal_usb_register_ep_xfer_complete_callback(void * pHandle,const am_hal_usb_ep_xfer_complete_callback cb)2407 am_hal_usb_register_ep_xfer_complete_callback(void *pHandle, const am_hal_usb_ep_xfer_complete_callback cb)
2408 {
2409     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
2410 
2411 #ifndef AM_HAL_DISABLE_API_VALIDATION
2412     if (!AM_HAL_USB_CHK_HANDLE(pHandle))
2413     {
2414         return AM_HAL_STATUS_INVALID_HANDLE;
2415     }
2416 #endif
2417 
2418     if (cb != NULL)
2419     {
2420         pState->ep_xfer_complete_callback = cb;
2421     }
2422     else
2423     {
2424         return AM_HAL_STATUS_INVALID_ARG;
2425     }
2426 
2427     return AM_HAL_STATUS_SUCCESS;
2428 }
2429 
2430 //*****************************************************************************
2431 //
2432 // Send setup request to upper layer
2433 //
2434 //*****************************************************************************
2435 static void
am_hal_usb_ep0_handle_setup_req(am_hal_usb_state_t * pState,USB_Type * pUSB)2436 am_hal_usb_ep0_handle_setup_req(am_hal_usb_state_t *pState, USB_Type *pUSB)
2437 {
2438     uint8_t setup_req[8];
2439 
2440     if (CSR0_OutPktRdy(pUSB))
2441     {
2442         uint16_t count0 = COUNT0(pUSB);
2443         am_hal_usb_fifo_unloading(pUSB, AM_HAL_USB_EP0_NUMBER, setup_req, count0);
2444         pState->eEP0State = AM_HAL_USB_EP0_STATE_SETUP;
2445 
2446         //
2447         // Let the upper layer USB device stack to handle this request
2448         //
2449         pState->ep0_setup_callback(setup_req);
2450     }
2451 }
2452 
2453 //*****************************************************************************
2454 //
2455 // Endpoint 0 Handling
2456 //
2457 //*****************************************************************************
2458 static void
am_hal_usb_ep0_handling(am_hal_usb_state_t * pState,USB_Type * pUSB)2459 am_hal_usb_ep0_handling(am_hal_usb_state_t *pState, USB_Type *pUSB)
2460 {
2461     uint8_t *buf;
2462     uint16_t index, remaining, maxpacket, count0;
2463 
2464     // Select the EP0
2465     EP_INDEX_Set(pUSB, AM_HAL_USB_EP0_NUMBER);
2466 
2467     maxpacket = pState->ep0_maxpacket;
2468 
2469     switch ( pState->eEP0State )
2470     {
2471         case AM_HAL_USB_EP0_STATE_IDLE:
2472             // process the setup request
2473             am_hal_usb_ep0_handle_setup_req(pState, pUSB);
2474             break;
2475 
2476         case AM_HAL_USB_EP0_STATE_SETUP:
2477             // This case is for unsupported setup requests
2478             if (CSR0_SentStall(pUSB))
2479             {
2480                 CSR0_SentStall_Clear(pUSB);
2481                 // Return to the IDLE state, may clear the SendStall bit when
2482                 // USB host clear the stall
2483                 am_hal_usb_ep0_state_reset(pState);
2484                 am_hal_usb_xfer_reset(&pState->ep0_xfer);
2485             }
2486             break;
2487 
2488         case AM_HAL_USB_EP0_STATE_DATA_RX:
2489             remaining = pState->ep0_xfer.remaining;
2490             buf       = pState->ep0_xfer.buf;
2491             index     = pState->ep0_xfer.len - remaining;
2492 
2493             // 7.6 error handling
2494             // how to handle Setup End error
2495             if (CSR0_SetupEnd(pUSB))
2496             {
2497                 CSR0_ServicedSetupEnd_Set(pUSB);
2498                 if (!CSR0_OutPktRdy(pUSB))
2499                 {
2500                     am_hal_usb_xfer_complete(pState, &pState->ep0_xfer, 0x0, pState->ep0_xfer.len - pState->ep0_xfer.remaining, USB_XFER_ERROR, NULL);
2501                     am_hal_usb_ep0_state_reset(pState);
2502                 }
2503                 return;
2504             }
2505 
2506             // 7.6 error handling
2507             // 3. The host sends more than MaxP data bytes in an OUT data packet
2508             if (CSR0_SentStall(pUSB))
2509             {
2510                 // Clear the SentStall bit
2511                 CSR0_SentStall_Clear(pUSB);
2512                 return;
2513             }
2514 
2515             // Write requests handling, in fact no such request is used
2516             // in TinyUSB, like TUSB_REQ_SET_DESCRIPTOR
2517             if (CSR0_OutPktRdy(pUSB))
2518             {
2519                 count0 = COUNT0(pUSB);
2520                 pState->ep0_xfer.remaining -= count0;
2521                 // Unload the FIFO data
2522                 am_hal_usb_fifo_unloading(pUSB, 0x0, pState->ep0_xfer.buf + index, count0);
2523 
2524                 if (count0 < maxpacket)
2525                 {
2526                     pState->eEP0State = AM_HAL_USB_EP0_STATE_STATUS_RX;
2527                     CSR0_ServicedOutPktRdyAndDataEnd_Set(pUSB);
2528                 }
2529                 else
2530                 {
2531                     CSR0_ServicedOutPktRdy_Set(pUSB);
2532                 }
2533             }
2534             break;
2535        case AM_HAL_USB_EP0_STATE_DATA_TX:
2536             // Read requests handling
2537             remaining = pState->ep0_xfer.remaining;
2538             buf       = pState->ep0_xfer.buf;
2539             index     = pState->ep0_xfer.len - remaining;
2540 
2541             if (CSR0_SetupEnd(pUSB))
2542             {
2543                 CSR0_ServicedSetupEnd_Set(pUSB);
2544                 am_hal_usb_xfer_complete(pState, &pState->ep0_xfer, 0x0 | AM_HAL_USB_EP_DIR_IN_MASK, pState->ep0_xfer.len - pState->ep0_xfer.remaining, USB_XFER_ERROR, NULL);
2545                 am_hal_usb_ep0_state_reset(pState);
2546                 return;
2547             }
2548 
2549             // see page 62
2550             if (CSR0_SentStall(pUSB))
2551             {
2552                 // Clear the SentStall bit
2553                 CSR0_SentStall_Clear(pUSB);
2554                 return;
2555             }
2556 
2557             if (CSR0_InPktRdy(pUSB) == 0x0) //In data packet FIFO is empty
2558             {
2559                 if (remaining <= maxpacket)
2560                 {
2561                     am_hal_usb_fifo_loading(pUSB, 0x0, buf + index, remaining);
2562                     pState->ep0_xfer.remaining = 0;
2563                     pState->eEP0State = AM_HAL_USB_EP0_STATE_STATUS_TX;
2564 
2565                     CSR0_InPktRdyAndDataEnd_Set(pUSB);
2566                 }
2567                 else
2568                 {
2569                     pState->ep0_xfer.remaining -= maxpacket;
2570                     am_hal_usb_fifo_loading(pUSB, 0x0, buf + index, maxpacket);
2571                     CSR0_InPktRdy_Set(pUSB);
2572                 }
2573             }
2574 
2575             break;
2576         case AM_HAL_USB_EP0_STATE_STATUS_RX:
2577             // See 7.6 error handling
2578             // 1. The host sends more data during the OUT Data phase of a write request than was specified in the command.
2579             //    This condition is detected when the host sends an OUT token after the DataEnd bit (CSR0.D3) has been set.
2580             // 4. The host sends a non-zero length DATA1 packet during the STATUS phase of a read request.
2581             if (CSR0_SentStall(pUSB))
2582             {
2583                 // Clear the SentStall bit
2584                 CSR0_SentStall_Clear(pUSB);
2585                 // Notify the upper layer USB stack to handle it
2586                 am_hal_usb_xfer_complete(pState, &pState->ep0_xfer, 0x0, pState->ep0_xfer.len - pState->ep0_xfer.remaining, USB_XFER_STALL, NULL);
2587             }
2588             else
2589             {
2590                 am_hal_usb_xfer_complete(pState, &pState->ep0_xfer, 0x0, pState->ep0_xfer.len - pState->ep0_xfer.remaining, USB_XFER_DONE, NULL);
2591             }
2592             am_hal_usb_ep0_state_reset(pState);
2593 
2594             //
2595             // check if a new next setup request is coming
2596             //
2597             am_hal_usb_ep0_handle_setup_req(pState, pUSB);
2598             break;
2599 
2600         case AM_HAL_USB_EP0_STATE_STATUS_TX:
2601             // See 7.6 error handling SendStall
2602             // 2. The host request more data during the IN Data phase of a read request than was specified in the command.
2603             // This condition is detected when the host sends an IN token after the DataEnd bit in the CSR0 register has been set.
2604             if (CSR0_SentStall(pUSB))
2605             {
2606                 // Clear the SentStall bit
2607                 CSR0_SentStall_Clear(pUSB);
2608                 // Notify the upper layer USB stack to handle it
2609                 am_hal_usb_xfer_complete(pState, &pState->ep0_xfer, 0x0 | AM_HAL_USB_EP_DIR_IN_MASK, pState->ep0_xfer.len - pState->ep0_xfer.remaining, USB_XFER_STALL, NULL);
2610             }
2611             else
2612             {
2613                 am_hal_usb_xfer_complete(pState, &pState->ep0_xfer, 0x0 | AM_HAL_USB_EP_DIR_IN_MASK, pState->ep0_xfer.len - pState->ep0_xfer.remaining, USB_XFER_DONE, NULL);
2614             }
2615             am_hal_usb_ep0_state_reset(pState);
2616 
2617             //
2618             // check if a new setup request is coming
2619             //
2620             am_hal_usb_ep0_handle_setup_req(pState, pUSB);
2621             break;
2622 
2623         default:
2624             // Never come here
2625             break;
2626     }
2627 }
2628 
2629 //*****************************************************************************
2630 //
2631 // Bulk In endpoint error handling
2632 //
2633 //*****************************************************************************
2634 static void
am_hal_usb_in_ep_handling(am_hal_usb_state_t * pState,USB_Type * pUSB,uint8_t ui8EpNum)2635 am_hal_usb_in_ep_handling(am_hal_usb_state_t *pState, USB_Type *pUSB, uint8_t ui8EpNum)
2636 {
2637     am_hal_usb_ep_xfer_t *pXfer;
2638     uint32_t maxpacket;
2639 
2640     pXfer = &pState->ep_xfers[ui8EpNum - 1][AM_HAL_USB_EP_DIR_IN];
2641     maxpacket = pState->epin_maxpackets[ui8EpNum - 1];
2642 
2643     EP_INDEX_Set(pUSB, ui8EpNum);
2644 
2645     // Note: automatic bulk packet splitting option is not enabled
2646 
2647     // 8.1.3 Bulk In endpoint error handling
2648     if (INCSRL_SentStall(pUSB))
2649     {
2650         // Just clear the SentStall bit
2651         // leave the SendStall bit set
2652         INCSRL_SentStall_Clear(pUSB);
2653         return;
2654     }
2655 
2656     // In endpoint FIFO is empty
2657     if (INCSRL_InPktRdy(pUSB) == 0x0)
2658     {
2659         // Packet has been sent out
2660         if (pXfer->remaining == 0x0)
2661         {
2662 #ifdef AM_HAL_USB_FEATURE_ZERO_LENGTH_PACKET
2663             // If zero packet is needed
2664             if (pXfer->flags.zlp)
2665             {
2666                 INCSRL_InPktRdy_Set(pUSB);
2667             }
2668 #endif
2669             INTRINE_Disable(pUSB, 0x1 << ui8EpNum);
2670             am_hal_usb_xfer_complete(pState, pXfer, ui8EpNum | AM_HAL_USB_EP_DIR_IN_MASK, pXfer->len, USB_XFER_DONE, NULL);
2671             return;
2672         }
2673 
2674         uint16_t min = pXfer->remaining < maxpacket ? pXfer->remaining : maxpacket;
2675         am_hal_usb_fifo_loading(pUSB, ui8EpNum, pXfer->buf + pXfer->len - pXfer->remaining, min);
2676         INCSRL_InPktRdy_Set(pUSB);
2677 
2678         pXfer->remaining -= min;
2679 
2680         if (pXfer->remaining == 0x0 && min == maxpacket)
2681         {
2682             pXfer->flags.zlp = 1;
2683         }
2684 
2685         return;
2686     }
2687 }
2688 
2689 //*****************************************************************************
2690 //
2691 // Bulk Out endpoint error handling
2692 //
2693 //*****************************************************************************
2694 static void
am_hal_usb_out_ep_handling(am_hal_usb_state_t * pState,USB_Type * pUSB,uint8_t ui8EpNum)2695 am_hal_usb_out_ep_handling(am_hal_usb_state_t *pState, USB_Type *pUSB, uint8_t ui8EpNum)
2696 {
2697     uint16_t count;
2698     uint16_t maxpacket;
2699     am_hal_usb_ep_xfer_t *pXfer;
2700 
2701     pXfer = &pState->ep_xfers[ui8EpNum - 1][AM_HAL_USB_EP_DIR_OUT];
2702 
2703     EP_INDEX_Set(pUSB, ui8EpNum);
2704 
2705     // 8.2.3 Bulk Out endpoint error handling
2706     if (OUTCSRL_SentStall(pUSB))
2707     {
2708         // Just clear the SentStall bit
2709         // leave the SendStall bit set
2710         OUTCSRL_SentStall_Clear(pUSB);
2711         return;
2712     }
2713 
2714     if (OUTCSRL_OutPktRdy(pUSB))
2715     {
2716         count = OUTCOUNT(pUSB);
2717         maxpacket = pState->epout_maxpackets[ui8EpNum - 1];
2718 
2719         if (pXfer->remaining < count)
2720         {
2721             am_hal_usb_fifo_unloading(pUSB, ui8EpNum, pXfer->buf + pXfer->len - pXfer->remaining, pXfer->remaining);
2722             pXfer->remaining = 0;
2723         }
2724         else
2725         {
2726             // Buffer is enough to receive it
2727             am_hal_usb_fifo_unloading(pUSB, ui8EpNum, pXfer->buf + pXfer->len - pXfer->remaining, count);
2728             pXfer->remaining -= count;
2729         }
2730 
2731         if (pXfer->remaining == 0x0 || count < maxpacket)
2732         {
2733             INTROUTE_Disable(pUSB, 0x1 << ui8EpNum);
2734             am_hal_usb_xfer_complete(pState, pXfer, ui8EpNum, pXfer->len - pXfer->remaining, USB_XFER_DONE, NULL);
2735             return;
2736         }
2737 #ifdef AM_HAL_USB_FEATURE_EP_READ_TIMEOUT
2738         else
2739         {
2740             if (pXfer->xfer_started == false)
2741             {
2742                 pXfer->xfer_started = true;
2743                 pXfer->timeout--;
2744             }
2745             else
2746             {
2747                 // Reset the timeout
2748                 pXfer->timeout = AM_HAL_USB_TIMEOUT;
2749             }
2750         }
2751 #endif
2752         OUTCSRL_OutPktRdy_Clear(pUSB);
2753     }
2754 }
2755 
2756 //*****************************************************************************
2757 //
2758 // USB interrupt service routine
2759 //
2760 //*****************************************************************************
2761 void
am_hal_usb_interrupt_service(void * pHandle,uint32_t ui32IntrUsbStatus,uint32_t ui32IntrInStatus,uint32_t ui32IntrOutStatus)2762 am_hal_usb_interrupt_service(void *pHandle,
2763                              uint32_t ui32IntrUsbStatus,
2764                              uint32_t ui32IntrInStatus,
2765                              uint32_t ui32IntrOutStatus)
2766 {
2767     uint8_t i;
2768     am_hal_usb_state_t *pState = (am_hal_usb_state_t *)pHandle;
2769 
2770 #ifndef AM_HAL_DISABLE_API_VALIDATION
2771     if (!AM_HAL_USB_CHK_HANDLE(pHandle))
2772     {
2773         return;
2774     }
2775 #endif
2776 
2777     USB_Type *pUSB = USBn(pState->ui32Module);
2778 
2779     // Handling the resume interrupt
2780     if (ui32IntrUsbStatus & USB_INTRUSB_Resume_Msk)
2781     {
2782         //
2783         // Turning XCVRs on
2784         //
2785         USBPHY->REG10 |= 0x2;
2786 
2787         // Back to active state
2788         pState->eDevState = AM_HAL_USB_DEV_STATE_RESUMING;
2789         if (pState->dev_evt_callback)
2790         {
2791             pState->dev_evt_callback(AM_HAL_USB_DEV_EVT_RESUME);
2792         }
2793     }
2794 
2795     // Handling the reset interrupt
2796     if (ui32IntrUsbStatus & USB_INTRUSB_Reset_Msk)
2797     {
2798         // Back to the init state
2799         pState->eDevState = AM_HAL_USB_DEV_STATE_INIT;
2800         am_hal_usb_ep_xfer_t *pXfer = &pState->ep0_xfer;
2801         if (pXfer->flags.busy == 0x1)
2802         {
2803             // Notify the upper layer, ep0 transfer is aborted
2804             am_hal_usb_xfer_complete(pState, pXfer, am_hal_usb_ep_addr(0x0, pXfer->flags.dir), pXfer->len - pXfer->remaining, USB_XFER_ABORT, NULL);
2805         }
2806         am_hal_usb_ep0_state_reset(pState);
2807 
2808         for (int i = 0; i < AM_HAL_USB_EP_MAX_NUMBER; i++)
2809         {
2810             for (int j = 0; j < 2; j++)
2811             {
2812                 pXfer = &pState->ep_xfers[i][j];
2813                 // Notify the upper layer, endpoint transfer is aborted
2814                 if (pXfer->flags.busy)
2815                 {
2816                     am_hal_usb_xfer_complete(pState, pXfer, am_hal_usb_ep_addr(i + 1, j), pXfer->len - pXfer->remaining, USB_XFER_ABORT, NULL);
2817                 }
2818             }
2819         }
2820         memset((void *)&pState->ep_xfers, 0x0, sizeof(pState->ep_xfers));
2821 
2822         // Reset the ep fifo allocation
2823         am_hal_usb_ep_fifo_reset(&pState->ui32Allocated);
2824 
2825         // Disable all IN/OUT EP interrupts when USB is reset
2826         // when receiving the set configuration request
2827         // enable the related EP interrupts
2828         INTRINE_Disable(pUSB, AM_HAL_USB_EP_MASK);
2829         INTROUTE_Disable(pUSB, AM_HAL_USB_EP_MASK);
2830 
2831         // Disable the SOF interrupt
2832         // enable it only when upper layer stack need it
2833 #ifdef AM_HAL_USB_FEATURE_EP_READ_TIMEOUT
2834         INTRUSBE_SOF_Enable(pUSB);
2835 #else
2836         INTRUSBE_SOF_Disable(pUSB);
2837 #endif
2838 
2839         //
2840         // Always enable the SuspendM
2841         //
2842         INTRUSBE_Suspend_Enable(pUSB);
2843 
2844         if (pState->dev_evt_callback)
2845         {
2846             pState->dev_evt_callback(AM_HAL_USB_DEV_EVT_BUS_RESET);
2847         }
2848     }
2849 
2850     // Handling the SOF interrupt
2851     if (ui32IntrUsbStatus & USB_INTRUSB_SOF_Msk)
2852     {
2853         // Notify the SOF event
2854 #ifdef AM_HAL_USB_FEATURE_EP_READ_TIMEOUT
2855         for (int i = 0; i < AM_HAL_USB_EP_MAX_NUMBER; i++)
2856         {
2857             am_hal_usb_ep_xfer_t *pXfer = &pState->ep_xfers[i][0];
2858             // Notify the upper layer, endpoint transfer is aborted
2859             if (pXfer->timeout == 0x0 && pXfer->flags.busy)
2860             {
2861                 INTROUTE_Disable(pUSB, 0x1 << i);
2862                 am_hal_usb_xfer_complete(pState, pXfer, am_hal_usb_ep_addr(i + 1, 0), pXfer->len - pXfer->remaining, USB_XFER_ABORT, NULL);
2863             }
2864             else
2865             {
2866                 if (pXfer->xfer_started)
2867                 {
2868                     pXfer->timeout--;
2869                 }
2870             }
2871         }
2872 #endif
2873         if (pState->dev_evt_callback)
2874         {
2875             pState->dev_evt_callback(AM_HAL_USB_DEV_EVT_SOF);
2876         }
2877     }
2878 
2879     // Handling the EP0 interrupt
2880     if (ui32IntrInStatus & USB_INTRIN_EP0_Msk)
2881     {
2882         am_hal_usb_ep0_handling(pState, pUSB);
2883     }
2884 
2885     // Handling IN Endpoint one by one
2886     for (i = AM_HAL_USB_EP1_NUMBER; i <= AM_HAL_USB_EP_MAX_NUMBER; i++)
2887     {
2888         if (ui32IntrInStatus & (0x1 << i))
2889         {
2890             am_hal_usb_in_ep_handling(pState, pUSB, i);
2891         }
2892     }
2893 
2894     // Handling OUT Endpoint one by one
2895     for (i = AM_HAL_USB_EP1_NUMBER; i <= AM_HAL_USB_EP_MAX_NUMBER; i++)
2896     {
2897         if (ui32IntrOutStatus & (0x1 << i))
2898         {
2899             am_hal_usb_out_ep_handling(pState, pUSB, i);
2900         }
2901     }
2902 
2903     // Handing the suspend interrupt finally
2904     if (ui32IntrUsbStatus & USB_INTRUSB_Suspend_Msk)
2905     {
2906         //
2907         // Turning XCVRs off for more power saving
2908         //
2909         USBPHY->REG10 &= 0xFD;
2910 
2911         pState->eDevState = AM_HAL_USB_DEV_STATE_SUSPENDING;
2912         if (pState->dev_evt_callback)
2913         {
2914             pState->dev_evt_callback(AM_HAL_USB_DEV_EVT_SUSPEND);
2915         }
2916     }
2917 
2918     return;
2919 }
2920 //*****************************************************************************
2921 //
2922 // Apply various specific commands / controls to the USB module
2923 //
2924 //*****************************************************************************
2925 uint32_t
am_hal_usb_control(am_hal_usb_control_e eControl,void * pArgs)2926 am_hal_usb_control(am_hal_usb_control_e eControl, void *pArgs)
2927 {
2928     uint32_t ui32RetVal = AM_HAL_STATUS_SUCCESS;
2929 
2930     switch (eControl)
2931     {
2932         case AM_HAL_CLKGEN_CONTROL_SET_XTAL_FREQ:
2933             //
2934             // this is used when the xtal is not 32mhz and
2935             // high speed mode is needed
2936             // this is only needed when using HFRC2 adjust and the 32Mhz clock
2937             //
2938 
2939             if (!pArgs)
2940             {
2941                 ui32RetVal = AM_HAL_STATUS_INVALID_ARG;
2942                 break;
2943             }
2944             g_ui32XtalFreq = *((uint32_t *) pArgs);
2945             break;
2946 
2947         case AM_HAL_CLKGEN_CONTROL_SET_HFRC2_TYPE:
2948             ui32RetVal =  am_hal_usb_setHFRC2( *((am_hal_usb_hs_clock_type *) pArgs)) ;
2949 			break ;
2950 
2951         default:
2952             ui32RetVal = AM_HAL_STATUS_INVALID_ARG;
2953             break;
2954     }
2955 
2956     return ui32RetVal;
2957 }
2958 
2959 //*****************************************************************************
2960 //
2961 // USB set HFRC2 FLL for 24 Mhz usb input
2962 //
2963 //*****************************************************************************
2964 uint32_t
am_hal_usb_setHFRC2(am_hal_usb_hs_clock_type tUsbHsClockType)2965 am_hal_usb_setHFRC2(am_hal_usb_hs_clock_type tUsbHsClockType)
2966 {
2967     uint32_t ui32Status = AM_HAL_STATUS_INVALID_ARG;
2968     switch ( tUsbHsClockType )
2969     {
2970         case AM_HAL_USB_HS_CLK_DISABLE:
2971         case AM_HAL_USB_HS_CLK_DISABLE_HFRC2_ADJ:
2972             //
2973             // the clock is going to be disabled
2974             //
2975             ui32Status = am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_HFRC2_STOP, NULL);
2976 
2977             if (AM_HAL_USB_HS_CLK_DISABLE_HFRC2_ADJ == tUsbHsClockType)
2978             {
2979                 //
2980                 // also specifically requested to disable HFRC2 adj
2981                 //
2982                 ui32Status = am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_HF2ADJ_DISABLE, NULL);
2983             }
2984             break ;
2985 
2986         case AM_HAL_USB_HS_CLK_HFRC2_ADJ:
2987         case AM_HAL_USB_HS_CLK_HFRC2_ADJ_EXTERN_CLK:
2988             //
2989             // the HFRC2 clock is going to be enabled
2990             // if here the caller has selected to use HFRC2 adjust, this also requires using the
2991             // internal 32Mhz or an external clock
2992             //
2993             ui32Status = am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_HFRC2_STOP, false);
2994             if (ui32Status != AM_HAL_STATUS_SUCCESS)
2995             {
2996                 break ;
2997             }
2998             {
2999                 am_hal_mcuctrl_control_arg_t ctrlArgs = g_amHalMcuctrlArgDefault;
3000                 ctrlArgs.ui32_arg_hfxtal_user_mask = 1 << AM_HAL_HFXTAL_USB_PHI_EN;
3001                 ctrlArgs.b_arg_apply_ext_source = AM_HAL_USB_HS_CLK_HFRC2_ADJ_EXTERN_CLK == tUsbHsClockType;
3002 
3003                 ui32Status = am_hal_mcuctrl_control(AM_HAL_MCUCTRL_CONTROL_EXTCLK32M_KICK_START, &ctrlArgs);
3004                 if (ui32Status != AM_HAL_STATUS_SUCCESS)
3005                 {
3006                     break;
3007                 }
3008             }
3009 
3010             //
3011             // setup data struct to pass to clock config (control)
3012             //
3013             am_hal_clockgen_hf2adj_compute_t tHfadj_cmp;
3014 
3015             tHfadj_cmp.eHF2AdjType = AM_HAL_CLKGEN_HF2ADJ_COMP_COMP_FREQ;
3016             tHfadj_cmp.ui32Source_freq_in_hz = g_ui32XtalFreq;
3017             tHfadj_cmp.ui32Target_freq_in_hz = 24000000;
3018 
3019             ui32Status = am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_HF2ADJ_COMPUTE, (void *) &tHfadj_cmp);
3020             if (ui32Status != AM_HAL_STATUS_SUCCESS)
3021             {
3022                 break ;
3023             }
3024             ui32Status = am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_HFRC2_START, NULL);
3025             break ;
3026 
3027         case AM_HAL_USB_HS_CLK_HFRC2:
3028             //
3029             // HFRC2 enabled with no adjust FLL, this is the default for HIGH_SPEED USB
3030             //
3031             ui32Status = am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_HFRC2_START, NULL);
3032             break ;
3033 
3034         default:
3035             break ;
3036     }
3037 
3038     return ui32Status;
3039 }
3040 
3041 
3042 //*****************************************************************************
3043 //
3044 // End Doxygen group.
3045 //! @}
3046 //
3047 //*****************************************************************************
3048