usb_host_ehci.c 201 KB

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