00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include "conf_usb_host.h"
00049 #include "board.h"
00050 #include "USBHDriver.h"
00051 #include "USBH.h"
00052
00053 #include <string.h>
00054 #include <stdlib.h>
00055
00056
00057
00058 #ifndef UHD_USB_INT_LEVEL
00059 # define UHD_USB_INT_LEVEL 5 // By default USB interrupt have low priority
00060 #endif
00061
00062 #define USB_HOST_MAX_EP 9
00063 #define UHD_PIPE_USED(pipe) (USB_HOST_MAX_EP >= pipe)
00064
00065 #if ( (UHD_PIPE_USED( 1) && Is_uhd_pipe_dma_supported( 1)) \
00066 ||(UHD_PIPE_USED( 2) && Is_uhd_pipe_dma_supported( 2)) \
00067 ||(UHD_PIPE_USED( 3) && Is_uhd_pipe_dma_supported( 3)) \
00068 ||(UHD_PIPE_USED( 4) && Is_uhd_pipe_dma_supported( 4)) \
00069 ||(UHD_PIPE_USED( 5) && Is_uhd_pipe_dma_supported( 5)) \
00070 ||(UHD_PIPE_USED( 6) && Is_uhd_pipe_dma_supported( 6)) \
00071 ||(UHD_PIPE_USED( 7) && Is_uhd_pipe_dma_supported( 7)) \
00072 ||(UHD_PIPE_USED( 8) && Is_uhd_pipe_dma_supported( 8)) \
00073 ||(UHD_PIPE_USED( 9) && Is_uhd_pipe_dma_supported( 9)) \
00074 ||(UHD_PIPE_USED(10) && Is_uhd_pipe_dma_supported(10)) \
00075 ||(UHD_PIPE_USED(11) && Is_uhd_pipe_dma_supported(11)) \
00076 ||(UHD_PIPE_USED(12) && Is_uhd_pipe_dma_supported(12)) \
00077 ||(UHD_PIPE_USED(13) && Is_uhd_pipe_dma_supported(13)) \
00078 ||(UHD_PIPE_USED(14) && Is_uhd_pipe_dma_supported(14)) \
00079 ||(UHD_PIPE_USED(15) && Is_uhd_pipe_dma_supported(15)) \
00080 )
00081 # define UHD_PIPE_DMA_SUPPORTED
00082 #endif
00083
00084 #if ( (UHD_PIPE_USED( 1) && !Is_uhd_pipe_dma_supported( 1)) \
00085 ||(UHD_PIPE_USED( 2) && !Is_uhd_pipe_dma_supported( 2)) \
00086 ||(UHD_PIPE_USED( 3) && !Is_uhd_pipe_dma_supported( 3)) \
00087 ||(UHD_PIPE_USED( 4) && !Is_uhd_pipe_dma_supported( 4)) \
00088 ||(UHD_PIPE_USED( 5) && !Is_uhd_pipe_dma_supported( 5)) \
00089 ||(UHD_PIPE_USED( 6) && !Is_uhd_pipe_dma_supported( 6)) \
00090 ||(UHD_PIPE_USED( 7) && !Is_uhd_pipe_dma_supported( 7)) \
00091 ||(UHD_PIPE_USED( 8) && !Is_uhd_pipe_dma_supported( 8)) \
00092 ||(UHD_PIPE_USED( 9) && !Is_uhd_pipe_dma_supported( 9)) \
00093 ||(UHD_PIPE_USED(10) && !Is_uhd_pipe_dma_supported(10)) \
00094 ||(UHD_PIPE_USED(11) && !Is_uhd_pipe_dma_supported(11)) \
00095 ||(UHD_PIPE_USED(12) && !Is_uhd_pipe_dma_supported(12)) \
00096 ||(UHD_PIPE_USED(13) && !Is_uhd_pipe_dma_supported(13)) \
00097 ||(UHD_PIPE_USED(14) && !Is_uhd_pipe_dma_supported(14)) \
00098 ||(UHD_PIPE_USED(15) && !Is_uhd_pipe_dma_supported(15)) \
00099 )
00100 # define UHD_PIPE_FIFO_SUPPORTED
00101 #endif
00102
00103
00104
00105
00106 #ifndef UHC_MODE_CHANGE
00107 # define UHC_MODE_CHANGE(arg)
00108 #endif
00109 #ifndef UHC_SOF_EVENT
00110 # define UHC_SOF_EVENT()
00111 #endif
00112 #ifndef UHC_VBUS_CHANGE
00113 # define UHC_VBUS_CHANGE(b_present)
00114 #endif
00115 #ifndef UHC_VBUS_ERROR
00116 # define UHC_VBUS_ERROR()
00117 #endif
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 #ifndef UHD_ISOCHRONOUS_NB_BANK
00163 # define UHD_ISOCHRONOUS_NB_BANK 2
00164 #else
00165 # if (UHD_ISOCHRONOUS_NB_BANK < 1) || (UHD_ISOCHRONOUS_NB_BANK > 2)
00166 # error UHD_ISOCHRONOUS_NB_BANK must be define with 1 or 2.
00167 # endif
00168 #endif
00169
00170 #ifndef UHD_BULK_NB_BANK
00171 # define UHD_BULK_NB_BANK 2
00172 #else
00173 # if (UHD_BULK_NB_BANK < 1) || (UHD_BULK_NB_BANK > 2)
00174 # error UHD_BULK_NB_BANK must be define with 1 or 2.
00175 # endif
00176 #endif
00177
00178 #ifndef UHD_INTERRUPT_NB_BANK
00179 # define UHD_INTERRUPT_NB_BANK 1
00180 #else
00181 # if (UHD_INTERRUPT_NB_BANK < 1) || (UHD_INTERRUPT_NB_BANK > 2)
00182 # error UHD_INTERRUPT_NB_BANK must be define with 1 or 2.
00183 # endif
00184 #endif
00185
00186
00187
00188
00189
00190 #ifndef UHD_NO_SLEEP_MGR
00191
00192 #include "sleepmgr.h"
00193
00194 enum uhd_uotghs_state_enum {
00195 UHD_STATE_OFF = 0,
00196 UHD_STATE_WAIT_ID_HOST = 1,
00197 UHD_STATE_NO_VBUS = 2,
00198 UHD_STATE_DISCONNECT = 3,
00199 UHD_STATE_SUSPEND = 4,
00200 UHD_STATE_IDLE = 5,
00201 };
00202
00203
00204
00205
00206
00207 static void uhd_sleep_mode(enum uhd_uotghs_state_enum new_state)
00208 {
00209 enum sleepmgr_mode sleep_mode[] = {
00210 SLEEPMGR_BACKUP,
00211 SLEEPMGR_WAIT_FAST,
00212 SLEEPMGR_SLEEP_WFI,
00213 SLEEPMGR_SLEEP_WFI,
00214 SLEEPMGR_WAIT_FAST,
00215 SLEEPMGR_SLEEP_WFI,
00216 };
00217
00218 static enum uhd_uotghs_state_enum uhd_state = UHD_STATE_OFF;
00219
00220 if (uhd_state == new_state) {
00221 return;
00222 }
00223 if (new_state != UHD_STATE_OFF) {
00224
00225 sleepmgr_lock_mode(sleep_mode[new_state]);
00226 }
00227 if (uhd_state != UHD_STATE_OFF) {
00228
00229 sleepmgr_unlock_mode(sleep_mode[uhd_state]);
00230 }
00231 uhd_state = new_state;
00232 }
00233
00234 #else
00235 # define uhd_sleep_mode(arg)
00236 #endif // UHD_NO_SLEEP_MGR
00237
00238
00239
00240
00241 static uhd_callback_reset_t uhd_reset_callback = NULL;
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 struct uhd_ctrl_request_t {
00256
00257 struct uhd_ctrl_request_t *next_request;
00258
00259
00260 uhd_callback_setup_run_t callback_run;
00261
00262 uhd_callback_setup_end_t callback_end;
00263
00264
00265 uint8_t *payload;
00266
00267
00268 uint8_t add;
00269
00270
00271 USBGenericRequest req;
00272
00273
00274 uint16_t payload_size;
00275 };
00276
00277
00278 struct uhd_ctrl_request_t *uhd_ctrl_request_first;
00279 struct uhd_ctrl_request_t *uhd_ctrl_request_last;
00280
00281
00282 volatile uint16_t uhd_ctrl_request_timeout;
00283
00284
00285 uint16_t uhd_ctrl_nb_trans;
00286
00287
00288 static bool uhd_b_suspend_requested;
00289
00290
00291 typedef enum {
00292
00293 UHD_CTRL_REQ_PHASE_SETUP = 0,
00294
00295 UHD_CTRL_REQ_PHASE_DATA_OUT = 1,
00296
00297 UHD_CTRL_REQ_PHASE_DATA_IN = 2,
00298
00299 UHD_CTRL_REQ_PHASE_ZLP_IN = 3,
00300
00301 UHD_CTRL_REQ_PHASE_ZLP_OUT = 4,
00302 } uhd_ctrl_request_phase_t;
00303 uhd_ctrl_request_phase_t uhd_ctrl_request_phase;
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 typedef struct {
00321
00322 uhd_callback_trans_t call_end;
00323
00324
00325 uint8_t *buf;
00326
00327 uint32_t buf_size;
00328
00329 uint32_t nb_trans;
00330
00331
00332 uint16_t timeout;
00333
00334 uint16_t busy:1;
00335
00336 uint16_t b_shortpacket:1;
00337
00338 uint16_t b_periodic_start:1;
00339 } USBH_PipeJob_t;
00340
00341
00342 static USBH_PipeJob_t uhd_pipe_job[USBHS_EPT_NUM - 1];
00343
00344
00345 static uint8_t uhd_suspend_start;
00346 static uint8_t uhd_resume_start;
00347 static uint16_t uhd_pipes_unfreeze;
00348
00349
00350 static const Pin USB_HOST[] = PINS_VBUS_EN;
00351
00352 static void USBH_HAL_ManageSof(void);
00353 static void USBH_HAL_ControlInterrupt(void);
00354 static void USBH_HAL_PhaseControlSetup(void);
00355 static void USBH_HAL_PhaseDataInStart(void);
00356 static void USBH_HAL_PhaseDataIn(void);
00357 static void USBH_HAL_InZLP(void);
00358 static void USBH_HAL_PhaseDataOut(void);
00359 static void USBH_HAL_OutZLP(void);
00360 static void USBH_HAL_ControlReqEnd(USBH_XfrStatus_t status);
00361 static USBH_XfrStatus_t USBH_HAL_GetPipeError(uint8_t pipe);
00362 static uint8_t USBH_HAL_GetPipe(uint8_t Addr, uint8_t bEndpoint);
00363
00364 #ifdef UHD_PIPE_FIFO_SUPPORTED
00365 static void USBH_HAL_PipeOutReady(uint8_t pipe);
00366 static void USBH_HAL_PipeInReceived(uint8_t pipe);
00367 #endif
00368 #ifdef UHD_PIPE_DMA_SUPPORTED
00369 static void USBH_HAL_PipeXfrCmplt(uint8_t pipe);
00370 static void USBH_HAL_PipeDmaInterrupt(uint8_t pipe);
00371 #endif
00372
00373 static void USBH_HAL_PipeInterrupt(uint8_t pipe);
00374 static void USBH_HAL_PipeAbort(uint8_t pipe, USBH_XfrStatus_t status);
00375 static void USBH_HAL_PipeXfrEnd(uint8_t pipe, USBH_XfrStatus_t status);
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 void USBHS_Handler(void)
00401 {
00402 uint8_t pipe_int, pipe_dma_int;
00403 uint32_t status = USBHS_GetHostStatus(USBHS, 0xFF);
00404 uint32_t statusInt =( status & USBHS_IsHostIntEnable(USBHS, 0xFF));
00405
00406 memory_sync();
00407 TRACE_DEBUG("%c ", USBHS_IsUsbLowSpeed(USBHS) ? 'L' :
00408 (USBHS_IsUsbHighSpeed(USBHS) ? 'H' : 'F'));
00409 if(USBHS_IsUsbLowSpeed(USBHS) && (!(USBHS->USBHS_HSTCTRL & USBHS_HSTCTRL_SPDCONF_Msk)))
00410 {
00411 USBHS->USBHS_HSTCTRL |= USBHS_HSTCTRL_SPDCONF_LOW_POWER;
00412 }
00413
00414 if (status & USBHS_HSTISR_HSOFI)
00415 {
00416
00417 USBHS_ClearHostStatus(USBHS, USBHS_HSTICR_HSOFIC);
00418 USBH_HAL_ManageSof();
00419 }
00420 else
00421 {
00422 pipe_int = USBHS_GetInterruptPipeNum();
00423 pipe_dma_int = USBHS_GetInterruptPipeDmaNum();
00424 if (pipe_int == 0) {
00425 TRACE_DEBUG("Pipe0: ");
00426
00427 USBH_HAL_ControlInterrupt();
00428 }
00429 else if (pipe_int != USBHS_EPT_NUM) {
00430 TRACE_DEBUG("Pipe%x: ", pipe_int);
00431
00432 USBH_HAL_PipeInterrupt(pipe_int);
00433 }
00434 #ifdef UHD_PIPE_DMA_SUPPORTED
00435 else if (pipe_dma_int != USBHS_EPT_NUM) {
00436 TRACE_DEBUG("Pipe%x ", pipe_dma_int);
00437
00438 USBH_HAL_PipeDmaInterrupt(pipe_dma_int);
00439 }
00440 #endif
00441
00442 else if (status & USBHS_HSTISR_RSTI)
00443 {
00444 TRACE_INFO_WP("RST ");
00445 USBHS_ClearHostStatus(USBHS, USBHS_HSTICR_RSTIC);
00446 if (uhd_reset_callback != NULL) {
00447 uhd_reset_callback();
00448 }
00449 }
00450
00451
00452
00453
00454 else if (statusInt & USBHS_HSTIMR_DDISCIE) {
00455 USBHS_ClearHostStatus(USBHS, USBHS_HSTICR_DDISCIC);
00456 USBHS_HostIntDisable(USBHS, USBHS_HSTIDR_DDISCIEC);
00457 TRACE_INFO("Disconnect--\n\r");
00458
00459 USBHS_StopReset();
00460
00461
00462 USBHS_HostIntDisable(USBHS, ( USBHS_HSTIDR_HWUPIEC
00463 | USBHS_HSTIDR_RSMEDIEC
00464 | USBHS_HSTIDR_RXRSMIEC));
00465 uhd_sleep_mode(UHD_STATE_DISCONNECT);
00466 USBHS_ClearHostStatus(USBHS, USBHS_HSTICR_DCONNIC);
00467 USBHS_HostIntEnable(USBHS, USBHS_HSTIER_DCONNIES);
00468 USBHS_ClearHostStatus(USBHS, USBHS_HSTICR_HWUPIC);
00469 USBHS_HostIntEnable(USBHS, USBHS_HSTIER_HWUPIES);
00470 #ifdef USB_HOST_HS_SUPPORT
00471 USBHS_SetHostHighSpeed(USBHS);
00472 #endif
00473
00474 uhd_suspend_start = 0;
00475 uhd_resume_start = 0;
00476 USBH_notify_connection(false);
00477 }
00478 else if (statusInt & USBHS_HSTIMR_DCONNIE) {
00479 TRACE_INFO("Connect-- ");
00480 USBHS_ClearHostStatus(USBHS, USBHS_HSTICR_DCONNIC);
00481 USBHS_HostIntDisable(USBHS,USBHS_HSTIDR_DCONNIEC);
00482 USBHS_ClearHostStatus(USBHS, USBHS_HSTICR_DDISCIC);
00483 USBHS_HostIntEnable(USBHS, USBHS_HSTIER_DDISCIES);
00484 USBHS_EnableSOF(USBHS);
00485 uhd_sleep_mode(UHD_STATE_IDLE);
00486 uhd_suspend_start = 0;
00487 uhd_resume_start = 0;
00488 USBH_notify_connection(true);
00489 }
00490
00491
00492 else if((statusInt & USBHS_HSTISR_HWUPI ) && USBHS_IsHostIntEnable(USBHS, USBHS_HSTIMR_DCONNIE ) )
00493 {
00494 while (!USBHS_ISUsableClock(USBHS));
00495 USBHS_UnFreezeClock(USBHS);
00496
00497
00498 USBHS_HostIntDisable(USBHS, USBHS_HSTIDR_HWUPIEC);
00499
00500
00501 USBHS_Set(USBHS, USBHS_SR_VBUSRQ);
00502 uhd_sleep_mode(UHD_STATE_DISCONNECT);
00503 UHC_VBUS_CHANGE(true);
00504 }
00505
00506
00507 else if (USBHS_IsHostIntEnable(USBHS, USBHS_HSTIMR_HWUPIE) && (USBHS_GetHostStatus(USBHS, (USBHS_HSTISR_HWUPI | USBHS_HSTISR_RSMEDI | USBHS_HSTISR_RXRSMI) )))
00508 {
00509
00510 TRACE_INFO_WP("\n\rWKP ");
00511 while (!USBHS_ISUsableClock(USBHS));
00512 USBHS_UnFreezeClock(USBHS);
00513
00514 USBHS_HostIntDisable(USBHS, (USBHS_HSTIDR_HWUPIEC
00515 | USBHS_HSTIDR_RSMEDIEC
00516 | USBHS_HSTIDR_RXRSMIEC) );
00517 USBHS_EnableSOF(USBHS);
00518 if ((!(USBHS_HSTISR_RSMEDI & status))
00519 &&(!(USBHS_HSTISR_DDISCI & status))) {
00520
00521
00522
00523
00524
00525
00526
00527 if (USBHS_IsUsbHighSpeed(USBHS)) {
00528 USBHS_Resume();
00529 }
00530 }
00531
00532 uhd_resume_start = 50;
00533 uhd_sleep_mode(UHD_STATE_IDLE);
00534 }
00535 else
00536 {
00537 assert(false);
00538 }
00539
00540 }
00541 }
00542
00543
00544 void USBH_HAL_EnableUsbHost(void)
00545 {
00546 irqflags_t flags;
00547
00548
00549 flags = cpu_irq_save();
00550
00551
00552
00553
00554 sysclk_enable_usb();
00555 PMC_EnablePeripheral(ID_USBHS);
00556
00557
00558
00559 NVIC_SetPriority((IRQn_Type) ID_USBHS, UHD_USB_INT_LEVEL);
00560 NVIC_EnableIRQ((IRQn_Type) ID_USBHS);
00561
00562 uhd_sleep_mode(UHD_STATE_OFF);
00563
00564 PIO_Configure(USB_HOST, PIO_LISTSIZE(USB_HOST));
00565
00566 PIO_Set(USB_HOST);
00567
00568 USBHS_UsbMode(USBHS, HOST_MODE);
00569
00570
00571 USBHS_UsbEnable(USBHS, true);
00572
00573 #ifndef USB_HOST_HS_SUPPORT
00574 USBHS->USBHS_HSTCTRL |= USBHS_HSTCTRL_SPDCONF_LOW_POWER;
00575 #endif
00576
00577 uhd_ctrl_request_first = NULL;
00578 uhd_ctrl_request_last = NULL;
00579 uhd_ctrl_request_timeout = 0;
00580 uhd_suspend_start = 0;
00581 uhd_resume_start = 0;
00582 uhd_b_suspend_requested = false;
00583
00584
00585 USBHS_UnFreezeClock(USBHS);
00586 while (!USBHS_ISUsableClock(USBHS));
00587
00588
00589 USBHS_ClearHostStatus(USBHS, (USBHS_HSTICR_DCONNIC | USBHS_HSTICR_DDISCIC
00590 | USBHS_HSTICR_HSOFIC | USBHS_HSTICR_HWUPIC
00591 | USBHS_HSTICR_RSMEDIC | USBHS_HSTICR_RSTIC
00592 | USBHS_HSTICR_RXRSMIC));
00593
00594 memory_sync();
00595
00596 USBHS_VBusHWC(USBHS, false);
00597 uhd_sleep_mode(UHD_STATE_NO_VBUS);
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607 USBHS_HostIntEnable(USBHS, USBHS_HSTIER_HWUPIES);
00608 uhd_sleep_mode(UHD_STATE_DISCONNECT);
00609 UHC_VBUS_CHANGE(true);
00610
00611 PIO_Clear(USB_HOST);
00612
00613
00614
00615 USBHS_HostIntEnable(USBHS, (USBHS_HSTIER_RSTIES | USBHS_HSTIER_HSOFIES | USBHS_HSTIER_DCONNIES));
00616
00617 USBHS_FreezeClock(USBHS);
00618
00619 cpu_irq_restore(flags);
00620
00621 }
00622
00623 void USBH_HAL_DisableUsb(bool b_id_stop)
00624 {
00625 irqflags_t flags;
00626
00627
00628 while (!USBHS_ISUsableClock(USBHS));
00629 USBHS_UnFreezeClock(USBHS);
00630 printf("USB disabled \n\r");
00631
00632
00633 USBHS_HostIntDisable(USBHS, (USBHS_HSTICR_DCONNIC | USBHS_HSTICR_DDISCIC
00634 | USBHS_HSTICR_HSOFIC | USBHS_HSTICR_HWUPIC
00635 | USBHS_HSTICR_RSMEDIC | USBHS_HSTICR_RSTIC
00636 | USBHS_HSTICR_RXRSMIC));
00637
00638 USBHS_DisableSOF();
00639 USBHS_Ack(USBHS, USBHS_SR_VBUSRQ);
00640 USBH_notify_connection(false);
00641
00642 flags = cpu_irq_save();
00643 USBHS_FreezeClock(USBHS);
00644 USBHS_UsbEnable(USBHS, false);
00645 sysclk_disable_usb();
00646 PMC_DisablePeripheral(ID_USBHS);
00647 uhd_sleep_mode(UHD_STATE_OFF);
00648 cpu_irq_restore(flags);
00649 }
00650
00651 USBH_Speed_t USBH_HAL_GetSpeed(void)
00652 {
00653 switch (USBHS_GetUsbSpeed(USBHS)) {
00654
00655 case USBHS_SR_SPEED_HIGH_SPEED:
00656 return UHD_SPEED_HIGH;
00657
00658 case USBHS_SR_SPEED_FULL_SPEED:
00659 return UHD_SPEED_FULL;
00660
00661 case USBHS_SR_SPEED_LOW_SPEED:
00662 return UHD_SPEED_LOW;
00663
00664 default:
00665 assert(false);
00666 return UHD_SPEED_LOW;
00667 }
00668 }
00669
00670 uint16_t USBH_HAL_GetFrameNum(void)
00671 {
00672 return USBHS_HostGetSOF();
00673 }
00674
00675 uint16_t USBH_HAL_GetMicroFrameNum(void)
00676 {
00677 return USBHS_HostGetMSOF();
00678 }
00679
00680 void USBH_HAL_Reset(uhd_callback_reset_t callback)
00681 {
00682 uhd_reset_callback = callback;
00683 USBHS_Reset();
00684 }
00685
00686 void USBH_HAL_Suspend(void)
00687 {
00688 uint8_t pipe;
00689 if (uhd_ctrl_request_timeout) {
00690
00691 uhd_b_suspend_requested = true;
00692 return;
00693 }
00694
00695 uhd_pipes_unfreeze = 0;
00696 for (pipe = 1; pipe < USBHS_EPT_NUM; pipe++) {
00697 uhd_pipes_unfreeze |= (!USBHS_IsHostPipeIntTypeEnable(USBHS,pipe, USBHS_HSTPIPIMR_PFREEZE)) << pipe;
00698 USBHS_HostEnablePipeIntType(USBHS, pipe, USBHS_HSTPIPIER_PFREEZES);
00699 }
00700
00701 uhd_suspend_start = 3;
00702 }
00703
00704 bool USBH_HAL_IsSuspended(void)
00705 {
00706 return !USBHS_IsEnableSOF(USBHS);
00707 }
00708
00709 void USBH_HAL_Resume(void)
00710 {
00711 if (USBHS_IsEnableSOF(USBHS)) {
00712
00713 if (uhd_suspend_start) {
00714
00715
00716 uhd_suspend_start = 0;
00717 uhd_resume_start = 1;
00718 }
00719 return;
00720 }
00721
00722 while (!USBHS_ISUsableClock(USBHS));
00723 USBHS_UnFreezeClock(USBHS);
00724 USBHS_EnableSOF(USBHS);
00725 USBHS_Resume();
00726 uhd_sleep_mode(UHD_STATE_IDLE);
00727 }
00728
00729 bool USBH_HAL_ConfigureControlPipe(uint8_t Addr, uint16_t ep_size)
00730 {
00731 uint8_t bSizeEpt;
00732 if (ep_size < 8) {
00733 return false;
00734 }
00735 #ifdef USB_HOST_HUB_SUPPORT
00736 if (USBHS_IsHostPipeEnable(USBHS, 0)) {
00737
00738 #error TODO Add USB address in a list
00739 return true;
00740 }
00741 #endif
00742
00743 USBHS_HostPipeEnable(USBHS, 0);
00744
00745
00746 if(ep_size <= 8 )
00747 bSizeEpt = 0;
00748 else if (ep_size <= 16 )
00749 bSizeEpt = 1;
00750 else if (ep_size <= 32 )
00751 bSizeEpt = 2;
00752 else if (ep_size <= 64 )
00753 bSizeEpt = 3;
00754 else if (ep_size <= 128 )
00755 bSizeEpt = 4;
00756 else if (ep_size <= 256 )
00757 bSizeEpt = 5;
00758 else if (ep_size <= 512 )
00759 bSizeEpt = 6;
00760 else if (ep_size <= 1024 )
00761 bSizeEpt = 7;
00762
00763 #ifdef USB_HOST_HUB_SUPPORT
00764 bSizeEpt = 3;
00765 #endif
00766 USBHS_HostConfigure(USBHS, 0, USBHS_HSTPIPCFG_PBK_1_BANK, bSizeEpt, USBHS_HSTPIPCFG_PTYPE_CTRL, USBHS_HSTPIPCFG_PTOKEN_SETUP, 0, 0);
00767 USBHS_HostDisableAutoSw(USBHS, 0);
00768 USBHS_HostAllocMem(USBHS, 0);
00769 if (!USBHS_IsHostConfigOk(USBHS, 0)) {
00770 USBHS_HostPipeDisable(USBHS, 0);
00771 return false;
00772 }
00773 USBHS_HostSetAddr(USBHS, 0, Addr);
00774
00775
00776 USBHS_HostEnablePipeIntType(USBHS, 0, (USBHS_HSTPIPIER_RXSTALLDES | USBHS_HSTPIPIER_PERRES) );
00777 USBHS_HostPipeIntEnable(USBHS, 0);
00778 return true;
00779 }
00780
00781 bool USBH_HAL_ConfigurePipe(uint8_t Addr, USBEndpointDescriptor * ep_desc)
00782 {
00783 uint32_t ep_type, ep_dir;
00784 uint8_t ep_interval;
00785 uint8_t pipe;
00786 uint8_t bank, ep_addr, bSizeEpt;
00787
00788 for (pipe = 1; pipe < USBHS_EPT_NUM; pipe++) {
00789 if (USBHS_IsHostPipeEnable(USBHS, pipe)) {
00790 continue;
00791 }
00792 USBHS_HostPipeEnable(USBHS, pipe);
00793 ep_addr = ep_desc->bEndpointAddress & USB_EP_ADDR_MASK;
00794 ep_dir = (ep_desc->bEndpointAddress & USB_EP_DIR_IN)?
00795 (USBHS_HSTPIPCFG_PTOKEN_IN):
00796 (USBHS_HSTPIPCFG_PTOKEN_OUT),
00797 ep_type = ep_desc->bmAttributes&USB_EP_TYPE_MASK;
00798
00799 switch(ep_type) {
00800 case USBEndpointDescriptor_ISOCHRONOUS:
00801 bank = UHD_ISOCHRONOUS_NB_BANK;
00802 ep_interval = ep_desc->bInterval;
00803 ep_type = USBHS_HSTPIPCFG_PTYPE_ISO;
00804 break;
00805 case USBEndpointDescriptor_INTERRUPT:
00806 bank = UHD_INTERRUPT_NB_BANK;
00807 ep_interval = ep_desc->bInterval;
00808 ep_type = USBHS_HSTPIPCFG_PTYPE_INTRPT;
00809 break;
00810 case USBEndpointDescriptor_BULK:
00811 bank = UHD_BULK_NB_BANK;
00812
00813 ep_interval = 0;
00814 ep_type = USBHS_HSTPIPCFG_PTYPE_BLK;
00815 break;
00816 default:
00817 assert(false);
00818 return false;
00819 }
00820 switch(bank) {
00821 case 1:
00822 bank = USBHS_HSTPIPCFG_PBK_1_BANK;
00823 break;
00824 case 2:
00825 bank = USBHS_HSTPIPCFG_PBK_2_BANK;
00826 break;
00827 case 3:
00828 bank = USBHS_HSTPIPCFG_PBK_3_BANK;
00829 break;
00830 default:
00831 assert(false);
00832 return false;
00833 }
00834
00835
00836 if(ep_desc->wMaxPacketSize <= 8 )
00837 bSizeEpt = 0;
00838 else if (ep_desc->wMaxPacketSize <= 16 )
00839 bSizeEpt = 1;
00840 else if (ep_desc->wMaxPacketSize <= 32 )
00841 bSizeEpt = 2;
00842 else if (ep_desc->wMaxPacketSize <= 64 )
00843 bSizeEpt = 3;
00844 else if (ep_desc->wMaxPacketSize <= 128 )
00845 bSizeEpt = 4;
00846 else if (ep_desc->wMaxPacketSize <= 256 )
00847 bSizeEpt = 5;
00848 else if (ep_desc->wMaxPacketSize <= 512 )
00849 bSizeEpt = 6;
00850 else if (ep_desc->wMaxPacketSize <= 1024 )
00851 bSizeEpt = 7;
00852
00853
00854 USBHS_HostConfigure(USBHS, pipe, bank, bSizeEpt, ep_type, ep_dir, ep_addr, ep_interval);
00855 USBHS_HostEnableAutoSw(USBHS, pipe);
00856
00857 USBHS_HostAllocMem(USBHS, pipe);
00858 if (!USBHS_IsHostConfigOk(USBHS, pipe)) {
00859 USBHS_HostPipeDisable(USBHS, pipe);
00860 return false;
00861 }
00862
00863 USBHS_HostSetAddr(USBHS, pipe, Addr);
00864
00865 USBHS_HostPipeEnable(USBHS, pipe);
00866
00867
00868 USBHS_HostDmaIntEnable(USBHS, pipe-1);
00869 USBHS_HostEnablePipeIntType(USBHS, pipe, (USBHS_HSTPIPIER_RXSTALLDES | USBHS_HSTPIPIER_PERRES) );
00870
00871 USBHS_HostPipeIntEnable(USBHS, pipe);
00872
00873 return true;
00874 }
00875 return false;
00876 }
00877
00878
00879 void USBH_HAL_FreePipe(uint8_t Addr, uint8_t bEndpoint)
00880 {
00881 uint8_t pipe;
00882 #ifdef USB_HOST_HUB_SUPPORT
00883 if (bEndpoint == 0) {
00884
00885 #error TODO the list address must be updated
00886 if (uhd_ctrl_request_timeout
00887 && (uhd_ctrl_request_first->add == Addr)) {
00888
00889 USBH_HAL_ControlReqEnd(UHD_TRANS_DISCONNECT);
00890 }
00891 return;
00892 }
00893 #endif
00894
00895 for (pipe = 0; pipe < USBHS_EPT_NUM; pipe++) {
00896 if (!USBHS_IsHostPipeEnable(USBHS, pipe)) {
00897 continue;
00898 }
00899 if (Addr != USBHS_HostGetAddr(USBHS, pipe)) {
00900 continue;
00901 }
00902 if (bEndpoint != 0xFF) {
00903
00904 if (bEndpoint != USBHS_GetPipeEpAddr(USBHS, pipe)) {
00905 continue;
00906 }
00907 }
00908
00909 USBHS_HostPipeDisable(USBHS, pipe);
00910 USBHS_HostFreeMem(USBHS, pipe);
00911
00912
00913 #ifndef USB_HOST_HUB_SUPPORT
00914 if (pipe == 0) {
00915
00916 if (uhd_ctrl_request_timeout) {
00917 USBH_HAL_ControlReqEnd(UHD_TRANS_DISCONNECT);
00918 }
00919 continue;
00920 }
00921 #endif
00922
00923 USBH_HAL_PipeAbort(pipe, UHD_TRANS_DISCONNECT);
00924 }
00925 }
00926
00927 bool USBH_HAL_SetupReq(
00928 uint8_t Addr,
00929 USBGenericRequest *req,
00930 uint8_t *payload,
00931 uint16_t payload_size,
00932 uhd_callback_setup_run_t callback_run,
00933 uhd_callback_setup_end_t callback_end)
00934 {
00935 irqflags_t flags;
00936 struct uhd_ctrl_request_t *request;
00937 bool b_start_request = false;
00938
00939 request = malloc(sizeof(struct uhd_ctrl_request_t));
00940 if (request == NULL) {
00941 assert(false);
00942 return false;
00943 }
00944
00945
00946 request->add = (uint8_t) Addr;
00947 memcpy(&request->req, req, sizeof(USBGenericRequest));
00948 request->payload = payload;
00949 request->payload_size = payload_size;
00950 request->callback_run = callback_run;
00951 request->callback_end = callback_end;
00952 request->next_request = NULL;
00953
00954
00955 flags = cpu_irq_save();
00956 if (uhd_ctrl_request_first == NULL) {
00957 uhd_ctrl_request_first = request;
00958 b_start_request = true;
00959 } else {
00960 uhd_ctrl_request_last->next_request = request;
00961 }
00962 uhd_ctrl_request_last = request;
00963 cpu_irq_restore(flags);
00964
00965 if (b_start_request) {
00966
00967 USBH_HAL_PhaseControlSetup();
00968 }
00969 return true;
00970 }
00971
00972 bool USBH_HAL_RunEndpoint(uint8_t Addr,
00973 uint8_t bEndpoint,
00974 bool b_shortpacket,
00975 uint8_t *buf,
00976 uint32_t buf_size,
00977 uint16_t timeout,
00978 uhd_callback_trans_t callback)
00979 {
00980 irqflags_t flags;
00981 uint8_t pipe;
00982 USBH_PipeJob_t *pJob;
00983
00984 pipe = USBH_HAL_GetPipe(Addr,bEndpoint);
00985 if (pipe == USBHS_EPT_NUM) {
00986 return false;
00987 }
00988 #ifdef UHD_PIPE_FIFO_SUPPORTED
00989 bool b_pipe_in = (USBHS_HostGetToken(USBHS, pipe) == USBHS_HSTPIPCFG_PTOKEN_IN)?true:false;
00990 #endif
00991
00992
00993 pJob = &uhd_pipe_job[pipe-1];
00994 flags = cpu_irq_save();
00995 if (pJob->busy == true) {
00996 cpu_irq_restore(flags);
00997 return false;
00998 }
00999 pJob->busy = true;
01000
01001
01002 pJob->buf = buf;
01003 pJob->buf_size = buf_size;
01004 pJob->nb_trans = 0;
01005 pJob->timeout = timeout;
01006 pJob->b_shortpacket = b_shortpacket;
01007 pJob->call_end = callback;
01008 if( (USBHS_HostGetPipeType(USBHS, pipe) & (USBHS_HSTPIPCFG_PTYPE_ISO | USBHS_HSTPIPCFG_PTYPE_INTRPT)) && (USBHS_HostGetToken(USBHS, pipe) == USBHS_HSTPIPCFG_PTOKEN_OUT))
01009
01010
01011 {
01012 pJob->b_periodic_start = true;
01013 }
01014 cpu_irq_restore(flags);
01015
01016 #ifdef UHD_PIPE_FIFO_SUPPORTED
01017
01018 if (!Is_uhd_pipe_dma_supported(pipe)) {
01019 flags = cpu_irq_save();
01020 USBHS_HostDisableAutoSw(USBHS, pipe);;
01021 USBHS_HostDisablePipeIntType(USBHS, pipe, USBHS_HSTPIPIDR_PFREEZEC);
01022 if (b_pipe_in) {
01023 USBHS_HostEnableInReq(USBHS, pipe);
01024 USBHS_HostEnablePipeIntType(USBHS, pipe, USBHS_HSTPIPIER_RXINES);
01025 if (b_shortpacket) {
01026 USBHS_HostEnablePipeIntType(USBHS, pipe, USBHS_HSTPIPIER_SHORTPACKETIES);
01027 }
01028 } else {
01029 USBHS_HostDisablePipeIntType(USBHS, pipe, USBHS_HSTPIPIDR_NBUSYBKEC);
01030 USBHS_HostEnablePipeIntType(USBHS, pipe, USBHS_HSTPIPIER_TXOUTES);
01031 }
01032 USBHS_HostPipeIntEnable(USBHS, pipe);
01033 cpu_irq_restore(flags);
01034 return true;
01035 }
01036 #endif // UHD_PIPE_FIFO_SUPPORTED
01037
01038 #ifdef UHD_PIPE_DMA_SUPPORTED
01039
01040 USBH_HAL_PipeXfrCmplt(pipe);
01041 #endif
01042 return true;
01043 }
01044
01045 void USBH_HAL_AbortEndPoint(uint8_t Addr, uint8_t bEndpoint)
01046 {
01047 uint8_t pipe;
01048
01049 pipe = USBH_HAL_GetPipe(Addr,bEndpoint);
01050 if (pipe == USBHS_EPT_NUM) {
01051 return;
01052 }
01053 USBH_HAL_PipeAbort(pipe,UHD_TRANS_ABORTED);
01054 }
01055
01056
01057 static void USBH_HAL_DelayedSuspend(void)
01058 {
01059 volatile uint8_t AsyncInt= ( USBHS_HSTIER_HWUPIES |USBHS_HSTIER_RSMEDIES | USBHS_HSTIER_RXRSMIES );
01060
01061 if (--uhd_suspend_start == 0) {
01062
01063
01064
01065
01066 uint8_t pos =
01067 (USBHS_GetUsbSpeed(USBHS) == USBHS_SR_SPEED_HIGH_SPEED) ?
01068 13 : 114;
01069 while (pos < USBHS_HostGetFramePos()) {
01070 if (USBHS_GetHostStatus(USBHS, USBHS_HSTISR_DDISCI)) {
01071 break;
01072 }
01073 }
01074 USBHS_DisableSOF();
01075
01076
01077
01078
01079 for (pos = 0; pos < 15; pos ++) {
01080 memory_barrier();
01081 if (USBHS_GetHostStatus(USBHS, USBHS_HSTICR_HWUPIC
01082 | USBHS_HSTICR_RSMEDIC
01083 | USBHS_HSTICR_RXRSMIC))
01084 {
01085 break;
01086 }
01087 }
01088
01089
01090
01091 USBHS_ClearHostStatus(USBHS, ( USBHS_HSTICR_HWUPIC
01092 | USBHS_HSTICR_RSMEDIC
01093 | USBHS_HSTICR_RXRSMIC));
01094
01095 memory_sync();
01096
01097 USBHS_HostIntEnable(USBHS, AsyncInt );
01098
01099
01100 USBHS_FreezeClock(USBHS);
01101 uhd_sleep_mode(UHD_STATE_SUSPEND);
01102 }
01103 }
01104 static void USBH_HAL_DelayedResume(void)
01105 {
01106 uint8_t pipe;
01107 if (--uhd_resume_start == 0) {
01108
01109 for (pipe = 1; pipe < USBHS_EPT_NUM; pipe++) {
01110 if ((uhd_pipes_unfreeze >> pipe) & 0x01) {
01111 USBHS_HostDisablePipeIntType(USBHS, pipe, USBHS_HSTPIPIDR_PFREEZEC);
01112 }
01113 }
01114 USBH_notify_resume();
01115 }
01116 }
01117 static void USBH_HAL_ControlTimeout(void)
01118 {
01119 if (uhd_ctrl_request_timeout) {
01120
01121 if (--uhd_ctrl_request_timeout == 0) {
01122 TRACE_WARNING_WP("Timeout");
01123
01124 USBHS_HostEnablePipeIntType(USBHS, 0, USBHS_HSTPIPIER_PFREEZES);
01125 USBH_HAL_ControlReqEnd(UHD_TRANS_TIMEOUT);
01126 }
01127 }
01128 }
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141 static void USBH_HAL_ManageSof(void)
01142 {
01143
01144
01145 uint8_t pipe;
01146
01147 if (USBHS_IsUsbHighSpeed(USBHS)) {
01148 static uint8_t msof_cpt = 0;
01149 if (++msof_cpt % 8) {
01150
01151 if (!uhd_suspend_start && !uhd_resume_start) {
01152
01153
01154 USBH_notify_sof(true);
01155 }
01156 return;
01157 }
01158 }
01159
01160
01161 if (uhd_suspend_start) {
01162 USBH_HAL_DelayedSuspend();
01163 return;
01164 }
01165
01166 if (uhd_resume_start) {
01167 USBH_HAL_DelayedResume();
01168 return;
01169 }
01170
01171 USBH_HAL_ControlTimeout();
01172
01173
01174 USBH_PipeJob_t *pJob;
01175 for (pipe = 1; pipe < USBHS_EPT_NUM; pipe++) {
01176 pJob = &uhd_pipe_job[pipe-1];
01177 if (pJob->busy == true) {
01178 if (pJob->timeout) {
01179
01180 if (--(pJob->timeout) == 0) {
01181
01182 USBH_HAL_PipeAbort(pipe,UHD_TRANS_TIMEOUT);
01183 }
01184 }
01185 if (pJob->b_periodic_start) {
01186 pJob->b_periodic_start = false;
01187 USBHS_HostDisablePipeIntType(USBHS, pipe, USBHS_HSTPIPIDR_PFREEZEC);
01188 }
01189 }
01190 }
01191
01192 USBH_notify_sof(false);
01193
01194
01195 UHC_SOF_EVENT();
01196 memory_sync();
01197 }
01198
01199
01200
01201
01202
01203 static void USBH_HAL_ControlInterrupt(void)
01204 {
01205
01206
01207 assert(uhd_ctrl_request_timeout!=0);
01208
01209
01210 USBHS_HostDisablePipeIntType(USBHS, 0, (USBHS_HSTPIPIDR_TXSTPEC
01211 | USBHS_HSTPIPIDR_RXINEC
01212 | USBHS_HSTPIPIDR_TXOUTEC) );
01213
01214
01215 if (USBHS_HostGetIntTypeStatus(USBHS, 0, USBHS_HSTPIPISR_TXSTPI) )
01216 {
01217
01218 USBHS_HostEnablePipeIntType(USBHS, 0, USBHS_HSTPIPIER_PFREEZES);
01219 USBHS_HostAckPipeIntType(USBHS, 0, USBHS_HSTPIPICR_TXSTPIC);
01220 assert(uhd_ctrl_request_phase == UHD_CTRL_REQ_PHASE_SETUP);
01221
01222
01223 if ((uhd_ctrl_request_first->req.bmRequestType & USB_REQ_DIR_MASK)
01224 == USB_REQ_DIR_IN) {
01225 USBH_HAL_PhaseDataInStart();
01226 } else {
01227 if (uhd_ctrl_request_first->req.wLength) {
01228 USBH_HAL_PhaseDataOut();
01229 } else {
01230
01231 USBH_HAL_InZLP();
01232 }
01233 }
01234 return;
01235 }
01236 if (USBHS_HostGetIntTypeStatus(USBHS, 0,USBHS_HSTPIPISR_RXINI)) {
01237
01238
01239
01240 while (!USBHS_IsHostPipeIntTypeEnable(USBHS, 0, USBHS_HSTPIPIMR_PFREEZE));
01241
01242
01243 USBHS_HostAckPipeIntType(USBHS, 0, USBHS_HSTPIPICR_RXINIC);
01244 switch(uhd_ctrl_request_phase) {
01245 case UHD_CTRL_REQ_PHASE_DATA_IN:
01246 USBH_HAL_PhaseDataIn();
01247 break;
01248 case UHD_CTRL_REQ_PHASE_ZLP_IN:
01249 USBH_HAL_ControlReqEnd(UHD_TRANS_NOERROR);
01250 break;
01251 default:
01252 assert(false);
01253 break;
01254 }
01255 return;
01256 }
01257 if (USBHS_HostGetIntTypeStatus(USBHS, 0,USBHS_HSTPIPISR_TXOUTI)) {
01258
01259 USBHS_HostEnablePipeIntType(USBHS, 0, USBHS_HSTPIPIER_PFREEZES);
01260 USBHS_HostAckPipeIntType(USBHS, 0, USBHS_HSTPIPICR_TXOUTIC);
01261 switch(uhd_ctrl_request_phase) {
01262 case UHD_CTRL_REQ_PHASE_DATA_OUT:
01263 USBH_HAL_PhaseDataOut();
01264 break;
01265 case UHD_CTRL_REQ_PHASE_ZLP_OUT:
01266 USBH_HAL_ControlReqEnd(UHD_TRANS_NOERROR);
01267 break;
01268 default:
01269 assert(false);
01270 break;
01271 }
01272 return;
01273 }
01274 if (USBHS_HostGetIntTypeStatus(USBHS, 0,USBHS_HSTPIPISR_RXSTALLDI)) {
01275
01276 USBHS_HostAckPipeIntType(USBHS, 0, USBHS_HSTPIPICR_RXSTALLDIC);
01277 USBH_HAL_ControlReqEnd(UHD_TRANS_STALL);
01278 return;
01279 }
01280 if (USBHS_HostGetIntTypeStatus(USBHS, 0,USBHS_HSTPIPISR_PERRI)) {
01281
01282 USBH_HAL_ControlReqEnd(USBH_HAL_GetPipeError(0));
01283 printf("Control pipe error \n\r");
01284 return;
01285 }
01286 memory_sync();
01287 assert(false);
01288 }
01289
01290
01291
01292
01293
01294 static void USBH_HAL_PhaseControlSetup(void)
01295 {
01296 union{
01297 volatile uint64_t value64;
01298 USBGenericRequest req;
01299 } setup;
01300 volatile uint64_t *pEpData;
01301
01302 uhd_ctrl_request_phase = UHD_CTRL_REQ_PHASE_SETUP;
01303 memcpy(&setup.req, &uhd_ctrl_request_first->req, sizeof(USBGenericRequest));
01304 memory_sync();
01305
01306 uhd_ctrl_nb_trans = 0;
01307
01308
01309 #ifdef USB_HOST_HUB_SUPPORT
01310 if (!USBHS_IsHostPipeEnable(USBHS, 0)) {
01311 USBH_HAL_ControlReqEnd(UHD_TRANS_DISCONNECT);
01312 return;
01313 }
01314 #error TODO check address in list
01315
01316 uhd_configure_address(0, uhd_ctrl_request_first->add);
01317 #else
01318 if (!USBHS_IsHostPipeEnable(USBHS, 0) ||
01319 (uhd_ctrl_request_first->add != USBHS_HostGetAddr(USBHS, 0))) {
01320 USBH_HAL_ControlReqEnd(UHD_TRANS_DISCONNECT);
01321 return;
01322 }
01323 #endif
01324
01325
01326 USBHS_HostSetToken(USBHS, 0, USBHS_HSTPIPCFG_PTOKEN_SETUP);
01327 USBHS_HostAckPipeIntType(USBHS, 0, USBHS_HSTPIPICR_TXSTPIC);
01328 assert(sizeof(setup) == sizeof(uint64_t));
01329
01330 pEpData = (volatile uint64_t*)USBHS_RAM_ADDR;
01331 memory_sync();
01332 *pEpData = setup.value64;
01333 memory_barrier();
01334
01335 uhd_ctrl_request_timeout = 5000;
01336 USBHS_HostEnablePipeIntType(USBHS, 0, USBHS_HSTPIPIER_TXSTPES);
01337
01338 USBHS_HostDisablePipeIntType(USBHS, 0, (USBHS_HSTPIPIDR_FIFOCONC | USBHS_HSTPIPIDR_PFREEZEC));
01339
01340 }
01341
01342
01343
01344
01345
01346 static void USBH_HAL_PhaseDataInStart(void)
01347 {
01348 uhd_ctrl_request_phase = UHD_CTRL_REQ_PHASE_DATA_IN;
01349
01350 USBHS_HostSetToken(USBHS, 0, USBHS_HSTPIPCFG_PTOKEN_IN);
01351
01352 USBHS_HostAckPipeIntType(USBHS, 0, (USBHS_HSTPIPICR_RXINIC | USBHS_HSTPIPICR_SHORTPACKETIC) );
01353
01354 USBHS_HostEnablePipeIntType(USBHS, 0, USBHS_HSTPIPIER_RXINES);
01355
01356 USBHS_HostDisablePipeIntType(USBHS, 0, (USBHS_HSTPIPIDR_FIFOCONC | USBHS_HSTPIPIDR_PFREEZEC) );
01357
01358 memory_sync();
01359 }
01360
01361
01362
01363
01364
01365 static void USBH_HAL_PhaseDataIn(void)
01366 {
01367 bool b_short_packet;
01368 uint8_t *pEpData;
01369 uint8_t bPipe = 0;
01370 uint8_t nb_byte_received;
01371
01372
01373 nb_byte_received = USBHS_HostGetPipeByteCount(USBHS, bPipe);
01374 #ifdef USB_HOST_HUB_SUPPORT
01375
01376
01377 b_short_packet = (nb_byte_received != USBHS_HostGetSize(USBHS, 0));
01378 USBHS_HostAckPipeIntType(USBHS, 0, USBHS_HSTPIPICR_SHORTPACKETIC);
01379 #else
01380 b_short_packet = (USBHS_HostGetIntTypeStatus(USBHS, 0, USBHS_HSTPIPISR_SHORTPACKETI) == USBHS_HSTPIPISR_SHORTPACKETI)? true:false;
01381 #endif
01382
01383 pEpData = (uint8_t*)((uint32_t*)USBHS_RAM_ADDR
01384 + (EPT_VIRTUAL_SIZE * bPipe));
01385 uhd_ctrl_receiv_in_read_data:
01386 memory_sync();
01387
01388 while (uhd_ctrl_request_first->payload_size && nb_byte_received) {
01389 *uhd_ctrl_request_first->payload++ = *pEpData++;
01390 memory_sync();
01391 uhd_ctrl_nb_trans++;
01392 uhd_ctrl_request_first->payload_size--;
01393 nb_byte_received--;
01394 memory_barrier();
01395 }
01396
01397 if (!uhd_ctrl_request_first->payload_size && nb_byte_received) {
01398
01399 if (uhd_ctrl_request_first->callback_run == NULL
01400 || !uhd_ctrl_request_first->callback_run(
01401 USBHS_HostGetAddr(USBHS, bPipe),
01402 &uhd_ctrl_request_first->payload,
01403 &uhd_ctrl_request_first->payload_size)) {
01404
01405 goto uhd_ctrl_phase_data_in_end;
01406 }
01407
01408
01409 goto uhd_ctrl_receiv_in_read_data;
01410 }
01411
01412
01413 if ((uhd_ctrl_nb_trans == uhd_ctrl_request_first->req.wLength)
01414 || b_short_packet) {
01415
01416 uhd_ctrl_phase_data_in_end:
01417 USBH_HAL_OutZLP();
01418 return;
01419 }
01420
01421
01422 USBHS_HostEnablePipeIntType(USBHS, bPipe, USBHS_HSTPIPIER_RXINES);
01423
01424 USBHS_HostDisablePipeIntType(USBHS, bPipe, (USBHS_HSTPIPIDR_FIFOCONC | USBHS_HSTPIPIDR_PFREEZEC ));
01425 }
01426
01427
01428
01429
01430
01431 static void USBH_HAL_InZLP(void)
01432 {
01433 uhd_ctrl_request_phase = UHD_CTRL_REQ_PHASE_ZLP_IN;
01434 USBHS_HostSetToken(USBHS, 0, USBHS_HSTPIPCFG_PTOKEN_IN);
01435 USBHS_HostAckPipeIntType(USBHS, 0, (USBHS_HSTPIPICR_RXINIC | USBHS_HSTPIPICR_SHORTPACKETIC) );
01436
01437
01438 USBHS_HostEnablePipeIntType(USBHS, 0, USBHS_HSTPIPIER_RXINES);
01439
01440 USBHS_HostDisablePipeIntType(USBHS, 0, (USBHS_HSTPIPIDR_FIFOCONC | USBHS_HSTPIPIDR_PFREEZEC ));
01441 memory_sync();
01442 }
01443
01444
01445
01446
01447
01448 static void USBH_HAL_PhaseDataOut(void)
01449 {
01450 uint8_t *pEpData;
01451 uint8_t bPipe = 0;
01452 uint8_t ep_ctrl_size;
01453
01454 uhd_ctrl_request_phase = UHD_CTRL_REQ_PHASE_DATA_OUT;
01455
01456 if (uhd_ctrl_nb_trans == uhd_ctrl_request_first->req.wLength) {
01457
01458 USBH_HAL_InZLP();
01459 return;
01460 }
01461
01462 if (!uhd_ctrl_request_first->payload_size) {
01463
01464 if (uhd_ctrl_request_first->callback_run==NULL
01465 || !uhd_ctrl_request_first->callback_run(
01466 USBHS_HostGetAddr(USBHS, bPipe),
01467 &uhd_ctrl_request_first->payload,
01468 &uhd_ctrl_request_first->payload_size)) {
01469
01470 USBH_HAL_InZLP();
01471 return;
01472 }
01473 }
01474
01475 #ifdef USB_HOST_HUB_SUPPORT
01476
01477 #else
01478 ep_ctrl_size = USBHS_HostGetSize(USBHS, bPipe);
01479 #endif
01480
01481
01482 USBHS_HostSetToken(USBHS, bPipe, USBHS_HSTPIPCFG_PTOKEN_OUT);
01483
01484
01485 USBHS_HostAckPipeIntType(USBHS, bPipe, USBHS_HSTPIPICR_TXOUTIC);
01486 pEpData =(uint8_t*)((uint32_t*)USBHS_RAM_ADDR
01487 + (EPT_VIRTUAL_SIZE * bPipe));
01488 memory_sync();
01489 while ((uhd_ctrl_nb_trans < uhd_ctrl_request_first->req.wLength)
01490 && ep_ctrl_size && uhd_ctrl_request_first->payload_size) {
01491 *pEpData++ = *uhd_ctrl_request_first->payload++;
01492 memory_sync();
01493 uhd_ctrl_nb_trans++;
01494 ep_ctrl_size--;
01495 uhd_ctrl_request_first->payload_size--;
01496 memory_barrier();
01497 }
01498
01499 USBHS_HostEnablePipeIntType(USBHS, bPipe, USBHS_HSTPIPIER_TXOUTES);
01500 USBHS_HostDisablePipeIntType(USBHS, bPipe, (USBHS_HSTPIPIDR_FIFOCONC | USBHS_HSTPIPIDR_PFREEZEC ) );
01501
01502 }
01503
01504
01505
01506
01507
01508 static void USBH_HAL_OutZLP(void)
01509 {
01510 uint8_t bPipe = 0;
01511 uhd_ctrl_request_phase = UHD_CTRL_REQ_PHASE_ZLP_OUT;
01512 USBHS_HostSetToken(USBHS, bPipe, USBHS_HSTPIPCFG_PTOKEN_OUT);
01513
01514 USBHS_HostAckPipeIntType(USBHS, bPipe, USBHS_HSTPIPICR_TXOUTIC);
01515
01516 USBHS_HostEnablePipeIntType(USBHS, bPipe, USBHS_HSTPIPIER_TXOUTES);
01517
01518 USBHS_HostDisablePipeIntType(USBHS, bPipe, (USBHS_HSTPIPIDR_FIFOCONC | USBHS_HSTPIPIDR_PFREEZEC));
01519
01520 }
01521
01522
01523
01524
01525
01526
01527 static void USBH_HAL_ControlReqEnd(USBH_XfrStatus_t status)
01528 {
01529 uint8_t bPipe = 0;
01530 irqflags_t flags;
01531 uhd_callback_setup_end_t callback_end;
01532 struct uhd_ctrl_request_t *request_to_free;
01533 bool b_new_request;
01534
01535 uhd_ctrl_request_timeout = 0;
01536
01537
01538 callback_end = uhd_ctrl_request_first->callback_end;
01539 request_to_free = uhd_ctrl_request_first;
01540 flags = cpu_irq_save();
01541 uhd_ctrl_request_first = uhd_ctrl_request_first->next_request;
01542 b_new_request = (uhd_ctrl_request_first != NULL);
01543 cpu_irq_restore(flags);
01544 free(request_to_free);
01545
01546
01547 if (callback_end != NULL) {
01548 callback_end(USBHS_HostGetAddr(USBHS, bPipe), status, uhd_ctrl_nb_trans);
01549 }
01550
01551
01552 if (b_new_request) {
01553 USBH_HAL_PhaseControlSetup();
01554 }
01555 if (uhd_b_suspend_requested) {
01556
01557 uhd_b_suspend_requested = false;
01558 USBH_HAL_Suspend();
01559 }
01560 }
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570 static USBH_XfrStatus_t USBH_HAL_GetPipeError(uint8_t pipe)
01571 {
01572 uint32_t error = USBHS_HostGetErr(USBHS, pipe, (USBHS_HSTPIPERR_DATATGL |
01573 USBHS_HSTPIPERR_TIMEOUT |
01574 USBHS_HSTPIPERR_PID |
01575 USBHS_HSTPIPERR_DATAPID));
01576 USBHS_HostClearErr(USBHS, pipe, 0xFF);
01577 switch(error) {
01578 case USBHS_HSTPIPERR_DATATGL:
01579 return UHD_TRANS_DT_MISMATCH;
01580 case USBHS_HSTPIPERR_TIMEOUT:
01581 return UHD_TRANS_NOTRESPONDING;
01582 case USBHS_HSTPIPERR_DATAPID:
01583 case USBHS_HSTPIPERR_PID:
01584 default:
01585 return UHD_TRANS_PIDFAILURE;
01586 }
01587 }
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598 static uint8_t USBH_HAL_GetPipe(uint8_t Addr, uint8_t bEndpoint)
01599 {
01600 uint8_t pipe;
01601
01602
01603 for (pipe = 0; pipe < USBHS_EPT_NUM; pipe++) {
01604
01605 if (!USBHS_IsHostPipeEnable(USBHS, pipe)) {
01606 continue;
01607 }
01608 if (Addr != USBHS_HostGetAddr(USBHS,pipe)) {
01609 continue;
01610 }
01611 if (bEndpoint != USBHS_GetPipeEpAddr(USBHS, pipe)) {
01612 continue;
01613 }
01614 break;
01615 }
01616 return pipe;
01617 }
01618
01619 #ifdef UHD_PIPE_FIFO_SUPPORTED
01620
01621
01622
01623 static void USBH_HAL_PipeInReceived(uint8_t pipe)
01624 {
01625 USBH_PipeJob_t *pJob = &uhd_pipe_job[pipe - 1];
01626 uint32_t nb_data = 0, i;
01627 uint32_t nb_remain = pJob->buf_size - pJob->nb_trans;
01628 uint32_t pkt_size = USBHS_HostGetSize(USBHS, pipe);
01629 uint8_t *ptr_src =(uint8_t*)((uint32_t*)USBHS_RAM_ADDR
01630 + (EPT_VIRTUAL_SIZE * pipe));
01631 uint8_t *ptr_dst = &pJob->buf[pJob->nb_trans];
01632 bool b_full = false, b_short = false;
01633
01634 if (!pJob->busy) {
01635 return;
01636 }
01637
01638
01639 nb_data = USBHS_HostGetPipeByteCount(USBHS, pipe);
01640 if (nb_data < pkt_size) {
01641 b_short = true;
01642 }
01643
01644 if (nb_data > 0) {
01645 if (nb_data >= nb_remain) {
01646 nb_data = nb_remain;
01647 b_full = true;
01648 }
01649
01650 pJob->nb_trans += nb_data;
01651
01652 for (i = 0; i < nb_data; i++) {
01653 *ptr_dst++ = *ptr_src++;
01654 memory_sync();
01655 }
01656 }
01657
01658 USBHS_HostDisablePipeIntType(USBHS, pipe, USBHS_HSTPIPIDR_FIFOCONC);
01659
01660 if (b_full || b_short) {
01661 USBHS_HostEnablePipeIntType(USBHS, pipe, USBHS_HSTPIPIER_PFREEZES);
01662 USBHS_HostDisablePipeIntType(USBHS, pipe, (USBHS_HSTPIPIDR_SHORTPACKETIEC | USBHS_HSTPIPIDR_RXINEC) );
01663
01664
01665 USBHS_HostPipeIntDisable(USBHS, pipe);
01666
01667 USBHS_HostDisableInReq(USBHS, pipe);
01668
01669 USBH_HAL_PipeXfrEnd(pipe, UHD_TRANS_NOERROR);
01670 }
01671 }
01672
01673
01674
01675
01676 static void USBH_HAL_PipeOutReady(uint8_t pipe)
01677 {
01678 USBH_PipeJob_t *pJob = &uhd_pipe_job[pipe - 1];
01679 uint32_t pkt_size = USBHS_HostGetSize(USBHS, pipe);
01680 uint32_t nb_data = 0, i;
01681 uint32_t nb_remain;
01682 uint8_t *ptr_src;
01683 uint8_t *ptr_dst;
01684
01685 if (!pJob->busy) {
01686 return;
01687 }
01688
01689
01690 USBHS_HostAckPipeIntType(USBHS,pipe, USBHS_HSTPIPICR_TXOUTIC);
01691
01692 nb_remain = pJob->buf_size - pJob->nb_trans;
01693 nb_data = min(nb_remain, pkt_size);
01694
01695
01696 if (nb_data) {
01697
01698 ptr_dst =(uint8_t*)((uint32_t*)USBHS_RAM_ADDR
01699 + (EPT_VIRTUAL_SIZE * pipe));
01700 ptr_src = &pJob->buf[pJob->nb_trans];
01701
01702 pJob->nb_trans += nb_data;
01703
01704 memory_sync();
01705
01706 for (i = 0; i < nb_data; i++) {
01707 *ptr_dst++ = *ptr_src++;
01708 memory_sync();
01709 }
01710 }
01711
01712 USBHS_HostDisablePipeIntType(USBHS, pipe, USBHS_HSTPIPIDR_FIFOCONC);
01713
01714 if (nb_data < pkt_size) {
01715 pJob->b_shortpacket = false;
01716 }
01717
01718 if (pJob->nb_trans >= pJob->buf_size && !pJob->b_shortpacket) {
01719
01720 USBHS_HostDisablePipeIntType(USBHS, pipe, USBHS_HSTPIPIDR_TXOUTEC);
01721
01722 USBHS_HostEnablePipeIntType(USBHS, pipe, USBHS_HSTPIPIER_NBUSYBKES);
01723 return;
01724 }
01725 }
01726
01727 #endif // #ifdef UHD_PIPE_FIFO_SUPPORTED
01728
01729 #ifdef UHD_PIPE_DMA_SUPPORTED
01730
01731
01732
01733
01734
01735
01736 static void USBH_HAL_PipeXfrCmplt(uint8_t pipe)
01737 {
01738 uint32_t uhd_dma_ctrl = 0;
01739 USBH_PipeJob_t *pJob;
01740 uint32_t max_trans;
01741 uint32_t next_trans;
01742 irqflags_t flags;
01743 Usbhs *pUdp = USBHS;
01744 UsbhsHstdma *pUsbDma = &pUdp->USBHS_HSTDMA[pipe-1];
01745
01746
01747 pJob = &uhd_pipe_job[pipe - 1];
01748
01749 if (!pJob->busy) {
01750 return;
01751 }
01752
01753 if (pJob->nb_trans != pJob->buf_size) {
01754
01755 next_trans = pJob->buf_size - pJob->nb_trans;
01756 max_trans = UHD_PIPE_MAX_TRANS;
01757 if (USBHS_HostGetToken(USBHS, pipe) == USBHS_HSTPIPCFG_PTOKEN_IN) {
01758
01759 if ((256L*USBHS_HostGetSize(USBHS, pipe)) < UHD_PIPE_MAX_TRANS) {
01760 max_trans = 256L * USBHS_HostGetSize(USBHS, pipe);
01761 }
01762 }
01763 if (max_trans < next_trans) {
01764
01765
01766 next_trans = max_trans;
01767 }
01768
01769 if (next_trans == UHD_PIPE_MAX_TRANS) {
01770
01771 uhd_dma_ctrl = USBHS_HSTDMACONTROL_BUFF_LENGTH(0);
01772 } else {
01773 uhd_dma_ctrl = USBHS_HSTDMACONTROL_BUFF_LENGTH(next_trans);
01774 }
01775
01776 if (USBHS_HSTPIPCFG_PTOKEN_OUT == USBHS_HostGetToken(USBHS, pipe)) {
01777 if (0 != (next_trans % USBHS_HostGetSize(USBHS, pipe))) {
01778
01779
01780
01781 uhd_dma_ctrl |= USBHS_HSTDMACONTROL_END_B_EN;
01782
01783 pJob->b_shortpacket = false;
01784 }
01785 } else {
01786 if ((USBEndpointDescriptor_ISOCHRONOUS != USBHS_HostGetPipeType(USBHS, pipe))
01787 || ((int)next_trans <= USBHS_HostGetSize(USBHS, pipe))) {
01788
01789 uhd_dma_ctrl |= USBHS_HSTDMACONTROL_END_TR_IT
01790 | USBHS_HSTDMACONTROL_END_TR_EN;
01791 }
01792 }
01793
01794 USBHS_SetHostDmaBuffAdd(pUsbDma, (uint32_t) &pJob->buf[pJob->nb_trans]);
01795 uhd_dma_ctrl |= USBHS_HSTDMACONTROL_END_BUFFIT |
01796 USBHS_HSTDMACONTROL_CHANN_ENB;
01797
01798
01799
01800 flags = cpu_irq_save();
01801 if (!(USBHS_GetHostPipeDmaStatus(pUsbDma)
01802 & USBHS_HSTDMASTATUS_END_TR_ST)) {
01803 if (USBHS_HSTPIPCFG_PTOKEN_IN == USBHS_HostGetToken(USBHS, pipe)) {
01804 uint32_t pipe_size = USBHS_HostGetSize(USBHS, pipe);
01805 USBHS_HostInReq(USBHS, pipe, (next_trans + pipe_size-1) / pipe_size);
01806 }
01807 if (!pJob->b_periodic_start) {
01808 USBHS_HostDisablePipeIntType(USBHS, pipe, USBHS_HSTPIPIDR_NBUSYBKEC);
01809 USBHS_HostDisablePipeIntType(USBHS, pipe, USBHS_HSTPIPIDR_PFREEZEC);
01810 } else {
01811
01812 if (USBHS_IsHostPipeIntTypeEnable(USBHS, pipe, USBHS_HSTPIPIMR_NBUSYBKE)) {
01813 USBHS_HostDisablePipeIntType(USBHS, pipe, (USBHS_HSTPIPIDR_NBUSYBKEC | USBHS_HSTPIPIDR_PFREEZEC));
01814 } else {
01815
01816 }
01817 }
01818 SCB_CleanInvalidateDCache();
01819 USBHS_HostConfigureDma(pUsbDma, uhd_dma_ctrl);
01820 pJob->nb_trans += next_trans;
01821 cpu_irq_restore(flags);
01822 return;
01823 }
01824 cpu_irq_restore(flags);
01825
01826
01827
01828 pJob->buf_size = pJob->nb_trans;
01829 }
01830 if (USBHS_HSTPIPCFG_PTOKEN_OUT == USBHS_HostGetToken(USBHS, pipe)) {
01831 if (pJob->b_shortpacket) {
01832
01833
01834 USBHS_HostAckPipeIntType(USBHS, pipe, USBHS_HSTPIPICR_TXOUTIC);
01835 if (USBHS_HostGetIntTypeStatus(USBHS, pipe, USBHS_HSTPIPISR_RWALL)) {
01836
01837 USBHS_HostSetPipeIntType(USBHS, pipe, USBHS_HSTPIPIFR_TXOUTIS);
01838 }
01839 USBHS_HostEnablePipeIntType(USBHS, pipe, USBHS_HSTPIPIER_TXOUTES);
01840 return;
01841 }
01842 }
01843
01844 USBH_HAL_PipeXfrEnd(pipe, UHD_TRANS_NOERROR);
01845 }
01846
01847
01848
01849
01850
01851
01852
01853 static void USBH_HAL_PipeDmaInterrupt(uint8_t pipe)
01854 {
01855 USBH_PipeJob_t *pJob;
01856 uint32_t nb_remaining;
01857 Usbhs *pUdp = USBHS;
01858 UsbhsHstdma *pUsbDma = &pUdp->USBHS_HSTDMA[pipe-1];
01859
01860 SCB_CleanInvalidateDCache();
01861 if (USBHS_GetHostPipeDmaStatus(pUsbDma) & USBHS_HSTDMASTATUS_CHANN_ENB)
01862 {
01863 return;
01864 }
01865
01866 nb_remaining = ( (USBHS_GetHostPipeDmaStatus(pUsbDma) & USBHS_HSTDMASTATUS_BUFF_COUNT_Msk) >> USBHS_HSTDMASTATUS_BUFF_COUNT_Pos);
01867 memory_sync();
01868 if (nb_remaining) {
01869
01870 pJob = &uhd_pipe_job[pipe - 1];
01871
01872
01873
01874 pJob->nb_trans -= nb_remaining;
01875
01876
01877 pJob->buf_size = pJob->nb_trans;
01878 }
01879
01880 if (USBHS_HSTPIPCFG_PTOKEN_OUT == USBHS_HostGetToken(USBHS, pipe))
01881 {
01882
01883
01884 USBHS_HostEnablePipeIntType(USBHS, pipe, USBHS_HSTPIPIER_NBUSYBKES);
01885
01886
01887 if (USBHS_HostGetPipeType(USBHS, pipe) == USBHS_HSTPIPCFG_PTYPE_ISO)
01888 {
01889 USBH_HAL_PipeXfrEnd(pipe, UHD_TRANS_NOERROR);
01890 }
01891 }
01892 else
01893 {
01894 if (!USBHS_IsHostPipeIntTypeEnable(USBHS, pipe, USBHS_HSTPIPIMR_PFREEZE)) {
01895
01896
01897
01898
01899
01900 if (nb_remaining) {
01901
01902 USBHS_HostEnablePipeIntType(USBHS, pipe, USBHS_HSTPIPIER_PFREEZES);
01903 } else {
01904
01905 while (!USBHS_IsHostPipeIntTypeEnable(USBHS, pipe, USBHS_HSTPIPIMR_PFREEZE)) {
01906 }
01907 }
01908 }
01909
01910 USBH_HAL_PipeXfrCmplt(pipe);
01911 }
01912 }
01913 #endif // ifdef UHD_PIPE_DMA_SUPPORTED
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925 static void USBH_HAL_PipeInterrupt(uint8_t pipe)
01926 {
01927 uint32_t status = USBHS_HostGetIntTypeStatus(USBHS, pipe, 0xFFFFFFFF);
01928 uint32_t statusInt = status & USBHS_IsHostPipeIntTypeEnable(USBHS, pipe, 0xFFFFFFFF);
01929 #ifdef UHD_PIPE_FIFO_SUPPORTED
01930
01931 if (!Is_uhd_pipe_dma_supported(pipe)) {
01932
01933 if (statusInt & USBHS_HSTPIPISR_SHORTPACKETI)
01934 {
01935 USBHS_HostAckPipeIntType(USBHS, pipe, USBHS_HSTPIPICR_SHORTPACKETIC);
01936 USBH_HAL_PipeInReceived(pipe);
01937 return;
01938 }
01939
01940 if (statusInt & USBHS_HSTPIPIMR_RXINE ) {
01941 USBHS_HostAckPipeIntType(USBHS, pipe, USBHS_HSTPIPICR_RXINIC);
01942 USBH_HAL_PipeInReceived(pipe);
01943 return;
01944 }
01945
01946 if (statusInt & USBHS_HSTPIPISR_TXOUTI) {
01947 USBH_HAL_PipeOutReady(pipe);
01948 return;
01949 }
01950
01951 if (USBHS_IsHostPipeIntTypeEnable(USBHS, pipe, USBHS_HSTPIPIMR_NBUSYBKE)
01952 && (0==USBHS_HostGetNumOfBusyBank(USBHS, pipe)))
01953 {
01954 USBHS_HostEnablePipeIntType(USBHS, pipe, USBHS_HSTPIPIER_PFREEZES);
01955 USBHS_HostDisablePipeIntType(USBHS, pipe, USBHS_HSTPIPIDR_NBUSYBKEC );
01956
01957 USBHS_HostPipeIntDisable(USBHS, pipe);
01958
01959 USBHS_HostEnableAutoSw(USBHS, pipe);
01960
01961 USBH_HAL_PipeXfrEnd(pipe, UHD_TRANS_NOERROR);
01962 return;
01963 }
01964 if (status & USBHS_HSTPIPISR_RXSTALLDI) {
01965 USBHS_HostAckPipeIntType(USBHS, pipe, USBHS_HSTPIPICR_RXSTALLDIC);
01966 USBHS_HostEnablePipeIntType(USBHS, pipe, USBHS_HSTPIPIER_RSTDTS);
01967
01968 USBH_HAL_PipeAbort(pipe, UHD_TRANS_STALL);
01969 return;
01970 }
01971 if (status & USBHS_HSTPIPISR_PERRI) {
01972
01973 USBH_HAL_PipeAbort(pipe, USBH_HAL_GetPipeError(pipe));
01974 return;
01975 }
01976 assert(false);
01977 return;
01978 }
01979 #endif // UDD_EP_FIFO_SUPPORTED
01980
01981 #ifdef UHD_PIPE_DMA_SUPPORTED
01982
01983 if (USBHS_IsHostPipeIntTypeEnable(USBHS, pipe, USBHS_HSTPIPIMR_NBUSYBKE) && (0==USBHS_HostGetNumOfBusyBank(USBHS, pipe))) {
01984 USBHS_HostEnablePipeIntType(USBHS, pipe, USBHS_HSTPIPIER_PFREEZES);
01985 USBHS_HostDisablePipeIntType(USBHS, pipe, USBHS_HSTPIPIDR_NBUSYBKEC);
01986
01987 if (!(USBHS_HostGetPipeType(USBHS, pipe) == USBHS_HSTPIPCFG_PTYPE_ISO)) {
01988 USBH_HAL_PipeXfrEnd(pipe, UHD_TRANS_NOERROR);
01989 }
01990 return;
01991 }
01992 if (USBHS_HSTPIPIMR_TXOUTE & statusInt)
01993 {
01994 USBHS_HostDisablePipeIntType(USBHS, pipe, USBHS_HSTPIPIDR_TXOUTEC);
01995
01996
01997 USBHS_HostAckPipeIntType(USBHS, pipe, USBHS_HSTPIPICR_TXOUTIC);
01998 USBHS_HostDisablePipeIntType(USBHS, pipe, (USBHS_HSTPIPIDR_FIFOCONC | USBHS_HSTPIPIDR_PFREEZEC));
01999
02000 USBHS_HostEnablePipeIntType(USBHS, pipe, USBHS_HSTPIPIER_NBUSYBKES);
02001 return;
02002 }
02003 if (status & USBHS_HSTPIPISR_RXSTALLDI) {
02004 USBHS_HostAckPipeIntType(USBHS, pipe, USBHS_HSTPIPICR_RXSTALLDIC);
02005 USBHS_HostEnablePipeIntType(USBHS, pipe, USBHS_HSTPIPIER_RSTDTS);
02006 USBH_HAL_PipeAbort(pipe, UHD_TRANS_STALL);
02007 return;
02008 }
02009 if (status & USBHS_HSTPIPISR_PERRI) {
02010
02011 USBH_HAL_PipeAbort(pipe, USBH_HAL_GetPipeError(pipe));
02012 return;
02013 }
02014 assert(false);
02015 #endif // UHD_PIPE_DMA_SUPPORTED
02016 }
02017
02018
02019
02020
02021
02022
02023
02024
02025 static void USBH_HAL_PipeAbort(uint8_t pipe, USBH_XfrStatus_t status)
02026 {
02027 Usbhs *pUdp = USBHS;
02028 UsbhsHstdma *pUsbDma = &pUdp->USBHS_HSTDMA[pipe-1];
02029
02030 USBHS_HostPipeReset(USBHS, pipe);
02031
02032
02033 USBHS_HostEnableAutoSw(USBHS, pipe);
02034 USBHS_HostEnablePipeIntType(USBHS, pipe, (USBHS_HSTPIPIER_RXSTALLDES | USBHS_HSTPIPIER_PERRES) );
02035
02036 USBHS_HostDisablePipeIntType(USBHS, pipe, USBHS_HSTPIPIDR_TXOUTEC);
02037 #ifdef UHD_PIPE_DMA_SUPPORTED
02038 if (Is_uhd_pipe_dma_supported(pipe)) {
02039 USBHS_HostConfigureDma(pUsbDma, 0);
02040 }
02041 #endif
02042 USBH_HAL_PipeXfrEnd(pipe, status);
02043 }
02044
02045
02046
02047
02048
02049
02050
02051
02052 static void USBH_HAL_PipeXfrEnd(uint8_t pipe, USBH_XfrStatus_t status)
02053 {
02054 uint32_t dev_addr ,dev_ep;
02055 USBH_PipeJob_t *pJob;
02056
02057
02058 pJob = &uhd_pipe_job[pipe - 1];
02059 if (pJob->busy == false) {
02060 return;
02061 }
02062 pJob->busy = false;
02063 if (NULL == pJob->call_end) {
02064 return;
02065 }
02066 dev_addr = USBHS_HostGetAddr(USBHS, pipe);
02067 dev_ep = USBHS_GetPipeEpAddr(USBHS, pipe);
02068 pJob->call_end(dev_addr, dev_ep, status, pJob->nb_trans);
02069 }
02070
02071