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