rfal_rfst25r3916.c 199 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857
  1. /******************************************************************************
  2. * \attention
  3. *
  4. * <h2><center>&copy; COPYRIGHT 2020 STMicroelectronics</center></h2>
  5. *
  6. * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
  7. * You may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at:
  9. *
  10. * www.st.com/myliberty
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
  15. * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
  17. * See the License for the specific language governing permissions and
  18. * limitations under the License.
  19. *
  20. ******************************************************************************/
  21. /*
  22. * PROJECT: ST25R3916 firmware
  23. * Revision:
  24. * LANGUAGE: ISO C99
  25. */
  26. /*! \file
  27. *
  28. * \author Gustavo Patricio
  29. *
  30. * \brief RF Abstraction Layer (RFAL)
  31. *
  32. * RFAL implementation for ST25R3916
  33. */
  34. /*
  35. ******************************************************************************
  36. * INCLUDES
  37. ******************************************************************************
  38. */
  39. #include "../../include/rfal_chip.h"
  40. #include "../../utils.h"
  41. #include "st25r3916.h"
  42. #include "st25r3916_com.h"
  43. #include "st25r3916_irq.h"
  44. #include "../../include/rfal_analogConfig.h"
  45. #include "../../include/rfal_iso15693_2.h"
  46. #include "../../include/rfal_crc.h"
  47. /*
  48. ******************************************************************************
  49. * ENABLE SWITCHES
  50. ******************************************************************************
  51. */
  52. #ifndef RFAL_FEATURE_LISTEN_MODE
  53. #define RFAL_FEATURE_LISTEN_MODE false /* Listen Mode configuration missing. Disabled by default */
  54. #endif /* RFAL_FEATURE_LISTEN_MODE */
  55. #ifndef RFAL_FEATURE_WAKEUP_MODE
  56. #define RFAL_FEATURE_WAKEUP_MODE \
  57. false /* Wake-Up mode configuration missing. Disabled by default */
  58. #endif /* RFAL_FEATURE_WAKEUP_MODE */
  59. #ifndef RFAL_FEATURE_LOWPOWER_MODE
  60. #define RFAL_FEATURE_LOWPOWER_MODE \
  61. false /* Low Power mode configuration missing. Disabled by default */
  62. #endif /* RFAL_FEATURE_LOWPOWER_MODE */
  63. /*
  64. ******************************************************************************
  65. * GLOBAL TYPES
  66. ******************************************************************************
  67. */
  68. /*! Struct that holds all involved on a Transceive including the context passed by the caller */
  69. typedef struct {
  70. rfalTransceiveState state; /*!< Current transceive state */
  71. rfalTransceiveState lastState; /*!< Last transceive state (debug purposes) */
  72. ReturnCode status; /*!< Current status/error of the transceive */
  73. rfalTransceiveContext ctx; /*!< The transceive context given by the caller */
  74. } rfalTxRx;
  75. /*! Struct that holds all context for the Listen Mode */
  76. typedef struct {
  77. rfalLmState state; /*!< Current Listen Mode state */
  78. uint32_t mdMask; /*!< Listen Mode mask used */
  79. uint32_t mdReg; /*!< Listen Mode register value used */
  80. uint32_t mdIrqs; /*!< Listen Mode IRQs used */
  81. rfalBitRate brDetected; /*!< Last bit rate detected */
  82. uint8_t* rxBuf; /*!< Location to store incoming data in Listen Mode */
  83. uint16_t rxBufLen; /*!< Length of rxBuf */
  84. uint16_t* rxLen; /*!< Pointer to write the data length placed into rxBuf */
  85. bool dataFlag; /*!< Listen Mode current Data Flag */
  86. bool iniFlag; /*!< Listen Mode initialized Flag (FeliCa slots) */
  87. } rfalLm;
  88. /*! Struct that holds all context for the Wake-Up Mode */
  89. typedef struct {
  90. rfalWumState state; /*!< Current Wake-Up Mode state */
  91. rfalWakeUpConfig cfg; /*!< Current Wake-Up Mode context */
  92. } rfalWum;
  93. /*! Struct that holds all context for the Low Power Mode */
  94. typedef struct {
  95. bool isRunning;
  96. } rfalLpm;
  97. /*! Struct that holds the timings GT and FDTs */
  98. typedef struct {
  99. uint32_t GT; /*!< GT in 1/fc */
  100. uint32_t FDTListen; /*!< FDTListen in 1/fc */
  101. uint32_t FDTPoll; /*!< FDTPoll in 1/fc */
  102. uint8_t nTRFW; /*!< n*TRFW used during RF CA */
  103. } rfalTimings;
  104. /*! Struct that holds the software timers */
  105. typedef struct {
  106. uint32_t GT; /*!< RFAL's GT timer */
  107. uint32_t RXE; /*!< Timer between RXS and RXE */
  108. uint32_t txRx; /*!< Transceive sanity timer */
  109. } rfalTimers;
  110. /*! Struct that holds the RFAL's callbacks */
  111. typedef struct {
  112. rfalPreTxRxCallback preTxRx; /*!< RFAL's Pre TxRx callback */
  113. rfalPostTxRxCallback postTxRx; /*!< RFAL's Post TxRx callback */
  114. RfalStateChangedCallback state_changed_cb;
  115. void* ctx;
  116. } rfalCallbacks;
  117. /*! Struct that holds counters to control the FIFO on Tx and Rx */
  118. typedef struct {
  119. uint16_t
  120. expWL; /*!< The amount of bytes expected to be Tx when a WL interrupt occurs */
  121. uint16_t
  122. bytesTotal; /*!< Total bytes to be transmitted OR the total bytes received */
  123. uint16_t
  124. bytesWritten; /*!< Amount of bytes already written on FIFO (Tx) OR read (RX) from FIFO and written on rxBuffer*/
  125. uint8_t status
  126. [ST25R3916_FIFO_STATUS_LEN]; /*!< FIFO Status Registers */
  127. } rfalFIFO;
  128. /*! Struct that holds RFAL's configuration settings */
  129. typedef struct {
  130. uint8_t obsvModeTx; /*!< RFAL's config of the ST25R3916's observation mode while Tx */
  131. uint8_t obsvModeRx; /*!< RFAL's config of the ST25R3916's observation mode while Rx */
  132. rfalEHandling eHandling; /*!< RFAL's error handling config/mode */
  133. } rfalConfigs;
  134. /*! Struct that holds NFC-F data - Used only inside rfalFelicaPoll() (static to avoid adding it into stack) */
  135. typedef struct {
  136. rfalFeliCaPollRes
  137. pollResponses[RFAL_FELICA_POLL_MAX_SLOTS]; /* FeliCa Poll response container for 16 slots */
  138. } rfalNfcfWorkingData;
  139. /*! Struct that holds NFC-V current context
  140. *
  141. * This buffer has to be big enough for coping with maximum response size (hamming coded)
  142. * - inventory requests responses: 14*2+2 bytes
  143. * - read single block responses: (32+4)*2+2 bytes
  144. * - read multiple block could be very long... -> not supported
  145. * - current implementation expects it be written in one bulk into FIFO
  146. * - needs to be above FIFO water level of ST25R3916 (200)
  147. * - the coding function needs to be able to
  148. * put more than FIFO water level bytes into it (n*64+1)>200 */
  149. typedef struct {
  150. uint8_t codingBuffer[(
  151. (2 + 255 + 3) * 2)]; /*!< Coding buffer, length MUST be above 257: [257; ...] */
  152. uint16_t
  153. nfcvOffset; /*!< Offset needed for ISO15693 coding function */
  154. rfalTransceiveContext
  155. origCtx; /*!< context provided by user */
  156. uint16_t
  157. ignoreBits; /*!< Number of bits at the beginning of a frame to be ignored when decoding */
  158. } rfalNfcvWorkingData;
  159. /*! RFAL instance */
  160. typedef struct {
  161. rfalState state; /*!< RFAL's current state */
  162. rfalMode mode; /*!< RFAL's current mode */
  163. rfalBitRate txBR; /*!< RFAL's current Tx Bit Rate */
  164. rfalBitRate rxBR; /*!< RFAL's current Rx Bit Rate */
  165. bool field; /*!< Current field state (On / Off) */
  166. rfalConfigs conf; /*!< RFAL's configuration settings */
  167. rfalTimings timings; /*!< RFAL's timing setting */
  168. rfalTxRx TxRx; /*!< RFAL's transceive management */
  169. rfalFIFO fifo; /*!< RFAL's FIFO management */
  170. rfalTimers tmr; /*!< RFAL's Software timers */
  171. rfalCallbacks callbacks; /*!< RFAL's callbacks */
  172. #if RFAL_FEATURE_LISTEN_MODE
  173. rfalLm Lm; /*!< RFAL's listen mode management */
  174. #endif /* RFAL_FEATURE_LISTEN_MODE */
  175. #if RFAL_FEATURE_WAKEUP_MODE
  176. rfalWum wum; /*!< RFAL's Wake-up mode management */
  177. #endif /* RFAL_FEATURE_WAKEUP_MODE */
  178. #if RFAL_FEATURE_LOWPOWER_MODE
  179. rfalLpm lpm; /*!< RFAL's Low power mode management */
  180. #endif /* RFAL_FEATURE_LOWPOWER_MODE */
  181. #if RFAL_FEATURE_NFCF
  182. rfalNfcfWorkingData nfcfData; /*!< RFAL's working data when supporting NFC-F */
  183. #endif /* RFAL_FEATURE_NFCF */
  184. #if RFAL_FEATURE_NFCV
  185. rfalNfcvWorkingData nfcvData; /*!< RFAL's working data when performing NFC-V */
  186. #endif /* RFAL_FEATURE_NFCV */
  187. } rfal;
  188. /*! Felica's command set */
  189. typedef enum {
  190. FELICA_CMD_POLLING =
  191. 0x00, /*!< Felica Poll/REQC command (aka SENSF_REQ) to identify a card */
  192. FELICA_CMD_POLLING_RES =
  193. 0x01, /*!< Felica Poll/REQC command (aka SENSF_RES) response */
  194. FELICA_CMD_REQUEST_SERVICE =
  195. 0x02, /*!< verify the existence of Area and Service */
  196. FELICA_CMD_REQUEST_RESPONSE =
  197. 0x04, /*!< verify the existence of a card */
  198. FELICA_CMD_READ_WITHOUT_ENCRYPTION =
  199. 0x06, /*!< read Block Data from a Service that requires no authentication */
  200. FELICA_CMD_WRITE_WITHOUT_ENCRYPTION =
  201. 0x08, /*!< write Block Data to a Service that requires no authentication */
  202. FELICA_CMD_REQUEST_SYSTEM_CODE =
  203. 0x0C, /*!< acquire the System Code registered to a card */
  204. FELICA_CMD_AUTHENTICATION1 =
  205. 0x10, /*!< authenticate a card */
  206. FELICA_CMD_AUTHENTICATION2 =
  207. 0x12, /*!< allow a card to authenticate a Reader/Writer */
  208. FELICA_CMD_READ = 0x14, /*!< read Block Data from a Service that requires authentication */
  209. FELICA_CMD_WRITE = 0x16, /*!< write Block Data to a Service that requires authentication */
  210. } t_rfalFeliCaCmd;
  211. /*! Union representing all PTMem sections */
  212. typedef union { /* PRQA S 0750 # MISRA 19.2 - Both members are of the same type, just different names. Thus no problem can occur. */
  213. uint8_t PTMem_A
  214. [ST25R3916_PTM_A_LEN]; /*!< PT_Memory area allocated for NFC-A configuration */
  215. uint8_t PTMem_F
  216. [ST25R3916_PTM_F_LEN]; /*!< PT_Memory area allocated for NFC-F configuration */
  217. uint8_t
  218. TSN[ST25R3916_PTM_TSN_LEN]; /*!< PT_Memory area allocated for TSN - Random numbers */
  219. } t_rfalPTMem;
  220. /*
  221. ******************************************************************************
  222. * GLOBAL DEFINES
  223. ******************************************************************************
  224. */
  225. #define RFAL_FIFO_IN_WL \
  226. 200U /*!< Number of bytes in the FIFO when WL interrupt occurs while Tx */
  227. #define RFAL_FIFO_OUT_WL \
  228. (ST25R3916_FIFO_DEPTH - \
  229. RFAL_FIFO_IN_WL) /*!< Number of bytes sent/out of the FIFO when WL interrupt occurs while Tx */
  230. #define RFAL_FIFO_STATUS_REG1 \
  231. 0U /*!< Location of FIFO status register 1 in local copy */
  232. #define RFAL_FIFO_STATUS_REG2 \
  233. 1U /*!< Location of FIFO status register 2 in local copy */
  234. #define RFAL_FIFO_STATUS_INVALID \
  235. 0xFFU /*!< Value indicating that the local FIFO status in invalid|cleared */
  236. #define RFAL_ST25R3916_GPT_MAX_1FC \
  237. rfalConv8fcTo1fc( \
  238. 0xFFFFU) /*!< Max GPT steps in 1fc (0xFFFF steps of 8/fc => 0xFFFF * 590ns = 38,7ms) */
  239. #define RFAL_ST25R3916_NRT_MAX_1FC \
  240. rfalConv4096fcTo1fc( \
  241. 0xFFFFU) /*!< Max NRT steps in 1fc (0xFFFF steps of 4096/fc => 0xFFFF * 302us = 19.8s ) */
  242. #define RFAL_ST25R3916_NRT_DISABLED \
  243. 0U /*!< NRT Disabled: All 0 No-response timer is not started, wait forever */
  244. #define RFAL_ST25R3916_MRT_MAX_1FC \
  245. rfalConv64fcTo1fc( \
  246. 0x00FFU) /*!< Max MRT steps in 1fc (0x00FF steps of 64/fc => 0x00FF * 4.72us = 1.2ms ) */
  247. #define RFAL_ST25R3916_MRT_MIN_1FC \
  248. rfalConv64fcTo1fc( \
  249. 0x0004U) /*!< Min MRT steps in 1fc ( 0<=mrt<=4 ; 4 (64/fc) => 0x0004 * 4.72us = 18.88us ) */
  250. #define RFAL_ST25R3916_GT_MAX_1FC \
  251. rfalConvMsTo1fc( \
  252. 6000U) /*!< Max GT value allowed in 1/fc (SFGI=14 => SFGT + dSFGT = 5.4s) */
  253. #define RFAL_ST25R3916_GT_MIN_1FC \
  254. rfalConvMsTo1fc( \
  255. RFAL_ST25R3916_SW_TMR_MIN_1MS) /*!< Min GT value allowed in 1/fc */
  256. #define RFAL_ST25R3916_SW_TMR_MIN_1MS \
  257. 1U /*!< Min value of a SW timer in ms */
  258. #define RFAL_OBSMODE_DISABLE \
  259. 0x00U /*!< Observation Mode disabled */
  260. #define RFAL_RX_INCOMPLETE_MAXLEN \
  261. (uint8_t)1U /*!< Threshold value where incoming rx may be considered as incomplete */
  262. #define RFAL_EMVCO_RX_MAXLEN \
  263. (uint8_t)4U /*!< Maximum value where EMVCo to apply special error handling */
  264. #define RFAL_NORXE_TOUT \
  265. 50U /*!< Timeout to be used on a potential missing RXE - Silicon ST25R3916 Errata #TBD */
  266. #define RFAL_ISO14443A_SDD_RES_LEN \
  267. 5U /*!< SDD_RES | Anticollision (UID CLn) length - rfalNfcaSddRes */
  268. #define RFAL_ISO14443A_CRC_INTVAL \
  269. 0x6363 /*!< ISO14443 CRC Initial Value|Register */
  270. #define RFAL_FELICA_POLL_DELAY_TIME \
  271. 512U /*!< FeliCa Poll Processing time is 2.417 ms ~512*64/fc Digital 1.1 A4 */
  272. #define RFAL_FELICA_POLL_SLOT_TIME \
  273. 256U /*!< FeliCa Poll Time Slot duration is 1.208 ms ~256*64/fc Digital 1.1 A4 */
  274. #define RFAL_LM_SENSF_RD0_POS \
  275. 17U /*!< FeliCa SENSF_RES Request Data RD0 position */
  276. #define RFAL_LM_SENSF_RD1_POS \
  277. 18U /*!< FeliCa SENSF_RES Request Data RD1 position */
  278. #define RFAL_LM_NFCID_INCOMPLETE \
  279. 0x04U /*!< NFCA NFCID not complete bit in SEL_RES (SAK) */
  280. #define RFAL_ISO15693_IGNORE_BITS \
  281. rfalConvBytesToBits( \
  282. 2U) /*!< Ignore collisions before the UID (RES_FLAG + DSFID) */
  283. #define RFAL_ISO15693_INV_RES_LEN \
  284. 12U /*!< ISO15693 Inventory response length with CRC (bytes) */
  285. #define RFAL_ISO15693_INV_RES_DUR \
  286. 4U /*!< ISO15693 Inventory response duration @ 26 kbps (ms) */
  287. #define RFAL_WU_MIN_WEIGHT_VAL \
  288. 4U /*!< ST25R3916 minimum Wake-up weight value */
  289. /*******************************************************************************/
  290. #define RFAL_LM_GT \
  291. rfalConvUsTo1fc( \
  292. 100U) /*!< Listen Mode Guard Time enforced (GT - Passive; TIRFG - Active) */
  293. #define RFAL_FDT_POLL_ADJUSTMENT \
  294. rfalConvUsTo1fc( \
  295. 80U) /*!< FDT Poll adjustment: Time between the expiration of GPT to the actual Tx */
  296. #define RFAL_FDT_LISTEN_MRT_ADJUSTMENT \
  297. 64U /*!< MRT jitter adjustment: timeout will be between [ tout ; tout + 64 cycles ] */
  298. #define RFAL_AP2P_FIELDOFF_TRFW \
  299. rfalConv8fcTo1fc( \
  300. 64U) /*!< Time after TXE and Field Off in AP2P Trfw: 37.76us -> 64 (8/fc) */
  301. #ifndef RFAL_ST25R3916_AAT_SETTLE
  302. #define RFAL_ST25R3916_AAT_SETTLE \
  303. 5U /*!< Time in ms required for AAT pins and Osc to settle after en bit set */
  304. #endif /* RFAL_ST25R3916_AAT_SETTLE */
  305. /*! FWT adjustment:
  306. * 64 : NRT jitter between TXE and NRT start */
  307. #define RFAL_FWT_ADJUSTMENT 64U
  308. /*! FWT ISO14443A adjustment:
  309. * 512 : 4bit length
  310. * 64 : Half a bit duration due to ST25R3916 Coherent receiver (1/fc) */
  311. #define RFAL_FWT_A_ADJUSTMENT (512U + 64U)
  312. /*! FWT ISO14443B adjustment:
  313. * SOF (14etu) + 1Byte (10etu) + 1etu (IRQ comes 1etu after first byte) - 3etu (ST25R3916 sends TXE 3etu after) */
  314. #define RFAL_FWT_B_ADJUSTMENT ((14U + 10U + 1U - 3U) * 128U)
  315. /*! FWT FeliCa 212 adjustment:
  316. * 1024 : Length of the two Sync bytes at 212kbps */
  317. #define RFAL_FWT_F_212_ADJUSTMENT 1024U
  318. /*! FWT FeliCa 424 adjustment:
  319. * 512 : Length of the two Sync bytes at 424kbps */
  320. #define RFAL_FWT_F_424_ADJUSTMENT 512U
  321. /*! Time between our field Off and other peer field On : Tadt + (n x Trfw)
  322. * Ecma 340 11.1.2 - Tadt: [56.64 , 188.72] us ; n: [0 , 3] ; Trfw = 37.76 us
  323. * Should be: 189 + (3*38) = 303us ; we'll use a more relaxed setting: 605 us */
  324. #define RFAL_AP2P_FIELDON_TADTTRFW rfalConvUsTo1fc(605U)
  325. /*! FDT Listen adjustment for ISO14443A EMVCo 2.6 4.8.1.3 ; Digital 1.1 6.10
  326. *
  327. * 276: Time from the rising pulse of the pause of the logic '1' (i.e. the time point to measure the deaftime from),
  328. * to the actual end of the EOF sequence (the point where the MRT starts). Please note that the ST25R391x uses the
  329. * ISO14443-2 definition where the EOF consists of logic '0' followed by sequence Y.
  330. * -64: Further adjustment for receiver to be ready just before first bit
  331. */
  332. #define RFAL_FDT_LISTEN_A_ADJUSTMENT (276U - 64U)
  333. /*! FDT Listen adjustment for ISO14443B EMVCo 2.6 4.8.1.6 ; Digital 1.1 7.9
  334. *
  335. * 340: Time from the rising edge of the EoS to the starting point of the MRT timer (sometime after the final high
  336. * part of the EoS is completed)
  337. */
  338. #define RFAL_FDT_LISTEN_B_ADJUSTMENT 340U
  339. /*! FDT Listen adjustment for ISO15693
  340. * ISO15693 2000 8.4 t1 MIN = 4192/fc
  341. * ISO15693 2009 9.1 t1 MIN = 4320/fc
  342. * Digital 2.1 B.5 FDTV,LISTEN,MIN = 4310/fc
  343. * Set FDT Listen one step earlier than on the more recent spec versions for greater interoperability
  344. */
  345. #define RFAL_FDT_LISTEN_V_ADJUSTMENT 64U
  346. /*! FDT Poll adjustment for ISO14443B Correlator - sst 5 etu */
  347. #define RFAL_FDT_LISTEN_B_ADJT_CORR 128U
  348. /*! FDT Poll adjustment for ISO14443B Correlator sst window - 5 etu */
  349. #define RFAL_FDT_LISTEN_B_ADJT_CORR_SST 20U
  350. /*
  351. ******************************************************************************
  352. * GLOBAL MACROS
  353. ******************************************************************************
  354. */
  355. /*! Calculates Transceive Sanity Timer. It accounts for the slowest bit rate and the longest data format
  356. * 1s for transmission and reception of a 4K message at 106kpbs (~425ms each direction)
  357. * plus TxRx preparation and FIFO load over Serial Interface */
  358. #define rfalCalcSanityTmr(fwt) (uint16_t)(1000U + rfalConv1fcToMs((fwt)))
  359. #define rfalGennTRFW(n) \
  360. (((n) + 1U) & \
  361. ST25R3916_REG_AUX_nfc_n_mask) /*!< Generates the next n*TRRW used for RFCA */
  362. #define rfalCalcNumBytes(nBits) \
  363. (((uint32_t)(nBits) + 7U) / \
  364. 8U) /*!< Returns the number of bytes required to fit given the number of bits */
  365. #define rfalTimerStart(timer, time_ms) \
  366. do { \
  367. platformTimerDestroy(timer); \
  368. (timer) = platformTimerCreate((uint16_t)(time_ms)); \
  369. } while(0) /*!< Configures and starts timer */
  370. #define rfalTimerisExpired(timer) \
  371. platformTimerIsExpired( \
  372. timer) /*!< Checks if timer has expired */
  373. #define rfalTimerDestroy(timer) \
  374. platformTimerDestroy( \
  375. timer) /*!< Destroys timer */
  376. #define rfalST25R3916ObsModeDisable() \
  377. st25r3916WriteTestRegister( \
  378. 0x01U, \
  379. (0x40U)) /*!< Disable ST25R3916 Observation mode */
  380. #define rfalST25R3916ObsModeTx() \
  381. st25r3916WriteTestRegister( \
  382. 0x01U, \
  383. (0x40U | \
  384. gRFAL.conf \
  385. .obsvModeTx)) /*!< Enable Tx Observation mode */
  386. #define rfalST25R3916ObsModeRx() \
  387. st25r3916WriteTestRegister( \
  388. 0x01U, \
  389. (0x40U | \
  390. gRFAL.conf \
  391. .obsvModeRx)) /*!< Enable Rx Observation mode */
  392. #define rfalCheckDisableObsMode() \
  393. if(gRFAL.conf.obsvModeRx != 0U) { \
  394. rfalST25R3916ObsModeDisable(); \
  395. } /*!< Checks if the observation mode is enabled, and applies on ST25R3916 */
  396. #define rfalCheckEnableObsModeTx() \
  397. if(gRFAL.conf.obsvModeTx != 0U) { \
  398. rfalST25R3916ObsModeTx(); \
  399. } /*!< Checks if the observation mode is enabled, and applies on ST25R3916 */
  400. #define rfalCheckEnableObsModeRx() \
  401. if(gRFAL.conf.obsvModeRx != 0U) { \
  402. rfalST25R3916ObsModeRx(); \
  403. } /*!< Checks if the observation mode is enabled, and applies on ST25R3916 */
  404. #define rfalGetIncmplBits(FIFOStatus2) \
  405. (((FIFOStatus2) >> 1) & \
  406. 0x07U) /*!< Returns the number of bits from fifo status */
  407. #define rfalIsIncompleteByteError(error) \
  408. (((error) >= ERR_INCOMPLETE_BYTE) && \
  409. ((error) <= \
  410. ERR_INCOMPLETE_BYTE_07)) /*!< Checks if given error is a Incomplete error */
  411. #define rfalAdjACBR(b) \
  412. (((uint16_t)(b) >= (uint16_t)RFAL_BR_52p97) ? \
  413. (uint16_t)(b) : \
  414. ((uint16_t)(b) + \
  415. 1U)) /*!< Adjusts ST25R391x Bit rate to Analog Configuration */
  416. #define rfalConvBR2ACBR(b) \
  417. (((rfalAdjACBR((b))) << RFAL_ANALOG_CONFIG_BITRATE_SHIFT) & \
  418. RFAL_ANALOG_CONFIG_BITRATE_MASK) /*!< Converts ST25R391x Bit rate to Analog Configuration bit rate id */
  419. #define rfalConvTDFormat(v) \
  420. ((uint16_t)(v) << 8U) /*!< Converts a uint8_t to the format used in SW Tag Detection */
  421. /*
  422. ******************************************************************************
  423. * LOCAL VARIABLES
  424. ******************************************************************************
  425. */
  426. static rfal gRFAL; /*!< RFAL module instance */
  427. /*
  428. ******************************************************************************
  429. * LOCAL FUNCTION PROTOTYPES
  430. ******************************************************************************
  431. */
  432. static void rfalTransceiveTx(void);
  433. static void rfalTransceiveRx(void);
  434. static ReturnCode rfalTransceiveRunBlockingTx(void);
  435. static void rfalPrepareTransceive(void);
  436. static void rfalCleanupTransceive(void);
  437. static void rfalErrorHandling(void);
  438. static ReturnCode rfalRunTransceiveWorker(void);
  439. #if RFAL_FEATURE_LISTEN_MODE
  440. static ReturnCode rfalRunListenModeWorker(void);
  441. #endif /* RFAL_FEATURE_LISTEN_MODE */
  442. #if RFAL_FEATURE_WAKEUP_MODE
  443. static void rfalRunWakeUpModeWorker(void);
  444. static uint16_t rfalWakeUpModeFilter(uint16_t curRef, uint16_t curVal, uint8_t weight);
  445. #endif /* RFAL_FEATURE_WAKEUP_MODE */
  446. static void rfalFIFOStatusUpdate(void);
  447. static void rfalFIFOStatusClear(void);
  448. static bool rfalFIFOStatusIsMissingPar(void);
  449. static bool rfalFIFOStatusIsIncompleteByte(void);
  450. static uint16_t rfalFIFOStatusGetNumBytes(void);
  451. static uint8_t rfalFIFOGetNumIncompleteBits(void);
  452. /*
  453. ******************************************************************************
  454. * GLOBAL FUNCTIONS
  455. ******************************************************************************
  456. */
  457. /*******************************************************************************/
  458. ReturnCode rfalInitialize(void) {
  459. ReturnCode err;
  460. EXIT_ON_ERR(err, st25r3916Initialize());
  461. st25r3916ClearInterrupts();
  462. /* Disable any previous observation mode */
  463. rfalST25R3916ObsModeDisable();
  464. /*******************************************************************************/
  465. /* Apply RF Chip generic initialization */
  466. rfalSetAnalogConfig((RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_INIT));
  467. // TODO:
  468. // I don't want to mess with config table ("Default Analog Configuration for Chip-Specific Reset", rfal_analogConfigTbl.h)
  469. // so with every rfalSetAnalogConfig((RFAL_ANALOG_CONFIG_CHIP_INIT)) currently we need to clear pulldown bits
  470. // luckily for us this is done only here
  471. // disable pulldowns
  472. st25r3916ClrRegisterBits(
  473. ST25R3916_REG_IO_CONF2,
  474. (ST25R3916_REG_IO_CONF2_miso_pd1 | ST25R3916_REG_IO_CONF2_miso_pd2));
  475. /*******************************************************************************/
  476. /* Enable External Field Detector as: Automatics */
  477. st25r3916ChangeRegisterBits(
  478. ST25R3916_REG_OP_CONTROL,
  479. ST25R3916_REG_OP_CONTROL_en_fd_mask,
  480. ST25R3916_REG_OP_CONTROL_en_fd_auto_efd);
  481. /* Clear FIFO status local copy */
  482. rfalFIFOStatusClear();
  483. /*******************************************************************************/
  484. gRFAL.state = RFAL_STATE_INIT;
  485. gRFAL.mode = RFAL_MODE_NONE;
  486. gRFAL.field = false;
  487. /* Set RFAL default configs */
  488. gRFAL.conf.obsvModeRx = RFAL_OBSMODE_DISABLE;
  489. gRFAL.conf.obsvModeTx = RFAL_OBSMODE_DISABLE;
  490. gRFAL.conf.eHandling = RFAL_ERRORHANDLING_NONE;
  491. /* Transceive set to IDLE */
  492. gRFAL.TxRx.lastState = RFAL_TXRX_STATE_IDLE;
  493. gRFAL.TxRx.state = RFAL_TXRX_STATE_IDLE;
  494. /* Disable all timings */
  495. gRFAL.timings.FDTListen = RFAL_TIMING_NONE;
  496. gRFAL.timings.FDTPoll = RFAL_TIMING_NONE;
  497. gRFAL.timings.GT = RFAL_TIMING_NONE;
  498. gRFAL.timings.nTRFW = 0U;
  499. /* Destroy any previous pending timers */
  500. rfalTimerDestroy(gRFAL.tmr.GT);
  501. rfalTimerDestroy(gRFAL.tmr.txRx);
  502. rfalTimerDestroy(gRFAL.tmr.RXE);
  503. gRFAL.tmr.GT = RFAL_TIMING_NONE;
  504. gRFAL.tmr.txRx = RFAL_TIMING_NONE;
  505. gRFAL.tmr.RXE = RFAL_TIMING_NONE;
  506. gRFAL.callbacks.preTxRx = NULL;
  507. gRFAL.callbacks.postTxRx = NULL;
  508. gRFAL.callbacks.state_changed_cb = NULL;
  509. gRFAL.callbacks.ctx = NULL;
  510. #if RFAL_FEATURE_NFCV
  511. /* Initialize NFC-V Data */
  512. gRFAL.nfcvData.ignoreBits = 0;
  513. #endif /* RFAL_FEATURE_NFCV */
  514. #if RFAL_FEATURE_LISTEN_MODE
  515. /* Initialize Listen Mode */
  516. gRFAL.Lm.state = RFAL_LM_STATE_NOT_INIT;
  517. gRFAL.Lm.brDetected = RFAL_BR_KEEP;
  518. gRFAL.Lm.iniFlag = false;
  519. #endif /* RFAL_FEATURE_LISTEN_MODE */
  520. #if RFAL_FEATURE_WAKEUP_MODE
  521. /* Initialize Wake-Up Mode */
  522. gRFAL.wum.state = RFAL_WUM_STATE_NOT_INIT;
  523. #endif /* RFAL_FEATURE_WAKEUP_MODE */
  524. #if RFAL_FEATURE_LOWPOWER_MODE
  525. /* Initialize Low Power Mode */
  526. gRFAL.lpm.isRunning = false;
  527. #endif /* RFAL_FEATURE_LOWPOWER_MODE */
  528. /*******************************************************************************/
  529. /* Perform Automatic Calibration (if configured to do so). *
  530. * Registers set by rfalSetAnalogConfig will tell rfalCalibrate what to perform*/
  531. rfalCalibrate();
  532. return ERR_NONE;
  533. }
  534. /*******************************************************************************/
  535. ReturnCode rfalCalibrate(void) {
  536. uint16_t resValue;
  537. /* Check if RFAL is not initialized */
  538. if(gRFAL.state == RFAL_STATE_IDLE) {
  539. return ERR_WRONG_STATE;
  540. }
  541. /*******************************************************************************/
  542. /* Perform ST25R3916 regulators and antenna calibration */
  543. /*******************************************************************************/
  544. /* Automatic regulator adjustment only performed if not set manually on Analog Configs */
  545. if(st25r3916CheckReg(
  546. ST25R3916_REG_REGULATOR_CONTROL, ST25R3916_REG_REGULATOR_CONTROL_reg_s, 0x00)) {
  547. /* Adjust the regulators so that Antenna Calibrate has better Regulator values */
  548. st25r3916AdjustRegulators(&resValue);
  549. }
  550. return ERR_NONE;
  551. }
  552. /*******************************************************************************/
  553. ReturnCode rfalAdjustRegulators(uint16_t* result) {
  554. return st25r3916AdjustRegulators(result);
  555. }
  556. /*******************************************************************************/
  557. void rfalSetUpperLayerCallback(rfalUpperLayerCallback pFunc) {
  558. st25r3916IRQCallbackSet(pFunc);
  559. }
  560. /*******************************************************************************/
  561. void rfalSetPreTxRxCallback(rfalPreTxRxCallback pFunc) {
  562. gRFAL.callbacks.preTxRx = pFunc;
  563. }
  564. /*******************************************************************************/
  565. void rfalSetPostTxRxCallback(rfalPostTxRxCallback pFunc) {
  566. gRFAL.callbacks.postTxRx = pFunc;
  567. }
  568. void rfal_set_state_changed_callback(RfalStateChangedCallback callback) {
  569. gRFAL.callbacks.state_changed_cb = callback;
  570. }
  571. void rfal_set_callback_context(void* context) {
  572. gRFAL.callbacks.ctx = context;
  573. }
  574. /*******************************************************************************/
  575. ReturnCode rfalDeinitialize(void) {
  576. /* Deinitialize chip */
  577. st25r3916Deinitialize();
  578. /* Set Analog configurations for deinitialization */
  579. rfalSetAnalogConfig((RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_DEINIT));
  580. gRFAL.state = RFAL_STATE_IDLE;
  581. return ERR_NONE;
  582. }
  583. /*******************************************************************************/
  584. void rfalSetObsvMode(uint8_t txMode, uint8_t rxMode) {
  585. gRFAL.conf.obsvModeTx = txMode;
  586. gRFAL.conf.obsvModeRx = rxMode;
  587. }
  588. /*******************************************************************************/
  589. void rfalGetObsvMode(uint8_t* txMode, uint8_t* rxMode) {
  590. if(txMode != NULL) {
  591. *txMode = gRFAL.conf.obsvModeTx;
  592. }
  593. if(rxMode != NULL) {
  594. *rxMode = gRFAL.conf.obsvModeRx;
  595. }
  596. }
  597. /*******************************************************************************/
  598. void rfalDisableObsvMode(void) {
  599. gRFAL.conf.obsvModeTx = RFAL_OBSMODE_DISABLE;
  600. gRFAL.conf.obsvModeRx = RFAL_OBSMODE_DISABLE;
  601. }
  602. /*******************************************************************************/
  603. ReturnCode rfalSetMode(rfalMode mode, rfalBitRate txBR, rfalBitRate rxBR) {
  604. /* Check if RFAL is not initialized */
  605. if(gRFAL.state == RFAL_STATE_IDLE) {
  606. return ERR_WRONG_STATE;
  607. }
  608. /* Check allowed bit rate value */
  609. if((txBR == RFAL_BR_KEEP) || (rxBR == RFAL_BR_KEEP)) {
  610. return ERR_PARAM;
  611. }
  612. switch(mode) {
  613. /*******************************************************************************/
  614. case RFAL_MODE_POLL_NFCA:
  615. /* Disable wake up mode, if set */
  616. st25r3916ClrRegisterBits(ST25R3916_REG_OP_CONTROL, ST25R3916_REG_OP_CONTROL_wu);
  617. /* Enable ISO14443A mode */
  618. st25r3916WriteRegister(ST25R3916_REG_MODE, ST25R3916_REG_MODE_om_iso14443a);
  619. /* Set Analog configurations for this mode and bit rate */
  620. rfalSetAnalogConfig(
  621. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA |
  622. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX));
  623. rfalSetAnalogConfig(
  624. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA |
  625. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX));
  626. break;
  627. /*******************************************************************************/
  628. case RFAL_MODE_POLL_NFCA_T1T:
  629. /* Disable wake up mode, if set */
  630. st25r3916ClrRegisterBits(ST25R3916_REG_OP_CONTROL, ST25R3916_REG_OP_CONTROL_wu);
  631. /* Enable Topaz mode */
  632. st25r3916WriteRegister(ST25R3916_REG_MODE, ST25R3916_REG_MODE_om_topaz);
  633. /* Set Analog configurations for this mode and bit rate */
  634. rfalSetAnalogConfig(
  635. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA |
  636. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX));
  637. rfalSetAnalogConfig(
  638. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA |
  639. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX));
  640. break;
  641. /*******************************************************************************/
  642. case RFAL_MODE_POLL_NFCB:
  643. /* Disable wake up mode, if set */
  644. st25r3916ClrRegisterBits(ST25R3916_REG_OP_CONTROL, ST25R3916_REG_OP_CONTROL_wu);
  645. /* Enable ISO14443B mode */
  646. st25r3916WriteRegister(ST25R3916_REG_MODE, ST25R3916_REG_MODE_om_iso14443b);
  647. /* Set the EGT, SOF, EOF and EOF */
  648. st25r3916ChangeRegisterBits(
  649. ST25R3916_REG_ISO14443B_1,
  650. (ST25R3916_REG_ISO14443B_1_egt_mask | ST25R3916_REG_ISO14443B_1_sof_mask |
  651. ST25R3916_REG_ISO14443B_1_eof),
  652. ((0U << ST25R3916_REG_ISO14443B_1_egt_shift) | ST25R3916_REG_ISO14443B_1_sof_0_10etu |
  653. ST25R3916_REG_ISO14443B_1_sof_1_2etu | ST25R3916_REG_ISO14443B_1_eof_10etu));
  654. /* Set the minimum TR1, SOF, EOF and EOF12 */
  655. st25r3916ChangeRegisterBits(
  656. ST25R3916_REG_ISO14443B_2,
  657. (ST25R3916_REG_ISO14443B_2_tr1_mask | ST25R3916_REG_ISO14443B_2_no_sof |
  658. ST25R3916_REG_ISO14443B_2_no_eof),
  659. (ST25R3916_REG_ISO14443B_2_tr1_80fs80fs));
  660. /* Set Analog configurations for this mode and bit rate */
  661. rfalSetAnalogConfig(
  662. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB |
  663. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX));
  664. rfalSetAnalogConfig(
  665. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB |
  666. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX));
  667. break;
  668. /*******************************************************************************/
  669. case RFAL_MODE_POLL_B_PRIME:
  670. /* Disable wake up mode, if set */
  671. st25r3916ClrRegisterBits(ST25R3916_REG_OP_CONTROL, ST25R3916_REG_OP_CONTROL_wu);
  672. /* Enable ISO14443B mode */
  673. st25r3916WriteRegister(ST25R3916_REG_MODE, ST25R3916_REG_MODE_om_iso14443b);
  674. /* Set the EGT, SOF, EOF and EOF */
  675. st25r3916ChangeRegisterBits(
  676. ST25R3916_REG_ISO14443B_1,
  677. (ST25R3916_REG_ISO14443B_1_egt_mask | ST25R3916_REG_ISO14443B_1_sof_mask |
  678. ST25R3916_REG_ISO14443B_1_eof),
  679. ((0U << ST25R3916_REG_ISO14443B_1_egt_shift) | ST25R3916_REG_ISO14443B_1_sof_0_10etu |
  680. ST25R3916_REG_ISO14443B_1_sof_1_2etu | ST25R3916_REG_ISO14443B_1_eof_10etu));
  681. /* Set the minimum TR1, EOF and EOF12 */
  682. st25r3916ChangeRegisterBits(
  683. ST25R3916_REG_ISO14443B_2,
  684. (ST25R3916_REG_ISO14443B_2_tr1_mask | ST25R3916_REG_ISO14443B_2_no_sof |
  685. ST25R3916_REG_ISO14443B_2_no_eof),
  686. (ST25R3916_REG_ISO14443B_2_tr1_80fs80fs | ST25R3916_REG_ISO14443B_2_no_sof));
  687. /* Set Analog configurations for this mode and bit rate */
  688. rfalSetAnalogConfig(
  689. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB |
  690. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX));
  691. rfalSetAnalogConfig(
  692. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB |
  693. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX));
  694. break;
  695. /*******************************************************************************/
  696. case RFAL_MODE_POLL_B_CTS:
  697. /* Disable wake up mode, if set */
  698. st25r3916ClrRegisterBits(ST25R3916_REG_OP_CONTROL, ST25R3916_REG_OP_CONTROL_wu);
  699. /* Enable ISO14443B mode */
  700. st25r3916WriteRegister(ST25R3916_REG_MODE, ST25R3916_REG_MODE_om_iso14443b);
  701. /* Set the EGT, SOF, EOF and EOF */
  702. st25r3916ChangeRegisterBits(
  703. ST25R3916_REG_ISO14443B_1,
  704. (ST25R3916_REG_ISO14443B_1_egt_mask | ST25R3916_REG_ISO14443B_1_sof_mask |
  705. ST25R3916_REG_ISO14443B_1_eof),
  706. ((0U << ST25R3916_REG_ISO14443B_1_egt_shift) | ST25R3916_REG_ISO14443B_1_sof_0_10etu |
  707. ST25R3916_REG_ISO14443B_1_sof_1_2etu | ST25R3916_REG_ISO14443B_1_eof_10etu));
  708. /* Set the minimum TR1, clear SOF, EOF and EOF12 */
  709. st25r3916ChangeRegisterBits(
  710. ST25R3916_REG_ISO14443B_2,
  711. (ST25R3916_REG_ISO14443B_2_tr1_mask | ST25R3916_REG_ISO14443B_2_no_sof |
  712. ST25R3916_REG_ISO14443B_2_no_eof),
  713. (ST25R3916_REG_ISO14443B_2_tr1_80fs80fs | ST25R3916_REG_ISO14443B_2_no_sof |
  714. ST25R3916_REG_ISO14443B_2_no_eof));
  715. /* Set Analog configurations for this mode and bit rate */
  716. rfalSetAnalogConfig(
  717. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB |
  718. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX));
  719. rfalSetAnalogConfig(
  720. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB |
  721. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX));
  722. break;
  723. /*******************************************************************************/
  724. case RFAL_MODE_POLL_NFCF:
  725. /* Disable wake up mode, if set */
  726. st25r3916ClrRegisterBits(ST25R3916_REG_OP_CONTROL, ST25R3916_REG_OP_CONTROL_wu);
  727. /* Enable FeliCa mode */
  728. st25r3916WriteRegister(ST25R3916_REG_MODE, ST25R3916_REG_MODE_om_felica);
  729. /* Set Analog configurations for this mode and bit rate */
  730. rfalSetAnalogConfig(
  731. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCF |
  732. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX));
  733. rfalSetAnalogConfig(
  734. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCF |
  735. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX));
  736. break;
  737. /*******************************************************************************/
  738. case RFAL_MODE_POLL_NFCV:
  739. case RFAL_MODE_POLL_PICOPASS:
  740. #if !RFAL_FEATURE_NFCV
  741. return ERR_DISABLED;
  742. #else
  743. /* Disable wake up mode, if set */
  744. st25r3916ClrRegisterBits(ST25R3916_REG_OP_CONTROL, ST25R3916_REG_OP_CONTROL_wu);
  745. /* Set Analog configurations for this mode and bit rate */
  746. rfalSetAnalogConfig(
  747. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCV |
  748. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX));
  749. rfalSetAnalogConfig(
  750. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCV |
  751. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX));
  752. break;
  753. #endif /* RFAL_FEATURE_NFCV */
  754. /*******************************************************************************/
  755. case RFAL_MODE_POLL_ACTIVE_P2P:
  756. /* Set NFCIP1 active communication Initiator mode and Automatic Response RF Collision Avoidance to always after EOF */
  757. st25r3916WriteRegister(
  758. ST25R3916_REG_MODE,
  759. (ST25R3916_REG_MODE_targ_init | ST25R3916_REG_MODE_om_nfc |
  760. ST25R3916_REG_MODE_nfc_ar_eof));
  761. /* External Field Detector enabled as Automatics on rfalInitialize() */
  762. /* Set NRT to start at end of TX (own) field */
  763. st25r3916ChangeRegisterBits(
  764. ST25R3916_REG_TIMER_EMV_CONTROL,
  765. ST25R3916_REG_TIMER_EMV_CONTROL_nrt_nfc,
  766. ST25R3916_REG_TIMER_EMV_CONTROL_nrt_nfc_off);
  767. /* Set GPT to start after end of TX, as GPT is used in active communication mode to timeout the field switching off */
  768. /* The field is turned off 37.76us after the end of the transmission Trfw */
  769. st25r3916SetStartGPTimer(
  770. (uint16_t)rfalConv1fcTo8fc(RFAL_AP2P_FIELDOFF_TRFW),
  771. ST25R3916_REG_TIMER_EMV_CONTROL_gptc_etx_nfc);
  772. /* Set PPon2 timer with the max time between our field Off and other peer field On : Tadt + (n x Trfw) */
  773. st25r3916WriteRegister(
  774. ST25R3916_REG_PPON2, (uint8_t)rfalConv1fcTo64fc(RFAL_AP2P_FIELDON_TADTTRFW));
  775. /* Set Analog configurations for this mode and bit rate */
  776. rfalSetAnalogConfig(
  777. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_AP2P |
  778. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX));
  779. rfalSetAnalogConfig(
  780. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_AP2P |
  781. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX));
  782. break;
  783. /*******************************************************************************/
  784. case RFAL_MODE_LISTEN_ACTIVE_P2P:
  785. /* Set NFCIP1 active communication Target mode and Automatic Response RF Collision Avoidance to always after EOF */
  786. st25r3916WriteRegister(
  787. ST25R3916_REG_MODE,
  788. (ST25R3916_REG_MODE_targ_targ | ST25R3916_REG_MODE_om_targ_nfcip |
  789. ST25R3916_REG_MODE_nfc_ar_eof));
  790. /* Set TARFG: 0 (75us+0ms=75us), as Target no Guard time needed */
  791. st25r3916WriteRegister(ST25R3916_REG_FIELD_ON_GT, 0U);
  792. /* External Field Detector enabled as Automatics on rfalInitialize() */
  793. /* Set NRT to start at end of TX (own) field */
  794. st25r3916ChangeRegisterBits(
  795. ST25R3916_REG_TIMER_EMV_CONTROL,
  796. ST25R3916_REG_TIMER_EMV_CONTROL_nrt_nfc,
  797. ST25R3916_REG_TIMER_EMV_CONTROL_nrt_nfc_off);
  798. /* Set GPT to start after end of TX, as GPT is used in active communication mode to timeout the field switching off */
  799. /* The field is turned off 37.76us after the end of the transmission Trfw */
  800. st25r3916SetStartGPTimer(
  801. (uint16_t)rfalConv1fcTo8fc(RFAL_AP2P_FIELDOFF_TRFW),
  802. ST25R3916_REG_TIMER_EMV_CONTROL_gptc_etx_nfc);
  803. /* Set PPon2 timer with the max time between our field Off and other peer field On : Tadt + (n x Trfw) */
  804. st25r3916WriteRegister(
  805. ST25R3916_REG_PPON2, (uint8_t)rfalConv1fcTo64fc(RFAL_AP2P_FIELDON_TADTTRFW));
  806. /* Set Analog configurations for this mode and bit rate */
  807. rfalSetAnalogConfig(
  808. (RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_AP2P |
  809. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX));
  810. rfalSetAnalogConfig(
  811. (RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_AP2P |
  812. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX));
  813. break;
  814. /*******************************************************************************/
  815. case RFAL_MODE_LISTEN_NFCA:
  816. /* Disable wake up mode, if set */
  817. st25r3916ClrRegisterBits(ST25R3916_REG_OP_CONTROL, ST25R3916_REG_OP_CONTROL_wu);
  818. /* Enable Passive Target NFC-A mode, disable any Collision Avoidance */
  819. st25r3916WriteRegister(
  820. ST25R3916_REG_MODE,
  821. (ST25R3916_REG_MODE_targ | ST25R3916_REG_MODE_om_targ_nfca |
  822. ST25R3916_REG_MODE_nfc_ar_off));
  823. /* Set Analog configurations for this mode */
  824. rfalSetAnalogConfig(
  825. (RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_NFCA |
  826. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX));
  827. rfalSetAnalogConfig(
  828. (RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_NFCA |
  829. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX));
  830. break;
  831. /*******************************************************************************/
  832. case RFAL_MODE_LISTEN_NFCF:
  833. /* Disable wake up mode, if set */
  834. st25r3916ClrRegisterBits(ST25R3916_REG_OP_CONTROL, ST25R3916_REG_OP_CONTROL_wu);
  835. /* Enable Passive Target NFC-F mode, disable any Collision Avoidance */
  836. st25r3916WriteRegister(
  837. ST25R3916_REG_MODE,
  838. (ST25R3916_REG_MODE_targ | ST25R3916_REG_MODE_om_targ_nfcf |
  839. ST25R3916_REG_MODE_nfc_ar_off));
  840. /* Set Analog configurations for this mode */
  841. rfalSetAnalogConfig(
  842. (RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_NFCF |
  843. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX));
  844. rfalSetAnalogConfig(
  845. (RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_NFCF |
  846. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX));
  847. break;
  848. /*******************************************************************************/
  849. case RFAL_MODE_LISTEN_NFCB:
  850. return ERR_NOTSUPP;
  851. /*******************************************************************************/
  852. default:
  853. return ERR_NOT_IMPLEMENTED;
  854. }
  855. /* Set state as STATE_MODE_SET only if not initialized yet (PSL) */
  856. gRFAL.state = ((gRFAL.state < RFAL_STATE_MODE_SET) ? RFAL_STATE_MODE_SET : gRFAL.state);
  857. gRFAL.mode = mode;
  858. /* Apply the given bit rate */
  859. return rfalSetBitRate(txBR, rxBR);
  860. }
  861. /*******************************************************************************/
  862. rfalMode rfalGetMode(void) {
  863. return gRFAL.mode;
  864. }
  865. /*******************************************************************************/
  866. ReturnCode rfalSetBitRate(rfalBitRate txBR, rfalBitRate rxBR) {
  867. ReturnCode ret;
  868. /* Check if RFAL is not initialized */
  869. if(gRFAL.state == RFAL_STATE_IDLE) {
  870. return ERR_WRONG_STATE;
  871. }
  872. /* Store the new Bit Rates */
  873. gRFAL.txBR = ((txBR == RFAL_BR_KEEP) ? gRFAL.txBR : txBR);
  874. gRFAL.rxBR = ((rxBR == RFAL_BR_KEEP) ? gRFAL.rxBR : rxBR);
  875. /* Update the bitrate reg if not in NFCV mode (streaming) */
  876. if((RFAL_MODE_POLL_NFCV != gRFAL.mode) && (RFAL_MODE_POLL_PICOPASS != gRFAL.mode)) {
  877. /* Set bit rate register */
  878. EXIT_ON_ERR(ret, st25r3916SetBitrate((uint8_t)gRFAL.txBR, (uint8_t)gRFAL.rxBR));
  879. }
  880. switch(gRFAL.mode) {
  881. /*******************************************************************************/
  882. case RFAL_MODE_POLL_NFCA:
  883. case RFAL_MODE_POLL_NFCA_T1T:
  884. /* Set Analog configurations for this bit rate */
  885. rfalSetAnalogConfig((RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_POLL_COMMON));
  886. rfalSetAnalogConfig(
  887. (rfalAnalogConfigId)(RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA |
  888. rfalConvBR2ACBR(gRFAL.txBR) | RFAL_ANALOG_CONFIG_TX));
  889. rfalSetAnalogConfig(
  890. (rfalAnalogConfigId)(RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA |
  891. rfalConvBR2ACBR(gRFAL.rxBR) | RFAL_ANALOG_CONFIG_RX));
  892. break;
  893. /*******************************************************************************/
  894. case RFAL_MODE_POLL_NFCB:
  895. case RFAL_MODE_POLL_B_PRIME:
  896. case RFAL_MODE_POLL_B_CTS:
  897. /* Set Analog configurations for this bit rate */
  898. rfalSetAnalogConfig((RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_POLL_COMMON));
  899. rfalSetAnalogConfig(
  900. (rfalAnalogConfigId)(RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB |
  901. rfalConvBR2ACBR(gRFAL.txBR) | RFAL_ANALOG_CONFIG_TX));
  902. rfalSetAnalogConfig(
  903. (rfalAnalogConfigId)(RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB |
  904. rfalConvBR2ACBR(gRFAL.rxBR) | RFAL_ANALOG_CONFIG_RX));
  905. break;
  906. /*******************************************************************************/
  907. case RFAL_MODE_POLL_NFCF:
  908. /* Set Analog configurations for this bit rate */
  909. rfalSetAnalogConfig((RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_POLL_COMMON));
  910. rfalSetAnalogConfig(
  911. (rfalAnalogConfigId)(RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCF |
  912. rfalConvBR2ACBR(gRFAL.txBR) | RFAL_ANALOG_CONFIG_TX));
  913. rfalSetAnalogConfig(
  914. (rfalAnalogConfigId)(RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCF |
  915. rfalConvBR2ACBR(gRFAL.rxBR) | RFAL_ANALOG_CONFIG_RX));
  916. break;
  917. /*******************************************************************************/
  918. case RFAL_MODE_POLL_NFCV:
  919. case RFAL_MODE_POLL_PICOPASS:
  920. #if !RFAL_FEATURE_NFCV
  921. return ERR_DISABLED;
  922. #else
  923. if(((gRFAL.rxBR != RFAL_BR_26p48) && (gRFAL.rxBR != RFAL_BR_52p97)) ||
  924. ((gRFAL.txBR != RFAL_BR_1p66) && (gRFAL.txBR != RFAL_BR_26p48))) {
  925. return ERR_PARAM;
  926. }
  927. {
  928. const struct iso15693StreamConfig* isoStreamConfig;
  929. struct st25r3916StreamConfig streamConf;
  930. iso15693PhyConfig_t config;
  931. config.coding =
  932. ((gRFAL.txBR == RFAL_BR_1p66) ? ISO15693_VCD_CODING_1_256 :
  933. ISO15693_VCD_CODING_1_4);
  934. switch(gRFAL.rxBR) {
  935. case RFAL_BR_52p97:
  936. config.speedMode = 1;
  937. break;
  938. default:
  939. config.speedMode = 0;
  940. break;
  941. }
  942. iso15693PhyConfigure(&config, &isoStreamConfig);
  943. /* MISRA 11.3 - Cannot point directly into different object type, copy to local var */
  944. streamConf.din = isoStreamConfig->din;
  945. streamConf.dout = isoStreamConfig->dout;
  946. streamConf.report_period_length = isoStreamConfig->report_period_length;
  947. streamConf.useBPSK = isoStreamConfig->useBPSK;
  948. st25r3916StreamConfigure(&streamConf);
  949. }
  950. /* Set Analog configurations for this bit rate */
  951. rfalSetAnalogConfig((RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_POLL_COMMON));
  952. rfalSetAnalogConfig(
  953. (rfalAnalogConfigId)(RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCV |
  954. rfalConvBR2ACBR(gRFAL.txBR) | RFAL_ANALOG_CONFIG_TX));
  955. rfalSetAnalogConfig(
  956. (rfalAnalogConfigId)(RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCV |
  957. rfalConvBR2ACBR(gRFAL.rxBR) | RFAL_ANALOG_CONFIG_RX));
  958. break;
  959. #endif /* RFAL_FEATURE_NFCV */
  960. /*******************************************************************************/
  961. case RFAL_MODE_POLL_ACTIVE_P2P:
  962. /* Set Analog configurations for this bit rate */
  963. rfalSetAnalogConfig((RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_POLL_COMMON));
  964. rfalSetAnalogConfig(
  965. (rfalAnalogConfigId)(RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_AP2P |
  966. rfalConvBR2ACBR(gRFAL.txBR) | RFAL_ANALOG_CONFIG_TX));
  967. rfalSetAnalogConfig(
  968. (rfalAnalogConfigId)(RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_AP2P |
  969. rfalConvBR2ACBR(gRFAL.rxBR) | RFAL_ANALOG_CONFIG_RX));
  970. break;
  971. /*******************************************************************************/
  972. case RFAL_MODE_LISTEN_ACTIVE_P2P:
  973. /* Set Analog configurations for this bit rate */
  974. rfalSetAnalogConfig(
  975. (RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_LISTEN_COMMON));
  976. rfalSetAnalogConfig(
  977. (rfalAnalogConfigId)(RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_AP2P |
  978. rfalConvBR2ACBR(gRFAL.txBR) | RFAL_ANALOG_CONFIG_TX));
  979. rfalSetAnalogConfig(
  980. (rfalAnalogConfigId)(RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_AP2P |
  981. rfalConvBR2ACBR(gRFAL.rxBR) | RFAL_ANALOG_CONFIG_RX));
  982. break;
  983. /*******************************************************************************/
  984. case RFAL_MODE_LISTEN_NFCA:
  985. /* Set Analog configurations for this bit rate */
  986. rfalSetAnalogConfig(
  987. (RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_LISTEN_COMMON));
  988. rfalSetAnalogConfig(
  989. (rfalAnalogConfigId)(RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_NFCA |
  990. rfalConvBR2ACBR(gRFAL.txBR) | RFAL_ANALOG_CONFIG_TX));
  991. rfalSetAnalogConfig(
  992. (rfalAnalogConfigId)(RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_NFCA |
  993. rfalConvBR2ACBR(gRFAL.rxBR) | RFAL_ANALOG_CONFIG_RX));
  994. break;
  995. /*******************************************************************************/
  996. case RFAL_MODE_LISTEN_NFCF:
  997. /* Set Analog configurations for this bit rate */
  998. rfalSetAnalogConfig(
  999. (RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_LISTEN_COMMON));
  1000. rfalSetAnalogConfig(
  1001. (rfalAnalogConfigId)(RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_NFCF |
  1002. rfalConvBR2ACBR(gRFAL.txBR) | RFAL_ANALOG_CONFIG_TX));
  1003. rfalSetAnalogConfig(
  1004. (rfalAnalogConfigId)(RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_NFCF |
  1005. rfalConvBR2ACBR(gRFAL.rxBR) | RFAL_ANALOG_CONFIG_RX));
  1006. break;
  1007. /*******************************************************************************/
  1008. case RFAL_MODE_LISTEN_NFCB:
  1009. case RFAL_MODE_NONE:
  1010. return ERR_WRONG_STATE;
  1011. /*******************************************************************************/
  1012. default:
  1013. return ERR_NOT_IMPLEMENTED;
  1014. }
  1015. return ERR_NONE;
  1016. }
  1017. /*******************************************************************************/
  1018. ReturnCode rfalGetBitRate(rfalBitRate* txBR, rfalBitRate* rxBR) {
  1019. if((gRFAL.state == RFAL_STATE_IDLE) || (gRFAL.mode == RFAL_MODE_NONE)) {
  1020. return ERR_WRONG_STATE;
  1021. }
  1022. if(txBR != NULL) {
  1023. *txBR = gRFAL.txBR;
  1024. }
  1025. if(rxBR != NULL) {
  1026. *rxBR = gRFAL.rxBR;
  1027. }
  1028. return ERR_NONE;
  1029. }
  1030. /*******************************************************************************/
  1031. void rfalSetErrorHandling(rfalEHandling eHandling) {
  1032. switch(eHandling) {
  1033. case RFAL_ERRORHANDLING_NFC:
  1034. case RFAL_ERRORHANDLING_NONE:
  1035. st25r3916ClrRegisterBits(ST25R3916_REG_EMD_SUP_CONF, ST25R3916_REG_EMD_SUP_CONF_emd_emv);
  1036. break;
  1037. case RFAL_ERRORHANDLING_EMVCO:
  1038. /* MISRA 16.4: no empty default statement (in case RFAL_SW_EMD is defined) */
  1039. #ifndef RFAL_SW_EMD
  1040. st25r3916ModifyRegister(
  1041. ST25R3916_REG_EMD_SUP_CONF,
  1042. (ST25R3916_REG_EMD_SUP_CONF_emd_emv | ST25R3916_REG_EMD_SUP_CONF_emd_thld_mask),
  1043. (ST25R3916_REG_EMD_SUP_CONF_emd_emv_on | RFAL_EMVCO_RX_MAXLEN));
  1044. #endif /* RFAL_SW_EMD */
  1045. break;
  1046. default:
  1047. /* MISRA 16.4: no empty default statement (a comment being enough) */
  1048. break;
  1049. }
  1050. gRFAL.conf.eHandling = eHandling;
  1051. }
  1052. /*******************************************************************************/
  1053. rfalEHandling rfalGetErrorHandling(void) {
  1054. return gRFAL.conf.eHandling;
  1055. }
  1056. /*******************************************************************************/
  1057. void rfalSetFDTPoll(uint32_t FDTPoll) {
  1058. gRFAL.timings.FDTPoll = MIN(FDTPoll, RFAL_ST25R3916_GPT_MAX_1FC);
  1059. }
  1060. /*******************************************************************************/
  1061. uint32_t rfalGetFDTPoll(void) {
  1062. return gRFAL.timings.FDTPoll;
  1063. }
  1064. /*******************************************************************************/
  1065. void rfalSetFDTListen(uint32_t FDTListen) {
  1066. gRFAL.timings.FDTListen = MIN(FDTListen, RFAL_ST25R3916_MRT_MAX_1FC);
  1067. }
  1068. /*******************************************************************************/
  1069. uint32_t rfalGetFDTListen(void) {
  1070. return gRFAL.timings.FDTListen;
  1071. }
  1072. /*******************************************************************************/
  1073. void rfalSetGT(uint32_t GT) {
  1074. gRFAL.timings.GT = MIN(GT, RFAL_ST25R3916_GT_MAX_1FC);
  1075. }
  1076. /*******************************************************************************/
  1077. uint32_t rfalGetGT(void) {
  1078. return gRFAL.timings.GT;
  1079. }
  1080. /*******************************************************************************/
  1081. bool rfalIsGTExpired(void) {
  1082. if(gRFAL.tmr.GT != RFAL_TIMING_NONE) {
  1083. if(!rfalTimerisExpired(gRFAL.tmr.GT)) {
  1084. return false;
  1085. }
  1086. }
  1087. return true;
  1088. }
  1089. /*******************************************************************************/
  1090. ReturnCode rfalFieldOnAndStartGT(void) {
  1091. ReturnCode ret;
  1092. /* Check if RFAL has been initialized (Oscillator should be running) and also
  1093. * if a direct register access has been performed and left the Oscillator Off */
  1094. if(!st25r3916IsOscOn() || (gRFAL.state < RFAL_STATE_INIT)) {
  1095. return ERR_WRONG_STATE;
  1096. }
  1097. ret = ERR_NONE;
  1098. /* Set Analog configurations for Field On event */
  1099. rfalSetAnalogConfig((RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_FIELD_ON));
  1100. /*******************************************************************************/
  1101. /* Perform collision avoidance and turn field On if not already On */
  1102. if(!st25r3916IsTxEnabled() || !gRFAL.field) {
  1103. /* Set TARFG: 0 (75us+0ms=75us), GT is fulfilled using a SW timer */
  1104. st25r3916WriteRegister(ST25R3916_REG_FIELD_ON_GT, 0U);
  1105. /* Use Thresholds set by AnalogConfig */
  1106. ret = st25r3916PerformCollisionAvoidance(
  1107. ST25R3916_CMD_INITIAL_RF_COLLISION,
  1108. ST25R3916_THRESHOLD_DO_NOT_SET,
  1109. ST25R3916_THRESHOLD_DO_NOT_SET,
  1110. gRFAL.timings.nTRFW);
  1111. /* n * TRFW timing shall vary Activity 2.1 3.3.1.1 */
  1112. gRFAL.timings.nTRFW = rfalGennTRFW(gRFAL.timings.nTRFW);
  1113. gRFAL.field = st25r3916IsTxEnabled(); //(ret == ERR_NONE);
  1114. /* Only turn on Receiver and Transmitter if field was successfully turned On */
  1115. if(gRFAL.field) {
  1116. st25r3916TxRxOn(); /* Enable Tx and Rx (Tx is already On)*/
  1117. }
  1118. }
  1119. /*******************************************************************************/
  1120. /* Start GT timer in case the GT value is set */
  1121. if((gRFAL.timings.GT != RFAL_TIMING_NONE)) {
  1122. /* Ensure that a SW timer doesn't have a lower value then the minimum */
  1123. rfalTimerStart(
  1124. gRFAL.tmr.GT, rfalConv1fcToMs(MAX((gRFAL.timings.GT), RFAL_ST25R3916_GT_MIN_1FC)));
  1125. }
  1126. return ret;
  1127. }
  1128. /*******************************************************************************/
  1129. ReturnCode rfalFieldOff(void) {
  1130. /* Check whether a TxRx is not yet finished */
  1131. if(gRFAL.TxRx.state != RFAL_TXRX_STATE_IDLE) {
  1132. rfalCleanupTransceive();
  1133. }
  1134. /* Disable Tx and Rx */
  1135. st25r3916TxRxOff();
  1136. /* Set Analog configurations for Field Off event */
  1137. rfalSetAnalogConfig((RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_FIELD_OFF));
  1138. gRFAL.field = false;
  1139. return ERR_NONE;
  1140. }
  1141. /*******************************************************************************/
  1142. ReturnCode rfalStartTransceive(const rfalTransceiveContext* ctx) {
  1143. uint32_t FxTAdj; /* FWT or FDT adjustment calculation */
  1144. /* Check for valid parameters */
  1145. if(ctx == NULL) {
  1146. return ERR_PARAM;
  1147. }
  1148. /* Ensure that RFAL is already Initialized and the mode has been set */
  1149. if((gRFAL.state >= RFAL_STATE_MODE_SET) /*&& (gRFAL.TxRx.state == RFAL_TXRX_STATE_INIT )*/) {
  1150. /*******************************************************************************/
  1151. /* Check whether the field is already On, otherwise no TXE will be received */
  1152. if(!st25r3916IsTxEnabled() &&
  1153. (!rfalIsModePassiveListen(gRFAL.mode) && (ctx->txBuf != NULL))) {
  1154. return ERR_WRONG_STATE;
  1155. }
  1156. gRFAL.TxRx.ctx = *ctx;
  1157. /*******************************************************************************/
  1158. if(gRFAL.timings.FDTListen != RFAL_TIMING_NONE) {
  1159. /* Calculate MRT adjustment accordingly to the current mode */
  1160. FxTAdj = RFAL_FDT_LISTEN_MRT_ADJUSTMENT;
  1161. if(gRFAL.mode == RFAL_MODE_POLL_NFCA) {
  1162. FxTAdj += (uint32_t)RFAL_FDT_LISTEN_A_ADJUSTMENT;
  1163. }
  1164. if(gRFAL.mode == RFAL_MODE_POLL_NFCA_T1T) {
  1165. FxTAdj += (uint32_t)RFAL_FDT_LISTEN_A_ADJUSTMENT;
  1166. }
  1167. if(gRFAL.mode == RFAL_MODE_POLL_NFCB) {
  1168. FxTAdj += (uint32_t)RFAL_FDT_LISTEN_B_ADJUSTMENT;
  1169. }
  1170. if(gRFAL.mode == RFAL_MODE_POLL_NFCV) {
  1171. FxTAdj += (uint32_t)RFAL_FDT_LISTEN_V_ADJUSTMENT;
  1172. }
  1173. /* Ensure that MRT is using 64/fc steps */
  1174. st25r3916ClrRegisterBits(
  1175. ST25R3916_REG_TIMER_EMV_CONTROL, ST25R3916_REG_TIMER_EMV_CONTROL_mrt_step);
  1176. /* If Correlator is being used further adjustment is required for NFCB */
  1177. if((st25r3916CheckReg(ST25R3916_REG_AUX, ST25R3916_REG_AUX_dis_corr, 0x00U)) &&
  1178. (gRFAL.mode == RFAL_MODE_POLL_NFCB)) {
  1179. FxTAdj += (uint32_t)
  1180. RFAL_FDT_LISTEN_B_ADJT_CORR; /* Reduce FDT(Listen) */
  1181. st25r3916SetRegisterBits(
  1182. ST25R3916_REG_CORR_CONF1,
  1183. ST25R3916_REG_CORR_CONF1_corr_s3); /* Ensure BPSK start to 33 pilot pulses */
  1184. st25r3916ChangeRegisterBits(
  1185. ST25R3916_REG_SUBC_START_TIME,
  1186. ST25R3916_REG_SUBC_START_TIME_sst_mask,
  1187. RFAL_FDT_LISTEN_B_ADJT_CORR_SST); /* Set sst */
  1188. }
  1189. /* Set Minimum FDT(Listen) in which PICC is not allowed to send a response */
  1190. st25r3916WriteRegister(
  1191. ST25R3916_REG_MASK_RX_TIMER,
  1192. (uint8_t)rfalConv1fcTo64fc(
  1193. (FxTAdj > gRFAL.timings.FDTListen) ? RFAL_ST25R3916_MRT_MIN_1FC :
  1194. (gRFAL.timings.FDTListen - FxTAdj)));
  1195. }
  1196. /*******************************************************************************/
  1197. /* FDT Poll will be loaded in rfalPrepareTransceive() once the previous was expired */
  1198. /*******************************************************************************/
  1199. if((gRFAL.TxRx.ctx.fwt != RFAL_FWT_NONE) && (gRFAL.TxRx.ctx.fwt != 0U)) {
  1200. /* Ensure proper timing configuration */
  1201. if(gRFAL.timings.FDTListen >= gRFAL.TxRx.ctx.fwt) {
  1202. return ERR_PARAM;
  1203. }
  1204. FxTAdj = RFAL_FWT_ADJUSTMENT;
  1205. if(gRFAL.mode == RFAL_MODE_POLL_NFCA) {
  1206. FxTAdj += (uint32_t)RFAL_FWT_A_ADJUSTMENT;
  1207. }
  1208. if(gRFAL.mode == RFAL_MODE_POLL_NFCA_T1T) {
  1209. FxTAdj += (uint32_t)RFAL_FWT_A_ADJUSTMENT;
  1210. }
  1211. if(gRFAL.mode == RFAL_MODE_POLL_NFCB) {
  1212. FxTAdj += (uint32_t)RFAL_FWT_B_ADJUSTMENT;
  1213. }
  1214. if((gRFAL.mode == RFAL_MODE_POLL_NFCF) || (gRFAL.mode == RFAL_MODE_POLL_ACTIVE_P2P)) {
  1215. FxTAdj += (uint32_t)((gRFAL.txBR == RFAL_BR_212) ? RFAL_FWT_F_212_ADJUSTMENT :
  1216. RFAL_FWT_F_424_ADJUSTMENT);
  1217. }
  1218. /* Ensure that the given FWT doesn't exceed NRT maximum */
  1219. gRFAL.TxRx.ctx.fwt = MIN((gRFAL.TxRx.ctx.fwt + FxTAdj), RFAL_ST25R3916_NRT_MAX_1FC);
  1220. /* Set FWT in the NRT */
  1221. st25r3916SetNoResponseTime(rfalConv1fcTo64fc(gRFAL.TxRx.ctx.fwt));
  1222. } else {
  1223. /* Disable NRT, no NRE will be triggered, therefore wait endlessly for Rx */
  1224. st25r3916SetNoResponseTime(RFAL_ST25R3916_NRT_DISABLED);
  1225. }
  1226. gRFAL.state = RFAL_STATE_TXRX;
  1227. gRFAL.TxRx.state = RFAL_TXRX_STATE_TX_IDLE;
  1228. gRFAL.TxRx.status = ERR_BUSY;
  1229. #if RFAL_FEATURE_NFCV
  1230. /*******************************************************************************/
  1231. if((RFAL_MODE_POLL_NFCV == gRFAL.mode) ||
  1232. (RFAL_MODE_POLL_PICOPASS ==
  1233. gRFAL.mode)) { /* Exchange receive buffer with internal buffer */
  1234. gRFAL.nfcvData.origCtx = gRFAL.TxRx.ctx;
  1235. gRFAL.TxRx.ctx.rxBuf =
  1236. ((gRFAL.nfcvData.origCtx.rxBuf != NULL) ? gRFAL.nfcvData.codingBuffer : NULL);
  1237. gRFAL.TxRx.ctx.rxBufLen =
  1238. (uint16_t)rfalConvBytesToBits(sizeof(gRFAL.nfcvData.codingBuffer));
  1239. gRFAL.TxRx.ctx.flags =
  1240. (uint32_t)RFAL_TXRX_FLAGS_CRC_TX_MANUAL | (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_KEEP |
  1241. (uint32_t)RFAL_TXRX_FLAGS_NFCIP1_OFF |
  1242. (uint32_t)(gRFAL.nfcvData.origCtx.flags & (uint32_t)RFAL_TXRX_FLAGS_AGC_OFF) |
  1243. (uint32_t)RFAL_TXRX_FLAGS_PAR_RX_KEEP | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_NONE;
  1244. /* In NFCV a TxRx with a valid txBuf and txBufSize==0 indicates to send an EOF */
  1245. /* Skip logic below that would go directly into receive */
  1246. if(gRFAL.TxRx.ctx.txBuf != NULL) {
  1247. return ERR_NONE;
  1248. }
  1249. }
  1250. #endif /* RFAL_FEATURE_NFCV */
  1251. /*******************************************************************************/
  1252. /* Check if the Transceive start performing Tx or goes directly to Rx */
  1253. if((gRFAL.TxRx.ctx.txBuf == NULL) || (gRFAL.TxRx.ctx.txBufLen == 0U)) {
  1254. /* Clear FIFO, Clear and Enable the Interrupts */
  1255. rfalPrepareTransceive();
  1256. /* In AP2P check the field status */
  1257. if(rfalIsModeActiveComm(gRFAL.mode)) {
  1258. /* Disable our field upon a Rx reEnable, and start PPON2 manually */
  1259. st25r3916TxOff();
  1260. st25r3916ExecuteCommand(ST25R3916_CMD_START_PPON2_TIMER);
  1261. }
  1262. /* No Tx done, enable the Receiver */
  1263. st25r3916ExecuteCommand(ST25R3916_CMD_UNMASK_RECEIVE_DATA);
  1264. /* Start NRT manually, if FWT = 0 (wait endlessly for Rx) chip will ignore anyhow */
  1265. st25r3916ExecuteCommand(ST25R3916_CMD_START_NO_RESPONSE_TIMER);
  1266. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_IDLE;
  1267. }
  1268. return ERR_NONE;
  1269. }
  1270. return ERR_WRONG_STATE;
  1271. }
  1272. /*******************************************************************************/
  1273. bool rfalIsTransceiveInTx(void) {
  1274. return (
  1275. (gRFAL.TxRx.state >= RFAL_TXRX_STATE_TX_IDLE) &&
  1276. (gRFAL.TxRx.state < RFAL_TXRX_STATE_RX_IDLE));
  1277. }
  1278. /*******************************************************************************/
  1279. bool rfalIsTransceiveInRx(void) {
  1280. return (gRFAL.TxRx.state >= RFAL_TXRX_STATE_RX_IDLE);
  1281. }
  1282. /*******************************************************************************/
  1283. ReturnCode rfalTransceiveBlockingTx(
  1284. uint8_t* txBuf,
  1285. uint16_t txBufLen,
  1286. uint8_t* rxBuf,
  1287. uint16_t rxBufLen,
  1288. uint16_t* actLen,
  1289. uint32_t flags,
  1290. uint32_t fwt) {
  1291. ReturnCode ret;
  1292. rfalTransceiveContext ctx;
  1293. rfalCreateByteFlagsTxRxContext(ctx, txBuf, txBufLen, rxBuf, rxBufLen, actLen, flags, fwt);
  1294. EXIT_ON_ERR(ret, rfalStartTransceive(&ctx));
  1295. return rfalTransceiveRunBlockingTx();
  1296. }
  1297. ReturnCode rfalTransceiveBitsBlockingTx(
  1298. uint8_t* txBuf,
  1299. uint16_t txBufLen,
  1300. uint8_t* rxBuf,
  1301. uint16_t rxBufLen,
  1302. uint16_t* actLen,
  1303. uint32_t flags,
  1304. uint32_t fwt) {
  1305. ReturnCode ret;
  1306. rfalTransceiveContext ctx = {
  1307. .rxBuf = rxBuf,
  1308. .rxBufLen = rxBufLen,
  1309. .rxRcvdLen = actLen,
  1310. .txBuf = txBuf,
  1311. .txBufLen = txBufLen,
  1312. .flags = flags,
  1313. .fwt = fwt,
  1314. };
  1315. EXIT_ON_ERR(ret, rfalStartTransceive(&ctx));
  1316. return rfalTransceiveRunBlockingTx();
  1317. }
  1318. /*******************************************************************************/
  1319. static ReturnCode rfalTransceiveRunBlockingTx(void) {
  1320. ReturnCode ret;
  1321. do {
  1322. rfalWorker();
  1323. ret = rfalGetTransceiveStatus();
  1324. } while(rfalIsTransceiveInTx() && (ret == ERR_BUSY));
  1325. if(rfalIsTransceiveInRx()) {
  1326. return ERR_NONE;
  1327. }
  1328. return ret;
  1329. }
  1330. /*******************************************************************************/
  1331. ReturnCode rfalTransceiveBlockingRx(void) {
  1332. ReturnCode ret;
  1333. do {
  1334. rfalWorker();
  1335. ret = rfalGetTransceiveStatus();
  1336. } while(rfalIsTransceiveInRx() && (ret == ERR_BUSY));
  1337. return ret;
  1338. }
  1339. /*******************************************************************************/
  1340. ReturnCode rfalTransceiveBlockingTxRx(
  1341. uint8_t* txBuf,
  1342. uint16_t txBufLen,
  1343. uint8_t* rxBuf,
  1344. uint16_t rxBufLen,
  1345. uint16_t* actLen,
  1346. uint32_t flags,
  1347. uint32_t fwt) {
  1348. ReturnCode ret;
  1349. EXIT_ON_ERR(
  1350. ret, rfalTransceiveBlockingTx(txBuf, txBufLen, rxBuf, rxBufLen, actLen, flags, fwt));
  1351. ret = rfalTransceiveBlockingRx();
  1352. /* Convert received bits to bytes */
  1353. if(actLen != NULL) {
  1354. *actLen = rfalConvBitsToBytes(*actLen);
  1355. }
  1356. return ret;
  1357. }
  1358. ReturnCode rfalTransceiveBitsBlockingTxRx(
  1359. uint8_t* txBuf,
  1360. uint16_t txBufLen,
  1361. uint8_t* rxBuf,
  1362. uint16_t rxBufLen,
  1363. uint16_t* actLen,
  1364. uint32_t flags,
  1365. uint32_t fwt) {
  1366. ReturnCode ret;
  1367. EXIT_ON_ERR(
  1368. ret, rfalTransceiveBitsBlockingTx(txBuf, txBufLen, rxBuf, rxBufLen, actLen, flags, fwt));
  1369. ret = rfalTransceiveBlockingRx();
  1370. return ret;
  1371. }
  1372. /*******************************************************************************/
  1373. static ReturnCode rfalRunTransceiveWorker(void) {
  1374. if(gRFAL.state == RFAL_STATE_TXRX) {
  1375. /*******************************************************************************/
  1376. /* Check Transceive Sanity Timer has expired */
  1377. if(gRFAL.tmr.txRx != RFAL_TIMING_NONE) {
  1378. if(rfalTimerisExpired(gRFAL.tmr.txRx)) {
  1379. /* If sanity timer has expired abort ongoing transceive and signal error */
  1380. gRFAL.TxRx.status = ERR_IO;
  1381. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;
  1382. }
  1383. }
  1384. /*******************************************************************************/
  1385. /* Run Tx or Rx state machines */
  1386. if(rfalIsTransceiveInTx()) {
  1387. rfalTransceiveTx();
  1388. return rfalGetTransceiveStatus();
  1389. }
  1390. if(rfalIsTransceiveInRx()) {
  1391. rfalTransceiveRx();
  1392. return rfalGetTransceiveStatus();
  1393. }
  1394. }
  1395. return ERR_WRONG_STATE;
  1396. }
  1397. /*******************************************************************************/
  1398. rfalTransceiveState rfalGetTransceiveState(void) {
  1399. return gRFAL.TxRx.state;
  1400. }
  1401. /*******************************************************************************/
  1402. ReturnCode rfalGetTransceiveStatus(void) {
  1403. return ((gRFAL.TxRx.state == RFAL_TXRX_STATE_IDLE) ? gRFAL.TxRx.status : ERR_BUSY);
  1404. }
  1405. /*******************************************************************************/
  1406. ReturnCode rfalGetTransceiveRSSI(uint16_t* rssi) {
  1407. uint16_t amRSSI;
  1408. uint16_t pmRSSI;
  1409. bool isSumMode;
  1410. if(rssi == NULL) {
  1411. return ERR_PARAM;
  1412. }
  1413. st25r3916GetRSSI(&amRSSI, &pmRSSI);
  1414. /* Check if Correlator Summation mode is being used */
  1415. isSumMode =
  1416. (st25r3916CheckReg(
  1417. ST25R3916_REG_CORR_CONF1,
  1418. ST25R3916_REG_CORR_CONF1_corr_s4,
  1419. ST25R3916_REG_CORR_CONF1_corr_s4) ?
  1420. st25r3916CheckReg(ST25R3916_REG_AUX, ST25R3916_REG_AUX_dis_corr, 0x00) :
  1421. false);
  1422. if(isSumMode) {
  1423. /*******************************************************************************/
  1424. /* Using SQRT from math.h and float. If due to compiler, resources or performance
  1425. * issue this cannot be used, other approaches can be foreseen with less accuracy:
  1426. * Use a simpler sqrt algorithm
  1427. * *rssi = MAX( amRSSI, pmRSSI );
  1428. * *rssi = ( (amRSSI + pmRSSI) / 2);
  1429. */
  1430. *rssi = (uint16_t)sqrt(
  1431. ((double)amRSSI * (double)amRSSI) +
  1432. ((double)pmRSSI *
  1433. (double)
  1434. pmRSSI)); /* PRQA S 5209 # MISRA 4.9 - External function (sqrt()) requires double */
  1435. } else {
  1436. /* Check which channel was used */
  1437. *rssi =
  1438. (st25r3916CheckReg(
  1439. ST25R3916_REG_AUX_DISPLAY,
  1440. ST25R3916_REG_AUX_DISPLAY_a_cha,
  1441. ST25R3916_REG_AUX_DISPLAY_a_cha) ?
  1442. pmRSSI :
  1443. amRSSI);
  1444. }
  1445. return ERR_NONE;
  1446. }
  1447. /*******************************************************************************/
  1448. void rfalWorker(void) {
  1449. platformProtectWorker(); /* Protect RFAL Worker/Task/Process */
  1450. switch(gRFAL.state) {
  1451. case RFAL_STATE_TXRX:
  1452. rfalRunTransceiveWorker();
  1453. break;
  1454. #if RFAL_FEATURE_LISTEN_MODE
  1455. case RFAL_STATE_LM:
  1456. rfalRunListenModeWorker();
  1457. break;
  1458. #endif /* RFAL_FEATURE_LISTEN_MODE */
  1459. #if RFAL_FEATURE_WAKEUP_MODE
  1460. case RFAL_STATE_WUM:
  1461. rfalRunWakeUpModeWorker();
  1462. break;
  1463. #endif /* RFAL_FEATURE_WAKEUP_MODE */
  1464. /* Nothing to be done */
  1465. default:
  1466. /* MISRA 16.4: no empty default statement (a comment being enough) */
  1467. break;
  1468. }
  1469. platformUnprotectWorker(); /* Unprotect RFAL Worker/Task/Process */
  1470. }
  1471. /*******************************************************************************/
  1472. static void rfalErrorHandling(void) {
  1473. uint16_t fifoBytesToRead;
  1474. fifoBytesToRead = rfalFIFOStatusGetNumBytes();
  1475. #ifdef RFAL_SW_EMD
  1476. /*******************************************************************************/
  1477. /* EMVCo */
  1478. /*******************************************************************************/
  1479. if(gRFAL.conf.eHandling == RFAL_ERRORHANDLING_EMVCO) {
  1480. bool rxHasIncParError;
  1481. /*******************************************************************************/
  1482. /* EMD Handling - NFC Forum Digital 1.1 4.1.1.1 ; EMVCo v2.5 4.9.2 */
  1483. /* ReEnable the receiver on frames with a length < 4 bytes, upon: */
  1484. /* - Collision or Framing error detected */
  1485. /* - Residual bits are detected (hard framing error) */
  1486. /* - Parity error */
  1487. /* - CRC error */
  1488. /*******************************************************************************/
  1489. /* Check if reception has incomplete bytes or parity error */
  1490. rxHasIncParError =
  1491. (rfalFIFOStatusIsIncompleteByte() ? true :
  1492. rfalFIFOStatusIsMissingPar()); /* MISRA 13.5 */
  1493. /* In case there are residual bits decrement FIFO bytes */
  1494. /* Ensure FIFO contains some byte as the FIFO might be empty upon Framing errors */
  1495. if((fifoBytesToRead > 0U) && rxHasIncParError) {
  1496. fifoBytesToRead--;
  1497. }
  1498. if(((gRFAL.fifo.bytesTotal + fifoBytesToRead) < RFAL_EMVCO_RX_MAXLEN) &&
  1499. ((gRFAL.TxRx.status == ERR_RF_COLLISION) || (gRFAL.TxRx.status == ERR_FRAMING) ||
  1500. (gRFAL.TxRx.status == ERR_PAR) || (gRFAL.TxRx.status == ERR_CRC) ||
  1501. rxHasIncParError)) {
  1502. /* Ignore this reception, ReEnable receiver which also clears the FIFO */
  1503. st25r3916ExecuteCommand(ST25R3916_CMD_UNMASK_RECEIVE_DATA);
  1504. /* Ensure that the NRT has not expired meanwhile */
  1505. if(st25r3916CheckReg(
  1506. ST25R3916_REG_NFCIP1_BIT_RATE, ST25R3916_REG_NFCIP1_BIT_RATE_nrt_on, 0x00)) {
  1507. if(st25r3916CheckReg(
  1508. ST25R3916_REG_AUX_DISPLAY, ST25R3916_REG_AUX_DISPLAY_rx_act, 0x00)) {
  1509. /* Abort reception */
  1510. st25r3916ExecuteCommand(ST25R3916_CMD_MASK_RECEIVE_DATA);
  1511. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;
  1512. return;
  1513. }
  1514. }
  1515. rfalFIFOStatusClear();
  1516. gRFAL.fifo.bytesTotal = 0;
  1517. gRFAL.TxRx.status = ERR_BUSY;
  1518. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_WAIT_RXS;
  1519. }
  1520. return;
  1521. }
  1522. #endif
  1523. /*******************************************************************************/
  1524. /* ISO14443A Mode */
  1525. /*******************************************************************************/
  1526. if(gRFAL.mode == RFAL_MODE_POLL_NFCA) {
  1527. /*******************************************************************************/
  1528. /* If we received a frame with a incomplete byte we`ll raise a specific error *
  1529. * ( support for T2T 4 bit ACK / NAK, MIFARE and Kovio ) */
  1530. /*******************************************************************************/
  1531. if((gRFAL.TxRx.status == ERR_PAR) || (gRFAL.TxRx.status == ERR_CRC)) {
  1532. if(rfalFIFOStatusIsIncompleteByte()) {
  1533. st25r3916ReadFifo((uint8_t*)(gRFAL.TxRx.ctx.rxBuf), fifoBytesToRead);
  1534. if((gRFAL.TxRx.ctx.rxRcvdLen) != NULL) {
  1535. *gRFAL.TxRx.ctx.rxRcvdLen = rfalFIFOGetNumIncompleteBits();
  1536. }
  1537. gRFAL.TxRx.status = ERR_INCOMPLETE_BYTE;
  1538. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;
  1539. }
  1540. }
  1541. }
  1542. }
  1543. /*******************************************************************************/
  1544. static void rfalCleanupTransceive(void) {
  1545. /*******************************************************************************/
  1546. /* Transceive flags */
  1547. /*******************************************************************************/
  1548. /* Restore default settings on NFCIP1 mode, Receiving parity + CRC bits and manual Tx Parity*/
  1549. st25r3916ClrRegisterBits(
  1550. ST25R3916_REG_ISO14443A_NFC,
  1551. (ST25R3916_REG_ISO14443A_NFC_no_tx_par | ST25R3916_REG_ISO14443A_NFC_no_rx_par |
  1552. ST25R3916_REG_ISO14443A_NFC_nfc_f0));
  1553. /* Restore AGC enabled */
  1554. st25r3916SetRegisterBits(ST25R3916_REG_RX_CONF2, ST25R3916_REG_RX_CONF2_agc_en);
  1555. /*******************************************************************************/
  1556. /*******************************************************************************/
  1557. /* Transceive timers */
  1558. /*******************************************************************************/
  1559. rfalTimerDestroy(gRFAL.tmr.txRx);
  1560. rfalTimerDestroy(gRFAL.tmr.RXE);
  1561. gRFAL.tmr.txRx = RFAL_TIMING_NONE;
  1562. gRFAL.tmr.RXE = RFAL_TIMING_NONE;
  1563. /*******************************************************************************/
  1564. /*******************************************************************************/
  1565. /* Execute Post Transceive Callback */
  1566. /*******************************************************************************/
  1567. if(gRFAL.callbacks.postTxRx != NULL) {
  1568. gRFAL.callbacks.postTxRx(gRFAL.callbacks.ctx);
  1569. }
  1570. /*******************************************************************************/
  1571. }
  1572. /*******************************************************************************/
  1573. static void rfalPrepareTransceive(void) {
  1574. uint32_t maskInterrupts;
  1575. uint8_t reg;
  1576. /* If we are in RW or AP2P mode */
  1577. if(!rfalIsModePassiveListen(gRFAL.mode)) {
  1578. /* Reset receive logic with STOP command */
  1579. st25r3916ExecuteCommand(ST25R3916_CMD_STOP);
  1580. /* Reset Rx Gain */
  1581. st25r3916ExecuteCommand(ST25R3916_CMD_RESET_RXGAIN);
  1582. } else {
  1583. /* In Passive Listen Mode do not use STOP as it stops FDT timer */
  1584. st25r3916ExecuteCommand(ST25R3916_CMD_CLEAR_FIFO);
  1585. }
  1586. /*******************************************************************************/
  1587. /* FDT Poll */
  1588. /*******************************************************************************/
  1589. if(rfalIsModePassiveComm(gRFAL.mode)) /* Passive Comms */
  1590. {
  1591. /* In Passive communications General Purpose Timer is used to measure FDT Poll */
  1592. if(gRFAL.timings.FDTPoll != RFAL_TIMING_NONE) {
  1593. /* Configure GPT to start at RX end */
  1594. st25r3916SetStartGPTimer(
  1595. (uint16_t)rfalConv1fcTo8fc(MIN(
  1596. gRFAL.timings.FDTPoll, (gRFAL.timings.FDTPoll - RFAL_FDT_POLL_ADJUSTMENT))),
  1597. ST25R3916_REG_TIMER_EMV_CONTROL_gptc_erx);
  1598. }
  1599. }
  1600. /*******************************************************************************/
  1601. /* Execute Pre Transceive Callback */
  1602. /*******************************************************************************/
  1603. if(gRFAL.callbacks.preTxRx != NULL) {
  1604. gRFAL.callbacks.preTxRx(gRFAL.callbacks.ctx);
  1605. }
  1606. /*******************************************************************************/
  1607. maskInterrupts =
  1608. (ST25R3916_IRQ_MASK_FWL | ST25R3916_IRQ_MASK_TXE | ST25R3916_IRQ_MASK_RXS |
  1609. ST25R3916_IRQ_MASK_RXE | ST25R3916_IRQ_MASK_PAR | ST25R3916_IRQ_MASK_CRC |
  1610. ST25R3916_IRQ_MASK_ERR1 | ST25R3916_IRQ_MASK_ERR2 | ST25R3916_IRQ_MASK_NRE);
  1611. /*******************************************************************************/
  1612. /* Transceive flags */
  1613. /*******************************************************************************/
  1614. reg =
  1615. (ST25R3916_REG_ISO14443A_NFC_no_tx_par_off | ST25R3916_REG_ISO14443A_NFC_no_rx_par_off |
  1616. ST25R3916_REG_ISO14443A_NFC_nfc_f0_off);
  1617. /* Check if NFCIP1 mode is to be enabled */
  1618. if((gRFAL.TxRx.ctx.flags & (uint8_t)RFAL_TXRX_FLAGS_NFCIP1_ON) != 0U) {
  1619. reg |= ST25R3916_REG_ISO14443A_NFC_nfc_f0;
  1620. }
  1621. /* Check if Parity check is to be skipped and to keep the parity + CRC bits in FIFO */
  1622. if((gRFAL.TxRx.ctx.flags & (uint8_t)RFAL_TXRX_FLAGS_PAR_RX_KEEP) != 0U) {
  1623. reg |= ST25R3916_REG_ISO14443A_NFC_no_rx_par;
  1624. }
  1625. /* Check if automatic Parity bits is to be disabled */
  1626. if((gRFAL.TxRx.ctx.flags & (uint8_t)RFAL_TXRX_FLAGS_PAR_TX_NONE) != 0U) {
  1627. reg |= ST25R3916_REG_ISO14443A_NFC_no_tx_par;
  1628. }
  1629. /* Apply current TxRx flags on ISO14443A and NFC 106kb/s Settings Register */
  1630. st25r3916ChangeRegisterBits(
  1631. ST25R3916_REG_ISO14443A_NFC,
  1632. (ST25R3916_REG_ISO14443A_NFC_no_tx_par | ST25R3916_REG_ISO14443A_NFC_no_rx_par |
  1633. ST25R3916_REG_ISO14443A_NFC_nfc_f0),
  1634. reg);
  1635. /* Check if AGC is to be disabled */
  1636. if((gRFAL.TxRx.ctx.flags & (uint8_t)RFAL_TXRX_FLAGS_AGC_OFF) != 0U) {
  1637. st25r3916ClrRegisterBits(ST25R3916_REG_RX_CONF2, ST25R3916_REG_RX_CONF2_agc_en);
  1638. } else {
  1639. st25r3916SetRegisterBits(ST25R3916_REG_RX_CONF2, ST25R3916_REG_RX_CONF2_agc_en);
  1640. }
  1641. /*******************************************************************************/
  1642. /*******************************************************************************/
  1643. /* EMVCo NRT mode */
  1644. /*******************************************************************************/
  1645. if(gRFAL.conf.eHandling == RFAL_ERRORHANDLING_EMVCO) {
  1646. st25r3916SetRegisterBits(
  1647. ST25R3916_REG_TIMER_EMV_CONTROL, ST25R3916_REG_TIMER_EMV_CONTROL_nrt_emv);
  1648. maskInterrupts |= ST25R3916_IRQ_MASK_RX_REST;
  1649. } else {
  1650. st25r3916ClrRegisterBits(
  1651. ST25R3916_REG_TIMER_EMV_CONTROL, ST25R3916_REG_TIMER_EMV_CONTROL_nrt_emv);
  1652. }
  1653. /*******************************************************************************/
  1654. /* In Passive Listen mode additionally enable External Field interrupts */
  1655. if(rfalIsModePassiveListen(gRFAL.mode)) {
  1656. maskInterrupts |=
  1657. (ST25R3916_IRQ_MASK_EOF |
  1658. ST25R3916_IRQ_MASK_WU_F); /* Enable external Field interrupts to detect Link Loss and SENF_REQ auto responses */
  1659. }
  1660. /* In Active comms enable also External Field interrupts and set RF Collision Avoindance */
  1661. if(rfalIsModeActiveComm(gRFAL.mode)) {
  1662. maskInterrupts |=
  1663. (ST25R3916_IRQ_MASK_EOF | ST25R3916_IRQ_MASK_EON | ST25R3916_IRQ_MASK_PPON2 |
  1664. ST25R3916_IRQ_MASK_CAT | ST25R3916_IRQ_MASK_CAC);
  1665. /* Set n=0 for subsequent RF Collision Avoidance */
  1666. st25r3916ChangeRegisterBits(ST25R3916_REG_AUX, ST25R3916_REG_AUX_nfc_n_mask, 0);
  1667. }
  1668. /*******************************************************************************/
  1669. /* Start transceive Sanity Timer if a FWT is used */
  1670. if((gRFAL.TxRx.ctx.fwt != RFAL_FWT_NONE) && (gRFAL.TxRx.ctx.fwt != 0U)) {
  1671. rfalTimerStart(gRFAL.tmr.txRx, rfalCalcSanityTmr(gRFAL.TxRx.ctx.fwt));
  1672. }
  1673. /*******************************************************************************/
  1674. /*******************************************************************************/
  1675. /* Clear and enable these interrupts */
  1676. st25r3916GetInterrupt(maskInterrupts);
  1677. st25r3916EnableInterrupts(maskInterrupts);
  1678. /* Clear FIFO status local copy */
  1679. rfalFIFOStatusClear();
  1680. }
  1681. /*******************************************************************************/
  1682. static void rfalTransceiveTx(void) {
  1683. volatile uint32_t irqs;
  1684. uint16_t tmp;
  1685. ReturnCode ret;
  1686. /* Suppress warning in case NFC-V feature is disabled */
  1687. ret = ERR_NONE;
  1688. NO_WARNING(ret);
  1689. irqs = ST25R3916_IRQ_MASK_NONE;
  1690. if(gRFAL.TxRx.state != gRFAL.TxRx.lastState) {
  1691. /* rfalLogD( "RFAL: lastSt: %d curSt: %d \r\n", gRFAL.TxRx.lastState, gRFAL.TxRx.state ); */
  1692. gRFAL.TxRx.lastState = gRFAL.TxRx.state;
  1693. }
  1694. switch(gRFAL.TxRx.state) {
  1695. /*******************************************************************************/
  1696. case RFAL_TXRX_STATE_TX_IDLE:
  1697. /* Nothing to do */
  1698. gRFAL.TxRx.state = RFAL_TXRX_STATE_TX_WAIT_GT;
  1699. /* fall through */
  1700. /*******************************************************************************/
  1701. case RFAL_TXRX_STATE_TX_WAIT_GT: /* PRQA S 2003 # MISRA 16.3 - Intentional fall through */
  1702. if(!rfalIsGTExpired()) {
  1703. break;
  1704. }
  1705. rfalTimerDestroy(gRFAL.tmr.GT);
  1706. gRFAL.tmr.GT = RFAL_TIMING_NONE;
  1707. gRFAL.TxRx.state = RFAL_TXRX_STATE_TX_WAIT_FDT;
  1708. /* fall through */
  1709. /*******************************************************************************/
  1710. case RFAL_TXRX_STATE_TX_WAIT_FDT: /* PRQA S 2003 # MISRA 16.3 - Intentional fall through */
  1711. /* Only in Passive communications GPT is used to measure FDT Poll */
  1712. if(rfalIsModePassiveComm(gRFAL.mode)) {
  1713. if(st25r3916IsGPTRunning()) {
  1714. break;
  1715. }
  1716. }
  1717. gRFAL.TxRx.state = RFAL_TXRX_STATE_TX_TRANSMIT;
  1718. /* fall through */
  1719. /*******************************************************************************/
  1720. case RFAL_TXRX_STATE_TX_TRANSMIT: /* PRQA S 2003 # MISRA 16.3 - Intentional fall through */
  1721. /* Clear FIFO, Clear and Enable the Interrupts */
  1722. rfalPrepareTransceive();
  1723. /* ST25R3916 has a fixed FIFO water level */
  1724. gRFAL.fifo.expWL = RFAL_FIFO_OUT_WL;
  1725. #if RFAL_FEATURE_NFCV
  1726. /*******************************************************************************/
  1727. /* In NFC-V streaming mode, the FIFO needs to be loaded with the coded bits */
  1728. if((RFAL_MODE_POLL_NFCV == gRFAL.mode) || (RFAL_MODE_POLL_PICOPASS == gRFAL.mode)) {
  1729. #if 0
  1730. /* Debugging code: output the payload bits by writing into the FIFO and subsequent clearing */
  1731. st25r3916WriteFifo(gRFAL.TxRx.ctx.txBuf, rfalConvBitsToBytes(gRFAL.TxRx.ctx.txBufLen));
  1732. st25r3916ExecuteCommand( ST25R3916_CMD_CLEAR_FIFO );
  1733. #endif
  1734. /* Calculate the bytes needed to be Written into FIFO (a incomplete byte will be added as 1byte) */
  1735. gRFAL.nfcvData.nfcvOffset = 0;
  1736. ret = iso15693VCDCode(
  1737. gRFAL.TxRx.ctx.txBuf,
  1738. rfalConvBitsToBytes(gRFAL.TxRx.ctx.txBufLen),
  1739. (((gRFAL.nfcvData.origCtx.flags & (uint32_t)RFAL_TXRX_FLAGS_CRC_TX_MANUAL) != 0U) ?
  1740. false :
  1741. true),
  1742. (((gRFAL.nfcvData.origCtx.flags & (uint32_t)RFAL_TXRX_FLAGS_NFCV_FLAG_MANUAL) !=
  1743. 0U) ?
  1744. false :
  1745. true),
  1746. (RFAL_MODE_POLL_PICOPASS == gRFAL.mode),
  1747. &gRFAL.fifo.bytesTotal,
  1748. &gRFAL.nfcvData.nfcvOffset,
  1749. gRFAL.nfcvData.codingBuffer,
  1750. MIN((uint16_t)ST25R3916_FIFO_DEPTH, (uint16_t)sizeof(gRFAL.nfcvData.codingBuffer)),
  1751. &gRFAL.fifo.bytesWritten);
  1752. if((ret != ERR_NONE) && (ret != ERR_AGAIN)) {
  1753. gRFAL.TxRx.status = ret;
  1754. gRFAL.TxRx.state = RFAL_TXRX_STATE_TX_FAIL;
  1755. break;
  1756. }
  1757. /* Set the number of full bytes and bits to be transmitted */
  1758. st25r3916SetNumTxBits((uint16_t)rfalConvBytesToBits(gRFAL.fifo.bytesTotal));
  1759. /* Load FIFO with coded bytes */
  1760. st25r3916WriteFifo(gRFAL.nfcvData.codingBuffer, gRFAL.fifo.bytesWritten);
  1761. }
  1762. /*******************************************************************************/
  1763. else
  1764. #endif /* RFAL_FEATURE_NFCV */
  1765. {
  1766. /* Calculate the bytes needed to be Written into FIFO (a incomplete byte will be added as 1byte) */
  1767. gRFAL.fifo.bytesTotal = (uint16_t)rfalCalcNumBytes(gRFAL.TxRx.ctx.txBufLen);
  1768. /* Set the number of full bytes and bits to be transmitted */
  1769. st25r3916SetNumTxBits(gRFAL.TxRx.ctx.txBufLen);
  1770. /* Load FIFO with total length or FIFO's maximum */
  1771. gRFAL.fifo.bytesWritten = MIN(gRFAL.fifo.bytesTotal, ST25R3916_FIFO_DEPTH);
  1772. st25r3916WriteFifo(gRFAL.TxRx.ctx.txBuf, gRFAL.fifo.bytesWritten);
  1773. }
  1774. /*Check if Observation Mode is enabled and set it on ST25R391x */
  1775. rfalCheckEnableObsModeTx();
  1776. /*******************************************************************************/
  1777. /* If we're in Passive Listen mode ensure that the external field is still On */
  1778. if(rfalIsModePassiveListen(gRFAL.mode)) {
  1779. if(!rfalIsExtFieldOn()) {
  1780. gRFAL.TxRx.status = ERR_LINK_LOSS;
  1781. gRFAL.TxRx.state = RFAL_TXRX_STATE_TX_FAIL;
  1782. break;
  1783. }
  1784. }
  1785. /*******************************************************************************/
  1786. /* Trigger/Start transmission */
  1787. if((gRFAL.TxRx.ctx.flags & (uint32_t)RFAL_TXRX_FLAGS_CRC_TX_MANUAL) != 0U) {
  1788. st25r3916ExecuteCommand(ST25R3916_CMD_TRANSMIT_WITHOUT_CRC);
  1789. } else {
  1790. st25r3916ExecuteCommand(ST25R3916_CMD_TRANSMIT_WITH_CRC);
  1791. }
  1792. /* Check if a WL level is expected or TXE should come */
  1793. gRFAL.TxRx.state =
  1794. ((gRFAL.fifo.bytesWritten < gRFAL.fifo.bytesTotal) ? RFAL_TXRX_STATE_TX_WAIT_WL :
  1795. RFAL_TXRX_STATE_TX_WAIT_TXE);
  1796. break;
  1797. /*******************************************************************************/
  1798. case RFAL_TXRX_STATE_TX_WAIT_WL:
  1799. irqs = st25r3916GetInterrupt((ST25R3916_IRQ_MASK_FWL | ST25R3916_IRQ_MASK_TXE));
  1800. if(irqs == ST25R3916_IRQ_MASK_NONE) {
  1801. break; /* No interrupt to process */
  1802. }
  1803. if(((irqs & ST25R3916_IRQ_MASK_FWL) != 0U) && ((irqs & ST25R3916_IRQ_MASK_TXE) == 0U)) {
  1804. gRFAL.TxRx.state = RFAL_TXRX_STATE_TX_RELOAD_FIFO;
  1805. } else {
  1806. gRFAL.TxRx.status = ERR_IO;
  1807. gRFAL.TxRx.state = RFAL_TXRX_STATE_TX_FAIL;
  1808. break;
  1809. }
  1810. /* fall through */
  1811. /*******************************************************************************/
  1812. case RFAL_TXRX_STATE_TX_RELOAD_FIFO: /* PRQA S 2003 # MISRA 16.3 - Intentional fall through */
  1813. #if RFAL_FEATURE_NFCV
  1814. /*******************************************************************************/
  1815. /* In NFC-V streaming mode, the FIFO needs to be loaded with the coded bits */
  1816. if((RFAL_MODE_POLL_NFCV == gRFAL.mode) || (RFAL_MODE_POLL_PICOPASS == gRFAL.mode)) {
  1817. uint16_t maxLen;
  1818. /* Load FIFO with the remaining length or maximum available (which fit on the coding buffer) */
  1819. maxLen =
  1820. (uint16_t)MIN((gRFAL.fifo.bytesTotal - gRFAL.fifo.bytesWritten), gRFAL.fifo.expWL);
  1821. maxLen = (uint16_t)MIN(maxLen, sizeof(gRFAL.nfcvData.codingBuffer));
  1822. tmp = 0;
  1823. /* Calculate the bytes needed to be Written into FIFO (a incomplete byte will be added as 1byte) */
  1824. ret = iso15693VCDCode(
  1825. gRFAL.TxRx.ctx.txBuf,
  1826. rfalConvBitsToBytes(gRFAL.TxRx.ctx.txBufLen),
  1827. (((gRFAL.nfcvData.origCtx.flags & (uint32_t)RFAL_TXRX_FLAGS_CRC_TX_MANUAL) != 0U) ?
  1828. false :
  1829. true),
  1830. (((gRFAL.nfcvData.origCtx.flags & (uint32_t)RFAL_TXRX_FLAGS_NFCV_FLAG_MANUAL) !=
  1831. 0U) ?
  1832. false :
  1833. true),
  1834. (RFAL_MODE_POLL_PICOPASS == gRFAL.mode),
  1835. &gRFAL.fifo.bytesTotal,
  1836. &gRFAL.nfcvData.nfcvOffset,
  1837. gRFAL.nfcvData.codingBuffer,
  1838. maxLen,
  1839. &tmp);
  1840. if((ret != ERR_NONE) && (ret != ERR_AGAIN)) {
  1841. gRFAL.TxRx.status = ret;
  1842. gRFAL.TxRx.state = RFAL_TXRX_STATE_TX_FAIL;
  1843. break;
  1844. }
  1845. /* Load FIFO with coded bytes */
  1846. st25r3916WriteFifo(gRFAL.nfcvData.codingBuffer, tmp);
  1847. }
  1848. /*******************************************************************************/
  1849. else
  1850. #endif /* RFAL_FEATURE_NFCV */
  1851. {
  1852. /* Load FIFO with the remaining length or maximum available */
  1853. tmp = MIN(
  1854. (gRFAL.fifo.bytesTotal - gRFAL.fifo.bytesWritten),
  1855. gRFAL.fifo.expWL); /* tmp holds the number of bytes written on this iteration */
  1856. st25r3916WriteFifo(&gRFAL.TxRx.ctx.txBuf[gRFAL.fifo.bytesWritten], tmp);
  1857. }
  1858. /* Update total written bytes to FIFO */
  1859. gRFAL.fifo.bytesWritten += tmp;
  1860. /* Check if a WL level is expected or TXE should come */
  1861. gRFAL.TxRx.state =
  1862. ((gRFAL.fifo.bytesWritten < gRFAL.fifo.bytesTotal) ? RFAL_TXRX_STATE_TX_WAIT_WL :
  1863. RFAL_TXRX_STATE_TX_WAIT_TXE);
  1864. break;
  1865. /*******************************************************************************/
  1866. case RFAL_TXRX_STATE_TX_WAIT_TXE:
  1867. irqs = st25r3916GetInterrupt((ST25R3916_IRQ_MASK_FWL | ST25R3916_IRQ_MASK_TXE));
  1868. if(irqs == ST25R3916_IRQ_MASK_NONE) {
  1869. break; /* No interrupt to process */
  1870. }
  1871. if((irqs & ST25R3916_IRQ_MASK_TXE) != 0U) {
  1872. gRFAL.TxRx.state = RFAL_TXRX_STATE_TX_DONE;
  1873. } else if((irqs & ST25R3916_IRQ_MASK_FWL) != 0U) {
  1874. break; /* Ignore ST25R3916 FIFO WL if total TxLen is already on the FIFO */
  1875. } else {
  1876. gRFAL.TxRx.status = ERR_IO;
  1877. gRFAL.TxRx.state = RFAL_TXRX_STATE_TX_FAIL;
  1878. break;
  1879. }
  1880. /* fall through */
  1881. /*******************************************************************************/
  1882. case RFAL_TXRX_STATE_TX_DONE: /* PRQA S 2003 # MISRA 16.3 - Intentional fall through */
  1883. /* If no rxBuf is provided do not wait/expect Rx */
  1884. if(gRFAL.TxRx.ctx.rxBuf == NULL) {
  1885. /*Check if Observation Mode was enabled and disable it on ST25R391x */
  1886. rfalCheckDisableObsMode();
  1887. /* Clean up Transceive */
  1888. rfalCleanupTransceive();
  1889. gRFAL.TxRx.status = ERR_NONE;
  1890. gRFAL.TxRx.state = RFAL_TXRX_STATE_IDLE;
  1891. break;
  1892. }
  1893. rfalCheckEnableObsModeRx();
  1894. /* Goto Rx */
  1895. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_IDLE;
  1896. break;
  1897. /*******************************************************************************/
  1898. case RFAL_TXRX_STATE_TX_FAIL:
  1899. /* Error should be assigned by previous state */
  1900. if(gRFAL.TxRx.status == ERR_BUSY) {
  1901. gRFAL.TxRx.status = ERR_SYSTEM;
  1902. }
  1903. /*Check if Observation Mode was enabled and disable it on ST25R391x */
  1904. rfalCheckDisableObsMode();
  1905. /* Clean up Transceive */
  1906. rfalCleanupTransceive();
  1907. gRFAL.TxRx.state = RFAL_TXRX_STATE_IDLE;
  1908. break;
  1909. /*******************************************************************************/
  1910. default:
  1911. gRFAL.TxRx.status = ERR_SYSTEM;
  1912. gRFAL.TxRx.state = RFAL_TXRX_STATE_TX_FAIL;
  1913. break;
  1914. }
  1915. }
  1916. /*******************************************************************************/
  1917. static void rfalTransceiveRx(void) {
  1918. volatile uint32_t irqs;
  1919. uint16_t tmp;
  1920. uint16_t aux;
  1921. irqs = ST25R3916_IRQ_MASK_NONE;
  1922. if(gRFAL.TxRx.state != gRFAL.TxRx.lastState) {
  1923. /* rfalLogD( "RFAL: lastSt: %d curSt: %d \r\n", gRFAL.TxRx.lastState, gRFAL.TxRx.state ); */
  1924. gRFAL.TxRx.lastState = gRFAL.TxRx.state;
  1925. }
  1926. switch(gRFAL.TxRx.state) {
  1927. /*******************************************************************************/
  1928. case RFAL_TXRX_STATE_RX_IDLE:
  1929. /* Clear rx counters */
  1930. gRFAL.fifo.bytesWritten = 0; /* Total bytes written on RxBuffer */
  1931. gRFAL.fifo.bytesTotal = 0; /* Total bytes in FIFO will now be from Rx */
  1932. if(gRFAL.TxRx.ctx.rxRcvdLen != NULL) {
  1933. *gRFAL.TxRx.ctx.rxRcvdLen = 0;
  1934. }
  1935. gRFAL.TxRx.state =
  1936. (rfalIsModeActiveComm(gRFAL.mode) ? RFAL_TXRX_STATE_RX_WAIT_EON :
  1937. RFAL_TXRX_STATE_RX_WAIT_RXS);
  1938. break;
  1939. /*******************************************************************************/
  1940. case RFAL_TXRX_STATE_RX_WAIT_RXS:
  1941. /*******************************************************************************/
  1942. irqs = st25r3916GetInterrupt(
  1943. (ST25R3916_IRQ_MASK_RXS | ST25R3916_IRQ_MASK_NRE | ST25R3916_IRQ_MASK_EOF));
  1944. if(irqs == ST25R3916_IRQ_MASK_NONE) {
  1945. break; /* No interrupt to process */
  1946. }
  1947. /* Only raise Timeout if NRE is detected with no Rx Start (NRT EMV mode) */
  1948. if(((irqs & ST25R3916_IRQ_MASK_NRE) != 0U) && ((irqs & ST25R3916_IRQ_MASK_RXS) == 0U)) {
  1949. gRFAL.TxRx.status = ERR_TIMEOUT;
  1950. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;
  1951. break;
  1952. }
  1953. /* Only raise Link Loss if EOF is detected with no Rx Start */
  1954. if(((irqs & ST25R3916_IRQ_MASK_EOF) != 0U) && ((irqs & ST25R3916_IRQ_MASK_RXS) == 0U)) {
  1955. /* In AP2P a Field On has already occurred - treat this as timeout | mute */
  1956. gRFAL.TxRx.status = (rfalIsModeActiveComm(gRFAL.mode) ? ERR_TIMEOUT : ERR_LINK_LOSS);
  1957. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;
  1958. break;
  1959. }
  1960. if((irqs & ST25R3916_IRQ_MASK_RXS) != 0U) {
  1961. /*******************************************************************************/
  1962. /* REMARK: Silicon workaround ST25R3916 Errata #TBD */
  1963. /* Rarely on corrupted frames I_rxs gets signaled but I_rxe is not signaled */
  1964. /* Use a SW timer to handle an eventual missing RXE */
  1965. rfalTimerStart(gRFAL.tmr.RXE, RFAL_NORXE_TOUT);
  1966. /*******************************************************************************/
  1967. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_WAIT_RXE;
  1968. } else {
  1969. gRFAL.TxRx.status = ERR_IO;
  1970. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;
  1971. break;
  1972. }
  1973. /* remove NRE that might appear together (NRT EMV mode), and remove RXS, but keep EOF if present for next state */
  1974. irqs &= ~(ST25R3916_IRQ_MASK_RXS | ST25R3916_IRQ_MASK_NRE);
  1975. /* fall through */
  1976. /*******************************************************************************/
  1977. case RFAL_TXRX_STATE_RX_WAIT_RXE: /* PRQA S 2003 # MISRA 16.3 - Intentional fall through */
  1978. /*******************************************************************************/
  1979. /* REMARK: Silicon workaround ST25R3916 Errata #TBD */
  1980. /* ST25R396 may indicate RXS without RXE afterwards, this happens rarely on */
  1981. /* corrupted frames. */
  1982. /* SW timer is used to timeout upon a missing RXE */
  1983. if(rfalTimerisExpired(gRFAL.tmr.RXE)) {
  1984. gRFAL.TxRx.status = ERR_FRAMING;
  1985. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;
  1986. }
  1987. /*******************************************************************************/
  1988. irqs |= st25r3916GetInterrupt(
  1989. (ST25R3916_IRQ_MASK_RXE | ST25R3916_IRQ_MASK_FWL | ST25R3916_IRQ_MASK_EOF |
  1990. ST25R3916_IRQ_MASK_RX_REST | ST25R3916_IRQ_MASK_WU_F));
  1991. if(irqs == ST25R3916_IRQ_MASK_NONE) {
  1992. break; /* No interrupt to process */
  1993. }
  1994. if((irqs & ST25R3916_IRQ_MASK_RX_REST) != 0U) {
  1995. /* RX_REST indicates that Receiver has been reset due to EMD, therefore a RXS + RXE should *
  1996. * follow if a good reception is followed within the valid initial timeout */
  1997. /* Check whether NRT has expired already, if so signal a timeout */
  1998. if(st25r3916GetInterrupt(ST25R3916_IRQ_MASK_NRE) != 0U) {
  1999. gRFAL.TxRx.status = ERR_TIMEOUT;
  2000. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;
  2001. break;
  2002. }
  2003. if(st25r3916CheckReg(
  2004. ST25R3916_REG_NFCIP1_BIT_RATE,
  2005. ST25R3916_REG_NFCIP1_BIT_RATE_nrt_on,
  2006. 0)) /* MISRA 13.5 */
  2007. {
  2008. gRFAL.TxRx.status = ERR_TIMEOUT;
  2009. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;
  2010. break;
  2011. }
  2012. /* Discard any previous RXS */
  2013. st25r3916GetInterrupt(ST25R3916_IRQ_MASK_RXS);
  2014. /* Check whether a following reception has already started */
  2015. if(st25r3916CheckReg(
  2016. ST25R3916_REG_AUX_DISPLAY,
  2017. ST25R3916_REG_AUX_DISPLAY_rx_act,
  2018. ST25R3916_REG_AUX_DISPLAY_rx_act)) {
  2019. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_WAIT_RXE;
  2020. break;
  2021. }
  2022. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_WAIT_RXS;
  2023. break;
  2024. }
  2025. if(((irqs & ST25R3916_IRQ_MASK_FWL) != 0U) && ((irqs & ST25R3916_IRQ_MASK_RXE) == 0U)) {
  2026. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_READ_FIFO;
  2027. break;
  2028. }
  2029. /* Automatic responses allowed during TxRx only for the SENSF_REQ */
  2030. if((irqs & ST25R3916_IRQ_MASK_WU_F) != 0U) {
  2031. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_WAIT_RXS;
  2032. break;
  2033. }
  2034. /* After RXE retrieve and check for any error irqs */
  2035. irqs |= st25r3916GetInterrupt(
  2036. (ST25R3916_IRQ_MASK_CRC | ST25R3916_IRQ_MASK_PAR | ST25R3916_IRQ_MASK_ERR1 |
  2037. ST25R3916_IRQ_MASK_ERR2 | ST25R3916_IRQ_MASK_COL));
  2038. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_ERR_CHECK;
  2039. /* fall through */
  2040. /*******************************************************************************/
  2041. case RFAL_TXRX_STATE_RX_ERR_CHECK: /* PRQA S 2003 # MISRA 16.3 - Intentional fall through */
  2042. if((irqs & ST25R3916_IRQ_MASK_ERR1) != 0U) {
  2043. gRFAL.TxRx.status = ERR_FRAMING;
  2044. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_READ_DATA;
  2045. /* Check if there's a specific error handling for this */
  2046. rfalErrorHandling();
  2047. break;
  2048. }
  2049. /* Discard Soft Framing errors in AP2P and CE */
  2050. else if(rfalIsModePassivePoll(gRFAL.mode) && ((irqs & ST25R3916_IRQ_MASK_ERR2) != 0U)) {
  2051. gRFAL.TxRx.status = ERR_FRAMING;
  2052. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_READ_DATA;
  2053. /* Check if there's a specific error handling for this */
  2054. rfalErrorHandling();
  2055. break;
  2056. } else if((irqs & ST25R3916_IRQ_MASK_PAR) != 0U) {
  2057. gRFAL.TxRx.status = ERR_PAR;
  2058. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_READ_DATA;
  2059. /* Check if there's a specific error handling for this */
  2060. rfalErrorHandling();
  2061. break;
  2062. } else if((irqs & ST25R3916_IRQ_MASK_CRC) != 0U) {
  2063. gRFAL.TxRx.status = ERR_CRC;
  2064. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_READ_DATA;
  2065. /* Check if there's a specific error handling for this */
  2066. rfalErrorHandling();
  2067. break;
  2068. } else if((irqs & ST25R3916_IRQ_MASK_COL) != 0U) {
  2069. gRFAL.TxRx.status = ERR_RF_COLLISION;
  2070. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_READ_DATA;
  2071. /* Check if there's a specific error handling for this */
  2072. rfalErrorHandling();
  2073. break;
  2074. } else if(rfalIsModePassiveListen(gRFAL.mode) && ((irqs & ST25R3916_IRQ_MASK_EOF) != 0U)) {
  2075. gRFAL.TxRx.status = ERR_LINK_LOSS;
  2076. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;
  2077. break;
  2078. } else if((irqs & ST25R3916_IRQ_MASK_RXE) != 0U) {
  2079. /* Reception ended without any error indication, *
  2080. * check FIFO status for malformed or incomplete frames */
  2081. /* Check if the reception ends with an incomplete byte (residual bits) */
  2082. if(rfalFIFOStatusIsIncompleteByte()) {
  2083. gRFAL.TxRx.status = ERR_INCOMPLETE_BYTE;
  2084. }
  2085. /* Check if the reception ends missing parity bit */
  2086. else if(rfalFIFOStatusIsMissingPar()) {
  2087. gRFAL.TxRx.status = ERR_FRAMING;
  2088. } else {
  2089. /* MISRA 15.7 - Empty else */
  2090. }
  2091. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_READ_DATA;
  2092. } else {
  2093. gRFAL.TxRx.status = ERR_IO;
  2094. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;
  2095. break;
  2096. }
  2097. /* fall through */
  2098. /*******************************************************************************/
  2099. case RFAL_TXRX_STATE_RX_READ_DATA: /* PRQA S 2003 # MISRA 16.3 - Intentional fall through */
  2100. tmp = rfalFIFOStatusGetNumBytes();
  2101. /*******************************************************************************/
  2102. /* Check if CRC should not be placed in rxBuf */
  2103. if(((gRFAL.TxRx.ctx.flags & (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_KEEP) == 0U)) {
  2104. /* if received frame was bigger than CRC */
  2105. if((uint16_t)(gRFAL.fifo.bytesTotal + tmp) > 0U) {
  2106. /* By default CRC will not be placed into the rxBuffer */
  2107. if((tmp > RFAL_CRC_LEN)) {
  2108. tmp -= RFAL_CRC_LEN;
  2109. }
  2110. /* If the CRC was already placed into rxBuffer (due to WL interrupt where CRC was already in FIFO Read)
  2111. * cannot remove it from rxBuf. Can only remove it from rxBufLen not indicate the presence of CRC */
  2112. else if(gRFAL.fifo.bytesTotal > RFAL_CRC_LEN) {
  2113. gRFAL.fifo.bytesTotal -= RFAL_CRC_LEN;
  2114. } else {
  2115. /* MISRA 15.7 - Empty else */
  2116. }
  2117. }
  2118. }
  2119. gRFAL.fifo.bytesTotal += tmp; /* add to total bytes counter */
  2120. /*******************************************************************************/
  2121. /* Check if remaining bytes fit on the rxBuf available */
  2122. if(gRFAL.fifo.bytesTotal > rfalConvBitsToBytes(gRFAL.TxRx.ctx.rxBufLen)) {
  2123. tmp =
  2124. (uint16_t)(rfalConvBitsToBytes(gRFAL.TxRx.ctx.rxBufLen) - gRFAL.fifo.bytesWritten);
  2125. /* Transmission errors have precedence over buffer error */
  2126. if(gRFAL.TxRx.status == ERR_BUSY) {
  2127. gRFAL.TxRx.status = ERR_NOMEM;
  2128. }
  2129. }
  2130. /*******************************************************************************/
  2131. /* Retrieve remaining bytes from FIFO to rxBuf, and assign total length rcvd */
  2132. st25r3916ReadFifo(&gRFAL.TxRx.ctx.rxBuf[gRFAL.fifo.bytesWritten], tmp);
  2133. if(gRFAL.TxRx.ctx.rxRcvdLen != NULL) {
  2134. (*gRFAL.TxRx.ctx.rxRcvdLen) = (uint16_t)rfalConvBytesToBits(gRFAL.fifo.bytesTotal);
  2135. if(rfalFIFOStatusIsIncompleteByte()) {
  2136. (*gRFAL.TxRx.ctx.rxRcvdLen) -=
  2137. (RFAL_BITS_IN_BYTE - rfalFIFOGetNumIncompleteBits());
  2138. }
  2139. }
  2140. #if RFAL_FEATURE_NFCV
  2141. /*******************************************************************************/
  2142. /* Decode sub bit stream into payload bits for NFCV, if no error found so far */
  2143. if(((RFAL_MODE_POLL_NFCV == gRFAL.mode) || (RFAL_MODE_POLL_PICOPASS == gRFAL.mode)) &&
  2144. (gRFAL.TxRx.status == ERR_BUSY)) {
  2145. ReturnCode ret;
  2146. uint16_t offset = 0; /* REMARK offset not currently used */
  2147. ret = iso15693VICCDecode(
  2148. gRFAL.TxRx.ctx.rxBuf,
  2149. gRFAL.fifo.bytesTotal,
  2150. gRFAL.nfcvData.origCtx.rxBuf,
  2151. rfalConvBitsToBytes(gRFAL.nfcvData.origCtx.rxBufLen),
  2152. &offset,
  2153. gRFAL.nfcvData.origCtx.rxRcvdLen,
  2154. gRFAL.nfcvData.ignoreBits,
  2155. (RFAL_MODE_POLL_PICOPASS == gRFAL.mode));
  2156. if(((ERR_NONE == ret) || (ERR_CRC == ret)) &&
  2157. (((uint32_t)RFAL_TXRX_FLAGS_CRC_RX_KEEP & gRFAL.nfcvData.origCtx.flags) == 0U) &&
  2158. ((*gRFAL.nfcvData.origCtx.rxRcvdLen % RFAL_BITS_IN_BYTE) == 0U) &&
  2159. (*gRFAL.nfcvData.origCtx.rxRcvdLen >= rfalConvBytesToBits(RFAL_CRC_LEN))) {
  2160. *gRFAL.nfcvData.origCtx.rxRcvdLen -=
  2161. (uint16_t)rfalConvBytesToBits(RFAL_CRC_LEN); /* Remove CRC */
  2162. }
  2163. #if 0
  2164. /* Debugging code: output the payload bits by writing into the FIFO and subsequent clearing */
  2165. st25r3916WriteFifo(gRFAL.nfcvData.origCtx.rxBuf, rfalConvBitsToBytes( *gRFAL.nfcvData.origCtx.rxRcvdLen));
  2166. st25r3916ExecuteCommand( ST25R3916_CMD_CLEAR_FIFO );
  2167. #endif
  2168. /* Restore original ctx */
  2169. gRFAL.TxRx.ctx = gRFAL.nfcvData.origCtx;
  2170. gRFAL.TxRx.status = ((ret != ERR_NONE) ? ret : ERR_BUSY);
  2171. }
  2172. #endif /* RFAL_FEATURE_NFCV */
  2173. /*******************************************************************************/
  2174. /* If an error as been marked/detected don't fall into to RX_DONE */
  2175. if(gRFAL.TxRx.status != ERR_BUSY) {
  2176. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;
  2177. break;
  2178. }
  2179. if(rfalIsModeActiveComm(gRFAL.mode)) {
  2180. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_WAIT_EOF;
  2181. break;
  2182. }
  2183. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_DONE;
  2184. /* fall through */
  2185. /*******************************************************************************/
  2186. case RFAL_TXRX_STATE_RX_DONE: /* PRQA S 2003 # MISRA 16.3 - Intentional fall through */
  2187. /*Check if Observation Mode was enabled and disable it on ST25R391x */
  2188. rfalCheckDisableObsMode();
  2189. /* Clean up Transceive */
  2190. rfalCleanupTransceive();
  2191. gRFAL.TxRx.status = ERR_NONE;
  2192. gRFAL.TxRx.state = RFAL_TXRX_STATE_IDLE;
  2193. break;
  2194. /*******************************************************************************/
  2195. case RFAL_TXRX_STATE_RX_READ_FIFO:
  2196. /*******************************************************************************/
  2197. /* REMARK: Silicon workaround ST25R3916 Errata #TBD */
  2198. /* Rarely on corrupted frames I_rxs gets signaled but I_rxe is not signaled */
  2199. /* Use a SW timer to handle an eventual missing RXE */
  2200. rfalTimerStart(gRFAL.tmr.RXE, RFAL_NORXE_TOUT);
  2201. /*******************************************************************************/
  2202. tmp = rfalFIFOStatusGetNumBytes();
  2203. gRFAL.fifo.bytesTotal += tmp;
  2204. /*******************************************************************************/
  2205. /* Calculate the amount of bytes that still fits in rxBuf */
  2206. aux =
  2207. ((gRFAL.fifo.bytesTotal > rfalConvBitsToBytes(gRFAL.TxRx.ctx.rxBufLen)) ?
  2208. (rfalConvBitsToBytes(gRFAL.TxRx.ctx.rxBufLen) - gRFAL.fifo.bytesWritten) :
  2209. tmp);
  2210. /*******************************************************************************/
  2211. /* Retrieve incoming bytes from FIFO to rxBuf, and store already read amount */
  2212. st25r3916ReadFifo(&gRFAL.TxRx.ctx.rxBuf[gRFAL.fifo.bytesWritten], aux);
  2213. gRFAL.fifo.bytesWritten += aux;
  2214. /*******************************************************************************/
  2215. /* If the bytes already read were not the full FIFO WL, dump the remaining *
  2216. * FIFO so that ST25R391x can continue with reception */
  2217. if(aux < tmp) {
  2218. st25r3916ReadFifo(NULL, (tmp - aux));
  2219. }
  2220. rfalFIFOStatusClear();
  2221. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_WAIT_RXE;
  2222. break;
  2223. /*******************************************************************************/
  2224. case RFAL_TXRX_STATE_RX_FAIL:
  2225. /*Check if Observation Mode was enabled and disable it on ST25R391x */
  2226. rfalCheckDisableObsMode();
  2227. /* Clean up Transceive */
  2228. rfalCleanupTransceive();
  2229. /* Error should be assigned by previous state */
  2230. if(gRFAL.TxRx.status == ERR_BUSY) {
  2231. gRFAL.TxRx.status = ERR_SYSTEM;
  2232. }
  2233. /*rfalLogD( "RFAL: curSt: %d Error: %d \r\n", gRFAL.TxRx.state, gRFAL.TxRx.status );*/
  2234. gRFAL.TxRx.state = RFAL_TXRX_STATE_IDLE;
  2235. break;
  2236. /*******************************************************************************/
  2237. case RFAL_TXRX_STATE_RX_WAIT_EON:
  2238. irqs = st25r3916GetInterrupt(
  2239. (ST25R3916_IRQ_MASK_EON | ST25R3916_IRQ_MASK_NRE | ST25R3916_IRQ_MASK_PPON2));
  2240. if(irqs == ST25R3916_IRQ_MASK_NONE) {
  2241. break; /* No interrupt to process */
  2242. }
  2243. if((irqs & ST25R3916_IRQ_MASK_EON) != 0U) {
  2244. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_WAIT_RXS;
  2245. }
  2246. if((irqs & ST25R3916_IRQ_MASK_NRE) != 0U) {
  2247. gRFAL.TxRx.status = ERR_TIMEOUT;
  2248. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;
  2249. }
  2250. if((irqs & ST25R3916_IRQ_MASK_PPON2) != 0U) {
  2251. gRFAL.TxRx.status = ERR_LINK_LOSS;
  2252. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;
  2253. }
  2254. break;
  2255. /*******************************************************************************/
  2256. case RFAL_TXRX_STATE_RX_WAIT_EOF:
  2257. irqs = st25r3916GetInterrupt((ST25R3916_IRQ_MASK_CAT | ST25R3916_IRQ_MASK_CAC));
  2258. if(irqs == ST25R3916_IRQ_MASK_NONE) {
  2259. break; /* No interrupt to process */
  2260. }
  2261. if((irqs & ST25R3916_IRQ_MASK_CAT) != 0U) {
  2262. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_DONE;
  2263. } else if((irqs & ST25R3916_IRQ_MASK_CAC) != 0U) {
  2264. gRFAL.TxRx.status = ERR_RF_COLLISION;
  2265. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;
  2266. } else {
  2267. gRFAL.TxRx.status = ERR_IO;
  2268. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;
  2269. }
  2270. break;
  2271. /*******************************************************************************/
  2272. default:
  2273. gRFAL.TxRx.status = ERR_SYSTEM;
  2274. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;
  2275. break;
  2276. }
  2277. }
  2278. /*******************************************************************************/
  2279. static void rfalFIFOStatusUpdate(void) {
  2280. if(gRFAL.fifo.status[RFAL_FIFO_STATUS_REG2] == RFAL_FIFO_STATUS_INVALID) {
  2281. st25r3916ReadMultipleRegisters(
  2282. ST25R3916_REG_FIFO_STATUS1, gRFAL.fifo.status, ST25R3916_FIFO_STATUS_LEN);
  2283. }
  2284. }
  2285. /*******************************************************************************/
  2286. static void rfalFIFOStatusClear(void) {
  2287. gRFAL.fifo.status[RFAL_FIFO_STATUS_REG2] = RFAL_FIFO_STATUS_INVALID;
  2288. }
  2289. /*******************************************************************************/
  2290. static uint16_t rfalFIFOStatusGetNumBytes(void) {
  2291. uint16_t result;
  2292. rfalFIFOStatusUpdate();
  2293. result =
  2294. ((((uint16_t)gRFAL.fifo.status[RFAL_FIFO_STATUS_REG2] &
  2295. ST25R3916_REG_FIFO_STATUS2_fifo_b_mask) >>
  2296. ST25R3916_REG_FIFO_STATUS2_fifo_b_shift)
  2297. << RFAL_BITS_IN_BYTE);
  2298. result |= (((uint16_t)gRFAL.fifo.status[RFAL_FIFO_STATUS_REG1]) & 0x00FFU);
  2299. return result;
  2300. }
  2301. /*******************************************************************************/
  2302. static bool rfalFIFOStatusIsIncompleteByte(void) {
  2303. rfalFIFOStatusUpdate();
  2304. return (
  2305. (gRFAL.fifo.status[RFAL_FIFO_STATUS_REG2] & ST25R3916_REG_FIFO_STATUS2_fifo_lb_mask) !=
  2306. 0U);
  2307. }
  2308. /*******************************************************************************/
  2309. static bool rfalFIFOStatusIsMissingPar(void) {
  2310. rfalFIFOStatusUpdate();
  2311. return ((gRFAL.fifo.status[RFAL_FIFO_STATUS_REG2] & ST25R3916_REG_FIFO_STATUS2_np_lb) != 0U);
  2312. }
  2313. /*******************************************************************************/
  2314. static uint8_t rfalFIFOGetNumIncompleteBits(void) {
  2315. rfalFIFOStatusUpdate();
  2316. return (
  2317. (gRFAL.fifo.status[RFAL_FIFO_STATUS_REG2] & ST25R3916_REG_FIFO_STATUS2_fifo_lb_mask) >>
  2318. ST25R3916_REG_FIFO_STATUS2_fifo_lb_shift);
  2319. }
  2320. #if RFAL_FEATURE_NFCA
  2321. /*******************************************************************************/
  2322. ReturnCode rfalISO14443ATransceiveShortFrame(
  2323. rfal14443AShortFrameCmd txCmd,
  2324. uint8_t* rxBuf,
  2325. uint8_t rxBufLen,
  2326. uint16_t* rxRcvdLen,
  2327. uint32_t fwt) {
  2328. ReturnCode ret;
  2329. uint8_t directCmd;
  2330. /* Check if RFAL is properly initialized */
  2331. if(!st25r3916IsTxEnabled() || (gRFAL.state < RFAL_STATE_MODE_SET) ||
  2332. ((gRFAL.mode != RFAL_MODE_POLL_NFCA) && (gRFAL.mode != RFAL_MODE_POLL_NFCA_T1T))) {
  2333. return ERR_WRONG_STATE;
  2334. }
  2335. /* Check for valid parameters */
  2336. if((rxBuf == NULL) || (rxRcvdLen == NULL) || (fwt == RFAL_FWT_NONE)) {
  2337. return ERR_PARAM;
  2338. }
  2339. /*******************************************************************************/
  2340. /* Select the Direct Command to be performed */
  2341. switch(txCmd) {
  2342. case RFAL_14443A_SHORTFRAME_CMD_WUPA:
  2343. directCmd = ST25R3916_CMD_TRANSMIT_WUPA;
  2344. break;
  2345. case RFAL_14443A_SHORTFRAME_CMD_REQA:
  2346. directCmd = ST25R3916_CMD_TRANSMIT_REQA;
  2347. break;
  2348. default:
  2349. return ERR_PARAM;
  2350. }
  2351. /* Disable CRC while receiving since ATQA has no CRC included */
  2352. st25r3916SetRegisterBits(ST25R3916_REG_AUX, ST25R3916_REG_AUX_no_crc_rx);
  2353. /*******************************************************************************/
  2354. /* Wait for GT and FDT */
  2355. while(!rfalIsGTExpired()) { /* MISRA 15.6: mandatory brackets */
  2356. };
  2357. while(st25r3916IsGPTRunning()) { /* MISRA 15.6: mandatory brackets */
  2358. };
  2359. rfalTimerDestroy(gRFAL.tmr.GT);
  2360. gRFAL.tmr.GT = RFAL_TIMING_NONE;
  2361. /*******************************************************************************/
  2362. /* Prepare for Transceive, Receive only (bypass Tx states) */
  2363. gRFAL.TxRx.ctx.flags =
  2364. ((uint32_t)RFAL_TXRX_FLAGS_CRC_TX_MANUAL | (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_KEEP);
  2365. gRFAL.TxRx.ctx.rxBuf = rxBuf;
  2366. gRFAL.TxRx.ctx.rxBufLen = rxBufLen;
  2367. gRFAL.TxRx.ctx.rxRcvdLen = rxRcvdLen;
  2368. gRFAL.TxRx.ctx.fwt = fwt;
  2369. /*******************************************************************************/
  2370. /* Load NRT with FWT */
  2371. st25r3916SetNoResponseTime(rfalConv1fcTo64fc(
  2372. MIN((fwt + RFAL_FWT_ADJUSTMENT + RFAL_FWT_A_ADJUSTMENT), RFAL_ST25R3916_NRT_MAX_1FC)));
  2373. if(gRFAL.timings.FDTListen != RFAL_TIMING_NONE) {
  2374. /* Ensure that MRT is using 64/fc steps */
  2375. st25r3916ClrRegisterBits(
  2376. ST25R3916_REG_TIMER_EMV_CONTROL, ST25R3916_REG_TIMER_EMV_CONTROL_mrt_step);
  2377. /* Set Minimum FDT(Listen) in which PICC is not allowed to send a response */
  2378. st25r3916WriteRegister(
  2379. ST25R3916_REG_MASK_RX_TIMER,
  2380. (uint8_t)rfalConv1fcTo64fc(
  2381. ((RFAL_FDT_LISTEN_MRT_ADJUSTMENT + RFAL_FDT_LISTEN_A_ADJUSTMENT) >
  2382. gRFAL.timings.FDTListen) ?
  2383. RFAL_ST25R3916_MRT_MIN_1FC :
  2384. (gRFAL.timings.FDTListen -
  2385. (RFAL_FDT_LISTEN_MRT_ADJUSTMENT + RFAL_FDT_LISTEN_A_ADJUSTMENT))));
  2386. }
  2387. /* In Passive communications General Purpose Timer is used to measure FDT Poll */
  2388. if(gRFAL.timings.FDTPoll != RFAL_TIMING_NONE) {
  2389. /* Configure GPT to start at RX end */
  2390. st25r3916SetStartGPTimer(
  2391. (uint16_t)rfalConv1fcTo8fc(
  2392. MIN(gRFAL.timings.FDTPoll, (gRFAL.timings.FDTPoll - RFAL_FDT_POLL_ADJUSTMENT))),
  2393. ST25R3916_REG_TIMER_EMV_CONTROL_gptc_erx);
  2394. }
  2395. /*******************************************************************************/
  2396. rfalPrepareTransceive();
  2397. /* Also enable bit collision interrupt */
  2398. st25r3916GetInterrupt(ST25R3916_IRQ_MASK_COL);
  2399. st25r3916EnableInterrupts(ST25R3916_IRQ_MASK_COL);
  2400. /*Check if Observation Mode is enabled and set it on ST25R391x */
  2401. rfalCheckEnableObsModeTx();
  2402. /*******************************************************************************/
  2403. /* Clear nbtx bits before sending WUPA/REQA - otherwise ST25R3916 will report parity error, Note2 of the register */
  2404. st25r3916WriteRegister(ST25R3916_REG_NUM_TX_BYTES2, 0);
  2405. /* Send either WUPA or REQA. All affected tags will backscatter ATQA and change to READY state */
  2406. st25r3916ExecuteCommand(directCmd);
  2407. /* Wait for TXE */
  2408. if(st25r3916WaitForInterruptsTimed(
  2409. ST25R3916_IRQ_MASK_TXE,
  2410. (uint16_t)MAX(rfalConv1fcToMs(fwt), RFAL_ST25R3916_SW_TMR_MIN_1MS)) == 0U) {
  2411. ret = ERR_IO;
  2412. } else {
  2413. /*Check if Observation Mode is enabled and set it on ST25R391x */
  2414. rfalCheckEnableObsModeRx();
  2415. /* Jump into a transceive Rx state for reception (bypass Tx states) */
  2416. gRFAL.state = RFAL_STATE_TXRX;
  2417. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_IDLE;
  2418. gRFAL.TxRx.status = ERR_BUSY;
  2419. /* Execute Transceive Rx blocking */
  2420. ret = rfalTransceiveBlockingRx();
  2421. }
  2422. /* Disable Collision interrupt */
  2423. st25r3916DisableInterrupts((ST25R3916_IRQ_MASK_COL));
  2424. /* ReEnable CRC on Rx */
  2425. st25r3916ClrRegisterBits(ST25R3916_REG_AUX, ST25R3916_REG_AUX_no_crc_rx);
  2426. return ret;
  2427. }
  2428. /*******************************************************************************/
  2429. ReturnCode rfalISO14443ATransceiveAnticollisionFrame(
  2430. uint8_t* buf,
  2431. uint8_t* bytesToSend,
  2432. uint8_t* bitsToSend,
  2433. uint16_t* rxLength,
  2434. uint32_t fwt) {
  2435. ReturnCode ret;
  2436. rfalTransceiveContext ctx;
  2437. uint8_t collByte;
  2438. uint8_t collData;
  2439. /* Check if RFAL is properly initialized */
  2440. if((gRFAL.state < RFAL_STATE_MODE_SET) || (gRFAL.mode != RFAL_MODE_POLL_NFCA)) {
  2441. return ERR_WRONG_STATE;
  2442. }
  2443. /* Check for valid parameters */
  2444. if((buf == NULL) || (bytesToSend == NULL) || (bitsToSend == NULL) || (rxLength == NULL)) {
  2445. return ERR_PARAM;
  2446. }
  2447. /*******************************************************************************/
  2448. /* Set specific Analog Config for Anticolission if needed */
  2449. rfalSetAnalogConfig(
  2450. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA |
  2451. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_ANTICOL));
  2452. /*******************************************************************************/
  2453. /* Enable anti collision to recognise collision in first byte of SENS_REQ */
  2454. st25r3916SetRegisterBits(ST25R3916_REG_ISO14443A_NFC, ST25R3916_REG_ISO14443A_NFC_antcl);
  2455. /* Disable CRC while receiving */
  2456. st25r3916SetRegisterBits(ST25R3916_REG_AUX, ST25R3916_REG_AUX_no_crc_rx);
  2457. /*******************************************************************************/
  2458. /* Prepare for Transceive */
  2459. ctx.flags = ((uint32_t)RFAL_TXRX_FLAGS_CRC_TX_MANUAL | (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_KEEP);
  2460. ctx.txBuf = buf;
  2461. ctx.txBufLen = (uint16_t)(rfalConvBytesToBits(*bytesToSend) + *bitsToSend);
  2462. ctx.rxBuf = &buf[*bytesToSend];
  2463. ctx.rxBufLen = (uint16_t)rfalConvBytesToBits(RFAL_ISO14443A_SDD_RES_LEN);
  2464. ctx.rxRcvdLen = rxLength;
  2465. ctx.fwt = fwt;
  2466. /* Disable Automatic Gain Control (AGC) for better detection of collisions if using Coherent Receiver */
  2467. ctx.flags |=
  2468. (st25r3916CheckReg(
  2469. ST25R3916_REG_AUX, ST25R3916_REG_AUX_dis_corr, ST25R3916_REG_AUX_dis_corr) ?
  2470. (uint32_t)RFAL_TXRX_FLAGS_AGC_OFF :
  2471. 0x00U);
  2472. rfalStartTransceive(&ctx);
  2473. /* Additionally enable bit collision interrupt */
  2474. st25r3916GetInterrupt(ST25R3916_IRQ_MASK_COL);
  2475. st25r3916EnableInterrupts(ST25R3916_IRQ_MASK_COL);
  2476. /*******************************************************************************/
  2477. collByte = 0;
  2478. /* save the collision byte */
  2479. if((*bitsToSend) > 0U) {
  2480. buf[(*bytesToSend)] <<= (RFAL_BITS_IN_BYTE - (*bitsToSend));
  2481. buf[(*bytesToSend)] >>= (RFAL_BITS_IN_BYTE - (*bitsToSend));
  2482. collByte = buf[(*bytesToSend)];
  2483. }
  2484. /*******************************************************************************/
  2485. /* Run Transceive blocking */
  2486. ret = rfalTransceiveRunBlockingTx();
  2487. if(ret == ERR_NONE) {
  2488. ret = rfalTransceiveBlockingRx();
  2489. /*******************************************************************************/
  2490. if((*bitsToSend) > 0U) {
  2491. buf[(*bytesToSend)] >>= (*bitsToSend);
  2492. buf[(*bytesToSend)] <<= (*bitsToSend);
  2493. buf[(*bytesToSend)] |= collByte;
  2494. }
  2495. if((ERR_RF_COLLISION == ret)) {
  2496. /* read out collision register */
  2497. st25r3916ReadRegister(ST25R3916_REG_COLLISION_STATUS, &collData);
  2498. (*bytesToSend) =
  2499. ((collData >> ST25R3916_REG_COLLISION_STATUS_c_byte_shift) &
  2500. 0x0FU); // 4-bits Byte information
  2501. (*bitsToSend) =
  2502. ((collData >> ST25R3916_REG_COLLISION_STATUS_c_bit_shift) &
  2503. 0x07U); // 3-bits bit information
  2504. }
  2505. }
  2506. /*******************************************************************************/
  2507. /* Disable Collision interrupt */
  2508. st25r3916DisableInterrupts((ST25R3916_IRQ_MASK_COL));
  2509. /* Disable anti collision again */
  2510. st25r3916ClrRegisterBits(ST25R3916_REG_ISO14443A_NFC, ST25R3916_REG_ISO14443A_NFC_antcl);
  2511. /* ReEnable CRC on Rx */
  2512. st25r3916ClrRegisterBits(ST25R3916_REG_AUX, ST25R3916_REG_AUX_no_crc_rx);
  2513. /*******************************************************************************/
  2514. /* Restore common Analog configurations for this mode */
  2515. rfalSetAnalogConfig(
  2516. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA | rfalConvBR2ACBR(gRFAL.txBR) |
  2517. RFAL_ANALOG_CONFIG_TX));
  2518. rfalSetAnalogConfig(
  2519. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA | rfalConvBR2ACBR(gRFAL.rxBR) |
  2520. RFAL_ANALOG_CONFIG_RX));
  2521. return ret;
  2522. }
  2523. #endif /* RFAL_FEATURE_NFCA */
  2524. #if RFAL_FEATURE_NFCV
  2525. /*******************************************************************************/
  2526. ReturnCode rfalISO15693TransceiveAnticollisionFrame(
  2527. uint8_t* txBuf,
  2528. uint8_t txBufLen,
  2529. uint8_t* rxBuf,
  2530. uint8_t rxBufLen,
  2531. uint16_t* actLen) {
  2532. ReturnCode ret;
  2533. rfalTransceiveContext ctx;
  2534. /* Check if RFAL is properly initialized */
  2535. if((gRFAL.state < RFAL_STATE_MODE_SET) || (gRFAL.mode != RFAL_MODE_POLL_NFCV)) {
  2536. return ERR_WRONG_STATE;
  2537. }
  2538. /*******************************************************************************/
  2539. /* Set specific Analog Config for Anticolission if needed */
  2540. rfalSetAnalogConfig(
  2541. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCV |
  2542. RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_ANTICOL));
  2543. /* Ignoring collisions before the UID (RES_FLAG + DSFID) */
  2544. gRFAL.nfcvData.ignoreBits = (uint16_t)RFAL_ISO15693_IGNORE_BITS;
  2545. /*******************************************************************************/
  2546. /* Prepare for Transceive */
  2547. ctx.flags =
  2548. ((txBufLen == 0U) ? (uint32_t)RFAL_TXRX_FLAGS_CRC_TX_MANUAL :
  2549. (uint32_t)RFAL_TXRX_FLAGS_CRC_TX_AUTO) |
  2550. (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_KEEP | (uint32_t)RFAL_TXRX_FLAGS_AGC_OFF |
  2551. ((txBufLen == 0U) ?
  2552. (uint32_t)RFAL_TXRX_FLAGS_NFCV_FLAG_MANUAL :
  2553. (uint32_t)
  2554. RFAL_TXRX_FLAGS_NFCV_FLAG_AUTO); /* Disable Automatic Gain Control (AGC) for better detection of collision */
  2555. ctx.txBuf = txBuf;
  2556. ctx.txBufLen = (uint16_t)rfalConvBytesToBits(txBufLen);
  2557. ctx.rxBuf = rxBuf;
  2558. ctx.rxBufLen = (uint16_t)rfalConvBytesToBits(rxBufLen);
  2559. ctx.rxRcvdLen = actLen;
  2560. ctx.fwt = rfalConv64fcTo1fc(ISO15693_FWT);
  2561. rfalStartTransceive(&ctx);
  2562. /*******************************************************************************/
  2563. /* Run Transceive blocking */
  2564. ret = rfalTransceiveRunBlockingTx();
  2565. if(ret == ERR_NONE) {
  2566. ret = rfalTransceiveBlockingRx();
  2567. }
  2568. /* Check if a Transmission error and received data is less then expected */
  2569. if(((ret == ERR_RF_COLLISION) || (ret == ERR_CRC) || (ret == ERR_FRAMING)) &&
  2570. (rfalConvBitsToBytes(*ctx.rxRcvdLen) < RFAL_ISO15693_INV_RES_LEN)) {
  2571. /* If INVENTORY_RES is shorter than expected, tag is still modulating *
  2572. * Ensure that response is complete before next frame */
  2573. platformDelay((uint8_t)((RFAL_ISO15693_INV_RES_LEN - rfalConvBitsToBytes(*ctx.rxRcvdLen)) /
  2574. ((RFAL_ISO15693_INV_RES_LEN / RFAL_ISO15693_INV_RES_DUR) + 1U)));
  2575. }
  2576. /* Restore common Analog configurations for this mode */
  2577. rfalSetAnalogConfig(
  2578. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCV | rfalConvBR2ACBR(gRFAL.txBR) |
  2579. RFAL_ANALOG_CONFIG_TX));
  2580. rfalSetAnalogConfig(
  2581. (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCV | rfalConvBR2ACBR(gRFAL.rxBR) |
  2582. RFAL_ANALOG_CONFIG_RX));
  2583. gRFAL.nfcvData.ignoreBits = 0;
  2584. return ret;
  2585. }
  2586. /*******************************************************************************/
  2587. ReturnCode
  2588. rfalISO15693TransceiveEOFAnticollision(uint8_t* rxBuf, uint8_t rxBufLen, uint16_t* actLen) {
  2589. uint8_t dummy;
  2590. return rfalISO15693TransceiveAnticollisionFrame(&dummy, 0, rxBuf, rxBufLen, actLen);
  2591. }
  2592. /*******************************************************************************/
  2593. ReturnCode rfalISO15693TransceiveEOF(uint8_t* rxBuf, uint8_t rxBufLen, uint16_t* actLen) {
  2594. ReturnCode ret;
  2595. uint8_t dummy;
  2596. /* Check if RFAL is properly initialized */
  2597. if((gRFAL.state < RFAL_STATE_MODE_SET) || (gRFAL.mode != RFAL_MODE_POLL_NFCV)) {
  2598. return ERR_WRONG_STATE;
  2599. }
  2600. /*******************************************************************************/
  2601. /* Run Transceive blocking */
  2602. ret = rfalTransceiveBlockingTxRx(
  2603. &dummy,
  2604. 0,
  2605. rxBuf,
  2606. rxBufLen,
  2607. actLen,
  2608. ((uint32_t)RFAL_TXRX_FLAGS_CRC_TX_MANUAL | (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_KEEP |
  2609. (uint32_t)RFAL_TXRX_FLAGS_AGC_ON),
  2610. rfalConv64fcTo1fc(ISO15693_FWT));
  2611. return ret;
  2612. }
  2613. #endif /* RFAL_FEATURE_NFCV */
  2614. #if RFAL_FEATURE_NFCF
  2615. /*******************************************************************************/
  2616. ReturnCode rfalFeliCaPoll(
  2617. rfalFeliCaPollSlots slots,
  2618. uint16_t sysCode,
  2619. uint8_t reqCode,
  2620. rfalFeliCaPollRes* pollResList,
  2621. uint8_t pollResListSize,
  2622. uint8_t* devicesDetected,
  2623. uint8_t* collisionsDetected) {
  2624. ReturnCode ret;
  2625. uint8_t frame
  2626. [RFAL_FELICA_POLL_REQ_LEN - RFAL_FELICA_LEN_LEN]; // LEN is added by ST25R391x automatically
  2627. uint16_t actLen;
  2628. uint8_t frameIdx;
  2629. uint8_t devDetected;
  2630. uint8_t colDetected;
  2631. rfalEHandling curHandling;
  2632. uint8_t nbSlots;
  2633. /* Check if RFAL is properly initialized */
  2634. if((gRFAL.state < RFAL_STATE_MODE_SET) || (gRFAL.mode != RFAL_MODE_POLL_NFCF)) {
  2635. return ERR_WRONG_STATE;
  2636. }
  2637. frameIdx = 0;
  2638. colDetected = 0;
  2639. devDetected = 0;
  2640. nbSlots = (uint8_t)slots;
  2641. /*******************************************************************************/
  2642. /* Compute SENSF_REQ frame */
  2643. frame[frameIdx++] = (uint8_t)FELICA_CMD_POLLING; /* CMD: SENF_REQ */
  2644. frame[frameIdx++] = (uint8_t)(sysCode >> 8); /* System Code (SC) */
  2645. frame[frameIdx++] = (uint8_t)(sysCode & 0xFFU); /* System Code (SC) */
  2646. frame[frameIdx++] = reqCode; /* Communication Parameter Request (RC)*/
  2647. frame[frameIdx++] = nbSlots; /* TimeSlot (TSN) */
  2648. /*******************************************************************************/
  2649. /* NRT should not stop on reception - Use EMVCo mode to run NRT in nrt_emv *
  2650. * ERRORHANDLING_EMVCO has no special handling for NFC-F mode */
  2651. curHandling = gRFAL.conf.eHandling;
  2652. rfalSetErrorHandling(RFAL_ERRORHANDLING_EMVCO);
  2653. /*******************************************************************************/
  2654. /* Run transceive blocking,
  2655. * Calculate Total Response Time in(64/fc):
  2656. * 512 PICC process time + (n * 256 Time Slot duration) */
  2657. ret = rfalTransceiveBlockingTx(
  2658. frame,
  2659. (uint16_t)frameIdx,
  2660. (uint8_t*)gRFAL.nfcfData.pollResponses,
  2661. RFAL_FELICA_POLL_RES_LEN,
  2662. &actLen,
  2663. (RFAL_TXRX_FLAGS_DEFAULT),
  2664. rfalConv64fcTo1fc(
  2665. RFAL_FELICA_POLL_DELAY_TIME +
  2666. (RFAL_FELICA_POLL_SLOT_TIME * ((uint32_t)nbSlots + 1U))));
  2667. /*******************************************************************************/
  2668. /* If Tx OK, Wait for all responses, store them as soon as they appear */
  2669. if(ret == ERR_NONE) {
  2670. bool timeout;
  2671. do {
  2672. ret = rfalTransceiveBlockingRx();
  2673. if(ret == ERR_TIMEOUT) {
  2674. /* Upon timeout the full Poll Delay + (Slot time)*(nbSlots) has expired */
  2675. timeout = true;
  2676. } else {
  2677. /* Reception done, reEnabled Rx for following Slot */
  2678. st25r3916ExecuteCommand(ST25R3916_CMD_UNMASK_RECEIVE_DATA);
  2679. st25r3916ExecuteCommand(ST25R3916_CMD_RESET_RXGAIN);
  2680. /* If the reception was OK, new device found */
  2681. if(ret == ERR_NONE) {
  2682. devDetected++;
  2683. /* Overwrite the Transceive context for the next reception */
  2684. gRFAL.TxRx.ctx.rxBuf = (uint8_t*)gRFAL.nfcfData.pollResponses[devDetected];
  2685. }
  2686. /* If the reception was not OK, mark as collision */
  2687. else {
  2688. colDetected++;
  2689. }
  2690. /* Check whether NRT has expired meanwhile */
  2691. timeout = st25r3916CheckReg(
  2692. ST25R3916_REG_NFCIP1_BIT_RATE, ST25R3916_REG_NFCIP1_BIT_RATE_nrt_on, 0x00);
  2693. if(!timeout) {
  2694. /* Jump again into transceive Rx state for the following reception */
  2695. gRFAL.TxRx.status = ERR_BUSY;
  2696. gRFAL.state = RFAL_STATE_TXRX;
  2697. gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_IDLE;
  2698. }
  2699. }
  2700. } while(((nbSlots--) != 0U) && !timeout);
  2701. }
  2702. /*******************************************************************************/
  2703. /* Restore NRT to normal mode - back to previous error handling */
  2704. rfalSetErrorHandling(curHandling);
  2705. /*******************************************************************************/
  2706. /* Assign output parameters if requested */
  2707. if((pollResList != NULL) && (pollResListSize > 0U) && (devDetected > 0U)) {
  2708. ST_MEMCPY(
  2709. pollResList,
  2710. gRFAL.nfcfData.pollResponses,
  2711. (RFAL_FELICA_POLL_RES_LEN * (uint32_t)MIN(pollResListSize, devDetected)));
  2712. }
  2713. if(devicesDetected != NULL) {
  2714. *devicesDetected = devDetected;
  2715. }
  2716. if(collisionsDetected != NULL) {
  2717. *collisionsDetected = colDetected;
  2718. }
  2719. return (((colDetected != 0U) || (devDetected != 0U)) ? ERR_NONE : ret);
  2720. }
  2721. #endif /* RFAL_FEATURE_NFCF */
  2722. /*****************************************************************************
  2723. * Listen Mode *
  2724. *****************************************************************************/
  2725. /*******************************************************************************/
  2726. bool rfalIsExtFieldOn(void) {
  2727. return st25r3916IsExtFieldOn();
  2728. }
  2729. #if RFAL_FEATURE_LISTEN_MODE
  2730. /*******************************************************************************/
  2731. ReturnCode rfalListenStart(
  2732. uint32_t lmMask,
  2733. const rfalLmConfPA* confA,
  2734. const rfalLmConfPB* confB,
  2735. const rfalLmConfPF* confF,
  2736. uint8_t* rxBuf,
  2737. uint16_t rxBufLen,
  2738. uint16_t* rxLen) {
  2739. t_rfalPTMem
  2740. PTMem; /* PRQA S 0759 # MISRA 19.2 - Allocating Union where members are of the same type, just different names. Thus no problem can occur. */
  2741. uint8_t* pPTMem;
  2742. uint8_t autoResp;
  2743. /* Check if RFAL is initialized */
  2744. if(gRFAL.state < RFAL_STATE_INIT) {
  2745. return ERR_WRONG_STATE;
  2746. }
  2747. gRFAL.Lm.state = RFAL_LM_STATE_NOT_INIT;
  2748. gRFAL.Lm.mdIrqs = ST25R3916_IRQ_MASK_NONE;
  2749. gRFAL.Lm.mdReg =
  2750. (ST25R3916_REG_MODE_targ_init | ST25R3916_REG_MODE_om_nfc | ST25R3916_REG_MODE_nfc_ar_off);
  2751. /* By default disable all automatic responses */
  2752. autoResp =
  2753. (ST25R3916_REG_PASSIVE_TARGET_d_106_ac_a | ST25R3916_REG_PASSIVE_TARGET_rfu |
  2754. ST25R3916_REG_PASSIVE_TARGET_d_212_424_1r | ST25R3916_REG_PASSIVE_TARGET_d_ac_ap2p);
  2755. /*******************************************************************************/
  2756. if((lmMask & RFAL_LM_MASK_NFCA) != 0U) {
  2757. /* Check if the conf has been provided */
  2758. if(confA == NULL) {
  2759. return ERR_PARAM;
  2760. }
  2761. pPTMem = (uint8_t*)PTMem.PTMem_A;
  2762. /*******************************************************************************/
  2763. /* Check and set supported NFCID Length */
  2764. switch(confA->nfcidLen) {
  2765. case RFAL_LM_NFCID_LEN_04:
  2766. st25r3916ChangeRegisterBits(
  2767. ST25R3916_REG_AUX, ST25R3916_REG_AUX_nfc_id_mask, ST25R3916_REG_AUX_nfc_id_4bytes);
  2768. break;
  2769. case RFAL_LM_NFCID_LEN_07:
  2770. st25r3916ChangeRegisterBits(
  2771. ST25R3916_REG_AUX, ST25R3916_REG_AUX_nfc_id_mask, ST25R3916_REG_AUX_nfc_id_7bytes);
  2772. break;
  2773. default:
  2774. return ERR_PARAM;
  2775. }
  2776. /*******************************************************************************/
  2777. /* Set NFCID */
  2778. ST_MEMCPY(pPTMem, confA->nfcid, RFAL_NFCID1_TRIPLE_LEN);
  2779. pPTMem = &pPTMem[RFAL_NFCID1_TRIPLE_LEN]; /* MISRA 18.4 */
  2780. /* Set SENS_RES */
  2781. ST_MEMCPY(pPTMem, confA->SENS_RES, RFAL_LM_SENS_RES_LEN);
  2782. pPTMem = &pPTMem[RFAL_LM_SENS_RES_LEN]; /* MISRA 18.4 */
  2783. /* Set SEL_RES */
  2784. *pPTMem++ =
  2785. ((confA->nfcidLen == RFAL_LM_NFCID_LEN_04) ?
  2786. (confA->SEL_RES & ~RFAL_LM_NFCID_INCOMPLETE) :
  2787. (confA->SEL_RES | RFAL_LM_NFCID_INCOMPLETE));
  2788. *pPTMem++ = (confA->SEL_RES & ~RFAL_LM_NFCID_INCOMPLETE);
  2789. *pPTMem++ = (confA->SEL_RES & ~RFAL_LM_NFCID_INCOMPLETE);
  2790. /* Write into PTMem-A */
  2791. st25r3916WritePTMem(PTMem.PTMem_A, ST25R3916_PTM_A_LEN);
  2792. /*******************************************************************************/
  2793. /* Enable automatic responses for A */
  2794. autoResp &= ~ST25R3916_REG_PASSIVE_TARGET_d_106_ac_a;
  2795. /* Set Target mode, Bit Rate detection and Listen Mode for NFC-F */
  2796. gRFAL.Lm.mdReg |=
  2797. (ST25R3916_REG_MODE_targ_targ | ST25R3916_REG_MODE_om3 | ST25R3916_REG_MODE_om0 |
  2798. ST25R3916_REG_MODE_nfc_ar_off);
  2799. gRFAL.Lm.mdIrqs |=
  2800. (ST25R3916_IRQ_MASK_WU_A | ST25R3916_IRQ_MASK_WU_A_X | ST25R3916_IRQ_MASK_RXE_PTA);
  2801. }
  2802. /*******************************************************************************/
  2803. if((lmMask & RFAL_LM_MASK_NFCB) != 0U) {
  2804. /* Check if the conf has been provided */
  2805. if(confB == NULL) {
  2806. return ERR_PARAM;
  2807. }
  2808. return ERR_NOTSUPP;
  2809. }
  2810. /*******************************************************************************/
  2811. if((lmMask & RFAL_LM_MASK_NFCF) != 0U) {
  2812. pPTMem = (uint8_t*)PTMem.PTMem_F;
  2813. /* Check if the conf has been provided */
  2814. if(confF == NULL) {
  2815. return ERR_PARAM;
  2816. }
  2817. /*******************************************************************************/
  2818. /* Set System Code */
  2819. ST_MEMCPY(pPTMem, confF->SC, RFAL_LM_SENSF_SC_LEN);
  2820. pPTMem = &pPTMem[RFAL_LM_SENSF_SC_LEN]; /* MISRA 18.4 */
  2821. /* Set SENSF_RES */
  2822. ST_MEMCPY(pPTMem, confF->SENSF_RES, RFAL_LM_SENSF_RES_LEN);
  2823. /* Set RD bytes to 0x00 as ST25R3916 cannot support advances features */
  2824. pPTMem[RFAL_LM_SENSF_RD0_POS] =
  2825. 0x00; /* NFC Forum Digital 1.1 Table 46: 0x00 */
  2826. pPTMem[RFAL_LM_SENSF_RD1_POS] =
  2827. 0x00; /* NFC Forum Digital 1.1 Table 47: No automatic bit rates */
  2828. pPTMem = &pPTMem[RFAL_LM_SENS_RES_LEN]; /* MISRA 18.4 */
  2829. /* Write into PTMem-F */
  2830. st25r3916WritePTMemF(PTMem.PTMem_F, ST25R3916_PTM_F_LEN);
  2831. /*******************************************************************************/
  2832. /* Write 24 TSN "Random" Numbers at first initialization and let it rollover */
  2833. if(!gRFAL.Lm.iniFlag) {
  2834. pPTMem = (uint8_t*)PTMem.TSN;
  2835. *pPTMem++ = 0x12;
  2836. *pPTMem++ = 0x34;
  2837. *pPTMem++ = 0x56;
  2838. *pPTMem++ = 0x78;
  2839. *pPTMem++ = 0x9A;
  2840. *pPTMem++ = 0xBC;
  2841. *pPTMem++ = 0xDF;
  2842. *pPTMem++ = 0x21;
  2843. *pPTMem++ = 0x43;
  2844. *pPTMem++ = 0x65;
  2845. *pPTMem++ = 0x87;
  2846. *pPTMem++ = 0xA9;
  2847. /* Write into PTMem-TSN */
  2848. st25r3916WritePTMemTSN(PTMem.TSN, ST25R3916_PTM_TSN_LEN);
  2849. }
  2850. /*******************************************************************************/
  2851. /* Enable automatic responses for F */
  2852. autoResp &= ~(ST25R3916_REG_PASSIVE_TARGET_d_212_424_1r);
  2853. /* Set Target mode, Bit Rate detection and Listen Mode for NFC-F */
  2854. gRFAL.Lm.mdReg |=
  2855. (ST25R3916_REG_MODE_targ_targ | ST25R3916_REG_MODE_om3 | ST25R3916_REG_MODE_om2 |
  2856. ST25R3916_REG_MODE_nfc_ar_off);
  2857. /* In CE NFC-F any data without error will be passed to FIFO, to support CUP */
  2858. gRFAL.Lm.mdIrqs |=
  2859. (ST25R3916_IRQ_MASK_WU_F | ST25R3916_IRQ_MASK_RXE_PTA | ST25R3916_IRQ_MASK_RXE);
  2860. }
  2861. /*******************************************************************************/
  2862. if((lmMask & RFAL_LM_MASK_ACTIVE_P2P) != 0U) {
  2863. /* Enable Reception of P2P frames */
  2864. autoResp &= ~(ST25R3916_REG_PASSIVE_TARGET_d_ac_ap2p);
  2865. /* Set Target mode, Bit Rate detection and Automatic Response RF Collision Avoidance */
  2866. gRFAL.Lm.mdReg |=
  2867. (ST25R3916_REG_MODE_targ_targ | ST25R3916_REG_MODE_om3 | ST25R3916_REG_MODE_om2 |
  2868. ST25R3916_REG_MODE_om0 | ST25R3916_REG_MODE_nfc_ar_auto_rx);
  2869. /* n * TRFW timing shall vary Activity 2.1 3.4.1.1 */
  2870. st25r3916ChangeRegisterBits(
  2871. ST25R3916_REG_AUX, ST25R3916_REG_AUX_nfc_n_mask, gRFAL.timings.nTRFW);
  2872. gRFAL.timings.nTRFW = rfalGennTRFW(gRFAL.timings.nTRFW);
  2873. gRFAL.Lm.mdIrqs |= (ST25R3916_IRQ_MASK_RXE);
  2874. }
  2875. /* Check if one of the modes were selected */
  2876. if((gRFAL.Lm.mdReg & ST25R3916_REG_MODE_targ) == ST25R3916_REG_MODE_targ_targ) {
  2877. gRFAL.state = RFAL_STATE_LM;
  2878. gRFAL.Lm.mdMask = lmMask;
  2879. gRFAL.Lm.rxBuf = rxBuf;
  2880. gRFAL.Lm.rxBufLen = rxBufLen;
  2881. gRFAL.Lm.rxLen = rxLen;
  2882. *gRFAL.Lm.rxLen = 0;
  2883. gRFAL.Lm.dataFlag = false;
  2884. gRFAL.Lm.iniFlag = true;
  2885. /* Apply the Automatic Responses configuration */
  2886. st25r3916ChangeRegisterBits(
  2887. ST25R3916_REG_PASSIVE_TARGET,
  2888. (ST25R3916_REG_PASSIVE_TARGET_d_106_ac_a | ST25R3916_REG_PASSIVE_TARGET_rfu |
  2889. ST25R3916_REG_PASSIVE_TARGET_d_212_424_1r | ST25R3916_REG_PASSIVE_TARGET_d_ac_ap2p),
  2890. autoResp);
  2891. /* Disable GPT trigger source */
  2892. st25r3916ChangeRegisterBits(
  2893. ST25R3916_REG_TIMER_EMV_CONTROL,
  2894. ST25R3916_REG_TIMER_EMV_CONTROL_gptc_mask,
  2895. ST25R3916_REG_TIMER_EMV_CONTROL_gptc_no_trigger);
  2896. /* On Bit Rate Detection Mode ST25R391x will filter incoming frames during MRT time starting on External Field On event, use 512/fc steps */
  2897. st25r3916SetRegisterBits(
  2898. ST25R3916_REG_TIMER_EMV_CONTROL, ST25R3916_REG_TIMER_EMV_CONTROL_mrt_step_512);
  2899. st25r3916WriteRegister(
  2900. ST25R3916_REG_MASK_RX_TIMER, (uint8_t)rfalConv1fcTo512fc(RFAL_LM_GT));
  2901. /* Restore default settings on NFCIP1 mode, Receiving parity + CRC bits and manual Tx Parity*/
  2902. st25r3916ClrRegisterBits(
  2903. ST25R3916_REG_ISO14443A_NFC,
  2904. (ST25R3916_REG_ISO14443A_NFC_no_tx_par | ST25R3916_REG_ISO14443A_NFC_no_rx_par |
  2905. ST25R3916_REG_ISO14443A_NFC_nfc_f0));
  2906. /* External Field Detector enabled as Automatics on rfalInitialize() */
  2907. /* Set Analog configurations for generic Listen mode */
  2908. /* Not on SetState(POWER OFF) as otherwise would be applied on every Field Event */
  2909. rfalSetAnalogConfig((RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_LISTEN_ON));
  2910. /* Initialize as POWER_OFF and set proper mode in RF Chip */
  2911. rfalListenSetState(RFAL_LM_STATE_POWER_OFF);
  2912. } else {
  2913. return ERR_REQUEST; /* Listen Start called but no mode was enabled */
  2914. }
  2915. return ERR_NONE;
  2916. }
  2917. /*******************************************************************************/
  2918. static ReturnCode rfalRunListenModeWorker(void) {
  2919. volatile uint32_t irqs;
  2920. uint8_t tmp;
  2921. if(gRFAL.state != RFAL_STATE_LM) {
  2922. return ERR_WRONG_STATE;
  2923. }
  2924. switch(gRFAL.Lm.state) {
  2925. /*******************************************************************************/
  2926. case RFAL_LM_STATE_POWER_OFF:
  2927. irqs = st25r3916GetInterrupt((ST25R3916_IRQ_MASK_EON));
  2928. if(irqs == ST25R3916_IRQ_MASK_NONE) {
  2929. break; /* No interrupt to process */
  2930. }
  2931. if((irqs & ST25R3916_IRQ_MASK_EON) != 0U) {
  2932. rfalListenSetState(RFAL_LM_STATE_IDLE);
  2933. } else {
  2934. break;
  2935. }
  2936. /* fall through */
  2937. /*******************************************************************************/
  2938. case RFAL_LM_STATE_IDLE: /* PRQA S 2003 # MISRA 16.3 - Intentional fall through */
  2939. irqs = st25r3916GetInterrupt(
  2940. (ST25R3916_IRQ_MASK_NFCT | ST25R3916_IRQ_MASK_WU_F | ST25R3916_IRQ_MASK_RXE |
  2941. ST25R3916_IRQ_MASK_EOF | ST25R3916_IRQ_MASK_RXE_PTA));
  2942. if(irqs == ST25R3916_IRQ_MASK_NONE) {
  2943. break; /* No interrupt to process */
  2944. }
  2945. if((irqs & ST25R3916_IRQ_MASK_NFCT) != 0U) {
  2946. /* Retrieve detected bitrate */
  2947. uint8_t newBr;
  2948. st25r3916ReadRegister(ST25R3916_REG_NFCIP1_BIT_RATE, &newBr);
  2949. newBr >>= ST25R3916_REG_NFCIP1_BIT_RATE_nfc_rate_shift;
  2950. if(newBr > ST25R3916_REG_BIT_RATE_rxrate_424) {
  2951. newBr = ST25R3916_REG_BIT_RATE_rxrate_424;
  2952. }
  2953. gRFAL.Lm.brDetected =
  2954. (rfalBitRate)(newBr); /* PRQA S 4342 # MISRA 10.5 - Guaranteed that no invalid enum values may be created. See also equalityGuard_RFAL_BR_106 ff.*/
  2955. }
  2956. if(((irqs & ST25R3916_IRQ_MASK_WU_F) != 0U) && (gRFAL.Lm.brDetected != RFAL_BR_KEEP)) {
  2957. rfalListenSetState(RFAL_LM_STATE_READY_F);
  2958. } else if(((irqs & ST25R3916_IRQ_MASK_RXE) != 0U) && (gRFAL.Lm.brDetected != RFAL_BR_KEEP)) {
  2959. irqs = st25r3916GetInterrupt(
  2960. (ST25R3916_IRQ_MASK_WU_F | ST25R3916_IRQ_MASK_RXE | ST25R3916_IRQ_MASK_EOF |
  2961. ST25R3916_IRQ_MASK_CRC | ST25R3916_IRQ_MASK_PAR | ST25R3916_IRQ_MASK_ERR2 |
  2962. ST25R3916_IRQ_MASK_ERR1));
  2963. if(((irqs & ST25R3916_IRQ_MASK_CRC) != 0U) ||
  2964. ((irqs & ST25R3916_IRQ_MASK_PAR) != 0U) ||
  2965. ((irqs & ST25R3916_IRQ_MASK_ERR1) != 0U)) {
  2966. st25r3916ExecuteCommand(ST25R3916_CMD_CLEAR_FIFO);
  2967. st25r3916ExecuteCommand(ST25R3916_CMD_UNMASK_RECEIVE_DATA);
  2968. st25r3916TxOff();
  2969. break; /* A bad reception occurred, remain in same state */
  2970. }
  2971. /* Retrieve received data */
  2972. *gRFAL.Lm.rxLen = st25r3916GetNumFIFOBytes();
  2973. st25r3916ReadFifo(
  2974. gRFAL.Lm.rxBuf, MIN(*gRFAL.Lm.rxLen, rfalConvBitsToBytes(gRFAL.Lm.rxBufLen)));
  2975. /*******************************************************************************/
  2976. /* REMARK: Silicon workaround ST25R3916 Errata #TBD */
  2977. /* In bitrate detection mode CRC is now checked for NFC-A frames */
  2978. if((*gRFAL.Lm.rxLen > RFAL_CRC_LEN) && (gRFAL.Lm.brDetected == RFAL_BR_106)) {
  2979. if(rfalCrcCalculateCcitt(
  2980. RFAL_ISO14443A_CRC_INTVAL, gRFAL.Lm.rxBuf, *gRFAL.Lm.rxLen) != 0U) {
  2981. st25r3916ExecuteCommand(ST25R3916_CMD_CLEAR_FIFO);
  2982. st25r3916ExecuteCommand(ST25R3916_CMD_UNMASK_RECEIVE_DATA);
  2983. st25r3916TxOff();
  2984. break; /* A bad reception occurred, remain in same state */
  2985. }
  2986. }
  2987. /*******************************************************************************/
  2988. /* Check if the data we got has at least the CRC and remove it, otherwise leave at 0 */
  2989. *gRFAL.Lm.rxLen -= ((*gRFAL.Lm.rxLen > RFAL_CRC_LEN) ? RFAL_CRC_LEN : *gRFAL.Lm.rxLen);
  2990. *gRFAL.Lm.rxLen = (uint16_t)rfalConvBytesToBits(*gRFAL.Lm.rxLen);
  2991. gRFAL.Lm.dataFlag = true;
  2992. /*Check if Observation Mode was enabled and disable it on ST25R391x */
  2993. rfalCheckDisableObsMode();
  2994. } else if(
  2995. ((irqs & ST25R3916_IRQ_MASK_RXE_PTA) != 0U) && (gRFAL.Lm.brDetected != RFAL_BR_KEEP)) {
  2996. if(((gRFAL.Lm.mdMask & RFAL_LM_MASK_NFCA) != 0U) &&
  2997. (gRFAL.Lm.brDetected == RFAL_BR_106)) {
  2998. st25r3916ReadRegister(ST25R3916_REG_PASSIVE_TARGET_STATUS, &tmp);
  2999. if(tmp > ST25R3916_REG_PASSIVE_TARGET_STATUS_pta_st_idle) {
  3000. rfalListenSetState(RFAL_LM_STATE_READY_A);
  3001. }
  3002. }
  3003. } else if(((irqs & ST25R3916_IRQ_MASK_EOF) != 0U) && (!gRFAL.Lm.dataFlag)) {
  3004. rfalListenSetState(RFAL_LM_STATE_POWER_OFF);
  3005. } else {
  3006. /* MISRA 15.7 - Empty else */
  3007. }
  3008. break;
  3009. /*******************************************************************************/
  3010. case RFAL_LM_STATE_READY_F:
  3011. irqs = st25r3916GetInterrupt(
  3012. (ST25R3916_IRQ_MASK_WU_F | ST25R3916_IRQ_MASK_RXE | ST25R3916_IRQ_MASK_EOF));
  3013. if(irqs == ST25R3916_IRQ_MASK_NONE) {
  3014. break; /* No interrupt to process */
  3015. }
  3016. if((irqs & ST25R3916_IRQ_MASK_WU_F) != 0U) {
  3017. break;
  3018. } else if((irqs & ST25R3916_IRQ_MASK_RXE) != 0U) {
  3019. /* Retrieve the error flags/irqs */
  3020. irqs |= st25r3916GetInterrupt(
  3021. (ST25R3916_IRQ_MASK_CRC | ST25R3916_IRQ_MASK_ERR2 | ST25R3916_IRQ_MASK_ERR1));
  3022. if(((irqs & ST25R3916_IRQ_MASK_CRC) != 0U) ||
  3023. ((irqs & ST25R3916_IRQ_MASK_ERR1) != 0U)) {
  3024. st25r3916ExecuteCommand(ST25R3916_CMD_CLEAR_FIFO);
  3025. st25r3916ExecuteCommand(ST25R3916_CMD_UNMASK_RECEIVE_DATA);
  3026. break; /* A bad reception occurred, remain in same state */
  3027. }
  3028. /* Retrieve received data */
  3029. *gRFAL.Lm.rxLen = st25r3916GetNumFIFOBytes();
  3030. st25r3916ReadFifo(
  3031. gRFAL.Lm.rxBuf, MIN(*gRFAL.Lm.rxLen, rfalConvBitsToBytes(gRFAL.Lm.rxBufLen)));
  3032. /* Check if the data we got has at least the CRC and remove it, otherwise leave at 0 */
  3033. *gRFAL.Lm.rxLen -= ((*gRFAL.Lm.rxLen > RFAL_CRC_LEN) ? RFAL_CRC_LEN : *gRFAL.Lm.rxLen);
  3034. *gRFAL.Lm.rxLen = (uint16_t)rfalConvBytesToBits(*gRFAL.Lm.rxLen);
  3035. gRFAL.Lm.dataFlag = true;
  3036. } else if((irqs & ST25R3916_IRQ_MASK_EOF) != 0U) {
  3037. rfalListenSetState(RFAL_LM_STATE_POWER_OFF);
  3038. } else {
  3039. /* MISRA 15.7 - Empty else */
  3040. }
  3041. break;
  3042. /*******************************************************************************/
  3043. case RFAL_LM_STATE_READY_A:
  3044. irqs = st25r3916GetInterrupt((ST25R3916_IRQ_MASK_EOF | ST25R3916_IRQ_MASK_WU_A));
  3045. if(irqs == ST25R3916_IRQ_MASK_NONE) {
  3046. break; /* No interrupt to process */
  3047. }
  3048. if((irqs & ST25R3916_IRQ_MASK_WU_A) != 0U) {
  3049. rfalListenSetState(RFAL_LM_STATE_ACTIVE_A);
  3050. } else if((irqs & ST25R3916_IRQ_MASK_EOF) != 0U) {
  3051. rfalListenSetState(RFAL_LM_STATE_POWER_OFF);
  3052. } else {
  3053. /* MISRA 15.7 - Empty else */
  3054. }
  3055. break;
  3056. /*******************************************************************************/
  3057. case RFAL_LM_STATE_ACTIVE_A:
  3058. case RFAL_LM_STATE_ACTIVE_Ax:
  3059. irqs = st25r3916GetInterrupt((ST25R3916_IRQ_MASK_RXE | ST25R3916_IRQ_MASK_EOF));
  3060. if(irqs == ST25R3916_IRQ_MASK_NONE) {
  3061. break; /* No interrupt to process */
  3062. }
  3063. if((irqs & ST25R3916_IRQ_MASK_RXE) != 0U) {
  3064. /* Retrieve the error flags/irqs */
  3065. irqs |= st25r3916GetInterrupt(
  3066. (ST25R3916_IRQ_MASK_PAR | ST25R3916_IRQ_MASK_CRC | ST25R3916_IRQ_MASK_ERR2 |
  3067. ST25R3916_IRQ_MASK_ERR1));
  3068. *gRFAL.Lm.rxLen = st25r3916GetNumFIFOBytes();
  3069. if(((irqs & ST25R3916_IRQ_MASK_CRC) != 0U) ||
  3070. ((irqs & ST25R3916_IRQ_MASK_ERR1) != 0U) ||
  3071. ((irqs & ST25R3916_IRQ_MASK_PAR) != 0U) || (*gRFAL.Lm.rxLen <= RFAL_CRC_LEN)) {
  3072. /* Clear rx context and FIFO */
  3073. *gRFAL.Lm.rxLen = 0;
  3074. st25r3916ExecuteCommand(ST25R3916_CMD_CLEAR_FIFO);
  3075. st25r3916ExecuteCommand(ST25R3916_CMD_UNMASK_RECEIVE_DATA);
  3076. /* Check if we should go to IDLE or Sleep */
  3077. if(gRFAL.Lm.state == RFAL_LM_STATE_ACTIVE_Ax) {
  3078. rfalListenSleepStart(
  3079. RFAL_LM_STATE_SLEEP_A, gRFAL.Lm.rxBuf, gRFAL.Lm.rxBufLen, gRFAL.Lm.rxLen);
  3080. } else {
  3081. rfalListenSetState(RFAL_LM_STATE_IDLE);
  3082. }
  3083. st25r3916DisableInterrupts(ST25R3916_IRQ_MASK_RXE);
  3084. break;
  3085. }
  3086. /* Remove CRC from length */
  3087. *gRFAL.Lm.rxLen -= RFAL_CRC_LEN;
  3088. /* Retrieve received data */
  3089. st25r3916ReadFifo(
  3090. gRFAL.Lm.rxBuf, MIN(*gRFAL.Lm.rxLen, rfalConvBitsToBytes(gRFAL.Lm.rxBufLen)));
  3091. *gRFAL.Lm.rxLen = (uint16_t)rfalConvBytesToBits(*gRFAL.Lm.rxLen);
  3092. gRFAL.Lm.dataFlag = true;
  3093. } else if((irqs & ST25R3916_IRQ_MASK_EOF) != 0U) {
  3094. rfalListenSetState(RFAL_LM_STATE_POWER_OFF);
  3095. } else {
  3096. /* MISRA 15.7 - Empty else */
  3097. }
  3098. break;
  3099. /*******************************************************************************/
  3100. case RFAL_LM_STATE_SLEEP_A:
  3101. case RFAL_LM_STATE_SLEEP_B:
  3102. case RFAL_LM_STATE_SLEEP_AF:
  3103. irqs = st25r3916GetInterrupt(
  3104. (ST25R3916_IRQ_MASK_NFCT | ST25R3916_IRQ_MASK_WU_F | ST25R3916_IRQ_MASK_RXE |
  3105. ST25R3916_IRQ_MASK_EOF | ST25R3916_IRQ_MASK_RXE_PTA));
  3106. if(irqs == ST25R3916_IRQ_MASK_NONE) {
  3107. break; /* No interrupt to process */
  3108. }
  3109. if((irqs & ST25R3916_IRQ_MASK_NFCT) != 0U) {
  3110. uint8_t newBr;
  3111. /* Retrieve detected bitrate */
  3112. st25r3916ReadRegister(ST25R3916_REG_NFCIP1_BIT_RATE, &newBr);
  3113. newBr >>= ST25R3916_REG_NFCIP1_BIT_RATE_nfc_rate_shift;
  3114. if(newBr > ST25R3916_REG_BIT_RATE_rxrate_424) {
  3115. newBr = ST25R3916_REG_BIT_RATE_rxrate_424;
  3116. }
  3117. gRFAL.Lm.brDetected =
  3118. (rfalBitRate)(newBr); /* PRQA S 4342 # MISRA 10.5 - Guaranteed that no invalid enum values may be created. See also equalityGuard_RFAL_BR_106 ff.*/
  3119. }
  3120. if(((irqs & ST25R3916_IRQ_MASK_WU_F) != 0U) && (gRFAL.Lm.brDetected != RFAL_BR_KEEP)) {
  3121. rfalListenSetState(RFAL_LM_STATE_READY_F);
  3122. } else if(((irqs & ST25R3916_IRQ_MASK_RXE) != 0U) && (gRFAL.Lm.brDetected != RFAL_BR_KEEP)) {
  3123. /* Clear rx context and FIFO */
  3124. *gRFAL.Lm.rxLen = 0;
  3125. st25r3916ExecuteCommand(ST25R3916_CMD_CLEAR_FIFO);
  3126. st25r3916ExecuteCommand(ST25R3916_CMD_UNMASK_RECEIVE_DATA);
  3127. /* REMARK: In order to support CUP or proprietary frames, handling could be added here */
  3128. } else if(
  3129. ((irqs & ST25R3916_IRQ_MASK_RXE_PTA) != 0U) && (gRFAL.Lm.brDetected != RFAL_BR_KEEP)) {
  3130. if(((gRFAL.Lm.mdMask & RFAL_LM_MASK_NFCA) != 0U) &&
  3131. (gRFAL.Lm.brDetected == RFAL_BR_106)) {
  3132. st25r3916ReadRegister(ST25R3916_REG_PASSIVE_TARGET_STATUS, &tmp);
  3133. if(tmp > ST25R3916_REG_PASSIVE_TARGET_STATUS_pta_st_halt) {
  3134. rfalListenSetState(RFAL_LM_STATE_READY_Ax);
  3135. }
  3136. }
  3137. } else if((irqs & ST25R3916_IRQ_MASK_EOF) != 0U) {
  3138. rfalListenSetState(RFAL_LM_STATE_POWER_OFF);
  3139. } else {
  3140. /* MISRA 15.7 - Empty else */
  3141. }
  3142. break;
  3143. /*******************************************************************************/
  3144. case RFAL_LM_STATE_READY_Ax:
  3145. irqs = st25r3916GetInterrupt((ST25R3916_IRQ_MASK_EOF | ST25R3916_IRQ_MASK_WU_A_X));
  3146. if(irqs == ST25R3916_IRQ_MASK_NONE) {
  3147. break; /* No interrupt to process */
  3148. }
  3149. if((irqs & ST25R3916_IRQ_MASK_WU_A_X) != 0U) {
  3150. rfalListenSetState(RFAL_LM_STATE_ACTIVE_Ax);
  3151. } else if((irqs & ST25R3916_IRQ_MASK_EOF) != 0U) {
  3152. rfalListenSetState(RFAL_LM_STATE_POWER_OFF);
  3153. } else {
  3154. /* MISRA 15.7 - Empty else */
  3155. }
  3156. break;
  3157. /*******************************************************************************/
  3158. case RFAL_LM_STATE_CARDEMU_4A:
  3159. case RFAL_LM_STATE_CARDEMU_4B:
  3160. case RFAL_LM_STATE_CARDEMU_3:
  3161. case RFAL_LM_STATE_TARGET_F:
  3162. case RFAL_LM_STATE_TARGET_A:
  3163. break;
  3164. /*******************************************************************************/
  3165. default:
  3166. return ERR_WRONG_STATE;
  3167. }
  3168. return ERR_NONE;
  3169. }
  3170. /*******************************************************************************/
  3171. ReturnCode rfalListenStop(void) {
  3172. /* Check if RFAL is initialized */
  3173. if(gRFAL.state < RFAL_STATE_INIT) {
  3174. return ERR_WRONG_STATE;
  3175. }
  3176. gRFAL.Lm.state = RFAL_LM_STATE_NOT_INIT;
  3177. /*Check if Observation Mode was enabled and disable it on ST25R391x */
  3178. rfalCheckDisableObsMode();
  3179. /* Re-Enable the Oscillator if not running */
  3180. st25r3916OscOn();
  3181. /* Disable Receiver and Transmitter */
  3182. rfalFieldOff();
  3183. /* Disable all automatic responses */
  3184. st25r3916SetRegisterBits(
  3185. ST25R3916_REG_PASSIVE_TARGET,
  3186. (ST25R3916_REG_PASSIVE_TARGET_d_212_424_1r | ST25R3916_REG_PASSIVE_TARGET_rfu |
  3187. ST25R3916_REG_PASSIVE_TARGET_d_106_ac_a | ST25R3916_REG_PASSIVE_TARGET_d_ac_ap2p));
  3188. /* As there's no Off mode, set default value: ISO14443A with automatic RF Collision Avoidance Off */
  3189. st25r3916WriteRegister(
  3190. ST25R3916_REG_MODE,
  3191. (ST25R3916_REG_MODE_om_iso14443a | ST25R3916_REG_MODE_tr_am_ook |
  3192. ST25R3916_REG_MODE_nfc_ar_off));
  3193. st25r3916DisableInterrupts(
  3194. (ST25R3916_IRQ_MASK_RXE_PTA | ST25R3916_IRQ_MASK_WU_F | ST25R3916_IRQ_MASK_WU_A |
  3195. ST25R3916_IRQ_MASK_WU_A_X | ST25R3916_IRQ_MASK_RFU2 | ST25R3916_IRQ_MASK_OSC));
  3196. st25r3916GetInterrupt(
  3197. (ST25R3916_IRQ_MASK_RXE_PTA | ST25R3916_IRQ_MASK_WU_F | ST25R3916_IRQ_MASK_WU_A |
  3198. ST25R3916_IRQ_MASK_WU_A_X | ST25R3916_IRQ_MASK_RFU2));
  3199. /* Set Analog configurations for Listen Off event */
  3200. rfalSetAnalogConfig((RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_LISTEN_OFF));
  3201. return ERR_NONE;
  3202. }
  3203. /*******************************************************************************/
  3204. ReturnCode
  3205. rfalListenSleepStart(rfalLmState sleepSt, uint8_t* rxBuf, uint16_t rxBufLen, uint16_t* rxLen) {
  3206. /* Check if RFAL is not initialized */
  3207. if(gRFAL.state < RFAL_STATE_INIT) {
  3208. return ERR_WRONG_STATE;
  3209. }
  3210. switch(sleepSt) {
  3211. /*******************************************************************************/
  3212. case RFAL_LM_STATE_SLEEP_A:
  3213. /* Enable automatic responses for A */
  3214. st25r3916ClrRegisterBits(
  3215. ST25R3916_REG_PASSIVE_TARGET, (ST25R3916_REG_PASSIVE_TARGET_d_106_ac_a));
  3216. /* Reset NFCA target */
  3217. st25r3916ExecuteCommand(ST25R3916_CMD_GOTO_SLEEP);
  3218. /* Set Target mode, Bit Rate detection and Listen Mode for NFC-A */
  3219. st25r3916ChangeRegisterBits(
  3220. ST25R3916_REG_MODE,
  3221. (ST25R3916_REG_MODE_targ | ST25R3916_REG_MODE_om_mask |
  3222. ST25R3916_REG_MODE_nfc_ar_mask),
  3223. (ST25R3916_REG_MODE_targ_targ | ST25R3916_REG_MODE_om3 | ST25R3916_REG_MODE_om0 |
  3224. ST25R3916_REG_MODE_nfc_ar_off));
  3225. break;
  3226. /*******************************************************************************/
  3227. case RFAL_LM_STATE_SLEEP_AF:
  3228. /* Enable automatic responses for A + F */
  3229. st25r3916ClrRegisterBits(
  3230. ST25R3916_REG_PASSIVE_TARGET,
  3231. (ST25R3916_REG_PASSIVE_TARGET_d_212_424_1r | ST25R3916_REG_PASSIVE_TARGET_d_106_ac_a));
  3232. /* Reset NFCA target state */
  3233. st25r3916ExecuteCommand(ST25R3916_CMD_GOTO_SLEEP);
  3234. /* Set Target mode, Bit Rate detection, Listen Mode for NFC-A and NFC-F */
  3235. st25r3916ChangeRegisterBits(
  3236. ST25R3916_REG_MODE,
  3237. (ST25R3916_REG_MODE_targ | ST25R3916_REG_MODE_om_mask |
  3238. ST25R3916_REG_MODE_nfc_ar_mask),
  3239. (ST25R3916_REG_MODE_targ_targ | ST25R3916_REG_MODE_om3 | ST25R3916_REG_MODE_om2 |
  3240. ST25R3916_REG_MODE_om0 | ST25R3916_REG_MODE_nfc_ar_off));
  3241. break;
  3242. /*******************************************************************************/
  3243. case RFAL_LM_STATE_SLEEP_B:
  3244. /* REMARK: Support for CE-B would be added here */
  3245. return ERR_NOT_IMPLEMENTED;
  3246. /*******************************************************************************/
  3247. default:
  3248. return ERR_PARAM;
  3249. }
  3250. /* Ensure that the NFCIP1 mode is disabled */
  3251. st25r3916ClrRegisterBits(ST25R3916_REG_ISO14443A_NFC, ST25R3916_REG_ISO14443A_NFC_nfc_f0);
  3252. st25r3916ExecuteCommand(ST25R3916_CMD_UNMASK_RECEIVE_DATA);
  3253. /* Clear and enable required IRQs */
  3254. st25r3916ClearAndEnableInterrupts(
  3255. (ST25R3916_IRQ_MASK_NFCT | ST25R3916_IRQ_MASK_RXS | ST25R3916_IRQ_MASK_CRC |
  3256. ST25R3916_IRQ_MASK_ERR1 | ST25R3916_IRQ_MASK_ERR2 | ST25R3916_IRQ_MASK_PAR |
  3257. ST25R3916_IRQ_MASK_EON | ST25R3916_IRQ_MASK_EOF | gRFAL.Lm.mdIrqs));
  3258. /* Check whether the field was turn off right after the Sleep request */
  3259. if(!rfalIsExtFieldOn()) {
  3260. /*rfalLogD( "RFAL: curState: %02X newState: %02X \r\n", gRFAL.Lm.state, RFAL_LM_STATE_NOT_INIT );*/
  3261. rfalListenStop();
  3262. return ERR_LINK_LOSS;
  3263. }
  3264. /*rfalLogD( "RFAL: curState: %02X newState: %02X \r\n", gRFAL.Lm.state, sleepSt );*/
  3265. /* Set the new Sleep State*/
  3266. gRFAL.Lm.state = sleepSt;
  3267. gRFAL.state = RFAL_STATE_LM;
  3268. gRFAL.Lm.rxBuf = rxBuf;
  3269. gRFAL.Lm.rxBufLen = rxBufLen;
  3270. gRFAL.Lm.rxLen = rxLen;
  3271. *gRFAL.Lm.rxLen = 0;
  3272. gRFAL.Lm.dataFlag = false;
  3273. return ERR_NONE;
  3274. }
  3275. /*******************************************************************************/
  3276. rfalLmState rfalListenGetState(bool* dataFlag, rfalBitRate* lastBR) {
  3277. /* Allow state retrieval even if gRFAL.state != RFAL_STATE_LM so *
  3278. * that this Lm state can be used by caller after activation */
  3279. if(lastBR != NULL) {
  3280. *lastBR = gRFAL.Lm.brDetected;
  3281. }
  3282. if(dataFlag != NULL) {
  3283. *dataFlag = gRFAL.Lm.dataFlag;
  3284. }
  3285. return gRFAL.Lm.state;
  3286. }
  3287. /*******************************************************************************/
  3288. ReturnCode rfalListenSetState(rfalLmState newSt) {
  3289. ReturnCode ret;
  3290. rfalLmState newState;
  3291. bool reSetState;
  3292. /* Check if RFAL is initialized */
  3293. if(gRFAL.state < RFAL_STATE_INIT) {
  3294. return ERR_WRONG_STATE;
  3295. }
  3296. /* SetState clears the Data flag */
  3297. gRFAL.Lm.dataFlag = false;
  3298. newState = newSt;
  3299. ret = ERR_NONE;
  3300. do {
  3301. reSetState = false;
  3302. /*******************************************************************************/
  3303. switch(newState) {
  3304. /*******************************************************************************/
  3305. case RFAL_LM_STATE_POWER_OFF:
  3306. /* Enable the receiver and reset logic */
  3307. st25r3916SetRegisterBits(ST25R3916_REG_OP_CONTROL, ST25R3916_REG_OP_CONTROL_rx_en);
  3308. st25r3916ExecuteCommand(ST25R3916_CMD_STOP);
  3309. if((gRFAL.Lm.mdMask & RFAL_LM_MASK_NFCA) != 0U) {
  3310. /* Enable automatic responses for A */
  3311. st25r3916ClrRegisterBits(
  3312. ST25R3916_REG_PASSIVE_TARGET, ST25R3916_REG_PASSIVE_TARGET_d_106_ac_a);
  3313. /* Prepares the NFCIP-1 Passive target logic to wait in the Sense/Idle state */
  3314. st25r3916ExecuteCommand(ST25R3916_CMD_GOTO_SENSE);
  3315. }
  3316. if((gRFAL.Lm.mdMask & RFAL_LM_MASK_NFCF) != 0U) {
  3317. /* Enable automatic responses for F */
  3318. st25r3916ClrRegisterBits(
  3319. ST25R3916_REG_PASSIVE_TARGET, (ST25R3916_REG_PASSIVE_TARGET_d_212_424_1r));
  3320. }
  3321. if((gRFAL.Lm.mdMask & RFAL_LM_MASK_ACTIVE_P2P) != 0U) {
  3322. /* Ensure automatic response RF Collision Avoidance is back to only after Rx */
  3323. st25r3916ChangeRegisterBits(
  3324. ST25R3916_REG_MODE,
  3325. ST25R3916_REG_MODE_nfc_ar_mask,
  3326. ST25R3916_REG_MODE_nfc_ar_auto_rx);
  3327. /* Ensure that our field is Off, as automatic response RF Collision Avoidance may have been triggered */
  3328. st25r3916TxOff();
  3329. }
  3330. /*******************************************************************************/
  3331. /* Ensure that the NFCIP1 mode is disabled */
  3332. st25r3916ClrRegisterBits(
  3333. ST25R3916_REG_ISO14443A_NFC, ST25R3916_REG_ISO14443A_NFC_nfc_f0);
  3334. /*******************************************************************************/
  3335. /* Clear and enable required IRQs */
  3336. st25r3916DisableInterrupts(ST25R3916_IRQ_MASK_ALL);
  3337. st25r3916ClearAndEnableInterrupts(
  3338. (ST25R3916_IRQ_MASK_NFCT | ST25R3916_IRQ_MASK_RXS | ST25R3916_IRQ_MASK_CRC |
  3339. ST25R3916_IRQ_MASK_ERR1 | ST25R3916_IRQ_MASK_OSC | ST25R3916_IRQ_MASK_ERR2 |
  3340. ST25R3916_IRQ_MASK_PAR | ST25R3916_IRQ_MASK_EON | ST25R3916_IRQ_MASK_EOF |
  3341. gRFAL.Lm.mdIrqs));
  3342. /*******************************************************************************/
  3343. /* Clear the bitRate previously detected */
  3344. gRFAL.Lm.brDetected = RFAL_BR_KEEP;
  3345. /*******************************************************************************/
  3346. /* Apply the initial mode */
  3347. st25r3916ChangeRegisterBits(
  3348. ST25R3916_REG_MODE,
  3349. (ST25R3916_REG_MODE_targ | ST25R3916_REG_MODE_om_mask |
  3350. ST25R3916_REG_MODE_nfc_ar_mask),
  3351. (uint8_t)gRFAL.Lm.mdReg);
  3352. /*******************************************************************************/
  3353. /* Check if external Field is already On */
  3354. if(rfalIsExtFieldOn()) {
  3355. reSetState = true;
  3356. newState = RFAL_LM_STATE_IDLE; /* Set IDLE state */
  3357. }
  3358. #if 1 /* Perform bit rate detection in Low power mode */
  3359. else {
  3360. st25r3916ClrRegisterBits(
  3361. ST25R3916_REG_OP_CONTROL,
  3362. (ST25R3916_REG_OP_CONTROL_tx_en | ST25R3916_REG_OP_CONTROL_rx_en |
  3363. ST25R3916_REG_OP_CONTROL_en));
  3364. }
  3365. #endif
  3366. break;
  3367. /*******************************************************************************/
  3368. case RFAL_LM_STATE_IDLE:
  3369. /*******************************************************************************/
  3370. /* Check if device is coming from Low Power bit rate detection */
  3371. if(!st25r3916CheckReg(
  3372. ST25R3916_REG_OP_CONTROL,
  3373. ST25R3916_REG_OP_CONTROL_en,
  3374. ST25R3916_REG_OP_CONTROL_en)) {
  3375. /* Exit Low Power mode and confirm the temporarily enable */
  3376. st25r3916SetRegisterBits(
  3377. ST25R3916_REG_OP_CONTROL,
  3378. (ST25R3916_REG_OP_CONTROL_en | ST25R3916_REG_OP_CONTROL_rx_en));
  3379. if(!st25r3916CheckReg(
  3380. ST25R3916_REG_AUX_DISPLAY,
  3381. ST25R3916_REG_AUX_DISPLAY_osc_ok,
  3382. ST25R3916_REG_AUX_DISPLAY_osc_ok)) {
  3383. /* Wait for Oscillator ready */
  3384. if(st25r3916WaitForInterruptsTimed(
  3385. ST25R3916_IRQ_MASK_OSC, ST25R3916_TOUT_OSC_STABLE) == 0U) {
  3386. ret = ERR_IO;
  3387. break;
  3388. }
  3389. }
  3390. } else {
  3391. st25r3916GetInterrupt(ST25R3916_IRQ_MASK_OSC);
  3392. }
  3393. /*******************************************************************************/
  3394. /* In Active P2P the Initiator may: Turn its field On; LM goes into IDLE state;
  3395. * Initiator sends an unexpected frame raising a Protocol error; Initiator
  3396. * turns its field Off and ST25R3916 performs the automatic RF Collision
  3397. * Avoidance keeping our field On; upon a Protocol error upper layer sets
  3398. * again the state to IDLE to clear dataFlag and wait for next data.
  3399. *
  3400. * Ensure that when upper layer calls SetState(IDLE), it restores initial
  3401. * configuration and that check whether an external Field is still present */
  3402. if((gRFAL.Lm.mdMask & RFAL_LM_MASK_ACTIVE_P2P) != 0U) {
  3403. /* Ensure nfc_ar is reset and back to only after Rx */
  3404. st25r3916ExecuteCommand(ST25R3916_CMD_STOP);
  3405. st25r3916ChangeRegisterBits(
  3406. ST25R3916_REG_MODE,
  3407. ST25R3916_REG_MODE_nfc_ar_mask,
  3408. ST25R3916_REG_MODE_nfc_ar_auto_rx);
  3409. /* Ensure that our field is Off, as automatic response RF Collision Avoidance may have been triggered */
  3410. st25r3916TxOff();
  3411. /* If external Field is no longer detected go back to POWER_OFF */
  3412. if(!st25r3916IsExtFieldOn()) {
  3413. reSetState = true;
  3414. newState = RFAL_LM_STATE_POWER_OFF; /* Set POWER_OFF state */
  3415. }
  3416. }
  3417. /*******************************************************************************/
  3418. /* If we are in ACTIVE_A, reEnable Listen for A before going to IDLE, otherwise do nothing */
  3419. if(gRFAL.Lm.state == RFAL_LM_STATE_ACTIVE_A) {
  3420. /* Enable automatic responses for A and Reset NFCA target state */
  3421. st25r3916ClrRegisterBits(
  3422. ST25R3916_REG_PASSIVE_TARGET, (ST25R3916_REG_PASSIVE_TARGET_d_106_ac_a));
  3423. st25r3916ExecuteCommand(ST25R3916_CMD_GOTO_SENSE);
  3424. }
  3425. /* ReEnable the receiver */
  3426. st25r3916ExecuteCommand(ST25R3916_CMD_CLEAR_FIFO);
  3427. st25r3916ExecuteCommand(ST25R3916_CMD_UNMASK_RECEIVE_DATA);
  3428. /*******************************************************************************/
  3429. /*Check if Observation Mode is enabled and set it on ST25R391x */
  3430. rfalCheckEnableObsModeRx();
  3431. break;
  3432. /*******************************************************************************/
  3433. case RFAL_LM_STATE_READY_F:
  3434. /*******************************************************************************/
  3435. /* If we're coming from BitRate detection mode, the Bit Rate Definition reg
  3436. * still has the last bit rate used.
  3437. * If a frame is received between setting the mode to Listen NFCA and
  3438. * setting Bit Rate Definition reg, it will raise a framing error.
  3439. * Set the bitrate immediately, and then the normal SetMode procedure */
  3440. st25r3916SetBitrate((uint8_t)gRFAL.Lm.brDetected, (uint8_t)gRFAL.Lm.brDetected);
  3441. /*******************************************************************************/
  3442. /* Disable automatic responses for NFC-A */
  3443. st25r3916SetRegisterBits(
  3444. ST25R3916_REG_PASSIVE_TARGET, (ST25R3916_REG_PASSIVE_TARGET_d_106_ac_a));
  3445. /* Set Mode NFC-F only */
  3446. ret = rfalSetMode(RFAL_MODE_LISTEN_NFCF, gRFAL.Lm.brDetected, gRFAL.Lm.brDetected);
  3447. gRFAL.state = RFAL_STATE_LM; /* Keep in Listen Mode */
  3448. /* ReEnable the receiver */
  3449. st25r3916ExecuteCommand(ST25R3916_CMD_CLEAR_FIFO);
  3450. st25r3916ExecuteCommand(ST25R3916_CMD_UNMASK_RECEIVE_DATA);
  3451. /* Clear any previous transmission errors (if Reader polled for other/unsupported technologies) */
  3452. st25r3916GetInterrupt(
  3453. (ST25R3916_IRQ_MASK_PAR | ST25R3916_IRQ_MASK_CRC | ST25R3916_IRQ_MASK_ERR2 |
  3454. ST25R3916_IRQ_MASK_ERR1));
  3455. st25r3916EnableInterrupts(
  3456. ST25R3916_IRQ_MASK_RXE); /* Start looking for any incoming data */
  3457. break;
  3458. /*******************************************************************************/
  3459. case RFAL_LM_STATE_CARDEMU_3:
  3460. /* Set Listen NFCF mode */
  3461. ret = rfalSetMode(RFAL_MODE_LISTEN_NFCF, gRFAL.Lm.brDetected, gRFAL.Lm.brDetected);
  3462. break;
  3463. /*******************************************************************************/
  3464. case RFAL_LM_STATE_READY_Ax:
  3465. case RFAL_LM_STATE_READY_A:
  3466. /*******************************************************************************/
  3467. /* If we're coming from BitRate detection mode, the Bit Rate Definition reg
  3468. * still has the last bit rate used.
  3469. * If a frame is received between setting the mode to Listen NFCA and
  3470. * setting Bit Rate Definition reg, it will raise a framing error.
  3471. * Set the bitrate immediately, and then the normal SetMode procedure */
  3472. st25r3916SetBitrate((uint8_t)gRFAL.Lm.brDetected, (uint8_t)gRFAL.Lm.brDetected);
  3473. /*******************************************************************************/
  3474. /* Disable automatic responses for NFC-F */
  3475. st25r3916SetRegisterBits(
  3476. ST25R3916_REG_PASSIVE_TARGET, (ST25R3916_REG_PASSIVE_TARGET_d_212_424_1r));
  3477. /* Set Mode NFC-A only */
  3478. ret = rfalSetMode(RFAL_MODE_LISTEN_NFCA, gRFAL.Lm.brDetected, gRFAL.Lm.brDetected);
  3479. gRFAL.state = RFAL_STATE_LM; /* Keep in Listen Mode */
  3480. break;
  3481. /*******************************************************************************/
  3482. case RFAL_LM_STATE_ACTIVE_Ax:
  3483. case RFAL_LM_STATE_ACTIVE_A:
  3484. /* Disable automatic responses for A */
  3485. st25r3916SetRegisterBits(
  3486. ST25R3916_REG_PASSIVE_TARGET, (ST25R3916_REG_PASSIVE_TARGET_d_106_ac_a));
  3487. /* Clear any previous transmission errors (if Reader polled for other/unsupported technologies) */
  3488. st25r3916GetInterrupt(
  3489. (ST25R3916_IRQ_MASK_PAR | ST25R3916_IRQ_MASK_CRC | ST25R3916_IRQ_MASK_ERR2 |
  3490. ST25R3916_IRQ_MASK_ERR1));
  3491. st25r3916EnableInterrupts(
  3492. ST25R3916_IRQ_MASK_RXE); /* Start looking for any incoming data */
  3493. break;
  3494. case RFAL_LM_STATE_TARGET_F:
  3495. /* Disable Automatic response SENSF_REQ */
  3496. st25r3916SetRegisterBits(
  3497. ST25R3916_REG_PASSIVE_TARGET, (ST25R3916_REG_PASSIVE_TARGET_d_212_424_1r));
  3498. break;
  3499. /*******************************************************************************/
  3500. case RFAL_LM_STATE_SLEEP_A:
  3501. case RFAL_LM_STATE_SLEEP_B:
  3502. case RFAL_LM_STATE_SLEEP_AF:
  3503. /* These sleep states have to be set by the rfalListenSleepStart() method */
  3504. return ERR_REQUEST;
  3505. /*******************************************************************************/
  3506. case RFAL_LM_STATE_CARDEMU_4A:
  3507. case RFAL_LM_STATE_CARDEMU_4B:
  3508. case RFAL_LM_STATE_TARGET_A:
  3509. /* States not handled by the LM, just keep state context */
  3510. break;
  3511. /*******************************************************************************/
  3512. default:
  3513. return ERR_WRONG_STATE;
  3514. }
  3515. } while(reSetState);
  3516. gRFAL.Lm.state = newState;
  3517. // Call callback on state change
  3518. if(gRFAL.callbacks.state_changed_cb) {
  3519. gRFAL.callbacks.state_changed_cb(gRFAL.callbacks.ctx);
  3520. }
  3521. return ret;
  3522. }
  3523. #endif /* RFAL_FEATURE_LISTEN_MODE */
  3524. /*******************************************************************************
  3525. * Wake-Up Mode *
  3526. *******************************************************************************/
  3527. #if RFAL_FEATURE_WAKEUP_MODE
  3528. /*******************************************************************************/
  3529. ReturnCode rfalWakeUpModeStart(const rfalWakeUpConfig* config) {
  3530. uint8_t aux;
  3531. uint8_t reg;
  3532. uint32_t irqs;
  3533. /* Check if RFAL is not initialized */
  3534. if(gRFAL.state < RFAL_STATE_INIT) {
  3535. return ERR_WRONG_STATE;
  3536. }
  3537. /* The Wake-Up procedure is explained in detail in Application Note: AN4985 */
  3538. if(config == NULL) {
  3539. gRFAL.wum.cfg.period = RFAL_WUM_PERIOD_200MS;
  3540. gRFAL.wum.cfg.irqTout = false;
  3541. gRFAL.wum.cfg.indAmp.enabled = true;
  3542. gRFAL.wum.cfg.indPha.enabled = false;
  3543. gRFAL.wum.cfg.cap.enabled = false;
  3544. gRFAL.wum.cfg.indAmp.delta = 2U;
  3545. gRFAL.wum.cfg.indAmp.reference = RFAL_WUM_REFERENCE_AUTO;
  3546. gRFAL.wum.cfg.indAmp.autoAvg = false;
  3547. /*******************************************************************************/
  3548. /* Check if AAT is enabled and if so make use of the SW Tag Detection */
  3549. if(st25r3916CheckReg(
  3550. ST25R3916_REG_IO_CONF2,
  3551. ST25R3916_REG_IO_CONF2_aat_en,
  3552. ST25R3916_REG_IO_CONF2_aat_en)) {
  3553. gRFAL.wum.cfg.swTagDetect = true;
  3554. gRFAL.wum.cfg.indAmp.autoAvg = true;
  3555. gRFAL.wum.cfg.indAmp.aaWeight = RFAL_WUM_AA_WEIGHT_16;
  3556. }
  3557. } else {
  3558. gRFAL.wum.cfg = *config;
  3559. }
  3560. /* Check for valid configuration */
  3561. if((!gRFAL.wum.cfg.cap.enabled && !gRFAL.wum.cfg.indAmp.enabled &&
  3562. !gRFAL.wum.cfg.indPha.enabled) ||
  3563. (gRFAL.wum.cfg.cap.enabled &&
  3564. (gRFAL.wum.cfg.indAmp.enabled || gRFAL.wum.cfg.indPha.enabled)) ||
  3565. (gRFAL.wum.cfg.cap.enabled && gRFAL.wum.cfg.swTagDetect) ||
  3566. ((gRFAL.wum.cfg.indAmp.reference > RFAL_WUM_REFERENCE_AUTO) ||
  3567. (gRFAL.wum.cfg.indPha.reference > RFAL_WUM_REFERENCE_AUTO) ||
  3568. (gRFAL.wum.cfg.cap.reference > RFAL_WUM_REFERENCE_AUTO))) {
  3569. return ERR_PARAM;
  3570. }
  3571. irqs = ST25R3916_IRQ_MASK_NONE;
  3572. /* Disable Tx, Rx, External Field Detector and set default ISO14443A mode */
  3573. st25r3916TxRxOff();
  3574. st25r3916ClrRegisterBits(ST25R3916_REG_OP_CONTROL, ST25R3916_REG_OP_CONTROL_en_fd_mask);
  3575. st25r3916ChangeRegisterBits(
  3576. ST25R3916_REG_MODE,
  3577. (ST25R3916_REG_MODE_targ | ST25R3916_REG_MODE_om_mask),
  3578. (ST25R3916_REG_MODE_targ_init | ST25R3916_REG_MODE_om_iso14443a));
  3579. /* Set Analog configurations for Wake-up On event */
  3580. rfalSetAnalogConfig((RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_WAKEUP_ON));
  3581. /*******************************************************************************/
  3582. /* Prepare Wake-Up Timer Control Register */
  3583. reg = (uint8_t)(((uint8_t)gRFAL.wum.cfg.period & 0x0FU)
  3584. << ST25R3916_REG_WUP_TIMER_CONTROL_wut_shift);
  3585. reg |= (uint8_t)(((uint8_t)gRFAL.wum.cfg.period < (uint8_t)RFAL_WUM_PERIOD_100MS) ?
  3586. ST25R3916_REG_WUP_TIMER_CONTROL_wur :
  3587. 0x00U);
  3588. if(gRFAL.wum.cfg.irqTout || gRFAL.wum.cfg.swTagDetect) {
  3589. reg |= ST25R3916_REG_WUP_TIMER_CONTROL_wto;
  3590. irqs |= ST25R3916_IRQ_MASK_WT;
  3591. }
  3592. /* Check if HW Wake-up is to be used or SW Tag detection */
  3593. if(gRFAL.wum.cfg.swTagDetect) {
  3594. gRFAL.wum.cfg.indAmp.reference = 0U;
  3595. gRFAL.wum.cfg.indPha.reference = 0U;
  3596. gRFAL.wum.cfg.cap.reference = 0U;
  3597. } else {
  3598. /*******************************************************************************/
  3599. /* Check if Inductive Amplitude is to be performed */
  3600. if(gRFAL.wum.cfg.indAmp.enabled) {
  3601. aux = (uint8_t)((gRFAL.wum.cfg.indAmp.delta)
  3602. << ST25R3916_REG_AMPLITUDE_MEASURE_CONF_am_d_shift);
  3603. aux |= (uint8_t)(gRFAL.wum.cfg.indAmp.aaInclMeas ?
  3604. ST25R3916_REG_AMPLITUDE_MEASURE_CONF_am_aam :
  3605. 0x00U);
  3606. aux |= (uint8_t)(((uint8_t)gRFAL.wum.cfg.indAmp.aaWeight
  3607. << ST25R3916_REG_AMPLITUDE_MEASURE_CONF_am_aew_shift) &
  3608. ST25R3916_REG_AMPLITUDE_MEASURE_CONF_am_aew_mask);
  3609. aux |= (uint8_t)(gRFAL.wum.cfg.indAmp.autoAvg ?
  3610. ST25R3916_REG_AMPLITUDE_MEASURE_CONF_am_ae :
  3611. 0x00U);
  3612. st25r3916WriteRegister(ST25R3916_REG_AMPLITUDE_MEASURE_CONF, aux);
  3613. /* Only need to set the reference if not using Auto Average */
  3614. if(!gRFAL.wum.cfg.indAmp.autoAvg) {
  3615. if(gRFAL.wum.cfg.indAmp.reference == RFAL_WUM_REFERENCE_AUTO) {
  3616. st25r3916MeasureAmplitude(&aux);
  3617. gRFAL.wum.cfg.indAmp.reference = aux;
  3618. }
  3619. st25r3916WriteRegister(
  3620. ST25R3916_REG_AMPLITUDE_MEASURE_REF, (uint8_t)gRFAL.wum.cfg.indAmp.reference);
  3621. }
  3622. reg |= ST25R3916_REG_WUP_TIMER_CONTROL_wam;
  3623. irqs |= ST25R3916_IRQ_MASK_WAM;
  3624. }
  3625. /*******************************************************************************/
  3626. /* Check if Inductive Phase is to be performed */
  3627. if(gRFAL.wum.cfg.indPha.enabled) {
  3628. aux = (uint8_t)((gRFAL.wum.cfg.indPha.delta)
  3629. << ST25R3916_REG_PHASE_MEASURE_CONF_pm_d_shift);
  3630. aux |= (uint8_t)(gRFAL.wum.cfg.indPha.aaInclMeas ?
  3631. ST25R3916_REG_PHASE_MEASURE_CONF_pm_aam :
  3632. 0x00U);
  3633. aux |= (uint8_t)(((uint8_t)gRFAL.wum.cfg.indPha.aaWeight
  3634. << ST25R3916_REG_PHASE_MEASURE_CONF_pm_aew_shift) &
  3635. ST25R3916_REG_PHASE_MEASURE_CONF_pm_aew_mask);
  3636. aux |= (uint8_t)(gRFAL.wum.cfg.indPha.autoAvg ?
  3637. ST25R3916_REG_PHASE_MEASURE_CONF_pm_ae :
  3638. 0x00U);
  3639. st25r3916WriteRegister(ST25R3916_REG_PHASE_MEASURE_CONF, aux);
  3640. /* Only need to set the reference if not using Auto Average */
  3641. if(!gRFAL.wum.cfg.indPha.autoAvg) {
  3642. if(gRFAL.wum.cfg.indPha.reference == RFAL_WUM_REFERENCE_AUTO) {
  3643. st25r3916MeasurePhase(&aux);
  3644. gRFAL.wum.cfg.indPha.reference = aux;
  3645. }
  3646. st25r3916WriteRegister(
  3647. ST25R3916_REG_PHASE_MEASURE_REF, (uint8_t)gRFAL.wum.cfg.indPha.reference);
  3648. }
  3649. reg |= ST25R3916_REG_WUP_TIMER_CONTROL_wph;
  3650. irqs |= ST25R3916_IRQ_MASK_WPH;
  3651. }
  3652. /*******************************************************************************/
  3653. /* Check if Capacitive is to be performed */
  3654. if(gRFAL.wum.cfg.cap.enabled) {
  3655. /*******************************************************************************/
  3656. /* Perform Capacitive sensor calibration */
  3657. /* Disable Oscillator and Field */
  3658. st25r3916ClrRegisterBits(
  3659. ST25R3916_REG_OP_CONTROL,
  3660. (ST25R3916_REG_OP_CONTROL_en | ST25R3916_REG_OP_CONTROL_tx_en));
  3661. /* Sensor gain should be configured on Analog Config: RFAL_ANALOG_CONFIG_CHIP_WAKEUP_ON */
  3662. /* Perform calibration procedure */
  3663. st25r3916CalibrateCapacitiveSensor(NULL);
  3664. /*******************************************************************************/
  3665. aux = (uint8_t)((gRFAL.wum.cfg.cap.delta)
  3666. << ST25R3916_REG_CAPACITANCE_MEASURE_CONF_cm_d_shift);
  3667. aux |= (uint8_t)(gRFAL.wum.cfg.cap.aaInclMeas ?
  3668. ST25R3916_REG_CAPACITANCE_MEASURE_CONF_cm_aam :
  3669. 0x00U);
  3670. aux |= (uint8_t)(((uint8_t)gRFAL.wum.cfg.cap.aaWeight
  3671. << ST25R3916_REG_CAPACITANCE_MEASURE_CONF_cm_aew_shift) &
  3672. ST25R3916_REG_CAPACITANCE_MEASURE_CONF_cm_aew_mask);
  3673. aux |= (uint8_t)(gRFAL.wum.cfg.cap.autoAvg ?
  3674. ST25R3916_REG_CAPACITANCE_MEASURE_CONF_cm_ae :
  3675. 0x00U);
  3676. st25r3916WriteRegister(ST25R3916_REG_CAPACITANCE_MEASURE_CONF, aux);
  3677. /* Only need to set the reference if not using Auto Average */
  3678. if(!gRFAL.wum.cfg.cap.autoAvg || gRFAL.wum.cfg.swTagDetect) {
  3679. if(gRFAL.wum.cfg.indPha.reference == RFAL_WUM_REFERENCE_AUTO) {
  3680. st25r3916MeasureCapacitance(&aux);
  3681. gRFAL.wum.cfg.cap.reference = aux;
  3682. }
  3683. st25r3916WriteRegister(
  3684. ST25R3916_REG_CAPACITANCE_MEASURE_REF, (uint8_t)gRFAL.wum.cfg.cap.reference);
  3685. }
  3686. reg |= ST25R3916_REG_WUP_TIMER_CONTROL_wcap;
  3687. irqs |= ST25R3916_IRQ_MASK_WCAP;
  3688. }
  3689. }
  3690. /* Disable and clear all interrupts except Wake-Up IRQs */
  3691. st25r3916DisableInterrupts(ST25R3916_IRQ_MASK_ALL);
  3692. st25r3916GetInterrupt(irqs);
  3693. st25r3916EnableInterrupts(irqs);
  3694. /* Enable Low Power Wake-Up Mode (Disable: Oscilattor, Tx, Rx and External Field Detector) */
  3695. st25r3916WriteRegister(ST25R3916_REG_WUP_TIMER_CONTROL, reg);
  3696. st25r3916ChangeRegisterBits(
  3697. ST25R3916_REG_OP_CONTROL,
  3698. (ST25R3916_REG_OP_CONTROL_en | ST25R3916_REG_OP_CONTROL_rx_en |
  3699. ST25R3916_REG_OP_CONTROL_tx_en | ST25R3916_REG_OP_CONTROL_en_fd_mask |
  3700. ST25R3916_REG_OP_CONTROL_wu),
  3701. ST25R3916_REG_OP_CONTROL_wu);
  3702. gRFAL.wum.state = RFAL_WUM_STATE_ENABLED;
  3703. gRFAL.state = RFAL_STATE_WUM;
  3704. return ERR_NONE;
  3705. }
  3706. /*******************************************************************************/
  3707. bool rfalWakeUpModeHasWoke(void) {
  3708. return (gRFAL.wum.state >= RFAL_WUM_STATE_ENABLED_WOKE);
  3709. }
  3710. /*******************************************************************************/
  3711. static uint16_t rfalWakeUpModeFilter(uint16_t curRef, uint16_t curVal, uint8_t weight) {
  3712. uint16_t newRef;
  3713. /* Perform the averaging|filter as describded in ST25R3916 DS */
  3714. /* Avoid signed arithmetics by splitting in two cases */
  3715. if(curVal > curRef) {
  3716. newRef = curRef + ((curVal - curRef) / weight);
  3717. /* In order for the reference to converge to final value *
  3718. * increment once the diff is smaller that the weight */
  3719. if((curVal != curRef) && (curRef == newRef)) {
  3720. newRef &= 0xFF00U;
  3721. newRef += 0x0100U;
  3722. }
  3723. } else {
  3724. newRef = curRef - ((curRef - curVal) / weight);
  3725. /* In order for the reference to converge to final value *
  3726. * decrement once the diff is smaller that the weight */
  3727. if((curVal != curRef) && (curRef == newRef)) {
  3728. newRef &= 0xFF00U;
  3729. }
  3730. }
  3731. return newRef;
  3732. }
  3733. /*******************************************************************************/
  3734. static void rfalRunWakeUpModeWorker(void) {
  3735. uint32_t irqs;
  3736. uint8_t reg;
  3737. uint16_t value;
  3738. uint16_t delta;
  3739. if(gRFAL.state != RFAL_STATE_WUM) {
  3740. return;
  3741. }
  3742. switch(gRFAL.wum.state) {
  3743. case RFAL_WUM_STATE_ENABLED:
  3744. case RFAL_WUM_STATE_ENABLED_WOKE:
  3745. irqs = st25r3916GetInterrupt(
  3746. (ST25R3916_IRQ_MASK_WT | ST25R3916_IRQ_MASK_WAM | ST25R3916_IRQ_MASK_WPH |
  3747. ST25R3916_IRQ_MASK_WCAP));
  3748. if(irqs == ST25R3916_IRQ_MASK_NONE) {
  3749. break; /* No interrupt to process */
  3750. }
  3751. /*******************************************************************************/
  3752. /* Check and mark which measurement(s) cause interrupt */
  3753. if((irqs & ST25R3916_IRQ_MASK_WAM) != 0U) {
  3754. st25r3916ReadRegister(ST25R3916_REG_AMPLITUDE_MEASURE_RESULT, &reg);
  3755. gRFAL.wum.state = RFAL_WUM_STATE_ENABLED_WOKE;
  3756. }
  3757. if((irqs & ST25R3916_IRQ_MASK_WPH) != 0U) {
  3758. st25r3916ReadRegister(ST25R3916_REG_PHASE_MEASURE_RESULT, &reg);
  3759. gRFAL.wum.state = RFAL_WUM_STATE_ENABLED_WOKE;
  3760. }
  3761. if((irqs & ST25R3916_IRQ_MASK_WCAP) != 0U) {
  3762. st25r3916ReadRegister(ST25R3916_REG_CAPACITANCE_MEASURE_RESULT, &reg);
  3763. gRFAL.wum.state = RFAL_WUM_STATE_ENABLED_WOKE;
  3764. }
  3765. if((irqs & ST25R3916_IRQ_MASK_WT) != 0U) {
  3766. /*******************************************************************************/
  3767. if(gRFAL.wum.cfg.swTagDetect) {
  3768. /* Enable Ready mode and wait the settle time */
  3769. st25r3916ChangeRegisterBits(
  3770. ST25R3916_REG_OP_CONTROL,
  3771. (ST25R3916_REG_OP_CONTROL_en | ST25R3916_REG_OP_CONTROL_wu),
  3772. ST25R3916_REG_OP_CONTROL_en);
  3773. platformDelay(RFAL_ST25R3916_AAT_SETTLE);
  3774. /*******************************************************************************/
  3775. if(gRFAL.wum.cfg.indAmp.enabled) {
  3776. /* Perform amplitude measurement */
  3777. st25r3916MeasureAmplitude(&reg);
  3778. /* Convert inputs to TD format */
  3779. value = rfalConvTDFormat(reg);
  3780. delta = rfalConvTDFormat(gRFAL.wum.cfg.indAmp.delta);
  3781. /* Set first measurement as reference */
  3782. if(gRFAL.wum.cfg.indAmp.reference == 0U) {
  3783. gRFAL.wum.cfg.indAmp.reference = value;
  3784. }
  3785. /* Check if device should be woken */
  3786. if((value >= (gRFAL.wum.cfg.indAmp.reference + delta)) ||
  3787. (value <= (gRFAL.wum.cfg.indAmp.reference - delta))) {
  3788. gRFAL.wum.state = RFAL_WUM_STATE_ENABLED_WOKE;
  3789. break;
  3790. }
  3791. /* Update moving reference if enabled */
  3792. if(gRFAL.wum.cfg.indAmp.autoAvg) {
  3793. gRFAL.wum.cfg.indAmp.reference = rfalWakeUpModeFilter(
  3794. gRFAL.wum.cfg.indAmp.reference,
  3795. value,
  3796. (RFAL_WU_MIN_WEIGHT_VAL << (uint8_t)gRFAL.wum.cfg.indAmp.aaWeight));
  3797. }
  3798. }
  3799. /*******************************************************************************/
  3800. if(gRFAL.wum.cfg.indPha.enabled) {
  3801. /* Perform Phase measurement */
  3802. st25r3916MeasurePhase(&reg);
  3803. /* Convert inputs to TD format */
  3804. value = rfalConvTDFormat(reg);
  3805. delta = rfalConvTDFormat(gRFAL.wum.cfg.indPha.delta);
  3806. /* Set first measurement as reference */
  3807. if(gRFAL.wum.cfg.indPha.reference == 0U) {
  3808. gRFAL.wum.cfg.indPha.reference = value;
  3809. }
  3810. /* Check if device should be woken */
  3811. if((value >= (gRFAL.wum.cfg.indPha.reference + delta)) ||
  3812. (value <= (gRFAL.wum.cfg.indPha.reference - delta))) {
  3813. gRFAL.wum.state = RFAL_WUM_STATE_ENABLED_WOKE;
  3814. break;
  3815. }
  3816. /* Update moving reference if enabled */
  3817. if(gRFAL.wum.cfg.indPha.autoAvg) {
  3818. gRFAL.wum.cfg.indPha.reference = rfalWakeUpModeFilter(
  3819. gRFAL.wum.cfg.indPha.reference,
  3820. value,
  3821. (RFAL_WU_MIN_WEIGHT_VAL << (uint8_t)gRFAL.wum.cfg.indPha.aaWeight));
  3822. }
  3823. }
  3824. /* Re-Enable low power Wake-Up mode for wto to trigger another measurement(s) */
  3825. st25r3916ChangeRegisterBits(
  3826. ST25R3916_REG_OP_CONTROL,
  3827. (ST25R3916_REG_OP_CONTROL_en | ST25R3916_REG_OP_CONTROL_wu),
  3828. (ST25R3916_REG_OP_CONTROL_wu));
  3829. }
  3830. }
  3831. break;
  3832. default:
  3833. /* MISRA 16.4: no empty default statement (a comment being enough) */
  3834. break;
  3835. }
  3836. }
  3837. /*******************************************************************************/
  3838. ReturnCode rfalWakeUpModeStop(void) {
  3839. /* Check if RFAL is in Wake-up mode */
  3840. if(gRFAL.state != RFAL_STATE_WUM) {
  3841. return ERR_WRONG_STATE;
  3842. }
  3843. gRFAL.wum.state = RFAL_WUM_STATE_NOT_INIT;
  3844. /* Disable Wake-Up Mode */
  3845. st25r3916ClrRegisterBits(ST25R3916_REG_OP_CONTROL, ST25R3916_REG_OP_CONTROL_wu);
  3846. st25r3916DisableInterrupts(
  3847. (ST25R3916_IRQ_MASK_WT | ST25R3916_IRQ_MASK_WAM | ST25R3916_IRQ_MASK_WPH |
  3848. ST25R3916_IRQ_MASK_WCAP));
  3849. /* Re-Enable External Field Detector as: Automatics */
  3850. st25r3916ChangeRegisterBits(
  3851. ST25R3916_REG_OP_CONTROL,
  3852. ST25R3916_REG_OP_CONTROL_en_fd_mask,
  3853. ST25R3916_REG_OP_CONTROL_en_fd_auto_efd);
  3854. /* Re-Enable the Oscillator */
  3855. st25r3916OscOn();
  3856. /* Set Analog configurations for Wake-up Off event */
  3857. rfalSetAnalogConfig((RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_WAKEUP_OFF));
  3858. return ERR_NONE;
  3859. }
  3860. #endif /* RFAL_FEATURE_WAKEUP_MODE */
  3861. /*******************************************************************************
  3862. * Low-Power Mode *
  3863. *******************************************************************************/
  3864. #if RFAL_FEATURE_LOWPOWER_MODE
  3865. /*******************************************************************************/
  3866. ReturnCode rfalLowPowerModeStart(void) {
  3867. /* Check if RFAL is not initialized */
  3868. if(gRFAL.state < RFAL_STATE_INIT) {
  3869. return ERR_WRONG_STATE;
  3870. }
  3871. /* Stop any ongoing activity and set the device in low power by disabling oscillator, transmitter, receiver and external field detector */
  3872. st25r3916ExecuteCommand(ST25R3916_CMD_STOP);
  3873. st25r3916ClrRegisterBits(
  3874. ST25R3916_REG_OP_CONTROL,
  3875. (ST25R3916_REG_OP_CONTROL_en | ST25R3916_REG_OP_CONTROL_rx_en |
  3876. ST25R3916_REG_OP_CONTROL_wu | ST25R3916_REG_OP_CONTROL_tx_en |
  3877. ST25R3916_REG_OP_CONTROL_en_fd_mask));
  3878. rfalSetAnalogConfig((RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_LOWPOWER_ON));
  3879. gRFAL.state = RFAL_STATE_IDLE;
  3880. gRFAL.lpm.isRunning = true;
  3881. platformDisableIrqCallback();
  3882. return ERR_NONE;
  3883. }
  3884. /*******************************************************************************/
  3885. ReturnCode rfalLowPowerModeStop(void) {
  3886. ReturnCode ret;
  3887. platformEnableIrqCallback();
  3888. /* Check if RFAL is on right state */
  3889. if(!gRFAL.lpm.isRunning) {
  3890. return ERR_WRONG_STATE;
  3891. }
  3892. /* Re-enable device */
  3893. EXIT_ON_ERR(ret, st25r3916OscOn());
  3894. st25r3916ChangeRegisterBits(
  3895. ST25R3916_REG_OP_CONTROL,
  3896. ST25R3916_REG_OP_CONTROL_en_fd_mask,
  3897. ST25R3916_REG_OP_CONTROL_en_fd_auto_efd);
  3898. rfalSetAnalogConfig((RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_LOWPOWER_OFF));
  3899. gRFAL.state = RFAL_STATE_INIT;
  3900. return ERR_NONE;
  3901. }
  3902. #endif /* RFAL_FEATURE_LOWPOWER_MODE */
  3903. /*******************************************************************************
  3904. * RF Chip *
  3905. *******************************************************************************/
  3906. /*******************************************************************************/
  3907. ReturnCode rfalChipWriteReg(uint16_t reg, const uint8_t* values, uint8_t len) {
  3908. if(!st25r3916IsRegValid((uint8_t)reg)) {
  3909. return ERR_PARAM;
  3910. }
  3911. return st25r3916WriteMultipleRegisters((uint8_t)reg, values, len);
  3912. }
  3913. /*******************************************************************************/
  3914. ReturnCode rfalChipReadReg(uint16_t reg, uint8_t* values, uint8_t len) {
  3915. if(!st25r3916IsRegValid((uint8_t)reg)) {
  3916. return ERR_PARAM;
  3917. }
  3918. return st25r3916ReadMultipleRegisters((uint8_t)reg, values, len);
  3919. }
  3920. /*******************************************************************************/
  3921. ReturnCode rfalChipExecCmd(uint16_t cmd) {
  3922. if(!st25r3916IsCmdValid((uint8_t)cmd)) {
  3923. return ERR_PARAM;
  3924. }
  3925. return st25r3916ExecuteCommand((uint8_t)cmd);
  3926. }
  3927. /*******************************************************************************/
  3928. ReturnCode rfalChipWriteTestReg(uint16_t reg, uint8_t value) {
  3929. return st25r3916WriteTestRegister((uint8_t)reg, value);
  3930. }
  3931. /*******************************************************************************/
  3932. ReturnCode rfalChipReadTestReg(uint16_t reg, uint8_t* value) {
  3933. return st25r3916ReadTestRegister((uint8_t)reg, value);
  3934. }
  3935. /*******************************************************************************/
  3936. ReturnCode rfalChipChangeRegBits(uint16_t reg, uint8_t valueMask, uint8_t value) {
  3937. if(!st25r3916IsRegValid((uint8_t)reg)) {
  3938. return ERR_PARAM;
  3939. }
  3940. return st25r3916ChangeRegisterBits((uint8_t)reg, valueMask, value);
  3941. }
  3942. /*******************************************************************************/
  3943. ReturnCode rfalChipChangeTestRegBits(uint16_t reg, uint8_t valueMask, uint8_t value) {
  3944. st25r3916ChangeTestRegisterBits((uint8_t)reg, valueMask, value);
  3945. return ERR_NONE;
  3946. }
  3947. /*******************************************************************************/
  3948. ReturnCode rfalChipSetRFO(uint8_t rfo) {
  3949. return st25r3916ChangeRegisterBits(
  3950. ST25R3916_REG_TX_DRIVER, ST25R3916_REG_TX_DRIVER_d_res_mask, rfo);
  3951. }
  3952. /*******************************************************************************/
  3953. ReturnCode rfalChipGetRFO(uint8_t* result) {
  3954. ReturnCode ret;
  3955. ret = st25r3916ReadRegister(ST25R3916_REG_TX_DRIVER, result);
  3956. (*result) = ((*result) & ST25R3916_REG_TX_DRIVER_d_res_mask);
  3957. return ret;
  3958. }
  3959. /*******************************************************************************/
  3960. ReturnCode rfalChipMeasureAmplitude(uint8_t* result) {
  3961. ReturnCode err;
  3962. uint8_t reg_opc, reg_mode, reg_conf1, reg_conf2;
  3963. /* Save registers which will be adjusted below */
  3964. st25r3916ReadRegister(ST25R3916_REG_OP_CONTROL, &reg_opc);
  3965. st25r3916ReadRegister(ST25R3916_REG_MODE, &reg_mode);
  3966. st25r3916ReadRegister(ST25R3916_REG_RX_CONF1, &reg_conf1);
  3967. st25r3916ReadRegister(ST25R3916_REG_RX_CONF2, &reg_conf2);
  3968. /* Set values as per defaults of DS. These regs/bits influence receiver chain and change amplitude */
  3969. /* Doing so achieves an amplitude comparable over a complete polling cylce */
  3970. st25r3916WriteRegister(ST25R3916_REG_OP_CONTROL, (reg_opc & ~ST25R3916_REG_OP_CONTROL_rx_chn));
  3971. st25r3916WriteRegister(
  3972. ST25R3916_REG_MODE,
  3973. ST25R3916_REG_MODE_om_iso14443a | ST25R3916_REG_MODE_targ_init |
  3974. ST25R3916_REG_MODE_tr_am_ook | ST25R3916_REG_MODE_nfc_ar_off);
  3975. st25r3916WriteRegister(
  3976. ST25R3916_REG_RX_CONF1, (reg_conf1 & ~ST25R3916_REG_RX_CONF1_ch_sel_AM));
  3977. st25r3916WriteRegister(
  3978. ST25R3916_REG_RX_CONF2,
  3979. ((reg_conf2 & ~(ST25R3916_REG_RX_CONF2_demod_mode | ST25R3916_REG_RX_CONF2_amd_sel)) |
  3980. ST25R3916_REG_RX_CONF2_amd_sel_peak));
  3981. /* Perform the actual measurement */
  3982. err = st25r3916MeasureAmplitude(result);
  3983. /* Restore values */
  3984. st25r3916WriteRegister(ST25R3916_REG_OP_CONTROL, reg_opc);
  3985. st25r3916WriteRegister(ST25R3916_REG_MODE, reg_mode);
  3986. st25r3916WriteRegister(ST25R3916_REG_RX_CONF1, reg_conf1);
  3987. st25r3916WriteRegister(ST25R3916_REG_RX_CONF2, reg_conf2);
  3988. return err;
  3989. }
  3990. /*******************************************************************************/
  3991. ReturnCode rfalChipMeasurePhase(uint8_t* result) {
  3992. st25r3916MeasurePhase(result);
  3993. return ERR_NONE;
  3994. }
  3995. /*******************************************************************************/
  3996. ReturnCode rfalChipMeasureCapacitance(uint8_t* result) {
  3997. st25r3916MeasureCapacitance(result);
  3998. return ERR_NONE;
  3999. }
  4000. /*******************************************************************************/
  4001. ReturnCode rfalChipMeasurePowerSupply(uint8_t param, uint8_t* result) {
  4002. *result = st25r3916MeasurePowerSupply(param);
  4003. return ERR_NONE;
  4004. }
  4005. /*******************************************************************************/
  4006. extern uint8_t invalid_size_of_stream_configs
  4007. [(sizeof(struct st25r3916StreamConfig) == sizeof(struct iso15693StreamConfig)) ? 1 : (-1)];