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