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