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