12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018 |
- /*
- * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
- * Copyright 2016,2019 - 2020 NXP
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #include <usb/include/usb_host_config.h>
- #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI > 0U))
- #include "usb_host.h"
- #include "usb_host_hci.h"
- #include "usb_host_devices.h"
- #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
- #include "usb_host_framework.h"
- #endif
- #include "fsl_device_registers.h"
- #include "usb_host_ehci.h"
- #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT))
- #include <usb/phy/usb_phy.h>
- #endif
- #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
- #include "usb_host.h"
- #endif
- //#define USB_GINSTANCE_SIZE (sizeof(usb_host_ehci_instance_t))
- //#if defined(__ICCARM__) /* IAR Workbench */
- //#pragma location = "usb_heap_section"
- //static char ginstance_base[USB_GINSTANCE_SIZE];
- //#endif
- /*******************************************************************************
- * Definitions
- ******************************************************************************/
- #if defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM > 0U)
- #error The SOC does not suppoort dedicated RAM case.
- #endif
- #define USB_HOST_EHCI_BANDWIDTH_DELAY (3500U)
- #define USB_HOST_EHCI_BANDWIDTH_HUB_LS_SETUP (333U)
- #define USB_HOST_EHCI_BANDWIDTH_FRAME_TOTOAL_TIME (900U)
- #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
- #define USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH (18U)
- #define USB_HOST_EHCI_PORTSC_PTC_J_STATE (0x01U)
- #define USB_HOST_EHCI_PORTSC_PTC_K_STATE (0x02U)
- #define USB_HOST_EHCI_PORTSC_PTC_SE0_NAK (0x03U)
- #define USB_HOST_EHCI_PORTSC_PTC_PACKET (0x04U)
- #define USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_HS (0x05U)
- #define USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_FS (0x06U)
- #define USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_LS (0x07U)
- #endif
- /*******************************************************************************
- * Prototypes
- ******************************************************************************/
- /*!
- * @brief compute data bandwidth time.
- *
- * @param speed data speed.
- * @param pipeType data type.
- * @param direction data direction.
- * @param dataLength data length.
- *
- *@return time value.
- */
- static uint32_t USB_HostBandwidthComputeTime(uint8_t speed, uint8_t pipeType, uint8_t direction, uint32_t dataLength);
- /*!
- * @brief compute current allocated bandwidth when ehci work as full-speed or low-speed host.
- *
- * @param ehciInstance ehci instance pointer.
- * @param frameIndex frame index.
- * @param frameBandwidths return frame bandwidth data.
- */
- static void USB_HostBandwidthFslsHostComputeCurrent(usb_host_ehci_instance_t *ehciInstance,
- uint16_t frameIndex,
- uint16_t *frameBandwidth);
- /*!
- * @brief compute current hub's allocated FS/LS bandwidth when ehci work as hi-speed host.
- *
- * @param ehciInstance ehci instance pointer.
- * @param hubNumber hub address.
- * @param frameIndex frame index.
- * @param frameBandwidths return frame bandwidth data.
- */
- static void USB_HostBandwidthHsHostComputeCurrentFsls(usb_host_ehci_instance_t *ehciInstance,
- uint32_t hubNumber,
- uint16_t frameIndex,
- uint16_t frameBandwidths[8]);
- /*!
- * @brief compute current allocated HS bandwidth when ehci work as hi-speed host.
- *
- * @param ehciInstance ehci instance pointer.
- * @param frameIndex frame index.
- * @param frameBandwidths return frame bandwidth data.
- */
- static void USB_HostBandwidthHsHostComputeCurrentHsAll(usb_host_ehci_instance_t *ehciInstance,
- uint16_t frameIndex,
- uint16_t frameBandwidths[8]);
- /*!
- * @brief allocate HS bandwidth when host work as high-speed host.
- *
- * @param ehciInstance ehci instance pointer.
- * @param uframeInterval micro-frame interval.
- * @param timeData time for allocating.
- * @param uframe_index_out return start uframe index.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostBandwidthHsHostAllocateHsCommon(usb_host_ehci_instance_t *ehciInstance,
- uint16_t uframeInterval,
- uint16_t timeData,
- uint16_t *uframeIndexOut);
- /*!
- * @brief allocate HS interrupt bandwidth when host work as high-speed host.
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe pointer.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostBandwidthHsHostAllocateInterrupt(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer);
- /*!
- * @brief allocate bandwidth when host work as full-speed or low-speed host.
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe pointer.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostBandwidthFslsHostAllocate(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer);
- /*!
- * @brief get the 2 power value of uint8_t.
- *
- * @param value input uint8_t value.
- */
- static uint8_t USB_HostEhciGet2PowerValue(uint8_t value);
- /*!
- * @brief memory zero.
- *
- * @param buffer buffer pointer.
- * @param length buffer length.
- */
- static void USB_HostEhciZeroMem(uint32_t *buffer, uint32_t length);
- /*!
- * @brief host ehci delay.
- *
- * @param ehciIpBase ehci ip base address.
- * @param ms millisecond.
- */
- static void USB_HostEhciDelay(USBHS_Type *ehciIpBase, uint32_t ms);
- /*!
- * @brief host ehci start async schedule.
- *
- * @param ehciInstance ehci instance pointer.
- */
- static void USB_HostEhciStartAsync(usb_host_ehci_instance_t *ehciInstance);
- /*!
- * @brief host ehci stop async schedule.
- *
- * @param ehciInstance ehci instance pointer.
- */
- static void USB_HostEhciStopAsync(usb_host_ehci_instance_t *ehciInstance);
- /*!
- * @brief host ehci start periodic schedule.
- *
- * @param ehciInstance ehci instance pointer.
- */
- static void USB_HostEhciStartPeriodic(usb_host_ehci_instance_t *ehciInstance);
- /*!
- * @brief host ehci stop periodic schedule.
- *
- * @param ehciInstance ehci instance pointer.
- */
- static void USB_HostEhciStopPeriodic(usb_host_ehci_instance_t *ehciInstance);
- /*!
- * @brief initialize the qtd for one transfer.
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe pointer.
- * @param transfer transfer information.
- *
- *@return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostEhciQhQtdListInit(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer,
- usb_host_transfer_t *transfer);
- /*!
- * @brief release the qtd list.
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciQtdStart qtd list start pointer.
- * @param ehciQtdEnd qtd list end pointer.
- *
- *@return the transfer's length.
- */
- static uint32_t USB_HostEhciQtdListRelease(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_qtd_t *ehciQtdStart,
- usb_host_ehci_qtd_t *ehciQtdEnd);
- /*!
- * @brief de-initialize qh's linking qtd list.
- * 1. remove qtd from qh; 2. remove transfer from qh; 3. release qtd; 4. transfer callback.
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe.
- *
- *@return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostEhciQhQtdListDeinit(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer);
- /*!
- * @brief de-initialize transfer's linking qtd list.
- * 1. stop this qh schedule; 2. remove qtd from qh; 3. remove transfer from qh; 4. release qtd; 5. transfer callback; 6.
- *start this qh schedule.
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe pointer.
- * @param transfer transfer information.
- *
- *@return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostEhciTransferQtdListDeinit(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer,
- usb_host_transfer_t *transfer);
- /*!
- * @brief initialize QH when opening one control, bulk or interrupt pipe.
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe pointer.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostEhciQhInit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer);
- /*!
- * @brief de-initialize QH when closing one control, bulk or interrupt pipe.
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe pointer.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostEhciQhDeinit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer);
- /*!
- * @brief add qh to one frame entry.
- *
- * @param ehciInstance ehci instance pointer.
- * @param entryPointerValue entry pointer value.
- * @param framePos frame index.
- * @param uframeInterval micro-frame interval.
- */
- static void USB_HostEhciAddQhToFrame(usb_host_ehci_instance_t *ehciInstance,
- uint32_t entryPointerValue,
- uint16_t framePos,
- uint16_t uframeInterval);
- /*!
- * @brief remove entry from frame list.
- *
- * @param ehciInstance ehci instance pointer.
- * @param entryPointerValue entry pointer value.
- * @param framePos frame index.
- */
- static void USB_HostEhciRemoveFromFrame(usb_host_ehci_instance_t *ehciInstance,
- uint32_t entryPointerValue,
- uint16_t framePos);
- #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
- /*!
- * @brief add sitd array to the frame list.
- *
- * @param ehciInstance ehci instance pointer.
- * @param entryPointerValue entry pointer value.
- * @param startEntryPointer sitd entry pointer.
- */
- static void USB_HostEhciLinkSitd(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer,
- void *startEntryPointer);
- /*!
- * @brief initialize sitd array for one transfer.
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe pointer.
- * @param transfer transfer information.
- */
- static usb_status_t USB_HostEhciSitdArrayInit(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer,
- usb_host_transfer_t *transfer);
- /*!
- * @brief release sitd list.
- *
- * @param ehciInstance ehci instance pointer.
- * @param startSitdPointer start sitd pointer.
- * @param endSitdPointer end sitd pointer.
- *
- * @return transfer's result length.
- */
- static uint32_t USB_HostEhciSitdArrayRelease(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_sitd_t *startSitdPointer,
- usb_host_ehci_sitd_t *endSitdPointer);
- /*!
- * @brief de-initialize sitd list.
- * 1. remove transfer; 2. remove sitd from frame list and release sitd; 3. transfer callback
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe pointer.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostEhciSitdArrayDeinit(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer);
- #endif /* USB_HOST_CONFIG_EHCI_MAX_SITD */
- #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
- /*!
- * @brief compute the frame index when inserting itd.
- *
- * @param ehciInstance ehci instance pointer.
- * @param lastLinkUframe last inserted micro-frame.
- * @param startUframe start micro-frame.
- * @param uframeInterval micro-frame interval.
- *
- * @return frame index
- */
- static uint32_t USB_HostEhciGetItdLinkFrame(usb_host_ehci_instance_t *ehciInstance,
- uint32_t lastLinkUframe,
- uint16_t startUframe,
- uint16_t uframeInterval);
- /*!
- * @brief initialize itd list for one transfer.
- * 1. initialize itd list; 2. insert itd to frame list.
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe pointer.
- * @param transfer transfer information.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostEhciItdArrayInit(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer,
- usb_host_transfer_t *transfer);
- /*!
- * @brief release itd list.
- *
- * @param ehciInstance ehci instance pointer.
- * @param startItdPointer start itd pointer.
- * @param endItdPointer end itd pointer.
- *
- * @return transfer's result length.
- */
- static uint32_t USB_HostEhciItdArrayRelease(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_itd_t *startItdPointer,
- usb_host_ehci_itd_t *endItdPointer);
- /*!
- * @brief de-initialize itd list.
- * 1. remove transfer; 2. remove itd from frame list and release itd; 3. transfer callback
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe pointer.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostEhciItdArrayDeinit(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer);
- #endif /* USB_HOST_CONFIG_EHCI_MAX_ITD */
- /*!
- * @brief open control or bulk pipe.
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe pointer.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostEhciOpenControlBulk(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer);
- /*!
- * @brief close control or bulk pipe.
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe pointer.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostEhciCloseControlBulk(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer);
- /*!
- * @brief open interrupt pipe.
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe pointer.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostEhciOpenInterrupt(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer);
- /*!
- * @brief close interrupt pipe.
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe pointer.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostEhciCloseInterrupt(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer);
- #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
- ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
- /*!
- * @brief open iso pipe.
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe pointer.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostEhciOpenIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer);
- /*!
- * @brief close iso pipe.
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe pointer.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostEhciCloseIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer);
- /*!
- * @brief allocate HS iso bandwidth when host work as high-speed host.
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe pointer.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostBandwidthHsHostAllocateIso(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer);
- #endif
- /*!
- * @brief reset ehci ip.
- *
- * @param ehciInstance ehci instance pointer.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostEhciResetIP(usb_host_ehci_instance_t *ehciInstance);
- /*!
- * @brief start ehci ip.
- *
- * @param ehciInstance ehci instance pointer.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostEhciStartIP(usb_host_ehci_instance_t *ehciInstance);
- /*!
- * @brief cancel pipe's transfers.
- *
- * @param ehciInstance ehci instance pointer.
- * @param ehciPipePointer ehci pipe pointer.
- * @param transfer the canceling transfer.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostEhciCancelPipe(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer,
- usb_host_transfer_t *transfer);
- /*!
- * @brief control ehci bus.
- *
- * @param ehciInstance ehci instance pointer.
- * @param bus_control control code.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostEhciControlBus(usb_host_ehci_instance_t *ehciInstance, uint8_t busControl);
- /*!
- * @brief ehci transaction done process function.
- *
- * @param ehciInstance ehci instance pointer.
- */
- void USB_HostEhciTransactionDone(usb_host_ehci_instance_t *ehciInstance);
- /*!
- * @brief ehci port change interrupt process function.
- *
- * @param ehciInstance ehci instance pointer.
- */
- static void USB_HostEhciPortChange(usb_host_ehci_instance_t *ehciInstance);
- /*!
- * @brief ehci timer0 interrupt process function.
- * cancel control/bulk transfer that time out.
- *
- * @param ehciInstance ehci instance pointer.
- */
- static void USB_HostEhciTimer0(usb_host_ehci_instance_t *ehciInstance);
- #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
- /*!
- * @brief ehci timer1 interrupt process function.
- * cancel control/bulk transfer that time out.
- *
- * @param ehciInstance ehci instance pointer.
- */
- static void USB_HostEhciTimer1(usb_host_ehci_instance_t *ehciInstance);
- #endif
- #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
- /*!
- * @brief suspend bus.
- *
- * @param ehciInstance ehci instance pointer.
- */
- static void USB_HostEhciSuspendBus(usb_host_ehci_instance_t *ehciInstance);
- /*!
- * @brief resume bus.
- *
- * @param ehciInstance ehci instance pointer.
- */
- static void USB_HostEhciResumeBus(usb_host_ehci_instance_t *ehciInstance);
- extern usb_status_t USB_HostStandardSetGetDescriptor(usb_host_device_instance_t *deviceInstance,
- usb_host_transfer_t *transfer,
- void *param);
- #endif /* USB_HOST_CONFIG_COMPLIANCE_TEST */
- /*******************************************************************************
- * Variables
- ******************************************************************************/
- /* EHCI controller driver instances. */
- #if (USB_HOST_CONFIG_EHCI == 1U)
- USB_RAM_ADDRESS_ALIGNMENT(4096)
- USB_CONTROLLER_DATA static uint8_t s_UsbHostEhciFrameList1[USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 4];
- static uint8_t usbHostEhciFramListStatus[1] = {0};
- USB_RAM_ADDRESS_ALIGNMENT(64) USB_CONTROLLER_DATA static usb_host_ehci_data_t s_UsbHostEhciData1;
- #elif (USB_HOST_CONFIG_EHCI == 2U)
- USB_RAM_ADDRESS_ALIGNMENT(4096)
- USB_CONTROLLER_DATA static uint8_t s_UsbHostEhciFrameList1[USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 4];
- USB_RAM_ADDRESS_ALIGNMENT(4096)
- USB_CONTROLLER_DATA static uint8_t s_UsbHostEhciFrameList2[USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 4];
- static uint8_t usbHostEhciFramListStatus[2] = {0, 0};
- USB_RAM_ADDRESS_ALIGNMENT(64) USB_CONTROLLER_DATA static usb_host_ehci_data_t s_UsbHostEhciData1;
- USB_RAM_ADDRESS_ALIGNMENT(64) USB_CONTROLLER_DATA static usb_host_ehci_data_t s_UsbHostEhciData2;
- #else
- #error "Please increase the instance count."
- #endif
- #define USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE (1024U)
- #define USB_HOST_EHCI_MAX_MICRFRAME_VALUE ((USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE << 3U) - 1U)
- static uint8_t s_SlotMaxBandwidth[8] = {125, 125, 125, 125, 125, 125, 50, 0};
- static uint8_t s_SlotMaxBandwidthHs[8] = {100, 100, 100, 100, 100, 100, 100, 100};
- /*******************************************************************************
- * Code
- ******************************************************************************/
- /*!
- * @brief EHCI NC get USB NC bass address.
- *
- * This function is used to get USB NC bass address.
- *
- * @param[in] controllerId EHCI controller ID; See the #usb_controller_index_t.
- *
- * @retval USB NC bass address.
- */
- #if (defined(USB_HOST_CONFIG_LOW_POWER_MODE) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
- #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
- static void *USB_EhciNCGetBase(uint8_t controllerId)
- {
- void *usbNCBase = NULL;
- #if ((defined FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
- uint32_t instance;
- uint32_t newinstance = 0;
- uint32_t usbnc_base_temp[] = USBNC_BASE_ADDRS;
- uint32_t usbnc_base[] = USBNC_BASE_ADDRS;
- if (controllerId < (uint8_t)kUSB_ControllerEhci0)
- {
- return NULL;
- }
- controllerId = controllerId - (uint8_t)kUSB_ControllerEhci0;
- for (instance = 0; instance < (sizeof(usbnc_base_temp) / sizeof(usbnc_base_temp[0])); instance++)
- {
- if (usbnc_base_temp[instance] != 0U)
- {
- usbnc_base[newinstance++] = usbnc_base_temp[instance];
- }
- }
- if (controllerId > newinstance)
- {
- return NULL;
- }
- usbNCBase = (void *)(uint8_t *)usbnc_base[controllerId];
- #endif
- return usbNCBase;
- }
- #endif
- #endif
- #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
- usb_status_t USB_HostEhciTestSetMode(usb_host_ehci_instance_t *ehciInstance, uint32_t testMode)
- {
- uint32_t ehciPortSC;
- ehciPortSC = ehciInstance->ehciIpBase->PORTSC1;
- ehciPortSC &= ~((uint32_t)USBHS_PORTSC1_PTC_MASK); /* clear test mode bits */
- ehciPortSC |= (testMode << USBHS_PORTSC1_PTC_SHIFT); /* set test mode bits */
- ehciInstance->ehciIpBase->PORTSC1 = ehciPortSC;
- return kStatus_USB_Success;
- }
- static void USB_HostEhciTestSuspendResume(usb_host_ehci_instance_t *ehciInstance)
- {
- uint8_t timeCount;
- timeCount = 15; /* 15s */
- while (timeCount--)
- {
- USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
- }
- USB_HostEhciSuspendBus(ehciInstance);
- timeCount = 15; /* 15s */
- while (timeCount--)
- {
- USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
- }
- USB_HostEhciResumeBus(ehciInstance);
- }
- static void USB_HostEhciTestCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
- {
- USB_HostFreeTransfer(param, transfer);
- }
- static void USB_HostEhciTestSingleStepGetDeviceDesc(usb_host_ehci_instance_t *ehciInstance,
- usb_device_handle deviceHandle)
- {
- usb_host_process_descriptor_param_t getDescriptorParam;
- usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
- usb_host_transfer_t *transfer;
- uint8_t timeCount;
- /* disable periodic shedule */
- USB_HostEhciStopPeriodic(ehciInstance);
- timeCount = 15; /* 15s */
- while (timeCount--)
- {
- USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
- }
- /* malloc one transfer */
- if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success)
- {
- #ifdef HOST_ECHO
- usb_echo("allocate transfer error\r\n");
- #endif
- return;
- }
- getDescriptorParam.descriptorLength = sizeof(usb_descriptor_device_t);
- getDescriptorParam.descriptorLength = 18;
- getDescriptorParam.descriptorBuffer = (uint8_t *)&deviceInstance->deviceDescriptor;
- getDescriptorParam.descriptorType = USB_DESCRIPTOR_TYPE_DEVICE;
- getDescriptorParam.descriptorIndex = 0;
- getDescriptorParam.languageId = 0;
- transfer->callbackFn = USB_HostEhciTestCallback;
- transfer->callbackParam = ehciInstance->hostHandle;
- transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_DIR_IN;
- transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
- transfer->setupPacket->wIndex = 0;
- transfer->setupPacket->wLength = 0;
- transfer->setupPacket->wValue = 0;
- USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam);
- }
- static usb_status_t USB_HostEhciSingleStepQtdListInit(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer,
- usb_host_transfer_t *transfer,
- uint8_t setupPhase)
- {
- volatile usb_host_ehci_qh_t *vltQhPointer;
- usb_host_ehci_qtd_t *qtdPointer = NULL;
- volatile uint32_t *entryPointer;
- uint32_t qtdNumber;
- uint32_t dataLength;
- uint32_t dataAddress;
- uint8_t index;
- /* compute the qtd number */
- qtdNumber = 1;
- vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
- /* get qtd list */
- USB_HostEhciLock();
- if (qtdNumber <= ehciInstance->ehciQtdNumber)
- {
- ehciInstance->ehciQtdNumber -= qtdNumber;
- qtdPointer = NULL;
- do
- {
- if (qtdPointer != NULL)
- {
- qtdPointer->nextQtdPointer = (uint32_t)ehciInstance->ehciQtdHead;
- }
- qtdPointer = ehciInstance->ehciQtdHead;
- ehciInstance->ehciQtdHead = (usb_host_ehci_qtd_t *)qtdPointer->nextQtdPointer;
- qtdPointer->nextQtdPointer = 0;
- } while (--qtdNumber);
- }
- else
- {
- USB_HostEhciUnlock();
- return kStatus_USB_Error;
- }
- USB_HostEhciUnlock();
- /* int qTD */
- if (setupPhase == 1) /* setup transaction qtd init */
- {
- qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
- /* dt: need set; ioc: 0; C_Page: 0; PID Code: SETUP; Status: Active */
- qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0;
- qtdPointer->transferResults[0] =
- ((0x00000000 << EHCI_HOST_QTD_DT_SHIFT) | (8 << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
- (EHCI_HOST_PID_SETUP << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
- dataAddress = (uint32_t)(transfer->setupPacket);
- qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
- /* set buffer pointer no matter data length */
- for (index = 0; index < 4; ++index)
- {
- qtdPointer->bufferPointers[index] = ((dataAddress + (index + 1) * 4 * 1024) & 0xFFFFF000);
- }
- }
- else if (setupPhase == 2) /* data transaction qtd */
- {
- dataLength = transfer->transferLength;
- if (dataLength != 0)
- {
- qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
- /* dt: need set; ioc: 0; C_Page: 0; PID Code: IN/OUT; Status: Active */
- qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0;
- qtdPointer->transferResults[0] =
- ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (dataLength << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
- (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
- dataAddress = (uint32_t)(transfer->transferBuffer);
- qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
- /* set buffer pointer no matter data length */
- for (index = 0; index < 4; ++index)
- {
- qtdPointer->bufferPointers[index] = ((dataAddress + (index + 1) * 4 * 1024) & 0xFFFFF000);
- }
- }
- }
- else if (setupPhase == 3)
- {
- /* status transaction qtd */
- qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
- /* dt: dont care; ioc: 1; C_Page: 0; PID Code: IN/OUT; Status: Active */
- qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0;
- qtdPointer->transferResults[0] =
- ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) |
- (EHCI_HOST_QTD_IOC_MASK) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
- qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE;
- }
- qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE;
- qtdPointer->transferResults[0] |= EHCI_HOST_QTD_IOC_MASK; /* set IOC */
- /* save qtd to transfer */
- transfer->union1.unitHead = (uint32_t)qtdPointer;
- transfer->union2.unitTail = (uint32_t)qtdPointer;
- /* link transfer to qh */
- transfer->next = NULL;
- if (vltQhPointer->ehciTransferHead == NULL)
- {
- transfer->next = NULL;
- vltQhPointer->ehciTransferHead = vltQhPointer->ehciTransferTail = transfer;
- }
- else
- {
- transfer->next = NULL;
- vltQhPointer->ehciTransferTail->next = transfer;
- vltQhPointer->ehciTransferTail = transfer;
- }
- USB_HostEhciLock();
- /* link qtd to qh (link to end) */
- entryPointer = &(vltQhPointer->nextQtdPointer);
- dataAddress = *entryPointer; /* dataAddress variable means entry value here */
- while ((dataAddress) && (!(dataAddress & EHCI_HOST_T_INVALID_VALUE)))
- {
- entryPointer = (volatile uint32_t *)dataAddress;
- dataAddress = *entryPointer;
- }
- *entryPointer = (uint32_t)qtdPointer;
- USB_HostEhciUnlock();
- USB_HostEhciStartAsync(ehciInstance);
- return kStatus_USB_Success;
- }
- static void USB_HostEhciTestSingleStepGetDeviceDescData(usb_host_ehci_instance_t *ehciInstance,
- usb_device_handle deviceHandle)
- {
- static uint8_t buffer[USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH];
- usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
- usb_host_transfer_t *transfer;
- uint8_t timeCount;
- USB_HostEhciStopPeriodic(ehciInstance);
- if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success)
- {
- return;
- }
- transfer->callbackFn = USB_HostEhciTestCallback;
- transfer->callbackParam = ehciInstance->hostHandle;
- transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_DIR_IN;
- transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
- transfer->setupPacket->wLength = USB_SHORT_TO_LITTLE_ENDIAN(USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH);
- transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN((uint16_t)((uint16_t)USB_DESCRIPTOR_TYPE_DEVICE << 8));
- transfer->setupPacket->wIndex = 0;
- USB_HostEhciSingleStepQtdListInit(ehciInstance, (usb_host_ehci_pipe_t *)(deviceInstance->controlPipe), transfer, 1);
- timeCount = 15; /* 15s */
- while (timeCount--)
- {
- USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
- }
- if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success)
- {
- return;
- }
- transfer->callbackFn = USB_HostEhciTestCallback;
- transfer->callbackParam = ehciInstance->hostHandle;
- transfer->transferBuffer = buffer;
- transfer->transferLength = USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH;
- USB_HostEhciSingleStepQtdListInit(ehciInstance, (usb_host_ehci_pipe_t *)(deviceInstance->controlPipe), transfer, 2);
- if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success)
- {
- return;
- }
- transfer->callbackFn = USB_HostEhciTestCallback;
- transfer->callbackParam = ehciInstance->hostHandle;
- transfer->transferBuffer = NULL;
- transfer->transferLength = 0;
- USB_HostEhciSingleStepQtdListInit(ehciInstance, (usb_host_ehci_pipe_t *)(deviceInstance->controlPipe), transfer, 3);
- timeCount = 15; /* 15s */
- while (timeCount--)
- {
- USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
- }
- usb_echo("test_single_step_get_dev_desc_data finished\r\n");
- return;
- }
- static void USB_HostEhciTestModeInit(usb_device_handle deviceHandle)
- {
- uint32_t productId;
- usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
- usb_host_ehci_instance_t *ehciInstance =
- (usb_host_ehci_instance_t *)(((usb_host_instance_t *)(deviceInstance->hostHandle))->controllerHandle);
- USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDevicePID, &productId);
- usb_echo("usb host ehci test mode init product id:0x%x\r\n", productId);
- switch (productId)
- {
- case 0x0101U:
- USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_SE0_NAK);
- break;
- case 0x0102U:
- USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_J_STATE);
- break;
- case 0x0103U:
- USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_K_STATE);
- break;
- case 0x0104U:
- USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_PACKET);
- break;
- case 0x0105U:
- usb_echo("set test mode FORCE_ENALBE_HS\r\n");
- USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_HS);
- break;
- case 0x0106U:
- USB_HostEhciTestSuspendResume(ehciInstance);
- break;
- case 0x0107U:
- usb_echo("start test SINGLE_STEP_GET_DEV_DESC\r\n");
- USB_HostEhciTestSingleStepGetDeviceDesc(ehciInstance, deviceHandle);
- break;
- case 0x0108U:
- usb_echo("start test SINGLE_STEP_GET_DEV_DESC_DATA\r\n");
- USB_HostEhciTestSingleStepGetDeviceDescData(ehciInstance, deviceHandle);
- break;
- default:
- /*no action */
- break;
- }
- return;
- }
- static void USB_HostEhciSuspendBus(usb_host_ehci_instance_t *ehciInstance)
- {
- uint32_t ehciPortSC;
- USB_HostEhciLock();
- ehciPortSC = ehciInstance->ehciIpBase->PORTSC1;
- if (ehciPortSC & USBHS_PORTSC1_PE_MASK)
- {
- ehciPortSC = ehciInstance->ehciIpBase->PORTSC1;
- ehciPortSC &= (uint32_t)(~EHCI_PORTSC1_W1_BITS);
- ehciInstance->ehciIpBase->PORTSC1 = (ehciPortSC | USBHS_PORTSC1_SUSP_MASK);
- }
- USB_HostEhciUnlock();
- }
- static void USB_HostEhciResumeBus(usb_host_ehci_instance_t *ehciInstance)
- {
- uint32_t ehciPortSC;
- USB_HostEhciLock();
- /* Resume port */
- ehciPortSC = ehciInstance->ehciIpBase->PORTSC1;
- if (ehciPortSC & USBHS_PORTSC1_PE_MASK)
- {
- ehciPortSC &= (uint32_t)(~EHCI_PORTSC1_W1_BITS);
- ehciInstance->ehciIpBase->PORTSC1 = (ehciPortSC | USBHS_PORTSC1_FPR_MASK);
- }
- USB_HostEhciUnlock();
- }
- #endif
- static uint32_t USB_HostBandwidthComputeTime(uint8_t speed, uint8_t pipeType, uint8_t direction, uint32_t dataLength)
- {
- uint32_t result = (3167U + ((1000U * dataLength) * 7U * 8U / 6U)) / 1000U;
- if (pipeType == USB_ENDPOINT_ISOCHRONOUS) /* iso */
- {
- if (speed == USB_SPEED_HIGH)
- {
- result = 38U * 8U * 2083U + 2083U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
- }
- else if (speed == USB_SPEED_FULL)
- {
- if (direction == USB_IN)
- {
- result = 7268000U + 83540U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
- }
- else
- {
- result = 6265000U + 83540U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
- }
- }
- else
- {
- /*no action*/
- }
- }
- else /* interrupt */
- {
- if (speed == USB_SPEED_HIGH)
- {
- result = 55U * 8U * 2083U + 2083U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
- }
- else if (speed == USB_SPEED_FULL)
- {
- result = 9107000U + 83540U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
- }
- else if (speed == USB_SPEED_LOW)
- {
- if (direction == USB_IN)
- {
- result = 64060000U + 2000U * USB_HOST_EHCI_BANDWIDTH_HUB_LS_SETUP + 676670U * result +
- USB_HOST_EHCI_BANDWIDTH_DELAY;
- }
- else
- {
- result = 6265000U + 83540U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
- }
- }
- else
- {
- /*no action*/
- }
- }
- result /= 1000000U;
- if (result == 0U)
- {
- result = 1U;
- }
- return result;
- }
- static void USB_HostBandwidthFslsHostComputeCurrent(usb_host_ehci_instance_t *ehciInstance,
- uint16_t frameIndex,
- uint16_t *frameBandwidth)
- {
- usb_host_ehci_pipe_t *ehciPipePointer;
- void *temp;
- /* clear the bandwidth */
- *frameBandwidth = 0;
- ehciPipePointer = ehciInstance->ehciRunningPipeList;
- while (ehciPipePointer != NULL)
- {
- /* only compute iso and interrupt pipe */
- if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
- (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT))
- {
- /* does pipe allocate bandwidth in frameIndex frame? note: interval is power of 2. */
- if ((frameIndex >= ehciPipePointer->startFrame) &&
- (0U == ((uint32_t)((uint32_t)frameIndex - ehciPipePointer->startFrame) &
- ((uint32_t)ehciPipePointer->pipeCommon.interval - 1U))))
- {
- *frameBandwidth += ehciPipePointer->dataTime;
- }
- }
- temp = (void *)ehciPipePointer->pipeCommon.next;
- ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
- }
- }
- static void USB_HostBandwidthHsHostComputeCurrentFsls(usb_host_ehci_instance_t *ehciInstance,
- uint32_t hubNumber,
- uint16_t frameIndex,
- uint16_t frameBandwidths[8])
- {
- usb_host_ehci_pipe_t *ehciPipePointer;
- uint8_t index;
- uint32_t deviceInfo = 0U;
- void *temp;
- for (index = 0; index < 8U; ++index)
- {
- frameBandwidths[index] = 0;
- }
- ehciPipePointer = ehciInstance->ehciRunningPipeList;
- while (ehciPipePointer != NULL)
- {
- /* only compute iso and interrupt pipe */
- if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
- (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT))
- {
- /* compute FS/LS bandwidth that blong to same high-speed hub, because FS/LS bandwidth is allocated from
- * first parent high-speed hub */
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceHSHubNumber, &deviceInfo);
- if (deviceInfo != hubNumber)
- {
- temp = (void *)ehciPipePointer->pipeCommon.next;
- ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
- continue;
- }
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceSpeed, &deviceInfo);
- if (deviceInfo == USB_SPEED_HIGH)
- {
- temp = (void *)ehciPipePointer->pipeCommon.next;
- ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
- continue;
- }
- /* does pipe allocate bandwidth in frameIndex frame? note: interval is power of 2. */
- if ((frameIndex >= ehciPipePointer->startFrame) &&
- (0U == ((uint32_t)((uint32_t)frameIndex - ehciPipePointer->startFrame) &
- ((uint32_t)ehciPipePointer->pipeCommon.interval - 1U))))
- {
- if (ehciPipePointer->pipeCommon.pipeType ==
- USB_ENDPOINT_ISOCHRONOUS) /* iso bandwidth is allocated once */
- {
- frameBandwidths[ehciPipePointer->startUframe + 1U] += ehciPipePointer->dataTime;
- }
- else /* iso bandwidth is allocated three times */
- {
- frameBandwidths[ehciPipePointer->startUframe + 1U] += ehciPipePointer->dataTime;
- frameBandwidths[ehciPipePointer->startUframe + 2U] += ehciPipePointer->dataTime;
- frameBandwidths[ehciPipePointer->startUframe + 3U] += ehciPipePointer->dataTime;
- }
- }
- }
- temp = (void *)ehciPipePointer->pipeCommon.next;
- ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
- }
- for (index = 0; index < 7U; ++index) /* */
- {
- if (frameBandwidths[index] > s_SlotMaxBandwidth[index])
- {
- frameBandwidths[index + 1U] += (frameBandwidths[index] - s_SlotMaxBandwidth[index]);
- frameBandwidths[index] = s_SlotMaxBandwidth[index];
- }
- }
- }
- static void USB_HostBandwidthHsHostComputeCurrentHsAll(usb_host_ehci_instance_t *ehciInstance,
- uint16_t frameIndex,
- uint16_t frameBandwidths[8])
- {
- usb_host_ehci_pipe_t *ehciPipePointer;
- uint16_t index;
- uint32_t deviceInfo = 0U;
- uint16_t frameInterval;
- void *temp;
- for (index = 0; index < 8U; ++index)
- {
- frameBandwidths[index] = 0;
- }
- ehciPipePointer = ehciInstance->ehciRunningPipeList;
- while (ehciPipePointer != NULL)
- {
- /* only compute iso and interrupt pipe */
- if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
- (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT))
- {
- frameInterval = ehciPipePointer->pipeCommon.interval;
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceSpeed, &deviceInfo);
- if (deviceInfo == USB_SPEED_HIGH) /* high-speed data bandwidth */
- {
- /* frameInterval means micro-frame here */
- if (frameIndex >= ehciPipePointer->startFrame)
- {
- if ((frameInterval > 8U) &&
- (frameIndex * 8U - ehciPipePointer->startFrame * 8U >= ehciPipePointer->startUframe))
- {
- if (0U == ((((uint32_t)frameIndex) * 8U - ehciPipePointer->startFrame * 8U -
- ehciPipePointer->startUframe) &
- ((uint32_t)frameInterval - 1U)))
- {
- frameBandwidths[ehciPipePointer->startUframe] += ehciPipePointer->dataTime;
- }
- }
- else
- {
- for (index = ehciPipePointer->startUframe; index < 8U; index += frameInterval)
- {
- frameBandwidths[index] += ehciPipePointer->dataTime;
- }
- }
- }
- }
- else /* full-speed split bandwidth */
- {
- if ((frameIndex >= ehciPipePointer->startFrame) &&
- (0U == ((uint32_t)((uint32_t)frameIndex - ehciPipePointer->startFrame) &
- (uint32_t)((uint32_t)frameInterval - 1U))))
- {
- for (index = 0; index < 8U; ++index)
- {
- if (0U != ((uint32_t)(ehciPipePointer->uframeSmask) &
- (uint32_t)(0x01UL << index))) /* start-split micro-frames */
- {
- frameBandwidths[index] += ehciPipePointer->startSplitTime;
- }
- if (0U != ((uint32_t)(ehciPipePointer->uframeCmask) &
- (uint32_t)(0x01UL << index))) /* complete-split micro-frames */
- {
- frameBandwidths[index] += ehciPipePointer->completeSplitTime;
- }
- }
- }
- }
- }
- temp = (void *)ehciPipePointer->pipeCommon.next;
- ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
- }
- #if 0
- for (index = 0; index < 7; ++index) /* */
- {
- if (frameBandwidths[index] > s_SlotMaxBandwidthHs[index])
- {
- frameBandwidths[index + 1] += (frameBandwidths[index] - s_SlotMaxBandwidthHs[index]);
- frameBandwidths[index] = s_SlotMaxBandwidthHs[index];
- }
- }
- #endif
- }
- /*!
- * @brief allocate HS bandwidth when host work as high-speed host.
- *
- * @param ehciInstance ehci instance pointer.
- * @param uframeInterval micro-frame interval.
- * @param timeData time for allocating.
- * @param uframeIndexOut return start uframe index.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostBandwidthHsHostAllocateHsCommon(usb_host_ehci_instance_t *ehciInstance,
- uint16_t uframeInterval,
- uint16_t timeData,
- uint16_t *uframeIndexOut)
- {
- uint16_t uframeIntervalIndex;
- uint16_t uframeIndex;
- uint16_t frameIndex;
- uint16_t frameTimes[8];
- frameIndex = 0;
- for (uint8_t i = 0; i < 8U; ++i)
- {
- frameTimes[i] = 0U;
- }
- USB_HostBandwidthHsHostComputeCurrentHsAll(
- ehciInstance, frameIndex, frameTimes); /* compute the allocated bandwidths in the frameIndex frame */
- for (uframeIntervalIndex = 0; (uframeIntervalIndex < uframeInterval); ++uframeIntervalIndex) /* start micro-frame */
- {
- /* for all the micro-frame in interval uframeInterval */
- for (uframeIndex = uframeIntervalIndex; uframeIndex < (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 8U);
- uframeIndex += uframeInterval)
- {
- if (frameIndex != (uframeIndex >> 3))
- {
- frameIndex = (uframeIndex >> 3);
- USB_HostBandwidthHsHostComputeCurrentHsAll(
- ehciInstance, frameIndex,
- frameTimes); /* compute the allocated bandwidths in the new frameIndex frame */
- }
- if (frameTimes[uframeIndex & 0x0007U] + timeData >
- s_SlotMaxBandwidthHs[(uframeIndex & 0x0007U)]) /* micro-frame has enough idle bandwidth? */
- {
- break; /* fail */
- }
- }
- if (uframeIndex >= (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 8U)) /* success? */
- {
- break;
- }
- }
- if (uframeIntervalIndex < uframeInterval)
- {
- *uframeIndexOut = (uframeIntervalIndex);
- return kStatus_USB_Success;
- }
- else
- {
- return kStatus_USB_Error;
- }
- }
- #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
- ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
- static usb_status_t USB_HostBandwidthHsHostAllocateIso(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer)
- {
- usb_status_t status;
- uint32_t deviceInfo = 0;
- uint32_t hubNumber = 0;
- uint16_t uframeIntervalIndex = 0;
- uint16_t frameIntervalIndex = 0;
- uint16_t frameIndex;
- uint16_t timeCompleteSplit;
- uint16_t timeStartSplit;
- uint32_t timeData;
- uint8_t SsCsNumber = 0;
- uint16_t frameInterval;
- uint16_t frameTimes[8];
- uint8_t allocateOk = 1;
- uint16_t index;
- for (uint8_t i = 0; i < 8U; ++i)
- {
- frameTimes[i] = 0U;
- }
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceSpeed, &deviceInfo);
- timeData = USB_HostBandwidthComputeTime(
- (uint8_t)deviceInfo, USB_ENDPOINT_ISOCHRONOUS, ehciPipePointer->pipeCommon.direction,
- (((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize) * ehciPipePointer->pipeCommon.numberPerUframe));
- /* pipe is high-speed */
- if (deviceInfo == USB_SPEED_HIGH)
- {
- uframeIntervalIndex = 0;
- status = USB_HostBandwidthHsHostAllocateHsCommon(ehciInstance, ehciPipePointer->uframeInterval,
- (uint16_t)timeData, &uframeIntervalIndex);
- if (status == kStatus_USB_Success)
- {
- ehciPipePointer->startFrame = (uframeIntervalIndex / 8U);
- ehciPipePointer->startUframe = (uint8_t)(uframeIntervalIndex & 0x0007U);
- ehciPipePointer->dataTime = (uint16_t)timeData;
- return kStatus_USB_Success;
- }
- }
- else /* pipe is full-speed or low-speed */
- {
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetHubThinkTime,
- &deviceInfo); /* deviceInfo variable means hub think time */
- timeData += (deviceInfo * 7U / (6U * 12U));
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceHSHubNumber, &hubNumber);
- frameInterval = ehciPipePointer->pipeCommon.interval;
- /* compute start-split and complete-split bandwidth */
- if (ehciPipePointer->pipeCommon.direction == USB_OUT)
- {
- timeStartSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_ISOCHRONOUS, USB_OUT,
- ehciPipePointer->pipeCommon.maxPacketSize);
- timeCompleteSplit = 0;
- }
- else
- {
- timeStartSplit =
- (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_ISOCHRONOUS, USB_IN, 1);
- timeCompleteSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_ISOCHRONOUS, USB_IN,
- ehciPipePointer->pipeCommon.maxPacketSize);
- }
- /* note: bandwidth must put in one frame */
- for (uframeIntervalIndex = 0U; uframeIntervalIndex <= 5U; ++uframeIntervalIndex) /* uframe interval */
- {
- for (frameIntervalIndex = 0U; frameIntervalIndex < frameInterval; ++frameIntervalIndex) /* frame interval */
- {
- allocateOk = 1;
- for (frameIndex = frameIntervalIndex; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
- frameIndex += frameInterval) /* check all the frames */
- {
- /* compute start-split and complete-split number */
- SsCsNumber = (uint8_t)((ehciPipePointer->pipeCommon.maxPacketSize + 187U) /
- 188U); /* ss number for iso out; cs number for iso in */
- if (ehciPipePointer->pipeCommon.direction == USB_OUT) /* ISO OUT */
- {
- if (uframeIntervalIndex + SsCsNumber > 8U)
- {
- allocateOk = 0U;
- }
- }
- else
- {
- if (uframeIntervalIndex + 2U + SsCsNumber >
- 8U) /* ISO IN: there are two micro-frame interval between start-split and complete-split */
- {
- allocateOk = 0U;
- }
- }
- if (0U != allocateOk)
- {
- /* allocate start-split and complete-split bandwidth */
- USB_HostBandwidthHsHostComputeCurrentHsAll(ehciInstance, frameIndex, frameTimes);
- if (ehciPipePointer->pipeCommon.direction == USB_OUT) /* ISO OUT */
- {
- index = uframeIntervalIndex;
- for (; index < (uframeIntervalIndex + SsCsNumber); ++index)
- {
- if (frameTimes[index] + timeStartSplit > s_SlotMaxBandwidthHs[index])
- {
- allocateOk = 0U;
- break;
- }
- }
- }
- else /* ISO IN */
- {
- index = uframeIntervalIndex;
- if (frameTimes[index] + timeStartSplit > s_SlotMaxBandwidthHs[index])
- {
- allocateOk = 0U;
- }
- if (0U != allocateOk)
- {
- index =
- uframeIntervalIndex +
- 2U; /* there are two micro-frames interval between start-split and complete-split */
- for (; index < (uframeIntervalIndex + 2U + SsCsNumber); ++index)
- {
- if (frameTimes[index] + timeCompleteSplit > s_SlotMaxBandwidthHs[index])
- {
- allocateOk = 0U;
- break;
- }
- }
- }
- }
- }
- /* allocate data bandwidth */
- if (0U != allocateOk)
- {
- USB_HostBandwidthHsHostComputeCurrentFsls(ehciInstance, hubNumber, frameIndex, frameTimes);
- index = uframeIntervalIndex + 1U; /* timeData bandwidth start position */
- /* iso must occupy all the uframe bandwidth */
- {
- deviceInfo = timeData; /* note: deviceInfo variable means bandwidth here */
- while ((index < 8U) && (deviceInfo > s_SlotMaxBandwidth[index]))
- {
- if (frameTimes[index] > 0U)
- {
- allocateOk = 0U;
- break;
- }
- else
- {
- deviceInfo -= s_SlotMaxBandwidth[index];
- }
- ++index;
- }
- }
- }
- if (0U != allocateOk)
- {
- /* data bandwidth can be put in the frame? */
- index = uframeIntervalIndex + 1U; /* timeData bandwidth start position */
- frameTimes[index] += (uint16_t)timeData;
- for (; index < 7U; ++index)
- {
- if (frameTimes[index] > s_SlotMaxBandwidth[index])
- {
- frameTimes[index + 1U] += (frameTimes[index] - s_SlotMaxBandwidth[index]);
- frameTimes[index] = s_SlotMaxBandwidth[index];
- }
- else
- {
- break;
- }
- }
- if (frameTimes[index] > s_SlotMaxBandwidth[index])
- {
- allocateOk = 0;
- }
- }
- if (0U != allocateOk)
- {
- break;
- }
- }
- if (0U != allocateOk)
- {
- break;
- }
- }
- if (0U != allocateOk)
- {
- break;
- }
- }
- if (0U != allocateOk)
- {
- ehciPipePointer->startFrame = frameIntervalIndex;
- ehciPipePointer->startUframe = (uint8_t)uframeIntervalIndex;
- ehciPipePointer->dataTime = (uint16_t)timeData;
- ehciPipePointer->startSplitTime = timeStartSplit;
- ehciPipePointer->completeSplitTime = timeCompleteSplit;
- if (ehciPipePointer->pipeCommon.direction == USB_OUT)
- {
- index = uframeIntervalIndex;
- for (; index < (uframeIntervalIndex + SsCsNumber); ++index)
- {
- ehciPipePointer->uframeSmask = ehciPipePointer->uframeSmask | (uint8_t)(0x01UL << index);
- }
- }
- else
- {
- index = uframeIntervalIndex;
- ehciPipePointer->uframeSmask = ehciPipePointer->uframeSmask | (uint8_t)(0x01UL << index);
- index = uframeIntervalIndex + 2U;
- for (; index < (uframeIntervalIndex + 2U + SsCsNumber); ++index)
- {
- ehciPipePointer->uframeCmask = ehciPipePointer->uframeCmask | (uint8_t)(0x01UL << index);
- }
- }
- return kStatus_USB_Success;
- }
- }
- return kStatus_USB_Error;
- }
- #endif
- static usb_status_t USB_HostBandwidthHsHostAllocateInterrupt(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer)
- {
- usb_status_t status;
- uint32_t deviceInfo = 0;
- uint32_t hubNumber = 0;
- uint16_t uframeIntervalIndex = 0;
- uint16_t frameIntervalIndex = 0;
- uint16_t frameIndex;
- uint16_t timeCompleteSplit;
- uint16_t timeStartSplit;
- uint32_t timeData;
- uint8_t SsCsNumber;
- uint16_t frameInterval;
- uint16_t frameTimes[8];
- uint8_t allocateOk = 1;
- uint8_t index;
- for (uint8_t i = 0; i < 8U; ++i)
- {
- frameTimes[i] = 0U;
- }
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceSpeed, &deviceInfo);
- timeData = USB_HostBandwidthComputeTime(
- (uint8_t)deviceInfo, USB_ENDPOINT_INTERRUPT, ehciPipePointer->pipeCommon.direction,
- (uint32_t)ehciPipePointer->pipeCommon.maxPacketSize * ehciPipePointer->pipeCommon.numberPerUframe);
- /* pipe is high-speed */
- if (deviceInfo == USB_SPEED_HIGH)
- {
- uframeIntervalIndex = 0;
- status = USB_HostBandwidthHsHostAllocateHsCommon(ehciInstance, ehciPipePointer->uframeInterval,
- (uint16_t)timeData, &uframeIntervalIndex);
- if (status == kStatus_USB_Success)
- {
- ehciPipePointer->startFrame = (uframeIntervalIndex / 8U);
- ehciPipePointer->startUframe = (uint8_t)(uframeIntervalIndex & 0x0007U);
- /* for HS interrupt start transaction position */
- if (ehciPipePointer->uframeInterval >= 8U)
- {
- ehciPipePointer->uframeSmask = (0x01U << ehciPipePointer->startUframe);
- }
- else
- {
- ehciPipePointer->uframeSmask = 0x00U;
- for (index = ehciPipePointer->startUframe; index < 8U;
- index += (uint8_t)ehciPipePointer->uframeInterval)
- {
- ehciPipePointer->uframeSmask |= (0x01U << index);
- }
- }
- ehciPipePointer->dataTime = (uint16_t)timeData;
- return kStatus_USB_Success;
- }
- }
- else /* pipe is full-speed or low-speed */
- {
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetHubThinkTime, &deviceInfo);
- timeData += (deviceInfo * 7U / (6U * 12U));
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceHSHubNumber, &hubNumber);
- frameInterval = ehciPipePointer->pipeCommon.interval;
- SsCsNumber = 3U; /* complete split number */
- /* compute start-split and complete-split bandwidth */
- if (ehciPipePointer->pipeCommon.direction == USB_OUT)
- {
- timeStartSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_OUT,
- ehciPipePointer->pipeCommon.maxPacketSize);
- timeStartSplit +=
- (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_OUT, 1U);
- timeCompleteSplit =
- (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_OUT, 0U);
- }
- else
- {
- timeStartSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_IN, 1U);
- timeCompleteSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_IN,
- ehciPipePointer->pipeCommon.maxPacketSize);
- timeCompleteSplit +=
- (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_IN, 0U);
- }
- /* note: bandwidth must put in one frame */
- for (uframeIntervalIndex = 0U; uframeIntervalIndex <= 4U; ++uframeIntervalIndex) /* uframe interval */
- {
- for (frameIntervalIndex = 0U; frameIntervalIndex < frameInterval; ++frameIntervalIndex) /* frame interval */
- {
- allocateOk = 1U;
- for (frameIndex = frameIntervalIndex; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
- frameIndex += frameInterval) /* check all the frames */
- {
- /* allocate data bandwidth */
- USB_HostBandwidthHsHostComputeCurrentFsls(ehciInstance, hubNumber, frameIndex, frameTimes);
- index = (uint8_t)(uframeIntervalIndex + 1U);
- for (; index <= (uframeIntervalIndex + 3U); ++index) /* data bandwidth number is 3.
- uframeIntervalIndex don't exceed 4, so
- index cannot exceed 7 */
- {
- if (frameTimes[index] + timeData > s_SlotMaxBandwidth[index])
- {
- allocateOk = 0;
- break;
- }
- }
- if (0U != allocateOk)
- {
- USB_HostBandwidthHsHostComputeCurrentHsAll(ehciInstance, frameIndex, frameTimes);
- /* allocate start_split bandwidth */
- if (frameTimes[uframeIntervalIndex] + timeStartSplit >
- s_SlotMaxBandwidthHs[uframeIntervalIndex])
- {
- allocateOk = 0U;
- }
- if (0U != allocateOk)
- {
- /* allocate complete_split bandwidth */
- index = (uint8_t)uframeIntervalIndex + 2U;
- /* complete-split number is normal 3. When uframeIntervalIndex is 4, complete-split number
- * is 2. */
- for (; (index <= (uframeIntervalIndex + 1U + SsCsNumber)) && (index < 8U); ++index)
- {
- if (frameTimes[index] + timeCompleteSplit > s_SlotMaxBandwidthHs[index])
- {
- allocateOk = 0U;
- break;
- }
- }
- }
- }
- if (0U == allocateOk)
- {
- break; /* allocate fail */
- }
- }
- if (0U != allocateOk)
- {
- break;
- }
- }
- if (0U != allocateOk)
- {
- break;
- }
- }
- if (0U != allocateOk)
- {
- ehciPipePointer->startFrame = frameIntervalIndex;
- ehciPipePointer->startUframe = (uint8_t)uframeIntervalIndex;
- ehciPipePointer->uframeSmask = (0x01u << ehciPipePointer->startUframe);
- ehciPipePointer->uframeCmask = 0u;
- index = (uint8_t)uframeIntervalIndex + 2u;
- for (; (index <= (uframeIntervalIndex + 1u + SsCsNumber)) && (index < 8u); ++index)
- {
- ehciPipePointer->uframeCmask = ehciPipePointer->uframeCmask | (0x01U << index);
- }
- ehciPipePointer->dataTime = (uint16_t)timeData;
- ehciPipePointer->startSplitTime = timeStartSplit;
- ehciPipePointer->completeSplitTime = timeCompleteSplit;
- return kStatus_USB_Success;
- }
- }
- return kStatus_USB_BandwidthFail;
- }
- static usb_status_t USB_HostBandwidthFslsHostAllocate(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer)
- {
- uint32_t FslsTime = 0;
- uint32_t speed = 0;
- uint16_t uframeIntervalIndex;
- uint16_t frameIndex;
- uint16_t frameInterval;
- uint16_t frameTime;
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetHubThinkTime, &FslsTime);
- FslsTime += (FslsTime * 7U / (6U * 12U));
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
- FslsTime = FslsTime + USB_HostBandwidthComputeTime((uint8_t)speed, ehciPipePointer->pipeCommon.pipeType,
- ehciPipePointer->pipeCommon.direction,
- ehciPipePointer->pipeCommon.maxPacketSize);
- frameInterval = ehciPipePointer->pipeCommon.interval;
- for (uframeIntervalIndex = 0; uframeIntervalIndex < ehciPipePointer->uframeInterval;
- ++uframeIntervalIndex) /* uframeIntervalIndex can exceed 8 */
- {
- for (frameIndex = (uframeIntervalIndex >> 3); frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
- frameIndex += frameInterval)
- {
- USB_HostBandwidthFslsHostComputeCurrent(ehciInstance, frameIndex, &frameTime);
- if (frameTime + FslsTime > USB_HOST_EHCI_BANDWIDTH_FRAME_TOTOAL_TIME)
- {
- break;
- }
- }
- if (frameIndex >= USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE)
- {
- break;
- }
- }
- if (uframeIntervalIndex < ehciPipePointer->uframeInterval)
- {
- ehciPipePointer->startFrame = (uframeIntervalIndex >> 3);
- ehciPipePointer->startUframe = (uint8_t)(uframeIntervalIndex & 0x0007U);
- ehciPipePointer->uframeSmask = 0; /* useless */
- ehciPipePointer->uframeCmask = 0;
- ehciPipePointer->dataTime = (uint16_t)FslsTime;
- return kStatus_USB_Success;
- }
- return kStatus_USB_BandwidthFail;
- }
- static uint8_t USB_HostEhciGet2PowerValue(uint8_t value)
- {
- if ((value == 0U) || (value == 1U))
- {
- return value;
- }
- if (0U != (value & 0xf0U))
- {
- if (0U != (value & 0x80U))
- {
- return 128U;
- }
- else if (0U != (value & 0x40U))
- {
- return 64U;
- }
- else if (0U != (value & 0x20U))
- {
- return 32U;
- }
- else
- {
- return 16U;
- }
- }
- else
- {
- if (0U != (value & 0x08U))
- {
- return 8U;
- }
- else if (0U != (value & 0x04U))
- {
- return 4U;
- }
- else if (0U != (value & 0x02U))
- {
- return 2U;
- }
- else
- {
- return 1U;
- }
- }
- }
- static void USB_HostEhciZeroMem(uint32_t *buffer, uint32_t length)
- {
- /* note: the zero unit is uint32_t */
- while (0U != length)
- {
- length--;
- *buffer = 0;
- buffer++;
- }
- }
- static void USB_HostEhciDelay(USBHS_Type *ehciIpBase, uint32_t ms)
- {
- /* note: the max delay time cannot exceed half of max value (0x4000) */
- uint32_t sofStart;
- uint32_t SofEnd;
- uint32_t distance;
- sofStart = (ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE);
- do
- {
- SofEnd = (ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE);
- distance = (SofEnd + EHCI_MAX_UFRAME_VALUE + 1U - sofStart);
- } while ((distance & EHCI_MAX_UFRAME_VALUE) < (ms * 8U)); /* compute the distance between sofStart and SofEnd */
- }
- static void USB_HostEhciStartAsync(usb_host_ehci_instance_t *ehciInstance)
- {
- uint32_t stateSync;
- if (0U == (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK))
- {
- /* the status must be same when change USBCMD->ASE */
- do
- {
- stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK) |
- (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_ASE_MASK));
- } while ((stateSync == USBHS_USBSTS_AS_MASK) || (stateSync == USBHS_USBCMD_ASE_MASK));
- ehciInstance->ehciIpBase->ASYNCLISTADDR = (uint32_t)(ehciInstance->shedFirstQh);
- ehciInstance->ehciIpBase->USBCMD |= USBHS_USBCMD_ASE_MASK;
- while (0U == (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK))
- {
- }
- }
- }
- static void USB_HostEhciStopAsync(usb_host_ehci_instance_t *ehciInstance)
- {
- uint32_t stateSync;
- /* the status must be same when change USBCMD->ASE */
- do
- {
- stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK) |
- (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_ASE_MASK));
- } while ((stateSync == USBHS_USBSTS_AS_MASK) || (stateSync == USBHS_USBCMD_ASE_MASK));
- ehciInstance->ehciIpBase->USBCMD &= (uint32_t)(~(uint32_t)USBHS_USBCMD_ASE_MASK); /* disable async schedule */
- while (0U != (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK))
- {
- }
- }
- static void USB_HostEhciStartPeriodic(usb_host_ehci_instance_t *ehciInstance)
- {
- uint32_t stateSync;
- if (0U == (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK))
- {
- /* the status must be same when change USBCMD->PSE */
- do
- {
- stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK) |
- (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_PSE_MASK));
- } while ((stateSync == USBHS_USBSTS_PS_MASK) || (stateSync == USBHS_USBCMD_PSE_MASK));
- ehciInstance->ehciIpBase->PERIODICLISTBASE = (uint32_t)(ehciInstance->ehciFrameList);
- if (0U == (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_PSE_MASK))
- {
- ehciInstance->ehciIpBase->USBCMD |= USBHS_USBCMD_PSE_MASK; /* start periodic schedule */
- }
- while (0U == (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK))
- {
- }
- }
- return;
- }
- static void USB_HostEhciStopPeriodic(usb_host_ehci_instance_t *ehciInstance)
- {
- uint32_t stateSync;
- /* the status must be same when change USBCMD->PSE */
- do
- {
- stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK) |
- (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_PSE_MASK));
- } while ((stateSync == USBHS_USBSTS_PS_MASK) || (stateSync == USBHS_USBCMD_PSE_MASK));
- ehciInstance->ehciIpBase->USBCMD &= (~USBHS_USBCMD_PSE_MASK); /* stop periodic schedule */
- while (0U != (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK))
- {
- }
- }
- static usb_status_t USB_HostEhciQhQtdListInit(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer,
- usb_host_transfer_t *transfer)
- {
- volatile usb_host_ehci_qh_t *vltQhPointer;
- usb_host_ehci_qtd_t *qtdPointer = NULL;
- usb_host_ehci_qtd_t *BaseQtdPointer = NULL;
- volatile uint32_t *entryPointer;
- uint32_t qtdNumber;
- uint32_t dataLength;
- uint32_t dataAddress;
- uint32_t endAddress;
- uint8_t index;
- /* compute the qtd number */
- if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL)
- {
- /* assume setup data don't exceed one qtd data size, one qtd can transfer least 16k data */
- if (transfer->transferLength == 0U)
- {
- qtdNumber = 2U;
- }
- else
- {
- qtdNumber = 3U;
- }
- }
- else
- {
- qtdNumber = (((transfer->transferLength) & 0xFFFFC000U) >> 14U) +
- (0U != ((transfer->transferLength) & 0x00003FFFU) ? 1U : 0U);
- if (0U == qtdNumber)
- {
- qtdNumber = 1U;
- }
- }
- vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
- /* get qtd list */
- USB_HostEhciLock();
- if (qtdNumber <= ehciInstance->ehciQtdNumber)
- {
- ehciInstance->ehciQtdNumber -= (uint8_t)qtdNumber;
- BaseQtdPointer = ehciInstance->ehciQtdHead;
- qtdPointer = NULL;
- do
- {
- if (qtdPointer != NULL)
- {
- qtdPointer->nextQtdPointer = (uint32_t)ehciInstance->ehciQtdHead;
- }
- qtdPointer = ehciInstance->ehciQtdHead;
- ehciInstance->ehciQtdHead = (usb_host_ehci_qtd_t *)qtdPointer->nextQtdPointer;
- qtdPointer->nextQtdPointer = 0;
- --qtdNumber;
- } while (0U != qtdNumber);
- if (ehciInstance->ehciQtdNumber == 0U)
- {
- ehciInstance->ehciQtdTail = NULL;
- }
- }
- else
- {
- USB_HostEhciUnlock();
- return kStatus_USB_Error;
- }
- USB_HostEhciUnlock();
- /* int qTD list */
- if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL)
- {
- /* setup transaction qtd */
- qtdPointer = BaseQtdPointer;
- qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
- /* dt: need set; ioc: 0; C_Page: 0; PID Code: SETUP; Status: Active */
- qtdPointer->transferResults[1] = 0U;
- qtdPointer->transferResults[0] =
- ((0x00000000UL << EHCI_HOST_QTD_DT_SHIFT) | (8UL << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
- (EHCI_HOST_PID_SETUP << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
- dataAddress = ((uint32_t)transfer->setupPacket);
- qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
- /* set buffer pointer no matter data length */
- for (index = 0; index < 4U; ++index)
- {
- qtdPointer->bufferPointers[index] = ((dataAddress + ((uint32_t)index + 1U) * 4U * 1024U) & 0xFFFFF000U);
- }
- /* data transaction qtd */
- dataLength = transfer->transferLength;
- if (dataLength != 0U)
- {
- qtdPointer = (usb_host_ehci_qtd_t *)(qtdPointer->nextQtdPointer);
- qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
- /* dt: need set; ioc: 0; C_Page: 0; PID Code: IN/OUT; Status: Active */
- qtdPointer->transferResults[1] = 0U;
- if (transfer->direction == USB_OUT)
- {
- qtdPointer->transferResults[0] =
- ((0x00000001UL << EHCI_HOST_QTD_DT_SHIFT) | (dataLength << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
- (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
- }
- else
- {
- qtdPointer->transferResults[0] =
- ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (dataLength << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
- (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
- }
- dataAddress = (uint32_t)transfer->transferBuffer;
- qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
- /* set buffer pointer no matter data length */
- for (index = 0; index < 4U; ++index)
- {
- qtdPointer->bufferPointers[index] = ((dataAddress + ((uint32_t)index + 1U) * 4U * 1024U) & 0xFFFFF000U);
- }
- }
- /* status transaction qtd */
- qtdPointer = (usb_host_ehci_qtd_t *)(qtdPointer->nextQtdPointer);
- qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
- /* dt: dont care; ioc: 1; C_Page: 0; PID Code: IN/OUT; Status: Active */
- qtdPointer->transferResults[1] = 0;
- if ((dataLength == 0U) || (transfer->direction == USB_OUT))
- {
- qtdPointer->transferResults[0] =
- ((0x00000001UL << EHCI_HOST_QTD_DT_SHIFT) | (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) |
- (EHCI_HOST_QTD_IOC_MASK) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
- }
- else
- {
- qtdPointer->transferResults[0] =
- ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) |
- (EHCI_HOST_QTD_IOC_MASK) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
- }
- qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE;
- }
- else
- {
- dataAddress = (uint32_t)transfer->transferBuffer;
- qtdPointer = BaseQtdPointer;
- while (1U == 1U)
- {
- endAddress = dataAddress + (16U * 1024U);
- if (endAddress > (uint32_t)(transfer->transferBuffer + transfer->transferLength))
- {
- endAddress = (uint32_t)(transfer->transferBuffer + transfer->transferLength);
- }
- qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
- /* dt: set; ioc: 0; C_Page: 0; PID Code: IN/OUT; Status: Active */
- qtdPointer->transferResults[1] = 0U;
- if (transfer->direction == USB_OUT)
- {
- qtdPointer->transferResults[0] =
- (((endAddress - dataAddress) << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
- ((uint32_t)ehciPipePointer->pipeCommon.nextdata01 << EHCI_HOST_QTD_DT_SHIFT) |
- (EHCI_HOST_QTD_CERR_MAX_VALUE << EHCI_HOST_QTD_CERR_SHIFT) |
- (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
- }
- else
- {
- qtdPointer->transferResults[0] =
- (((endAddress - dataAddress) << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
- ((uint32_t)ehciPipePointer->pipeCommon.nextdata01 << EHCI_HOST_QTD_DT_SHIFT) |
- (EHCI_HOST_QTD_CERR_MAX_VALUE << EHCI_HOST_QTD_CERR_SHIFT) |
- (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
- }
- qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
- /* set buffer pointer no matter data length */
- for (index = 0; index < 4U; ++index)
- {
- qtdPointer->bufferPointers[index] = ((dataAddress + ((uint32_t)index + 1U) * 4U * 1024U) & 0xFFFFF000U);
- }
- dataAddress = endAddress; /* for next qtd */
- if (qtdPointer->nextQtdPointer == 0U)
- {
- break;
- }
- qtdPointer = (usb_host_ehci_qtd_t *)(qtdPointer->nextQtdPointer);
- }
- qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE;
- qtdPointer->transferResults[0] |= EHCI_HOST_QTD_IOC_MASK; /* last one set IOC */
- }
- /* save qtd to transfer */
- transfer->union1.unitHead = (uint32_t)BaseQtdPointer;
- transfer->union2.unitTail = (uint32_t)qtdPointer;
- /* link transfer to qh */
- transfer->next = NULL;
- if (vltQhPointer->ehciTransferHead == NULL)
- {
- transfer->next = NULL;
- vltQhPointer->ehciTransferTail = transfer;
- vltQhPointer->ehciTransferHead = transfer;
- }
- else
- {
- transfer->next = NULL;
- vltQhPointer->ehciTransferTail->next = transfer;
- vltQhPointer->ehciTransferTail = transfer;
- }
- USB_HostEhciLock();
- /* link qtd to qh (link to end) */
- entryPointer = &(vltQhPointer->nextQtdPointer);
- dataAddress = *entryPointer; /* dataAddress variable means entry value here */
- while ((0U != dataAddress) && (0U == (dataAddress & EHCI_HOST_T_INVALID_VALUE)))
- {
- entryPointer = (volatile uint32_t *)dataAddress;
- dataAddress = *entryPointer;
- }
- *entryPointer = (uint32_t)BaseQtdPointer;
- USB_HostEhciUnlock();
- USB_HostEhciStartAsync(ehciInstance);
- return kStatus_USB_Success;
- }
- static uint32_t USB_HostEhciQtdListRelease(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_qtd_t *ehciQtdStart,
- usb_host_ehci_qtd_t *ehciQtdEnd)
- {
- uint32_t length = 0;
- usb_host_ehci_qtd_t *qtdPointer;
- ehciQtdEnd->nextQtdPointer = 0U;
- /* compute remaining length */
- qtdPointer = ehciQtdStart;
- while (qtdPointer != ehciQtdEnd)
- {
- length +=
- ((qtdPointer->transferResults[0] & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >> EHCI_HOST_QTD_TOTAL_BYTES_SHIFT);
- qtdPointer = (usb_host_ehci_qtd_t *)qtdPointer->nextQtdPointer;
- }
- qtdPointer = ehciQtdEnd;
- length += ((qtdPointer->transferResults[0] & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >> EHCI_HOST_QTD_TOTAL_BYTES_SHIFT);
- /* put releasing qtd to idle qtd list */
- USB_HostEhciLock();
- if (ehciInstance->ehciQtdNumber == 0U)
- {
- ehciInstance->ehciQtdHead = ehciQtdStart;
- ehciInstance->ehciQtdTail = ehciQtdEnd;
- }
- else
- {
- ehciInstance->ehciQtdTail->nextQtdPointer = (uint32_t)ehciQtdStart;
- ehciInstance->ehciQtdTail = ehciQtdEnd;
- }
- while (ehciQtdStart != ehciQtdEnd)
- {
- ehciInstance->ehciQtdNumber++;
- ehciQtdStart = (usb_host_ehci_qtd_t *)ehciQtdStart->nextQtdPointer;
- }
- ehciInstance->ehciQtdNumber++;
- USB_HostEhciUnlock();
- return length;
- }
- static usb_status_t USB_HostEhciQhQtdListDeinit(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer)
- {
- volatile usb_host_ehci_qh_t *vltQhPointer;
- usb_host_transfer_t *transfer;
- usb_host_transfer_t *nextTransfer;
- uint32_t currentQtdPointer;
- uint8_t needStop = 0U;
- vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
- USB_HostEhciLock(); /* this API is called from APP, the host task may occupy to access the same resource */
- /* remove qtd from qh */
- /*for misra 13.5*/
- currentQtdPointer = vltQhPointer->currentQtdPointer;
- if ((0U == ((uint32_t)vltQhPointer->nextQtdPointer & EHCI_HOST_T_INVALID_VALUE)) ||
- (0U == ((uint32_t)currentQtdPointer & EHCI_HOST_T_INVALID_VALUE)))
- {
- /* need stop async schedule */
- if ((0U == (vltQhPointer->horizontalLinkPointer & EHCI_HOST_T_INVALID_VALUE)) &&
- (ehciPipePointer->pipeCommon.pipeType != USB_ENDPOINT_INTERRUPT))
- {
- needStop = 1U;
- }
- if (0U != needStop)
- {
- USB_HostEhciStopAsync(ehciInstance);
- }
- vltQhPointer->currentQtdPointer = EHCI_HOST_T_INVALID_VALUE; /* invalid current qtd */
- vltQhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE; /* invalid next qtd */
- vltQhPointer->transferOverlayResults[0] &= (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
- if (0U != needStop)
- {
- USB_HostEhciStartAsync(ehciInstance);
- }
- }
- /* remove transfer from the QH transfer list */
- transfer = vltQhPointer->ehciTransferHead;
- vltQhPointer->ehciTransferTail = NULL;
- vltQhPointer->ehciTransferHead = NULL;
- USB_HostEhciUnlock();
- /* release qtd and transfer callback*/
- while (transfer != NULL)
- {
- nextTransfer = transfer->next; /* the transfer is released when call back */
- transfer->transferSofar =
- USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
- (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
- transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
- 0U :
- (transfer->transferLength - transfer->transferSofar);
- /* callback function is different from the current condition */
- transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferCancel);
- transfer = nextTransfer;
- }
- return kStatus_USB_Success;
- }
- static usb_status_t USB_HostEhciTransferQtdListDeinit(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer,
- usb_host_transfer_t *transfer)
- {
- volatile usb_host_ehci_qh_t *vltQhPointer;
- usb_host_transfer_t *preSearchTransfer;
- uint32_t qhNextQtdValue;
- uint32_t qtdPointerEntry;
- uint32_t *searchQtdEntryPointer;
- vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
- USB_HostEhciLock(); /* this API is called from APP, the host task may occupy to access the same resource */
- /* remove qtd from qh */
- qhNextQtdValue = (uint32_t)vltQhPointer->currentQtdPointer;
- qtdPointerEntry = *((uint32_t *)qhNextQtdValue + 2); /* note: qtdPointerEntry means qtd status */
- if ((0U != (qhNextQtdValue & EHCI_HOST_T_INVALID_VALUE)) ||
- (0U == (qtdPointerEntry & EHCI_HOST_QTD_STATUS_ACTIVE_MASK)))
- {
- qhNextQtdValue = (uint32_t)vltQhPointer->nextQtdPointer;
- }
- if (0U == (qhNextQtdValue & EHCI_HOST_T_INVALID_VALUE)) /* there is pending qtd in the qh */
- {
- /* this qh don't schedule temporarily */
- if (ehciPipePointer->pipeCommon.pipeType != USB_ENDPOINT_INTERRUPT)
- {
- USB_HostEhciStopAsync(ehciInstance);
- }
- vltQhPointer->currentQtdPointer |= EHCI_HOST_T_INVALID_VALUE; /* invalid current qtd */
- vltQhPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE; /* invalid next qtd */
- if (ehciPipePointer->pipeCommon.pipeType != USB_ENDPOINT_INTERRUPT)
- {
- USB_HostEhciStartAsync(ehciInstance);
- }
- /* remove qtd from qh one by one */
- qtdPointerEntry = transfer->union1.unitHead;
- while (1U == 1U)
- {
- /* search qh's qtd list for qtdPointerEntry */
- searchQtdEntryPointer = &qhNextQtdValue;
- while (0U == ((*searchQtdEntryPointer) & EHCI_HOST_T_INVALID_VALUE))
- {
- if ((*searchQtdEntryPointer) == qtdPointerEntry)
- {
- *searchQtdEntryPointer = *((uint32_t *)qtdPointerEntry); /* remove the qtd from qh */
- break;
- }
- else
- {
- searchQtdEntryPointer = (uint32_t *)(*searchQtdEntryPointer);
- }
- }
- if (qtdPointerEntry == transfer->union2.unitTail)
- {
- break;
- }
- qtdPointerEntry = *((uint32_t *)qtdPointerEntry);
- }
- }
- /* remove transfer from the QH transfer list */
- preSearchTransfer = vltQhPointer->ehciTransferHead;
- if (preSearchTransfer == transfer)
- {
- vltQhPointer->ehciTransferHead = preSearchTransfer->next;
- }
- else
- {
- while (preSearchTransfer != NULL)
- {
- if (preSearchTransfer->next == transfer)
- {
- preSearchTransfer->next = transfer->next;
- break;
- }
- else
- {
- preSearchTransfer = preSearchTransfer->next;
- }
- }
- }
- USB_HostEhciUnlock();
- /* release qtd and callback */
- transfer->transferSofar =
- USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
- (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
- transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
- 0U :
- (transfer->transferLength - transfer->transferSofar);
- /* callback function is different from the current condition */
- transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferCancel);
- /* start this qh schedule */
- vltQhPointer->transferOverlayResults[0] &= (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
- if ((qhNextQtdValue != 0U) && (0U == (qhNextQtdValue & EHCI_HOST_T_INVALID_VALUE)))
- {
- vltQhPointer->nextQtdPointer = qhNextQtdValue;
- }
- return kStatus_USB_Success;
- }
- static usb_status_t USB_HostEhciQhInit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer)
- {
- usb_host_ehci_qh_t *qhPointer = NULL;
- uint32_t address = 0;
- uint32_t speed = 0;
- uint32_t portNumber = 0;
- uint32_t hubNumber = 0;
- ;
- uint32_t controlBits1 = 0U;
- uint32_t controlBits2 = 0U;
- /* get qh */
- USB_HostEhciLock();
- if (ehciInstance->ehciQhList != NULL)
- {
- qhPointer = (usb_host_ehci_qh_t *)ehciInstance->ehciQhList;
- ehciInstance->ehciQhList =
- (usb_host_ehci_qh_t *)(ehciInstance->ehciQhList->horizontalLinkPointer & EHCI_HOST_POINTER_ADDRESS_MASK);
- }
- USB_HostEhciUnlock();
- if (qhPointer == NULL)
- {
- #ifdef HOST_EHCO
- usb_echo("get qh error\r\n");
- #endif
- return kStatus_USB_Error;
- }
- ehciPipePointer->ehciQh = (void *)qhPointer;
- /* initialize qh */
- USB_HostEhciZeroMem((void *)qhPointer, sizeof(usb_host_ehci_qh_t) / 4U);
- qhPointer->horizontalLinkPointer = EHCI_HOST_T_INVALID_VALUE;
- qhPointer->currentQtdPointer = EHCI_HOST_T_INVALID_VALUE;
- qhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
- qhPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
- qhPointer->ehciPipePointer = ehciPipePointer;
- qhPointer->timeOutLabel = 0;
- qhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
- /* initialize staticEndpointStates[0] */
- if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT)
- {
- /* Software should set the RL field to zero if the queue head is an interrupt endpoint. */
- controlBits1 |= ((0UL << EHCI_HOST_QH_RL_SHIFT) & EHCI_HOST_QH_RL_MASK);
- }
- else
- {
- if (ehciPipePointer->pipeCommon.nakCount >= 16U)
- {
- controlBits1 |= ((15UL << EHCI_HOST_QH_RL_SHIFT) & EHCI_HOST_QH_RL_MASK);
- }
- else
- {
- controlBits1 |=
- (((uint32_t)ehciPipePointer->pipeCommon.nakCount << EHCI_HOST_QH_RL_SHIFT) & EHCI_HOST_QH_RL_MASK);
- }
- }
- if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL)
- {
- if (speed != USB_SPEED_HIGH)
- {
- controlBits1 |= (1UL << EHCI_HOST_QH_C_SHIFT);
- }
- controlBits1 |= (1UL << EHCI_HOST_QH_DTC_SHIFT);
- }
- controlBits1 |= ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT);
- controlBits1 |= (speed << EHCI_HOST_QH_EPS_SHIFT);
- controlBits1 |= ((uint32_t)ehciPipePointer->pipeCommon.endpointAddress << EHCI_HOST_QH_ENDPT_SHIFT);
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceAddress, &address);
- controlBits1 |= (address << EHCI_HOST_QH_DEVICE_ADDRESS_SHIFT);
- qhPointer->staticEndpointStates[0] = controlBits1;
- if (speed == USB_SPEED_HIGH)
- {
- controlBits2 |= ((uint32_t)ehciPipePointer->pipeCommon.numberPerUframe << EHCI_HOST_QH_MULT_SHIFT);
- }
- else
- {
- controlBits2 |= (0x00000001UL << EHCI_HOST_QH_MULT_SHIFT);
- }
- /*initialize staticEndpointStates[1] */
- if (speed != USB_SPEED_HIGH)
- {
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceHSHubNumber, &hubNumber);
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceHSHubPort, &portNumber);
- }
- else
- {
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceHubNumber, &hubNumber);
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDevicePortNumber, &portNumber);
- }
- controlBits2 |= (portNumber << EHCI_HOST_QH_PORT_NUMBER_SHIFT);
- controlBits2 |= (hubNumber << EHCI_HOST_QH_HUB_ADDR_SHIFT);
- controlBits2 |= ((uint32_t)ehciPipePointer->uframeCmask << EHCI_HOST_QH_UFRAME_CMASK_SHIFT);
- controlBits2 |= ((uint32_t)ehciPipePointer->uframeSmask << EHCI_HOST_QH_UFRAME_SMASK_SHIFT);
- qhPointer->staticEndpointStates[1] = controlBits2;
- return kStatus_USB_Success;
- }
- static usb_status_t USB_HostEhciQhDeinit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer)
- {
- usb_host_ehci_qh_t *qhPointer;
- qhPointer = (usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
- /* de-initialize qtd from qh */
- (void)USB_HostEhciQhQtdListDeinit(ehciInstance, ehciPipePointer);
- /* release QH */
- USB_HostEhciLock();
- qhPointer->horizontalLinkPointer = (uint32_t)ehciInstance->ehciQhList;
- ehciInstance->ehciQhList = qhPointer;
- USB_HostEhciUnlock();
- return kStatus_USB_Success;
- }
- static void USB_HostEhciAddQhToFrame(usb_host_ehci_instance_t *ehciInstance,
- uint32_t entryPointerValue,
- uint16_t framePos,
- uint16_t uframeInterval)
- {
- volatile uint32_t *frameEntryPointer;
- uint32_t frameEntryValue;
- void *temp;
- /* search for the inserting point by interval */
- temp = (void *)ehciInstance->ehciFrameList;
- frameEntryPointer = (volatile uint32_t *)(&((uint32_t *)temp)[framePos]);
- while (NULL != frameEntryPointer)
- {
- frameEntryValue = *frameEntryPointer;
- if (0U != (frameEntryValue & EHCI_HOST_T_INVALID_VALUE))
- {
- /* insert into the end */
- *((uint32_t *)entryPointerValue) = EHCI_HOST_T_INVALID_VALUE;
- *frameEntryPointer = (entryPointerValue | EHCI_HOST_POINTER_TYPE_QH);
- break;
- }
- if ((frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK) == entryPointerValue)
- {
- return; /* has inserted */
- }
- if (((frameEntryValue & EHCI_HOST_POINTER_TYPE_MASK) == EHCI_HOST_POINTER_TYPE_QH) &&
- (((usb_host_ehci_qh_t *)(frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK))
- ->ehciPipePointer->uframeInterval <= uframeInterval))
- {
- /* insert into this point */
- *((uint32_t *)entryPointerValue) = frameEntryValue;
- *frameEntryPointer = (entryPointerValue | EHCI_HOST_POINTER_TYPE_QH);
- return;
- }
- else
- {
- frameEntryPointer = (volatile uint32_t *)(frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK);
- }
- }
- }
- static void USB_HostEhciRemoveFromFrame(usb_host_ehci_instance_t *ehciInstance,
- uint32_t entryPointerValue,
- uint16_t framePos)
- {
- volatile uint32_t *frameEntryPointer;
- uint32_t frameEntryValue;
- void *temp;
- /* search for the qh/itd/sitd entry */
- temp = (void *)ehciInstance->ehciFrameList;
- frameEntryPointer = (volatile uint32_t *)(&((uint32_t *)temp)[framePos]);
- while (NULL != frameEntryPointer)
- {
- frameEntryValue = *frameEntryPointer;
- if (0U != (frameEntryValue & EHCI_HOST_T_INVALID_VALUE))
- {
- return;
- }
- if ((frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK) == entryPointerValue)
- {
- /* remove the entry */
- *frameEntryPointer = *((uint32_t *)entryPointerValue);
- break;
- }
- else
- {
- frameEntryPointer = (volatile uint32_t *)(frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK);
- }
- }
- }
- #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
- static void USB_HostEhciLinkSitd(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer,
- void *startEntryPointer)
- {
- usb_host_ehci_iso_t *isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
- usb_host_ehci_sitd_t *sitdPointer;
- uint32_t distance;
- uint32_t frameInterval;
- uint32_t shouldLinkFrame;
- uint32_t currentFrame;
- void *temp;
- frameInterval = ((uint32_t)ehciPipePointer->uframeInterval >> 3U);
- if (isoPointer->lastLinkFrame == 0xFFFFU) /* first link */
- {
- currentFrame = ((ehciInstance->ehciIpBase->FRINDEX & USB_HOST_EHCI_MAX_MICRFRAME_VALUE) >> 3U);
- currentFrame = ((uint32_t)(currentFrame + USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER) &
- (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3U)); /* add USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER */
- /* frame should align with interval */
- if (currentFrame <= ehciPipePointer->startFrame)
- {
- currentFrame = ehciPipePointer->startFrame;
- }
- else
- {
- currentFrame -= ehciPipePointer->startFrame;
- currentFrame = ((currentFrame + frameInterval - 1U) & (~(frameInterval - 1U)));
- currentFrame += ehciPipePointer->startFrame;
- }
- }
- else
- {
- shouldLinkFrame = isoPointer->lastLinkFrame + frameInterval; /* continuous next should link frame */
- if (shouldLinkFrame > USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3U)
- {
- shouldLinkFrame = shouldLinkFrame - ((USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3U) + 1U);
- }
- currentFrame = ((ehciInstance->ehciIpBase->FRINDEX & USB_HOST_EHCI_MAX_MICRFRAME_VALUE) >> 3U);
- distance =
- ((shouldLinkFrame + (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3U) + 1U - currentFrame) &
- (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3)); /* get the distance from shouldLinkFrame to currentFrame */
- /* shouldLinkFrame has add frameInterval, think about the align with interval, so here add (frameInterval *
- * 2) */
- if ((distance <=
- (USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER + frameInterval * USB_HOST_EHCI_ISO_MAX_CONTINUOUS_TRANSFER)) &&
- (distance > 0U))
- {
- currentFrame = shouldLinkFrame;
- }
- else /* re-link */
- {
- currentFrame =
- ((currentFrame + USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER) & (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3));
- /*if (currentFrame > (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3))
- {
- currentFrame = currentFrame - ((USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3) + 1U);
- }*/
- /* frame should align with interval */
- if (currentFrame <= ehciPipePointer->startFrame)
- {
- currentFrame = ehciPipePointer->startFrame;
- }
- else
- {
- currentFrame -= ehciPipePointer->startFrame;
- currentFrame = ((currentFrame + frameInterval - 1U) & (~(frameInterval - 1U)));
- currentFrame += ehciPipePointer->startFrame;
- }
- }
- }
- if (currentFrame >= USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE) /* frame turn around */
- {
- shouldLinkFrame =
- (currentFrame - USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE); /* shouldLinkFrame means inserted frame position */
- }
- else
- {
- shouldLinkFrame = currentFrame; /* shouldLinkFrame means inserted frame position */
- }
- sitdPointer = (usb_host_ehci_sitd_t *)startEntryPointer;
- while (NULL != sitdPointer)
- {
- sitdPointer->frameEntryIndex = (uint16_t)shouldLinkFrame;
- /* add to frame list head */
- temp = (void *)ehciInstance->ehciFrameList;
- sitdPointer->nextLinkPointer = ((uint32_t *)temp)[shouldLinkFrame];
- ((uint32_t *)temp)[shouldLinkFrame] = ((uint32_t)sitdPointer | EHCI_HOST_POINTER_TYPE_SITD);
- if (sitdPointer->nextSitdIndex == 0xFFU) /* 0xFF is invalid value */
- {
- break;
- }
- sitdPointer = &(ehciInstance->ehciSitdIndexBase[sitdPointer->nextSitdIndex]); /* next sitd */
- shouldLinkFrame += frameInterval;
- currentFrame += frameInterval;
- if (shouldLinkFrame >= USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE)
- {
- shouldLinkFrame = (shouldLinkFrame - USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE);
- }
- }
- if (currentFrame > (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3))
- {
- currentFrame = currentFrame - ((USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3) + 1U);
- }
- isoPointer->lastLinkFrame = (uint16_t)currentFrame; /* save the last link frame value */
- }
- static usb_status_t USB_HostEhciSitdArrayInit(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer,
- usb_host_transfer_t *transfer)
- {
- usb_host_ehci_iso_t *isoPointer;
- uint32_t sitdNumber = 0;
- usb_host_ehci_sitd_t *sitdPointer;
- uint32_t dataLength = 0;
- uint32_t sitdLength = 0;
- uint32_t dataBufferValue;
- uint32_t hubNumber = 0U;
- uint32_t portNumber = 0U;
- uint32_t address = 0U;
- uint32_t tmp;
- uint32_t *temp;
- uint32_t index;
- int32_t tempIndex;
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceAddress, &address);
- sitdNumber = ((transfer->transferLength - 1U + (ehciPipePointer->pipeCommon.maxPacketSize)) /
- (ehciPipePointer->pipeCommon.maxPacketSize));
- /* get sitd array */
- /* USB_HostEhciLock(); */
- if (ehciInstance->ehciSitdNumber >= sitdNumber)
- {
- sitdPointer = ehciInstance->ehciSitdList;
- transfer->union1.unitHead = (uint32_t)sitdPointer;
- for (index = 1U; index < sitdNumber; ++index)
- {
- /*misra 10.8*/
- tempIndex = (((usb_host_ehci_sitd_t *)(sitdPointer->nextLinkPointer & 0xFFFFFFFEU)) -
- ehciInstance->ehciSitdIndexBase);
- sitdPointer->nextSitdIndex = (uint8_t)tempIndex;
- sitdPointer = (usb_host_ehci_sitd_t *)(sitdPointer->nextLinkPointer & 0xFFFFFFFEU);
- }
- sitdPointer->nextSitdIndex = 0xFF;
- ehciInstance->ehciSitdList = (usb_host_ehci_sitd_t *)(sitdPointer->nextLinkPointer & 0xFFFFFFFEU);
- ehciInstance->ehciSitdNumber -= (uint8_t)sitdNumber;
- }
- else
- {
- /* USB_HostEhciUnlock(); */
- return kStatus_USB_Error;
- }
- /* USB_HostEhciUnlock(); */
- transfer->union2.unitTail = (uint32_t)sitdPointer;
- /* initialize sitd array */
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceHubNumber, &hubNumber);
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDevicePortNumber, &portNumber);
- sitdPointer = (usb_host_ehci_sitd_t *)transfer->union1.unitHead;
- dataLength = transfer->transferLength;
- while (0U != sitdNumber)
- {
- sitdNumber--;
- USB_HostEhciZeroMem((void *)sitdPointer, 7);
- sitdLength = dataLength;
- if (sitdLength > ehciPipePointer->pipeCommon.maxPacketSize)
- {
- sitdLength = ehciPipePointer->pipeCommon.maxPacketSize;
- }
- dataBufferValue = (uint32_t)(transfer->transferBuffer + (transfer->transferLength - dataLength));
- dataLength -= sitdLength; /* update left data length */
- sitdPointer->transferResults[1] = dataBufferValue;
- sitdPointer->transferResults[2] = ((dataBufferValue + 4U * 1024U) & 0xFFFFF000U);
- sitdPointer->endpointStates[0] =
- (((uint32_t)ehciPipePointer->pipeCommon.direction << EHCI_HOST_SITD_DIRECTION_SHIFT) |
- (portNumber << EHCI_HOST_SITD_PORT_NUMBER_SHIFT) | (hubNumber << EHCI_HOST_SITD_HUB_ADDR_SHIFT) |
- ((uint32_t)ehciPipePointer->pipeCommon.endpointAddress << EHCI_HOST_SITD_ENDPT_SHIFT) |
- (address << EHCI_HOST_SITD_DEVICE_ADDRESS_SHIFT));
- sitdPointer->transferResults[0] =
- ((sitdLength << EHCI_HOST_SITD_TOTAL_BYTES_SHIFT) | (EHCI_HOST_SITD_STATUS_ACTIVE_MASK));
- if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH)
- {
- sitdPointer->endpointStates[1] = (((uint32_t)ehciPipePointer->uframeCmask << EHCI_HOST_SITD_CMASK_SHIFT) |
- ((uint32_t)ehciPipePointer->uframeSmask << EHCI_HOST_SITD_SMASK_SHIFT));
- tmp = (sitdLength + 187U) / 188U;
- if (tmp > 1U)
- {
- sitdPointer->transferResults[2] |= (0x01U << EHCI_HOST_SITD_TP_SHIFT); /* for iso split */
- }
- else
- {
- sitdPointer->transferResults[2] |= (0x00U << EHCI_HOST_SITD_TP_SHIFT); /* for iso split */
- }
- sitdPointer->transferResults[2] |= (tmp << EHCI_HOST_SITD_TCOUNT_SHIFT); /* for iso split */
- }
- sitdPointer->backPointer = EHCI_HOST_T_INVALID_VALUE;
- sitdPointer = (ehciInstance->ehciSitdIndexBase + sitdPointer->nextSitdIndex);
- }
- sitdPointer = (usb_host_ehci_sitd_t *)transfer->union2.unitTail;
- sitdPointer->transferResults[0] |= (1UL << EHCI_HOST_SITD_IOC_SHIFT); /* last set IOC */
- /* link transfer to usb_host_ehci_iso_t transfer list */
- isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
- USB_HostEhciLock();
- if (isoPointer->ehciTransferHead == NULL)
- {
- transfer->next = NULL;
- isoPointer->ehciTransferTail = transfer;
- isoPointer->ehciTransferHead = transfer;
- }
- else
- {
- transfer->next = NULL;
- isoPointer->ehciTransferTail->next = transfer;
- isoPointer->ehciTransferTail = transfer;
- }
- USB_HostEhciUnlock();
- /* link itd to frame list (note: initialize frameEntryIndex)*/
- /*misra 11.6*/
- temp = (uint32_t *)(transfer->union1.unitHead);
- USB_HostEhciLinkSitd(ehciInstance, ehciPipePointer, (void *)temp);
- return kStatus_USB_Success;
- }
- static uint32_t USB_HostEhciSitdArrayRelease(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_sitd_t *startSitdPointer,
- usb_host_ehci_sitd_t *endSitdPointer)
- {
- usb_host_ehci_sitd_t *sitdPointer = startSitdPointer;
- uint32_t leftLength = 0;
- /* remove itd from frame list */
- while (1U == 1U)
- {
- /* record the transfer's result length */
- leftLength +=
- ((sitdPointer->transferResults[0] & EHCI_HOST_SITD_TOTAL_BYTES_MASK) >> EHCI_HOST_SITD_TOTAL_BYTES_SHIFT);
- USB_HostEhciRemoveFromFrame(ehciInstance, (uint32_t)sitdPointer,
- sitdPointer->frameEntryIndex); /* remove from the inserted frame list */
- /* release itd */
- /* USB_HostEhciLock(); */
- /*set next link pointer to invalid in case hardware access invalid sitd structure in special case*/
- sitdPointer->nextLinkPointer = (((uint32_t)ehciInstance->ehciSitdList) | EHCI_HOST_T_INVALID_VALUE);
- ehciInstance->ehciSitdList = sitdPointer;
- ehciInstance->ehciSitdNumber++;
- /* USB_HostEhciUnlock(); */
- if (sitdPointer == endSitdPointer)
- {
- break;
- }
- sitdPointer = &(ehciInstance->ehciSitdIndexBase[sitdPointer->nextSitdIndex]);
- }
- return leftLength;
- }
- static usb_status_t USB_HostEhciSitdArrayDeinit(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer)
- {
- usb_host_ehci_iso_t *isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
- usb_host_transfer_t *transfer;
- usb_host_transfer_t *nextTransfer;
- /* firstly remove the transfer (because host task may occupy to access the resource) */
- USB_HostEhciLock();
- transfer = isoPointer->ehciTransferHead;
- isoPointer->ehciTransferTail = NULL;
- isoPointer->ehciTransferHead = NULL;
- USB_HostEhciUnlock();
- while (transfer != NULL)
- {
- nextTransfer = transfer->next;
- /* remove sitd from frame list and release itd */
- transfer->transferSofar =
- transfer->transferLength - USB_HostEhciSitdArrayRelease(ehciInstance,
- (usb_host_ehci_sitd_t *)transfer->union1.unitHead,
- (usb_host_ehci_sitd_t *)transfer->union2.unitTail);
- /* callback function is different from the current condition */
- transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferCancel);
- /* next transfer */
- transfer = nextTransfer;
- }
- return kStatus_USB_Success;
- }
- #endif /* USB_HOST_CONFIG_EHCI_MAX_SITD */
- #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
- static uint32_t USB_HostEhciGetItdLinkFrame(usb_host_ehci_instance_t *ehciInstance,
- uint32_t lastLinkUframe,
- uint16_t startUframe,
- uint16_t uframeInterval)
- {
- uint32_t shouldLinkUframe;
- uint32_t currentUframe;
- uint32_t distance;
- if (lastLinkUframe != 0xFFFFU)
- {
- shouldLinkUframe = lastLinkUframe + uframeInterval;
- if (shouldLinkUframe > USB_HOST_EHCI_MAX_MICRFRAME_VALUE)
- {
- shouldLinkUframe = shouldLinkUframe - (USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U);
- }
- currentUframe = (ehciInstance->ehciIpBase->FRINDEX & USB_HOST_EHCI_MAX_MICRFRAME_VALUE);
- distance = ((shouldLinkUframe + USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U - currentUframe) &
- USB_HOST_EHCI_MAX_MICRFRAME_VALUE); /* get the distance */
- /* shouldLinkUframe has add uframeInterval, think about the align with interval, so here add (uframeInterval
- * * 2) */
- if ((distance <= ((uint32_t)USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER +
- ((uint32_t)uframeInterval * USB_HOST_EHCI_ISO_MAX_CONTINUOUS_TRANSFER))) &&
- (distance > 2U))
- {
- currentUframe = shouldLinkUframe;
- }
- else /* re-link */
- {
- currentUframe =
- ((currentUframe + USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER) & USB_HOST_EHCI_MAX_MICRFRAME_VALUE);
- /*if (currentUframe > USB_HOST_EHCI_MAX_MICRFRAME_VALUE)
- {
- currentUframe = currentUframe - (USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U);
- }*/
- /* uframe should align with interval */
- if (currentUframe <= startUframe)
- {
- currentUframe = startUframe;
- }
- else
- {
- currentUframe -= startUframe;
- currentUframe = ((uint32_t)(currentUframe + uframeInterval) &
- (~((uint32_t)uframeInterval - 1U))); /* uframeInterval is power of 2 */
- currentUframe += startUframe;
- }
- }
- }
- else
- {
- currentUframe = (ehciInstance->ehciIpBase->FRINDEX & USB_HOST_EHCI_MAX_MICRFRAME_VALUE);
- currentUframe = ((currentUframe + USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER) & USB_HOST_EHCI_MAX_MICRFRAME_VALUE);
- /* uframe should align with interval */
- if (currentUframe <= startUframe)
- {
- currentUframe = startUframe;
- }
- else
- {
- currentUframe -= startUframe;
- currentUframe =
- ((currentUframe + uframeInterval) & (~(uframeInterval - 1U))); /* uframeInterval is power of 2 */
- currentUframe += startUframe;
- }
- }
- return currentUframe;
- }
- static usb_status_t USB_HostEhciItdArrayInit(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer,
- usb_host_transfer_t *transfer)
- {
- usb_host_ehci_iso_t *isoPointer;
- usb_host_ehci_itd_t *itdPointer = NULL;
- usb_host_ehci_itd_t *itdHead = NULL;
- usb_host_ehci_itd_t *tmpItdPointer;
- uint32_t dataLength; /* the remaining data for sending */
- uint32_t transactionLength; /* the initializing transaction descriptor data length */
- uint32_t itdBufferValue;
- uint32_t itdBufferBaseValue; /* for calculating PG value */
- uint32_t address = 0U;
- uint32_t lastShouldLinkUframe;
- uint32_t linkUframe;
- uint32_t minDataPerItd =
- (uint32_t)ehciPipePointer->pipeCommon.numberPerUframe * ehciPipePointer->pipeCommon.maxPacketSize;
- uint8_t maxItdNumber;
- uint16_t index = 0;
- isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceAddress, &address);
- /* max needed itd number, the actual needed number may be less because micro-frame interval may be less than 8 */
- maxItdNumber = (uint8_t)((transfer->transferLength - 1U + minDataPerItd) / minDataPerItd);
- if (ehciPipePointer->uframeInterval < 8U)
- {
- maxItdNumber = (uint8_t)((maxItdNumber * ehciPipePointer->uframeInterval + 7U) / 8U) + 1U;
- }
- if (maxItdNumber > ehciInstance->ehciItdNumber)
- {
- return kStatus_USB_Error;
- }
- /* link transfer to usb_host_ehci_iso_t transfer list */
- transfer->next = NULL;
- /* USB_HostEhciLock(); */
- if (isoPointer->ehciTransferHead == NULL)
- {
- isoPointer->ehciTransferTail = transfer;
- isoPointer->ehciTransferHead = transfer;
- }
- else
- {
- isoPointer->ehciTransferTail->next = transfer;
- isoPointer->ehciTransferTail = transfer;
- }
- /* USB_HostEhciUnlock(); */
- dataLength = transfer->transferLength;
- transfer->union1.unitHead = 0U;
- /* get the link micro-frame */
- lastShouldLinkUframe = USB_HostEhciGetItdLinkFrame(
- ehciInstance, isoPointer->lastLinkFrame,
- (uint16_t)((ehciPipePointer->startFrame << 3) + ehciPipePointer->startUframe), ehciPipePointer->uframeInterval);
- if (lastShouldLinkUframe > USB_HOST_EHCI_MAX_MICRFRAME_VALUE)
- {
- linkUframe = lastShouldLinkUframe - (USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U);
- }
- else
- {
- linkUframe = lastShouldLinkUframe;
- }
- itdHead = ehciInstance->ehciItdList;
- while (0U != dataLength)
- {
- /* get one idle itd */
- tmpItdPointer = ehciInstance->ehciItdList;
- if (tmpItdPointer == NULL)
- {
- return kStatus_USB_Error; /* this should not reach */
- }
- ehciInstance->ehciItdList = (usb_host_ehci_itd_t *)tmpItdPointer->nextItdPointer;
- ehciInstance->ehciItdNumber -= 1U;
- tmpItdPointer->nextItdPointer = NULL;
- /* use the itd */
- if (transfer->union1.unitHead == 0U) /* first itd */
- {
- transfer->union1.unitHead = (uint32_t)tmpItdPointer;
- }
- else /* link itd list */
- {
- itdPointer->nextItdPointer = tmpItdPointer;
- }
- itdPointer = tmpItdPointer;
- /* itd has been set to all zero when releasing */
- itdBufferValue = (uint32_t)(transfer->transferBuffer + (transfer->transferLength - dataLength));
- itdBufferBaseValue = itdBufferValue;
- for (index = 0; index < 7U; ++index)
- {
- itdPointer->bufferPointers[index] = ((itdBufferBaseValue + ((uint32_t)index * 4U * 1024U)) & 0xFFFFF000U);
- }
- /* initialize iTD common fields */
- itdPointer->bufferPointers[0] |=
- (((uint32_t)ehciPipePointer->pipeCommon.endpointAddress << EHCI_HOST_ITD_ENDPT_SHIFT) |
- (address << EHCI_HOST_ITD_DEVICE_ADDRESS_SHIFT));
- itdPointer->bufferPointers[1] |=
- (((uint32_t)ehciPipePointer->pipeCommon.direction << EHCI_HOST_ITD_DIRECTION_SHIFT) |
- ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_ITD_MAX_PACKET_SIZE_SHIFT));
- itdPointer->bufferPointers[2] |= (ehciPipePointer->pipeCommon.numberPerUframe);
- /* initialize transaction descriptors */
- for (index = (uint8_t)(linkUframe & 0x0007U); index < 8U; index += ehciPipePointer->uframeInterval)
- {
- transactionLength = ((dataLength > minDataPerItd) ? minDataPerItd : dataLength);
- /* initialize the uframeIndex's transaction descriptor in itd */
- itdPointer->transactions[index] =
- ((EHCI_HOST_ITD_STATUS_ACTIVE_MASK) | (transactionLength << EHCI_HOST_ITD_TRANSACTION_LEN_SHIFT) |
- ((((itdBufferValue & 0xFFFFF000U) - (itdBufferBaseValue & 0xFFFFF000U)) >>
- EHCI_HOST_ITD_BUFFER_POINTER_SHIFT)
- << EHCI_HOST_ITD_PG_SHIFT) |
- (itdBufferValue & EHCI_HOST_ITD_TRANSACTION_OFFSET_MASK));
- dataLength -= transactionLength;
- itdBufferValue += transactionLength;
- if (dataLength <= 0U)
- {
- break;
- }
- }
- }
- transfer->union2.unitTail = (uint32_t)itdPointer;
- itdPointer->transactions[index] |= (1UL << EHCI_HOST_ITD_IOC_SHIFT); /* last set IOC */
- itdPointer = itdHead;
- /* link itd to frame list (note: initialize frameEntryIndex)*/
- while (NULL != itdPointer)
- {
- void *temp = (void *)ehciInstance->ehciFrameList;
- uint32_t *linkPointer = &((uint32_t *)temp)[linkUframe >> 3];
- uint32_t linkValue = *linkPointer;
- itdPointer->frameEntryIndex = linkUframe >> 3;
- while ((0U == (linkValue & EHCI_HOST_T_INVALID_VALUE)) &&
- ((linkValue & EHCI_HOST_POINTER_TYPE_MASK) == EHCI_HOST_POINTER_TYPE_ITD))
- {
- linkPointer = (uint32_t *)(linkValue & EHCI_HOST_POINTER_ADDRESS_MASK);
- linkValue = *linkPointer;
- }
- itdPointer->nextLinkPointer = *linkPointer;
- *linkPointer = ((uint32_t)itdPointer | EHCI_HOST_POINTER_TYPE_ITD);
- itdPointer = itdPointer->nextItdPointer;
- if (itdPointer == NULL)
- {
- break;
- }
- linkUframe += ehciPipePointer->uframeInterval;
- lastShouldLinkUframe += ehciPipePointer->uframeInterval;
- if (linkUframe >= (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE << 3))
- {
- linkUframe = (linkUframe - (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE << 3));
- }
- }
- if (lastShouldLinkUframe > USB_HOST_EHCI_MAX_MICRFRAME_VALUE)
- {
- lastShouldLinkUframe = lastShouldLinkUframe - (USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U);
- }
- isoPointer->lastLinkFrame = (uint16_t)lastShouldLinkUframe;
- return kStatus_USB_Success;
- }
- static uint32_t USB_HostEhciItdArrayRelease(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_itd_t *startItdPointer,
- usb_host_ehci_itd_t *endItdPointer)
- {
- usb_host_ehci_itd_t *itdPointer = startItdPointer;
- uint8_t index;
- uint32_t doneLength = 0;
- /* remove itd from frame list */
- while (1U == 1U)
- {
- /* record the transfer's result length */
- for (index = 0U; index < 8U; ++index)
- {
- doneLength += ((itdPointer->transactions[index] & EHCI_HOST_ITD_TRANSACTION_LEN_MASK) >>
- EHCI_HOST_ITD_TRANSACTION_LEN_SHIFT);
- }
- USB_HostEhciRemoveFromFrame(ehciInstance, (uint32_t)itdPointer,
- (uint16_t)itdPointer->frameEntryIndex); /* remove from the inserted frame list */
- /* release itd */
- /* USB_HostEhciLock(); */
- /*set next link pointer to invalid in case hardware access invalid itd structure in special case*/
- itdPointer->nextLinkPointer = EHCI_HOST_T_INVALID_VALUE;
- USB_HostEhciZeroMem((uint32_t *)(void *)itdPointer + 1, ((sizeof(usb_host_ehci_itd_t) >> 2) - 4U));
- itdPointer->nextItdPointer = (usb_host_ehci_itd_t *)ehciInstance->ehciItdList;
- ehciInstance->ehciItdList = itdPointer;
- ehciInstance->ehciItdNumber++;
- /* USB_HostEhciUnlock(); */
- if (itdPointer == endItdPointer)
- {
- break;
- }
- itdPointer = itdPointer->nextItdPointer;
- }
- return doneLength;
- }
- static usb_status_t USB_HostEhciItdArrayDeinit(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer)
- {
- usb_host_ehci_iso_t *isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
- usb_host_transfer_t *transfer;
- usb_host_transfer_t *nextTransfer;
- uint32_t doneLength = 0;
- /* firstly remove the transfer (because host task may occupy to access the resource) */
- USB_HostEhciLock();
- transfer = isoPointer->ehciTransferHead;
- isoPointer->ehciTransferTail = NULL;
- isoPointer->ehciTransferHead = NULL;
- USB_HostEhciUnlock();
- while (transfer != NULL)
- {
- nextTransfer = transfer->next;
- doneLength = 0;
- /* remove itd from frame list and release itd */
- doneLength = USB_HostEhciItdArrayRelease(ehciInstance, (usb_host_ehci_itd_t *)transfer->union1.unitHead,
- (usb_host_ehci_itd_t *)transfer->union2.unitTail);
- /* transfer callback */
- if (ehciPipePointer->pipeCommon.direction == USB_OUT)
- {
- doneLength = transfer->transferLength;
- }
- transfer->transferSofar = doneLength;
- /* callback function is different from the current condition */
- transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferCancel);
- /* next transfer */
- transfer = nextTransfer;
- }
- return kStatus_USB_Success;
- }
- #endif /* USB_HOST_CONFIG_EHCI_MAX_ITD */
- static usb_status_t USB_HostEhciOpenControlBulk(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer)
- {
- usb_host_ehci_qh_t *qhPointer;
- if (USB_HostEhciQhInit(ehciInstance, ehciPipePointer) != kStatus_USB_Success) /* initialize control/bulk qh */
- {
- return kStatus_USB_Error;
- }
- qhPointer = (usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
- /* add qh to async */
- qhPointer->horizontalLinkPointer = ehciInstance->shedFirstQh->horizontalLinkPointer;
- ehciInstance->shedFirstQh->horizontalLinkPointer = ((uint32_t)qhPointer | EHCI_HOST_POINTER_TYPE_QH);
- return kStatus_USB_Success;
- }
- static usb_status_t USB_HostEhciCloseControlBulk(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer)
- {
- volatile usb_host_ehci_qh_t *vltPrevQhPointer;
- uint32_t horizontalLinkValue;
- uint32_t *temp;
- /* remove qh from async schedule */
- temp = (uint32_t *)ehciPipePointer->ehciQh;
- if ((ehciInstance->shedFirstQh->horizontalLinkPointer & EHCI_HOST_POINTER_ADDRESS_MASK) ==
- (uint32_t)temp) /* the removing qh is the first qh in the async list */
- {
- USB_HostEhciStopAsync(ehciInstance);
- ehciInstance->shedFirstQh->horizontalLinkPointer =
- ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer;
- USB_HostEhciStartAsync(ehciInstance);
- }
- else
- {
- /* search for the removing qh from the async list */
- vltPrevQhPointer = ehciInstance->shedFirstQh;
- while (vltPrevQhPointer != NULL)
- {
- horizontalLinkValue = vltPrevQhPointer->horizontalLinkPointer;
- if ((0U != (horizontalLinkValue & EHCI_HOST_T_INVALID_VALUE)) ||
- ((horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK) == (uint32_t)temp) ||
- ((horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK) == (uint32_t)ehciInstance->shedFirstQh))
- {
- break;
- }
- vltPrevQhPointer = (volatile usb_host_ehci_qh_t *)(horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK);
- }
- /* remove the qh from async list */
- /*for misra 11.6*/
- temp = (uint32_t *)ehciPipePointer->ehciQh;
- if ((vltPrevQhPointer != NULL) && (0U == (horizontalLinkValue & EHCI_HOST_T_INVALID_VALUE)) &&
- ((horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK) == (uint32_t)temp))
- {
- USB_HostEhciStopAsync(ehciInstance);
- vltPrevQhPointer->horizontalLinkPointer =
- ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer;
- USB_HostEhciStartAsync(ehciInstance);
- }
- }
- ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer =
- EHCI_HOST_T_INVALID_VALUE; /* invalid next qh link */
- return USB_HostEhciQhDeinit(ehciInstance, ehciPipePointer); /* de-initialize qh and release qh */
- }
- static usb_status_t USB_HostEhciOpenInterrupt(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer)
- {
- usb_status_t status = kStatus_USB_Success;
- uint32_t frameIndex;
- uint32_t *temp;
- /* allocate bandwidth */
- if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH)
- {
- status = USB_HostBandwidthHsHostAllocateInterrupt(ehciInstance, ehciPipePointer); /* host works as high-speed */
- }
- else
- {
- status = USB_HostBandwidthFslsHostAllocate(ehciInstance,
- ehciPipePointer); /* host works as full-speed or low-speed */
- }
- if (status != kStatus_USB_Success)
- {
- return status;
- }
- if (USB_HostEhciQhInit(ehciInstance, ehciPipePointer) != kStatus_USB_Success)
- {
- return kStatus_USB_Error;
- }
- /* insert QH to frame list */
- for (frameIndex = ehciPipePointer->startFrame; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
- frameIndex += (((uint32_t)ehciPipePointer->uframeInterval + 7U) / 8U))
- {
- temp = (uint32_t *)ehciPipePointer->ehciQh;
- USB_HostEhciAddQhToFrame(ehciInstance, (uint32_t)temp, (uint16_t)frameIndex, ehciPipePointer->uframeInterval);
- }
- return kStatus_USB_Success;
- }
- static usb_status_t USB_HostEhciCloseInterrupt(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer)
- {
- uint32_t frameIndex;
- uint32_t *temp;
- /* remove from frame list */
- for (frameIndex = ehciPipePointer->startFrame; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
- frameIndex += (((uint32_t)ehciPipePointer->uframeInterval + 7U) / 8U))
- {
- temp = (uint32_t *)ehciPipePointer->ehciQh;
- USB_HostEhciRemoveFromFrame(ehciInstance, (uint32_t)temp, (uint16_t)frameIndex);
- }
- ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer |=
- EHCI_HOST_T_INVALID_VALUE; /* invalid next qh link */
- return USB_HostEhciQhDeinit(ehciInstance, ehciPipePointer); /* de-initilaze qh and release qh */
- }
- #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
- ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
- static usb_status_t USB_HostEhciOpenIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer)
- {
- usb_host_ehci_iso_t *isoPointer;
- usb_status_t status = kStatus_USB_Success;
- if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH)
- {
- status = USB_HostBandwidthHsHostAllocateIso(
- ehciInstance, ehciPipePointer); /* allocate iso bandwidth when host works as high-speed */
- }
- else
- {
- status = USB_HostBandwidthFslsHostAllocate(
- ehciInstance, ehciPipePointer); /* allocate iso bandwidth when host works as full-speed or low-speed */
- }
- if (status != kStatus_USB_Success)
- {
- return status;
- }
- /* get usb_host_ehci_iso_t */
- if (ehciInstance->ehciIsoList == NULL)
- {
- return kStatus_USB_Error;
- }
- USB_HostEhciLock();
- isoPointer = ehciInstance->ehciIsoList;
- ehciInstance->ehciIsoList = ehciInstance->ehciIsoList->next;
- USB_HostEhciUnlock();
- isoPointer->lastLinkFrame = 0xFFFF;
- ehciPipePointer->ehciQh = isoPointer;
- return status;
- }
- static usb_status_t USB_HostEhciCloseIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer)
- {
- usb_host_ehci_iso_t *isoPointer;
- uint32_t speed = 0U;
- isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
- if (isoPointer->ehciTransferHead != NULL)
- {
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
- if (speed == USB_SPEED_HIGH)
- {
- #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
- (void)USB_HostEhciItdArrayDeinit(ehciInstance, ehciPipePointer); /* de-initialize itd list and free them */
- #endif
- }
- else
- {
- #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
- (void)USB_HostEhciSitdArrayDeinit(ehciInstance,
- ehciPipePointer); /* de-initialize sitd list and free them */
- #endif
- }
- }
- /* release usb_host_ehci_iso_t */
- USB_HostEhciLock();
- isoPointer->next = ehciInstance->ehciIsoList;
- ehciInstance->ehciIsoList = isoPointer;
- USB_HostEhciUnlock();
- return kStatus_USB_Success;
- }
- #endif
- static usb_status_t USB_HostEhciResetIP(usb_host_ehci_instance_t *ehciInstance)
- {
- /* reset controller */
- ehciInstance->ehciIpBase->USBCMD = USBHS_USBCMD_RST_MASK;
- while (0U != (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_RST_MASK))
- {
- }
- /* set host mode */
- #if (ENDIANNESS == USB_LITTLE_ENDIAN)
- ehciInstance->ehciIpBase->USBMODE |= 0x03U;
- #else
- ehciInstance->ehciIpBase->USBMODE |= (0x03U | (0x01U << USBHS_USBMODE_ES_SHIFT));
- #endif
- /* check frame list size */
- if (0U == (ehciInstance->ehciIpBase->HCCPARAMS & USBHS_HCCPARAMS_PFL_MASK))
- {
- #if ((USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE < 8) || (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE > 1024))
- return kStatus_USB_Error;
- #endif
- #if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE & (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE - 1))
- return kStatus_USB_Error; /* frame size must be 1024/512/256/128/64/32/16/8 */
- #endif
- }
- return kStatus_USB_Success;
- }
- static usb_status_t USB_HostEhciStartIP(usb_host_ehci_instance_t *ehciInstance)
- {
- uint32_t tmp = 0;
- if (0U != (ehciInstance->ehciIpBase->HCSPARAMS & USBHS_HCSPARAMS_PPC_MASK)) /* Ports have power port switches */
- {
- /* only has one port */
- tmp = ehciInstance->ehciIpBase->PORTSC1;
- tmp &= (~EHCI_PORTSC1_W1_BITS);
- ehciInstance->ehciIpBase->PORTSC1 = (tmp | USBHS_PORTSC1_PP_MASK); /* turn on port power */
- }
- /* set frame list size */
- if (0U != (ehciInstance->ehciIpBase->HCCPARAMS & USBHS_HCCPARAMS_PFL_MASK))
- {
- #if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE <= 64)
- ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_FS2_MASK);
- #if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 64)
- ehciInstance->ehciIpBase->USBCMD |= (0x00U << USBHS_USBCMD_FS_SHIFT);
- #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 32)
- ehciInstance->ehciIpBase->USBCMD |= (0x01U << USBHS_USBCMD_FS_SHIFT);
- #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 16)
- ehciInstance->ehciIpBase->USBCMD |= (0x02U << USBHS_USBCMD_FS_SHIFT);
- #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 8)
- ehciInstance->ehciIpBase->USBCMD |= (0x03U << USBHS_USBCMD_FS_SHIFT);
- #endif
- #else
- #if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 1024)
- ehciInstance->ehciIpBase->USBCMD |= (0x00U << USBHS_USBCMD_FS_SHIFT);
- #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 512)
- ehciInstance->ehciIpBase->USBCMD |= (0x01U << USBHS_USBCMD_FS_SHIFT);
- #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 256)
- ehciInstance->ehciIpBase->USBCMD |= (0x02U << USBHS_USBCMD_FS_SHIFT);
- #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 128)
- ehciInstance->ehciIpBase->USBCMD |= (0x03U << USBHS_USBCMD_FS_SHIFT);
- #endif
- #endif
- }
- /* no interrupt threshold */
- ehciInstance->ehciIpBase->USBCMD &= ~USBHS_USBCMD_ITC_MASK;
- /* start the controller */
- ehciInstance->ehciIpBase->USBCMD |= USBHS_USBCMD_RS_MASK;
- /* set timer0 */
- ehciInstance->ehciIpBase->GPTIMER0LD = (100U * 1000U - 1U); /* 100ms */
- /* enable interrupt (USB interrupt enable + USB error interrupt enable + port change detect enable + system error
- * enable + interrupt on async advance enable) + general purpos Timer 0 Interrupt enable */
- ehciInstance->ehciIpBase->USBINTR |= (0x1000037U);
- return kStatus_USB_Success;
- }
- static usb_status_t USB_HostEhciCancelPipe(usb_host_ehci_instance_t *ehciInstance,
- usb_host_ehci_pipe_t *ehciPipePointer,
- usb_host_transfer_t *transfer)
- {
- usb_host_ehci_qh_t *qhPointer;
- #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
- ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
- usb_host_ehci_iso_t *isoPointer;
- uint32_t speed = 0U;
- #endif
- uint8_t cancelPipe = 0;
- switch (ehciPipePointer->pipeCommon.pipeType)
- {
- case USB_ENDPOINT_BULK:
- case USB_ENDPOINT_CONTROL:
- case USB_ENDPOINT_INTERRUPT:
- qhPointer = (usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
- if (qhPointer->ehciTransferHead == NULL) /* there is no transfer to cancel */
- {
- return kStatus_USB_Success;
- }
- if (transfer != NULL)
- {
- if ((qhPointer->ehciTransferHead == transfer) &&
- (qhPointer->ehciTransferHead == qhPointer->ehciTransferTail)) /* only has this one transfer */
- {
- cancelPipe = 1U;
- }
- else
- {
- cancelPipe = 0U;
- }
- }
- else
- {
- cancelPipe = 1U;
- }
- if (cancelPipe == 1U) /* cancel all pipe */
- {
- (void)USB_HostEhciQhQtdListDeinit(ehciInstance, ehciPipePointer); /* release all the qtd */
- }
- else /* cancel one transfer */
- {
- (void)USB_HostEhciTransferQtdListDeinit(ehciInstance, ehciPipePointer, transfer);
- }
- break;
- #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
- ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
- case USB_ENDPOINT_ISOCHRONOUS:
- isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
- if (isoPointer->ehciTransferHead == NULL) /* there is no transfer to cancel */
- {
- return kStatus_USB_Success;
- }
- /* cancel all pipe, don't implement canceling transfer for iso */
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
- if (speed == USB_SPEED_HIGH)
- {
- #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
- (void)USB_HostEhciItdArrayDeinit(ehciInstance, ehciPipePointer); /* de-initialize itd */
- #endif
- }
- else
- {
- #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
- (void)USB_HostEhciSitdArrayDeinit(ehciInstance, ehciPipePointer); /* de-initialize sitd */
- #endif
- }
- break;
- #endif
- default:
- /*no action*/
- break;
- }
- return kStatus_USB_Success;
- }
- static usb_status_t USB_HostEhciControlBus(usb_host_ehci_instance_t *ehciInstance, uint8_t busControl)
- {
- usb_status_t status = kStatus_USB_Success;
- uint32_t portScRegister;
- usb_host_bus_control_t controlCode = (usb_host_bus_control_t)busControl;
- switch (controlCode)
- {
- case kUSB_HostBusReset:
- /* reset port */
- portScRegister = ehciInstance->ehciIpBase->PORTSC1;
- portScRegister &= (~EHCI_PORTSC1_W1_BITS);
- ehciInstance->ehciIpBase->PORTSC1 = (portScRegister | USBHS_PORTSC1_PR_MASK);
- while (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_PR_MASK))
- {
- }
- break;
- case kUSB_HostBusRestart:
- ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceDetached;
- ehciInstance->ehciIpBase->USBINTR |= (USBHS_USBINTR_PCE_MASK); /* enable ehci port change interrupt */
- break;
- case kUSB_HostBusEnableAttach: /* enable device attach */
- if (ehciInstance->deviceAttached == (uint8_t)kEHCIDeviceDetached)
- {
- ehciInstance->ehciIpBase->USBINTR |= (USBHS_USBINTR_PCE_MASK); /* enable ehci port change interrupt */
- }
- break;
- case kUSB_HostBusDisableAttach: /* disable device attach */
- ehciInstance->ehciIpBase->USBINTR &= (~USBHS_USBINTR_PCE_MASK); /* disable ehci port change interrupt */
- break;
- #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
- case kUSB_HostBusSuspend:
- if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
- {
- /* set timer1 */
- ehciInstance->ehciIpBase->GPTIMER1LD = (1 * 1000); /* 1ms */
- ehciInstance->ehciIpBase->GPTIMER1CTL |=
- (USBHS_GPTIMER0CTL_RUN_MASK | USBHS_GPTIMER0CTL_MODE_MASK | USBHS_GPTIMER0CTL_RST_MASK);
- USB_HostEhciStopAsync(ehciInstance);
- USB_HostEhciStopPeriodic(ehciInstance);
- while (0U != (ehciInstance->ehciIpBase->USBSTS & (USBHS_USBSTS_PS_MASK | USBHS_USBSTS_AS_MASK)))
- {
- __NOP();
- }
- ehciInstance->ehciIpBase->PORTSC1 &= ~USBHS_PORTSC1_WKCN_MASK;
- ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_WKDS_MASK;
- ehciInstance->ehciIpBase->PORTSC1 |= (USBHS_PORTSC1_SUSP_MASK); /* Suspend the device */
- #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
- PMU->WAKEUP_PM2_MASK1 |= PMU_WAKEUP_PM2_MASK1_USB(1);
- #endif
- ehciInstance->matchTick = 0U;
- ehciInstance->ehciIpBase->USBINTR |= (USBHS_USBINTR_TIE1_MASK);
- ehciInstance->busSuspendStatus = kBus_EhciStartSuspend;
- }
- else
- {
- status = kStatus_USB_Error;
- }
- break;
- case kUSB_HostBusResume:
- ehciInstance->ehciIpBase->PORTSC1 &= ~(USBHS_PORTSC1_SUSP_MASK); /* Clear Suspend bit */
- ehciInstance->ehciIpBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK;
- if (ehciInstance->deviceAttached != (uint8_t)kEHCIDeviceDetached)
- {
- ehciInstance->busSuspendStatus = kBus_EhciStartResume;
- #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
- ehciInstance->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK;
- #else
- #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
- #else
- ehciInstance->ehciIpBase->USBGENCTRL &= ~USBHS_USBGENCTRL_WU_IE_MASK;
- #endif
- #endif
- ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK);
- ehciInstance->ehciIpBase->PORTSC1 |= (USBHS_PORTSC1_FPR_MASK); /* Resume the device */
- }
- else
- {
- status = kStatus_USB_Error;
- }
- break;
- #endif
- default:
- status = kStatus_USB_Error;
- break;
- }
- return status;
- }
- void USB_HostEhciTransactionDone(usb_host_ehci_instance_t *ehciInstance)
- {
- /* process async QH */
- usb_host_ehci_pipe_t *ehciPipePointer;
- usb_host_ehci_pipe_t *ehciClearPipePointer = NULL;
- volatile usb_host_ehci_qh_t *vltQhPointer;
- volatile usb_host_ehci_qtd_t *vltQtdPointer;
- usb_host_transfer_t *transfer;
- usb_host_transfer_t *nextTransfer;
- uint32_t qtdStatus = 0;
- #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
- volatile usb_host_ehci_itd_t *vltItdPointer;
- uint8_t index = 0;
- #endif
- #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
- volatile usb_host_ehci_sitd_t *vltSitdPointer;
- #endif
- #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
- ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
- usb_host_ehci_iso_t *isoPointer;
- uint32_t dataLength;
- uint32_t speed = 0U;
- #endif
- void *temp;
- uint32_t transferResults;
- uint32_t transferOverlayResults;
- ehciPipePointer = ehciInstance->ehciRunningPipeList; /* check all the running pipes */
- while (ehciPipePointer != NULL)
- {
- switch (ehciPipePointer->pipeCommon.pipeType)
- {
- case USB_ENDPOINT_BULK:
- case USB_ENDPOINT_INTERRUPT:
- case USB_ENDPOINT_CONTROL:
- vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; /* pipe's qh */
- transfer = vltQhPointer->ehciTransferHead; /* qh's transfer */
- while (transfer != NULL)
- {
- nextTransfer = transfer->next;
- /* normal case */
- vltQtdPointer = (volatile usb_host_ehci_qtd_t *)transfer->union2.unitTail;
- transferResults = vltQtdPointer->transferResults[0];
- transferOverlayResults = vltQhPointer->transferOverlayResults[0];
- if ((0U != (transferResults & (EHCI_HOST_QTD_IOC_MASK))) &&
- (0U == (transferResults & EHCI_HOST_QTD_STATUS_ACTIVE_MASK))) /* transfer is done */
- {
- qtdStatus = (transferResults & EHCI_HOST_QTD_STATUS_ERROR_MASK);
- transfer->transferSofar =
- USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
- (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
- transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
- 0U :
- (transfer->transferLength - transfer->transferSofar);
- vltQhPointer->ehciTransferHead = transfer->next;
- vltQhPointer->timeOutLabel = 0U;
- vltQhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
- if (0U != qtdStatus) /* has errors */
- {
- if (0U == (transferOverlayResults & EHCI_HOST_QTD_STATUS_ACTIVE_MASK))
- {
- vltQhPointer->transferOverlayResults[0] &=
- (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
- }
- if (0U != (qtdStatus & EHCI_HOST_QH_STATUS_NOSTALL_ERROR_MASK))
- {
- /* callback function is different from the current condition */
- transfer->callbackFn(transfer->callbackParam, transfer,
- kStatus_USB_TransferFailed); /* transfer fail */
- }
- else
- {
- /* callback function is different from the current condition */
- transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferStall);
- }
- }
- else
- {
- if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL) &&
- (transfer->setupPacket->bRequest == USB_REQUEST_STANDARD_CLEAR_FEATURE) &&
- (transfer->setupPacket->bmRequestType == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT) &&
- ((USB_SHORT_FROM_LITTLE_ENDIAN(transfer->setupPacket->wValue) & 0x00FFu) ==
- USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT))
- {
- ehciClearPipePointer = ehciInstance->ehciRunningPipeList;
- while (ehciClearPipePointer != NULL)
- {
- /* only compute bulk and interrupt pipe */
- if (((ehciClearPipePointer->pipeCommon.endpointAddress |
- (ehciClearPipePointer->pipeCommon.direction
- << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) ==
- (uint8_t)(USB_SHORT_FROM_LITTLE_ENDIAN(transfer->setupPacket->wIndex))) &&
- (ehciClearPipePointer->pipeCommon.deviceHandle ==
- ehciPipePointer->pipeCommon.deviceHandle))
- {
- break;
- }
- temp = (void *)ehciClearPipePointer->pipeCommon.next;
- ehciClearPipePointer = (usb_host_ehci_pipe_t *)temp;
- }
- if ((ehciClearPipePointer != NULL) &&
- ((ehciClearPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT) ||
- (ehciClearPipePointer->pipeCommon.pipeType == USB_ENDPOINT_BULK)))
- {
- ((volatile usb_host_ehci_qh_t *)(ehciClearPipePointer->ehciQh))
- ->transferOverlayResults[0] &= (~EHCI_HOST_QTD_DT_MASK);
- }
- }
- /* callback function is different from the current condition */
- transfer->callbackFn(transfer->callbackParam, transfer,
- kStatus_USB_Success); /* transfer success */
- }
- }
- else if ((0U == (transferOverlayResults & EHCI_HOST_QTD_STATUS_ACTIVE_MASK)) &&
- (0U != (transferOverlayResults &
- EHCI_HOST_QH_STATUS_ERROR_MASK))) /* there is error and transfer is done */
- {
- qtdStatus = (vltQhPointer->transferOverlayResults[0] & EHCI_HOST_QH_STATUS_ERROR_MASK);
- vltQtdPointer = (volatile usb_host_ehci_qtd_t *)(vltQhPointer->currentQtdPointer);
- if ((0U != ((uint32_t)vltQtdPointer & EHCI_HOST_T_INVALID_VALUE)) ||
- (vltQtdPointer == NULL)) /* the error status is unreasonable */
- {
- vltQhPointer->transferOverlayResults[0] &=
- (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
- }
- else
- {
- /* remove qtd from qh */
- do
- {
- if (vltQtdPointer == NULL)
- {
- break;
- }
- else if (0U != (vltQtdPointer->transferResults[0] & EHCI_HOST_QTD_IOC_MASK))
- {
- break;
- }
- else
- {
- /* no action */
- }
- vltQtdPointer = (volatile usb_host_ehci_qtd_t *)vltQtdPointer->nextQtdPointer;
- } while (true);
- vltQhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
- vltQhPointer->currentQtdPointer = EHCI_HOST_T_INVALID_VALUE;
- vltQhPointer->transferOverlayResults[0] &=
- (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
- if (vltQtdPointer != NULL)
- {
- vltQhPointer->nextQtdPointer = vltQtdPointer->nextQtdPointer;
- }
- transfer->transferSofar = USB_HostEhciQtdListRelease(
- ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
- (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
- transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
- 0U :
- (transfer->transferLength - transfer->transferSofar);
- vltQhPointer->ehciTransferHead = transfer->next;
- vltQhPointer->timeOutLabel = 0U;
- vltQhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
- if (0U != (qtdStatus & EHCI_HOST_QH_STATUS_NOSTALL_ERROR_MASK))
- {
- /* callback function is different from the current condition */
- transfer->callbackFn(transfer->callbackParam, transfer,
- kStatus_USB_TransferFailed); /* transfer fail */
- }
- else
- {
- /* callback function is different from the current condition */
- transfer->callbackFn(transfer->callbackParam, transfer,
- kStatus_USB_TransferStall); /* transfer stall */
- }
- }
- }
- else
- {
- break;
- }
- transfer = nextTransfer;
- }
- break;
- #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
- ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
- case USB_ENDPOINT_ISOCHRONOUS:
- qtdStatus = 0; /* qtdStatus means break here, because there is only one break in while for misra */
- isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh; /* pipe's usb_host_ehci_iso_t */
- transfer = isoPointer->ehciTransferHead; /* usb_host_ehci_iso_t's transfer */
- while (transfer != NULL)
- {
- nextTransfer = transfer->next;
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
- if (speed == USB_SPEED_HIGH)
- {
- #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
- vltItdPointer =
- (volatile usb_host_ehci_itd_t *)(transfer->union2.unitTail); /* transfer's last itd */
- for (index = 0; index < 8U; ++index)
- {
- if (0U != (vltItdPointer->transactions[index] & EHCI_HOST_ITD_STATUS_ACTIVE_MASK))
- {
- break;
- }
- }
- if (index == 8U) /* transfer is done */
- {
- /* remove itd from frame list and release itd */
- dataLength = USB_HostEhciItdArrayRelease(ehciInstance,
- (usb_host_ehci_itd_t *)transfer->union1.unitHead,
- (usb_host_ehci_itd_t *)transfer->union2.unitTail);
- transfer->transferSofar = dataLength;
- isoPointer->ehciTransferHead = transfer->next;
- /* callback function is different from the current condition */
- transfer->callbackFn(transfer->callbackParam, transfer,
- kStatus_USB_Success); /* transfer callback success */
- /* TODO: iso callback error */
- }
- else
- {
- qtdStatus = 1U; /* break */
- }
- #endif
- }
- else
- {
- #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
- vltSitdPointer =
- (volatile usb_host_ehci_sitd_t *)(transfer->union2.unitTail); /* transfer's last sitd */
- if (0U == (vltSitdPointer->transferResults[0] &
- EHCI_HOST_SITD_STATUS_ACTIVE_MASK)) /* transfer is done */
- {
- /* remove sitd from frame list and release itd */
- dataLength = USB_HostEhciSitdArrayRelease(
- ehciInstance, (usb_host_ehci_sitd_t *)transfer->union1.unitHead,
- (usb_host_ehci_sitd_t *)transfer->union2.unitTail);
- transfer->transferSofar = transfer->transferLength - dataLength;
- isoPointer->ehciTransferHead = transfer->next;
- /* callback function is different from the current condition */
- transfer->callbackFn(transfer->callbackParam, transfer,
- kStatus_USB_Success); /* transfer callback success */
- /* TODO: iso callback error */
- }
- else
- {
- qtdStatus = 1U; /* break */
- }
- #endif
- }
- if (qtdStatus == 1U)
- {
- break;
- }
- transfer = nextTransfer;
- }
- break;
- #endif
- default:
- /*no action*/
- break;
- }
- temp = (void *)ehciPipePointer->pipeCommon.next;
- ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
- }
- }
- static void USB_HostEhciPortChange(usb_host_ehci_instance_t *ehciInstance)
- {
- /* note: only has one port */
- uint32_t portScRegister = ehciInstance->ehciIpBase->PORTSC1;
- uint32_t sofStart = 0;
- uint32_t sofCount = 0;
- uint32_t index;
- if (0U != (portScRegister & USBHS_PORTSC1_CSC_MASK)) /* connection status change */
- {
- sofStart = (ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE);
- /* process CSC bit */
- while (1U == 1U)
- {
- portScRegister = ehciInstance->ehciIpBase->PORTSC1;
- if (0U != (portScRegister & USBHS_PORTSC1_CSC_MASK))
- {
- /* clear csc bit */
- portScRegister = ehciInstance->ehciIpBase->PORTSC1;
- portScRegister &= (~EHCI_PORTSC1_W1_BITS);
- ehciInstance->ehciIpBase->PORTSC1 = (portScRegister | USBHS_PORTSC1_CSC_MASK);
- }
- sofCount = (ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE);
- if (((sofCount + EHCI_MAX_UFRAME_VALUE + 1U - sofStart) & EHCI_MAX_UFRAME_VALUE) >
- (1U * 8U)) /* delay 1ms to clear CSC */
- {
- break;
- }
- }
- }
- /* process CCS bit */
- portScRegister = ehciInstance->ehciIpBase->PORTSC1;
- if (0U != (portScRegister & USBHS_PORTSC1_CCS_MASK)) /* process attach */
- {
- if ((ehciInstance->deviceAttached == (uint8_t)kEHCIDevicePhyAttached) ||
- (ehciInstance->deviceAttached == (uint8_t)kEHCIDeviceAttached))
- {
- return;
- }
- #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
- ehciInstance->busSuspendStatus = kBus_EhciIdle;
- ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
- #endif
- for (index = 0; index < USB_HOST_EHCI_PORT_CONNECT_DEBOUNCE_DELAY; ++index)
- {
- USB_HostEhciDelay(ehciInstance->ehciIpBase, 1);
- if (0U == (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
- {
- break;
- }
- }
- if (index < USB_HOST_EHCI_PORT_CONNECT_DEBOUNCE_DELAY) /* CCS is cleared */
- {
- ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceDetached;
- return;
- }
- /* reset port */
- portScRegister = ehciInstance->ehciIpBase->PORTSC1;
- portScRegister &= (~EHCI_PORTSC1_W1_BITS);
- ehciInstance->ehciIpBase->PORTSC1 = (portScRegister | USBHS_PORTSC1_PR_MASK);
- while (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_PR_MASK))
- {
- }
- ehciInstance->firstDeviceSpeed =
- (uint8_t)((ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_PSPD_MASK) >> USBHS_PORTSC1_PSPD_SHIFT);
- /* enable ehci phy disconnection */
- #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
- if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH)
- {
- USB_EhcihostPhyDisconnectDetectCmd(ehciInstance->controllerId, 1);
- }
- #endif
- /* wait for reset */
- USB_HostEhciDelay(ehciInstance->ehciIpBase, USB_HOST_EHCI_PORT_RESET_DELAY);
- /* process attach */
- (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_DEVICE_ATTACH);
- /* gpt timer start */
- ehciInstance->ehciIpBase->GPTIMER0CTL |=
- (USBHS_GPTIMER0CTL_RUN_MASK | USBHS_GPTIMER0CTL_MODE_MASK | USBHS_GPTIMER0CTL_RST_MASK);
- ehciInstance->deviceAttached = (uint8_t)kEHCIDevicePhyAttached;
- }
- else
- {
- if ((ehciInstance->deviceAttached == (uint8_t)kEHCIDevicePhyAttached) ||
- (ehciInstance->deviceAttached == (uint8_t)kEHCIDeviceAttached))
- {
- #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
- ehciInstance->busSuspendStatus = kBus_EhciIdle;
- ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
- #endif
- /* disable ehci phy disconnection */
- #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
- USB_EhcihostPhyDisconnectDetectCmd(ehciInstance->controllerId, 0);
- #endif
- /* disable async and periodic */
- USB_HostEhciStopAsync(ehciInstance);
- USB_HostEhciStopPeriodic(ehciInstance);
- (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_DEVICE_DETACH);
- }
- }
- }
- static void USB_HostEhciTimer0(usb_host_ehci_instance_t *ehciInstance)
- {
- volatile usb_host_ehci_qh_t *vltQhPointer;
- usb_host_ehci_qtd_t *vltQtdPointer;
- usb_host_transfer_t *transfer;
- uint32_t backValue;
- volatile uint32_t *totalBytesAddress = NULL;
- usb_host_ehci_pipe_t *ehciPipePointer = ehciInstance->ehciRunningPipeList;
- void *temp;
- uint8_t timeoutLabel;
- while (ehciPipePointer != NULL)
- {
- switch (ehciPipePointer->pipeCommon.pipeType)
- {
- case USB_ENDPOINT_BULK:
- case USB_ENDPOINT_CONTROL:
- vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; /* pipe's qh */
- transfer = vltQhPointer->ehciTransferHead; /* qh's transfer */
- if ((transfer != NULL)) /* there is transfering data */
- {
- timeoutLabel = 0U;
- if (ehciInstance->deviceAttached != (uint8_t)kEHCIDeviceAttached)
- {
- vltQtdPointer = (usb_host_ehci_qtd_t *)transfer->union2.unitTail;
- vltQhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE; /* invalid next qtd */
- vltQhPointer->transferOverlayResults[0] &=
- (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
- timeoutLabel = 1;
- }
- else
- {
- if (0U != (vltQhPointer->transferOverlayResults[0] & EHCI_HOST_QTD_STATUS_ACTIVE_MASK))
- {
- vltQtdPointer = (usb_host_ehci_qtd_t *)vltQhPointer->currentQtdPointer;
- totalBytesAddress = &(vltQhPointer->transferOverlayResults[0]);
- }
- else
- {
- vltQtdPointer = (usb_host_ehci_qtd_t *)transfer->union2.unitTail;
- totalBytesAddress = &(vltQtdPointer->transferResults[0]);
- }
- backValue =
- (((*totalBytesAddress) & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >>
- EHCI_HOST_QTD_TOTAL_BYTES_SHIFT); /* backValue is used for total bytes to transfer */
- if (vltQhPointer->timeOutLabel != backValue) /* use total bytes to reflect the time out */
- {
- vltQhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
- vltQhPointer->timeOutLabel = (uint16_t)backValue;
- }
- else
- {
- /* time out when the total bytes don't change for the duration
- * USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE
- */
- (vltQhPointer->timeOutValue)--;
- if (vltQhPointer->timeOutValue == 0U)
- {
- /* stop the qh schedule */
- USB_HostEhciStopAsync(ehciInstance);
- if (backValue != (((*totalBytesAddress) & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >>
- EHCI_HOST_QTD_TOTAL_BYTES_SHIFT))
- {
- USB_HostEhciStartAsync(ehciInstance);
- }
- else
- {
- vltQhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE; /* invalid next qtd */
- vltQhPointer->transferOverlayResults[0] &=
- (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
- USB_HostEhciStartAsync(ehciInstance);
- timeoutLabel = 1U;
- }
- }
- }
- }
- if (timeoutLabel == 1U)
- {
- /* remove qtd from qh */
- temp = (void *)vltQhPointer->ehciTransferTail;
- while ((vltQtdPointer != NULL) &&
- (0U == (vltQtdPointer->transferResults[0] & EHCI_HOST_QTD_IOC_MASK)) &&
- (vltQtdPointer != (usb_host_ehci_qtd_t *)temp))
- {
- vltQtdPointer = (usb_host_ehci_qtd_t *)vltQtdPointer->nextQtdPointer;
- }
- if ((vltQtdPointer != NULL) &&
- (0U == (vltQtdPointer->nextQtdPointer & EHCI_HOST_T_INVALID_VALUE)))
- {
- vltQhPointer->nextQtdPointer =
- vltQtdPointer->nextQtdPointer; /* start qh if there are other qtd that don't belong to
- the transfer */
- }
- transfer->transferSofar =
- USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
- (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
- transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
- 0U :
- (transfer->transferLength - transfer->transferSofar);
- vltQhPointer->ehciTransferHead = transfer->next;
- vltQhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
- /* callback function is different from the current condition */
- transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferFailed);
- }
- }
- break;
- default:
- /*no action*/
- break;
- }
- temp = (void *)ehciPipePointer->pipeCommon.next;
- ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
- }
- }
- #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
- static void USB_HostEhciTimer1(usb_host_ehci_instance_t *ehciInstance)
- {
- if (ehciInstance->deviceAttached != (uint8_t)kEHCIDeviceDetached)
- {
- if (kBus_EhciStartSuspend == ehciInstance->busSuspendStatus)
- {
- usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
- if (0U == ehciInstance->matchTick)
- {
- ehciInstance->matchTick = hostPointer->hwTick;
- }
- else
- {
- if ((hostPointer->hwTick - ehciInstance->matchTick) >= 5U)
- {
- ehciInstance->ehciIpBase->USBCMD &= ~USBHS_USBCMD_RS_MASK;
- ehciInstance->ehciIpBase->USBSTS |= USBHS_USBSTS_SRI_MASK;
- #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
- #if 0
- ehciInstance->registerPhyBase->CTRL |= USBPHY_CTRL_ENVBUSCHG_WKUP_MASK
- | USBPHY_CTRL_ENIDCHG_WKUP_MASK
- | USBPHY_CTRL_ENDPDMCHG_WKUP_MASK
- | USBPHY_CTRL_ENIRQRESUMEDETECT_MASK
- ;
- #endif
- #endif
- #if (defined(FSL_FEATURE_USBPHY_28FDSOI) && (FSL_FEATURE_USBPHY_28FDSOI > 0U))
- ehciInstance->registerPhyBase->USB1_VBUS_DETECT_SET |=
- USBPHY_USB1_VBUS_DETECT_VBUSVALID_TO_SESSVALID_MASK;
- #endif
- ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_PHCD_MASK;
- #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
- ehciInstance->registerPhyBase->PWD = 0xFFFFFFFFU;
- while (0U != (ehciInstance->registerPhyBase->CTRL & (USBPHY_CTRL_UTMI_SUSPENDM_MASK)))
- {
- __NOP();
- }
- #endif
- #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
- ehciInstance->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WKUP_ID_EN_MASK |
- USBNC_USB_OTGn_CTRL_WKUP_VBUS_EN_MASK |
- USBNC_USB_OTGn_CTRL_WKUP_DPDM_EN_MASK;
- ehciInstance->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WIE_MASK;
- #else
- #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
- #else
- ehciInstance->ehciIpBase->USBGENCTRL = USBHS_USBGENCTRL_WU_IE_MASK;
- #endif
- #endif
- #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
- ehciInstance->registerPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK;
- #endif
- (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
- kUSB_HostEventSuspended); /* call host callback function */
- ehciInstance->busSuspendStatus = kBus_EhciSuspended;
- }
- }
- }
- else if (kBus_EhciStartResume == ehciInstance->busSuspendStatus)
- {
- usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
- if (0U == (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_FPR_MASK))
- {
- ehciInstance->ehciIpBase->PORTSC1 &= ~USBHS_PORTSC1_WKDS_MASK;
- if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
- {
- USB_HostEhciStartAsync(ehciInstance);
- USB_HostEhciStartPeriodic(ehciInstance);
- }
- (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
- kUSB_HostEventResumed); /* call host callback function */
- hostPointer->suspendedDevice = NULL;
- ehciInstance->busSuspendStatus = kBus_EhciIdle;
- ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
- }
- }
- else
- {
- }
- }
- else
- {
- ehciInstance->busSuspendStatus = kBus_EhciIdle;
- ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
- }
- }
- #endif
- usb_status_t USB_HostEhciCreate(uint8_t controllerId,
- usb_host_handle upperLayerHandle,
- usb_host_controller_handle *controllerHandle)
- {
- uint32_t index = 0;
- osa_status_t osaStatus;
- usb_host_ehci_instance_t *ehciInstance;
- uint32_t usbhsBaseAddrs[] = USBHS_BASE_ADDRS;
- usb_host_ehci_data_t *usbHostEhciData[USB_HOST_CONFIG_EHCI];
- uint32_t *framePointer;
- void *temp;
- uint8_t instanceIndex = 0U;
- if ((controllerId - (uint8_t)kUSB_ControllerEhci0) >= (sizeof(usbhsBaseAddrs) / sizeof(usbhsBaseAddrs[0])))
- {
- return kStatus_USB_ControllerNotFound;
- }
- *controllerHandle = NULL;
- ehciInstance = (usb_host_ehci_instance_t *)OSA_MemoryAllocate(
- sizeof(usb_host_ehci_instance_t)); /* malloc host ehci instance */
- if (ehciInstance == NULL)
- {
- return kStatus_USB_AllocFail;
- }
- ehciInstance->controllerId = controllerId;
- ehciInstance->hostHandle = upperLayerHandle;
- ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceDetached;
- ehciInstance->ehciIpBase = (USBHS_Type *)
- usbhsBaseAddrs[controllerId - (uint8_t)kUSB_ControllerEhci0]; /* operate ehci ip through the base address */
- #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
- ehciInstance->busSuspendStatus = kBus_EhciIdle;
- #if (defined(USB_HOST_CONFIG_LOW_POWER_MODE) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
- #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
- ehciInstance->registerPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
- #endif
- #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
- ehciInstance->registerNcBase = (USBNC_Type *)USB_EhciNCGetBase(controllerId);
- #endif
- #endif
- #endif
- if ((USB_HostEhciResetIP(ehciInstance) != kStatus_USB_Success) ||
- ((ehciInstance->controllerId < (uint8_t)kUSB_ControllerEhci0))) /* reset ehci ip */
- {
- OSA_MemoryFree(ehciInstance);
- return kStatus_USB_Error;
- }
- #if (USB_HOST_CONFIG_EHCI == 1U)
- if (0U == usbHostEhciFramListStatus[0])
- {
- usbHostEhciFramListStatus[0] = 1U;
- instanceIndex = 0U;
- ehciInstance->ehciFrameList = &s_UsbHostEhciFrameList1[0];
- }
- #elif (USB_HOST_CONFIG_EHCI == 2U)
- if (0U == usbHostEhciFramListStatus[0])
- {
- usbHostEhciFramListStatus[0] = 1U;
- instanceIndex = 0U;
- ehciInstance->ehciFrameList = &s_UsbHostEhciFrameList1[0];
- }
- else if (0U == usbHostEhciFramListStatus[1])
- {
- usbHostEhciFramListStatus[1] = 1U;
- instanceIndex = 1U;
- ehciInstance->ehciFrameList = &s_UsbHostEhciFrameList2[0];
- }
- else
- {
- /*no action*/
- }
- #endif
- if (ehciInstance->ehciFrameList == NULL)
- {
- OSA_MemoryFree(ehciInstance);
- return kStatus_USB_Error;
- }
- #if (USB_HOST_CONFIG_EHCI == 1U)
- usbHostEhciData[0] = &s_UsbHostEhciData1;
- #elif (USB_HOST_CONFIG_EHCI == 2U)
- usbHostEhciData[0] = &s_UsbHostEhciData1;
- usbHostEhciData[1] = &s_UsbHostEhciData2;
- #else
- #error "Please increase the instance count."
- #endif
- temp = (void *)usbHostEhciData[instanceIndex];
- ehciInstance->ehciUnitBase = (uint32_t *)(temp);
- /* initialize qh/qtd/itd/sitd/iso list */
- ehciInstance->ehciQhList = (usb_host_ehci_qh_t *)((uint32_t)(ehciInstance->ehciUnitBase));
- ehciInstance->ehciQtdHead = (usb_host_ehci_qtd_t *)((uint32_t)ehciInstance->ehciQhList +
- (sizeof(usb_host_ehci_qh_t) * USB_HOST_CONFIG_EHCI_MAX_QH));
- ehciInstance->ehciItdList = (usb_host_ehci_itd_t *)((uint32_t)ehciInstance->ehciQtdHead +
- (sizeof(usb_host_ehci_qtd_t) * USB_HOST_CONFIG_EHCI_MAX_QTD));
- #if ((defined(USB_HOST_CONFIG_EHCI_MAX_ITD)) && (USB_HOST_CONFIG_EHCI_MAX_ITD > 0U))
- /* If one ITD's first 32 bytes and next 32 bytes are in different 4K region,
- * the ITD need move 32 bytes because the ITD cannot cross over 4K boundary.
- */
- index = ((((((uint32_t)(ehciInstance->ehciItdList)) + 4095U) & 0xFFFFF000U) -
- ((uint32_t)(ehciInstance->ehciItdList))) >>
- 5U);
- if (((index / 3U) < USB_HOST_CONFIG_EHCI_MAX_ITD) && ((index % 3U) == 1U))
- {
- ehciInstance->ehciItdList = (usb_host_ehci_itd_t *)(((uint32_t)(ehciInstance->ehciItdList)) + 32U);
- }
- #endif
- ehciInstance->ehciSitdIndexBase =
- (usb_host_ehci_sitd_t *)((uint32_t)ehciInstance->ehciItdList +
- (sizeof(usb_host_ehci_itd_t) * USB_HOST_CONFIG_EHCI_MAX_ITD));
- ehciInstance->ehciSitdList = ehciInstance->ehciSitdIndexBase;
- ehciInstance->ehciIsoList = (usb_host_ehci_iso_t *)((uint32_t)ehciInstance->ehciSitdList +
- (sizeof(usb_host_ehci_sitd_t) * USB_HOST_CONFIG_EHCI_MAX_SITD));
- ehciInstance->ehciPipeIndexBase =
- (usb_host_ehci_pipe_t *)((uint32_t)ehciInstance->ehciIsoList +
- (sizeof(usb_host_ehci_iso_t) * USB_HOST_EHCI_ISO_NUMBER));
- for (index = 1U; index < USB_HOST_CONFIG_EHCI_MAX_QH; ++index)
- {
- ehciInstance->ehciQhList[index - 1U].horizontalLinkPointer = (uint32_t)(&ehciInstance->ehciQhList[index]);
- }
- ehciInstance->ehciQhList[USB_HOST_CONFIG_EHCI_MAX_QH - 1U].horizontalLinkPointer = 0U;
- for (index = 1; index < USB_HOST_CONFIG_EHCI_MAX_QTD; ++index)
- {
- ehciInstance->ehciQtdHead[index - 1U].nextQtdPointer = (uint32_t)(&ehciInstance->ehciQtdHead[index]);
- }
- ehciInstance->ehciQtdNumber = USB_HOST_CONFIG_EHCI_MAX_QTD;
- ehciInstance->ehciQtdHead[USB_HOST_CONFIG_EHCI_MAX_QTD - 1U].nextQtdPointer = 0U;
- ehciInstance->ehciQtdTail = &ehciInstance->ehciQtdHead[USB_HOST_CONFIG_EHCI_MAX_QTD - 1U];
- #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
- for (index = 1; index < USB_HOST_CONFIG_EHCI_MAX_ITD; ++index)
- {
- ehciInstance->ehciItdList[index - 1U].nextItdPointer =
- (usb_host_ehci_itd_t *)(&ehciInstance->ehciItdList[index]);
- }
- ehciInstance->ehciItdNumber = USB_HOST_CONFIG_EHCI_MAX_ITD;
- ehciInstance->ehciItdList[USB_HOST_CONFIG_EHCI_MAX_ITD - 1U].nextItdPointer = NULL;
- #endif /* USB_HOST_CONFIG_EHCI_MAX_ITD */
- #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
- for (index = 1; index < USB_HOST_CONFIG_EHCI_MAX_SITD; ++index)
- {
- ehciInstance->ehciSitdList[index - 1U].nextLinkPointer = (uint32_t)(&ehciInstance->ehciSitdList[index]);
- }
- ehciInstance->ehciSitdNumber = USB_HOST_CONFIG_EHCI_MAX_SITD;
- ehciInstance->ehciSitdList[USB_HOST_CONFIG_EHCI_MAX_SITD - 1U].nextLinkPointer = 0U;
- #endif /* USB_HOST_CONFIG_EHCI_MAX_SITD */
- #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
- for (index = 1; index < USB_HOST_EHCI_ISO_NUMBER; ++index)
- {
- ehciInstance->ehciIsoList[index - 1U].next = &ehciInstance->ehciIsoList[index];
- }
- ehciInstance->ehciIsoList[USB_HOST_EHCI_ISO_NUMBER - 1U].next = NULL;
- #endif
- /* initialize pipes */
- ehciInstance->ehciPipeList = ehciInstance->ehciPipeIndexBase;
- for (index = 1; index < USB_HOST_CONFIG_MAX_PIPES; ++index)
- {
- temp = (void *)&ehciInstance->ehciPipeList[index];
- ehciInstance->ehciPipeList[index - 1U].pipeCommon.next = (usb_host_pipe_t *)temp;
- }
- /* initialize mutext */
- ehciInstance->ehciMutex = (osa_mutex_handle_t)(&ehciInstance->mutexBuffer[0]);
- osaStatus = OSA_MutexCreate(ehciInstance->ehciMutex);
- if (osaStatus != KOSA_StatusSuccess)
- {
- #ifdef HOST_ECHO
- usb_echo("ehci mutex init fail\r\n");
- #endif
- OSA_MemoryFree(ehciInstance);
- return kStatus_USB_Error;
- }
- /* initialize task event */
- ehciInstance->taskEventHandle = (osa_event_handle_t)&ehciInstance->taskEventHandleBuffer[0];
- osaStatus = OSA_EventCreate(ehciInstance->taskEventHandle, 1);
- if (osaStatus != KOSA_StatusSuccess)
- {
- #ifdef HOST_ECHO
- usb_echo("ehci event init fail\r\n");
- #endif
- (void)OSA_MutexDestroy(ehciInstance->ehciMutex);
- OSA_MemoryFree(ehciInstance);
- return kStatus_USB_Error;
- }
- /* initialize first qh */
- ehciInstance->shedFirstQh = ehciInstance->ehciQhList;
- ehciInstance->ehciQhList =
- (usb_host_ehci_qh_t *)(ehciInstance->ehciQhList->horizontalLinkPointer & EHCI_HOST_POINTER_ADDRESS_MASK);
- ehciInstance->shedFirstQh->staticEndpointStates[0] |= (1UL << EHCI_HOST_QH_H_SHIFT); /* first qh */
- ehciInstance->shedFirstQh->horizontalLinkPointer = EHCI_HOST_T_INVALID_VALUE;
- ehciInstance->shedFirstQh->currentQtdPointer = EHCI_HOST_T_INVALID_VALUE;
- ehciInstance->shedFirstQh->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
- ehciInstance->shedFirstQh->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
- ehciInstance->shedFirstQh->horizontalLinkPointer =
- (uint32_t)((uint32_t)(ehciInstance->shedFirstQh) | EHCI_HOST_POINTER_TYPE_QH);
- /* initialize periodic list */
- temp = (void *)ehciInstance->ehciFrameList;
- framePointer = (uint32_t *)temp;
- for (index = 0; index < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE; ++index)
- {
- framePointer[index] = EHCI_HOST_T_INVALID_VALUE;
- }
- (void)USB_HostEhciStartIP(ehciInstance); /* start ehci ip */
- *controllerHandle = ehciInstance;
- return kStatus_USB_Success;
- }
- usb_status_t USB_HostEhciDestory(usb_host_controller_handle controllerHandle)
- {
- usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
- /* disable all interrupts */
- ehciInstance->ehciIpBase->USBINTR = 0;
- /* stop the controller */
- ehciInstance->ehciIpBase->USBCMD = 0;
- /* free memory */
- #if (USB_HOST_CONFIG_EHCI == 1U)
- if (ehciInstance->ehciFrameList == &s_UsbHostEhciFrameList1[0])
- {
- usbHostEhciFramListStatus[0] = 0;
- }
- #elif (USB_HOST_CONFIG_EHCI == 2U)
- if (ehciInstance->ehciFrameList == &s_UsbHostEhciFrameList1[0])
- {
- usbHostEhciFramListStatus[0] = 0;
- }
- else if (ehciInstance->ehciFrameList == &s_UsbHostEhciFrameList2[0])
- {
- usbHostEhciFramListStatus[1] = 0;
- }
- else
- {
- /*no action*/
- }
- #endif
- (void)OSA_MutexDestroy(ehciInstance->ehciMutex);
- (void)OSA_EventDestroy(ehciInstance->taskEventHandle);
- OSA_MemoryFree(ehciInstance);
- return kStatus_USB_Success;
- }
- usb_status_t USB_HostEhciOpenPipe(usb_host_controller_handle controllerHandle,
- usb_host_pipe_handle *pipeHandle,
- usb_host_pipe_init_t *pipeInit)
- {
- usb_host_ehci_pipe_t *ehciPipePointer = NULL;
- usb_status_t status;
- uint32_t speed = 0;
- usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
- void *temp;
- /* get one pipe */
- USB_HostEhciLock();
- if (ehciInstance->ehciPipeList != NULL)
- {
- ehciPipePointer = ehciInstance->ehciPipeList;
- temp = (void *)ehciPipePointer->pipeCommon.next;
- ehciInstance->ehciPipeList = (usb_host_ehci_pipe_t *)temp;
- }
- USB_HostEhciUnlock();
- if (ehciPipePointer == NULL)
- {
- #ifdef HOST_ECHO
- usb_echo("ehci open pipe failed\r\n");
- #endif
- return kStatus_USB_Busy;
- }
- /* initialize pipe informations */
- USB_HostEhciZeroMem((void *)ehciPipePointer, sizeof(usb_host_ehci_pipe_t) / 4U);
- ehciPipePointer->pipeCommon.deviceHandle = pipeInit->devInstance;
- ehciPipePointer->pipeCommon.endpointAddress = pipeInit->endpointAddress;
- ehciPipePointer->pipeCommon.direction = pipeInit->direction;
- ehciPipePointer->pipeCommon.interval = pipeInit->interval;
- ehciPipePointer->pipeCommon.maxPacketSize = pipeInit->maxPacketSize;
- ehciPipePointer->pipeCommon.pipeType = pipeInit->pipeType;
- ehciPipePointer->pipeCommon.numberPerUframe = pipeInit->numberPerUframe + 1U;
- if (ehciPipePointer->pipeCommon.numberPerUframe > 3U)
- {
- ehciPipePointer->pipeCommon.numberPerUframe = 3U;
- }
- ehciPipePointer->pipeCommon.nakCount = pipeInit->nakCount;
- ehciPipePointer->pipeCommon.nextdata01 = 0U;
- ehciPipePointer->ehciQh = NULL;
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
- if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
- (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT))
- {
- if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS)
- {
- ehciPipePointer->pipeCommon.interval =
- (uint16_t)(1UL << (ehciPipePointer->pipeCommon.interval - 1U)); /* iso interval is the power of 2 */
- }
- else
- {
- if (speed == USB_SPEED_HIGH)
- {
- ehciPipePointer->pipeCommon.interval = (uint16_t)(
- 1UL << (ehciPipePointer->pipeCommon.interval - 1U)); /* HS interrupt interval is the power of 2 */
- }
- else
- {
- ehciPipePointer->pipeCommon.interval = USB_HostEhciGet2PowerValue(
- (uint8_t)ehciPipePointer->pipeCommon.interval); /* FS/LS interrupt interval should be the power of
- 2, it is used for ehci bandwidth */
- }
- }
- }
- /* save the micro-frame interval, it is convenient for the interval process */
- if (speed == USB_SPEED_HIGH)
- {
- ehciPipePointer->uframeInterval = ehciPipePointer->pipeCommon.interval;
- }
- else
- {
- ehciPipePointer->uframeInterval = 8U * ehciPipePointer->pipeCommon.interval;
- }
- /* open pipe */
- switch (ehciPipePointer->pipeCommon.pipeType)
- {
- case USB_ENDPOINT_CONTROL:
- case USB_ENDPOINT_BULK:
- status = USB_HostEhciOpenControlBulk(ehciInstance, ehciPipePointer);
- break;
- #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
- ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
- case USB_ENDPOINT_ISOCHRONOUS:
- status = USB_HostEhciOpenIso(ehciInstance, ehciPipePointer);
- break;
- #endif
- case USB_ENDPOINT_INTERRUPT:
- status = USB_HostEhciOpenInterrupt(ehciInstance, ehciPipePointer);
- break;
- default:
- status = kStatus_USB_Error;
- break;
- }
- if (status != kStatus_USB_Success)
- {
- /* release pipe */
- USB_HostEhciLock();
- temp = (void *)ehciInstance->ehciPipeList;
- ehciPipePointer->pipeCommon.next = (usb_host_pipe_t *)temp;
- ehciInstance->ehciPipeList = ehciPipePointer;
- USB_HostEhciUnlock();
- return status;
- }
- /* add pipe to run pipe list */
- USB_HostEhciLock();
- temp = (void *)ehciInstance->ehciRunningPipeList;
- ehciPipePointer->pipeCommon.next = (usb_host_pipe_t *)temp;
- ehciInstance->ehciRunningPipeList = ehciPipePointer;
- USB_HostEhciUnlock();
- *pipeHandle = ehciPipePointer;
- return status;
- }
- usb_status_t USB_HostEhciClosePipe(usb_host_controller_handle controllerHandle, usb_host_pipe_handle pipeHandle)
- {
- usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
- usb_host_ehci_pipe_t *ehciPipePointer = (usb_host_ehci_pipe_t *)pipeHandle;
- usb_host_pipe_t *prevPointer = NULL;
- void *temp;
- void *tempCurrent;
- switch (ehciPipePointer->pipeCommon.pipeType)
- {
- case USB_ENDPOINT_BULK:
- case USB_ENDPOINT_CONTROL:
- (void)USB_HostEhciCloseControlBulk(ehciInstance, ehciPipePointer);
- break;
- case USB_ENDPOINT_INTERRUPT:
- (void)USB_HostEhciCloseInterrupt(ehciInstance, ehciPipePointer);
- break;
- #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
- ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
- case USB_ENDPOINT_ISOCHRONOUS:
- (void)USB_HostEhciCloseIso(ehciInstance, ehciPipePointer);
- break;
- #endif
- default:
- /*no action*/
- break;
- }
- /* delete pipe from run pipe list */
- USB_HostEhciLock();
- temp = (void *)ehciInstance->ehciRunningPipeList;
- prevPointer = (usb_host_pipe_t *)temp;
- tempCurrent = (void *)ehciPipePointer;
- if (prevPointer == (usb_host_pipe_t *)tempCurrent)
- {
- temp = (void *)prevPointer->next;
- ehciInstance->ehciRunningPipeList = (usb_host_ehci_pipe_t *)(temp);
- }
- else
- {
- while (prevPointer != NULL)
- {
- temp = (void *)ehciPipePointer;
- if (prevPointer->next == (usb_host_pipe_t *)temp)
- {
- prevPointer->next = ehciPipePointer->pipeCommon.next;
- break;
- }
- else
- {
- prevPointer = prevPointer->next;
- }
- }
- }
- USB_HostEhciUnlock();
- /* release pipe */
- USB_HostEhciLock();
- temp = (void *)ehciInstance->ehciPipeList;
- ehciPipePointer->pipeCommon.next = (usb_host_pipe_t *)temp;
- ehciInstance->ehciPipeList = ehciPipePointer;
- USB_HostEhciUnlock();
- return kStatus_USB_Success;
- }
- usb_status_t USB_HostEhciWritePipe(usb_host_controller_handle controllerHandle,
- usb_host_pipe_handle pipeHandle,
- usb_host_transfer_t *transfer)
- {
- usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
- usb_host_ehci_pipe_t *ehciPipePointer = (usb_host_ehci_pipe_t *)pipeHandle;
- usb_status_t status = kStatus_USB_Success;
- #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
- ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
- uint32_t speed = 0U;
- #endif
- switch (ehciPipePointer->pipeCommon.pipeType)
- {
- case USB_ENDPOINT_BULK:
- case USB_ENDPOINT_CONTROL:
- case USB_ENDPOINT_INTERRUPT:
- status = USB_HostEhciQhQtdListInit(ehciInstance, ehciPipePointer,
- transfer); /* initialize qtd for control/bulk transfer */
- break;
- #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
- ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
- case USB_ENDPOINT_ISOCHRONOUS:
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
- if (speed == USB_SPEED_HIGH)
- {
- #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
- status = USB_HostEhciItdArrayInit(ehciInstance, ehciPipePointer,
- transfer); /* initialize itd for iso transfer */
- #endif
- }
- else
- {
- #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
- status = USB_HostEhciSitdArrayInit(ehciInstance, ehciPipePointer,
- transfer); /* initialize sitd for iso transfer */
- #endif
- }
- break;
- #endif
- default:
- /*no action*/
- break;
- }
- return status;
- }
- usb_status_t USB_HostEhciReadpipe(usb_host_controller_handle controllerHandle,
- usb_host_pipe_handle pipeHandle,
- usb_host_transfer_t *transfer)
- {
- return USB_HostEhciWritePipe(controllerHandle, pipeHandle, transfer); /* same as write */
- }
- usb_status_t USB_HostEhciIoctl(usb_host_controller_handle controllerHandle, uint32_t ioctlEvent, void *ioctlParam)
- {
- usb_status_t status = kStatus_USB_Success;
- usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
- usb_host_cancel_param_t *param;
- usb_host_ehci_pipe_t *ehciPipePointer;
- volatile usb_host_ehci_qh_t *vltQhPointer;
- uint32_t deviceAddress = 0;
- usb_host_controller_control_t controlCode = (usb_host_controller_control_t)ioctlEvent;
- if (controllerHandle == NULL)
- {
- return kStatus_USB_InvalidHandle;
- }
- switch (controlCode)
- {
- case kUSB_HostCancelTransfer: /* cancel pipe or one transfer */
- param = (usb_host_cancel_param_t *)ioctlParam;
- status = USB_HostEhciCancelPipe(ehciInstance, (usb_host_ehci_pipe_t *)param->pipeHandle, param->transfer);
- break;
- case kUSB_HostBusControl: /* bus control */
- status = USB_HostEhciControlBus(ehciInstance, *((uint8_t *)ioctlParam));
- break;
- case kUSB_HostGetFrameNumber: /* get frame number */
- *((uint32_t *)ioctlParam) = ((ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE) >> 3);
- break;
- case kUSB_HostUpdateControlEndpointAddress:
- ehciPipePointer = (usb_host_ehci_pipe_t *)ioctlParam;
- vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
- /* update address */
- (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
- (uint32_t)kUSB_HostGetDeviceAddress, &deviceAddress);
- vltQhPointer->staticEndpointStates[0] |= deviceAddress;
- USB_HostEhciDelay(ehciInstance->ehciIpBase, 2U);
- break;
- case kUSB_HostUpdateControlPacketSize:
- ehciPipePointer = (usb_host_ehci_pipe_t *)ioctlParam;
- vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
- USB_HostEhciLock();
- if (0U != (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK))
- {
- USB_HostEhciStopAsync(ehciInstance);
- /* update max packet size */
- vltQhPointer->staticEndpointStates[0] =
- (((vltQhPointer->staticEndpointStates[0]) & (~EHCI_HOST_QH_MAX_PACKET_LENGTH_MASK)) |
- ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT));
- USB_HostEhciStartAsync(ehciInstance);
- }
- else
- {
- /* update max packet size */
- vltQhPointer->staticEndpointStates[0] =
- (((vltQhPointer->staticEndpointStates[0]) & (~EHCI_HOST_QH_MAX_PACKET_LENGTH_MASK)) |
- ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT));
- }
- USB_HostEhciUnlock();
- break;
- #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
- case kUSB_HostTestModeInit: /* test mode control */
- USB_HostEhciTestModeInit((usb_host_device_instance_t *)ioctlParam);
- break;
- #endif
- default:
- status = kStatus_USB_NotSupported;
- break;
- }
- return status;
- }
- void USB_HostEhciTaskFunction(void *hostHandle)
- {
- usb_host_ehci_instance_t *ehciInstance;
- uint32_t bitSet;
- usb_device_handle deviceHandle;
- if (hostHandle == NULL)
- {
- return;
- }
- ehciInstance = (usb_host_ehci_instance_t *)((usb_host_instance_t *)hostHandle)->controllerHandle;
- if (OSA_EventWait(ehciInstance->taskEventHandle, 0xFF, 0, USB_OSA_WAIT_TIMEOUT, &bitSet) ==
- KOSA_StatusSuccess) /* wait all event */
- {
- if (0U != (bitSet & EHCI_TASK_EVENT_PORT_CHANGE)) /* port change */
- {
- USB_HostEhciPortChange(ehciInstance);
- }
- if (0U != (bitSet & EHCI_TASK_EVENT_TIMER0)) /* timer0 */
- {
- USB_HostEhciTimer0(ehciInstance);
- }
- #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
- if (0U != (bitSet & EHCI_TASK_EVENT_TIMER1)) /* timer1 */
- {
- USB_HostEhciTimer1(ehciInstance);
- }
- #endif
- if ((ehciInstance->deviceAttached == (uint8_t)kEHCIDeviceAttached))
- {
- if (0U != (bitSet & EHCI_TASK_EVENT_TRANSACTION_DONE)) /* transaction done */
- {
- USB_HostEhciTransactionDone(ehciInstance);
- }
- if (0U != (bitSet & EHCI_TASK_EVENT_DEVICE_DETACH)) /* device detach */
- {
- ehciInstance->ehciIpBase->USBINTR &=
- (~USBHS_USBINTR_PCE_MASK); /* disable attach, enable when the detach process is done */
- ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceDetached;
- (void)USB_HostDetachDevice(ehciInstance->hostHandle, 0, 0);
- }
- }
- else if (ehciInstance->deviceAttached != (uint8_t)kEHCIDeviceAttached)
- {
- if (0U != (bitSet & EHCI_TASK_EVENT_DEVICE_ATTACH)) /* device is attached */
- {
- USB_HostEhciStartAsync(ehciInstance);
- USB_HostEhciStartPeriodic(ehciInstance);
- if (USB_HostAttachDevice(ehciInstance->hostHandle, ehciInstance->firstDeviceSpeed, 0, 0, 1,
- &deviceHandle) == kStatus_USB_Success)
- {
- ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceAttached;
- }
- }
- }
- else
- {
- /*no action*/
- }
- }
- }
- void USB_HostEhciIsrFunction(void *hostHandle)
- {
- usb_host_ehci_instance_t *ehciInstance;
- static uint32_t interruptStatus = 0;
- if (hostHandle == NULL)
- {
- return;
- }
- ehciInstance = (usb_host_ehci_instance_t *)((usb_host_instance_t *)hostHandle)->controllerHandle;
- #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
- #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
- if (0U != (ehciInstance->registerNcBase->USB_OTGn_CTRL & USBNC_USB_OTGn_CTRL_WIE_MASK))
- {
- usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
- ehciInstance->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK;
- (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
- kUSB_HostEventDetectResume); /* call host callback function */
- #if (defined(USBNC_USB_OTGn_PHY_CTRL_0_UTMI_CLK_VLD_MASK))
- while (0U == (ehciInstance->registerNcBase->USB_OTGn_PHY_CTRL_0 & USBNC_USB_OTGn_PHY_CTRL_0_UTMI_CLK_VLD_MASK))
- {
- }
- #endif
- if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
- {
- USB_HostEhciStartAsync(ehciInstance);
- USB_HostEhciStartPeriodic(ehciInstance);
- }
- ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK);
- if ((kBus_EhciSuspended == ehciInstance->busSuspendStatus))
- {
- /* ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_FPR_MASK; */
- ehciInstance->busSuspendStatus = kBus_EhciStartResume;
- }
- else
- {
- /*no action*/
- }
- }
- else
- {
- /*no action*/
- }
- #else
- #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
- #else
- if (0U != (ehciInstance->ehciIpBase->USBGENCTRL & USBHS_USBGENCTRL_WU_IE_MASK))
- {
- usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
- (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
- kUSB_HostEventDetectResume); /* call host callback function */
- while (0U == (USBPHY->PLL_SIC & USBPHY_PLL_SIC_PLL_LOCK_MASK))
- {
- }
- ehciInstance->ehciIpBase->USBGENCTRL |= USBHS_USBGENCTRL_WU_INT_CLR_MASK;
- ehciInstance->ehciIpBase->USBGENCTRL &= ~USBHS_USBGENCTRL_WU_IE_MASK;
- if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
- {
- USB_HostEhciStartAsync(ehciInstance);
- USB_HostEhciStartPeriodic(ehciInstance);
- }
- ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK);
- if ((kBus_EhciSuspended == ehciInstance->busSuspendStatus))
- {
- ehciInstance->busSuspendStatus = kBus_EhciStartResume;
- /*ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_FPR_MASK; */
- }
- else
- {
- /*no action*/
- }
- }
- else
- {
- /*no action*/
- }
- #endif /* FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT */
- #endif /* FSL_FEATURE_SOC_USBNC_COUNT */
- #endif /* USB_HOST_CONFIG_LOW_POWER_MODE */
- interruptStatus = ehciInstance->ehciIpBase->USBSTS;
- interruptStatus &= ehciInstance->ehciIpBase->USBINTR;
- while (0U != interruptStatus) /* there are usb interrupts */
- {
- ehciInstance->ehciIpBase->USBSTS = interruptStatus; /* clear interrupt */
- if (0U != (interruptStatus & USBHS_USBSTS_SRI_MASK)) /* SOF interrupt */
- {
- }
- if (0U != (interruptStatus & USBHS_USBSTS_SEI_MASK)) /* system error interrupt */
- {
- }
- if ((0U != (interruptStatus & USBHS_USBSTS_UI_MASK)) ||
- (0U != (interruptStatus & USBHS_USBSTS_UEI_MASK))) /* USB interrupt or USB error interrupt */
- {
- (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_TRANSACTION_DONE);
- }
- if (0U != (interruptStatus & USBHS_USBSTS_PCI_MASK)) /* port change detect interrupt */
- {
- #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
- usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
- if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_FPR_MASK))
- {
- if (kBus_EhciStartSuspend == ehciInstance->busSuspendStatus)
- {
- if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
- {
- USB_HostEhciStartAsync(ehciInstance);
- USB_HostEhciStartPeriodic(ehciInstance);
- }
- (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
- kUSB_HostEventNotSuspended); /* call host callback function */
- hostPointer->suspendedDevice = NULL;
- ehciInstance->busSuspendStatus = kBus_EhciIdle;
- ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
- }
- else
- {
- /*no action */
- }
- }
- #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
- if ((kBus_EhciSuspended == ehciInstance->busSuspendStatus))
- {
- usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
- (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
- kUSB_HostEventDetectResume); /* call host callback function */
- uint32_t delay = 100000;
- while (delay-- && !(USBOTG->PLL_CONTROL_0 & USBC_PLL_CONTROL_0_PLL_READY_MASK))
- {
- }
- if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
- {
- USB_HostEhciStartAsync(ehciInstance);
- USB_HostEhciStartPeriodic(ehciInstance);
- }
- ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK);
- ehciInstance->busSuspendStatus = kBus_EhciStartResume;
- }
- #endif
- #endif
- (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_PORT_CHANGE);
- }
- if (0U != (interruptStatus & USBHS_USBSTS_TI0_MASK)) /* timer 0 interrupt */
- {
- (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_TIMER0);
- }
- #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
- if (0U != (interruptStatus & USBHS_USBSTS_TI1_MASK)) /* timer 1 interrupt */
- {
- (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_TIMER1);
- }
- #endif
- interruptStatus = ehciInstance->ehciIpBase->USBSTS;
- interruptStatus &= ehciInstance->ehciIpBase->USBINTR;
- }
- }
- #endif /* USB_HOST_CONFIG_EHCI */
|