usb_host_ehci.c 205 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018
  1. /*
  2. * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
  3. * Copyright 2016,2019 - 2020 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include <usb/include/usb_host_config.h>
  9. #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI > 0U))
  10. #include "usb_host.h"
  11. #include "usb_host_hci.h"
  12. #include "usb_host_devices.h"
  13. #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
  14. #include "usb_host_framework.h"
  15. #endif
  16. #include "fsl_device_registers.h"
  17. #include "usb_host_ehci.h"
  18. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT))
  19. #include <usb/phy/usb_phy.h>
  20. #endif
  21. #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
  22. #include "usb_host.h"
  23. #endif
  24. //#define USB_GINSTANCE_SIZE (sizeof(usb_host_ehci_instance_t))
  25. //#if defined(__ICCARM__) /* IAR Workbench */
  26. //#pragma location = "usb_heap_section"
  27. //static char ginstance_base[USB_GINSTANCE_SIZE];
  28. //#endif
  29. /*******************************************************************************
  30. * Definitions
  31. ******************************************************************************/
  32. #if defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM > 0U)
  33. #error The SOC does not suppoort dedicated RAM case.
  34. #endif
  35. #define USB_HOST_EHCI_BANDWIDTH_DELAY (3500U)
  36. #define USB_HOST_EHCI_BANDWIDTH_HUB_LS_SETUP (333U)
  37. #define USB_HOST_EHCI_BANDWIDTH_FRAME_TOTOAL_TIME (900U)
  38. #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
  39. #define USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH (18U)
  40. #define USB_HOST_EHCI_PORTSC_PTC_J_STATE (0x01U)
  41. #define USB_HOST_EHCI_PORTSC_PTC_K_STATE (0x02U)
  42. #define USB_HOST_EHCI_PORTSC_PTC_SE0_NAK (0x03U)
  43. #define USB_HOST_EHCI_PORTSC_PTC_PACKET (0x04U)
  44. #define USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_HS (0x05U)
  45. #define USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_FS (0x06U)
  46. #define USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_LS (0x07U)
  47. #endif
  48. /*******************************************************************************
  49. * Prototypes
  50. ******************************************************************************/
  51. /*!
  52. * @brief compute data bandwidth time.
  53. *
  54. * @param speed data speed.
  55. * @param pipeType data type.
  56. * @param direction data direction.
  57. * @param dataLength data length.
  58. *
  59. *@return time value.
  60. */
  61. static uint32_t USB_HostBandwidthComputeTime(uint8_t speed, uint8_t pipeType, uint8_t direction, uint32_t dataLength);
  62. /*!
  63. * @brief compute current allocated bandwidth when ehci work as full-speed or low-speed host.
  64. *
  65. * @param ehciInstance ehci instance pointer.
  66. * @param frameIndex frame index.
  67. * @param frameBandwidths return frame bandwidth data.
  68. */
  69. static void USB_HostBandwidthFslsHostComputeCurrent(usb_host_ehci_instance_t *ehciInstance,
  70. uint16_t frameIndex,
  71. uint16_t *frameBandwidth);
  72. /*!
  73. * @brief compute current hub's allocated FS/LS bandwidth when ehci work as hi-speed host.
  74. *
  75. * @param ehciInstance ehci instance pointer.
  76. * @param hubNumber hub address.
  77. * @param frameIndex frame index.
  78. * @param frameBandwidths return frame bandwidth data.
  79. */
  80. static void USB_HostBandwidthHsHostComputeCurrentFsls(usb_host_ehci_instance_t *ehciInstance,
  81. uint32_t hubNumber,
  82. uint16_t frameIndex,
  83. uint16_t frameBandwidths[8]);
  84. /*!
  85. * @brief compute current allocated HS bandwidth when ehci work as hi-speed host.
  86. *
  87. * @param ehciInstance ehci instance pointer.
  88. * @param frameIndex frame index.
  89. * @param frameBandwidths return frame bandwidth data.
  90. */
  91. static void USB_HostBandwidthHsHostComputeCurrentHsAll(usb_host_ehci_instance_t *ehciInstance,
  92. uint16_t frameIndex,
  93. uint16_t frameBandwidths[8]);
  94. /*!
  95. * @brief allocate HS bandwidth when host work as high-speed host.
  96. *
  97. * @param ehciInstance ehci instance pointer.
  98. * @param uframeInterval micro-frame interval.
  99. * @param timeData time for allocating.
  100. * @param uframe_index_out return start uframe index.
  101. *
  102. * @return kStatus_USB_Success or error codes.
  103. */
  104. static usb_status_t USB_HostBandwidthHsHostAllocateHsCommon(usb_host_ehci_instance_t *ehciInstance,
  105. uint16_t uframeInterval,
  106. uint16_t timeData,
  107. uint16_t *uframeIndexOut);
  108. /*!
  109. * @brief allocate HS interrupt bandwidth when host work as high-speed host.
  110. *
  111. * @param ehciInstance ehci instance pointer.
  112. * @param ehciPipePointer ehci pipe pointer.
  113. *
  114. * @return kStatus_USB_Success or error codes.
  115. */
  116. static usb_status_t USB_HostBandwidthHsHostAllocateInterrupt(usb_host_ehci_instance_t *ehciInstance,
  117. usb_host_ehci_pipe_t *ehciPipePointer);
  118. /*!
  119. * @brief allocate bandwidth when host work as full-speed or low-speed host.
  120. *
  121. * @param ehciInstance ehci instance pointer.
  122. * @param ehciPipePointer ehci pipe pointer.
  123. *
  124. * @return kStatus_USB_Success or error codes.
  125. */
  126. static usb_status_t USB_HostBandwidthFslsHostAllocate(usb_host_ehci_instance_t *ehciInstance,
  127. usb_host_ehci_pipe_t *ehciPipePointer);
  128. /*!
  129. * @brief get the 2 power value of uint8_t.
  130. *
  131. * @param value input uint8_t value.
  132. */
  133. static uint8_t USB_HostEhciGet2PowerValue(uint8_t value);
  134. /*!
  135. * @brief memory zero.
  136. *
  137. * @param buffer buffer pointer.
  138. * @param length buffer length.
  139. */
  140. static void USB_HostEhciZeroMem(uint32_t *buffer, uint32_t length);
  141. /*!
  142. * @brief host ehci delay.
  143. *
  144. * @param ehciIpBase ehci ip base address.
  145. * @param ms millisecond.
  146. */
  147. static void USB_HostEhciDelay(USBHS_Type *ehciIpBase, uint32_t ms);
  148. /*!
  149. * @brief host ehci start async schedule.
  150. *
  151. * @param ehciInstance ehci instance pointer.
  152. */
  153. static void USB_HostEhciStartAsync(usb_host_ehci_instance_t *ehciInstance);
  154. /*!
  155. * @brief host ehci stop async schedule.
  156. *
  157. * @param ehciInstance ehci instance pointer.
  158. */
  159. static void USB_HostEhciStopAsync(usb_host_ehci_instance_t *ehciInstance);
  160. /*!
  161. * @brief host ehci start periodic schedule.
  162. *
  163. * @param ehciInstance ehci instance pointer.
  164. */
  165. static void USB_HostEhciStartPeriodic(usb_host_ehci_instance_t *ehciInstance);
  166. /*!
  167. * @brief host ehci stop periodic schedule.
  168. *
  169. * @param ehciInstance ehci instance pointer.
  170. */
  171. static void USB_HostEhciStopPeriodic(usb_host_ehci_instance_t *ehciInstance);
  172. /*!
  173. * @brief initialize the qtd for one transfer.
  174. *
  175. * @param ehciInstance ehci instance pointer.
  176. * @param ehciPipePointer ehci pipe pointer.
  177. * @param transfer transfer information.
  178. *
  179. *@return kStatus_USB_Success or error codes.
  180. */
  181. static usb_status_t USB_HostEhciQhQtdListInit(usb_host_ehci_instance_t *ehciInstance,
  182. usb_host_ehci_pipe_t *ehciPipePointer,
  183. usb_host_transfer_t *transfer);
  184. /*!
  185. * @brief release the qtd list.
  186. *
  187. * @param ehciInstance ehci instance pointer.
  188. * @param ehciQtdStart qtd list start pointer.
  189. * @param ehciQtdEnd qtd list end pointer.
  190. *
  191. *@return the transfer's length.
  192. */
  193. static uint32_t USB_HostEhciQtdListRelease(usb_host_ehci_instance_t *ehciInstance,
  194. usb_host_ehci_qtd_t *ehciQtdStart,
  195. usb_host_ehci_qtd_t *ehciQtdEnd);
  196. /*!
  197. * @brief de-initialize qh's linking qtd list.
  198. * 1. remove qtd from qh; 2. remove transfer from qh; 3. release qtd; 4. transfer callback.
  199. *
  200. * @param ehciInstance ehci instance pointer.
  201. * @param ehciPipePointer ehci pipe.
  202. *
  203. *@return kStatus_USB_Success or error codes.
  204. */
  205. static usb_status_t USB_HostEhciQhQtdListDeinit(usb_host_ehci_instance_t *ehciInstance,
  206. usb_host_ehci_pipe_t *ehciPipePointer);
  207. /*!
  208. * @brief de-initialize transfer's linking qtd list.
  209. * 1. stop this qh schedule; 2. remove qtd from qh; 3. remove transfer from qh; 4. release qtd; 5. transfer callback; 6.
  210. *start this qh schedule.
  211. *
  212. * @param ehciInstance ehci instance pointer.
  213. * @param ehciPipePointer ehci pipe pointer.
  214. * @param transfer transfer information.
  215. *
  216. *@return kStatus_USB_Success or error codes.
  217. */
  218. static usb_status_t USB_HostEhciTransferQtdListDeinit(usb_host_ehci_instance_t *ehciInstance,
  219. usb_host_ehci_pipe_t *ehciPipePointer,
  220. usb_host_transfer_t *transfer);
  221. /*!
  222. * @brief initialize QH when opening one control, bulk or interrupt pipe.
  223. *
  224. * @param ehciInstance ehci instance pointer.
  225. * @param ehciPipePointer ehci pipe pointer.
  226. *
  227. * @return kStatus_USB_Success or error codes.
  228. */
  229. static usb_status_t USB_HostEhciQhInit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer);
  230. /*!
  231. * @brief de-initialize QH when closing one control, bulk or interrupt pipe.
  232. *
  233. * @param ehciInstance ehci instance pointer.
  234. * @param ehciPipePointer ehci pipe pointer.
  235. *
  236. * @return kStatus_USB_Success or error codes.
  237. */
  238. static usb_status_t USB_HostEhciQhDeinit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer);
  239. /*!
  240. * @brief add qh to one frame entry.
  241. *
  242. * @param ehciInstance ehci instance pointer.
  243. * @param entryPointerValue entry pointer value.
  244. * @param framePos frame index.
  245. * @param uframeInterval micro-frame interval.
  246. */
  247. static void USB_HostEhciAddQhToFrame(usb_host_ehci_instance_t *ehciInstance,
  248. uint32_t entryPointerValue,
  249. uint16_t framePos,
  250. uint16_t uframeInterval);
  251. /*!
  252. * @brief remove entry from frame list.
  253. *
  254. * @param ehciInstance ehci instance pointer.
  255. * @param entryPointerValue entry pointer value.
  256. * @param framePos frame index.
  257. */
  258. static void USB_HostEhciRemoveFromFrame(usb_host_ehci_instance_t *ehciInstance,
  259. uint32_t entryPointerValue,
  260. uint16_t framePos);
  261. #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
  262. /*!
  263. * @brief add sitd array to the frame list.
  264. *
  265. * @param ehciInstance ehci instance pointer.
  266. * @param entryPointerValue entry pointer value.
  267. * @param startEntryPointer sitd entry pointer.
  268. */
  269. static void USB_HostEhciLinkSitd(usb_host_ehci_instance_t *ehciInstance,
  270. usb_host_ehci_pipe_t *ehciPipePointer,
  271. void *startEntryPointer);
  272. /*!
  273. * @brief initialize sitd array for one transfer.
  274. *
  275. * @param ehciInstance ehci instance pointer.
  276. * @param ehciPipePointer ehci pipe pointer.
  277. * @param transfer transfer information.
  278. */
  279. static usb_status_t USB_HostEhciSitdArrayInit(usb_host_ehci_instance_t *ehciInstance,
  280. usb_host_ehci_pipe_t *ehciPipePointer,
  281. usb_host_transfer_t *transfer);
  282. /*!
  283. * @brief release sitd list.
  284. *
  285. * @param ehciInstance ehci instance pointer.
  286. * @param startSitdPointer start sitd pointer.
  287. * @param endSitdPointer end sitd pointer.
  288. *
  289. * @return transfer's result length.
  290. */
  291. static uint32_t USB_HostEhciSitdArrayRelease(usb_host_ehci_instance_t *ehciInstance,
  292. usb_host_ehci_sitd_t *startSitdPointer,
  293. usb_host_ehci_sitd_t *endSitdPointer);
  294. /*!
  295. * @brief de-initialize sitd list.
  296. * 1. remove transfer; 2. remove sitd from frame list and release sitd; 3. transfer callback
  297. *
  298. * @param ehciInstance ehci instance pointer.
  299. * @param ehciPipePointer ehci pipe pointer.
  300. *
  301. * @return kStatus_USB_Success or error codes.
  302. */
  303. static usb_status_t USB_HostEhciSitdArrayDeinit(usb_host_ehci_instance_t *ehciInstance,
  304. usb_host_ehci_pipe_t *ehciPipePointer);
  305. #endif /* USB_HOST_CONFIG_EHCI_MAX_SITD */
  306. #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
  307. /*!
  308. * @brief compute the frame index when inserting itd.
  309. *
  310. * @param ehciInstance ehci instance pointer.
  311. * @param lastLinkUframe last inserted micro-frame.
  312. * @param startUframe start micro-frame.
  313. * @param uframeInterval micro-frame interval.
  314. *
  315. * @return frame index
  316. */
  317. static uint32_t USB_HostEhciGetItdLinkFrame(usb_host_ehci_instance_t *ehciInstance,
  318. uint32_t lastLinkUframe,
  319. uint16_t startUframe,
  320. uint16_t uframeInterval);
  321. /*!
  322. * @brief initialize itd list for one transfer.
  323. * 1. initialize itd list; 2. insert itd to frame list.
  324. *
  325. * @param ehciInstance ehci instance pointer.
  326. * @param ehciPipePointer ehci pipe pointer.
  327. * @param transfer transfer information.
  328. *
  329. * @return kStatus_USB_Success or error codes.
  330. */
  331. static usb_status_t USB_HostEhciItdArrayInit(usb_host_ehci_instance_t *ehciInstance,
  332. usb_host_ehci_pipe_t *ehciPipePointer,
  333. usb_host_transfer_t *transfer);
  334. /*!
  335. * @brief release itd list.
  336. *
  337. * @param ehciInstance ehci instance pointer.
  338. * @param startItdPointer start itd pointer.
  339. * @param endItdPointer end itd pointer.
  340. *
  341. * @return transfer's result length.
  342. */
  343. static uint32_t USB_HostEhciItdArrayRelease(usb_host_ehci_instance_t *ehciInstance,
  344. usb_host_ehci_itd_t *startItdPointer,
  345. usb_host_ehci_itd_t *endItdPointer);
  346. /*!
  347. * @brief de-initialize itd list.
  348. * 1. remove transfer; 2. remove itd from frame list and release itd; 3. transfer callback
  349. *
  350. * @param ehciInstance ehci instance pointer.
  351. * @param ehciPipePointer ehci pipe pointer.
  352. *
  353. * @return kStatus_USB_Success or error codes.
  354. */
  355. static usb_status_t USB_HostEhciItdArrayDeinit(usb_host_ehci_instance_t *ehciInstance,
  356. usb_host_ehci_pipe_t *ehciPipePointer);
  357. #endif /* USB_HOST_CONFIG_EHCI_MAX_ITD */
  358. /*!
  359. * @brief open control or bulk pipe.
  360. *
  361. * @param ehciInstance ehci instance pointer.
  362. * @param ehciPipePointer ehci pipe pointer.
  363. *
  364. * @return kStatus_USB_Success or error codes.
  365. */
  366. static usb_status_t USB_HostEhciOpenControlBulk(usb_host_ehci_instance_t *ehciInstance,
  367. usb_host_ehci_pipe_t *ehciPipePointer);
  368. /*!
  369. * @brief close control or bulk pipe.
  370. *
  371. * @param ehciInstance ehci instance pointer.
  372. * @param ehciPipePointer ehci pipe pointer.
  373. *
  374. * @return kStatus_USB_Success or error codes.
  375. */
  376. static usb_status_t USB_HostEhciCloseControlBulk(usb_host_ehci_instance_t *ehciInstance,
  377. usb_host_ehci_pipe_t *ehciPipePointer);
  378. /*!
  379. * @brief open interrupt pipe.
  380. *
  381. * @param ehciInstance ehci instance pointer.
  382. * @param ehciPipePointer ehci pipe pointer.
  383. *
  384. * @return kStatus_USB_Success or error codes.
  385. */
  386. static usb_status_t USB_HostEhciOpenInterrupt(usb_host_ehci_instance_t *ehciInstance,
  387. usb_host_ehci_pipe_t *ehciPipePointer);
  388. /*!
  389. * @brief close interrupt pipe.
  390. *
  391. * @param ehciInstance ehci instance pointer.
  392. * @param ehciPipePointer ehci pipe pointer.
  393. *
  394. * @return kStatus_USB_Success or error codes.
  395. */
  396. static usb_status_t USB_HostEhciCloseInterrupt(usb_host_ehci_instance_t *ehciInstance,
  397. usb_host_ehci_pipe_t *ehciPipePointer);
  398. #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
  399. ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
  400. /*!
  401. * @brief open iso pipe.
  402. *
  403. * @param ehciInstance ehci instance pointer.
  404. * @param ehciPipePointer ehci pipe pointer.
  405. *
  406. * @return kStatus_USB_Success or error codes.
  407. */
  408. static usb_status_t USB_HostEhciOpenIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer);
  409. /*!
  410. * @brief close iso pipe.
  411. *
  412. * @param ehciInstance ehci instance pointer.
  413. * @param ehciPipePointer ehci pipe pointer.
  414. *
  415. * @return kStatus_USB_Success or error codes.
  416. */
  417. static usb_status_t USB_HostEhciCloseIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer);
  418. /*!
  419. * @brief allocate HS iso bandwidth when host work as high-speed host.
  420. *
  421. * @param ehciInstance ehci instance pointer.
  422. * @param ehciPipePointer ehci pipe pointer.
  423. *
  424. * @return kStatus_USB_Success or error codes.
  425. */
  426. static usb_status_t USB_HostBandwidthHsHostAllocateIso(usb_host_ehci_instance_t *ehciInstance,
  427. usb_host_ehci_pipe_t *ehciPipePointer);
  428. #endif
  429. /*!
  430. * @brief reset ehci ip.
  431. *
  432. * @param ehciInstance ehci instance pointer.
  433. *
  434. * @return kStatus_USB_Success or error codes.
  435. */
  436. static usb_status_t USB_HostEhciResetIP(usb_host_ehci_instance_t *ehciInstance);
  437. /*!
  438. * @brief start ehci ip.
  439. *
  440. * @param ehciInstance ehci instance pointer.
  441. *
  442. * @return kStatus_USB_Success or error codes.
  443. */
  444. static usb_status_t USB_HostEhciStartIP(usb_host_ehci_instance_t *ehciInstance);
  445. /*!
  446. * @brief cancel pipe's transfers.
  447. *
  448. * @param ehciInstance ehci instance pointer.
  449. * @param ehciPipePointer ehci pipe pointer.
  450. * @param transfer the canceling transfer.
  451. *
  452. * @return kStatus_USB_Success or error codes.
  453. */
  454. static usb_status_t USB_HostEhciCancelPipe(usb_host_ehci_instance_t *ehciInstance,
  455. usb_host_ehci_pipe_t *ehciPipePointer,
  456. usb_host_transfer_t *transfer);
  457. /*!
  458. * @brief control ehci bus.
  459. *
  460. * @param ehciInstance ehci instance pointer.
  461. * @param bus_control control code.
  462. *
  463. * @return kStatus_USB_Success or error codes.
  464. */
  465. static usb_status_t USB_HostEhciControlBus(usb_host_ehci_instance_t *ehciInstance, uint8_t busControl);
  466. /*!
  467. * @brief ehci transaction done process function.
  468. *
  469. * @param ehciInstance ehci instance pointer.
  470. */
  471. void USB_HostEhciTransactionDone(usb_host_ehci_instance_t *ehciInstance);
  472. /*!
  473. * @brief ehci port change interrupt process function.
  474. *
  475. * @param ehciInstance ehci instance pointer.
  476. */
  477. static void USB_HostEhciPortChange(usb_host_ehci_instance_t *ehciInstance);
  478. /*!
  479. * @brief ehci timer0 interrupt process function.
  480. * cancel control/bulk transfer that time out.
  481. *
  482. * @param ehciInstance ehci instance pointer.
  483. */
  484. static void USB_HostEhciTimer0(usb_host_ehci_instance_t *ehciInstance);
  485. #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
  486. /*!
  487. * @brief ehci timer1 interrupt process function.
  488. * cancel control/bulk transfer that time out.
  489. *
  490. * @param ehciInstance ehci instance pointer.
  491. */
  492. static void USB_HostEhciTimer1(usb_host_ehci_instance_t *ehciInstance);
  493. #endif
  494. #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
  495. /*!
  496. * @brief suspend bus.
  497. *
  498. * @param ehciInstance ehci instance pointer.
  499. */
  500. static void USB_HostEhciSuspendBus(usb_host_ehci_instance_t *ehciInstance);
  501. /*!
  502. * @brief resume bus.
  503. *
  504. * @param ehciInstance ehci instance pointer.
  505. */
  506. static void USB_HostEhciResumeBus(usb_host_ehci_instance_t *ehciInstance);
  507. extern usb_status_t USB_HostStandardSetGetDescriptor(usb_host_device_instance_t *deviceInstance,
  508. usb_host_transfer_t *transfer,
  509. void *param);
  510. #endif /* USB_HOST_CONFIG_COMPLIANCE_TEST */
  511. /*******************************************************************************
  512. * Variables
  513. ******************************************************************************/
  514. /* EHCI controller driver instances. */
  515. #if (USB_HOST_CONFIG_EHCI == 1U)
  516. USB_RAM_ADDRESS_ALIGNMENT(4096)
  517. USB_CONTROLLER_DATA static uint8_t s_UsbHostEhciFrameList1[USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 4];
  518. static uint8_t usbHostEhciFramListStatus[1] = {0};
  519. USB_RAM_ADDRESS_ALIGNMENT(64) USB_CONTROLLER_DATA static usb_host_ehci_data_t s_UsbHostEhciData1;
  520. #elif (USB_HOST_CONFIG_EHCI == 2U)
  521. USB_RAM_ADDRESS_ALIGNMENT(4096)
  522. USB_CONTROLLER_DATA static uint8_t s_UsbHostEhciFrameList1[USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 4];
  523. USB_RAM_ADDRESS_ALIGNMENT(4096)
  524. USB_CONTROLLER_DATA static uint8_t s_UsbHostEhciFrameList2[USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 4];
  525. static uint8_t usbHostEhciFramListStatus[2] = {0, 0};
  526. USB_RAM_ADDRESS_ALIGNMENT(64) USB_CONTROLLER_DATA static usb_host_ehci_data_t s_UsbHostEhciData1;
  527. USB_RAM_ADDRESS_ALIGNMENT(64) USB_CONTROLLER_DATA static usb_host_ehci_data_t s_UsbHostEhciData2;
  528. #else
  529. #error "Please increase the instance count."
  530. #endif
  531. #define USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE (1024U)
  532. #define USB_HOST_EHCI_MAX_MICRFRAME_VALUE ((USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE << 3U) - 1U)
  533. static uint8_t s_SlotMaxBandwidth[8] = {125, 125, 125, 125, 125, 125, 50, 0};
  534. static uint8_t s_SlotMaxBandwidthHs[8] = {100, 100, 100, 100, 100, 100, 100, 100};
  535. /*******************************************************************************
  536. * Code
  537. ******************************************************************************/
  538. /*!
  539. * @brief EHCI NC get USB NC bass address.
  540. *
  541. * This function is used to get USB NC bass address.
  542. *
  543. * @param[in] controllerId EHCI controller ID; See the #usb_controller_index_t.
  544. *
  545. * @retval USB NC bass address.
  546. */
  547. #if (defined(USB_HOST_CONFIG_LOW_POWER_MODE) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
  548. #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
  549. static void *USB_EhciNCGetBase(uint8_t controllerId)
  550. {
  551. void *usbNCBase = NULL;
  552. #if ((defined FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
  553. uint32_t instance;
  554. uint32_t newinstance = 0;
  555. uint32_t usbnc_base_temp[] = USBNC_BASE_ADDRS;
  556. uint32_t usbnc_base[] = USBNC_BASE_ADDRS;
  557. if (controllerId < (uint8_t)kUSB_ControllerEhci0)
  558. {
  559. return NULL;
  560. }
  561. controllerId = controllerId - (uint8_t)kUSB_ControllerEhci0;
  562. for (instance = 0; instance < (sizeof(usbnc_base_temp) / sizeof(usbnc_base_temp[0])); instance++)
  563. {
  564. if (usbnc_base_temp[instance] != 0U)
  565. {
  566. usbnc_base[newinstance++] = usbnc_base_temp[instance];
  567. }
  568. }
  569. if (controllerId > newinstance)
  570. {
  571. return NULL;
  572. }
  573. usbNCBase = (void *)(uint8_t *)usbnc_base[controllerId];
  574. #endif
  575. return usbNCBase;
  576. }
  577. #endif
  578. #endif
  579. #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
  580. usb_status_t USB_HostEhciTestSetMode(usb_host_ehci_instance_t *ehciInstance, uint32_t testMode)
  581. {
  582. uint32_t ehciPortSC;
  583. ehciPortSC = ehciInstance->ehciIpBase->PORTSC1;
  584. ehciPortSC &= ~((uint32_t)USBHS_PORTSC1_PTC_MASK); /* clear test mode bits */
  585. ehciPortSC |= (testMode << USBHS_PORTSC1_PTC_SHIFT); /* set test mode bits */
  586. ehciInstance->ehciIpBase->PORTSC1 = ehciPortSC;
  587. return kStatus_USB_Success;
  588. }
  589. static void USB_HostEhciTestSuspendResume(usb_host_ehci_instance_t *ehciInstance)
  590. {
  591. uint8_t timeCount;
  592. timeCount = 15; /* 15s */
  593. while (timeCount--)
  594. {
  595. USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
  596. }
  597. USB_HostEhciSuspendBus(ehciInstance);
  598. timeCount = 15; /* 15s */
  599. while (timeCount--)
  600. {
  601. USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
  602. }
  603. USB_HostEhciResumeBus(ehciInstance);
  604. }
  605. static void USB_HostEhciTestCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
  606. {
  607. USB_HostFreeTransfer(param, transfer);
  608. }
  609. static void USB_HostEhciTestSingleStepGetDeviceDesc(usb_host_ehci_instance_t *ehciInstance,
  610. usb_device_handle deviceHandle)
  611. {
  612. usb_host_process_descriptor_param_t getDescriptorParam;
  613. usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
  614. usb_host_transfer_t *transfer;
  615. uint8_t timeCount;
  616. /* disable periodic shedule */
  617. USB_HostEhciStopPeriodic(ehciInstance);
  618. timeCount = 15; /* 15s */
  619. while (timeCount--)
  620. {
  621. USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
  622. }
  623. /* malloc one transfer */
  624. if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success)
  625. {
  626. #ifdef HOST_ECHO
  627. usb_echo("allocate transfer error\r\n");
  628. #endif
  629. return;
  630. }
  631. getDescriptorParam.descriptorLength = sizeof(usb_descriptor_device_t);
  632. getDescriptorParam.descriptorLength = 18;
  633. getDescriptorParam.descriptorBuffer = (uint8_t *)&deviceInstance->deviceDescriptor;
  634. getDescriptorParam.descriptorType = USB_DESCRIPTOR_TYPE_DEVICE;
  635. getDescriptorParam.descriptorIndex = 0;
  636. getDescriptorParam.languageId = 0;
  637. transfer->callbackFn = USB_HostEhciTestCallback;
  638. transfer->callbackParam = ehciInstance->hostHandle;
  639. transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_DIR_IN;
  640. transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
  641. transfer->setupPacket->wIndex = 0;
  642. transfer->setupPacket->wLength = 0;
  643. transfer->setupPacket->wValue = 0;
  644. USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam);
  645. }
  646. static usb_status_t USB_HostEhciSingleStepQtdListInit(usb_host_ehci_instance_t *ehciInstance,
  647. usb_host_ehci_pipe_t *ehciPipePointer,
  648. usb_host_transfer_t *transfer,
  649. uint8_t setupPhase)
  650. {
  651. volatile usb_host_ehci_qh_t *vltQhPointer;
  652. usb_host_ehci_qtd_t *qtdPointer = NULL;
  653. volatile uint32_t *entryPointer;
  654. uint32_t qtdNumber;
  655. uint32_t dataLength;
  656. uint32_t dataAddress;
  657. uint8_t index;
  658. /* compute the qtd number */
  659. qtdNumber = 1;
  660. vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
  661. /* get qtd list */
  662. USB_HostEhciLock();
  663. if (qtdNumber <= ehciInstance->ehciQtdNumber)
  664. {
  665. ehciInstance->ehciQtdNumber -= qtdNumber;
  666. qtdPointer = NULL;
  667. do
  668. {
  669. if (qtdPointer != NULL)
  670. {
  671. qtdPointer->nextQtdPointer = (uint32_t)ehciInstance->ehciQtdHead;
  672. }
  673. qtdPointer = ehciInstance->ehciQtdHead;
  674. ehciInstance->ehciQtdHead = (usb_host_ehci_qtd_t *)qtdPointer->nextQtdPointer;
  675. qtdPointer->nextQtdPointer = 0;
  676. } while (--qtdNumber);
  677. }
  678. else
  679. {
  680. USB_HostEhciUnlock();
  681. return kStatus_USB_Error;
  682. }
  683. USB_HostEhciUnlock();
  684. /* int qTD */
  685. if (setupPhase == 1) /* setup transaction qtd init */
  686. {
  687. qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
  688. /* dt: need set; ioc: 0; C_Page: 0; PID Code: SETUP; Status: Active */
  689. qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0;
  690. qtdPointer->transferResults[0] =
  691. ((0x00000000 << EHCI_HOST_QTD_DT_SHIFT) | (8 << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
  692. (EHCI_HOST_PID_SETUP << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
  693. dataAddress = (uint32_t)(transfer->setupPacket);
  694. qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
  695. /* set buffer pointer no matter data length */
  696. for (index = 0; index < 4; ++index)
  697. {
  698. qtdPointer->bufferPointers[index] = ((dataAddress + (index + 1) * 4 * 1024) & 0xFFFFF000);
  699. }
  700. }
  701. else if (setupPhase == 2) /* data transaction qtd */
  702. {
  703. dataLength = transfer->transferLength;
  704. if (dataLength != 0)
  705. {
  706. qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
  707. /* dt: need set; ioc: 0; C_Page: 0; PID Code: IN/OUT; Status: Active */
  708. qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0;
  709. qtdPointer->transferResults[0] =
  710. ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (dataLength << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
  711. (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
  712. dataAddress = (uint32_t)(transfer->transferBuffer);
  713. qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
  714. /* set buffer pointer no matter data length */
  715. for (index = 0; index < 4; ++index)
  716. {
  717. qtdPointer->bufferPointers[index] = ((dataAddress + (index + 1) * 4 * 1024) & 0xFFFFF000);
  718. }
  719. }
  720. }
  721. else if (setupPhase == 3)
  722. {
  723. /* status transaction qtd */
  724. qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
  725. /* dt: dont care; ioc: 1; C_Page: 0; PID Code: IN/OUT; Status: Active */
  726. qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0;
  727. qtdPointer->transferResults[0] =
  728. ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) |
  729. (EHCI_HOST_QTD_IOC_MASK) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
  730. qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE;
  731. }
  732. qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE;
  733. qtdPointer->transferResults[0] |= EHCI_HOST_QTD_IOC_MASK; /* set IOC */
  734. /* save qtd to transfer */
  735. transfer->union1.unitHead = (uint32_t)qtdPointer;
  736. transfer->union2.unitTail = (uint32_t)qtdPointer;
  737. /* link transfer to qh */
  738. transfer->next = NULL;
  739. if (vltQhPointer->ehciTransferHead == NULL)
  740. {
  741. transfer->next = NULL;
  742. vltQhPointer->ehciTransferHead = vltQhPointer->ehciTransferTail = transfer;
  743. }
  744. else
  745. {
  746. transfer->next = NULL;
  747. vltQhPointer->ehciTransferTail->next = transfer;
  748. vltQhPointer->ehciTransferTail = transfer;
  749. }
  750. USB_HostEhciLock();
  751. /* link qtd to qh (link to end) */
  752. entryPointer = &(vltQhPointer->nextQtdPointer);
  753. dataAddress = *entryPointer; /* dataAddress variable means entry value here */
  754. while ((dataAddress) && (!(dataAddress & EHCI_HOST_T_INVALID_VALUE)))
  755. {
  756. entryPointer = (volatile uint32_t *)dataAddress;
  757. dataAddress = *entryPointer;
  758. }
  759. *entryPointer = (uint32_t)qtdPointer;
  760. USB_HostEhciUnlock();
  761. USB_HostEhciStartAsync(ehciInstance);
  762. return kStatus_USB_Success;
  763. }
  764. static void USB_HostEhciTestSingleStepGetDeviceDescData(usb_host_ehci_instance_t *ehciInstance,
  765. usb_device_handle deviceHandle)
  766. {
  767. static uint8_t buffer[USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH];
  768. usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
  769. usb_host_transfer_t *transfer;
  770. uint8_t timeCount;
  771. USB_HostEhciStopPeriodic(ehciInstance);
  772. if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success)
  773. {
  774. return;
  775. }
  776. transfer->callbackFn = USB_HostEhciTestCallback;
  777. transfer->callbackParam = ehciInstance->hostHandle;
  778. transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_DIR_IN;
  779. transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
  780. transfer->setupPacket->wLength = USB_SHORT_TO_LITTLE_ENDIAN(USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH);
  781. transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN((uint16_t)((uint16_t)USB_DESCRIPTOR_TYPE_DEVICE << 8));
  782. transfer->setupPacket->wIndex = 0;
  783. USB_HostEhciSingleStepQtdListInit(ehciInstance, (usb_host_ehci_pipe_t *)(deviceInstance->controlPipe), transfer, 1);
  784. timeCount = 15; /* 15s */
  785. while (timeCount--)
  786. {
  787. USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
  788. }
  789. if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success)
  790. {
  791. return;
  792. }
  793. transfer->callbackFn = USB_HostEhciTestCallback;
  794. transfer->callbackParam = ehciInstance->hostHandle;
  795. transfer->transferBuffer = buffer;
  796. transfer->transferLength = USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH;
  797. USB_HostEhciSingleStepQtdListInit(ehciInstance, (usb_host_ehci_pipe_t *)(deviceInstance->controlPipe), transfer, 2);
  798. if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success)
  799. {
  800. return;
  801. }
  802. transfer->callbackFn = USB_HostEhciTestCallback;
  803. transfer->callbackParam = ehciInstance->hostHandle;
  804. transfer->transferBuffer = NULL;
  805. transfer->transferLength = 0;
  806. USB_HostEhciSingleStepQtdListInit(ehciInstance, (usb_host_ehci_pipe_t *)(deviceInstance->controlPipe), transfer, 3);
  807. timeCount = 15; /* 15s */
  808. while (timeCount--)
  809. {
  810. USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
  811. }
  812. usb_echo("test_single_step_get_dev_desc_data finished\r\n");
  813. return;
  814. }
  815. static void USB_HostEhciTestModeInit(usb_device_handle deviceHandle)
  816. {
  817. uint32_t productId;
  818. usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
  819. usb_host_ehci_instance_t *ehciInstance =
  820. (usb_host_ehci_instance_t *)(((usb_host_instance_t *)(deviceInstance->hostHandle))->controllerHandle);
  821. USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDevicePID, &productId);
  822. usb_echo("usb host ehci test mode init product id:0x%x\r\n", productId);
  823. switch (productId)
  824. {
  825. case 0x0101U:
  826. USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_SE0_NAK);
  827. break;
  828. case 0x0102U:
  829. USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_J_STATE);
  830. break;
  831. case 0x0103U:
  832. USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_K_STATE);
  833. break;
  834. case 0x0104U:
  835. USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_PACKET);
  836. break;
  837. case 0x0105U:
  838. usb_echo("set test mode FORCE_ENALBE_HS\r\n");
  839. USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_HS);
  840. break;
  841. case 0x0106U:
  842. USB_HostEhciTestSuspendResume(ehciInstance);
  843. break;
  844. case 0x0107U:
  845. usb_echo("start test SINGLE_STEP_GET_DEV_DESC\r\n");
  846. USB_HostEhciTestSingleStepGetDeviceDesc(ehciInstance, deviceHandle);
  847. break;
  848. case 0x0108U:
  849. usb_echo("start test SINGLE_STEP_GET_DEV_DESC_DATA\r\n");
  850. USB_HostEhciTestSingleStepGetDeviceDescData(ehciInstance, deviceHandle);
  851. break;
  852. default:
  853. /*no action */
  854. break;
  855. }
  856. return;
  857. }
  858. static void USB_HostEhciSuspendBus(usb_host_ehci_instance_t *ehciInstance)
  859. {
  860. uint32_t ehciPortSC;
  861. USB_HostEhciLock();
  862. ehciPortSC = ehciInstance->ehciIpBase->PORTSC1;
  863. if (ehciPortSC & USBHS_PORTSC1_PE_MASK)
  864. {
  865. ehciPortSC = ehciInstance->ehciIpBase->PORTSC1;
  866. ehciPortSC &= (uint32_t)(~EHCI_PORTSC1_W1_BITS);
  867. ehciInstance->ehciIpBase->PORTSC1 = (ehciPortSC | USBHS_PORTSC1_SUSP_MASK);
  868. }
  869. USB_HostEhciUnlock();
  870. }
  871. static void USB_HostEhciResumeBus(usb_host_ehci_instance_t *ehciInstance)
  872. {
  873. uint32_t ehciPortSC;
  874. USB_HostEhciLock();
  875. /* Resume port */
  876. ehciPortSC = ehciInstance->ehciIpBase->PORTSC1;
  877. if (ehciPortSC & USBHS_PORTSC1_PE_MASK)
  878. {
  879. ehciPortSC &= (uint32_t)(~EHCI_PORTSC1_W1_BITS);
  880. ehciInstance->ehciIpBase->PORTSC1 = (ehciPortSC | USBHS_PORTSC1_FPR_MASK);
  881. }
  882. USB_HostEhciUnlock();
  883. }
  884. #endif
  885. static uint32_t USB_HostBandwidthComputeTime(uint8_t speed, uint8_t pipeType, uint8_t direction, uint32_t dataLength)
  886. {
  887. uint32_t result = (3167U + ((1000U * dataLength) * 7U * 8U / 6U)) / 1000U;
  888. if (pipeType == USB_ENDPOINT_ISOCHRONOUS) /* iso */
  889. {
  890. if (speed == USB_SPEED_HIGH)
  891. {
  892. result = 38U * 8U * 2083U + 2083U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
  893. }
  894. else if (speed == USB_SPEED_FULL)
  895. {
  896. if (direction == USB_IN)
  897. {
  898. result = 7268000U + 83540U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
  899. }
  900. else
  901. {
  902. result = 6265000U + 83540U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
  903. }
  904. }
  905. else
  906. {
  907. /*no action*/
  908. }
  909. }
  910. else /* interrupt */
  911. {
  912. if (speed == USB_SPEED_HIGH)
  913. {
  914. result = 55U * 8U * 2083U + 2083U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
  915. }
  916. else if (speed == USB_SPEED_FULL)
  917. {
  918. result = 9107000U + 83540U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
  919. }
  920. else if (speed == USB_SPEED_LOW)
  921. {
  922. if (direction == USB_IN)
  923. {
  924. result = 64060000U + 2000U * USB_HOST_EHCI_BANDWIDTH_HUB_LS_SETUP + 676670U * result +
  925. USB_HOST_EHCI_BANDWIDTH_DELAY;
  926. }
  927. else
  928. {
  929. result = 6265000U + 83540U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
  930. }
  931. }
  932. else
  933. {
  934. /*no action*/
  935. }
  936. }
  937. result /= 1000000U;
  938. if (result == 0U)
  939. {
  940. result = 1U;
  941. }
  942. return result;
  943. }
  944. static void USB_HostBandwidthFslsHostComputeCurrent(usb_host_ehci_instance_t *ehciInstance,
  945. uint16_t frameIndex,
  946. uint16_t *frameBandwidth)
  947. {
  948. usb_host_ehci_pipe_t *ehciPipePointer;
  949. void *temp;
  950. /* clear the bandwidth */
  951. *frameBandwidth = 0;
  952. ehciPipePointer = ehciInstance->ehciRunningPipeList;
  953. while (ehciPipePointer != NULL)
  954. {
  955. /* only compute iso and interrupt pipe */
  956. if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
  957. (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT))
  958. {
  959. /* does pipe allocate bandwidth in frameIndex frame? note: interval is power of 2. */
  960. if ((frameIndex >= ehciPipePointer->startFrame) &&
  961. (0U == ((uint32_t)((uint32_t)frameIndex - ehciPipePointer->startFrame) &
  962. ((uint32_t)ehciPipePointer->pipeCommon.interval - 1U))))
  963. {
  964. *frameBandwidth += ehciPipePointer->dataTime;
  965. }
  966. }
  967. temp = (void *)ehciPipePointer->pipeCommon.next;
  968. ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
  969. }
  970. }
  971. static void USB_HostBandwidthHsHostComputeCurrentFsls(usb_host_ehci_instance_t *ehciInstance,
  972. uint32_t hubNumber,
  973. uint16_t frameIndex,
  974. uint16_t frameBandwidths[8])
  975. {
  976. usb_host_ehci_pipe_t *ehciPipePointer;
  977. uint8_t index;
  978. uint32_t deviceInfo = 0U;
  979. void *temp;
  980. for (index = 0; index < 8U; ++index)
  981. {
  982. frameBandwidths[index] = 0;
  983. }
  984. ehciPipePointer = ehciInstance->ehciRunningPipeList;
  985. while (ehciPipePointer != NULL)
  986. {
  987. /* only compute iso and interrupt pipe */
  988. if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
  989. (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT))
  990. {
  991. /* compute FS/LS bandwidth that blong to same high-speed hub, because FS/LS bandwidth is allocated from
  992. * first parent high-speed hub */
  993. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  994. (uint32_t)kUSB_HostGetDeviceHSHubNumber, &deviceInfo);
  995. if (deviceInfo != hubNumber)
  996. {
  997. temp = (void *)ehciPipePointer->pipeCommon.next;
  998. ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
  999. continue;
  1000. }
  1001. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  1002. (uint32_t)kUSB_HostGetDeviceSpeed, &deviceInfo);
  1003. if (deviceInfo == USB_SPEED_HIGH)
  1004. {
  1005. temp = (void *)ehciPipePointer->pipeCommon.next;
  1006. ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
  1007. continue;
  1008. }
  1009. /* does pipe allocate bandwidth in frameIndex frame? note: interval is power of 2. */
  1010. if ((frameIndex >= ehciPipePointer->startFrame) &&
  1011. (0U == ((uint32_t)((uint32_t)frameIndex - ehciPipePointer->startFrame) &
  1012. ((uint32_t)ehciPipePointer->pipeCommon.interval - 1U))))
  1013. {
  1014. if (ehciPipePointer->pipeCommon.pipeType ==
  1015. USB_ENDPOINT_ISOCHRONOUS) /* iso bandwidth is allocated once */
  1016. {
  1017. frameBandwidths[ehciPipePointer->startUframe + 1U] += ehciPipePointer->dataTime;
  1018. }
  1019. else /* iso bandwidth is allocated three times */
  1020. {
  1021. frameBandwidths[ehciPipePointer->startUframe + 1U] += ehciPipePointer->dataTime;
  1022. frameBandwidths[ehciPipePointer->startUframe + 2U] += ehciPipePointer->dataTime;
  1023. frameBandwidths[ehciPipePointer->startUframe + 3U] += ehciPipePointer->dataTime;
  1024. }
  1025. }
  1026. }
  1027. temp = (void *)ehciPipePointer->pipeCommon.next;
  1028. ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
  1029. }
  1030. for (index = 0; index < 7U; ++index) /* */
  1031. {
  1032. if (frameBandwidths[index] > s_SlotMaxBandwidth[index])
  1033. {
  1034. frameBandwidths[index + 1U] += (frameBandwidths[index] - s_SlotMaxBandwidth[index]);
  1035. frameBandwidths[index] = s_SlotMaxBandwidth[index];
  1036. }
  1037. }
  1038. }
  1039. static void USB_HostBandwidthHsHostComputeCurrentHsAll(usb_host_ehci_instance_t *ehciInstance,
  1040. uint16_t frameIndex,
  1041. uint16_t frameBandwidths[8])
  1042. {
  1043. usb_host_ehci_pipe_t *ehciPipePointer;
  1044. uint16_t index;
  1045. uint32_t deviceInfo = 0U;
  1046. uint16_t frameInterval;
  1047. void *temp;
  1048. for (index = 0; index < 8U; ++index)
  1049. {
  1050. frameBandwidths[index] = 0;
  1051. }
  1052. ehciPipePointer = ehciInstance->ehciRunningPipeList;
  1053. while (ehciPipePointer != NULL)
  1054. {
  1055. /* only compute iso and interrupt pipe */
  1056. if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
  1057. (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT))
  1058. {
  1059. frameInterval = ehciPipePointer->pipeCommon.interval;
  1060. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  1061. (uint32_t)kUSB_HostGetDeviceSpeed, &deviceInfo);
  1062. if (deviceInfo == USB_SPEED_HIGH) /* high-speed data bandwidth */
  1063. {
  1064. /* frameInterval means micro-frame here */
  1065. if (frameIndex >= ehciPipePointer->startFrame)
  1066. {
  1067. if ((frameInterval > 8U) &&
  1068. (frameIndex * 8U - ehciPipePointer->startFrame * 8U >= ehciPipePointer->startUframe))
  1069. {
  1070. if (0U == ((((uint32_t)frameIndex) * 8U - ehciPipePointer->startFrame * 8U -
  1071. ehciPipePointer->startUframe) &
  1072. ((uint32_t)frameInterval - 1U)))
  1073. {
  1074. frameBandwidths[ehciPipePointer->startUframe] += ehciPipePointer->dataTime;
  1075. }
  1076. }
  1077. else
  1078. {
  1079. for (index = ehciPipePointer->startUframe; index < 8U; index += frameInterval)
  1080. {
  1081. frameBandwidths[index] += ehciPipePointer->dataTime;
  1082. }
  1083. }
  1084. }
  1085. }
  1086. else /* full-speed split bandwidth */
  1087. {
  1088. if ((frameIndex >= ehciPipePointer->startFrame) &&
  1089. (0U == ((uint32_t)((uint32_t)frameIndex - ehciPipePointer->startFrame) &
  1090. (uint32_t)((uint32_t)frameInterval - 1U))))
  1091. {
  1092. for (index = 0; index < 8U; ++index)
  1093. {
  1094. if (0U != ((uint32_t)(ehciPipePointer->uframeSmask) &
  1095. (uint32_t)(0x01UL << index))) /* start-split micro-frames */
  1096. {
  1097. frameBandwidths[index] += ehciPipePointer->startSplitTime;
  1098. }
  1099. if (0U != ((uint32_t)(ehciPipePointer->uframeCmask) &
  1100. (uint32_t)(0x01UL << index))) /* complete-split micro-frames */
  1101. {
  1102. frameBandwidths[index] += ehciPipePointer->completeSplitTime;
  1103. }
  1104. }
  1105. }
  1106. }
  1107. }
  1108. temp = (void *)ehciPipePointer->pipeCommon.next;
  1109. ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
  1110. }
  1111. #if 0
  1112. for (index = 0; index < 7; ++index) /* */
  1113. {
  1114. if (frameBandwidths[index] > s_SlotMaxBandwidthHs[index])
  1115. {
  1116. frameBandwidths[index + 1] += (frameBandwidths[index] - s_SlotMaxBandwidthHs[index]);
  1117. frameBandwidths[index] = s_SlotMaxBandwidthHs[index];
  1118. }
  1119. }
  1120. #endif
  1121. }
  1122. /*!
  1123. * @brief allocate HS bandwidth when host work as high-speed host.
  1124. *
  1125. * @param ehciInstance ehci instance pointer.
  1126. * @param uframeInterval micro-frame interval.
  1127. * @param timeData time for allocating.
  1128. * @param uframeIndexOut return start uframe index.
  1129. *
  1130. * @return kStatus_USB_Success or error codes.
  1131. */
  1132. static usb_status_t USB_HostBandwidthHsHostAllocateHsCommon(usb_host_ehci_instance_t *ehciInstance,
  1133. uint16_t uframeInterval,
  1134. uint16_t timeData,
  1135. uint16_t *uframeIndexOut)
  1136. {
  1137. uint16_t uframeIntervalIndex;
  1138. uint16_t uframeIndex;
  1139. uint16_t frameIndex;
  1140. uint16_t frameTimes[8];
  1141. frameIndex = 0;
  1142. for (uint8_t i = 0; i < 8U; ++i)
  1143. {
  1144. frameTimes[i] = 0U;
  1145. }
  1146. USB_HostBandwidthHsHostComputeCurrentHsAll(
  1147. ehciInstance, frameIndex, frameTimes); /* compute the allocated bandwidths in the frameIndex frame */
  1148. for (uframeIntervalIndex = 0; (uframeIntervalIndex < uframeInterval); ++uframeIntervalIndex) /* start micro-frame */
  1149. {
  1150. /* for all the micro-frame in interval uframeInterval */
  1151. for (uframeIndex = uframeIntervalIndex; uframeIndex < (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 8U);
  1152. uframeIndex += uframeInterval)
  1153. {
  1154. if (frameIndex != (uframeIndex >> 3))
  1155. {
  1156. frameIndex = (uframeIndex >> 3);
  1157. USB_HostBandwidthHsHostComputeCurrentHsAll(
  1158. ehciInstance, frameIndex,
  1159. frameTimes); /* compute the allocated bandwidths in the new frameIndex frame */
  1160. }
  1161. if (frameTimes[uframeIndex & 0x0007U] + timeData >
  1162. s_SlotMaxBandwidthHs[(uframeIndex & 0x0007U)]) /* micro-frame has enough idle bandwidth? */
  1163. {
  1164. break; /* fail */
  1165. }
  1166. }
  1167. if (uframeIndex >= (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 8U)) /* success? */
  1168. {
  1169. break;
  1170. }
  1171. }
  1172. if (uframeIntervalIndex < uframeInterval)
  1173. {
  1174. *uframeIndexOut = (uframeIntervalIndex);
  1175. return kStatus_USB_Success;
  1176. }
  1177. else
  1178. {
  1179. return kStatus_USB_Error;
  1180. }
  1181. }
  1182. #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
  1183. ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
  1184. static usb_status_t USB_HostBandwidthHsHostAllocateIso(usb_host_ehci_instance_t *ehciInstance,
  1185. usb_host_ehci_pipe_t *ehciPipePointer)
  1186. {
  1187. usb_status_t status;
  1188. uint32_t deviceInfo = 0;
  1189. uint32_t hubNumber = 0;
  1190. uint16_t uframeIntervalIndex = 0;
  1191. uint16_t frameIntervalIndex = 0;
  1192. uint16_t frameIndex;
  1193. uint16_t timeCompleteSplit;
  1194. uint16_t timeStartSplit;
  1195. uint32_t timeData;
  1196. uint8_t SsCsNumber = 0;
  1197. uint16_t frameInterval;
  1198. uint16_t frameTimes[8];
  1199. uint8_t allocateOk = 1;
  1200. uint16_t index;
  1201. for (uint8_t i = 0; i < 8U; ++i)
  1202. {
  1203. frameTimes[i] = 0U;
  1204. }
  1205. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  1206. (uint32_t)kUSB_HostGetDeviceSpeed, &deviceInfo);
  1207. timeData = USB_HostBandwidthComputeTime(
  1208. (uint8_t)deviceInfo, USB_ENDPOINT_ISOCHRONOUS, ehciPipePointer->pipeCommon.direction,
  1209. (((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize) * ehciPipePointer->pipeCommon.numberPerUframe));
  1210. /* pipe is high-speed */
  1211. if (deviceInfo == USB_SPEED_HIGH)
  1212. {
  1213. uframeIntervalIndex = 0;
  1214. status = USB_HostBandwidthHsHostAllocateHsCommon(ehciInstance, ehciPipePointer->uframeInterval,
  1215. (uint16_t)timeData, &uframeIntervalIndex);
  1216. if (status == kStatus_USB_Success)
  1217. {
  1218. ehciPipePointer->startFrame = (uframeIntervalIndex / 8U);
  1219. ehciPipePointer->startUframe = (uint8_t)(uframeIntervalIndex & 0x0007U);
  1220. ehciPipePointer->dataTime = (uint16_t)timeData;
  1221. return kStatus_USB_Success;
  1222. }
  1223. }
  1224. else /* pipe is full-speed or low-speed */
  1225. {
  1226. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  1227. (uint32_t)kUSB_HostGetHubThinkTime,
  1228. &deviceInfo); /* deviceInfo variable means hub think time */
  1229. timeData += (deviceInfo * 7U / (6U * 12U));
  1230. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  1231. (uint32_t)kUSB_HostGetDeviceHSHubNumber, &hubNumber);
  1232. frameInterval = ehciPipePointer->pipeCommon.interval;
  1233. /* compute start-split and complete-split bandwidth */
  1234. if (ehciPipePointer->pipeCommon.direction == USB_OUT)
  1235. {
  1236. timeStartSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_ISOCHRONOUS, USB_OUT,
  1237. ehciPipePointer->pipeCommon.maxPacketSize);
  1238. timeCompleteSplit = 0;
  1239. }
  1240. else
  1241. {
  1242. timeStartSplit =
  1243. (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_ISOCHRONOUS, USB_IN, 1);
  1244. timeCompleteSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_ISOCHRONOUS, USB_IN,
  1245. ehciPipePointer->pipeCommon.maxPacketSize);
  1246. }
  1247. /* note: bandwidth must put in one frame */
  1248. for (uframeIntervalIndex = 0U; uframeIntervalIndex <= 5U; ++uframeIntervalIndex) /* uframe interval */
  1249. {
  1250. for (frameIntervalIndex = 0U; frameIntervalIndex < frameInterval; ++frameIntervalIndex) /* frame interval */
  1251. {
  1252. allocateOk = 1;
  1253. for (frameIndex = frameIntervalIndex; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
  1254. frameIndex += frameInterval) /* check all the frames */
  1255. {
  1256. /* compute start-split and complete-split number */
  1257. SsCsNumber = (uint8_t)((ehciPipePointer->pipeCommon.maxPacketSize + 187U) /
  1258. 188U); /* ss number for iso out; cs number for iso in */
  1259. if (ehciPipePointer->pipeCommon.direction == USB_OUT) /* ISO OUT */
  1260. {
  1261. if (uframeIntervalIndex + SsCsNumber > 8U)
  1262. {
  1263. allocateOk = 0U;
  1264. }
  1265. }
  1266. else
  1267. {
  1268. if (uframeIntervalIndex + 2U + SsCsNumber >
  1269. 8U) /* ISO IN: there are two micro-frame interval between start-split and complete-split */
  1270. {
  1271. allocateOk = 0U;
  1272. }
  1273. }
  1274. if (0U != allocateOk)
  1275. {
  1276. /* allocate start-split and complete-split bandwidth */
  1277. USB_HostBandwidthHsHostComputeCurrentHsAll(ehciInstance, frameIndex, frameTimes);
  1278. if (ehciPipePointer->pipeCommon.direction == USB_OUT) /* ISO OUT */
  1279. {
  1280. index = uframeIntervalIndex;
  1281. for (; index < (uframeIntervalIndex + SsCsNumber); ++index)
  1282. {
  1283. if (frameTimes[index] + timeStartSplit > s_SlotMaxBandwidthHs[index])
  1284. {
  1285. allocateOk = 0U;
  1286. break;
  1287. }
  1288. }
  1289. }
  1290. else /* ISO IN */
  1291. {
  1292. index = uframeIntervalIndex;
  1293. if (frameTimes[index] + timeStartSplit > s_SlotMaxBandwidthHs[index])
  1294. {
  1295. allocateOk = 0U;
  1296. }
  1297. if (0U != allocateOk)
  1298. {
  1299. index =
  1300. uframeIntervalIndex +
  1301. 2U; /* there are two micro-frames interval between start-split and complete-split */
  1302. for (; index < (uframeIntervalIndex + 2U + SsCsNumber); ++index)
  1303. {
  1304. if (frameTimes[index] + timeCompleteSplit > s_SlotMaxBandwidthHs[index])
  1305. {
  1306. allocateOk = 0U;
  1307. break;
  1308. }
  1309. }
  1310. }
  1311. }
  1312. }
  1313. /* allocate data bandwidth */
  1314. if (0U != allocateOk)
  1315. {
  1316. USB_HostBandwidthHsHostComputeCurrentFsls(ehciInstance, hubNumber, frameIndex, frameTimes);
  1317. index = uframeIntervalIndex + 1U; /* timeData bandwidth start position */
  1318. /* iso must occupy all the uframe bandwidth */
  1319. {
  1320. deviceInfo = timeData; /* note: deviceInfo variable means bandwidth here */
  1321. while ((index < 8U) && (deviceInfo > s_SlotMaxBandwidth[index]))
  1322. {
  1323. if (frameTimes[index] > 0U)
  1324. {
  1325. allocateOk = 0U;
  1326. break;
  1327. }
  1328. else
  1329. {
  1330. deviceInfo -= s_SlotMaxBandwidth[index];
  1331. }
  1332. ++index;
  1333. }
  1334. }
  1335. }
  1336. if (0U != allocateOk)
  1337. {
  1338. /* data bandwidth can be put in the frame? */
  1339. index = uframeIntervalIndex + 1U; /* timeData bandwidth start position */
  1340. frameTimes[index] += (uint16_t)timeData;
  1341. for (; index < 7U; ++index)
  1342. {
  1343. if (frameTimes[index] > s_SlotMaxBandwidth[index])
  1344. {
  1345. frameTimes[index + 1U] += (frameTimes[index] - s_SlotMaxBandwidth[index]);
  1346. frameTimes[index] = s_SlotMaxBandwidth[index];
  1347. }
  1348. else
  1349. {
  1350. break;
  1351. }
  1352. }
  1353. if (frameTimes[index] > s_SlotMaxBandwidth[index])
  1354. {
  1355. allocateOk = 0;
  1356. }
  1357. }
  1358. if (0U != allocateOk)
  1359. {
  1360. break;
  1361. }
  1362. }
  1363. if (0U != allocateOk)
  1364. {
  1365. break;
  1366. }
  1367. }
  1368. if (0U != allocateOk)
  1369. {
  1370. break;
  1371. }
  1372. }
  1373. if (0U != allocateOk)
  1374. {
  1375. ehciPipePointer->startFrame = frameIntervalIndex;
  1376. ehciPipePointer->startUframe = (uint8_t)uframeIntervalIndex;
  1377. ehciPipePointer->dataTime = (uint16_t)timeData;
  1378. ehciPipePointer->startSplitTime = timeStartSplit;
  1379. ehciPipePointer->completeSplitTime = timeCompleteSplit;
  1380. if (ehciPipePointer->pipeCommon.direction == USB_OUT)
  1381. {
  1382. index = uframeIntervalIndex;
  1383. for (; index < (uframeIntervalIndex + SsCsNumber); ++index)
  1384. {
  1385. ehciPipePointer->uframeSmask = ehciPipePointer->uframeSmask | (uint8_t)(0x01UL << index);
  1386. }
  1387. }
  1388. else
  1389. {
  1390. index = uframeIntervalIndex;
  1391. ehciPipePointer->uframeSmask = ehciPipePointer->uframeSmask | (uint8_t)(0x01UL << index);
  1392. index = uframeIntervalIndex + 2U;
  1393. for (; index < (uframeIntervalIndex + 2U + SsCsNumber); ++index)
  1394. {
  1395. ehciPipePointer->uframeCmask = ehciPipePointer->uframeCmask | (uint8_t)(0x01UL << index);
  1396. }
  1397. }
  1398. return kStatus_USB_Success;
  1399. }
  1400. }
  1401. return kStatus_USB_Error;
  1402. }
  1403. #endif
  1404. static usb_status_t USB_HostBandwidthHsHostAllocateInterrupt(usb_host_ehci_instance_t *ehciInstance,
  1405. usb_host_ehci_pipe_t *ehciPipePointer)
  1406. {
  1407. usb_status_t status;
  1408. uint32_t deviceInfo = 0;
  1409. uint32_t hubNumber = 0;
  1410. uint16_t uframeIntervalIndex = 0;
  1411. uint16_t frameIntervalIndex = 0;
  1412. uint16_t frameIndex;
  1413. uint16_t timeCompleteSplit;
  1414. uint16_t timeStartSplit;
  1415. uint32_t timeData;
  1416. uint8_t SsCsNumber;
  1417. uint16_t frameInterval;
  1418. uint16_t frameTimes[8];
  1419. uint8_t allocateOk = 1;
  1420. uint8_t index;
  1421. for (uint8_t i = 0; i < 8U; ++i)
  1422. {
  1423. frameTimes[i] = 0U;
  1424. }
  1425. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  1426. (uint32_t)kUSB_HostGetDeviceSpeed, &deviceInfo);
  1427. timeData = USB_HostBandwidthComputeTime(
  1428. (uint8_t)deviceInfo, USB_ENDPOINT_INTERRUPT, ehciPipePointer->pipeCommon.direction,
  1429. (uint32_t)ehciPipePointer->pipeCommon.maxPacketSize * ehciPipePointer->pipeCommon.numberPerUframe);
  1430. /* pipe is high-speed */
  1431. if (deviceInfo == USB_SPEED_HIGH)
  1432. {
  1433. uframeIntervalIndex = 0;
  1434. status = USB_HostBandwidthHsHostAllocateHsCommon(ehciInstance, ehciPipePointer->uframeInterval,
  1435. (uint16_t)timeData, &uframeIntervalIndex);
  1436. if (status == kStatus_USB_Success)
  1437. {
  1438. ehciPipePointer->startFrame = (uframeIntervalIndex / 8U);
  1439. ehciPipePointer->startUframe = (uint8_t)(uframeIntervalIndex & 0x0007U);
  1440. /* for HS interrupt start transaction position */
  1441. if (ehciPipePointer->uframeInterval >= 8U)
  1442. {
  1443. ehciPipePointer->uframeSmask = (0x01U << ehciPipePointer->startUframe);
  1444. }
  1445. else
  1446. {
  1447. ehciPipePointer->uframeSmask = 0x00U;
  1448. for (index = ehciPipePointer->startUframe; index < 8U;
  1449. index += (uint8_t)ehciPipePointer->uframeInterval)
  1450. {
  1451. ehciPipePointer->uframeSmask |= (0x01U << index);
  1452. }
  1453. }
  1454. ehciPipePointer->dataTime = (uint16_t)timeData;
  1455. return kStatus_USB_Success;
  1456. }
  1457. }
  1458. else /* pipe is full-speed or low-speed */
  1459. {
  1460. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  1461. (uint32_t)kUSB_HostGetHubThinkTime, &deviceInfo);
  1462. timeData += (deviceInfo * 7U / (6U * 12U));
  1463. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  1464. (uint32_t)kUSB_HostGetDeviceHSHubNumber, &hubNumber);
  1465. frameInterval = ehciPipePointer->pipeCommon.interval;
  1466. SsCsNumber = 3U; /* complete split number */
  1467. /* compute start-split and complete-split bandwidth */
  1468. if (ehciPipePointer->pipeCommon.direction == USB_OUT)
  1469. {
  1470. timeStartSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_OUT,
  1471. ehciPipePointer->pipeCommon.maxPacketSize);
  1472. timeStartSplit +=
  1473. (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_OUT, 1U);
  1474. timeCompleteSplit =
  1475. (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_OUT, 0U);
  1476. }
  1477. else
  1478. {
  1479. timeStartSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_IN, 1U);
  1480. timeCompleteSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_IN,
  1481. ehciPipePointer->pipeCommon.maxPacketSize);
  1482. timeCompleteSplit +=
  1483. (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_IN, 0U);
  1484. }
  1485. /* note: bandwidth must put in one frame */
  1486. for (uframeIntervalIndex = 0U; uframeIntervalIndex <= 4U; ++uframeIntervalIndex) /* uframe interval */
  1487. {
  1488. for (frameIntervalIndex = 0U; frameIntervalIndex < frameInterval; ++frameIntervalIndex) /* frame interval */
  1489. {
  1490. allocateOk = 1U;
  1491. for (frameIndex = frameIntervalIndex; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
  1492. frameIndex += frameInterval) /* check all the frames */
  1493. {
  1494. /* allocate data bandwidth */
  1495. USB_HostBandwidthHsHostComputeCurrentFsls(ehciInstance, hubNumber, frameIndex, frameTimes);
  1496. index = (uint8_t)(uframeIntervalIndex + 1U);
  1497. for (; index <= (uframeIntervalIndex + 3U); ++index) /* data bandwidth number is 3.
  1498. uframeIntervalIndex don't exceed 4, so
  1499. index cannot exceed 7 */
  1500. {
  1501. if (frameTimes[index] + timeData > s_SlotMaxBandwidth[index])
  1502. {
  1503. allocateOk = 0;
  1504. break;
  1505. }
  1506. }
  1507. if (0U != allocateOk)
  1508. {
  1509. USB_HostBandwidthHsHostComputeCurrentHsAll(ehciInstance, frameIndex, frameTimes);
  1510. /* allocate start_split bandwidth */
  1511. if (frameTimes[uframeIntervalIndex] + timeStartSplit >
  1512. s_SlotMaxBandwidthHs[uframeIntervalIndex])
  1513. {
  1514. allocateOk = 0U;
  1515. }
  1516. if (0U != allocateOk)
  1517. {
  1518. /* allocate complete_split bandwidth */
  1519. index = (uint8_t)uframeIntervalIndex + 2U;
  1520. /* complete-split number is normal 3. When uframeIntervalIndex is 4, complete-split number
  1521. * is 2. */
  1522. for (; (index <= (uframeIntervalIndex + 1U + SsCsNumber)) && (index < 8U); ++index)
  1523. {
  1524. if (frameTimes[index] + timeCompleteSplit > s_SlotMaxBandwidthHs[index])
  1525. {
  1526. allocateOk = 0U;
  1527. break;
  1528. }
  1529. }
  1530. }
  1531. }
  1532. if (0U == allocateOk)
  1533. {
  1534. break; /* allocate fail */
  1535. }
  1536. }
  1537. if (0U != allocateOk)
  1538. {
  1539. break;
  1540. }
  1541. }
  1542. if (0U != allocateOk)
  1543. {
  1544. break;
  1545. }
  1546. }
  1547. if (0U != allocateOk)
  1548. {
  1549. ehciPipePointer->startFrame = frameIntervalIndex;
  1550. ehciPipePointer->startUframe = (uint8_t)uframeIntervalIndex;
  1551. ehciPipePointer->uframeSmask = (0x01u << ehciPipePointer->startUframe);
  1552. ehciPipePointer->uframeCmask = 0u;
  1553. index = (uint8_t)uframeIntervalIndex + 2u;
  1554. for (; (index <= (uframeIntervalIndex + 1u + SsCsNumber)) && (index < 8u); ++index)
  1555. {
  1556. ehciPipePointer->uframeCmask = ehciPipePointer->uframeCmask | (0x01U << index);
  1557. }
  1558. ehciPipePointer->dataTime = (uint16_t)timeData;
  1559. ehciPipePointer->startSplitTime = timeStartSplit;
  1560. ehciPipePointer->completeSplitTime = timeCompleteSplit;
  1561. return kStatus_USB_Success;
  1562. }
  1563. }
  1564. return kStatus_USB_BandwidthFail;
  1565. }
  1566. static usb_status_t USB_HostBandwidthFslsHostAllocate(usb_host_ehci_instance_t *ehciInstance,
  1567. usb_host_ehci_pipe_t *ehciPipePointer)
  1568. {
  1569. uint32_t FslsTime = 0;
  1570. uint32_t speed = 0;
  1571. uint16_t uframeIntervalIndex;
  1572. uint16_t frameIndex;
  1573. uint16_t frameInterval;
  1574. uint16_t frameTime;
  1575. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  1576. (uint32_t)kUSB_HostGetHubThinkTime, &FslsTime);
  1577. FslsTime += (FslsTime * 7U / (6U * 12U));
  1578. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  1579. (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
  1580. FslsTime = FslsTime + USB_HostBandwidthComputeTime((uint8_t)speed, ehciPipePointer->pipeCommon.pipeType,
  1581. ehciPipePointer->pipeCommon.direction,
  1582. ehciPipePointer->pipeCommon.maxPacketSize);
  1583. frameInterval = ehciPipePointer->pipeCommon.interval;
  1584. for (uframeIntervalIndex = 0; uframeIntervalIndex < ehciPipePointer->uframeInterval;
  1585. ++uframeIntervalIndex) /* uframeIntervalIndex can exceed 8 */
  1586. {
  1587. for (frameIndex = (uframeIntervalIndex >> 3); frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
  1588. frameIndex += frameInterval)
  1589. {
  1590. USB_HostBandwidthFslsHostComputeCurrent(ehciInstance, frameIndex, &frameTime);
  1591. if (frameTime + FslsTime > USB_HOST_EHCI_BANDWIDTH_FRAME_TOTOAL_TIME)
  1592. {
  1593. break;
  1594. }
  1595. }
  1596. if (frameIndex >= USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE)
  1597. {
  1598. break;
  1599. }
  1600. }
  1601. if (uframeIntervalIndex < ehciPipePointer->uframeInterval)
  1602. {
  1603. ehciPipePointer->startFrame = (uframeIntervalIndex >> 3);
  1604. ehciPipePointer->startUframe = (uint8_t)(uframeIntervalIndex & 0x0007U);
  1605. ehciPipePointer->uframeSmask = 0; /* useless */
  1606. ehciPipePointer->uframeCmask = 0;
  1607. ehciPipePointer->dataTime = (uint16_t)FslsTime;
  1608. return kStatus_USB_Success;
  1609. }
  1610. return kStatus_USB_BandwidthFail;
  1611. }
  1612. static uint8_t USB_HostEhciGet2PowerValue(uint8_t value)
  1613. {
  1614. if ((value == 0U) || (value == 1U))
  1615. {
  1616. return value;
  1617. }
  1618. if (0U != (value & 0xf0U))
  1619. {
  1620. if (0U != (value & 0x80U))
  1621. {
  1622. return 128U;
  1623. }
  1624. else if (0U != (value & 0x40U))
  1625. {
  1626. return 64U;
  1627. }
  1628. else if (0U != (value & 0x20U))
  1629. {
  1630. return 32U;
  1631. }
  1632. else
  1633. {
  1634. return 16U;
  1635. }
  1636. }
  1637. else
  1638. {
  1639. if (0U != (value & 0x08U))
  1640. {
  1641. return 8U;
  1642. }
  1643. else if (0U != (value & 0x04U))
  1644. {
  1645. return 4U;
  1646. }
  1647. else if (0U != (value & 0x02U))
  1648. {
  1649. return 2U;
  1650. }
  1651. else
  1652. {
  1653. return 1U;
  1654. }
  1655. }
  1656. }
  1657. static void USB_HostEhciZeroMem(uint32_t *buffer, uint32_t length)
  1658. {
  1659. /* note: the zero unit is uint32_t */
  1660. while (0U != length)
  1661. {
  1662. length--;
  1663. *buffer = 0;
  1664. buffer++;
  1665. }
  1666. }
  1667. static void USB_HostEhciDelay(USBHS_Type *ehciIpBase, uint32_t ms)
  1668. {
  1669. /* note: the max delay time cannot exceed half of max value (0x4000) */
  1670. uint32_t sofStart;
  1671. uint32_t SofEnd;
  1672. uint32_t distance;
  1673. sofStart = (ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE);
  1674. do
  1675. {
  1676. SofEnd = (ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE);
  1677. distance = (SofEnd + EHCI_MAX_UFRAME_VALUE + 1U - sofStart);
  1678. } while ((distance & EHCI_MAX_UFRAME_VALUE) < (ms * 8U)); /* compute the distance between sofStart and SofEnd */
  1679. }
  1680. static void USB_HostEhciStartAsync(usb_host_ehci_instance_t *ehciInstance)
  1681. {
  1682. uint32_t stateSync;
  1683. if (0U == (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK))
  1684. {
  1685. /* the status must be same when change USBCMD->ASE */
  1686. do
  1687. {
  1688. stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK) |
  1689. (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_ASE_MASK));
  1690. } while ((stateSync == USBHS_USBSTS_AS_MASK) || (stateSync == USBHS_USBCMD_ASE_MASK));
  1691. ehciInstance->ehciIpBase->ASYNCLISTADDR = (uint32_t)(ehciInstance->shedFirstQh);
  1692. ehciInstance->ehciIpBase->USBCMD |= USBHS_USBCMD_ASE_MASK;
  1693. while (0U == (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK))
  1694. {
  1695. }
  1696. }
  1697. }
  1698. static void USB_HostEhciStopAsync(usb_host_ehci_instance_t *ehciInstance)
  1699. {
  1700. uint32_t stateSync;
  1701. /* the status must be same when change USBCMD->ASE */
  1702. do
  1703. {
  1704. stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK) |
  1705. (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_ASE_MASK));
  1706. } while ((stateSync == USBHS_USBSTS_AS_MASK) || (stateSync == USBHS_USBCMD_ASE_MASK));
  1707. ehciInstance->ehciIpBase->USBCMD &= (uint32_t)(~(uint32_t)USBHS_USBCMD_ASE_MASK); /* disable async schedule */
  1708. while (0U != (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK))
  1709. {
  1710. }
  1711. }
  1712. static void USB_HostEhciStartPeriodic(usb_host_ehci_instance_t *ehciInstance)
  1713. {
  1714. uint32_t stateSync;
  1715. if (0U == (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK))
  1716. {
  1717. /* the status must be same when change USBCMD->PSE */
  1718. do
  1719. {
  1720. stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK) |
  1721. (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_PSE_MASK));
  1722. } while ((stateSync == USBHS_USBSTS_PS_MASK) || (stateSync == USBHS_USBCMD_PSE_MASK));
  1723. ehciInstance->ehciIpBase->PERIODICLISTBASE = (uint32_t)(ehciInstance->ehciFrameList);
  1724. if (0U == (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_PSE_MASK))
  1725. {
  1726. ehciInstance->ehciIpBase->USBCMD |= USBHS_USBCMD_PSE_MASK; /* start periodic schedule */
  1727. }
  1728. while (0U == (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK))
  1729. {
  1730. }
  1731. }
  1732. return;
  1733. }
  1734. static void USB_HostEhciStopPeriodic(usb_host_ehci_instance_t *ehciInstance)
  1735. {
  1736. uint32_t stateSync;
  1737. /* the status must be same when change USBCMD->PSE */
  1738. do
  1739. {
  1740. stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK) |
  1741. (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_PSE_MASK));
  1742. } while ((stateSync == USBHS_USBSTS_PS_MASK) || (stateSync == USBHS_USBCMD_PSE_MASK));
  1743. ehciInstance->ehciIpBase->USBCMD &= (~USBHS_USBCMD_PSE_MASK); /* stop periodic schedule */
  1744. while (0U != (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK))
  1745. {
  1746. }
  1747. }
  1748. static usb_status_t USB_HostEhciQhQtdListInit(usb_host_ehci_instance_t *ehciInstance,
  1749. usb_host_ehci_pipe_t *ehciPipePointer,
  1750. usb_host_transfer_t *transfer)
  1751. {
  1752. volatile usb_host_ehci_qh_t *vltQhPointer;
  1753. usb_host_ehci_qtd_t *qtdPointer = NULL;
  1754. usb_host_ehci_qtd_t *BaseQtdPointer = NULL;
  1755. volatile uint32_t *entryPointer;
  1756. uint32_t qtdNumber;
  1757. uint32_t dataLength;
  1758. uint32_t dataAddress;
  1759. uint32_t endAddress;
  1760. uint8_t index;
  1761. /* compute the qtd number */
  1762. if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL)
  1763. {
  1764. /* assume setup data don't exceed one qtd data size, one qtd can transfer least 16k data */
  1765. if (transfer->transferLength == 0U)
  1766. {
  1767. qtdNumber = 2U;
  1768. }
  1769. else
  1770. {
  1771. qtdNumber = 3U;
  1772. }
  1773. }
  1774. else
  1775. {
  1776. qtdNumber = (((transfer->transferLength) & 0xFFFFC000U) >> 14U) +
  1777. (0U != ((transfer->transferLength) & 0x00003FFFU) ? 1U : 0U);
  1778. if (0U == qtdNumber)
  1779. {
  1780. qtdNumber = 1U;
  1781. }
  1782. }
  1783. vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
  1784. /* get qtd list */
  1785. USB_HostEhciLock();
  1786. if (qtdNumber <= ehciInstance->ehciQtdNumber)
  1787. {
  1788. ehciInstance->ehciQtdNumber -= (uint8_t)qtdNumber;
  1789. BaseQtdPointer = ehciInstance->ehciQtdHead;
  1790. qtdPointer = NULL;
  1791. do
  1792. {
  1793. if (qtdPointer != NULL)
  1794. {
  1795. qtdPointer->nextQtdPointer = (uint32_t)ehciInstance->ehciQtdHead;
  1796. }
  1797. qtdPointer = ehciInstance->ehciQtdHead;
  1798. ehciInstance->ehciQtdHead = (usb_host_ehci_qtd_t *)qtdPointer->nextQtdPointer;
  1799. qtdPointer->nextQtdPointer = 0;
  1800. --qtdNumber;
  1801. } while (0U != qtdNumber);
  1802. if (ehciInstance->ehciQtdNumber == 0U)
  1803. {
  1804. ehciInstance->ehciQtdTail = NULL;
  1805. }
  1806. }
  1807. else
  1808. {
  1809. USB_HostEhciUnlock();
  1810. return kStatus_USB_Error;
  1811. }
  1812. USB_HostEhciUnlock();
  1813. /* int qTD list */
  1814. if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL)
  1815. {
  1816. /* setup transaction qtd */
  1817. qtdPointer = BaseQtdPointer;
  1818. qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
  1819. /* dt: need set; ioc: 0; C_Page: 0; PID Code: SETUP; Status: Active */
  1820. qtdPointer->transferResults[1] = 0U;
  1821. qtdPointer->transferResults[0] =
  1822. ((0x00000000UL << EHCI_HOST_QTD_DT_SHIFT) | (8UL << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
  1823. (EHCI_HOST_PID_SETUP << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
  1824. dataAddress = ((uint32_t)transfer->setupPacket);
  1825. qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
  1826. /* set buffer pointer no matter data length */
  1827. for (index = 0; index < 4U; ++index)
  1828. {
  1829. qtdPointer->bufferPointers[index] = ((dataAddress + ((uint32_t)index + 1U) * 4U * 1024U) & 0xFFFFF000U);
  1830. }
  1831. /* data transaction qtd */
  1832. dataLength = transfer->transferLength;
  1833. if (dataLength != 0U)
  1834. {
  1835. qtdPointer = (usb_host_ehci_qtd_t *)(qtdPointer->nextQtdPointer);
  1836. qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
  1837. /* dt: need set; ioc: 0; C_Page: 0; PID Code: IN/OUT; Status: Active */
  1838. qtdPointer->transferResults[1] = 0U;
  1839. if (transfer->direction == USB_OUT)
  1840. {
  1841. qtdPointer->transferResults[0] =
  1842. ((0x00000001UL << EHCI_HOST_QTD_DT_SHIFT) | (dataLength << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
  1843. (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
  1844. }
  1845. else
  1846. {
  1847. qtdPointer->transferResults[0] =
  1848. ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (dataLength << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
  1849. (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
  1850. }
  1851. dataAddress = (uint32_t)transfer->transferBuffer;
  1852. qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
  1853. /* set buffer pointer no matter data length */
  1854. for (index = 0; index < 4U; ++index)
  1855. {
  1856. qtdPointer->bufferPointers[index] = ((dataAddress + ((uint32_t)index + 1U) * 4U * 1024U) & 0xFFFFF000U);
  1857. }
  1858. }
  1859. /* status transaction qtd */
  1860. qtdPointer = (usb_host_ehci_qtd_t *)(qtdPointer->nextQtdPointer);
  1861. qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
  1862. /* dt: dont care; ioc: 1; C_Page: 0; PID Code: IN/OUT; Status: Active */
  1863. qtdPointer->transferResults[1] = 0;
  1864. if ((dataLength == 0U) || (transfer->direction == USB_OUT))
  1865. {
  1866. qtdPointer->transferResults[0] =
  1867. ((0x00000001UL << EHCI_HOST_QTD_DT_SHIFT) | (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) |
  1868. (EHCI_HOST_QTD_IOC_MASK) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
  1869. }
  1870. else
  1871. {
  1872. qtdPointer->transferResults[0] =
  1873. ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) |
  1874. (EHCI_HOST_QTD_IOC_MASK) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
  1875. }
  1876. qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE;
  1877. }
  1878. else
  1879. {
  1880. dataAddress = (uint32_t)transfer->transferBuffer;
  1881. qtdPointer = BaseQtdPointer;
  1882. while (1U == 1U)
  1883. {
  1884. endAddress = dataAddress + (16U * 1024U);
  1885. if (endAddress > (uint32_t)(transfer->transferBuffer + transfer->transferLength))
  1886. {
  1887. endAddress = (uint32_t)(transfer->transferBuffer + transfer->transferLength);
  1888. }
  1889. qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
  1890. /* dt: set; ioc: 0; C_Page: 0; PID Code: IN/OUT; Status: Active */
  1891. qtdPointer->transferResults[1] = 0U;
  1892. if (transfer->direction == USB_OUT)
  1893. {
  1894. qtdPointer->transferResults[0] =
  1895. (((endAddress - dataAddress) << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
  1896. ((uint32_t)ehciPipePointer->pipeCommon.nextdata01 << EHCI_HOST_QTD_DT_SHIFT) |
  1897. (EHCI_HOST_QTD_CERR_MAX_VALUE << EHCI_HOST_QTD_CERR_SHIFT) |
  1898. (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
  1899. }
  1900. else
  1901. {
  1902. qtdPointer->transferResults[0] =
  1903. (((endAddress - dataAddress) << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
  1904. ((uint32_t)ehciPipePointer->pipeCommon.nextdata01 << EHCI_HOST_QTD_DT_SHIFT) |
  1905. (EHCI_HOST_QTD_CERR_MAX_VALUE << EHCI_HOST_QTD_CERR_SHIFT) |
  1906. (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
  1907. }
  1908. qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
  1909. /* set buffer pointer no matter data length */
  1910. for (index = 0; index < 4U; ++index)
  1911. {
  1912. qtdPointer->bufferPointers[index] = ((dataAddress + ((uint32_t)index + 1U) * 4U * 1024U) & 0xFFFFF000U);
  1913. }
  1914. dataAddress = endAddress; /* for next qtd */
  1915. if (qtdPointer->nextQtdPointer == 0U)
  1916. {
  1917. break;
  1918. }
  1919. qtdPointer = (usb_host_ehci_qtd_t *)(qtdPointer->nextQtdPointer);
  1920. }
  1921. qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE;
  1922. qtdPointer->transferResults[0] |= EHCI_HOST_QTD_IOC_MASK; /* last one set IOC */
  1923. }
  1924. /* save qtd to transfer */
  1925. transfer->union1.unitHead = (uint32_t)BaseQtdPointer;
  1926. transfer->union2.unitTail = (uint32_t)qtdPointer;
  1927. /* link transfer to qh */
  1928. transfer->next = NULL;
  1929. if (vltQhPointer->ehciTransferHead == NULL)
  1930. {
  1931. transfer->next = NULL;
  1932. vltQhPointer->ehciTransferTail = transfer;
  1933. vltQhPointer->ehciTransferHead = transfer;
  1934. }
  1935. else
  1936. {
  1937. transfer->next = NULL;
  1938. vltQhPointer->ehciTransferTail->next = transfer;
  1939. vltQhPointer->ehciTransferTail = transfer;
  1940. }
  1941. USB_HostEhciLock();
  1942. /* link qtd to qh (link to end) */
  1943. entryPointer = &(vltQhPointer->nextQtdPointer);
  1944. dataAddress = *entryPointer; /* dataAddress variable means entry value here */
  1945. while ((0U != dataAddress) && (0U == (dataAddress & EHCI_HOST_T_INVALID_VALUE)))
  1946. {
  1947. entryPointer = (volatile uint32_t *)dataAddress;
  1948. dataAddress = *entryPointer;
  1949. }
  1950. *entryPointer = (uint32_t)BaseQtdPointer;
  1951. USB_HostEhciUnlock();
  1952. USB_HostEhciStartAsync(ehciInstance);
  1953. return kStatus_USB_Success;
  1954. }
  1955. static uint32_t USB_HostEhciQtdListRelease(usb_host_ehci_instance_t *ehciInstance,
  1956. usb_host_ehci_qtd_t *ehciQtdStart,
  1957. usb_host_ehci_qtd_t *ehciQtdEnd)
  1958. {
  1959. uint32_t length = 0;
  1960. usb_host_ehci_qtd_t *qtdPointer;
  1961. ehciQtdEnd->nextQtdPointer = 0U;
  1962. /* compute remaining length */
  1963. qtdPointer = ehciQtdStart;
  1964. while (qtdPointer != ehciQtdEnd)
  1965. {
  1966. length +=
  1967. ((qtdPointer->transferResults[0] & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >> EHCI_HOST_QTD_TOTAL_BYTES_SHIFT);
  1968. qtdPointer = (usb_host_ehci_qtd_t *)qtdPointer->nextQtdPointer;
  1969. }
  1970. qtdPointer = ehciQtdEnd;
  1971. length += ((qtdPointer->transferResults[0] & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >> EHCI_HOST_QTD_TOTAL_BYTES_SHIFT);
  1972. /* put releasing qtd to idle qtd list */
  1973. USB_HostEhciLock();
  1974. if (ehciInstance->ehciQtdNumber == 0U)
  1975. {
  1976. ehciInstance->ehciQtdHead = ehciQtdStart;
  1977. ehciInstance->ehciQtdTail = ehciQtdEnd;
  1978. }
  1979. else
  1980. {
  1981. ehciInstance->ehciQtdTail->nextQtdPointer = (uint32_t)ehciQtdStart;
  1982. ehciInstance->ehciQtdTail = ehciQtdEnd;
  1983. }
  1984. while (ehciQtdStart != ehciQtdEnd)
  1985. {
  1986. ehciInstance->ehciQtdNumber++;
  1987. ehciQtdStart = (usb_host_ehci_qtd_t *)ehciQtdStart->nextQtdPointer;
  1988. }
  1989. ehciInstance->ehciQtdNumber++;
  1990. USB_HostEhciUnlock();
  1991. return length;
  1992. }
  1993. static usb_status_t USB_HostEhciQhQtdListDeinit(usb_host_ehci_instance_t *ehciInstance,
  1994. usb_host_ehci_pipe_t *ehciPipePointer)
  1995. {
  1996. volatile usb_host_ehci_qh_t *vltQhPointer;
  1997. usb_host_transfer_t *transfer;
  1998. usb_host_transfer_t *nextTransfer;
  1999. uint32_t currentQtdPointer;
  2000. uint8_t needStop = 0U;
  2001. vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
  2002. USB_HostEhciLock(); /* this API is called from APP, the host task may occupy to access the same resource */
  2003. /* remove qtd from qh */
  2004. /*for misra 13.5*/
  2005. currentQtdPointer = vltQhPointer->currentQtdPointer;
  2006. if ((0U == ((uint32_t)vltQhPointer->nextQtdPointer & EHCI_HOST_T_INVALID_VALUE)) ||
  2007. (0U == ((uint32_t)currentQtdPointer & EHCI_HOST_T_INVALID_VALUE)))
  2008. {
  2009. /* need stop async schedule */
  2010. if ((0U == (vltQhPointer->horizontalLinkPointer & EHCI_HOST_T_INVALID_VALUE)) &&
  2011. (ehciPipePointer->pipeCommon.pipeType != USB_ENDPOINT_INTERRUPT))
  2012. {
  2013. needStop = 1U;
  2014. }
  2015. if (0U != needStop)
  2016. {
  2017. USB_HostEhciStopAsync(ehciInstance);
  2018. }
  2019. vltQhPointer->currentQtdPointer = EHCI_HOST_T_INVALID_VALUE; /* invalid current qtd */
  2020. vltQhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE; /* invalid next qtd */
  2021. vltQhPointer->transferOverlayResults[0] &= (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
  2022. if (0U != needStop)
  2023. {
  2024. USB_HostEhciStartAsync(ehciInstance);
  2025. }
  2026. }
  2027. /* remove transfer from the QH transfer list */
  2028. transfer = vltQhPointer->ehciTransferHead;
  2029. vltQhPointer->ehciTransferTail = NULL;
  2030. vltQhPointer->ehciTransferHead = NULL;
  2031. USB_HostEhciUnlock();
  2032. /* release qtd and transfer callback*/
  2033. while (transfer != NULL)
  2034. {
  2035. nextTransfer = transfer->next; /* the transfer is released when call back */
  2036. transfer->transferSofar =
  2037. USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
  2038. (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
  2039. transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
  2040. 0U :
  2041. (transfer->transferLength - transfer->transferSofar);
  2042. /* callback function is different from the current condition */
  2043. transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferCancel);
  2044. transfer = nextTransfer;
  2045. }
  2046. return kStatus_USB_Success;
  2047. }
  2048. static usb_status_t USB_HostEhciTransferQtdListDeinit(usb_host_ehci_instance_t *ehciInstance,
  2049. usb_host_ehci_pipe_t *ehciPipePointer,
  2050. usb_host_transfer_t *transfer)
  2051. {
  2052. volatile usb_host_ehci_qh_t *vltQhPointer;
  2053. usb_host_transfer_t *preSearchTransfer;
  2054. uint32_t qhNextQtdValue;
  2055. uint32_t qtdPointerEntry;
  2056. uint32_t *searchQtdEntryPointer;
  2057. vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
  2058. USB_HostEhciLock(); /* this API is called from APP, the host task may occupy to access the same resource */
  2059. /* remove qtd from qh */
  2060. qhNextQtdValue = (uint32_t)vltQhPointer->currentQtdPointer;
  2061. qtdPointerEntry = *((uint32_t *)qhNextQtdValue + 2); /* note: qtdPointerEntry means qtd status */
  2062. if ((0U != (qhNextQtdValue & EHCI_HOST_T_INVALID_VALUE)) ||
  2063. (0U == (qtdPointerEntry & EHCI_HOST_QTD_STATUS_ACTIVE_MASK)))
  2064. {
  2065. qhNextQtdValue = (uint32_t)vltQhPointer->nextQtdPointer;
  2066. }
  2067. if (0U == (qhNextQtdValue & EHCI_HOST_T_INVALID_VALUE)) /* there is pending qtd in the qh */
  2068. {
  2069. /* this qh don't schedule temporarily */
  2070. if (ehciPipePointer->pipeCommon.pipeType != USB_ENDPOINT_INTERRUPT)
  2071. {
  2072. USB_HostEhciStopAsync(ehciInstance);
  2073. }
  2074. vltQhPointer->currentQtdPointer |= EHCI_HOST_T_INVALID_VALUE; /* invalid current qtd */
  2075. vltQhPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE; /* invalid next qtd */
  2076. if (ehciPipePointer->pipeCommon.pipeType != USB_ENDPOINT_INTERRUPT)
  2077. {
  2078. USB_HostEhciStartAsync(ehciInstance);
  2079. }
  2080. /* remove qtd from qh one by one */
  2081. qtdPointerEntry = transfer->union1.unitHead;
  2082. while (1U == 1U)
  2083. {
  2084. /* search qh's qtd list for qtdPointerEntry */
  2085. searchQtdEntryPointer = &qhNextQtdValue;
  2086. while (0U == ((*searchQtdEntryPointer) & EHCI_HOST_T_INVALID_VALUE))
  2087. {
  2088. if ((*searchQtdEntryPointer) == qtdPointerEntry)
  2089. {
  2090. *searchQtdEntryPointer = *((uint32_t *)qtdPointerEntry); /* remove the qtd from qh */
  2091. break;
  2092. }
  2093. else
  2094. {
  2095. searchQtdEntryPointer = (uint32_t *)(*searchQtdEntryPointer);
  2096. }
  2097. }
  2098. if (qtdPointerEntry == transfer->union2.unitTail)
  2099. {
  2100. break;
  2101. }
  2102. qtdPointerEntry = *((uint32_t *)qtdPointerEntry);
  2103. }
  2104. }
  2105. /* remove transfer from the QH transfer list */
  2106. preSearchTransfer = vltQhPointer->ehciTransferHead;
  2107. if (preSearchTransfer == transfer)
  2108. {
  2109. vltQhPointer->ehciTransferHead = preSearchTransfer->next;
  2110. }
  2111. else
  2112. {
  2113. while (preSearchTransfer != NULL)
  2114. {
  2115. if (preSearchTransfer->next == transfer)
  2116. {
  2117. preSearchTransfer->next = transfer->next;
  2118. break;
  2119. }
  2120. else
  2121. {
  2122. preSearchTransfer = preSearchTransfer->next;
  2123. }
  2124. }
  2125. }
  2126. USB_HostEhciUnlock();
  2127. /* release qtd and callback */
  2128. transfer->transferSofar =
  2129. USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
  2130. (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
  2131. transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
  2132. 0U :
  2133. (transfer->transferLength - transfer->transferSofar);
  2134. /* callback function is different from the current condition */
  2135. transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferCancel);
  2136. /* start this qh schedule */
  2137. vltQhPointer->transferOverlayResults[0] &= (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
  2138. if ((qhNextQtdValue != 0U) && (0U == (qhNextQtdValue & EHCI_HOST_T_INVALID_VALUE)))
  2139. {
  2140. vltQhPointer->nextQtdPointer = qhNextQtdValue;
  2141. }
  2142. return kStatus_USB_Success;
  2143. }
  2144. static usb_status_t USB_HostEhciQhInit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer)
  2145. {
  2146. usb_host_ehci_qh_t *qhPointer = NULL;
  2147. uint32_t address = 0;
  2148. uint32_t speed = 0;
  2149. uint32_t portNumber = 0;
  2150. uint32_t hubNumber = 0;
  2151. ;
  2152. uint32_t controlBits1 = 0U;
  2153. uint32_t controlBits2 = 0U;
  2154. /* get qh */
  2155. USB_HostEhciLock();
  2156. if (ehciInstance->ehciQhList != NULL)
  2157. {
  2158. qhPointer = (usb_host_ehci_qh_t *)ehciInstance->ehciQhList;
  2159. ehciInstance->ehciQhList =
  2160. (usb_host_ehci_qh_t *)(ehciInstance->ehciQhList->horizontalLinkPointer & EHCI_HOST_POINTER_ADDRESS_MASK);
  2161. }
  2162. USB_HostEhciUnlock();
  2163. if (qhPointer == NULL)
  2164. {
  2165. #ifdef HOST_EHCO
  2166. usb_echo("get qh error\r\n");
  2167. #endif
  2168. return kStatus_USB_Error;
  2169. }
  2170. ehciPipePointer->ehciQh = (void *)qhPointer;
  2171. /* initialize qh */
  2172. USB_HostEhciZeroMem((void *)qhPointer, sizeof(usb_host_ehci_qh_t) / 4U);
  2173. qhPointer->horizontalLinkPointer = EHCI_HOST_T_INVALID_VALUE;
  2174. qhPointer->currentQtdPointer = EHCI_HOST_T_INVALID_VALUE;
  2175. qhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
  2176. qhPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
  2177. qhPointer->ehciPipePointer = ehciPipePointer;
  2178. qhPointer->timeOutLabel = 0;
  2179. qhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
  2180. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  2181. (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
  2182. /* initialize staticEndpointStates[0] */
  2183. if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT)
  2184. {
  2185. /* Software should set the RL field to zero if the queue head is an interrupt endpoint. */
  2186. controlBits1 |= ((0UL << EHCI_HOST_QH_RL_SHIFT) & EHCI_HOST_QH_RL_MASK);
  2187. }
  2188. else
  2189. {
  2190. if (ehciPipePointer->pipeCommon.nakCount >= 16U)
  2191. {
  2192. controlBits1 |= ((15UL << EHCI_HOST_QH_RL_SHIFT) & EHCI_HOST_QH_RL_MASK);
  2193. }
  2194. else
  2195. {
  2196. controlBits1 |=
  2197. (((uint32_t)ehciPipePointer->pipeCommon.nakCount << EHCI_HOST_QH_RL_SHIFT) & EHCI_HOST_QH_RL_MASK);
  2198. }
  2199. }
  2200. if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL)
  2201. {
  2202. if (speed != USB_SPEED_HIGH)
  2203. {
  2204. controlBits1 |= (1UL << EHCI_HOST_QH_C_SHIFT);
  2205. }
  2206. controlBits1 |= (1UL << EHCI_HOST_QH_DTC_SHIFT);
  2207. }
  2208. controlBits1 |= ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT);
  2209. controlBits1 |= (speed << EHCI_HOST_QH_EPS_SHIFT);
  2210. controlBits1 |= ((uint32_t)ehciPipePointer->pipeCommon.endpointAddress << EHCI_HOST_QH_ENDPT_SHIFT);
  2211. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  2212. (uint32_t)kUSB_HostGetDeviceAddress, &address);
  2213. controlBits1 |= (address << EHCI_HOST_QH_DEVICE_ADDRESS_SHIFT);
  2214. qhPointer->staticEndpointStates[0] = controlBits1;
  2215. if (speed == USB_SPEED_HIGH)
  2216. {
  2217. controlBits2 |= ((uint32_t)ehciPipePointer->pipeCommon.numberPerUframe << EHCI_HOST_QH_MULT_SHIFT);
  2218. }
  2219. else
  2220. {
  2221. controlBits2 |= (0x00000001UL << EHCI_HOST_QH_MULT_SHIFT);
  2222. }
  2223. /*initialize staticEndpointStates[1] */
  2224. if (speed != USB_SPEED_HIGH)
  2225. {
  2226. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  2227. (uint32_t)kUSB_HostGetDeviceHSHubNumber, &hubNumber);
  2228. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  2229. (uint32_t)kUSB_HostGetDeviceHSHubPort, &portNumber);
  2230. }
  2231. else
  2232. {
  2233. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  2234. (uint32_t)kUSB_HostGetDeviceHubNumber, &hubNumber);
  2235. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  2236. (uint32_t)kUSB_HostGetDevicePortNumber, &portNumber);
  2237. }
  2238. controlBits2 |= (portNumber << EHCI_HOST_QH_PORT_NUMBER_SHIFT);
  2239. controlBits2 |= (hubNumber << EHCI_HOST_QH_HUB_ADDR_SHIFT);
  2240. controlBits2 |= ((uint32_t)ehciPipePointer->uframeCmask << EHCI_HOST_QH_UFRAME_CMASK_SHIFT);
  2241. controlBits2 |= ((uint32_t)ehciPipePointer->uframeSmask << EHCI_HOST_QH_UFRAME_SMASK_SHIFT);
  2242. qhPointer->staticEndpointStates[1] = controlBits2;
  2243. return kStatus_USB_Success;
  2244. }
  2245. static usb_status_t USB_HostEhciQhDeinit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer)
  2246. {
  2247. usb_host_ehci_qh_t *qhPointer;
  2248. qhPointer = (usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
  2249. /* de-initialize qtd from qh */
  2250. (void)USB_HostEhciQhQtdListDeinit(ehciInstance, ehciPipePointer);
  2251. /* release QH */
  2252. USB_HostEhciLock();
  2253. qhPointer->horizontalLinkPointer = (uint32_t)ehciInstance->ehciQhList;
  2254. ehciInstance->ehciQhList = qhPointer;
  2255. USB_HostEhciUnlock();
  2256. return kStatus_USB_Success;
  2257. }
  2258. static void USB_HostEhciAddQhToFrame(usb_host_ehci_instance_t *ehciInstance,
  2259. uint32_t entryPointerValue,
  2260. uint16_t framePos,
  2261. uint16_t uframeInterval)
  2262. {
  2263. volatile uint32_t *frameEntryPointer;
  2264. uint32_t frameEntryValue;
  2265. void *temp;
  2266. /* search for the inserting point by interval */
  2267. temp = (void *)ehciInstance->ehciFrameList;
  2268. frameEntryPointer = (volatile uint32_t *)(&((uint32_t *)temp)[framePos]);
  2269. while (NULL != frameEntryPointer)
  2270. {
  2271. frameEntryValue = *frameEntryPointer;
  2272. if (0U != (frameEntryValue & EHCI_HOST_T_INVALID_VALUE))
  2273. {
  2274. /* insert into the end */
  2275. *((uint32_t *)entryPointerValue) = EHCI_HOST_T_INVALID_VALUE;
  2276. *frameEntryPointer = (entryPointerValue | EHCI_HOST_POINTER_TYPE_QH);
  2277. break;
  2278. }
  2279. if ((frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK) == entryPointerValue)
  2280. {
  2281. return; /* has inserted */
  2282. }
  2283. if (((frameEntryValue & EHCI_HOST_POINTER_TYPE_MASK) == EHCI_HOST_POINTER_TYPE_QH) &&
  2284. (((usb_host_ehci_qh_t *)(frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK))
  2285. ->ehciPipePointer->uframeInterval <= uframeInterval))
  2286. {
  2287. /* insert into this point */
  2288. *((uint32_t *)entryPointerValue) = frameEntryValue;
  2289. *frameEntryPointer = (entryPointerValue | EHCI_HOST_POINTER_TYPE_QH);
  2290. return;
  2291. }
  2292. else
  2293. {
  2294. frameEntryPointer = (volatile uint32_t *)(frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK);
  2295. }
  2296. }
  2297. }
  2298. static void USB_HostEhciRemoveFromFrame(usb_host_ehci_instance_t *ehciInstance,
  2299. uint32_t entryPointerValue,
  2300. uint16_t framePos)
  2301. {
  2302. volatile uint32_t *frameEntryPointer;
  2303. uint32_t frameEntryValue;
  2304. void *temp;
  2305. /* search for the qh/itd/sitd entry */
  2306. temp = (void *)ehciInstance->ehciFrameList;
  2307. frameEntryPointer = (volatile uint32_t *)(&((uint32_t *)temp)[framePos]);
  2308. while (NULL != frameEntryPointer)
  2309. {
  2310. frameEntryValue = *frameEntryPointer;
  2311. if (0U != (frameEntryValue & EHCI_HOST_T_INVALID_VALUE))
  2312. {
  2313. return;
  2314. }
  2315. if ((frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK) == entryPointerValue)
  2316. {
  2317. /* remove the entry */
  2318. *frameEntryPointer = *((uint32_t *)entryPointerValue);
  2319. break;
  2320. }
  2321. else
  2322. {
  2323. frameEntryPointer = (volatile uint32_t *)(frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK);
  2324. }
  2325. }
  2326. }
  2327. #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
  2328. static void USB_HostEhciLinkSitd(usb_host_ehci_instance_t *ehciInstance,
  2329. usb_host_ehci_pipe_t *ehciPipePointer,
  2330. void *startEntryPointer)
  2331. {
  2332. usb_host_ehci_iso_t *isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
  2333. usb_host_ehci_sitd_t *sitdPointer;
  2334. uint32_t distance;
  2335. uint32_t frameInterval;
  2336. uint32_t shouldLinkFrame;
  2337. uint32_t currentFrame;
  2338. void *temp;
  2339. frameInterval = ((uint32_t)ehciPipePointer->uframeInterval >> 3U);
  2340. if (isoPointer->lastLinkFrame == 0xFFFFU) /* first link */
  2341. {
  2342. currentFrame = ((ehciInstance->ehciIpBase->FRINDEX & USB_HOST_EHCI_MAX_MICRFRAME_VALUE) >> 3U);
  2343. currentFrame = ((uint32_t)(currentFrame + USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER) &
  2344. (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3U)); /* add USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER */
  2345. /* frame should align with interval */
  2346. if (currentFrame <= ehciPipePointer->startFrame)
  2347. {
  2348. currentFrame = ehciPipePointer->startFrame;
  2349. }
  2350. else
  2351. {
  2352. currentFrame -= ehciPipePointer->startFrame;
  2353. currentFrame = ((currentFrame + frameInterval - 1U) & (~(frameInterval - 1U)));
  2354. currentFrame += ehciPipePointer->startFrame;
  2355. }
  2356. }
  2357. else
  2358. {
  2359. shouldLinkFrame = isoPointer->lastLinkFrame + frameInterval; /* continuous next should link frame */
  2360. if (shouldLinkFrame > USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3U)
  2361. {
  2362. shouldLinkFrame = shouldLinkFrame - ((USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3U) + 1U);
  2363. }
  2364. currentFrame = ((ehciInstance->ehciIpBase->FRINDEX & USB_HOST_EHCI_MAX_MICRFRAME_VALUE) >> 3U);
  2365. distance =
  2366. ((shouldLinkFrame + (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3U) + 1U - currentFrame) &
  2367. (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3)); /* get the distance from shouldLinkFrame to currentFrame */
  2368. /* shouldLinkFrame has add frameInterval, think about the align with interval, so here add (frameInterval *
  2369. * 2) */
  2370. if ((distance <=
  2371. (USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER + frameInterval * USB_HOST_EHCI_ISO_MAX_CONTINUOUS_TRANSFER)) &&
  2372. (distance > 0U))
  2373. {
  2374. currentFrame = shouldLinkFrame;
  2375. }
  2376. else /* re-link */
  2377. {
  2378. currentFrame =
  2379. ((currentFrame + USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER) & (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3));
  2380. /*if (currentFrame > (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3))
  2381. {
  2382. currentFrame = currentFrame - ((USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3) + 1U);
  2383. }*/
  2384. /* frame should align with interval */
  2385. if (currentFrame <= ehciPipePointer->startFrame)
  2386. {
  2387. currentFrame = ehciPipePointer->startFrame;
  2388. }
  2389. else
  2390. {
  2391. currentFrame -= ehciPipePointer->startFrame;
  2392. currentFrame = ((currentFrame + frameInterval - 1U) & (~(frameInterval - 1U)));
  2393. currentFrame += ehciPipePointer->startFrame;
  2394. }
  2395. }
  2396. }
  2397. if (currentFrame >= USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE) /* frame turn around */
  2398. {
  2399. shouldLinkFrame =
  2400. (currentFrame - USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE); /* shouldLinkFrame means inserted frame position */
  2401. }
  2402. else
  2403. {
  2404. shouldLinkFrame = currentFrame; /* shouldLinkFrame means inserted frame position */
  2405. }
  2406. sitdPointer = (usb_host_ehci_sitd_t *)startEntryPointer;
  2407. while (NULL != sitdPointer)
  2408. {
  2409. sitdPointer->frameEntryIndex = (uint16_t)shouldLinkFrame;
  2410. /* add to frame list head */
  2411. temp = (void *)ehciInstance->ehciFrameList;
  2412. sitdPointer->nextLinkPointer = ((uint32_t *)temp)[shouldLinkFrame];
  2413. ((uint32_t *)temp)[shouldLinkFrame] = ((uint32_t)sitdPointer | EHCI_HOST_POINTER_TYPE_SITD);
  2414. if (sitdPointer->nextSitdIndex == 0xFFU) /* 0xFF is invalid value */
  2415. {
  2416. break;
  2417. }
  2418. sitdPointer = &(ehciInstance->ehciSitdIndexBase[sitdPointer->nextSitdIndex]); /* next sitd */
  2419. shouldLinkFrame += frameInterval;
  2420. currentFrame += frameInterval;
  2421. if (shouldLinkFrame >= USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE)
  2422. {
  2423. shouldLinkFrame = (shouldLinkFrame - USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE);
  2424. }
  2425. }
  2426. if (currentFrame > (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3))
  2427. {
  2428. currentFrame = currentFrame - ((USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3) + 1U);
  2429. }
  2430. isoPointer->lastLinkFrame = (uint16_t)currentFrame; /* save the last link frame value */
  2431. }
  2432. static usb_status_t USB_HostEhciSitdArrayInit(usb_host_ehci_instance_t *ehciInstance,
  2433. usb_host_ehci_pipe_t *ehciPipePointer,
  2434. usb_host_transfer_t *transfer)
  2435. {
  2436. usb_host_ehci_iso_t *isoPointer;
  2437. uint32_t sitdNumber = 0;
  2438. usb_host_ehci_sitd_t *sitdPointer;
  2439. uint32_t dataLength = 0;
  2440. uint32_t sitdLength = 0;
  2441. uint32_t dataBufferValue;
  2442. uint32_t hubNumber = 0U;
  2443. uint32_t portNumber = 0U;
  2444. uint32_t address = 0U;
  2445. uint32_t tmp;
  2446. uint32_t *temp;
  2447. uint32_t index;
  2448. int32_t tempIndex;
  2449. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  2450. (uint32_t)kUSB_HostGetDeviceAddress, &address);
  2451. sitdNumber = ((transfer->transferLength - 1U + (ehciPipePointer->pipeCommon.maxPacketSize)) /
  2452. (ehciPipePointer->pipeCommon.maxPacketSize));
  2453. /* get sitd array */
  2454. /* USB_HostEhciLock(); */
  2455. if (ehciInstance->ehciSitdNumber >= sitdNumber)
  2456. {
  2457. sitdPointer = ehciInstance->ehciSitdList;
  2458. transfer->union1.unitHead = (uint32_t)sitdPointer;
  2459. for (index = 1U; index < sitdNumber; ++index)
  2460. {
  2461. /*misra 10.8*/
  2462. tempIndex = (((usb_host_ehci_sitd_t *)(sitdPointer->nextLinkPointer & 0xFFFFFFFEU)) -
  2463. ehciInstance->ehciSitdIndexBase);
  2464. sitdPointer->nextSitdIndex = (uint8_t)tempIndex;
  2465. sitdPointer = (usb_host_ehci_sitd_t *)(sitdPointer->nextLinkPointer & 0xFFFFFFFEU);
  2466. }
  2467. sitdPointer->nextSitdIndex = 0xFF;
  2468. ehciInstance->ehciSitdList = (usb_host_ehci_sitd_t *)(sitdPointer->nextLinkPointer & 0xFFFFFFFEU);
  2469. ehciInstance->ehciSitdNumber -= (uint8_t)sitdNumber;
  2470. }
  2471. else
  2472. {
  2473. /* USB_HostEhciUnlock(); */
  2474. return kStatus_USB_Error;
  2475. }
  2476. /* USB_HostEhciUnlock(); */
  2477. transfer->union2.unitTail = (uint32_t)sitdPointer;
  2478. /* initialize sitd array */
  2479. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  2480. (uint32_t)kUSB_HostGetDeviceHubNumber, &hubNumber);
  2481. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  2482. (uint32_t)kUSB_HostGetDevicePortNumber, &portNumber);
  2483. sitdPointer = (usb_host_ehci_sitd_t *)transfer->union1.unitHead;
  2484. dataLength = transfer->transferLength;
  2485. while (0U != sitdNumber)
  2486. {
  2487. sitdNumber--;
  2488. USB_HostEhciZeroMem((void *)sitdPointer, 7);
  2489. sitdLength = dataLength;
  2490. if (sitdLength > ehciPipePointer->pipeCommon.maxPacketSize)
  2491. {
  2492. sitdLength = ehciPipePointer->pipeCommon.maxPacketSize;
  2493. }
  2494. dataBufferValue = (uint32_t)(transfer->transferBuffer + (transfer->transferLength - dataLength));
  2495. dataLength -= sitdLength; /* update left data length */
  2496. sitdPointer->transferResults[1] = dataBufferValue;
  2497. sitdPointer->transferResults[2] = ((dataBufferValue + 4U * 1024U) & 0xFFFFF000U);
  2498. sitdPointer->endpointStates[0] =
  2499. (((uint32_t)ehciPipePointer->pipeCommon.direction << EHCI_HOST_SITD_DIRECTION_SHIFT) |
  2500. (portNumber << EHCI_HOST_SITD_PORT_NUMBER_SHIFT) | (hubNumber << EHCI_HOST_SITD_HUB_ADDR_SHIFT) |
  2501. ((uint32_t)ehciPipePointer->pipeCommon.endpointAddress << EHCI_HOST_SITD_ENDPT_SHIFT) |
  2502. (address << EHCI_HOST_SITD_DEVICE_ADDRESS_SHIFT));
  2503. sitdPointer->transferResults[0] =
  2504. ((sitdLength << EHCI_HOST_SITD_TOTAL_BYTES_SHIFT) | (EHCI_HOST_SITD_STATUS_ACTIVE_MASK));
  2505. if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH)
  2506. {
  2507. sitdPointer->endpointStates[1] = (((uint32_t)ehciPipePointer->uframeCmask << EHCI_HOST_SITD_CMASK_SHIFT) |
  2508. ((uint32_t)ehciPipePointer->uframeSmask << EHCI_HOST_SITD_SMASK_SHIFT));
  2509. tmp = (sitdLength + 187U) / 188U;
  2510. if (tmp > 1U)
  2511. {
  2512. sitdPointer->transferResults[2] |= (0x01U << EHCI_HOST_SITD_TP_SHIFT); /* for iso split */
  2513. }
  2514. else
  2515. {
  2516. sitdPointer->transferResults[2] |= (0x00U << EHCI_HOST_SITD_TP_SHIFT); /* for iso split */
  2517. }
  2518. sitdPointer->transferResults[2] |= (tmp << EHCI_HOST_SITD_TCOUNT_SHIFT); /* for iso split */
  2519. }
  2520. sitdPointer->backPointer = EHCI_HOST_T_INVALID_VALUE;
  2521. sitdPointer = (ehciInstance->ehciSitdIndexBase + sitdPointer->nextSitdIndex);
  2522. }
  2523. sitdPointer = (usb_host_ehci_sitd_t *)transfer->union2.unitTail;
  2524. sitdPointer->transferResults[0] |= (1UL << EHCI_HOST_SITD_IOC_SHIFT); /* last set IOC */
  2525. /* link transfer to usb_host_ehci_iso_t transfer list */
  2526. isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
  2527. USB_HostEhciLock();
  2528. if (isoPointer->ehciTransferHead == NULL)
  2529. {
  2530. transfer->next = NULL;
  2531. isoPointer->ehciTransferTail = transfer;
  2532. isoPointer->ehciTransferHead = transfer;
  2533. }
  2534. else
  2535. {
  2536. transfer->next = NULL;
  2537. isoPointer->ehciTransferTail->next = transfer;
  2538. isoPointer->ehciTransferTail = transfer;
  2539. }
  2540. USB_HostEhciUnlock();
  2541. /* link itd to frame list (note: initialize frameEntryIndex)*/
  2542. /*misra 11.6*/
  2543. temp = (uint32_t *)(transfer->union1.unitHead);
  2544. USB_HostEhciLinkSitd(ehciInstance, ehciPipePointer, (void *)temp);
  2545. return kStatus_USB_Success;
  2546. }
  2547. static uint32_t USB_HostEhciSitdArrayRelease(usb_host_ehci_instance_t *ehciInstance,
  2548. usb_host_ehci_sitd_t *startSitdPointer,
  2549. usb_host_ehci_sitd_t *endSitdPointer)
  2550. {
  2551. usb_host_ehci_sitd_t *sitdPointer = startSitdPointer;
  2552. uint32_t leftLength = 0;
  2553. /* remove itd from frame list */
  2554. while (1U == 1U)
  2555. {
  2556. /* record the transfer's result length */
  2557. leftLength +=
  2558. ((sitdPointer->transferResults[0] & EHCI_HOST_SITD_TOTAL_BYTES_MASK) >> EHCI_HOST_SITD_TOTAL_BYTES_SHIFT);
  2559. USB_HostEhciRemoveFromFrame(ehciInstance, (uint32_t)sitdPointer,
  2560. sitdPointer->frameEntryIndex); /* remove from the inserted frame list */
  2561. /* release itd */
  2562. /* USB_HostEhciLock(); */
  2563. /*set next link pointer to invalid in case hardware access invalid sitd structure in special case*/
  2564. sitdPointer->nextLinkPointer = (((uint32_t)ehciInstance->ehciSitdList) | EHCI_HOST_T_INVALID_VALUE);
  2565. ehciInstance->ehciSitdList = sitdPointer;
  2566. ehciInstance->ehciSitdNumber++;
  2567. /* USB_HostEhciUnlock(); */
  2568. if (sitdPointer == endSitdPointer)
  2569. {
  2570. break;
  2571. }
  2572. sitdPointer = &(ehciInstance->ehciSitdIndexBase[sitdPointer->nextSitdIndex]);
  2573. }
  2574. return leftLength;
  2575. }
  2576. static usb_status_t USB_HostEhciSitdArrayDeinit(usb_host_ehci_instance_t *ehciInstance,
  2577. usb_host_ehci_pipe_t *ehciPipePointer)
  2578. {
  2579. usb_host_ehci_iso_t *isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
  2580. usb_host_transfer_t *transfer;
  2581. usb_host_transfer_t *nextTransfer;
  2582. /* firstly remove the transfer (because host task may occupy to access the resource) */
  2583. USB_HostEhciLock();
  2584. transfer = isoPointer->ehciTransferHead;
  2585. isoPointer->ehciTransferTail = NULL;
  2586. isoPointer->ehciTransferHead = NULL;
  2587. USB_HostEhciUnlock();
  2588. while (transfer != NULL)
  2589. {
  2590. nextTransfer = transfer->next;
  2591. /* remove sitd from frame list and release itd */
  2592. transfer->transferSofar =
  2593. transfer->transferLength - USB_HostEhciSitdArrayRelease(ehciInstance,
  2594. (usb_host_ehci_sitd_t *)transfer->union1.unitHead,
  2595. (usb_host_ehci_sitd_t *)transfer->union2.unitTail);
  2596. /* callback function is different from the current condition */
  2597. transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferCancel);
  2598. /* next transfer */
  2599. transfer = nextTransfer;
  2600. }
  2601. return kStatus_USB_Success;
  2602. }
  2603. #endif /* USB_HOST_CONFIG_EHCI_MAX_SITD */
  2604. #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
  2605. static uint32_t USB_HostEhciGetItdLinkFrame(usb_host_ehci_instance_t *ehciInstance,
  2606. uint32_t lastLinkUframe,
  2607. uint16_t startUframe,
  2608. uint16_t uframeInterval)
  2609. {
  2610. uint32_t shouldLinkUframe;
  2611. uint32_t currentUframe;
  2612. uint32_t distance;
  2613. if (lastLinkUframe != 0xFFFFU)
  2614. {
  2615. shouldLinkUframe = lastLinkUframe + uframeInterval;
  2616. if (shouldLinkUframe > USB_HOST_EHCI_MAX_MICRFRAME_VALUE)
  2617. {
  2618. shouldLinkUframe = shouldLinkUframe - (USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U);
  2619. }
  2620. currentUframe = (ehciInstance->ehciIpBase->FRINDEX & USB_HOST_EHCI_MAX_MICRFRAME_VALUE);
  2621. distance = ((shouldLinkUframe + USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U - currentUframe) &
  2622. USB_HOST_EHCI_MAX_MICRFRAME_VALUE); /* get the distance */
  2623. /* shouldLinkUframe has add uframeInterval, think about the align with interval, so here add (uframeInterval
  2624. * * 2) */
  2625. if ((distance <= ((uint32_t)USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER +
  2626. ((uint32_t)uframeInterval * USB_HOST_EHCI_ISO_MAX_CONTINUOUS_TRANSFER))) &&
  2627. (distance > 2U))
  2628. {
  2629. currentUframe = shouldLinkUframe;
  2630. }
  2631. else /* re-link */
  2632. {
  2633. currentUframe =
  2634. ((currentUframe + USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER) & USB_HOST_EHCI_MAX_MICRFRAME_VALUE);
  2635. /*if (currentUframe > USB_HOST_EHCI_MAX_MICRFRAME_VALUE)
  2636. {
  2637. currentUframe = currentUframe - (USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U);
  2638. }*/
  2639. /* uframe should align with interval */
  2640. if (currentUframe <= startUframe)
  2641. {
  2642. currentUframe = startUframe;
  2643. }
  2644. else
  2645. {
  2646. currentUframe -= startUframe;
  2647. currentUframe = ((uint32_t)(currentUframe + uframeInterval) &
  2648. (~((uint32_t)uframeInterval - 1U))); /* uframeInterval is power of 2 */
  2649. currentUframe += startUframe;
  2650. }
  2651. }
  2652. }
  2653. else
  2654. {
  2655. currentUframe = (ehciInstance->ehciIpBase->FRINDEX & USB_HOST_EHCI_MAX_MICRFRAME_VALUE);
  2656. currentUframe = ((currentUframe + USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER) & USB_HOST_EHCI_MAX_MICRFRAME_VALUE);
  2657. /* uframe should align with interval */
  2658. if (currentUframe <= startUframe)
  2659. {
  2660. currentUframe = startUframe;
  2661. }
  2662. else
  2663. {
  2664. currentUframe -= startUframe;
  2665. currentUframe =
  2666. ((currentUframe + uframeInterval) & (~(uframeInterval - 1U))); /* uframeInterval is power of 2 */
  2667. currentUframe += startUframe;
  2668. }
  2669. }
  2670. return currentUframe;
  2671. }
  2672. static usb_status_t USB_HostEhciItdArrayInit(usb_host_ehci_instance_t *ehciInstance,
  2673. usb_host_ehci_pipe_t *ehciPipePointer,
  2674. usb_host_transfer_t *transfer)
  2675. {
  2676. usb_host_ehci_iso_t *isoPointer;
  2677. usb_host_ehci_itd_t *itdPointer = NULL;
  2678. usb_host_ehci_itd_t *itdHead = NULL;
  2679. usb_host_ehci_itd_t *tmpItdPointer;
  2680. uint32_t dataLength; /* the remaining data for sending */
  2681. uint32_t transactionLength; /* the initializing transaction descriptor data length */
  2682. uint32_t itdBufferValue;
  2683. uint32_t itdBufferBaseValue; /* for calculating PG value */
  2684. uint32_t address = 0U;
  2685. uint32_t lastShouldLinkUframe;
  2686. uint32_t linkUframe;
  2687. uint32_t minDataPerItd =
  2688. (uint32_t)ehciPipePointer->pipeCommon.numberPerUframe * ehciPipePointer->pipeCommon.maxPacketSize;
  2689. uint8_t maxItdNumber;
  2690. uint16_t index = 0;
  2691. isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
  2692. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  2693. (uint32_t)kUSB_HostGetDeviceAddress, &address);
  2694. /* max needed itd number, the actual needed number may be less because micro-frame interval may be less than 8 */
  2695. maxItdNumber = (uint8_t)((transfer->transferLength - 1U + minDataPerItd) / minDataPerItd);
  2696. if (ehciPipePointer->uframeInterval < 8U)
  2697. {
  2698. maxItdNumber = (uint8_t)((maxItdNumber * ehciPipePointer->uframeInterval + 7U) / 8U) + 1U;
  2699. }
  2700. if (maxItdNumber > ehciInstance->ehciItdNumber)
  2701. {
  2702. return kStatus_USB_Error;
  2703. }
  2704. /* link transfer to usb_host_ehci_iso_t transfer list */
  2705. transfer->next = NULL;
  2706. /* USB_HostEhciLock(); */
  2707. if (isoPointer->ehciTransferHead == NULL)
  2708. {
  2709. isoPointer->ehciTransferTail = transfer;
  2710. isoPointer->ehciTransferHead = transfer;
  2711. }
  2712. else
  2713. {
  2714. isoPointer->ehciTransferTail->next = transfer;
  2715. isoPointer->ehciTransferTail = transfer;
  2716. }
  2717. /* USB_HostEhciUnlock(); */
  2718. dataLength = transfer->transferLength;
  2719. transfer->union1.unitHead = 0U;
  2720. /* get the link micro-frame */
  2721. lastShouldLinkUframe = USB_HostEhciGetItdLinkFrame(
  2722. ehciInstance, isoPointer->lastLinkFrame,
  2723. (uint16_t)((ehciPipePointer->startFrame << 3) + ehciPipePointer->startUframe), ehciPipePointer->uframeInterval);
  2724. if (lastShouldLinkUframe > USB_HOST_EHCI_MAX_MICRFRAME_VALUE)
  2725. {
  2726. linkUframe = lastShouldLinkUframe - (USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U);
  2727. }
  2728. else
  2729. {
  2730. linkUframe = lastShouldLinkUframe;
  2731. }
  2732. itdHead = ehciInstance->ehciItdList;
  2733. while (0U != dataLength)
  2734. {
  2735. /* get one idle itd */
  2736. tmpItdPointer = ehciInstance->ehciItdList;
  2737. if (tmpItdPointer == NULL)
  2738. {
  2739. return kStatus_USB_Error; /* this should not reach */
  2740. }
  2741. ehciInstance->ehciItdList = (usb_host_ehci_itd_t *)tmpItdPointer->nextItdPointer;
  2742. ehciInstance->ehciItdNumber -= 1U;
  2743. tmpItdPointer->nextItdPointer = NULL;
  2744. /* use the itd */
  2745. if (transfer->union1.unitHead == 0U) /* first itd */
  2746. {
  2747. transfer->union1.unitHead = (uint32_t)tmpItdPointer;
  2748. }
  2749. else /* link itd list */
  2750. {
  2751. itdPointer->nextItdPointer = tmpItdPointer;
  2752. }
  2753. itdPointer = tmpItdPointer;
  2754. /* itd has been set to all zero when releasing */
  2755. itdBufferValue = (uint32_t)(transfer->transferBuffer + (transfer->transferLength - dataLength));
  2756. itdBufferBaseValue = itdBufferValue;
  2757. for (index = 0; index < 7U; ++index)
  2758. {
  2759. itdPointer->bufferPointers[index] = ((itdBufferBaseValue + ((uint32_t)index * 4U * 1024U)) & 0xFFFFF000U);
  2760. }
  2761. /* initialize iTD common fields */
  2762. itdPointer->bufferPointers[0] |=
  2763. (((uint32_t)ehciPipePointer->pipeCommon.endpointAddress << EHCI_HOST_ITD_ENDPT_SHIFT) |
  2764. (address << EHCI_HOST_ITD_DEVICE_ADDRESS_SHIFT));
  2765. itdPointer->bufferPointers[1] |=
  2766. (((uint32_t)ehciPipePointer->pipeCommon.direction << EHCI_HOST_ITD_DIRECTION_SHIFT) |
  2767. ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_ITD_MAX_PACKET_SIZE_SHIFT));
  2768. itdPointer->bufferPointers[2] |= (ehciPipePointer->pipeCommon.numberPerUframe);
  2769. /* initialize transaction descriptors */
  2770. for (index = (uint8_t)(linkUframe & 0x0007U); index < 8U; index += ehciPipePointer->uframeInterval)
  2771. {
  2772. transactionLength = ((dataLength > minDataPerItd) ? minDataPerItd : dataLength);
  2773. /* initialize the uframeIndex's transaction descriptor in itd */
  2774. itdPointer->transactions[index] =
  2775. ((EHCI_HOST_ITD_STATUS_ACTIVE_MASK) | (transactionLength << EHCI_HOST_ITD_TRANSACTION_LEN_SHIFT) |
  2776. ((((itdBufferValue & 0xFFFFF000U) - (itdBufferBaseValue & 0xFFFFF000U)) >>
  2777. EHCI_HOST_ITD_BUFFER_POINTER_SHIFT)
  2778. << EHCI_HOST_ITD_PG_SHIFT) |
  2779. (itdBufferValue & EHCI_HOST_ITD_TRANSACTION_OFFSET_MASK));
  2780. dataLength -= transactionLength;
  2781. itdBufferValue += transactionLength;
  2782. if (dataLength <= 0U)
  2783. {
  2784. break;
  2785. }
  2786. }
  2787. }
  2788. transfer->union2.unitTail = (uint32_t)itdPointer;
  2789. itdPointer->transactions[index] |= (1UL << EHCI_HOST_ITD_IOC_SHIFT); /* last set IOC */
  2790. itdPointer = itdHead;
  2791. /* link itd to frame list (note: initialize frameEntryIndex)*/
  2792. while (NULL != itdPointer)
  2793. {
  2794. void *temp = (void *)ehciInstance->ehciFrameList;
  2795. uint32_t *linkPointer = &((uint32_t *)temp)[linkUframe >> 3];
  2796. uint32_t linkValue = *linkPointer;
  2797. itdPointer->frameEntryIndex = linkUframe >> 3;
  2798. while ((0U == (linkValue & EHCI_HOST_T_INVALID_VALUE)) &&
  2799. ((linkValue & EHCI_HOST_POINTER_TYPE_MASK) == EHCI_HOST_POINTER_TYPE_ITD))
  2800. {
  2801. linkPointer = (uint32_t *)(linkValue & EHCI_HOST_POINTER_ADDRESS_MASK);
  2802. linkValue = *linkPointer;
  2803. }
  2804. itdPointer->nextLinkPointer = *linkPointer;
  2805. *linkPointer = ((uint32_t)itdPointer | EHCI_HOST_POINTER_TYPE_ITD);
  2806. itdPointer = itdPointer->nextItdPointer;
  2807. if (itdPointer == NULL)
  2808. {
  2809. break;
  2810. }
  2811. linkUframe += ehciPipePointer->uframeInterval;
  2812. lastShouldLinkUframe += ehciPipePointer->uframeInterval;
  2813. if (linkUframe >= (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE << 3))
  2814. {
  2815. linkUframe = (linkUframe - (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE << 3));
  2816. }
  2817. }
  2818. if (lastShouldLinkUframe > USB_HOST_EHCI_MAX_MICRFRAME_VALUE)
  2819. {
  2820. lastShouldLinkUframe = lastShouldLinkUframe - (USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U);
  2821. }
  2822. isoPointer->lastLinkFrame = (uint16_t)lastShouldLinkUframe;
  2823. return kStatus_USB_Success;
  2824. }
  2825. static uint32_t USB_HostEhciItdArrayRelease(usb_host_ehci_instance_t *ehciInstance,
  2826. usb_host_ehci_itd_t *startItdPointer,
  2827. usb_host_ehci_itd_t *endItdPointer)
  2828. {
  2829. usb_host_ehci_itd_t *itdPointer = startItdPointer;
  2830. uint8_t index;
  2831. uint32_t doneLength = 0;
  2832. /* remove itd from frame list */
  2833. while (1U == 1U)
  2834. {
  2835. /* record the transfer's result length */
  2836. for (index = 0U; index < 8U; ++index)
  2837. {
  2838. doneLength += ((itdPointer->transactions[index] & EHCI_HOST_ITD_TRANSACTION_LEN_MASK) >>
  2839. EHCI_HOST_ITD_TRANSACTION_LEN_SHIFT);
  2840. }
  2841. USB_HostEhciRemoveFromFrame(ehciInstance, (uint32_t)itdPointer,
  2842. (uint16_t)itdPointer->frameEntryIndex); /* remove from the inserted frame list */
  2843. /* release itd */
  2844. /* USB_HostEhciLock(); */
  2845. /*set next link pointer to invalid in case hardware access invalid itd structure in special case*/
  2846. itdPointer->nextLinkPointer = EHCI_HOST_T_INVALID_VALUE;
  2847. USB_HostEhciZeroMem((uint32_t *)(void *)itdPointer + 1, ((sizeof(usb_host_ehci_itd_t) >> 2) - 4U));
  2848. itdPointer->nextItdPointer = (usb_host_ehci_itd_t *)ehciInstance->ehciItdList;
  2849. ehciInstance->ehciItdList = itdPointer;
  2850. ehciInstance->ehciItdNumber++;
  2851. /* USB_HostEhciUnlock(); */
  2852. if (itdPointer == endItdPointer)
  2853. {
  2854. break;
  2855. }
  2856. itdPointer = itdPointer->nextItdPointer;
  2857. }
  2858. return doneLength;
  2859. }
  2860. static usb_status_t USB_HostEhciItdArrayDeinit(usb_host_ehci_instance_t *ehciInstance,
  2861. usb_host_ehci_pipe_t *ehciPipePointer)
  2862. {
  2863. usb_host_ehci_iso_t *isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
  2864. usb_host_transfer_t *transfer;
  2865. usb_host_transfer_t *nextTransfer;
  2866. uint32_t doneLength = 0;
  2867. /* firstly remove the transfer (because host task may occupy to access the resource) */
  2868. USB_HostEhciLock();
  2869. transfer = isoPointer->ehciTransferHead;
  2870. isoPointer->ehciTransferTail = NULL;
  2871. isoPointer->ehciTransferHead = NULL;
  2872. USB_HostEhciUnlock();
  2873. while (transfer != NULL)
  2874. {
  2875. nextTransfer = transfer->next;
  2876. doneLength = 0;
  2877. /* remove itd from frame list and release itd */
  2878. doneLength = USB_HostEhciItdArrayRelease(ehciInstance, (usb_host_ehci_itd_t *)transfer->union1.unitHead,
  2879. (usb_host_ehci_itd_t *)transfer->union2.unitTail);
  2880. /* transfer callback */
  2881. if (ehciPipePointer->pipeCommon.direction == USB_OUT)
  2882. {
  2883. doneLength = transfer->transferLength;
  2884. }
  2885. transfer->transferSofar = doneLength;
  2886. /* callback function is different from the current condition */
  2887. transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferCancel);
  2888. /* next transfer */
  2889. transfer = nextTransfer;
  2890. }
  2891. return kStatus_USB_Success;
  2892. }
  2893. #endif /* USB_HOST_CONFIG_EHCI_MAX_ITD */
  2894. static usb_status_t USB_HostEhciOpenControlBulk(usb_host_ehci_instance_t *ehciInstance,
  2895. usb_host_ehci_pipe_t *ehciPipePointer)
  2896. {
  2897. usb_host_ehci_qh_t *qhPointer;
  2898. if (USB_HostEhciQhInit(ehciInstance, ehciPipePointer) != kStatus_USB_Success) /* initialize control/bulk qh */
  2899. {
  2900. return kStatus_USB_Error;
  2901. }
  2902. qhPointer = (usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
  2903. /* add qh to async */
  2904. qhPointer->horizontalLinkPointer = ehciInstance->shedFirstQh->horizontalLinkPointer;
  2905. ehciInstance->shedFirstQh->horizontalLinkPointer = ((uint32_t)qhPointer | EHCI_HOST_POINTER_TYPE_QH);
  2906. return kStatus_USB_Success;
  2907. }
  2908. static usb_status_t USB_HostEhciCloseControlBulk(usb_host_ehci_instance_t *ehciInstance,
  2909. usb_host_ehci_pipe_t *ehciPipePointer)
  2910. {
  2911. volatile usb_host_ehci_qh_t *vltPrevQhPointer;
  2912. uint32_t horizontalLinkValue;
  2913. uint32_t *temp;
  2914. /* remove qh from async schedule */
  2915. temp = (uint32_t *)ehciPipePointer->ehciQh;
  2916. if ((ehciInstance->shedFirstQh->horizontalLinkPointer & EHCI_HOST_POINTER_ADDRESS_MASK) ==
  2917. (uint32_t)temp) /* the removing qh is the first qh in the async list */
  2918. {
  2919. USB_HostEhciStopAsync(ehciInstance);
  2920. ehciInstance->shedFirstQh->horizontalLinkPointer =
  2921. ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer;
  2922. USB_HostEhciStartAsync(ehciInstance);
  2923. }
  2924. else
  2925. {
  2926. /* search for the removing qh from the async list */
  2927. vltPrevQhPointer = ehciInstance->shedFirstQh;
  2928. while (vltPrevQhPointer != NULL)
  2929. {
  2930. horizontalLinkValue = vltPrevQhPointer->horizontalLinkPointer;
  2931. if ((0U != (horizontalLinkValue & EHCI_HOST_T_INVALID_VALUE)) ||
  2932. ((horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK) == (uint32_t)temp) ||
  2933. ((horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK) == (uint32_t)ehciInstance->shedFirstQh))
  2934. {
  2935. break;
  2936. }
  2937. vltPrevQhPointer = (volatile usb_host_ehci_qh_t *)(horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK);
  2938. }
  2939. /* remove the qh from async list */
  2940. /*for misra 11.6*/
  2941. temp = (uint32_t *)ehciPipePointer->ehciQh;
  2942. if ((vltPrevQhPointer != NULL) && (0U == (horizontalLinkValue & EHCI_HOST_T_INVALID_VALUE)) &&
  2943. ((horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK) == (uint32_t)temp))
  2944. {
  2945. USB_HostEhciStopAsync(ehciInstance);
  2946. vltPrevQhPointer->horizontalLinkPointer =
  2947. ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer;
  2948. USB_HostEhciStartAsync(ehciInstance);
  2949. }
  2950. }
  2951. ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer =
  2952. EHCI_HOST_T_INVALID_VALUE; /* invalid next qh link */
  2953. return USB_HostEhciQhDeinit(ehciInstance, ehciPipePointer); /* de-initialize qh and release qh */
  2954. }
  2955. static usb_status_t USB_HostEhciOpenInterrupt(usb_host_ehci_instance_t *ehciInstance,
  2956. usb_host_ehci_pipe_t *ehciPipePointer)
  2957. {
  2958. usb_status_t status = kStatus_USB_Success;
  2959. uint32_t frameIndex;
  2960. uint32_t *temp;
  2961. /* allocate bandwidth */
  2962. if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH)
  2963. {
  2964. status = USB_HostBandwidthHsHostAllocateInterrupt(ehciInstance, ehciPipePointer); /* host works as high-speed */
  2965. }
  2966. else
  2967. {
  2968. status = USB_HostBandwidthFslsHostAllocate(ehciInstance,
  2969. ehciPipePointer); /* host works as full-speed or low-speed */
  2970. }
  2971. if (status != kStatus_USB_Success)
  2972. {
  2973. return status;
  2974. }
  2975. if (USB_HostEhciQhInit(ehciInstance, ehciPipePointer) != kStatus_USB_Success)
  2976. {
  2977. return kStatus_USB_Error;
  2978. }
  2979. /* insert QH to frame list */
  2980. for (frameIndex = ehciPipePointer->startFrame; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
  2981. frameIndex += (((uint32_t)ehciPipePointer->uframeInterval + 7U) / 8U))
  2982. {
  2983. temp = (uint32_t *)ehciPipePointer->ehciQh;
  2984. USB_HostEhciAddQhToFrame(ehciInstance, (uint32_t)temp, (uint16_t)frameIndex, ehciPipePointer->uframeInterval);
  2985. }
  2986. return kStatus_USB_Success;
  2987. }
  2988. static usb_status_t USB_HostEhciCloseInterrupt(usb_host_ehci_instance_t *ehciInstance,
  2989. usb_host_ehci_pipe_t *ehciPipePointer)
  2990. {
  2991. uint32_t frameIndex;
  2992. uint32_t *temp;
  2993. /* remove from frame list */
  2994. for (frameIndex = ehciPipePointer->startFrame; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
  2995. frameIndex += (((uint32_t)ehciPipePointer->uframeInterval + 7U) / 8U))
  2996. {
  2997. temp = (uint32_t *)ehciPipePointer->ehciQh;
  2998. USB_HostEhciRemoveFromFrame(ehciInstance, (uint32_t)temp, (uint16_t)frameIndex);
  2999. }
  3000. ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer |=
  3001. EHCI_HOST_T_INVALID_VALUE; /* invalid next qh link */
  3002. return USB_HostEhciQhDeinit(ehciInstance, ehciPipePointer); /* de-initilaze qh and release qh */
  3003. }
  3004. #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
  3005. ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
  3006. static usb_status_t USB_HostEhciOpenIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer)
  3007. {
  3008. usb_host_ehci_iso_t *isoPointer;
  3009. usb_status_t status = kStatus_USB_Success;
  3010. if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH)
  3011. {
  3012. status = USB_HostBandwidthHsHostAllocateIso(
  3013. ehciInstance, ehciPipePointer); /* allocate iso bandwidth when host works as high-speed */
  3014. }
  3015. else
  3016. {
  3017. status = USB_HostBandwidthFslsHostAllocate(
  3018. ehciInstance, ehciPipePointer); /* allocate iso bandwidth when host works as full-speed or low-speed */
  3019. }
  3020. if (status != kStatus_USB_Success)
  3021. {
  3022. return status;
  3023. }
  3024. /* get usb_host_ehci_iso_t */
  3025. if (ehciInstance->ehciIsoList == NULL)
  3026. {
  3027. return kStatus_USB_Error;
  3028. }
  3029. USB_HostEhciLock();
  3030. isoPointer = ehciInstance->ehciIsoList;
  3031. ehciInstance->ehciIsoList = ehciInstance->ehciIsoList->next;
  3032. USB_HostEhciUnlock();
  3033. isoPointer->lastLinkFrame = 0xFFFF;
  3034. ehciPipePointer->ehciQh = isoPointer;
  3035. return status;
  3036. }
  3037. static usb_status_t USB_HostEhciCloseIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer)
  3038. {
  3039. usb_host_ehci_iso_t *isoPointer;
  3040. uint32_t speed = 0U;
  3041. isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
  3042. if (isoPointer->ehciTransferHead != NULL)
  3043. {
  3044. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  3045. (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
  3046. if (speed == USB_SPEED_HIGH)
  3047. {
  3048. #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
  3049. (void)USB_HostEhciItdArrayDeinit(ehciInstance, ehciPipePointer); /* de-initialize itd list and free them */
  3050. #endif
  3051. }
  3052. else
  3053. {
  3054. #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
  3055. (void)USB_HostEhciSitdArrayDeinit(ehciInstance,
  3056. ehciPipePointer); /* de-initialize sitd list and free them */
  3057. #endif
  3058. }
  3059. }
  3060. /* release usb_host_ehci_iso_t */
  3061. USB_HostEhciLock();
  3062. isoPointer->next = ehciInstance->ehciIsoList;
  3063. ehciInstance->ehciIsoList = isoPointer;
  3064. USB_HostEhciUnlock();
  3065. return kStatus_USB_Success;
  3066. }
  3067. #endif
  3068. static usb_status_t USB_HostEhciResetIP(usb_host_ehci_instance_t *ehciInstance)
  3069. {
  3070. /* reset controller */
  3071. ehciInstance->ehciIpBase->USBCMD = USBHS_USBCMD_RST_MASK;
  3072. while (0U != (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_RST_MASK))
  3073. {
  3074. }
  3075. /* set host mode */
  3076. #if (ENDIANNESS == USB_LITTLE_ENDIAN)
  3077. ehciInstance->ehciIpBase->USBMODE |= 0x03U;
  3078. #else
  3079. ehciInstance->ehciIpBase->USBMODE |= (0x03U | (0x01U << USBHS_USBMODE_ES_SHIFT));
  3080. #endif
  3081. /* check frame list size */
  3082. if (0U == (ehciInstance->ehciIpBase->HCCPARAMS & USBHS_HCCPARAMS_PFL_MASK))
  3083. {
  3084. #if ((USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE < 8) || (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE > 1024))
  3085. return kStatus_USB_Error;
  3086. #endif
  3087. #if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE & (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE - 1))
  3088. return kStatus_USB_Error; /* frame size must be 1024/512/256/128/64/32/16/8 */
  3089. #endif
  3090. }
  3091. return kStatus_USB_Success;
  3092. }
  3093. static usb_status_t USB_HostEhciStartIP(usb_host_ehci_instance_t *ehciInstance)
  3094. {
  3095. uint32_t tmp = 0;
  3096. if (0U != (ehciInstance->ehciIpBase->HCSPARAMS & USBHS_HCSPARAMS_PPC_MASK)) /* Ports have power port switches */
  3097. {
  3098. /* only has one port */
  3099. tmp = ehciInstance->ehciIpBase->PORTSC1;
  3100. tmp &= (~EHCI_PORTSC1_W1_BITS);
  3101. ehciInstance->ehciIpBase->PORTSC1 = (tmp | USBHS_PORTSC1_PP_MASK); /* turn on port power */
  3102. }
  3103. /* set frame list size */
  3104. if (0U != (ehciInstance->ehciIpBase->HCCPARAMS & USBHS_HCCPARAMS_PFL_MASK))
  3105. {
  3106. #if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE <= 64)
  3107. ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_FS2_MASK);
  3108. #if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 64)
  3109. ehciInstance->ehciIpBase->USBCMD |= (0x00U << USBHS_USBCMD_FS_SHIFT);
  3110. #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 32)
  3111. ehciInstance->ehciIpBase->USBCMD |= (0x01U << USBHS_USBCMD_FS_SHIFT);
  3112. #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 16)
  3113. ehciInstance->ehciIpBase->USBCMD |= (0x02U << USBHS_USBCMD_FS_SHIFT);
  3114. #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 8)
  3115. ehciInstance->ehciIpBase->USBCMD |= (0x03U << USBHS_USBCMD_FS_SHIFT);
  3116. #endif
  3117. #else
  3118. #if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 1024)
  3119. ehciInstance->ehciIpBase->USBCMD |= (0x00U << USBHS_USBCMD_FS_SHIFT);
  3120. #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 512)
  3121. ehciInstance->ehciIpBase->USBCMD |= (0x01U << USBHS_USBCMD_FS_SHIFT);
  3122. #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 256)
  3123. ehciInstance->ehciIpBase->USBCMD |= (0x02U << USBHS_USBCMD_FS_SHIFT);
  3124. #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 128)
  3125. ehciInstance->ehciIpBase->USBCMD |= (0x03U << USBHS_USBCMD_FS_SHIFT);
  3126. #endif
  3127. #endif
  3128. }
  3129. /* no interrupt threshold */
  3130. ehciInstance->ehciIpBase->USBCMD &= ~USBHS_USBCMD_ITC_MASK;
  3131. /* start the controller */
  3132. ehciInstance->ehciIpBase->USBCMD |= USBHS_USBCMD_RS_MASK;
  3133. /* set timer0 */
  3134. ehciInstance->ehciIpBase->GPTIMER0LD = (100U * 1000U - 1U); /* 100ms */
  3135. /* enable interrupt (USB interrupt enable + USB error interrupt enable + port change detect enable + system error
  3136. * enable + interrupt on async advance enable) + general purpos Timer 0 Interrupt enable */
  3137. ehciInstance->ehciIpBase->USBINTR |= (0x1000037U);
  3138. return kStatus_USB_Success;
  3139. }
  3140. static usb_status_t USB_HostEhciCancelPipe(usb_host_ehci_instance_t *ehciInstance,
  3141. usb_host_ehci_pipe_t *ehciPipePointer,
  3142. usb_host_transfer_t *transfer)
  3143. {
  3144. usb_host_ehci_qh_t *qhPointer;
  3145. #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
  3146. ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
  3147. usb_host_ehci_iso_t *isoPointer;
  3148. uint32_t speed = 0U;
  3149. #endif
  3150. uint8_t cancelPipe = 0;
  3151. switch (ehciPipePointer->pipeCommon.pipeType)
  3152. {
  3153. case USB_ENDPOINT_BULK:
  3154. case USB_ENDPOINT_CONTROL:
  3155. case USB_ENDPOINT_INTERRUPT:
  3156. qhPointer = (usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
  3157. if (qhPointer->ehciTransferHead == NULL) /* there is no transfer to cancel */
  3158. {
  3159. return kStatus_USB_Success;
  3160. }
  3161. if (transfer != NULL)
  3162. {
  3163. if ((qhPointer->ehciTransferHead == transfer) &&
  3164. (qhPointer->ehciTransferHead == qhPointer->ehciTransferTail)) /* only has this one transfer */
  3165. {
  3166. cancelPipe = 1U;
  3167. }
  3168. else
  3169. {
  3170. cancelPipe = 0U;
  3171. }
  3172. }
  3173. else
  3174. {
  3175. cancelPipe = 1U;
  3176. }
  3177. if (cancelPipe == 1U) /* cancel all pipe */
  3178. {
  3179. (void)USB_HostEhciQhQtdListDeinit(ehciInstance, ehciPipePointer); /* release all the qtd */
  3180. }
  3181. else /* cancel one transfer */
  3182. {
  3183. (void)USB_HostEhciTransferQtdListDeinit(ehciInstance, ehciPipePointer, transfer);
  3184. }
  3185. break;
  3186. #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
  3187. ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
  3188. case USB_ENDPOINT_ISOCHRONOUS:
  3189. isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
  3190. if (isoPointer->ehciTransferHead == NULL) /* there is no transfer to cancel */
  3191. {
  3192. return kStatus_USB_Success;
  3193. }
  3194. /* cancel all pipe, don't implement canceling transfer for iso */
  3195. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  3196. (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
  3197. if (speed == USB_SPEED_HIGH)
  3198. {
  3199. #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
  3200. (void)USB_HostEhciItdArrayDeinit(ehciInstance, ehciPipePointer); /* de-initialize itd */
  3201. #endif
  3202. }
  3203. else
  3204. {
  3205. #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
  3206. (void)USB_HostEhciSitdArrayDeinit(ehciInstance, ehciPipePointer); /* de-initialize sitd */
  3207. #endif
  3208. }
  3209. break;
  3210. #endif
  3211. default:
  3212. /*no action*/
  3213. break;
  3214. }
  3215. return kStatus_USB_Success;
  3216. }
  3217. static usb_status_t USB_HostEhciControlBus(usb_host_ehci_instance_t *ehciInstance, uint8_t busControl)
  3218. {
  3219. usb_status_t status = kStatus_USB_Success;
  3220. uint32_t portScRegister;
  3221. usb_host_bus_control_t controlCode = (usb_host_bus_control_t)busControl;
  3222. switch (controlCode)
  3223. {
  3224. case kUSB_HostBusReset:
  3225. /* reset port */
  3226. portScRegister = ehciInstance->ehciIpBase->PORTSC1;
  3227. portScRegister &= (~EHCI_PORTSC1_W1_BITS);
  3228. ehciInstance->ehciIpBase->PORTSC1 = (portScRegister | USBHS_PORTSC1_PR_MASK);
  3229. while (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_PR_MASK))
  3230. {
  3231. }
  3232. break;
  3233. case kUSB_HostBusRestart:
  3234. ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceDetached;
  3235. ehciInstance->ehciIpBase->USBINTR |= (USBHS_USBINTR_PCE_MASK); /* enable ehci port change interrupt */
  3236. break;
  3237. case kUSB_HostBusEnableAttach: /* enable device attach */
  3238. if (ehciInstance->deviceAttached == (uint8_t)kEHCIDeviceDetached)
  3239. {
  3240. ehciInstance->ehciIpBase->USBINTR |= (USBHS_USBINTR_PCE_MASK); /* enable ehci port change interrupt */
  3241. }
  3242. break;
  3243. case kUSB_HostBusDisableAttach: /* disable device attach */
  3244. ehciInstance->ehciIpBase->USBINTR &= (~USBHS_USBINTR_PCE_MASK); /* disable ehci port change interrupt */
  3245. break;
  3246. #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
  3247. case kUSB_HostBusSuspend:
  3248. if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
  3249. {
  3250. /* set timer1 */
  3251. ehciInstance->ehciIpBase->GPTIMER1LD = (1 * 1000); /* 1ms */
  3252. ehciInstance->ehciIpBase->GPTIMER1CTL |=
  3253. (USBHS_GPTIMER0CTL_RUN_MASK | USBHS_GPTIMER0CTL_MODE_MASK | USBHS_GPTIMER0CTL_RST_MASK);
  3254. USB_HostEhciStopAsync(ehciInstance);
  3255. USB_HostEhciStopPeriodic(ehciInstance);
  3256. while (0U != (ehciInstance->ehciIpBase->USBSTS & (USBHS_USBSTS_PS_MASK | USBHS_USBSTS_AS_MASK)))
  3257. {
  3258. __NOP();
  3259. }
  3260. ehciInstance->ehciIpBase->PORTSC1 &= ~USBHS_PORTSC1_WKCN_MASK;
  3261. ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_WKDS_MASK;
  3262. ehciInstance->ehciIpBase->PORTSC1 |= (USBHS_PORTSC1_SUSP_MASK); /* Suspend the device */
  3263. #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
  3264. PMU->WAKEUP_PM2_MASK1 |= PMU_WAKEUP_PM2_MASK1_USB(1);
  3265. #endif
  3266. ehciInstance->matchTick = 0U;
  3267. ehciInstance->ehciIpBase->USBINTR |= (USBHS_USBINTR_TIE1_MASK);
  3268. ehciInstance->busSuspendStatus = kBus_EhciStartSuspend;
  3269. }
  3270. else
  3271. {
  3272. status = kStatus_USB_Error;
  3273. }
  3274. break;
  3275. case kUSB_HostBusResume:
  3276. ehciInstance->ehciIpBase->PORTSC1 &= ~(USBHS_PORTSC1_SUSP_MASK); /* Clear Suspend bit */
  3277. ehciInstance->ehciIpBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK;
  3278. if (ehciInstance->deviceAttached != (uint8_t)kEHCIDeviceDetached)
  3279. {
  3280. ehciInstance->busSuspendStatus = kBus_EhciStartResume;
  3281. #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
  3282. ehciInstance->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK;
  3283. #else
  3284. #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
  3285. #else
  3286. ehciInstance->ehciIpBase->USBGENCTRL &= ~USBHS_USBGENCTRL_WU_IE_MASK;
  3287. #endif
  3288. #endif
  3289. ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK);
  3290. ehciInstance->ehciIpBase->PORTSC1 |= (USBHS_PORTSC1_FPR_MASK); /* Resume the device */
  3291. }
  3292. else
  3293. {
  3294. status = kStatus_USB_Error;
  3295. }
  3296. break;
  3297. #endif
  3298. default:
  3299. status = kStatus_USB_Error;
  3300. break;
  3301. }
  3302. return status;
  3303. }
  3304. void USB_HostEhciTransactionDone(usb_host_ehci_instance_t *ehciInstance)
  3305. {
  3306. /* process async QH */
  3307. usb_host_ehci_pipe_t *ehciPipePointer;
  3308. usb_host_ehci_pipe_t *ehciClearPipePointer = NULL;
  3309. volatile usb_host_ehci_qh_t *vltQhPointer;
  3310. volatile usb_host_ehci_qtd_t *vltQtdPointer;
  3311. usb_host_transfer_t *transfer;
  3312. usb_host_transfer_t *nextTransfer;
  3313. uint32_t qtdStatus = 0;
  3314. #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
  3315. volatile usb_host_ehci_itd_t *vltItdPointer;
  3316. uint8_t index = 0;
  3317. #endif
  3318. #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
  3319. volatile usb_host_ehci_sitd_t *vltSitdPointer;
  3320. #endif
  3321. #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
  3322. ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
  3323. usb_host_ehci_iso_t *isoPointer;
  3324. uint32_t dataLength;
  3325. uint32_t speed = 0U;
  3326. #endif
  3327. void *temp;
  3328. uint32_t transferResults;
  3329. uint32_t transferOverlayResults;
  3330. ehciPipePointer = ehciInstance->ehciRunningPipeList; /* check all the running pipes */
  3331. while (ehciPipePointer != NULL)
  3332. {
  3333. switch (ehciPipePointer->pipeCommon.pipeType)
  3334. {
  3335. case USB_ENDPOINT_BULK:
  3336. case USB_ENDPOINT_INTERRUPT:
  3337. case USB_ENDPOINT_CONTROL:
  3338. vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; /* pipe's qh */
  3339. transfer = vltQhPointer->ehciTransferHead; /* qh's transfer */
  3340. while (transfer != NULL)
  3341. {
  3342. nextTransfer = transfer->next;
  3343. /* normal case */
  3344. vltQtdPointer = (volatile usb_host_ehci_qtd_t *)transfer->union2.unitTail;
  3345. transferResults = vltQtdPointer->transferResults[0];
  3346. transferOverlayResults = vltQhPointer->transferOverlayResults[0];
  3347. if ((0U != (transferResults & (EHCI_HOST_QTD_IOC_MASK))) &&
  3348. (0U == (transferResults & EHCI_HOST_QTD_STATUS_ACTIVE_MASK))) /* transfer is done */
  3349. {
  3350. qtdStatus = (transferResults & EHCI_HOST_QTD_STATUS_ERROR_MASK);
  3351. transfer->transferSofar =
  3352. USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
  3353. (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
  3354. transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
  3355. 0U :
  3356. (transfer->transferLength - transfer->transferSofar);
  3357. vltQhPointer->ehciTransferHead = transfer->next;
  3358. vltQhPointer->timeOutLabel = 0U;
  3359. vltQhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
  3360. if (0U != qtdStatus) /* has errors */
  3361. {
  3362. if (0U == (transferOverlayResults & EHCI_HOST_QTD_STATUS_ACTIVE_MASK))
  3363. {
  3364. vltQhPointer->transferOverlayResults[0] &=
  3365. (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
  3366. }
  3367. if (0U != (qtdStatus & EHCI_HOST_QH_STATUS_NOSTALL_ERROR_MASK))
  3368. {
  3369. /* callback function is different from the current condition */
  3370. transfer->callbackFn(transfer->callbackParam, transfer,
  3371. kStatus_USB_TransferFailed); /* transfer fail */
  3372. }
  3373. else
  3374. {
  3375. /* callback function is different from the current condition */
  3376. transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferStall);
  3377. }
  3378. }
  3379. else
  3380. {
  3381. if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL) &&
  3382. (transfer->setupPacket->bRequest == USB_REQUEST_STANDARD_CLEAR_FEATURE) &&
  3383. (transfer->setupPacket->bmRequestType == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT) &&
  3384. ((USB_SHORT_FROM_LITTLE_ENDIAN(transfer->setupPacket->wValue) & 0x00FFu) ==
  3385. USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT))
  3386. {
  3387. ehciClearPipePointer = ehciInstance->ehciRunningPipeList;
  3388. while (ehciClearPipePointer != NULL)
  3389. {
  3390. /* only compute bulk and interrupt pipe */
  3391. if (((ehciClearPipePointer->pipeCommon.endpointAddress |
  3392. (ehciClearPipePointer->pipeCommon.direction
  3393. << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) ==
  3394. (uint8_t)(USB_SHORT_FROM_LITTLE_ENDIAN(transfer->setupPacket->wIndex))) &&
  3395. (ehciClearPipePointer->pipeCommon.deviceHandle ==
  3396. ehciPipePointer->pipeCommon.deviceHandle))
  3397. {
  3398. break;
  3399. }
  3400. temp = (void *)ehciClearPipePointer->pipeCommon.next;
  3401. ehciClearPipePointer = (usb_host_ehci_pipe_t *)temp;
  3402. }
  3403. if ((ehciClearPipePointer != NULL) &&
  3404. ((ehciClearPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT) ||
  3405. (ehciClearPipePointer->pipeCommon.pipeType == USB_ENDPOINT_BULK)))
  3406. {
  3407. ((volatile usb_host_ehci_qh_t *)(ehciClearPipePointer->ehciQh))
  3408. ->transferOverlayResults[0] &= (~EHCI_HOST_QTD_DT_MASK);
  3409. }
  3410. }
  3411. /* callback function is different from the current condition */
  3412. transfer->callbackFn(transfer->callbackParam, transfer,
  3413. kStatus_USB_Success); /* transfer success */
  3414. }
  3415. }
  3416. else if ((0U == (transferOverlayResults & EHCI_HOST_QTD_STATUS_ACTIVE_MASK)) &&
  3417. (0U != (transferOverlayResults &
  3418. EHCI_HOST_QH_STATUS_ERROR_MASK))) /* there is error and transfer is done */
  3419. {
  3420. qtdStatus = (vltQhPointer->transferOverlayResults[0] & EHCI_HOST_QH_STATUS_ERROR_MASK);
  3421. vltQtdPointer = (volatile usb_host_ehci_qtd_t *)(vltQhPointer->currentQtdPointer);
  3422. if ((0U != ((uint32_t)vltQtdPointer & EHCI_HOST_T_INVALID_VALUE)) ||
  3423. (vltQtdPointer == NULL)) /* the error status is unreasonable */
  3424. {
  3425. vltQhPointer->transferOverlayResults[0] &=
  3426. (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
  3427. }
  3428. else
  3429. {
  3430. /* remove qtd from qh */
  3431. do
  3432. {
  3433. if (vltQtdPointer == NULL)
  3434. {
  3435. break;
  3436. }
  3437. else if (0U != (vltQtdPointer->transferResults[0] & EHCI_HOST_QTD_IOC_MASK))
  3438. {
  3439. break;
  3440. }
  3441. else
  3442. {
  3443. /* no action */
  3444. }
  3445. vltQtdPointer = (volatile usb_host_ehci_qtd_t *)vltQtdPointer->nextQtdPointer;
  3446. } while (true);
  3447. vltQhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
  3448. vltQhPointer->currentQtdPointer = EHCI_HOST_T_INVALID_VALUE;
  3449. vltQhPointer->transferOverlayResults[0] &=
  3450. (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
  3451. if (vltQtdPointer != NULL)
  3452. {
  3453. vltQhPointer->nextQtdPointer = vltQtdPointer->nextQtdPointer;
  3454. }
  3455. transfer->transferSofar = USB_HostEhciQtdListRelease(
  3456. ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
  3457. (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
  3458. transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
  3459. 0U :
  3460. (transfer->transferLength - transfer->transferSofar);
  3461. vltQhPointer->ehciTransferHead = transfer->next;
  3462. vltQhPointer->timeOutLabel = 0U;
  3463. vltQhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
  3464. if (0U != (qtdStatus & EHCI_HOST_QH_STATUS_NOSTALL_ERROR_MASK))
  3465. {
  3466. /* callback function is different from the current condition */
  3467. transfer->callbackFn(transfer->callbackParam, transfer,
  3468. kStatus_USB_TransferFailed); /* transfer fail */
  3469. }
  3470. else
  3471. {
  3472. /* callback function is different from the current condition */
  3473. transfer->callbackFn(transfer->callbackParam, transfer,
  3474. kStatus_USB_TransferStall); /* transfer stall */
  3475. }
  3476. }
  3477. }
  3478. else
  3479. {
  3480. break;
  3481. }
  3482. transfer = nextTransfer;
  3483. }
  3484. break;
  3485. #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
  3486. ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
  3487. case USB_ENDPOINT_ISOCHRONOUS:
  3488. qtdStatus = 0; /* qtdStatus means break here, because there is only one break in while for misra */
  3489. isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh; /* pipe's usb_host_ehci_iso_t */
  3490. transfer = isoPointer->ehciTransferHead; /* usb_host_ehci_iso_t's transfer */
  3491. while (transfer != NULL)
  3492. {
  3493. nextTransfer = transfer->next;
  3494. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  3495. (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
  3496. if (speed == USB_SPEED_HIGH)
  3497. {
  3498. #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
  3499. vltItdPointer =
  3500. (volatile usb_host_ehci_itd_t *)(transfer->union2.unitTail); /* transfer's last itd */
  3501. for (index = 0; index < 8U; ++index)
  3502. {
  3503. if (0U != (vltItdPointer->transactions[index] & EHCI_HOST_ITD_STATUS_ACTIVE_MASK))
  3504. {
  3505. break;
  3506. }
  3507. }
  3508. if (index == 8U) /* transfer is done */
  3509. {
  3510. /* remove itd from frame list and release itd */
  3511. dataLength = USB_HostEhciItdArrayRelease(ehciInstance,
  3512. (usb_host_ehci_itd_t *)transfer->union1.unitHead,
  3513. (usb_host_ehci_itd_t *)transfer->union2.unitTail);
  3514. transfer->transferSofar = dataLength;
  3515. isoPointer->ehciTransferHead = transfer->next;
  3516. /* callback function is different from the current condition */
  3517. transfer->callbackFn(transfer->callbackParam, transfer,
  3518. kStatus_USB_Success); /* transfer callback success */
  3519. /* TODO: iso callback error */
  3520. }
  3521. else
  3522. {
  3523. qtdStatus = 1U; /* break */
  3524. }
  3525. #endif
  3526. }
  3527. else
  3528. {
  3529. #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
  3530. vltSitdPointer =
  3531. (volatile usb_host_ehci_sitd_t *)(transfer->union2.unitTail); /* transfer's last sitd */
  3532. if (0U == (vltSitdPointer->transferResults[0] &
  3533. EHCI_HOST_SITD_STATUS_ACTIVE_MASK)) /* transfer is done */
  3534. {
  3535. /* remove sitd from frame list and release itd */
  3536. dataLength = USB_HostEhciSitdArrayRelease(
  3537. ehciInstance, (usb_host_ehci_sitd_t *)transfer->union1.unitHead,
  3538. (usb_host_ehci_sitd_t *)transfer->union2.unitTail);
  3539. transfer->transferSofar = transfer->transferLength - dataLength;
  3540. isoPointer->ehciTransferHead = transfer->next;
  3541. /* callback function is different from the current condition */
  3542. transfer->callbackFn(transfer->callbackParam, transfer,
  3543. kStatus_USB_Success); /* transfer callback success */
  3544. /* TODO: iso callback error */
  3545. }
  3546. else
  3547. {
  3548. qtdStatus = 1U; /* break */
  3549. }
  3550. #endif
  3551. }
  3552. if (qtdStatus == 1U)
  3553. {
  3554. break;
  3555. }
  3556. transfer = nextTransfer;
  3557. }
  3558. break;
  3559. #endif
  3560. default:
  3561. /*no action*/
  3562. break;
  3563. }
  3564. temp = (void *)ehciPipePointer->pipeCommon.next;
  3565. ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
  3566. }
  3567. }
  3568. static void USB_HostEhciPortChange(usb_host_ehci_instance_t *ehciInstance)
  3569. {
  3570. /* note: only has one port */
  3571. uint32_t portScRegister = ehciInstance->ehciIpBase->PORTSC1;
  3572. uint32_t sofStart = 0;
  3573. uint32_t sofCount = 0;
  3574. uint32_t index;
  3575. if (0U != (portScRegister & USBHS_PORTSC1_CSC_MASK)) /* connection status change */
  3576. {
  3577. sofStart = (ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE);
  3578. /* process CSC bit */
  3579. while (1U == 1U)
  3580. {
  3581. portScRegister = ehciInstance->ehciIpBase->PORTSC1;
  3582. if (0U != (portScRegister & USBHS_PORTSC1_CSC_MASK))
  3583. {
  3584. /* clear csc bit */
  3585. portScRegister = ehciInstance->ehciIpBase->PORTSC1;
  3586. portScRegister &= (~EHCI_PORTSC1_W1_BITS);
  3587. ehciInstance->ehciIpBase->PORTSC1 = (portScRegister | USBHS_PORTSC1_CSC_MASK);
  3588. }
  3589. sofCount = (ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE);
  3590. if (((sofCount + EHCI_MAX_UFRAME_VALUE + 1U - sofStart) & EHCI_MAX_UFRAME_VALUE) >
  3591. (1U * 8U)) /* delay 1ms to clear CSC */
  3592. {
  3593. break;
  3594. }
  3595. }
  3596. }
  3597. /* process CCS bit */
  3598. portScRegister = ehciInstance->ehciIpBase->PORTSC1;
  3599. if (0U != (portScRegister & USBHS_PORTSC1_CCS_MASK)) /* process attach */
  3600. {
  3601. if ((ehciInstance->deviceAttached == (uint8_t)kEHCIDevicePhyAttached) ||
  3602. (ehciInstance->deviceAttached == (uint8_t)kEHCIDeviceAttached))
  3603. {
  3604. return;
  3605. }
  3606. #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
  3607. ehciInstance->busSuspendStatus = kBus_EhciIdle;
  3608. ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
  3609. #endif
  3610. for (index = 0; index < USB_HOST_EHCI_PORT_CONNECT_DEBOUNCE_DELAY; ++index)
  3611. {
  3612. USB_HostEhciDelay(ehciInstance->ehciIpBase, 1);
  3613. if (0U == (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
  3614. {
  3615. break;
  3616. }
  3617. }
  3618. if (index < USB_HOST_EHCI_PORT_CONNECT_DEBOUNCE_DELAY) /* CCS is cleared */
  3619. {
  3620. ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceDetached;
  3621. return;
  3622. }
  3623. /* reset port */
  3624. portScRegister = ehciInstance->ehciIpBase->PORTSC1;
  3625. portScRegister &= (~EHCI_PORTSC1_W1_BITS);
  3626. ehciInstance->ehciIpBase->PORTSC1 = (portScRegister | USBHS_PORTSC1_PR_MASK);
  3627. while (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_PR_MASK))
  3628. {
  3629. }
  3630. ehciInstance->firstDeviceSpeed =
  3631. (uint8_t)((ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_PSPD_MASK) >> USBHS_PORTSC1_PSPD_SHIFT);
  3632. /* enable ehci phy disconnection */
  3633. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
  3634. if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH)
  3635. {
  3636. USB_EhcihostPhyDisconnectDetectCmd(ehciInstance->controllerId, 1);
  3637. }
  3638. #endif
  3639. /* wait for reset */
  3640. USB_HostEhciDelay(ehciInstance->ehciIpBase, USB_HOST_EHCI_PORT_RESET_DELAY);
  3641. /* process attach */
  3642. (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_DEVICE_ATTACH);
  3643. /* gpt timer start */
  3644. ehciInstance->ehciIpBase->GPTIMER0CTL |=
  3645. (USBHS_GPTIMER0CTL_RUN_MASK | USBHS_GPTIMER0CTL_MODE_MASK | USBHS_GPTIMER0CTL_RST_MASK);
  3646. ehciInstance->deviceAttached = (uint8_t)kEHCIDevicePhyAttached;
  3647. }
  3648. else
  3649. {
  3650. if ((ehciInstance->deviceAttached == (uint8_t)kEHCIDevicePhyAttached) ||
  3651. (ehciInstance->deviceAttached == (uint8_t)kEHCIDeviceAttached))
  3652. {
  3653. #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
  3654. ehciInstance->busSuspendStatus = kBus_EhciIdle;
  3655. ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
  3656. #endif
  3657. /* disable ehci phy disconnection */
  3658. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
  3659. USB_EhcihostPhyDisconnectDetectCmd(ehciInstance->controllerId, 0);
  3660. #endif
  3661. /* disable async and periodic */
  3662. USB_HostEhciStopAsync(ehciInstance);
  3663. USB_HostEhciStopPeriodic(ehciInstance);
  3664. (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_DEVICE_DETACH);
  3665. }
  3666. }
  3667. }
  3668. static void USB_HostEhciTimer0(usb_host_ehci_instance_t *ehciInstance)
  3669. {
  3670. volatile usb_host_ehci_qh_t *vltQhPointer;
  3671. usb_host_ehci_qtd_t *vltQtdPointer;
  3672. usb_host_transfer_t *transfer;
  3673. uint32_t backValue;
  3674. volatile uint32_t *totalBytesAddress = NULL;
  3675. usb_host_ehci_pipe_t *ehciPipePointer = ehciInstance->ehciRunningPipeList;
  3676. void *temp;
  3677. uint8_t timeoutLabel;
  3678. while (ehciPipePointer != NULL)
  3679. {
  3680. switch (ehciPipePointer->pipeCommon.pipeType)
  3681. {
  3682. case USB_ENDPOINT_BULK:
  3683. case USB_ENDPOINT_CONTROL:
  3684. vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; /* pipe's qh */
  3685. transfer = vltQhPointer->ehciTransferHead; /* qh's transfer */
  3686. if ((transfer != NULL)) /* there is transfering data */
  3687. {
  3688. timeoutLabel = 0U;
  3689. if (ehciInstance->deviceAttached != (uint8_t)kEHCIDeviceAttached)
  3690. {
  3691. vltQtdPointer = (usb_host_ehci_qtd_t *)transfer->union2.unitTail;
  3692. vltQhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE; /* invalid next qtd */
  3693. vltQhPointer->transferOverlayResults[0] &=
  3694. (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
  3695. timeoutLabel = 1;
  3696. }
  3697. else
  3698. {
  3699. if (0U != (vltQhPointer->transferOverlayResults[0] & EHCI_HOST_QTD_STATUS_ACTIVE_MASK))
  3700. {
  3701. vltQtdPointer = (usb_host_ehci_qtd_t *)vltQhPointer->currentQtdPointer;
  3702. totalBytesAddress = &(vltQhPointer->transferOverlayResults[0]);
  3703. }
  3704. else
  3705. {
  3706. vltQtdPointer = (usb_host_ehci_qtd_t *)transfer->union2.unitTail;
  3707. totalBytesAddress = &(vltQtdPointer->transferResults[0]);
  3708. }
  3709. backValue =
  3710. (((*totalBytesAddress) & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >>
  3711. EHCI_HOST_QTD_TOTAL_BYTES_SHIFT); /* backValue is used for total bytes to transfer */
  3712. if (vltQhPointer->timeOutLabel != backValue) /* use total bytes to reflect the time out */
  3713. {
  3714. vltQhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
  3715. vltQhPointer->timeOutLabel = (uint16_t)backValue;
  3716. }
  3717. else
  3718. {
  3719. /* time out when the total bytes don't change for the duration
  3720. * USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE
  3721. */
  3722. (vltQhPointer->timeOutValue)--;
  3723. if (vltQhPointer->timeOutValue == 0U)
  3724. {
  3725. /* stop the qh schedule */
  3726. USB_HostEhciStopAsync(ehciInstance);
  3727. if (backValue != (((*totalBytesAddress) & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >>
  3728. EHCI_HOST_QTD_TOTAL_BYTES_SHIFT))
  3729. {
  3730. USB_HostEhciStartAsync(ehciInstance);
  3731. }
  3732. else
  3733. {
  3734. vltQhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE; /* invalid next qtd */
  3735. vltQhPointer->transferOverlayResults[0] &=
  3736. (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
  3737. USB_HostEhciStartAsync(ehciInstance);
  3738. timeoutLabel = 1U;
  3739. }
  3740. }
  3741. }
  3742. }
  3743. if (timeoutLabel == 1U)
  3744. {
  3745. /* remove qtd from qh */
  3746. temp = (void *)vltQhPointer->ehciTransferTail;
  3747. while ((vltQtdPointer != NULL) &&
  3748. (0U == (vltQtdPointer->transferResults[0] & EHCI_HOST_QTD_IOC_MASK)) &&
  3749. (vltQtdPointer != (usb_host_ehci_qtd_t *)temp))
  3750. {
  3751. vltQtdPointer = (usb_host_ehci_qtd_t *)vltQtdPointer->nextQtdPointer;
  3752. }
  3753. if ((vltQtdPointer != NULL) &&
  3754. (0U == (vltQtdPointer->nextQtdPointer & EHCI_HOST_T_INVALID_VALUE)))
  3755. {
  3756. vltQhPointer->nextQtdPointer =
  3757. vltQtdPointer->nextQtdPointer; /* start qh if there are other qtd that don't belong to
  3758. the transfer */
  3759. }
  3760. transfer->transferSofar =
  3761. USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
  3762. (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
  3763. transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
  3764. 0U :
  3765. (transfer->transferLength - transfer->transferSofar);
  3766. vltQhPointer->ehciTransferHead = transfer->next;
  3767. vltQhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
  3768. /* callback function is different from the current condition */
  3769. transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferFailed);
  3770. }
  3771. }
  3772. break;
  3773. default:
  3774. /*no action*/
  3775. break;
  3776. }
  3777. temp = (void *)ehciPipePointer->pipeCommon.next;
  3778. ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
  3779. }
  3780. }
  3781. #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
  3782. static void USB_HostEhciTimer1(usb_host_ehci_instance_t *ehciInstance)
  3783. {
  3784. if (ehciInstance->deviceAttached != (uint8_t)kEHCIDeviceDetached)
  3785. {
  3786. if (kBus_EhciStartSuspend == ehciInstance->busSuspendStatus)
  3787. {
  3788. usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
  3789. if (0U == ehciInstance->matchTick)
  3790. {
  3791. ehciInstance->matchTick = hostPointer->hwTick;
  3792. }
  3793. else
  3794. {
  3795. if ((hostPointer->hwTick - ehciInstance->matchTick) >= 5U)
  3796. {
  3797. ehciInstance->ehciIpBase->USBCMD &= ~USBHS_USBCMD_RS_MASK;
  3798. ehciInstance->ehciIpBase->USBSTS |= USBHS_USBSTS_SRI_MASK;
  3799. #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
  3800. #if 0
  3801. ehciInstance->registerPhyBase->CTRL |= USBPHY_CTRL_ENVBUSCHG_WKUP_MASK
  3802. | USBPHY_CTRL_ENIDCHG_WKUP_MASK
  3803. | USBPHY_CTRL_ENDPDMCHG_WKUP_MASK
  3804. | USBPHY_CTRL_ENIRQRESUMEDETECT_MASK
  3805. ;
  3806. #endif
  3807. #endif
  3808. #if (defined(FSL_FEATURE_USBPHY_28FDSOI) && (FSL_FEATURE_USBPHY_28FDSOI > 0U))
  3809. ehciInstance->registerPhyBase->USB1_VBUS_DETECT_SET |=
  3810. USBPHY_USB1_VBUS_DETECT_VBUSVALID_TO_SESSVALID_MASK;
  3811. #endif
  3812. ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_PHCD_MASK;
  3813. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
  3814. ehciInstance->registerPhyBase->PWD = 0xFFFFFFFFU;
  3815. while (0U != (ehciInstance->registerPhyBase->CTRL & (USBPHY_CTRL_UTMI_SUSPENDM_MASK)))
  3816. {
  3817. __NOP();
  3818. }
  3819. #endif
  3820. #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
  3821. ehciInstance->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WKUP_ID_EN_MASK |
  3822. USBNC_USB_OTGn_CTRL_WKUP_VBUS_EN_MASK |
  3823. USBNC_USB_OTGn_CTRL_WKUP_DPDM_EN_MASK;
  3824. ehciInstance->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WIE_MASK;
  3825. #else
  3826. #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
  3827. #else
  3828. ehciInstance->ehciIpBase->USBGENCTRL = USBHS_USBGENCTRL_WU_IE_MASK;
  3829. #endif
  3830. #endif
  3831. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
  3832. ehciInstance->registerPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK;
  3833. #endif
  3834. (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
  3835. kUSB_HostEventSuspended); /* call host callback function */
  3836. ehciInstance->busSuspendStatus = kBus_EhciSuspended;
  3837. }
  3838. }
  3839. }
  3840. else if (kBus_EhciStartResume == ehciInstance->busSuspendStatus)
  3841. {
  3842. usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
  3843. if (0U == (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_FPR_MASK))
  3844. {
  3845. ehciInstance->ehciIpBase->PORTSC1 &= ~USBHS_PORTSC1_WKDS_MASK;
  3846. if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
  3847. {
  3848. USB_HostEhciStartAsync(ehciInstance);
  3849. USB_HostEhciStartPeriodic(ehciInstance);
  3850. }
  3851. (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
  3852. kUSB_HostEventResumed); /* call host callback function */
  3853. hostPointer->suspendedDevice = NULL;
  3854. ehciInstance->busSuspendStatus = kBus_EhciIdle;
  3855. ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
  3856. }
  3857. }
  3858. else
  3859. {
  3860. }
  3861. }
  3862. else
  3863. {
  3864. ehciInstance->busSuspendStatus = kBus_EhciIdle;
  3865. ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
  3866. }
  3867. }
  3868. #endif
  3869. usb_status_t USB_HostEhciCreate(uint8_t controllerId,
  3870. usb_host_handle upperLayerHandle,
  3871. usb_host_controller_handle *controllerHandle)
  3872. {
  3873. uint32_t index = 0;
  3874. osa_status_t osaStatus;
  3875. usb_host_ehci_instance_t *ehciInstance;
  3876. uint32_t usbhsBaseAddrs[] = USBHS_BASE_ADDRS;
  3877. usb_host_ehci_data_t *usbHostEhciData[USB_HOST_CONFIG_EHCI];
  3878. uint32_t *framePointer;
  3879. void *temp;
  3880. uint8_t instanceIndex = 0U;
  3881. if ((controllerId - (uint8_t)kUSB_ControllerEhci0) >= (sizeof(usbhsBaseAddrs) / sizeof(usbhsBaseAddrs[0])))
  3882. {
  3883. return kStatus_USB_ControllerNotFound;
  3884. }
  3885. *controllerHandle = NULL;
  3886. ehciInstance = (usb_host_ehci_instance_t *)OSA_MemoryAllocate(
  3887. sizeof(usb_host_ehci_instance_t)); /* malloc host ehci instance */
  3888. if (ehciInstance == NULL)
  3889. {
  3890. return kStatus_USB_AllocFail;
  3891. }
  3892. ehciInstance->controllerId = controllerId;
  3893. ehciInstance->hostHandle = upperLayerHandle;
  3894. ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceDetached;
  3895. ehciInstance->ehciIpBase = (USBHS_Type *)
  3896. usbhsBaseAddrs[controllerId - (uint8_t)kUSB_ControllerEhci0]; /* operate ehci ip through the base address */
  3897. #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
  3898. ehciInstance->busSuspendStatus = kBus_EhciIdle;
  3899. #if (defined(USB_HOST_CONFIG_LOW_POWER_MODE) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
  3900. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
  3901. ehciInstance->registerPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
  3902. #endif
  3903. #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
  3904. ehciInstance->registerNcBase = (USBNC_Type *)USB_EhciNCGetBase(controllerId);
  3905. #endif
  3906. #endif
  3907. #endif
  3908. if ((USB_HostEhciResetIP(ehciInstance) != kStatus_USB_Success) ||
  3909. ((ehciInstance->controllerId < (uint8_t)kUSB_ControllerEhci0))) /* reset ehci ip */
  3910. {
  3911. OSA_MemoryFree(ehciInstance);
  3912. return kStatus_USB_Error;
  3913. }
  3914. #if (USB_HOST_CONFIG_EHCI == 1U)
  3915. if (0U == usbHostEhciFramListStatus[0])
  3916. {
  3917. usbHostEhciFramListStatus[0] = 1U;
  3918. instanceIndex = 0U;
  3919. ehciInstance->ehciFrameList = &s_UsbHostEhciFrameList1[0];
  3920. }
  3921. #elif (USB_HOST_CONFIG_EHCI == 2U)
  3922. if (0U == usbHostEhciFramListStatus[0])
  3923. {
  3924. usbHostEhciFramListStatus[0] = 1U;
  3925. instanceIndex = 0U;
  3926. ehciInstance->ehciFrameList = &s_UsbHostEhciFrameList1[0];
  3927. }
  3928. else if (0U == usbHostEhciFramListStatus[1])
  3929. {
  3930. usbHostEhciFramListStatus[1] = 1U;
  3931. instanceIndex = 1U;
  3932. ehciInstance->ehciFrameList = &s_UsbHostEhciFrameList2[0];
  3933. }
  3934. else
  3935. {
  3936. /*no action*/
  3937. }
  3938. #endif
  3939. if (ehciInstance->ehciFrameList == NULL)
  3940. {
  3941. OSA_MemoryFree(ehciInstance);
  3942. return kStatus_USB_Error;
  3943. }
  3944. #if (USB_HOST_CONFIG_EHCI == 1U)
  3945. usbHostEhciData[0] = &s_UsbHostEhciData1;
  3946. #elif (USB_HOST_CONFIG_EHCI == 2U)
  3947. usbHostEhciData[0] = &s_UsbHostEhciData1;
  3948. usbHostEhciData[1] = &s_UsbHostEhciData2;
  3949. #else
  3950. #error "Please increase the instance count."
  3951. #endif
  3952. temp = (void *)usbHostEhciData[instanceIndex];
  3953. ehciInstance->ehciUnitBase = (uint32_t *)(temp);
  3954. /* initialize qh/qtd/itd/sitd/iso list */
  3955. ehciInstance->ehciQhList = (usb_host_ehci_qh_t *)((uint32_t)(ehciInstance->ehciUnitBase));
  3956. ehciInstance->ehciQtdHead = (usb_host_ehci_qtd_t *)((uint32_t)ehciInstance->ehciQhList +
  3957. (sizeof(usb_host_ehci_qh_t) * USB_HOST_CONFIG_EHCI_MAX_QH));
  3958. ehciInstance->ehciItdList = (usb_host_ehci_itd_t *)((uint32_t)ehciInstance->ehciQtdHead +
  3959. (sizeof(usb_host_ehci_qtd_t) * USB_HOST_CONFIG_EHCI_MAX_QTD));
  3960. #if ((defined(USB_HOST_CONFIG_EHCI_MAX_ITD)) && (USB_HOST_CONFIG_EHCI_MAX_ITD > 0U))
  3961. /* If one ITD's first 32 bytes and next 32 bytes are in different 4K region,
  3962. * the ITD need move 32 bytes because the ITD cannot cross over 4K boundary.
  3963. */
  3964. index = ((((((uint32_t)(ehciInstance->ehciItdList)) + 4095U) & 0xFFFFF000U) -
  3965. ((uint32_t)(ehciInstance->ehciItdList))) >>
  3966. 5U);
  3967. if (((index / 3U) < USB_HOST_CONFIG_EHCI_MAX_ITD) && ((index % 3U) == 1U))
  3968. {
  3969. ehciInstance->ehciItdList = (usb_host_ehci_itd_t *)(((uint32_t)(ehciInstance->ehciItdList)) + 32U);
  3970. }
  3971. #endif
  3972. ehciInstance->ehciSitdIndexBase =
  3973. (usb_host_ehci_sitd_t *)((uint32_t)ehciInstance->ehciItdList +
  3974. (sizeof(usb_host_ehci_itd_t) * USB_HOST_CONFIG_EHCI_MAX_ITD));
  3975. ehciInstance->ehciSitdList = ehciInstance->ehciSitdIndexBase;
  3976. ehciInstance->ehciIsoList = (usb_host_ehci_iso_t *)((uint32_t)ehciInstance->ehciSitdList +
  3977. (sizeof(usb_host_ehci_sitd_t) * USB_HOST_CONFIG_EHCI_MAX_SITD));
  3978. ehciInstance->ehciPipeIndexBase =
  3979. (usb_host_ehci_pipe_t *)((uint32_t)ehciInstance->ehciIsoList +
  3980. (sizeof(usb_host_ehci_iso_t) * USB_HOST_EHCI_ISO_NUMBER));
  3981. for (index = 1U; index < USB_HOST_CONFIG_EHCI_MAX_QH; ++index)
  3982. {
  3983. ehciInstance->ehciQhList[index - 1U].horizontalLinkPointer = (uint32_t)(&ehciInstance->ehciQhList[index]);
  3984. }
  3985. ehciInstance->ehciQhList[USB_HOST_CONFIG_EHCI_MAX_QH - 1U].horizontalLinkPointer = 0U;
  3986. for (index = 1; index < USB_HOST_CONFIG_EHCI_MAX_QTD; ++index)
  3987. {
  3988. ehciInstance->ehciQtdHead[index - 1U].nextQtdPointer = (uint32_t)(&ehciInstance->ehciQtdHead[index]);
  3989. }
  3990. ehciInstance->ehciQtdNumber = USB_HOST_CONFIG_EHCI_MAX_QTD;
  3991. ehciInstance->ehciQtdHead[USB_HOST_CONFIG_EHCI_MAX_QTD - 1U].nextQtdPointer = 0U;
  3992. ehciInstance->ehciQtdTail = &ehciInstance->ehciQtdHead[USB_HOST_CONFIG_EHCI_MAX_QTD - 1U];
  3993. #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
  3994. for (index = 1; index < USB_HOST_CONFIG_EHCI_MAX_ITD; ++index)
  3995. {
  3996. ehciInstance->ehciItdList[index - 1U].nextItdPointer =
  3997. (usb_host_ehci_itd_t *)(&ehciInstance->ehciItdList[index]);
  3998. }
  3999. ehciInstance->ehciItdNumber = USB_HOST_CONFIG_EHCI_MAX_ITD;
  4000. ehciInstance->ehciItdList[USB_HOST_CONFIG_EHCI_MAX_ITD - 1U].nextItdPointer = NULL;
  4001. #endif /* USB_HOST_CONFIG_EHCI_MAX_ITD */
  4002. #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
  4003. for (index = 1; index < USB_HOST_CONFIG_EHCI_MAX_SITD; ++index)
  4004. {
  4005. ehciInstance->ehciSitdList[index - 1U].nextLinkPointer = (uint32_t)(&ehciInstance->ehciSitdList[index]);
  4006. }
  4007. ehciInstance->ehciSitdNumber = USB_HOST_CONFIG_EHCI_MAX_SITD;
  4008. ehciInstance->ehciSitdList[USB_HOST_CONFIG_EHCI_MAX_SITD - 1U].nextLinkPointer = 0U;
  4009. #endif /* USB_HOST_CONFIG_EHCI_MAX_SITD */
  4010. #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
  4011. for (index = 1; index < USB_HOST_EHCI_ISO_NUMBER; ++index)
  4012. {
  4013. ehciInstance->ehciIsoList[index - 1U].next = &ehciInstance->ehciIsoList[index];
  4014. }
  4015. ehciInstance->ehciIsoList[USB_HOST_EHCI_ISO_NUMBER - 1U].next = NULL;
  4016. #endif
  4017. /* initialize pipes */
  4018. ehciInstance->ehciPipeList = ehciInstance->ehciPipeIndexBase;
  4019. for (index = 1; index < USB_HOST_CONFIG_MAX_PIPES; ++index)
  4020. {
  4021. temp = (void *)&ehciInstance->ehciPipeList[index];
  4022. ehciInstance->ehciPipeList[index - 1U].pipeCommon.next = (usb_host_pipe_t *)temp;
  4023. }
  4024. /* initialize mutext */
  4025. ehciInstance->ehciMutex = (osa_mutex_handle_t)(&ehciInstance->mutexBuffer[0]);
  4026. osaStatus = OSA_MutexCreate(ehciInstance->ehciMutex);
  4027. if (osaStatus != KOSA_StatusSuccess)
  4028. {
  4029. #ifdef HOST_ECHO
  4030. usb_echo("ehci mutex init fail\r\n");
  4031. #endif
  4032. OSA_MemoryFree(ehciInstance);
  4033. return kStatus_USB_Error;
  4034. }
  4035. /* initialize task event */
  4036. ehciInstance->taskEventHandle = (osa_event_handle_t)&ehciInstance->taskEventHandleBuffer[0];
  4037. osaStatus = OSA_EventCreate(ehciInstance->taskEventHandle, 1);
  4038. if (osaStatus != KOSA_StatusSuccess)
  4039. {
  4040. #ifdef HOST_ECHO
  4041. usb_echo("ehci event init fail\r\n");
  4042. #endif
  4043. (void)OSA_MutexDestroy(ehciInstance->ehciMutex);
  4044. OSA_MemoryFree(ehciInstance);
  4045. return kStatus_USB_Error;
  4046. }
  4047. /* initialize first qh */
  4048. ehciInstance->shedFirstQh = ehciInstance->ehciQhList;
  4049. ehciInstance->ehciQhList =
  4050. (usb_host_ehci_qh_t *)(ehciInstance->ehciQhList->horizontalLinkPointer & EHCI_HOST_POINTER_ADDRESS_MASK);
  4051. ehciInstance->shedFirstQh->staticEndpointStates[0] |= (1UL << EHCI_HOST_QH_H_SHIFT); /* first qh */
  4052. ehciInstance->shedFirstQh->horizontalLinkPointer = EHCI_HOST_T_INVALID_VALUE;
  4053. ehciInstance->shedFirstQh->currentQtdPointer = EHCI_HOST_T_INVALID_VALUE;
  4054. ehciInstance->shedFirstQh->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
  4055. ehciInstance->shedFirstQh->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
  4056. ehciInstance->shedFirstQh->horizontalLinkPointer =
  4057. (uint32_t)((uint32_t)(ehciInstance->shedFirstQh) | EHCI_HOST_POINTER_TYPE_QH);
  4058. /* initialize periodic list */
  4059. temp = (void *)ehciInstance->ehciFrameList;
  4060. framePointer = (uint32_t *)temp;
  4061. for (index = 0; index < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE; ++index)
  4062. {
  4063. framePointer[index] = EHCI_HOST_T_INVALID_VALUE;
  4064. }
  4065. (void)USB_HostEhciStartIP(ehciInstance); /* start ehci ip */
  4066. *controllerHandle = ehciInstance;
  4067. return kStatus_USB_Success;
  4068. }
  4069. usb_status_t USB_HostEhciDestory(usb_host_controller_handle controllerHandle)
  4070. {
  4071. usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
  4072. /* disable all interrupts */
  4073. ehciInstance->ehciIpBase->USBINTR = 0;
  4074. /* stop the controller */
  4075. ehciInstance->ehciIpBase->USBCMD = 0;
  4076. /* free memory */
  4077. #if (USB_HOST_CONFIG_EHCI == 1U)
  4078. if (ehciInstance->ehciFrameList == &s_UsbHostEhciFrameList1[0])
  4079. {
  4080. usbHostEhciFramListStatus[0] = 0;
  4081. }
  4082. #elif (USB_HOST_CONFIG_EHCI == 2U)
  4083. if (ehciInstance->ehciFrameList == &s_UsbHostEhciFrameList1[0])
  4084. {
  4085. usbHostEhciFramListStatus[0] = 0;
  4086. }
  4087. else if (ehciInstance->ehciFrameList == &s_UsbHostEhciFrameList2[0])
  4088. {
  4089. usbHostEhciFramListStatus[1] = 0;
  4090. }
  4091. else
  4092. {
  4093. /*no action*/
  4094. }
  4095. #endif
  4096. (void)OSA_MutexDestroy(ehciInstance->ehciMutex);
  4097. (void)OSA_EventDestroy(ehciInstance->taskEventHandle);
  4098. OSA_MemoryFree(ehciInstance);
  4099. return kStatus_USB_Success;
  4100. }
  4101. usb_status_t USB_HostEhciOpenPipe(usb_host_controller_handle controllerHandle,
  4102. usb_host_pipe_handle *pipeHandle,
  4103. usb_host_pipe_init_t *pipeInit)
  4104. {
  4105. usb_host_ehci_pipe_t *ehciPipePointer = NULL;
  4106. usb_status_t status;
  4107. uint32_t speed = 0;
  4108. usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
  4109. void *temp;
  4110. /* get one pipe */
  4111. USB_HostEhciLock();
  4112. if (ehciInstance->ehciPipeList != NULL)
  4113. {
  4114. ehciPipePointer = ehciInstance->ehciPipeList;
  4115. temp = (void *)ehciPipePointer->pipeCommon.next;
  4116. ehciInstance->ehciPipeList = (usb_host_ehci_pipe_t *)temp;
  4117. }
  4118. USB_HostEhciUnlock();
  4119. if (ehciPipePointer == NULL)
  4120. {
  4121. #ifdef HOST_ECHO
  4122. usb_echo("ehci open pipe failed\r\n");
  4123. #endif
  4124. return kStatus_USB_Busy;
  4125. }
  4126. /* initialize pipe informations */
  4127. USB_HostEhciZeroMem((void *)ehciPipePointer, sizeof(usb_host_ehci_pipe_t) / 4U);
  4128. ehciPipePointer->pipeCommon.deviceHandle = pipeInit->devInstance;
  4129. ehciPipePointer->pipeCommon.endpointAddress = pipeInit->endpointAddress;
  4130. ehciPipePointer->pipeCommon.direction = pipeInit->direction;
  4131. ehciPipePointer->pipeCommon.interval = pipeInit->interval;
  4132. ehciPipePointer->pipeCommon.maxPacketSize = pipeInit->maxPacketSize;
  4133. ehciPipePointer->pipeCommon.pipeType = pipeInit->pipeType;
  4134. ehciPipePointer->pipeCommon.numberPerUframe = pipeInit->numberPerUframe + 1U;
  4135. if (ehciPipePointer->pipeCommon.numberPerUframe > 3U)
  4136. {
  4137. ehciPipePointer->pipeCommon.numberPerUframe = 3U;
  4138. }
  4139. ehciPipePointer->pipeCommon.nakCount = pipeInit->nakCount;
  4140. ehciPipePointer->pipeCommon.nextdata01 = 0U;
  4141. ehciPipePointer->ehciQh = NULL;
  4142. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  4143. (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
  4144. if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
  4145. (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT))
  4146. {
  4147. if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS)
  4148. {
  4149. ehciPipePointer->pipeCommon.interval =
  4150. (uint16_t)(1UL << (ehciPipePointer->pipeCommon.interval - 1U)); /* iso interval is the power of 2 */
  4151. }
  4152. else
  4153. {
  4154. if (speed == USB_SPEED_HIGH)
  4155. {
  4156. ehciPipePointer->pipeCommon.interval = (uint16_t)(
  4157. 1UL << (ehciPipePointer->pipeCommon.interval - 1U)); /* HS interrupt interval is the power of 2 */
  4158. }
  4159. else
  4160. {
  4161. ehciPipePointer->pipeCommon.interval = USB_HostEhciGet2PowerValue(
  4162. (uint8_t)ehciPipePointer->pipeCommon.interval); /* FS/LS interrupt interval should be the power of
  4163. 2, it is used for ehci bandwidth */
  4164. }
  4165. }
  4166. }
  4167. /* save the micro-frame interval, it is convenient for the interval process */
  4168. if (speed == USB_SPEED_HIGH)
  4169. {
  4170. ehciPipePointer->uframeInterval = ehciPipePointer->pipeCommon.interval;
  4171. }
  4172. else
  4173. {
  4174. ehciPipePointer->uframeInterval = 8U * ehciPipePointer->pipeCommon.interval;
  4175. }
  4176. /* open pipe */
  4177. switch (ehciPipePointer->pipeCommon.pipeType)
  4178. {
  4179. case USB_ENDPOINT_CONTROL:
  4180. case USB_ENDPOINT_BULK:
  4181. status = USB_HostEhciOpenControlBulk(ehciInstance, ehciPipePointer);
  4182. break;
  4183. #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
  4184. ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
  4185. case USB_ENDPOINT_ISOCHRONOUS:
  4186. status = USB_HostEhciOpenIso(ehciInstance, ehciPipePointer);
  4187. break;
  4188. #endif
  4189. case USB_ENDPOINT_INTERRUPT:
  4190. status = USB_HostEhciOpenInterrupt(ehciInstance, ehciPipePointer);
  4191. break;
  4192. default:
  4193. status = kStatus_USB_Error;
  4194. break;
  4195. }
  4196. if (status != kStatus_USB_Success)
  4197. {
  4198. /* release pipe */
  4199. USB_HostEhciLock();
  4200. temp = (void *)ehciInstance->ehciPipeList;
  4201. ehciPipePointer->pipeCommon.next = (usb_host_pipe_t *)temp;
  4202. ehciInstance->ehciPipeList = ehciPipePointer;
  4203. USB_HostEhciUnlock();
  4204. return status;
  4205. }
  4206. /* add pipe to run pipe list */
  4207. USB_HostEhciLock();
  4208. temp = (void *)ehciInstance->ehciRunningPipeList;
  4209. ehciPipePointer->pipeCommon.next = (usb_host_pipe_t *)temp;
  4210. ehciInstance->ehciRunningPipeList = ehciPipePointer;
  4211. USB_HostEhciUnlock();
  4212. *pipeHandle = ehciPipePointer;
  4213. return status;
  4214. }
  4215. usb_status_t USB_HostEhciClosePipe(usb_host_controller_handle controllerHandle, usb_host_pipe_handle pipeHandle)
  4216. {
  4217. usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
  4218. usb_host_ehci_pipe_t *ehciPipePointer = (usb_host_ehci_pipe_t *)pipeHandle;
  4219. usb_host_pipe_t *prevPointer = NULL;
  4220. void *temp;
  4221. void *tempCurrent;
  4222. switch (ehciPipePointer->pipeCommon.pipeType)
  4223. {
  4224. case USB_ENDPOINT_BULK:
  4225. case USB_ENDPOINT_CONTROL:
  4226. (void)USB_HostEhciCloseControlBulk(ehciInstance, ehciPipePointer);
  4227. break;
  4228. case USB_ENDPOINT_INTERRUPT:
  4229. (void)USB_HostEhciCloseInterrupt(ehciInstance, ehciPipePointer);
  4230. break;
  4231. #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
  4232. ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
  4233. case USB_ENDPOINT_ISOCHRONOUS:
  4234. (void)USB_HostEhciCloseIso(ehciInstance, ehciPipePointer);
  4235. break;
  4236. #endif
  4237. default:
  4238. /*no action*/
  4239. break;
  4240. }
  4241. /* delete pipe from run pipe list */
  4242. USB_HostEhciLock();
  4243. temp = (void *)ehciInstance->ehciRunningPipeList;
  4244. prevPointer = (usb_host_pipe_t *)temp;
  4245. tempCurrent = (void *)ehciPipePointer;
  4246. if (prevPointer == (usb_host_pipe_t *)tempCurrent)
  4247. {
  4248. temp = (void *)prevPointer->next;
  4249. ehciInstance->ehciRunningPipeList = (usb_host_ehci_pipe_t *)(temp);
  4250. }
  4251. else
  4252. {
  4253. while (prevPointer != NULL)
  4254. {
  4255. temp = (void *)ehciPipePointer;
  4256. if (prevPointer->next == (usb_host_pipe_t *)temp)
  4257. {
  4258. prevPointer->next = ehciPipePointer->pipeCommon.next;
  4259. break;
  4260. }
  4261. else
  4262. {
  4263. prevPointer = prevPointer->next;
  4264. }
  4265. }
  4266. }
  4267. USB_HostEhciUnlock();
  4268. /* release pipe */
  4269. USB_HostEhciLock();
  4270. temp = (void *)ehciInstance->ehciPipeList;
  4271. ehciPipePointer->pipeCommon.next = (usb_host_pipe_t *)temp;
  4272. ehciInstance->ehciPipeList = ehciPipePointer;
  4273. USB_HostEhciUnlock();
  4274. return kStatus_USB_Success;
  4275. }
  4276. usb_status_t USB_HostEhciWritePipe(usb_host_controller_handle controllerHandle,
  4277. usb_host_pipe_handle pipeHandle,
  4278. usb_host_transfer_t *transfer)
  4279. {
  4280. usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
  4281. usb_host_ehci_pipe_t *ehciPipePointer = (usb_host_ehci_pipe_t *)pipeHandle;
  4282. usb_status_t status = kStatus_USB_Success;
  4283. #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
  4284. ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
  4285. uint32_t speed = 0U;
  4286. #endif
  4287. switch (ehciPipePointer->pipeCommon.pipeType)
  4288. {
  4289. case USB_ENDPOINT_BULK:
  4290. case USB_ENDPOINT_CONTROL:
  4291. case USB_ENDPOINT_INTERRUPT:
  4292. status = USB_HostEhciQhQtdListInit(ehciInstance, ehciPipePointer,
  4293. transfer); /* initialize qtd for control/bulk transfer */
  4294. break;
  4295. #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
  4296. ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
  4297. case USB_ENDPOINT_ISOCHRONOUS:
  4298. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  4299. (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
  4300. if (speed == USB_SPEED_HIGH)
  4301. {
  4302. #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
  4303. status = USB_HostEhciItdArrayInit(ehciInstance, ehciPipePointer,
  4304. transfer); /* initialize itd for iso transfer */
  4305. #endif
  4306. }
  4307. else
  4308. {
  4309. #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
  4310. status = USB_HostEhciSitdArrayInit(ehciInstance, ehciPipePointer,
  4311. transfer); /* initialize sitd for iso transfer */
  4312. #endif
  4313. }
  4314. break;
  4315. #endif
  4316. default:
  4317. /*no action*/
  4318. break;
  4319. }
  4320. return status;
  4321. }
  4322. usb_status_t USB_HostEhciReadpipe(usb_host_controller_handle controllerHandle,
  4323. usb_host_pipe_handle pipeHandle,
  4324. usb_host_transfer_t *transfer)
  4325. {
  4326. return USB_HostEhciWritePipe(controllerHandle, pipeHandle, transfer); /* same as write */
  4327. }
  4328. usb_status_t USB_HostEhciIoctl(usb_host_controller_handle controllerHandle, uint32_t ioctlEvent, void *ioctlParam)
  4329. {
  4330. usb_status_t status = kStatus_USB_Success;
  4331. usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
  4332. usb_host_cancel_param_t *param;
  4333. usb_host_ehci_pipe_t *ehciPipePointer;
  4334. volatile usb_host_ehci_qh_t *vltQhPointer;
  4335. uint32_t deviceAddress = 0;
  4336. usb_host_controller_control_t controlCode = (usb_host_controller_control_t)ioctlEvent;
  4337. if (controllerHandle == NULL)
  4338. {
  4339. return kStatus_USB_InvalidHandle;
  4340. }
  4341. switch (controlCode)
  4342. {
  4343. case kUSB_HostCancelTransfer: /* cancel pipe or one transfer */
  4344. param = (usb_host_cancel_param_t *)ioctlParam;
  4345. status = USB_HostEhciCancelPipe(ehciInstance, (usb_host_ehci_pipe_t *)param->pipeHandle, param->transfer);
  4346. break;
  4347. case kUSB_HostBusControl: /* bus control */
  4348. status = USB_HostEhciControlBus(ehciInstance, *((uint8_t *)ioctlParam));
  4349. break;
  4350. case kUSB_HostGetFrameNumber: /* get frame number */
  4351. *((uint32_t *)ioctlParam) = ((ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE) >> 3);
  4352. break;
  4353. case kUSB_HostUpdateControlEndpointAddress:
  4354. ehciPipePointer = (usb_host_ehci_pipe_t *)ioctlParam;
  4355. vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
  4356. /* update address */
  4357. (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
  4358. (uint32_t)kUSB_HostGetDeviceAddress, &deviceAddress);
  4359. vltQhPointer->staticEndpointStates[0] |= deviceAddress;
  4360. USB_HostEhciDelay(ehciInstance->ehciIpBase, 2U);
  4361. break;
  4362. case kUSB_HostUpdateControlPacketSize:
  4363. ehciPipePointer = (usb_host_ehci_pipe_t *)ioctlParam;
  4364. vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
  4365. USB_HostEhciLock();
  4366. if (0U != (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK))
  4367. {
  4368. USB_HostEhciStopAsync(ehciInstance);
  4369. /* update max packet size */
  4370. vltQhPointer->staticEndpointStates[0] =
  4371. (((vltQhPointer->staticEndpointStates[0]) & (~EHCI_HOST_QH_MAX_PACKET_LENGTH_MASK)) |
  4372. ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT));
  4373. USB_HostEhciStartAsync(ehciInstance);
  4374. }
  4375. else
  4376. {
  4377. /* update max packet size */
  4378. vltQhPointer->staticEndpointStates[0] =
  4379. (((vltQhPointer->staticEndpointStates[0]) & (~EHCI_HOST_QH_MAX_PACKET_LENGTH_MASK)) |
  4380. ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT));
  4381. }
  4382. USB_HostEhciUnlock();
  4383. break;
  4384. #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
  4385. case kUSB_HostTestModeInit: /* test mode control */
  4386. USB_HostEhciTestModeInit((usb_host_device_instance_t *)ioctlParam);
  4387. break;
  4388. #endif
  4389. default:
  4390. status = kStatus_USB_NotSupported;
  4391. break;
  4392. }
  4393. return status;
  4394. }
  4395. void USB_HostEhciTaskFunction(void *hostHandle)
  4396. {
  4397. usb_host_ehci_instance_t *ehciInstance;
  4398. uint32_t bitSet;
  4399. usb_device_handle deviceHandle;
  4400. if (hostHandle == NULL)
  4401. {
  4402. return;
  4403. }
  4404. ehciInstance = (usb_host_ehci_instance_t *)((usb_host_instance_t *)hostHandle)->controllerHandle;
  4405. if (OSA_EventWait(ehciInstance->taskEventHandle, 0xFF, 0, USB_OSA_WAIT_TIMEOUT, &bitSet) ==
  4406. KOSA_StatusSuccess) /* wait all event */
  4407. {
  4408. if (0U != (bitSet & EHCI_TASK_EVENT_PORT_CHANGE)) /* port change */
  4409. {
  4410. USB_HostEhciPortChange(ehciInstance);
  4411. }
  4412. if (0U != (bitSet & EHCI_TASK_EVENT_TIMER0)) /* timer0 */
  4413. {
  4414. USB_HostEhciTimer0(ehciInstance);
  4415. }
  4416. #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
  4417. if (0U != (bitSet & EHCI_TASK_EVENT_TIMER1)) /* timer1 */
  4418. {
  4419. USB_HostEhciTimer1(ehciInstance);
  4420. }
  4421. #endif
  4422. if ((ehciInstance->deviceAttached == (uint8_t)kEHCIDeviceAttached))
  4423. {
  4424. if (0U != (bitSet & EHCI_TASK_EVENT_TRANSACTION_DONE)) /* transaction done */
  4425. {
  4426. USB_HostEhciTransactionDone(ehciInstance);
  4427. }
  4428. if (0U != (bitSet & EHCI_TASK_EVENT_DEVICE_DETACH)) /* device detach */
  4429. {
  4430. ehciInstance->ehciIpBase->USBINTR &=
  4431. (~USBHS_USBINTR_PCE_MASK); /* disable attach, enable when the detach process is done */
  4432. ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceDetached;
  4433. (void)USB_HostDetachDevice(ehciInstance->hostHandle, 0, 0);
  4434. }
  4435. }
  4436. else if (ehciInstance->deviceAttached != (uint8_t)kEHCIDeviceAttached)
  4437. {
  4438. if (0U != (bitSet & EHCI_TASK_EVENT_DEVICE_ATTACH)) /* device is attached */
  4439. {
  4440. USB_HostEhciStartAsync(ehciInstance);
  4441. USB_HostEhciStartPeriodic(ehciInstance);
  4442. if (USB_HostAttachDevice(ehciInstance->hostHandle, ehciInstance->firstDeviceSpeed, 0, 0, 1,
  4443. &deviceHandle) == kStatus_USB_Success)
  4444. {
  4445. ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceAttached;
  4446. }
  4447. }
  4448. }
  4449. else
  4450. {
  4451. /*no action*/
  4452. }
  4453. }
  4454. }
  4455. void USB_HostEhciIsrFunction(void *hostHandle)
  4456. {
  4457. usb_host_ehci_instance_t *ehciInstance;
  4458. static uint32_t interruptStatus = 0;
  4459. if (hostHandle == NULL)
  4460. {
  4461. return;
  4462. }
  4463. ehciInstance = (usb_host_ehci_instance_t *)((usb_host_instance_t *)hostHandle)->controllerHandle;
  4464. #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
  4465. #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
  4466. if (0U != (ehciInstance->registerNcBase->USB_OTGn_CTRL & USBNC_USB_OTGn_CTRL_WIE_MASK))
  4467. {
  4468. usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
  4469. ehciInstance->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK;
  4470. (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
  4471. kUSB_HostEventDetectResume); /* call host callback function */
  4472. #if (defined(USBNC_USB_OTGn_PHY_CTRL_0_UTMI_CLK_VLD_MASK))
  4473. while (0U == (ehciInstance->registerNcBase->USB_OTGn_PHY_CTRL_0 & USBNC_USB_OTGn_PHY_CTRL_0_UTMI_CLK_VLD_MASK))
  4474. {
  4475. }
  4476. #endif
  4477. if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
  4478. {
  4479. USB_HostEhciStartAsync(ehciInstance);
  4480. USB_HostEhciStartPeriodic(ehciInstance);
  4481. }
  4482. ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK);
  4483. if ((kBus_EhciSuspended == ehciInstance->busSuspendStatus))
  4484. {
  4485. /* ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_FPR_MASK; */
  4486. ehciInstance->busSuspendStatus = kBus_EhciStartResume;
  4487. }
  4488. else
  4489. {
  4490. /*no action*/
  4491. }
  4492. }
  4493. else
  4494. {
  4495. /*no action*/
  4496. }
  4497. #else
  4498. #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
  4499. #else
  4500. if (0U != (ehciInstance->ehciIpBase->USBGENCTRL & USBHS_USBGENCTRL_WU_IE_MASK))
  4501. {
  4502. usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
  4503. (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
  4504. kUSB_HostEventDetectResume); /* call host callback function */
  4505. while (0U == (USBPHY->PLL_SIC & USBPHY_PLL_SIC_PLL_LOCK_MASK))
  4506. {
  4507. }
  4508. ehciInstance->ehciIpBase->USBGENCTRL |= USBHS_USBGENCTRL_WU_INT_CLR_MASK;
  4509. ehciInstance->ehciIpBase->USBGENCTRL &= ~USBHS_USBGENCTRL_WU_IE_MASK;
  4510. if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
  4511. {
  4512. USB_HostEhciStartAsync(ehciInstance);
  4513. USB_HostEhciStartPeriodic(ehciInstance);
  4514. }
  4515. ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK);
  4516. if ((kBus_EhciSuspended == ehciInstance->busSuspendStatus))
  4517. {
  4518. ehciInstance->busSuspendStatus = kBus_EhciStartResume;
  4519. /*ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_FPR_MASK; */
  4520. }
  4521. else
  4522. {
  4523. /*no action*/
  4524. }
  4525. }
  4526. else
  4527. {
  4528. /*no action*/
  4529. }
  4530. #endif /* FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT */
  4531. #endif /* FSL_FEATURE_SOC_USBNC_COUNT */
  4532. #endif /* USB_HOST_CONFIG_LOW_POWER_MODE */
  4533. interruptStatus = ehciInstance->ehciIpBase->USBSTS;
  4534. interruptStatus &= ehciInstance->ehciIpBase->USBINTR;
  4535. while (0U != interruptStatus) /* there are usb interrupts */
  4536. {
  4537. ehciInstance->ehciIpBase->USBSTS = interruptStatus; /* clear interrupt */
  4538. if (0U != (interruptStatus & USBHS_USBSTS_SRI_MASK)) /* SOF interrupt */
  4539. {
  4540. }
  4541. if (0U != (interruptStatus & USBHS_USBSTS_SEI_MASK)) /* system error interrupt */
  4542. {
  4543. }
  4544. if ((0U != (interruptStatus & USBHS_USBSTS_UI_MASK)) ||
  4545. (0U != (interruptStatus & USBHS_USBSTS_UEI_MASK))) /* USB interrupt or USB error interrupt */
  4546. {
  4547. (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_TRANSACTION_DONE);
  4548. }
  4549. if (0U != (interruptStatus & USBHS_USBSTS_PCI_MASK)) /* port change detect interrupt */
  4550. {
  4551. #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
  4552. usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
  4553. if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_FPR_MASK))
  4554. {
  4555. if (kBus_EhciStartSuspend == ehciInstance->busSuspendStatus)
  4556. {
  4557. if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
  4558. {
  4559. USB_HostEhciStartAsync(ehciInstance);
  4560. USB_HostEhciStartPeriodic(ehciInstance);
  4561. }
  4562. (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
  4563. kUSB_HostEventNotSuspended); /* call host callback function */
  4564. hostPointer->suspendedDevice = NULL;
  4565. ehciInstance->busSuspendStatus = kBus_EhciIdle;
  4566. ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
  4567. }
  4568. else
  4569. {
  4570. /*no action */
  4571. }
  4572. }
  4573. #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
  4574. if ((kBus_EhciSuspended == ehciInstance->busSuspendStatus))
  4575. {
  4576. usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
  4577. (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
  4578. kUSB_HostEventDetectResume); /* call host callback function */
  4579. uint32_t delay = 100000;
  4580. while (delay-- && !(USBOTG->PLL_CONTROL_0 & USBC_PLL_CONTROL_0_PLL_READY_MASK))
  4581. {
  4582. }
  4583. if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
  4584. {
  4585. USB_HostEhciStartAsync(ehciInstance);
  4586. USB_HostEhciStartPeriodic(ehciInstance);
  4587. }
  4588. ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK);
  4589. ehciInstance->busSuspendStatus = kBus_EhciStartResume;
  4590. }
  4591. #endif
  4592. #endif
  4593. (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_PORT_CHANGE);
  4594. }
  4595. if (0U != (interruptStatus & USBHS_USBSTS_TI0_MASK)) /* timer 0 interrupt */
  4596. {
  4597. (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_TIMER0);
  4598. }
  4599. #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
  4600. if (0U != (interruptStatus & USBHS_USBSTS_TI1_MASK)) /* timer 1 interrupt */
  4601. {
  4602. (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_TIMER1);
  4603. }
  4604. #endif
  4605. interruptStatus = ehciInstance->ehciIpBase->USBSTS;
  4606. interruptStatus &= ehciInstance->ehciIpBase->USBINTR;
  4607. }
  4608. }
  4609. #endif /* USB_HOST_CONFIG_EHCI */