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