stm32l4xx_hal_ospi.c 108 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231
  1. /**
  2. ******************************************************************************
  3. * @file stm32l4xx_hal_ospi.c
  4. * @author MCD Application Team
  5. * @brief OSPI HAL module driver.
  6. This file provides firmware functions to manage the following
  7. functionalities of the OctoSPI interface (OSPI).
  8. + Initialization and de-initialization functions
  9. + Hyperbus configuration
  10. + Indirect functional mode management
  11. + Memory-mapped functional mode management
  12. + Auto-polling functional mode management
  13. + Interrupts and flags management
  14. + DMA channel configuration for indirect functional mode
  15. + Errors management and abort functionality
  16. + IO manager configuration
  17. ******************************************************************************
  18. * @attention
  19. *
  20. * Copyright (c) 2017 STMicroelectronics.
  21. * All rights reserved.
  22. *
  23. * This software is licensed under terms that can be found in the LICENSE file
  24. * in the root directory of this software component.
  25. * If no LICENSE file comes with this software, it is provided AS-IS.
  26. *
  27. ******************************************************************************
  28. @verbatim
  29. ===============================================================================
  30. ##### How to use this driver #####
  31. ===============================================================================
  32. [..]
  33. *** Initialization ***
  34. ======================
  35. [..]
  36. As prerequisite, fill in the HAL_OSPI_MspInit() :
  37. (+) Enable OctoSPI and OctoSPIM clocks interface with __HAL_RCC_OSPIx_CLK_ENABLE().
  38. (+) Reset OctoSPI Peripheral with __HAL_RCC_OSPIx_FORCE_RESET() and __HAL_RCC_OSPIx_RELEASE_RESET().
  39. (+) Enable the clocks for the OctoSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().
  40. (+) Configure these OctoSPI pins in alternate mode using HAL_GPIO_Init().
  41. (+) If interrupt or DMA mode is used, enable and configure OctoSPI global
  42. interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
  43. (+) If DMA mode is used, enable the clocks for the OctoSPI DMA channel
  44. with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(),
  45. link it with OctoSPI handle using __HAL_LINKDMA(), enable and configure
  46. DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
  47. [..]
  48. Configure the fifo threshold, the dual-quad mode, the memory type, the
  49. device size, the CS high time, the free running clock, the clock mode,
  50. the wrap size, the clock prescaler, the sample shifting, the hold delay
  51. and the CS boundary using the HAL_OSPI_Init() function.
  52. [..]
  53. When using Hyperbus, configure the RW recovery time, the access time,
  54. the write latency and the latency mode using the HAL_OSPI_HyperbusCfg()
  55. function.
  56. *** Indirect functional mode ***
  57. ================================
  58. [..]
  59. In regular mode, configure the command sequence using the HAL_OSPI_Command()
  60. or HAL_OSPI_Command_IT() functions :
  61. (+) Instruction phase : the mode used and if present the size, the instruction
  62. opcode and the DTR mode.
  63. (+) Address phase : the mode used and if present the size, the address
  64. value and the DTR mode.
  65. (+) Alternate-bytes phase : the mode used and if present the size, the
  66. alternate bytes values and the DTR mode.
  67. (+) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase).
  68. (+) Data phase : the mode used and if present the number of bytes and the DTR mode.
  69. (+) Data strobe (DQS) mode : the activation (or not) of this mode
  70. (+) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode.
  71. (+) Flash identifier : in dual-quad mode, indicates which flash is concerned
  72. (+) Operation type : always common configuration
  73. [..]
  74. In Hyperbus mode, configure the command sequence using the HAL_OSPI_HyperbusCmd()
  75. function :
  76. (+) Address space : indicate if the access will be done in register or memory
  77. (+) Address size
  78. (+) Number of data
  79. (+) Data strobe (DQS) mode : the activation (or not) of this mode
  80. [..]
  81. If no data is required for the command (only for regular mode, not for
  82. Hyperbus mode), it is sent directly to the memory :
  83. (+) In polling mode, the output of the function is done when the transfer is complete.
  84. (+) In interrupt mode, HAL_OSPI_CmdCpltCallback() will be called when the transfer is complete.
  85. [..]
  86. For the indirect write mode, use HAL_OSPI_Transmit(), HAL_OSPI_Transmit_DMA() or
  87. HAL_OSPI_Transmit_IT() after the command configuration :
  88. (+) In polling mode, the output of the function is done when the transfer is complete.
  89. (+) In interrupt mode, HAL_OSPI_FifoThresholdCallback() will be called when the fifo threshold
  90. is reached and HAL_OSPI_TxCpltCallback() will be called when the transfer is complete.
  91. (+) In DMA mode, HAL_OSPI_TxHalfCpltCallback() will be called at the half transfer and
  92. HAL_OSPI_TxCpltCallback() will be called when the transfer is complete.
  93. [..]
  94. For the indirect read mode, use HAL_OSPI_Receive(), HAL_OSPI_Receive_DMA() or
  95. HAL_OSPI_Receive_IT() after the command configuration :
  96. (+) In polling mode, the output of the function is done when the transfer is complete.
  97. (+) In interrupt mode, HAL_OSPI_FifoThresholdCallback() will be called when the fifo threshold
  98. is reached and HAL_OSPI_RxCpltCallback() will be called when the transfer is complete.
  99. (+) In DMA mode, HAL_OSPI_RxHalfCpltCallback() will be called at the half transfer and
  100. HAL_OSPI_RxCpltCallback() will be called when the transfer is complete.
  101. *** Auto-polling functional mode ***
  102. ====================================
  103. [..]
  104. Configure the command sequence by the same way than the indirect mode
  105. [..]
  106. Configure the auto-polling functional mode using the HAL_OSPI_AutoPolling()
  107. or HAL_OSPI_AutoPolling_IT() functions :
  108. (+) The size of the status bytes, the match value, the mask used, the match mode (OR/AND),
  109. the polling interval and the automatic stop activation.
  110. [..]
  111. After the configuration :
  112. (+) In polling mode, the output of the function is done when the status match is reached. The
  113. automatic stop is activated to avoid an infinite loop.
  114. (+) In interrupt mode, HAL_OSPI_StatusMatchCallback() will be called each time the status match is reached.
  115. *** Memory-mapped functional mode ***
  116. =====================================
  117. [..]
  118. Configure the command sequence by the same way than the indirect mode except
  119. for the operation type in regular mode :
  120. (+) Operation type equals to read configuration : the command configuration
  121. applies to read access in memory-mapped mode
  122. (+) Operation type equals to write configuration : the command configuration
  123. applies to write access in memory-mapped mode
  124. (+) Both read and write configuration should be performed before activating
  125. memory-mapped mode
  126. [..]
  127. Configure the memory-mapped functional mode using the HAL_OSPI_MemoryMapped()
  128. functions :
  129. (+) The timeout activation and the timeout period.
  130. [..]
  131. After the configuration, the OctoSPI will be used as soon as an access on the AHB is done on
  132. the address range. HAL_OSPI_TimeOutCallback() will be called when the timeout expires.
  133. *** Errors management and abort functionality ***
  134. =================================================
  135. [..]
  136. HAL_OSPI_GetError() function gives the error raised during the last operation.
  137. [..]
  138. HAL_OSPI_Abort() and HAL_OSPI_AbortIT() functions aborts any on-going operation and
  139. flushes the fifo :
  140. (+) In polling mode, the output of the function is done when the transfer
  141. complete bit is set and the busy bit cleared.
  142. (+) In interrupt mode, HAL_OSPI_AbortCpltCallback() will be called when
  143. the transfer complete bit is set.
  144. *** Control functions ***
  145. =========================
  146. [..]
  147. HAL_OSPI_GetState() function gives the current state of the HAL OctoSPI driver.
  148. [..]
  149. HAL_OSPI_SetTimeout() function configures the timeout value used in the driver.
  150. [..]
  151. HAL_OSPI_SetFifoThreshold() function configures the threshold on the Fifo of the OSPI Peripheral.
  152. [..]
  153. HAL_OSPI_GetFifoThreshold() function gives the current of the Fifo's threshold
  154. *** IO manager configuration functions ***
  155. ==========================================
  156. [..]
  157. HAL_OSPIM_Config() function configures the IO manager for the OctoSPI instance.
  158. *** Callback registration ***
  159. =============================================
  160. [..]
  161. The compilation define USE_HAL_OSPI_REGISTER_CALLBACKS when set to 1
  162. allows the user to configure dynamically the driver callbacks.
  163. [..]
  164. Use function HAL_OSPI_RegisterCallback() to register a user callback,
  165. it allows to register following callbacks:
  166. (+) ErrorCallback : callback when error occurs.
  167. (+) AbortCpltCallback : callback when abort is completed.
  168. (+) FifoThresholdCallback : callback when the fifo threshold is reached.
  169. (+) CmdCpltCallback : callback when a command without data is completed.
  170. (+) RxCpltCallback : callback when a reception transfer is completed.
  171. (+) TxCpltCallback : callback when a transmission transfer is completed.
  172. (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
  173. (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
  174. (+) StatusMatchCallback : callback when a status match occurs.
  175. (+) TimeOutCallback : callback when the timeout perioed expires.
  176. (+) MspInitCallback : OSPI MspInit.
  177. (+) MspDeInitCallback : OSPI MspDeInit.
  178. [..]
  179. This function takes as parameters the HAL peripheral handle, the Callback ID
  180. and a pointer to the user callback function.
  181. [..]
  182. Use function HAL_OSPI_UnRegisterCallback() to reset a callback to the default
  183. weak (overridden) function. It allows to reset following callbacks:
  184. (+) ErrorCallback : callback when error occurs.
  185. (+) AbortCpltCallback : callback when abort is completed.
  186. (+) FifoThresholdCallback : callback when the fifo threshold is reached.
  187. (+) CmdCpltCallback : callback when a command without data is completed.
  188. (+) RxCpltCallback : callback when a reception transfer is completed.
  189. (+) TxCpltCallback : callback when a transmission transfer is completed.
  190. (+) RxHalfCpltCallback : callback when half of the reception transfer is completed.
  191. (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed.
  192. (+) StatusMatchCallback : callback when a status match occurs.
  193. (+) TimeOutCallback : callback when the timeout perioed expires.
  194. (+) MspInitCallback : OSPI MspInit.
  195. (+) MspDeInitCallback : OSPI MspDeInit.
  196. [..]
  197. This function) takes as parameters the HAL peripheral handle and the Callback ID.
  198. [..]
  199. By default, after the HAL_OSPI_Init() and if the state is HAL_OSPI_STATE_RESET
  200. all callbacks are reset to the corresponding legacy weak (overridden) functions.
  201. Exception done for MspInit and MspDeInit callbacks that are respectively
  202. reset to the legacy weak (overridden) functions in the HAL_OSPI_Init()
  203. and HAL_OSPI_DeInit() only when these callbacks are null (not registered beforehand).
  204. If not, MspInit or MspDeInit are not null, the HAL_OSPI_Init() and HAL_OSPI_DeInit()
  205. keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
  206. [..]
  207. Callbacks can be registered/unregistered in READY state only.
  208. Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
  209. in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
  210. during the Init/DeInit.
  211. In that case first register the MspInit/MspDeInit user callbacks
  212. using HAL_OSPI_RegisterCallback() before calling HAL_OSPI_DeInit()
  213. or HAL_OSPI_Init() function.
  214. [..]
  215. When The compilation define USE_HAL_OSPI_REGISTER_CALLBACKS is set to 0 or
  216. not defined, the callback registering feature is not available
  217. and weak (overridden) callbacks are used.
  218. @endverbatim
  219. ******************************************************************************
  220. */
  221. /* Includes ------------------------------------------------------------------*/
  222. #include "stm32l4xx_hal.h"
  223. #if defined(OCTOSPI) || defined(OCTOSPI1) || defined(OCTOSPI2)
  224. /** @addtogroup STM32L4xx_HAL_Driver
  225. * @{
  226. */
  227. /** @defgroup OSPI OSPI
  228. * @brief OSPI HAL module driver
  229. * @{
  230. */
  231. #ifdef HAL_OSPI_MODULE_ENABLED
  232. /**
  233. @cond 0
  234. */
  235. /* Private typedef -----------------------------------------------------------*/
  236. /* Private define ------------------------------------------------------------*/
  237. #define OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE ((uint32_t)0x00000000) /*!< Indirect write mode */
  238. #define OSPI_FUNCTIONAL_MODE_INDIRECT_READ ((uint32_t)OCTOSPI_CR_FMODE_0) /*!< Indirect read mode */
  239. #define OSPI_FUNCTIONAL_MODE_AUTO_POLLING ((uint32_t)OCTOSPI_CR_FMODE_1) /*!< Automatic polling mode */
  240. #define OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED ((uint32_t)OCTOSPI_CR_FMODE) /*!< Memory-mapped mode */
  241. #define OSPI_CFG_STATE_MASK 0x00000004U
  242. #define OSPI_BUSY_STATE_MASK 0x00000008U
  243. #define OSPI_NB_INSTANCE 2U
  244. #define OSPI_IOM_NB_PORTS 2U
  245. #define OSPI_IOM_PORT_MASK 0x1U
  246. /* Private macro -------------------------------------------------------------*/
  247. #define IS_OSPI_FUNCTIONAL_MODE(MODE) (((MODE) == OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
  248. ((MODE) == OSPI_FUNCTIONAL_MODE_INDIRECT_READ) || \
  249. ((MODE) == OSPI_FUNCTIONAL_MODE_AUTO_POLLING) || \
  250. ((MODE) == OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
  251. /* Private variables ---------------------------------------------------------*/
  252. /* Private function prototypes -----------------------------------------------*/
  253. static void OSPI_DMACplt(DMA_HandleTypeDef *hdma);
  254. static void OSPI_DMAHalfCplt(DMA_HandleTypeDef *hdma);
  255. static void OSPI_DMAError(DMA_HandleTypeDef *hdma);
  256. static void OSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma);
  257. static HAL_StatusTypeDef OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef *hospi, uint32_t Flag, FlagStatus State,
  258. uint32_t Tickstart, uint32_t Timeout);
  259. static HAL_StatusTypeDef OSPI_ConfigCmd(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd);
  260. static HAL_StatusTypeDef OSPIM_GetConfig(uint8_t instance_nb, OSPIM_CfgTypeDef *cfg);
  261. /**
  262. @endcond
  263. */
  264. /* Exported functions --------------------------------------------------------*/
  265. /** @defgroup OSPI_Exported_Functions OSPI Exported Functions
  266. * @{
  267. */
  268. /** @defgroup OSPI_Exported_Functions_Group1 Initialization/de-initialization functions
  269. * @brief Initialization and Configuration functions
  270. *
  271. @verbatim
  272. ===============================================================================
  273. ##### Initialization and Configuration functions #####
  274. ===============================================================================
  275. [..]
  276. This subsection provides a set of functions allowing to :
  277. (+) Initialize the OctoSPI.
  278. (+) De-initialize the OctoSPI.
  279. @endverbatim
  280. * @{
  281. */
  282. /**
  283. * @brief Initialize the OSPI mode according to the specified parameters
  284. * in the OSPI_InitTypeDef and initialize the associated handle.
  285. * @param hospi : OSPI handle
  286. * @retval HAL status
  287. */
  288. HAL_StatusTypeDef HAL_OSPI_Init(OSPI_HandleTypeDef *hospi)
  289. {
  290. HAL_StatusTypeDef status = HAL_OK;
  291. uint32_t tickstart = HAL_GetTick();
  292. /* Check the OSPI handle allocation */
  293. if (hospi == NULL)
  294. {
  295. status = HAL_ERROR;
  296. /* No error code can be set set as the handler is null */
  297. }
  298. else
  299. {
  300. /* Check the parameters of the initialization structure */
  301. assert_param(IS_OSPI_FIFO_THRESHOLD(hospi->Init.FifoThreshold));
  302. assert_param(IS_OSPI_DUALQUAD_MODE(hospi->Init.DualQuad));
  303. assert_param(IS_OSPI_MEMORY_TYPE(hospi->Init.MemoryType));
  304. assert_param(IS_OSPI_DEVICE_SIZE(hospi->Init.DeviceSize));
  305. assert_param(IS_OSPI_CS_HIGH_TIME(hospi->Init.ChipSelectHighTime));
  306. assert_param(IS_OSPI_FREE_RUN_CLK(hospi->Init.FreeRunningClock));
  307. assert_param(IS_OSPI_CLOCK_MODE(hospi->Init.ClockMode));
  308. assert_param(IS_OSPI_CLK_PRESCALER(hospi->Init.ClockPrescaler));
  309. assert_param(IS_OSPI_SAMPLE_SHIFTING(hospi->Init.SampleShifting));
  310. assert_param(IS_OSPI_DHQC(hospi->Init.DelayHoldQuarterCycle));
  311. assert_param(IS_OSPI_CS_BOUNDARY(hospi->Init.ChipSelectBoundary));
  312. assert_param(IS_OSPI_DLYBYP(hospi->Init.DelayBlockBypass));
  313. #if defined (OCTOSPI_DCR3_MAXTRAN)
  314. assert_param(IS_OSPI_MAXTRAN(hospi->Init.MaxTran));
  315. #endif
  316. /* Initialize error code */
  317. hospi->ErrorCode = HAL_OSPI_ERROR_NONE;
  318. /* Check if the state is the reset state */
  319. if (hospi->State == HAL_OSPI_STATE_RESET)
  320. {
  321. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  322. /* Reset Callback pointers in HAL_OSPI_STATE_RESET only */
  323. hospi->ErrorCallback = HAL_OSPI_ErrorCallback;
  324. hospi->AbortCpltCallback = HAL_OSPI_AbortCpltCallback;
  325. hospi->FifoThresholdCallback = HAL_OSPI_FifoThresholdCallback;
  326. hospi->CmdCpltCallback = HAL_OSPI_CmdCpltCallback;
  327. hospi->RxCpltCallback = HAL_OSPI_RxCpltCallback;
  328. hospi->TxCpltCallback = HAL_OSPI_TxCpltCallback;
  329. hospi->RxHalfCpltCallback = HAL_OSPI_RxHalfCpltCallback;
  330. hospi->TxHalfCpltCallback = HAL_OSPI_TxHalfCpltCallback;
  331. hospi->StatusMatchCallback = HAL_OSPI_StatusMatchCallback;
  332. hospi->TimeOutCallback = HAL_OSPI_TimeOutCallback;
  333. if (hospi->MspInitCallback == NULL)
  334. {
  335. hospi->MspInitCallback = HAL_OSPI_MspInit;
  336. }
  337. /* Init the low level hardware */
  338. hospi->MspInitCallback(hospi);
  339. #else
  340. /* Initialization of the low level hardware */
  341. HAL_OSPI_MspInit(hospi);
  342. #endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
  343. /* Configure the default timeout for the OSPI memory access */
  344. (void)HAL_OSPI_SetTimeout(hospi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
  345. /* Configure memory type, device size, chip select high time, delay block bypass,
  346. free running clock, clock mode */
  347. MODIFY_REG(hospi->Instance->DCR1,
  348. (OCTOSPI_DCR1_MTYP | OCTOSPI_DCR1_DEVSIZE | OCTOSPI_DCR1_CSHT | OCTOSPI_DCR1_DLYBYP |
  349. OCTOSPI_DCR1_FRCK | OCTOSPI_DCR1_CKMODE),
  350. (hospi->Init.MemoryType | ((hospi->Init.DeviceSize - 1U) << OCTOSPI_DCR1_DEVSIZE_Pos) |
  351. ((hospi->Init.ChipSelectHighTime - 1U) << OCTOSPI_DCR1_CSHT_Pos) |
  352. hospi->Init.DelayBlockBypass | hospi->Init.ClockMode));
  353. #if defined (OCTOSPI_DCR3_MAXTRAN)
  354. /* Configure chip select boundary and maximum transfer */
  355. hospi->Instance->DCR3 = ((hospi->Init.ChipSelectBoundary << OCTOSPI_DCR3_CSBOUND_Pos) |
  356. (hospi->Init.MaxTran << OCTOSPI_DCR3_MAXTRAN_Pos));
  357. #else
  358. /* Configure chip select boundary */
  359. hospi->Instance->DCR3 = (hospi->Init.ChipSelectBoundary << OCTOSPI_DCR3_CSBOUND_Pos);
  360. #endif
  361. #if defined (OCTOSPI_DCR4_REFRESH)
  362. /* Configure refresh */
  363. hospi->Instance->DCR4 = hospi->Init.Refresh;
  364. #endif
  365. /* Configure FIFO threshold */
  366. MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold - 1U) << OCTOSPI_CR_FTHRES_Pos));
  367. /* Wait till busy flag is reset */
  368. status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
  369. if (status == HAL_OK)
  370. {
  371. /* Configure clock prescaler */
  372. MODIFY_REG(hospi->Instance->DCR2, OCTOSPI_DCR2_PRESCALER,
  373. ((hospi->Init.ClockPrescaler - 1U) << OCTOSPI_DCR2_PRESCALER_Pos));
  374. /* Configure Dual Quad mode */
  375. MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_DQM, hospi->Init.DualQuad);
  376. /* Configure sample shifting and delay hold quarter cycle */
  377. MODIFY_REG(hospi->Instance->TCR, (OCTOSPI_TCR_SSHIFT | OCTOSPI_TCR_DHQC),
  378. (hospi->Init.SampleShifting | hospi->Init.DelayHoldQuarterCycle));
  379. /* Enable OctoSPI */
  380. __HAL_OSPI_ENABLE(hospi);
  381. /* Enable free running clock if needed : must be done after OSPI enable */
  382. if (hospi->Init.FreeRunningClock == HAL_OSPI_FREERUNCLK_ENABLE)
  383. {
  384. SET_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK);
  385. }
  386. /* Initialize the OSPI state */
  387. if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
  388. {
  389. hospi->State = HAL_OSPI_STATE_HYPERBUS_INIT;
  390. }
  391. else
  392. {
  393. hospi->State = HAL_OSPI_STATE_READY;
  394. }
  395. }
  396. }
  397. }
  398. /* Return function status */
  399. return status;
  400. }
  401. /**
  402. * @brief Initialize the OSPI MSP.
  403. * @param hospi : OSPI handle
  404. * @retval None
  405. */
  406. __weak void HAL_OSPI_MspInit(OSPI_HandleTypeDef *hospi)
  407. {
  408. /* Prevent unused argument(s) compilation warning */
  409. UNUSED(hospi);
  410. /* NOTE : This function should not be modified, when the callback is needed,
  411. the HAL_OSPI_MspInit can be implemented in the user file
  412. */
  413. }
  414. /**
  415. * @brief De-Initialize the OSPI peripheral.
  416. * @param hospi : OSPI handle
  417. * @retval HAL status
  418. */
  419. HAL_StatusTypeDef HAL_OSPI_DeInit(OSPI_HandleTypeDef *hospi)
  420. {
  421. HAL_StatusTypeDef status = HAL_OK;
  422. /* Check the OSPI handle allocation */
  423. if (hospi == NULL)
  424. {
  425. status = HAL_ERROR;
  426. /* No error code can be set set as the handler is null */
  427. }
  428. else
  429. {
  430. /* Disable OctoSPI */
  431. __HAL_OSPI_DISABLE(hospi);
  432. /* Disable free running clock if needed : must be done after OSPI disable */
  433. CLEAR_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK);
  434. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  435. if (hospi->MspDeInitCallback == NULL)
  436. {
  437. hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
  438. }
  439. /* DeInit the low level hardware */
  440. hospi->MspDeInitCallback(hospi);
  441. #else
  442. /* De-initialize the low-level hardware */
  443. HAL_OSPI_MspDeInit(hospi);
  444. #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
  445. /* Reset the driver state */
  446. hospi->State = HAL_OSPI_STATE_RESET;
  447. }
  448. return status;
  449. }
  450. /**
  451. * @brief DeInitialize the OSPI MSP.
  452. * @param hospi : OSPI handle
  453. * @retval None
  454. */
  455. __weak void HAL_OSPI_MspDeInit(OSPI_HandleTypeDef *hospi)
  456. {
  457. /* Prevent unused argument(s) compilation warning */
  458. UNUSED(hospi);
  459. /* NOTE : This function should not be modified, when the callback is needed,
  460. the HAL_OSPI_MspDeInit can be implemented in the user file
  461. */
  462. }
  463. /**
  464. * @}
  465. */
  466. /** @defgroup OSPI_Exported_Functions_Group2 Input and Output operation functions
  467. * @brief OSPI Transmit/Receive functions
  468. *
  469. @verbatim
  470. ===============================================================================
  471. ##### IO operation functions #####
  472. ===============================================================================
  473. [..]
  474. This subsection provides a set of functions allowing to :
  475. (+) Handle the interrupts.
  476. (+) Handle the command sequence (regular and Hyperbus).
  477. (+) Handle the Hyperbus configuration.
  478. (+) Transmit data in blocking, interrupt or DMA mode.
  479. (+) Receive data in blocking, interrupt or DMA mode.
  480. (+) Manage the auto-polling functional mode.
  481. (+) Manage the memory-mapped functional mode.
  482. @endverbatim
  483. * @{
  484. */
  485. /**
  486. * @brief Handle OSPI interrupt request.
  487. * @param hospi : OSPI handle
  488. * @retval None
  489. */
  490. void HAL_OSPI_IRQHandler(OSPI_HandleTypeDef *hospi)
  491. {
  492. __IO uint32_t *data_reg = &hospi->Instance->DR;
  493. uint32_t flag = hospi->Instance->SR;
  494. uint32_t itsource = hospi->Instance->CR;
  495. uint32_t currentstate = hospi->State;
  496. /* OctoSPI fifo threshold interrupt occurred -------------------------------*/
  497. if (((flag & HAL_OSPI_FLAG_FT) != 0U) && ((itsource & HAL_OSPI_IT_FT) != 0U))
  498. {
  499. if (currentstate == HAL_OSPI_STATE_BUSY_TX)
  500. {
  501. /* Write a data in the fifo */
  502. *((__IO uint8_t *)data_reg) = *hospi->pBuffPtr;
  503. hospi->pBuffPtr++;
  504. hospi->XferCount--;
  505. }
  506. else if (currentstate == HAL_OSPI_STATE_BUSY_RX)
  507. {
  508. /* Read a data from the fifo */
  509. *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
  510. hospi->pBuffPtr++;
  511. hospi->XferCount--;
  512. }
  513. else
  514. {
  515. /* Nothing to do */
  516. }
  517. if (hospi->XferCount == 0U)
  518. {
  519. /* All data have been received or transmitted for the transfer */
  520. /* Disable fifo threshold interrupt */
  521. __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_FT);
  522. }
  523. /* Fifo threshold callback */
  524. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  525. hospi->FifoThresholdCallback(hospi);
  526. #else
  527. HAL_OSPI_FifoThresholdCallback(hospi);
  528. #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
  529. }
  530. /* OctoSPI transfer complete interrupt occurred ----------------------------*/
  531. else if (((flag & HAL_OSPI_FLAG_TC) != 0U) && ((itsource & HAL_OSPI_IT_TC) != 0U))
  532. {
  533. if (currentstate == HAL_OSPI_STATE_BUSY_RX)
  534. {
  535. if ((hospi->XferCount > 0U) && ((flag & OCTOSPI_SR_FLEVEL) != 0U))
  536. {
  537. /* Read the last data received in the fifo */
  538. *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
  539. hospi->pBuffPtr++;
  540. hospi->XferCount--;
  541. }
  542. else if (hospi->XferCount == 0U)
  543. {
  544. /* Clear flag */
  545. hospi->Instance->FCR = HAL_OSPI_FLAG_TC;
  546. /* Disable the interrupts */
  547. __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
  548. /* Update state */
  549. hospi->State = HAL_OSPI_STATE_READY;
  550. /* RX complete callback */
  551. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  552. hospi->RxCpltCallback(hospi);
  553. #else
  554. HAL_OSPI_RxCpltCallback(hospi);
  555. #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
  556. }
  557. else
  558. {
  559. /* Nothing to do */
  560. }
  561. }
  562. else
  563. {
  564. /* Clear flag */
  565. hospi->Instance->FCR = HAL_OSPI_FLAG_TC;
  566. /* Disable the interrupts */
  567. __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
  568. /* Update state */
  569. hospi->State = HAL_OSPI_STATE_READY;
  570. if (currentstate == HAL_OSPI_STATE_BUSY_TX)
  571. {
  572. /* TX complete callback */
  573. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  574. hospi->TxCpltCallback(hospi);
  575. #else
  576. HAL_OSPI_TxCpltCallback(hospi);
  577. #endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
  578. }
  579. else if (currentstate == HAL_OSPI_STATE_BUSY_CMD)
  580. {
  581. /* Command complete callback */
  582. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  583. hospi->CmdCpltCallback(hospi);
  584. #else
  585. HAL_OSPI_CmdCpltCallback(hospi);
  586. #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
  587. }
  588. else if (currentstate == HAL_OSPI_STATE_ABORT)
  589. {
  590. if (hospi->ErrorCode == HAL_OSPI_ERROR_NONE)
  591. {
  592. /* Abort called by the user */
  593. /* Abort complete callback */
  594. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  595. hospi->AbortCpltCallback(hospi);
  596. #else
  597. HAL_OSPI_AbortCpltCallback(hospi);
  598. #endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
  599. }
  600. else
  601. {
  602. /* Abort due to an error (eg : DMA error) */
  603. /* Error callback */
  604. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  605. hospi->ErrorCallback(hospi);
  606. #else
  607. HAL_OSPI_ErrorCallback(hospi);
  608. #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
  609. }
  610. }
  611. else
  612. {
  613. /* Nothing to do */
  614. }
  615. }
  616. }
  617. /* OctoSPI status match interrupt occurred ---------------------------------*/
  618. else if (((flag & HAL_OSPI_FLAG_SM) != 0U) && ((itsource & HAL_OSPI_IT_SM) != 0U))
  619. {
  620. /* Clear flag */
  621. hospi->Instance->FCR = HAL_OSPI_FLAG_SM;
  622. /* Check if automatic poll mode stop is activated */
  623. if ((hospi->Instance->CR & OCTOSPI_CR_APMS) != 0U)
  624. {
  625. /* Disable the interrupts */
  626. __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE);
  627. /* Update state */
  628. hospi->State = HAL_OSPI_STATE_READY;
  629. }
  630. /* Status match callback */
  631. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  632. hospi->StatusMatchCallback(hospi);
  633. #else
  634. HAL_OSPI_StatusMatchCallback(hospi);
  635. #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
  636. }
  637. /* OctoSPI transfer error interrupt occurred -------------------------------*/
  638. else if (((flag & HAL_OSPI_FLAG_TE) != 0U) && ((itsource & HAL_OSPI_IT_TE) != 0U))
  639. {
  640. /* Clear flag */
  641. hospi->Instance->FCR = HAL_OSPI_FLAG_TE;
  642. /* Disable all interrupts */
  643. __HAL_OSPI_DISABLE_IT(hospi, (HAL_OSPI_IT_TO | HAL_OSPI_IT_SM | HAL_OSPI_IT_FT | HAL_OSPI_IT_TC | HAL_OSPI_IT_TE));
  644. /* Set error code */
  645. hospi->ErrorCode = HAL_OSPI_ERROR_TRANSFER;
  646. /* Check if the DMA is enabled */
  647. if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
  648. {
  649. /* Disable the DMA transfer on the OctoSPI side */
  650. CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
  651. /* Disable the DMA transfer on the DMA side */
  652. hospi->hdma->XferAbortCallback = OSPI_DMAAbortCplt;
  653. if (HAL_DMA_Abort_IT(hospi->hdma) != HAL_OK)
  654. {
  655. /* Update state */
  656. hospi->State = HAL_OSPI_STATE_READY;
  657. /* Error callback */
  658. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  659. hospi->ErrorCallback(hospi);
  660. #else
  661. HAL_OSPI_ErrorCallback(hospi);
  662. #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
  663. }
  664. }
  665. else
  666. {
  667. /* Update state */
  668. hospi->State = HAL_OSPI_STATE_READY;
  669. /* Error callback */
  670. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  671. hospi->ErrorCallback(hospi);
  672. #else
  673. HAL_OSPI_ErrorCallback(hospi);
  674. #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
  675. }
  676. }
  677. /* OctoSPI timeout interrupt occurred --------------------------------------*/
  678. else if (((flag & HAL_OSPI_FLAG_TO) != 0U) && ((itsource & HAL_OSPI_IT_TO) != 0U))
  679. {
  680. /* Clear flag */
  681. hospi->Instance->FCR = HAL_OSPI_FLAG_TO;
  682. /* Timeout callback */
  683. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  684. hospi->TimeOutCallback(hospi);
  685. #else
  686. HAL_OSPI_TimeOutCallback(hospi);
  687. #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
  688. }
  689. else
  690. {
  691. /* Nothing to do */
  692. }
  693. }
  694. /**
  695. * @brief Set the command configuration.
  696. * @param hospi : OSPI handle
  697. * @param cmd : structure that contains the command configuration information
  698. * @param Timeout : Timeout duration
  699. * @retval HAL status
  700. */
  701. HAL_StatusTypeDef HAL_OSPI_Command(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd, uint32_t Timeout)
  702. {
  703. HAL_StatusTypeDef status;
  704. uint32_t state;
  705. uint32_t tickstart = HAL_GetTick();
  706. /* Check the parameters of the command structure */
  707. assert_param(IS_OSPI_OPERATION_TYPE(cmd->OperationType));
  708. if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
  709. {
  710. assert_param(IS_OSPI_FLASH_ID(cmd->FlashId));
  711. }
  712. assert_param(IS_OSPI_INSTRUCTION_MODE(cmd->InstructionMode));
  713. if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
  714. {
  715. assert_param(IS_OSPI_INSTRUCTION_SIZE(cmd->InstructionSize));
  716. assert_param(IS_OSPI_INSTRUCTION_DTR_MODE(cmd->InstructionDtrMode));
  717. }
  718. assert_param(IS_OSPI_ADDRESS_MODE(cmd->AddressMode));
  719. if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
  720. {
  721. assert_param(IS_OSPI_ADDRESS_SIZE(cmd->AddressSize));
  722. assert_param(IS_OSPI_ADDRESS_DTR_MODE(cmd->AddressDtrMode));
  723. }
  724. assert_param(IS_OSPI_ALT_BYTES_MODE(cmd->AlternateBytesMode));
  725. if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
  726. {
  727. assert_param(IS_OSPI_ALT_BYTES_SIZE(cmd->AlternateBytesSize));
  728. assert_param(IS_OSPI_ALT_BYTES_DTR_MODE(cmd->AlternateBytesDtrMode));
  729. }
  730. assert_param(IS_OSPI_DATA_MODE(cmd->DataMode));
  731. if (cmd->DataMode != HAL_OSPI_DATA_NONE)
  732. {
  733. if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
  734. {
  735. assert_param(IS_OSPI_NUMBER_DATA(cmd->NbData));
  736. }
  737. assert_param(IS_OSPI_DATA_DTR_MODE(cmd->DataDtrMode));
  738. assert_param(IS_OSPI_DUMMY_CYCLES(cmd->DummyCycles));
  739. }
  740. assert_param(IS_OSPI_DQS_MODE(cmd->DQSMode));
  741. assert_param(IS_OSPI_SIOO_MODE(cmd->SIOOMode));
  742. /* Check the state of the driver */
  743. state = hospi->State;
  744. if (((state == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS)) ||
  745. ((state == HAL_OSPI_STATE_READ_CMD_CFG) && (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)) ||
  746. ((state == HAL_OSPI_STATE_WRITE_CMD_CFG) && (cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG)))
  747. {
  748. /* Wait till busy flag is reset */
  749. status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
  750. if (status == HAL_OK)
  751. {
  752. /* Initialize error code */
  753. hospi->ErrorCode = HAL_OSPI_ERROR_NONE;
  754. /* Configure the registers */
  755. status = OSPI_ConfigCmd(hospi, cmd);
  756. if (status == HAL_OK)
  757. {
  758. if (cmd->DataMode == HAL_OSPI_DATA_NONE)
  759. {
  760. /* When there is no data phase, the transfer start as soon as the configuration is done
  761. so wait until TC flag is set to go back in idle state */
  762. status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
  763. __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
  764. }
  765. else
  766. {
  767. /* Update the state */
  768. if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
  769. {
  770. hospi->State = HAL_OSPI_STATE_CMD_CFG;
  771. }
  772. else if (cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG)
  773. {
  774. if (hospi->State == HAL_OSPI_STATE_WRITE_CMD_CFG)
  775. {
  776. hospi->State = HAL_OSPI_STATE_CMD_CFG;
  777. }
  778. else
  779. {
  780. hospi->State = HAL_OSPI_STATE_READ_CMD_CFG;
  781. }
  782. }
  783. else
  784. {
  785. if (hospi->State == HAL_OSPI_STATE_READ_CMD_CFG)
  786. {
  787. hospi->State = HAL_OSPI_STATE_CMD_CFG;
  788. }
  789. else
  790. {
  791. hospi->State = HAL_OSPI_STATE_WRITE_CMD_CFG;
  792. }
  793. }
  794. }
  795. }
  796. }
  797. }
  798. else
  799. {
  800. status = HAL_ERROR;
  801. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  802. }
  803. /* Return function status */
  804. return status;
  805. }
  806. /**
  807. * @brief Set the command configuration in interrupt mode.
  808. * @param hospi : OSPI handle
  809. * @param cmd : structure that contains the command configuration information
  810. * @note This function is used only in Indirect Read or Write Modes
  811. * @retval HAL status
  812. */
  813. HAL_StatusTypeDef HAL_OSPI_Command_IT(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd)
  814. {
  815. HAL_StatusTypeDef status;
  816. uint32_t tickstart = HAL_GetTick();
  817. /* Check the parameters of the command structure */
  818. assert_param(IS_OSPI_OPERATION_TYPE(cmd->OperationType));
  819. if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
  820. {
  821. assert_param(IS_OSPI_FLASH_ID(cmd->FlashId));
  822. }
  823. assert_param(IS_OSPI_INSTRUCTION_MODE(cmd->InstructionMode));
  824. if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
  825. {
  826. assert_param(IS_OSPI_INSTRUCTION_SIZE(cmd->InstructionSize));
  827. assert_param(IS_OSPI_INSTRUCTION_DTR_MODE(cmd->InstructionDtrMode));
  828. }
  829. assert_param(IS_OSPI_ADDRESS_MODE(cmd->AddressMode));
  830. if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
  831. {
  832. assert_param(IS_OSPI_ADDRESS_SIZE(cmd->AddressSize));
  833. assert_param(IS_OSPI_ADDRESS_DTR_MODE(cmd->AddressDtrMode));
  834. }
  835. assert_param(IS_OSPI_ALT_BYTES_MODE(cmd->AlternateBytesMode));
  836. if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
  837. {
  838. assert_param(IS_OSPI_ALT_BYTES_SIZE(cmd->AlternateBytesSize));
  839. assert_param(IS_OSPI_ALT_BYTES_DTR_MODE(cmd->AlternateBytesDtrMode));
  840. }
  841. assert_param(IS_OSPI_DATA_MODE(cmd->DataMode));
  842. if (cmd->DataMode != HAL_OSPI_DATA_NONE)
  843. {
  844. assert_param(IS_OSPI_NUMBER_DATA(cmd->NbData));
  845. assert_param(IS_OSPI_DATA_DTR_MODE(cmd->DataDtrMode));
  846. assert_param(IS_OSPI_DUMMY_CYCLES(cmd->DummyCycles));
  847. }
  848. assert_param(IS_OSPI_DQS_MODE(cmd->DQSMode));
  849. assert_param(IS_OSPI_SIOO_MODE(cmd->SIOOMode));
  850. /* Check the state of the driver */
  851. if ((hospi->State == HAL_OSPI_STATE_READY) && (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG) &&
  852. (cmd->DataMode == HAL_OSPI_DATA_NONE) && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS))
  853. {
  854. /* Wait till busy flag is reset */
  855. status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
  856. if (status == HAL_OK)
  857. {
  858. /* Initialize error code */
  859. hospi->ErrorCode = HAL_OSPI_ERROR_NONE;
  860. /* Clear flags related to interrupt */
  861. __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
  862. /* Configure the registers */
  863. status = OSPI_ConfigCmd(hospi, cmd);
  864. if (status == HAL_OK)
  865. {
  866. /* Update the state */
  867. hospi->State = HAL_OSPI_STATE_BUSY_CMD;
  868. /* Enable the transfer complete and transfer error interrupts */
  869. __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_TE);
  870. }
  871. }
  872. }
  873. else
  874. {
  875. status = HAL_ERROR;
  876. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  877. }
  878. /* Return function status */
  879. return status;
  880. }
  881. /**
  882. * @brief Configure the Hyperbus parameters.
  883. * @param hospi : OSPI handle
  884. * @param cfg : Structure containing the Hyperbus configuration
  885. * @param Timeout : Timeout duration
  886. * @retval HAL status
  887. */
  888. HAL_StatusTypeDef HAL_OSPI_HyperbusCfg(OSPI_HandleTypeDef *hospi, OSPI_HyperbusCfgTypeDef *cfg, uint32_t Timeout)
  889. {
  890. HAL_StatusTypeDef status;
  891. uint32_t state;
  892. uint32_t tickstart = HAL_GetTick();
  893. /* Check the parameters of the hyperbus configuration structure */
  894. assert_param(IS_OSPI_RW_RECOVERY_TIME(cfg->RWRecoveryTime));
  895. assert_param(IS_OSPI_ACCESS_TIME(cfg->AccessTime));
  896. assert_param(IS_OSPI_WRITE_ZERO_LATENCY(cfg->WriteZeroLatency));
  897. assert_param(IS_OSPI_LATENCY_MODE(cfg->LatencyMode));
  898. /* Check the state of the driver */
  899. state = hospi->State;
  900. if ((state == HAL_OSPI_STATE_HYPERBUS_INIT) || (state == HAL_OSPI_STATE_READY))
  901. {
  902. /* Wait till busy flag is reset */
  903. status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
  904. if (status == HAL_OK)
  905. {
  906. /* Configure Hyperbus configuration Latency register */
  907. WRITE_REG(hospi->Instance->HLCR, ((cfg->RWRecoveryTime << OCTOSPI_HLCR_TRWR_Pos) |
  908. (cfg->AccessTime << OCTOSPI_HLCR_TACC_Pos) |
  909. cfg->WriteZeroLatency | cfg->LatencyMode));
  910. /* Update the state */
  911. hospi->State = HAL_OSPI_STATE_READY;
  912. }
  913. }
  914. else
  915. {
  916. status = HAL_ERROR;
  917. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  918. }
  919. /* Return function status */
  920. return status;
  921. }
  922. /**
  923. * @brief Set the Hyperbus command configuration.
  924. * @param hospi : OSPI handle
  925. * @param cmd : Structure containing the Hyperbus command
  926. * @param Timeout : Timeout duration
  927. * @retval HAL status
  928. */
  929. HAL_StatusTypeDef HAL_OSPI_HyperbusCmd(OSPI_HandleTypeDef *hospi, OSPI_HyperbusCmdTypeDef *cmd, uint32_t Timeout)
  930. {
  931. HAL_StatusTypeDef status;
  932. uint32_t tickstart = HAL_GetTick();
  933. /* Check the parameters of the hyperbus command structure */
  934. assert_param(IS_OSPI_ADDRESS_SPACE(cmd->AddressSpace));
  935. assert_param(IS_OSPI_ADDRESS_SIZE(cmd->AddressSize));
  936. assert_param(IS_OSPI_NUMBER_DATA(cmd->NbData));
  937. assert_param(IS_OSPI_DQS_MODE(cmd->DQSMode));
  938. /* Check the state of the driver */
  939. if ((hospi->State == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS))
  940. {
  941. /* Wait till busy flag is reset */
  942. status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
  943. if (status == HAL_OK)
  944. {
  945. /* Re-initialize the value of the functional mode */
  946. MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U);
  947. /* Configure the address space in the DCR1 register */
  948. MODIFY_REG(hospi->Instance->DCR1, OCTOSPI_DCR1_MTYP_0, cmd->AddressSpace);
  949. /* Configure the CCR and WCCR registers with the address size and the following configuration :
  950. - DQS signal enabled (used as RWDS)
  951. - DTR mode enabled on address and data
  952. - address and data on 8 lines */
  953. WRITE_REG(hospi->Instance->CCR, (cmd->DQSMode | OCTOSPI_CCR_DDTR | OCTOSPI_CCR_DMODE_2 |
  954. cmd->AddressSize | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADMODE_2));
  955. WRITE_REG(hospi->Instance->WCCR, (cmd->DQSMode | OCTOSPI_WCCR_DDTR | OCTOSPI_WCCR_DMODE_2 |
  956. cmd->AddressSize | OCTOSPI_WCCR_ADDTR | OCTOSPI_WCCR_ADMODE_2));
  957. /* Configure the DLR register with the number of data */
  958. WRITE_REG(hospi->Instance->DLR, (cmd->NbData - 1U));
  959. /* Configure the AR register with the address value */
  960. WRITE_REG(hospi->Instance->AR, cmd->Address);
  961. /* Update the state */
  962. hospi->State = HAL_OSPI_STATE_CMD_CFG;
  963. }
  964. }
  965. else
  966. {
  967. status = HAL_ERROR;
  968. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  969. }
  970. /* Return function status */
  971. return status;
  972. }
  973. /**
  974. * @brief Transmit an amount of data in blocking mode.
  975. * @param hospi : OSPI handle
  976. * @param pData : pointer to data buffer
  977. * @param Timeout : Timeout duration
  978. * @note This function is used only in Indirect Write Mode
  979. * @retval HAL status
  980. */
  981. HAL_StatusTypeDef HAL_OSPI_Transmit(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout)
  982. {
  983. HAL_StatusTypeDef status;
  984. uint32_t tickstart = HAL_GetTick();
  985. __IO uint32_t *data_reg = &hospi->Instance->DR;
  986. /* Check the data pointer allocation */
  987. if (pData == NULL)
  988. {
  989. status = HAL_ERROR;
  990. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
  991. }
  992. else
  993. {
  994. /* Check the state */
  995. if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
  996. {
  997. /* Configure counters and size */
  998. hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
  999. hospi->XferSize = hospi->XferCount;
  1000. hospi->pBuffPtr = pData;
  1001. /* Configure CR register with functional mode as indirect write */
  1002. MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
  1003. do
  1004. {
  1005. /* Wait till fifo threshold flag is set to send data */
  1006. status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_FT, SET, tickstart, Timeout);
  1007. if (status != HAL_OK)
  1008. {
  1009. break;
  1010. }
  1011. *((__IO uint8_t *)data_reg) = *hospi->pBuffPtr;
  1012. hospi->pBuffPtr++;
  1013. hospi->XferCount--;
  1014. }
  1015. while (hospi->XferCount > 0U);
  1016. if (status == HAL_OK)
  1017. {
  1018. /* Wait till transfer complete flag is set to go back in idle state */
  1019. status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
  1020. if (status == HAL_OK)
  1021. {
  1022. /* Clear transfer complete flag */
  1023. __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
  1024. /* Update state */
  1025. hospi->State = HAL_OSPI_STATE_READY;
  1026. }
  1027. }
  1028. }
  1029. else
  1030. {
  1031. status = HAL_ERROR;
  1032. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  1033. }
  1034. }
  1035. /* Return function status */
  1036. return status;
  1037. }
  1038. /**
  1039. * @brief Receive an amount of data in blocking mode.
  1040. * @param hospi : OSPI handle
  1041. * @param pData : pointer to data buffer
  1042. * @param Timeout : Timeout duration
  1043. * @note This function is used only in Indirect Read Mode
  1044. * @retval HAL status
  1045. */
  1046. HAL_StatusTypeDef HAL_OSPI_Receive(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout)
  1047. {
  1048. HAL_StatusTypeDef status;
  1049. uint32_t tickstart = HAL_GetTick();
  1050. __IO uint32_t *data_reg = &hospi->Instance->DR;
  1051. uint32_t addr_reg = hospi->Instance->AR;
  1052. uint32_t ir_reg = hospi->Instance->IR;
  1053. /* Check the data pointer allocation */
  1054. if (pData == NULL)
  1055. {
  1056. status = HAL_ERROR;
  1057. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
  1058. }
  1059. else
  1060. {
  1061. /* Check the state */
  1062. if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
  1063. {
  1064. /* Configure counters and size */
  1065. hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
  1066. hospi->XferSize = hospi->XferCount;
  1067. hospi->pBuffPtr = pData;
  1068. /* Configure CR register with functional mode as indirect read */
  1069. MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
  1070. /* Trig the transfer by re-writing address or instruction register */
  1071. if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
  1072. {
  1073. WRITE_REG(hospi->Instance->AR, addr_reg);
  1074. }
  1075. else
  1076. {
  1077. if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
  1078. {
  1079. WRITE_REG(hospi->Instance->AR, addr_reg);
  1080. }
  1081. else
  1082. {
  1083. WRITE_REG(hospi->Instance->IR, ir_reg);
  1084. }
  1085. }
  1086. do
  1087. {
  1088. /* Wait till fifo threshold or transfer complete flags are set to read received data */
  1089. status = OSPI_WaitFlagStateUntilTimeout(hospi, (HAL_OSPI_FLAG_FT | HAL_OSPI_FLAG_TC), SET, tickstart, Timeout);
  1090. if (status != HAL_OK)
  1091. {
  1092. break;
  1093. }
  1094. *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
  1095. hospi->pBuffPtr++;
  1096. hospi->XferCount--;
  1097. }
  1098. while (hospi->XferCount > 0U);
  1099. if (status == HAL_OK)
  1100. {
  1101. /* Wait till transfer complete flag is set to go back in idle state */
  1102. status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
  1103. if (status == HAL_OK)
  1104. {
  1105. /* Clear transfer complete flag */
  1106. __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
  1107. /* Update state */
  1108. hospi->State = HAL_OSPI_STATE_READY;
  1109. }
  1110. }
  1111. }
  1112. else
  1113. {
  1114. status = HAL_ERROR;
  1115. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  1116. }
  1117. }
  1118. /* Return function status */
  1119. return status;
  1120. }
  1121. /**
  1122. * @brief Send an amount of data in non-blocking mode with interrupt.
  1123. * @param hospi : OSPI handle
  1124. * @param pData : pointer to data buffer
  1125. * @note This function is used only in Indirect Write Mode
  1126. * @retval HAL status
  1127. */
  1128. HAL_StatusTypeDef HAL_OSPI_Transmit_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData)
  1129. {
  1130. HAL_StatusTypeDef status = HAL_OK;
  1131. /* Check the data pointer allocation */
  1132. if (pData == NULL)
  1133. {
  1134. status = HAL_ERROR;
  1135. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
  1136. }
  1137. else
  1138. {
  1139. /* Check the state */
  1140. if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
  1141. {
  1142. /* Configure counters and size */
  1143. hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
  1144. hospi->XferSize = hospi->XferCount;
  1145. hospi->pBuffPtr = pData;
  1146. /* Configure CR register with functional mode as indirect write */
  1147. MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
  1148. /* Clear flags related to interrupt */
  1149. __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
  1150. /* Update the state */
  1151. hospi->State = HAL_OSPI_STATE_BUSY_TX;
  1152. /* Enable the transfer complete, fifo threshold and transfer error interrupts */
  1153. __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
  1154. }
  1155. else
  1156. {
  1157. status = HAL_ERROR;
  1158. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  1159. }
  1160. }
  1161. /* Return function status */
  1162. return status;
  1163. }
  1164. /**
  1165. * @brief Receive an amount of data in non-blocking mode with interrupt.
  1166. * @param hospi : OSPI handle
  1167. * @param pData : pointer to data buffer
  1168. * @note This function is used only in Indirect Read Mode
  1169. * @retval HAL status
  1170. */
  1171. HAL_StatusTypeDef HAL_OSPI_Receive_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData)
  1172. {
  1173. HAL_StatusTypeDef status = HAL_OK;
  1174. uint32_t addr_reg = hospi->Instance->AR;
  1175. uint32_t ir_reg = hospi->Instance->IR;
  1176. /* Check the data pointer allocation */
  1177. if (pData == NULL)
  1178. {
  1179. status = HAL_ERROR;
  1180. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
  1181. }
  1182. else
  1183. {
  1184. /* Check the state */
  1185. if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
  1186. {
  1187. /* Configure counters and size */
  1188. hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
  1189. hospi->XferSize = hospi->XferCount;
  1190. hospi->pBuffPtr = pData;
  1191. /* Configure CR register with functional mode as indirect read */
  1192. MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
  1193. /* Clear flags related to interrupt */
  1194. __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
  1195. /* Update the state */
  1196. hospi->State = HAL_OSPI_STATE_BUSY_RX;
  1197. /* Enable the transfer complete, fifo threshold and transfer error interrupts */
  1198. __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
  1199. /* Trig the transfer by re-writing address or instruction register */
  1200. if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
  1201. {
  1202. WRITE_REG(hospi->Instance->AR, addr_reg);
  1203. }
  1204. else
  1205. {
  1206. if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
  1207. {
  1208. WRITE_REG(hospi->Instance->AR, addr_reg);
  1209. }
  1210. else
  1211. {
  1212. WRITE_REG(hospi->Instance->IR, ir_reg);
  1213. }
  1214. }
  1215. }
  1216. else
  1217. {
  1218. status = HAL_ERROR;
  1219. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  1220. }
  1221. }
  1222. /* Return function status */
  1223. return status;
  1224. }
  1225. /**
  1226. * @brief Send an amount of data in non-blocking mode with DMA.
  1227. * @param hospi : OSPI handle
  1228. * @param pData : pointer to data buffer
  1229. * @note This function is used only in Indirect Write Mode
  1230. * @note If DMA peripheral access is configured as halfword, the number
  1231. * of data and the fifo threshold should be aligned on halfword
  1232. * @note If DMA peripheral access is configured as word, the number
  1233. * of data and the fifo threshold should be aligned on word
  1234. * @retval HAL status
  1235. */
  1236. HAL_StatusTypeDef HAL_OSPI_Transmit_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData)
  1237. {
  1238. HAL_StatusTypeDef status = HAL_OK;
  1239. uint32_t data_size = hospi->Instance->DLR + 1U;
  1240. /* Check the data pointer allocation */
  1241. if (pData == NULL)
  1242. {
  1243. status = HAL_ERROR;
  1244. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
  1245. }
  1246. else
  1247. {
  1248. /* Check the state */
  1249. if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
  1250. {
  1251. /* Configure counters and size */
  1252. if (hospi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
  1253. {
  1254. hospi->XferCount = data_size;
  1255. }
  1256. else if (hospi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
  1257. {
  1258. if (((data_size % 2U) != 0U) || ((hospi->Init.FifoThreshold % 2U) != 0U))
  1259. {
  1260. /* The number of data or the fifo threshold is not aligned on halfword
  1261. => no transfer possible with DMA peripheral access configured as halfword */
  1262. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
  1263. status = HAL_ERROR;
  1264. }
  1265. else
  1266. {
  1267. hospi->XferCount = (data_size >> 1);
  1268. }
  1269. }
  1270. else if (hospi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
  1271. {
  1272. if (((data_size % 4U) != 0U) || ((hospi->Init.FifoThreshold % 4U) != 0U))
  1273. {
  1274. /* The number of data or the fifo threshold is not aligned on word
  1275. => no transfer possible with DMA peripheral access configured as word */
  1276. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
  1277. status = HAL_ERROR;
  1278. }
  1279. else
  1280. {
  1281. hospi->XferCount = (data_size >> 2);
  1282. }
  1283. }
  1284. else
  1285. {
  1286. /* Nothing to do */
  1287. }
  1288. if (status == HAL_OK)
  1289. {
  1290. hospi->XferSize = hospi->XferCount;
  1291. hospi->pBuffPtr = pData;
  1292. /* Configure CR register with functional mode as indirect write */
  1293. MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
  1294. /* Clear flags related to interrupt */
  1295. __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
  1296. /* Update the state */
  1297. hospi->State = HAL_OSPI_STATE_BUSY_TX;
  1298. /* Set the DMA transfer complete callback */
  1299. hospi->hdma->XferCpltCallback = OSPI_DMACplt;
  1300. /* Set the DMA Half transfer complete callback */
  1301. hospi->hdma->XferHalfCpltCallback = OSPI_DMAHalfCplt;
  1302. /* Set the DMA error callback */
  1303. hospi->hdma->XferErrorCallback = OSPI_DMAError;
  1304. /* Clear the DMA abort callback */
  1305. hospi->hdma->XferAbortCallback = NULL;
  1306. /* Configure the direction of the DMA */
  1307. hospi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
  1308. MODIFY_REG(hospi->hdma->Instance->CCR, DMA_CCR_DIR, hospi->hdma->Init.Direction);
  1309. /* Enable the transmit DMA Channel */
  1310. if (HAL_DMA_Start_IT(hospi->hdma, (uint32_t)pData, (uint32_t)&hospi->Instance->DR, hospi->XferSize) == HAL_OK)
  1311. {
  1312. /* Enable the transfer error interrupt */
  1313. __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TE);
  1314. /* Enable the DMA transfer by setting the DMAEN bit */
  1315. SET_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
  1316. }
  1317. else
  1318. {
  1319. status = HAL_ERROR;
  1320. hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
  1321. hospi->State = HAL_OSPI_STATE_READY;
  1322. }
  1323. }
  1324. }
  1325. else
  1326. {
  1327. status = HAL_ERROR;
  1328. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  1329. }
  1330. }
  1331. /* Return function status */
  1332. return status;
  1333. }
  1334. /**
  1335. * @brief Receive an amount of data in non-blocking mode with DMA.
  1336. * @param hospi : OSPI handle
  1337. * @param pData : pointer to data buffer.
  1338. * @note This function is used only in Indirect Read Mode
  1339. * @note If DMA peripheral access is configured as halfword, the number
  1340. * of data and the fifo threshold should be aligned on halfword
  1341. * @note If DMA peripheral access is configured as word, the number
  1342. * of data and the fifo threshold should be aligned on word
  1343. * @retval HAL status
  1344. */
  1345. HAL_StatusTypeDef HAL_OSPI_Receive_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData)
  1346. {
  1347. HAL_StatusTypeDef status = HAL_OK;
  1348. uint32_t data_size = hospi->Instance->DLR + 1U;
  1349. uint32_t addr_reg = hospi->Instance->AR;
  1350. uint32_t ir_reg = hospi->Instance->IR;
  1351. /* Check the data pointer allocation */
  1352. if (pData == NULL)
  1353. {
  1354. status = HAL_ERROR;
  1355. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
  1356. }
  1357. else
  1358. {
  1359. /* Check the state */
  1360. if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
  1361. {
  1362. /* Configure counters and size */
  1363. if (hospi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
  1364. {
  1365. hospi->XferCount = data_size;
  1366. }
  1367. else if (hospi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
  1368. {
  1369. if (((data_size % 2U) != 0U) || ((hospi->Init.FifoThreshold % 2U) != 0U))
  1370. {
  1371. /* The number of data or the fifo threshold is not aligned on halfword
  1372. => no transfer possible with DMA peripheral access configured as halfword */
  1373. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
  1374. status = HAL_ERROR;
  1375. }
  1376. else
  1377. {
  1378. hospi->XferCount = (data_size >> 1);
  1379. }
  1380. }
  1381. else if (hospi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
  1382. {
  1383. if (((data_size % 4U) != 0U) || ((hospi->Init.FifoThreshold % 4U) != 0U))
  1384. {
  1385. /* The number of data or the fifo threshold is not aligned on word
  1386. => no transfer possible with DMA peripheral access configured as word */
  1387. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
  1388. status = HAL_ERROR;
  1389. }
  1390. else
  1391. {
  1392. hospi->XferCount = (data_size >> 2);
  1393. }
  1394. }
  1395. else
  1396. {
  1397. /* Nothing to do */
  1398. }
  1399. if (status == HAL_OK)
  1400. {
  1401. hospi->XferSize = hospi->XferCount;
  1402. hospi->pBuffPtr = pData;
  1403. /* Configure CR register with functional mode as indirect read */
  1404. MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
  1405. /* Clear flags related to interrupt */
  1406. __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
  1407. /* Update the state */
  1408. hospi->State = HAL_OSPI_STATE_BUSY_RX;
  1409. /* Set the DMA transfer complete callback */
  1410. hospi->hdma->XferCpltCallback = OSPI_DMACplt;
  1411. /* Set the DMA Half transfer complete callback */
  1412. hospi->hdma->XferHalfCpltCallback = OSPI_DMAHalfCplt;
  1413. /* Set the DMA error callback */
  1414. hospi->hdma->XferErrorCallback = OSPI_DMAError;
  1415. /* Clear the DMA abort callback */
  1416. hospi->hdma->XferAbortCallback = NULL;
  1417. /* Configure the direction of the DMA */
  1418. hospi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY;
  1419. MODIFY_REG(hospi->hdma->Instance->CCR, DMA_CCR_DIR, hospi->hdma->Init.Direction);
  1420. /* Enable the transmit DMA Channel */
  1421. if (HAL_DMA_Start_IT(hospi->hdma, (uint32_t)&hospi->Instance->DR, (uint32_t)pData, hospi->XferSize) == HAL_OK)
  1422. {
  1423. /* Enable the transfer error interrupt */
  1424. __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TE);
  1425. /* Trig the transfer by re-writing address or instruction register */
  1426. if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
  1427. {
  1428. WRITE_REG(hospi->Instance->AR, addr_reg);
  1429. }
  1430. else
  1431. {
  1432. if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
  1433. {
  1434. WRITE_REG(hospi->Instance->AR, addr_reg);
  1435. }
  1436. else
  1437. {
  1438. WRITE_REG(hospi->Instance->IR, ir_reg);
  1439. }
  1440. }
  1441. /* Enable the DMA transfer by setting the DMAEN bit */
  1442. SET_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
  1443. }
  1444. else
  1445. {
  1446. status = HAL_ERROR;
  1447. hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
  1448. hospi->State = HAL_OSPI_STATE_READY;
  1449. }
  1450. }
  1451. }
  1452. else
  1453. {
  1454. status = HAL_ERROR;
  1455. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  1456. }
  1457. }
  1458. /* Return function status */
  1459. return status;
  1460. }
  1461. /**
  1462. * @brief Configure the OSPI Automatic Polling Mode in blocking mode.
  1463. * @param hospi : OSPI handle
  1464. * @param cfg : structure that contains the polling configuration information.
  1465. * @param Timeout : Timeout duration
  1466. * @note This function is used only in Automatic Polling Mode
  1467. * @note This function should not be used when the memory is in octal mode (see Errata Sheet)
  1468. * @retval HAL status
  1469. */
  1470. HAL_StatusTypeDef HAL_OSPI_AutoPolling(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
  1471. {
  1472. HAL_StatusTypeDef status;
  1473. uint32_t tickstart = HAL_GetTick();
  1474. uint32_t addr_reg = hospi->Instance->AR;
  1475. uint32_t ir_reg = hospi->Instance->IR;
  1476. #ifdef USE_FULL_ASSERT
  1477. uint32_t dlr_reg = hospi->Instance->DLR;
  1478. #endif /* USE_FULL_ASSERT */
  1479. /* Check the parameters of the autopolling configuration structure */
  1480. assert_param(IS_OSPI_MATCH_MODE(cfg->MatchMode));
  1481. assert_param(IS_OSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
  1482. assert_param(IS_OSPI_INTERVAL(cfg->Interval));
  1483. assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg + 1U));
  1484. /* Check the state */
  1485. if ((hospi->State == HAL_OSPI_STATE_CMD_CFG) && (cfg->AutomaticStop == HAL_OSPI_AUTOMATIC_STOP_ENABLE))
  1486. {
  1487. /* Wait till busy flag is reset */
  1488. status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
  1489. if (status == HAL_OK)
  1490. {
  1491. /* Configure registers */
  1492. WRITE_REG(hospi->Instance->PSMAR, cfg->Match);
  1493. WRITE_REG(hospi->Instance->PSMKR, cfg->Mask);
  1494. WRITE_REG(hospi->Instance->PIR, cfg->Interval);
  1495. MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE),
  1496. (cfg->MatchMode | cfg->AutomaticStop | OSPI_FUNCTIONAL_MODE_AUTO_POLLING));
  1497. /* Trig the transfer by re-writing address or instruction register */
  1498. if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
  1499. {
  1500. WRITE_REG(hospi->Instance->AR, addr_reg);
  1501. }
  1502. else
  1503. {
  1504. if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
  1505. {
  1506. WRITE_REG(hospi->Instance->AR, addr_reg);
  1507. }
  1508. else
  1509. {
  1510. WRITE_REG(hospi->Instance->IR, ir_reg);
  1511. }
  1512. }
  1513. /* Wait till status match flag is set to go back in idle state */
  1514. status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_SM, SET, tickstart, Timeout);
  1515. if (status == HAL_OK)
  1516. {
  1517. /* Clear status match flag */
  1518. __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_SM);
  1519. /* Update state */
  1520. hospi->State = HAL_OSPI_STATE_READY;
  1521. }
  1522. }
  1523. }
  1524. else
  1525. {
  1526. status = HAL_ERROR;
  1527. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  1528. }
  1529. /* Return function status */
  1530. return status;
  1531. }
  1532. /**
  1533. * @brief Configure the OSPI Automatic Polling Mode in non-blocking mode.
  1534. * @param hospi : OSPI handle
  1535. * @param cfg : structure that contains the polling configuration information.
  1536. * @note This function is used only in Automatic Polling Mode
  1537. * @note This function should not be used when the memory is in octal mode (see Errata Sheet)
  1538. * @retval HAL status
  1539. */
  1540. HAL_StatusTypeDef HAL_OSPI_AutoPolling_IT(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg)
  1541. {
  1542. HAL_StatusTypeDef status;
  1543. uint32_t tickstart = HAL_GetTick();
  1544. uint32_t addr_reg = hospi->Instance->AR;
  1545. uint32_t ir_reg = hospi->Instance->IR;
  1546. #ifdef USE_FULL_ASSERT
  1547. uint32_t dlr_reg = hospi->Instance->DLR;
  1548. #endif /* USE_FULL_ASSERT */
  1549. /* Check the parameters of the autopolling configuration structure */
  1550. assert_param(IS_OSPI_MATCH_MODE(cfg->MatchMode));
  1551. assert_param(IS_OSPI_AUTOMATIC_STOP(cfg->AutomaticStop));
  1552. assert_param(IS_OSPI_INTERVAL(cfg->Interval));
  1553. assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg + 1U));
  1554. /* Check the state */
  1555. if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
  1556. {
  1557. /* Wait till busy flag is reset */
  1558. status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
  1559. if (status == HAL_OK)
  1560. {
  1561. /* Configure registers */
  1562. WRITE_REG(hospi->Instance->PSMAR, cfg->Match);
  1563. WRITE_REG(hospi->Instance->PSMKR, cfg->Mask);
  1564. WRITE_REG(hospi->Instance->PIR, cfg->Interval);
  1565. MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE),
  1566. (cfg->MatchMode | cfg->AutomaticStop | OSPI_FUNCTIONAL_MODE_AUTO_POLLING));
  1567. /* Clear flags related to interrupt */
  1568. __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_SM);
  1569. /* Update state */
  1570. hospi->State = HAL_OSPI_STATE_BUSY_AUTO_POLLING;
  1571. /* Enable the status match and transfer error interrupts */
  1572. __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE);
  1573. /* Trig the transfer by re-writing address or instruction register */
  1574. if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
  1575. {
  1576. WRITE_REG(hospi->Instance->AR, addr_reg);
  1577. }
  1578. else
  1579. {
  1580. if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
  1581. {
  1582. WRITE_REG(hospi->Instance->AR, addr_reg);
  1583. }
  1584. else
  1585. {
  1586. WRITE_REG(hospi->Instance->IR, ir_reg);
  1587. }
  1588. }
  1589. }
  1590. }
  1591. else
  1592. {
  1593. status = HAL_ERROR;
  1594. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  1595. }
  1596. /* Return function status */
  1597. return status;
  1598. }
  1599. /**
  1600. * @brief Configure the Memory Mapped mode.
  1601. * @param hospi : OSPI handle
  1602. * @param cfg : structure that contains the memory mapped configuration information.
  1603. * @note This function is used only in Memory mapped Mode
  1604. * @retval HAL status
  1605. */
  1606. HAL_StatusTypeDef HAL_OSPI_MemoryMapped(OSPI_HandleTypeDef *hospi, OSPI_MemoryMappedTypeDef *cfg)
  1607. {
  1608. HAL_StatusTypeDef status;
  1609. uint32_t tickstart = HAL_GetTick();
  1610. /* Check the parameters of the memory-mapped configuration structure */
  1611. assert_param(IS_OSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
  1612. /* Check the state */
  1613. if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
  1614. {
  1615. /* Wait till busy flag is reset */
  1616. status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
  1617. if (status == HAL_OK)
  1618. {
  1619. /* Update state */
  1620. hospi->State = HAL_OSPI_STATE_BUSY_MEM_MAPPED;
  1621. if (cfg->TimeOutActivation == HAL_OSPI_TIMEOUT_COUNTER_ENABLE)
  1622. {
  1623. assert_param(IS_OSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
  1624. /* Configure register */
  1625. WRITE_REG(hospi->Instance->LPTR, cfg->TimeOutPeriod);
  1626. /* Clear flags related to interrupt */
  1627. __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TO);
  1628. /* Enable the timeout interrupt */
  1629. __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TO);
  1630. }
  1631. /* Configure CR register with functional mode as memory-mapped */
  1632. MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_TCEN | OCTOSPI_CR_FMODE),
  1633. (cfg->TimeOutActivation | OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED));
  1634. }
  1635. }
  1636. else
  1637. {
  1638. status = HAL_ERROR;
  1639. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  1640. }
  1641. /* Return function status */
  1642. return status;
  1643. }
  1644. /**
  1645. * @brief Transfer Error callback.
  1646. * @param hospi : OSPI handle
  1647. * @retval None
  1648. */
  1649. __weak void HAL_OSPI_ErrorCallback(OSPI_HandleTypeDef *hospi)
  1650. {
  1651. /* Prevent unused argument(s) compilation warning */
  1652. UNUSED(hospi);
  1653. /* NOTE : This function should not be modified, when the callback is needed,
  1654. the HAL_OSPI_ErrorCallback could be implemented in the user file
  1655. */
  1656. }
  1657. /**
  1658. * @brief Abort completed callback.
  1659. * @param hospi : OSPI handle
  1660. * @retval None
  1661. */
  1662. __weak void HAL_OSPI_AbortCpltCallback(OSPI_HandleTypeDef *hospi)
  1663. {
  1664. /* Prevent unused argument(s) compilation warning */
  1665. UNUSED(hospi);
  1666. /* NOTE: This function should not be modified, when the callback is needed,
  1667. the HAL_OSPI_AbortCpltCallback could be implemented in the user file
  1668. */
  1669. }
  1670. /**
  1671. * @brief FIFO Threshold callback.
  1672. * @param hospi : OSPI handle
  1673. * @retval None
  1674. */
  1675. __weak void HAL_OSPI_FifoThresholdCallback(OSPI_HandleTypeDef *hospi)
  1676. {
  1677. /* Prevent unused argument(s) compilation warning */
  1678. UNUSED(hospi);
  1679. /* NOTE : This function should not be modified, when the callback is needed,
  1680. the HAL_OSPI_FIFOThresholdCallback could be implemented in the user file
  1681. */
  1682. }
  1683. /**
  1684. * @brief Command completed callback.
  1685. * @param hospi : OSPI handle
  1686. * @retval None
  1687. */
  1688. __weak void HAL_OSPI_CmdCpltCallback(OSPI_HandleTypeDef *hospi)
  1689. {
  1690. /* Prevent unused argument(s) compilation warning */
  1691. UNUSED(hospi);
  1692. /* NOTE: This function should not be modified, when the callback is needed,
  1693. the HAL_OSPI_CmdCpltCallback could be implemented in the user file
  1694. */
  1695. }
  1696. /**
  1697. * @brief Rx Transfer completed callback.
  1698. * @param hospi : OSPI handle
  1699. * @retval None
  1700. */
  1701. __weak void HAL_OSPI_RxCpltCallback(OSPI_HandleTypeDef *hospi)
  1702. {
  1703. /* Prevent unused argument(s) compilation warning */
  1704. UNUSED(hospi);
  1705. /* NOTE: This function should not be modified, when the callback is needed,
  1706. the HAL_OSPI_RxCpltCallback could be implemented in the user file
  1707. */
  1708. }
  1709. /**
  1710. * @brief Tx Transfer completed callback.
  1711. * @param hospi : OSPI handle
  1712. * @retval None
  1713. */
  1714. __weak void HAL_OSPI_TxCpltCallback(OSPI_HandleTypeDef *hospi)
  1715. {
  1716. /* Prevent unused argument(s) compilation warning */
  1717. UNUSED(hospi);
  1718. /* NOTE: This function should not be modified, when the callback is needed,
  1719. the HAL_OSPI_TxCpltCallback could be implemented in the user file
  1720. */
  1721. }
  1722. /**
  1723. * @brief Rx Half Transfer completed callback.
  1724. * @param hospi : OSPI handle
  1725. * @retval None
  1726. */
  1727. __weak void HAL_OSPI_RxHalfCpltCallback(OSPI_HandleTypeDef *hospi)
  1728. {
  1729. /* Prevent unused argument(s) compilation warning */
  1730. UNUSED(hospi);
  1731. /* NOTE: This function should not be modified, when the callback is needed,
  1732. the HAL_OSPI_RxHalfCpltCallback could be implemented in the user file
  1733. */
  1734. }
  1735. /**
  1736. * @brief Tx Half Transfer completed callback.
  1737. * @param hospi : OSPI handle
  1738. * @retval None
  1739. */
  1740. __weak void HAL_OSPI_TxHalfCpltCallback(OSPI_HandleTypeDef *hospi)
  1741. {
  1742. /* Prevent unused argument(s) compilation warning */
  1743. UNUSED(hospi);
  1744. /* NOTE: This function should not be modified, when the callback is needed,
  1745. the HAL_OSPI_TxHalfCpltCallback could be implemented in the user file
  1746. */
  1747. }
  1748. /**
  1749. * @brief Status Match callback.
  1750. * @param hospi : OSPI handle
  1751. * @retval None
  1752. */
  1753. __weak void HAL_OSPI_StatusMatchCallback(OSPI_HandleTypeDef *hospi)
  1754. {
  1755. /* Prevent unused argument(s) compilation warning */
  1756. UNUSED(hospi);
  1757. /* NOTE : This function should not be modified, when the callback is needed,
  1758. the HAL_OSPI_StatusMatchCallback could be implemented in the user file
  1759. */
  1760. }
  1761. /**
  1762. * @brief Timeout callback.
  1763. * @param hospi : OSPI handle
  1764. * @retval None
  1765. */
  1766. __weak void HAL_OSPI_TimeOutCallback(OSPI_HandleTypeDef *hospi)
  1767. {
  1768. /* Prevent unused argument(s) compilation warning */
  1769. UNUSED(hospi);
  1770. /* NOTE : This function should not be modified, when the callback is needed,
  1771. the HAL_OSPI_TimeOutCallback could be implemented in the user file
  1772. */
  1773. }
  1774. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  1775. /**
  1776. * @brief Register a User OSPI Callback
  1777. * To be used to override the weak predefined callback
  1778. * @param hospi : OSPI handle
  1779. * @param CallbackID : ID of the callback to be registered
  1780. * This parameter can be one of the following values:
  1781. * @arg @ref HAL_OSPI_ERROR_CB_ID OSPI Error Callback ID
  1782. * @arg @ref HAL_OSPI_ABORT_CB_ID OSPI Abort Callback ID
  1783. * @arg @ref HAL_OSPI_FIFO_THRESHOLD_CB_ID OSPI FIFO Threshold Callback ID
  1784. * @arg @ref HAL_OSPI_CMD_CPLT_CB_ID OSPI Command Complete Callback ID
  1785. * @arg @ref HAL_OSPI_RX_CPLT_CB_ID OSPI Rx Complete Callback ID
  1786. * @arg @ref HAL_OSPI_TX_CPLT_CB_ID OSPI Tx Complete Callback ID
  1787. * @arg @ref HAL_OSPI_RX_HALF_CPLT_CB_ID OSPI Rx Half Complete Callback ID
  1788. * @arg @ref HAL_OSPI_TX_HALF_CPLT_CB_ID OSPI Tx Half Complete Callback ID
  1789. * @arg @ref HAL_OSPI_STATUS_MATCH_CB_ID OSPI Status Match Callback ID
  1790. * @arg @ref HAL_OSPI_TIMEOUT_CB_ID OSPI Timeout Callback ID
  1791. * @arg @ref HAL_OSPI_MSP_INIT_CB_ID OSPI MspInit callback ID
  1792. * @arg @ref HAL_OSPI_MSP_DEINIT_CB_ID OSPI MspDeInit callback ID
  1793. * @param pCallback : pointer to the Callback function
  1794. * @retval status
  1795. */
  1796. HAL_StatusTypeDef HAL_OSPI_RegisterCallback(OSPI_HandleTypeDef *hospi, HAL_OSPI_CallbackIDTypeDef CallbackID,
  1797. pOSPI_CallbackTypeDef pCallback)
  1798. {
  1799. HAL_StatusTypeDef status = HAL_OK;
  1800. if (pCallback == NULL)
  1801. {
  1802. /* Update the error code */
  1803. hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
  1804. return HAL_ERROR;
  1805. }
  1806. if (hospi->State == HAL_OSPI_STATE_READY)
  1807. {
  1808. switch (CallbackID)
  1809. {
  1810. case HAL_OSPI_ERROR_CB_ID :
  1811. hospi->ErrorCallback = pCallback;
  1812. break;
  1813. case HAL_OSPI_ABORT_CB_ID :
  1814. hospi->AbortCpltCallback = pCallback;
  1815. break;
  1816. case HAL_OSPI_FIFO_THRESHOLD_CB_ID :
  1817. hospi->FifoThresholdCallback = pCallback;
  1818. break;
  1819. case HAL_OSPI_CMD_CPLT_CB_ID :
  1820. hospi->CmdCpltCallback = pCallback;
  1821. break;
  1822. case HAL_OSPI_RX_CPLT_CB_ID :
  1823. hospi->RxCpltCallback = pCallback;
  1824. break;
  1825. case HAL_OSPI_TX_CPLT_CB_ID :
  1826. hospi->TxCpltCallback = pCallback;
  1827. break;
  1828. case HAL_OSPI_RX_HALF_CPLT_CB_ID :
  1829. hospi->RxHalfCpltCallback = pCallback;
  1830. break;
  1831. case HAL_OSPI_TX_HALF_CPLT_CB_ID :
  1832. hospi->TxHalfCpltCallback = pCallback;
  1833. break;
  1834. case HAL_OSPI_STATUS_MATCH_CB_ID :
  1835. hospi->StatusMatchCallback = pCallback;
  1836. break;
  1837. case HAL_OSPI_TIMEOUT_CB_ID :
  1838. hospi->TimeOutCallback = pCallback;
  1839. break;
  1840. case HAL_OSPI_MSP_INIT_CB_ID :
  1841. hospi->MspInitCallback = pCallback;
  1842. break;
  1843. case HAL_OSPI_MSP_DEINIT_CB_ID :
  1844. hospi->MspDeInitCallback = pCallback;
  1845. break;
  1846. default :
  1847. /* Update the error code */
  1848. hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
  1849. /* update return status */
  1850. status = HAL_ERROR;
  1851. break;
  1852. }
  1853. }
  1854. else if (hospi->State == HAL_OSPI_STATE_RESET)
  1855. {
  1856. switch (CallbackID)
  1857. {
  1858. case HAL_OSPI_MSP_INIT_CB_ID :
  1859. hospi->MspInitCallback = pCallback;
  1860. break;
  1861. case HAL_OSPI_MSP_DEINIT_CB_ID :
  1862. hospi->MspDeInitCallback = pCallback;
  1863. break;
  1864. default :
  1865. /* Update the error code */
  1866. hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
  1867. /* update return status */
  1868. status = HAL_ERROR;
  1869. break;
  1870. }
  1871. }
  1872. else
  1873. {
  1874. /* Update the error code */
  1875. hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
  1876. /* update return status */
  1877. status = HAL_ERROR;
  1878. }
  1879. return status;
  1880. }
  1881. /**
  1882. * @brief Unregister a User OSPI Callback
  1883. * OSPI Callback is redirected to the weak predefined callback
  1884. * @param hospi : OSPI handle
  1885. * @param CallbackID : ID of the callback to be unregistered
  1886. * This parameter can be one of the following values:
  1887. * @arg @ref HAL_OSPI_ERROR_CB_ID OSPI Error Callback ID
  1888. * @arg @ref HAL_OSPI_ABORT_CB_ID OSPI Abort Callback ID
  1889. * @arg @ref HAL_OSPI_FIFO_THRESHOLD_CB_ID OSPI FIFO Threshold Callback ID
  1890. * @arg @ref HAL_OSPI_CMD_CPLT_CB_ID OSPI Command Complete Callback ID
  1891. * @arg @ref HAL_OSPI_RX_CPLT_CB_ID OSPI Rx Complete Callback ID
  1892. * @arg @ref HAL_OSPI_TX_CPLT_CB_ID OSPI Tx Complete Callback ID
  1893. * @arg @ref HAL_OSPI_RX_HALF_CPLT_CB_ID OSPI Rx Half Complete Callback ID
  1894. * @arg @ref HAL_OSPI_TX_HALF_CPLT_CB_ID OSPI Tx Half Complete Callback ID
  1895. * @arg @ref HAL_OSPI_STATUS_MATCH_CB_ID OSPI Status Match Callback ID
  1896. * @arg @ref HAL_OSPI_TIMEOUT_CB_ID OSPI Timeout Callback ID
  1897. * @arg @ref HAL_OSPI_MSP_INIT_CB_ID OSPI MspInit callback ID
  1898. * @arg @ref HAL_OSPI_MSP_DEINIT_CB_ID OSPI MspDeInit callback ID
  1899. * @retval status
  1900. */
  1901. HAL_StatusTypeDef HAL_OSPI_UnRegisterCallback(OSPI_HandleTypeDef *hospi, HAL_OSPI_CallbackIDTypeDef CallbackID)
  1902. {
  1903. HAL_StatusTypeDef status = HAL_OK;
  1904. if (hospi->State == HAL_OSPI_STATE_READY)
  1905. {
  1906. switch (CallbackID)
  1907. {
  1908. case HAL_OSPI_ERROR_CB_ID :
  1909. hospi->ErrorCallback = HAL_OSPI_ErrorCallback;
  1910. break;
  1911. case HAL_OSPI_ABORT_CB_ID :
  1912. hospi->AbortCpltCallback = HAL_OSPI_AbortCpltCallback;
  1913. break;
  1914. case HAL_OSPI_FIFO_THRESHOLD_CB_ID :
  1915. hospi->FifoThresholdCallback = HAL_OSPI_FifoThresholdCallback;
  1916. break;
  1917. case HAL_OSPI_CMD_CPLT_CB_ID :
  1918. hospi->CmdCpltCallback = HAL_OSPI_CmdCpltCallback;
  1919. break;
  1920. case HAL_OSPI_RX_CPLT_CB_ID :
  1921. hospi->RxCpltCallback = HAL_OSPI_RxCpltCallback;
  1922. break;
  1923. case HAL_OSPI_TX_CPLT_CB_ID :
  1924. hospi->TxCpltCallback = HAL_OSPI_TxCpltCallback;
  1925. break;
  1926. case HAL_OSPI_RX_HALF_CPLT_CB_ID :
  1927. hospi->RxHalfCpltCallback = HAL_OSPI_RxHalfCpltCallback;
  1928. break;
  1929. case HAL_OSPI_TX_HALF_CPLT_CB_ID :
  1930. hospi->TxHalfCpltCallback = HAL_OSPI_TxHalfCpltCallback;
  1931. break;
  1932. case HAL_OSPI_STATUS_MATCH_CB_ID :
  1933. hospi->StatusMatchCallback = HAL_OSPI_StatusMatchCallback;
  1934. break;
  1935. case HAL_OSPI_TIMEOUT_CB_ID :
  1936. hospi->TimeOutCallback = HAL_OSPI_TimeOutCallback;
  1937. break;
  1938. case HAL_OSPI_MSP_INIT_CB_ID :
  1939. hospi->MspInitCallback = HAL_OSPI_MspInit;
  1940. break;
  1941. case HAL_OSPI_MSP_DEINIT_CB_ID :
  1942. hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
  1943. break;
  1944. default :
  1945. /* Update the error code */
  1946. hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
  1947. /* update return status */
  1948. status = HAL_ERROR;
  1949. break;
  1950. }
  1951. }
  1952. else if (hospi->State == HAL_OSPI_STATE_RESET)
  1953. {
  1954. switch (CallbackID)
  1955. {
  1956. case HAL_OSPI_MSP_INIT_CB_ID :
  1957. hospi->MspInitCallback = HAL_OSPI_MspInit;
  1958. break;
  1959. case HAL_OSPI_MSP_DEINIT_CB_ID :
  1960. hospi->MspDeInitCallback = HAL_OSPI_MspDeInit;
  1961. break;
  1962. default :
  1963. /* Update the error code */
  1964. hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
  1965. /* update return status */
  1966. status = HAL_ERROR;
  1967. break;
  1968. }
  1969. }
  1970. else
  1971. {
  1972. /* Update the error code */
  1973. hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
  1974. /* update return status */
  1975. status = HAL_ERROR;
  1976. }
  1977. return status;
  1978. }
  1979. #endif /* defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
  1980. /**
  1981. * @}
  1982. */
  1983. /** @defgroup OSPI_Exported_Functions_Group3 Peripheral Control and State functions
  1984. * @brief OSPI control and State functions
  1985. *
  1986. @verbatim
  1987. ===============================================================================
  1988. ##### Peripheral Control and State functions #####
  1989. ===============================================================================
  1990. [..]
  1991. This subsection provides a set of functions allowing to :
  1992. (+) Check in run-time the state of the driver.
  1993. (+) Check the error code set during last operation.
  1994. (+) Abort any operation.
  1995. (+) Manage the Fifo threshold.
  1996. (+) Configure the timeout duration used in the driver.
  1997. @endverbatim
  1998. * @{
  1999. */
  2000. /**
  2001. * @brief Abort the current transmission.
  2002. * @param hospi : OSPI handle
  2003. * @retval HAL status
  2004. */
  2005. HAL_StatusTypeDef HAL_OSPI_Abort(OSPI_HandleTypeDef *hospi)
  2006. {
  2007. HAL_StatusTypeDef status = HAL_OK;
  2008. uint32_t state;
  2009. uint32_t tickstart = HAL_GetTick();
  2010. /* Check if the state is in one of the busy or configured states */
  2011. state = hospi->State;
  2012. if (((state & OSPI_BUSY_STATE_MASK) != 0U) || ((state & OSPI_CFG_STATE_MASK) != 0U))
  2013. {
  2014. /* Check if the DMA is enabled */
  2015. if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
  2016. {
  2017. /* Disable the DMA transfer on the OctoSPI side */
  2018. CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
  2019. /* Disable the DMA transfer on the DMA side */
  2020. status = HAL_DMA_Abort(hospi->hdma);
  2021. if (status != HAL_OK)
  2022. {
  2023. hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
  2024. }
  2025. }
  2026. if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
  2027. {
  2028. /* Perform an abort of the OctoSPI */
  2029. SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
  2030. /* Wait until the transfer complete flag is set to go back in idle state */
  2031. status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, hospi->Timeout);
  2032. if (status == HAL_OK)
  2033. {
  2034. /* Clear transfer complete flag */
  2035. __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
  2036. /* Wait until the busy flag is reset to go back in idle state */
  2037. status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
  2038. if (status == HAL_OK)
  2039. {
  2040. /* Update state */
  2041. hospi->State = HAL_OSPI_STATE_READY;
  2042. }
  2043. }
  2044. }
  2045. else
  2046. {
  2047. /* Update state */
  2048. hospi->State = HAL_OSPI_STATE_READY;
  2049. }
  2050. }
  2051. else
  2052. {
  2053. status = HAL_ERROR;
  2054. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  2055. }
  2056. /* Return function status */
  2057. return status;
  2058. }
  2059. /**
  2060. * @brief Abort the current transmission (non-blocking function)
  2061. * @param hospi : OSPI handle
  2062. * @retval HAL status
  2063. */
  2064. HAL_StatusTypeDef HAL_OSPI_Abort_IT(OSPI_HandleTypeDef *hospi)
  2065. {
  2066. HAL_StatusTypeDef status = HAL_OK;
  2067. uint32_t state;
  2068. /* Check if the state is in one of the busy or configured states */
  2069. state = hospi->State;
  2070. if (((state & OSPI_BUSY_STATE_MASK) != 0U) || ((state & OSPI_CFG_STATE_MASK) != 0U))
  2071. {
  2072. /* Disable all interrupts */
  2073. __HAL_OSPI_DISABLE_IT(hospi, (HAL_OSPI_IT_TO | HAL_OSPI_IT_SM | HAL_OSPI_IT_FT | HAL_OSPI_IT_TC | HAL_OSPI_IT_TE));
  2074. /* Update state */
  2075. hospi->State = HAL_OSPI_STATE_ABORT;
  2076. /* Check if the DMA is enabled */
  2077. if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
  2078. {
  2079. /* Disable the DMA transfer on the OctoSPI side */
  2080. CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
  2081. /* Disable the DMA transfer on the DMA side */
  2082. hospi->hdma->XferAbortCallback = OSPI_DMAAbortCplt;
  2083. if (HAL_DMA_Abort_IT(hospi->hdma) != HAL_OK)
  2084. {
  2085. /* Update state */
  2086. hospi->State = HAL_OSPI_STATE_READY;
  2087. /* Abort callback */
  2088. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  2089. hospi->AbortCpltCallback(hospi);
  2090. #else
  2091. HAL_OSPI_AbortCpltCallback(hospi);
  2092. #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
  2093. }
  2094. }
  2095. else
  2096. {
  2097. if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
  2098. {
  2099. /* Clear transfer complete flag */
  2100. __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
  2101. /* Enable the transfer complete interrupts */
  2102. __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
  2103. /* Perform an abort of the OctoSPI */
  2104. SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
  2105. }
  2106. else
  2107. {
  2108. /* Update state */
  2109. hospi->State = HAL_OSPI_STATE_READY;
  2110. /* Abort callback */
  2111. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  2112. hospi->AbortCpltCallback(hospi);
  2113. #else
  2114. HAL_OSPI_AbortCpltCallback(hospi);
  2115. #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
  2116. }
  2117. }
  2118. }
  2119. else
  2120. {
  2121. status = HAL_ERROR;
  2122. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  2123. }
  2124. /* Return function status */
  2125. return status;
  2126. }
  2127. /** @brief Set OSPI Fifo threshold.
  2128. * @param hospi : OSPI handle.
  2129. * @param Threshold : Threshold of the Fifo.
  2130. * @retval HAL status
  2131. */
  2132. HAL_StatusTypeDef HAL_OSPI_SetFifoThreshold(OSPI_HandleTypeDef *hospi, uint32_t Threshold)
  2133. {
  2134. HAL_StatusTypeDef status = HAL_OK;
  2135. /* Check the state */
  2136. if ((hospi->State & OSPI_BUSY_STATE_MASK) == 0U)
  2137. {
  2138. /* Synchronize initialization structure with the new fifo threshold value */
  2139. hospi->Init.FifoThreshold = Threshold;
  2140. /* Configure new fifo threshold */
  2141. MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold - 1U) << OCTOSPI_CR_FTHRES_Pos));
  2142. }
  2143. else
  2144. {
  2145. status = HAL_ERROR;
  2146. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
  2147. }
  2148. /* Return function status */
  2149. return status;
  2150. }
  2151. /** @brief Get OSPI Fifo threshold.
  2152. * @param hospi : OSPI handle.
  2153. * @retval Fifo threshold
  2154. */
  2155. uint32_t HAL_OSPI_GetFifoThreshold(const OSPI_HandleTypeDef *hospi)
  2156. {
  2157. return ((READ_BIT(hospi->Instance->CR, OCTOSPI_CR_FTHRES) >> OCTOSPI_CR_FTHRES_Pos) + 1U);
  2158. }
  2159. /** @brief Set OSPI timeout.
  2160. * @param hospi : OSPI handle.
  2161. * @param Timeout : Timeout for the memory access.
  2162. * @retval None
  2163. */
  2164. HAL_StatusTypeDef HAL_OSPI_SetTimeout(OSPI_HandleTypeDef *hospi, uint32_t Timeout)
  2165. {
  2166. hospi->Timeout = Timeout;
  2167. return HAL_OK;
  2168. }
  2169. /**
  2170. * @brief Return the OSPI error code.
  2171. * @param hospi : OSPI handle
  2172. * @retval OSPI Error Code
  2173. */
  2174. uint32_t HAL_OSPI_GetError(const OSPI_HandleTypeDef *hospi)
  2175. {
  2176. return hospi->ErrorCode;
  2177. }
  2178. /**
  2179. * @brief Return the OSPI handle state.
  2180. * @param hospi : OSPI handle
  2181. * @retval HAL state
  2182. */
  2183. uint32_t HAL_OSPI_GetState(const OSPI_HandleTypeDef *hospi)
  2184. {
  2185. /* Return OSPI handle state */
  2186. return hospi->State;
  2187. }
  2188. /**
  2189. * @}
  2190. */
  2191. /** @defgroup OSPI_Exported_Functions_Group4 IO Manager configuration function
  2192. * @brief OSPI IO Manager configuration function
  2193. *
  2194. @verbatim
  2195. ===============================================================================
  2196. ##### IO Manager configuration function #####
  2197. ===============================================================================
  2198. [..]
  2199. This subsection provides a set of functions allowing to :
  2200. (+) Configure the IO manager.
  2201. @endverbatim
  2202. * @{
  2203. */
  2204. /**
  2205. * @brief Configure the OctoSPI IO manager.
  2206. * @param hospi : OSPI handle
  2207. * @param cfg : Configuration of the IO Manager for the instance
  2208. * @param Timeout : Timeout duration
  2209. * @retval HAL status
  2210. */
  2211. HAL_StatusTypeDef HAL_OSPIM_Config(OSPI_HandleTypeDef *hospi, OSPIM_CfgTypeDef *cfg, uint32_t Timeout)
  2212. {
  2213. HAL_StatusTypeDef status = HAL_OK;
  2214. uint32_t instance;
  2215. uint8_t index;
  2216. uint8_t ospi_enabled = 0U;
  2217. uint8_t other_instance;
  2218. OSPIM_CfgTypeDef IOM_cfg[OSPI_NB_INSTANCE];
  2219. /* Prevent unused argument(s) compilation warning */
  2220. UNUSED(Timeout);
  2221. /* Check the parameters of the OctoSPI IO Manager configuration structure */
  2222. assert_param(IS_OSPIM_PORT(cfg->ClkPort));
  2223. assert_param(IS_OSPIM_DQS_PORT(cfg->DQSPort));
  2224. assert_param(IS_OSPIM_PORT(cfg->NCSPort));
  2225. assert_param(IS_OSPIM_IO_PORT(cfg->IOLowPort));
  2226. assert_param(IS_OSPIM_IO_PORT(cfg->IOHighPort));
  2227. #if defined (OCTOSPIM_CR_MUXEN)
  2228. assert_param(IS_OSPIM_REQ2ACKTIME(cfg->Req2AckTime));
  2229. #endif
  2230. if (hospi->Instance == OCTOSPI1)
  2231. {
  2232. instance = 0U;
  2233. other_instance = 1U;
  2234. }
  2235. else
  2236. {
  2237. instance = 1U;
  2238. other_instance = 0U;
  2239. }
  2240. /**************** Get current configuration of the instances ****************/
  2241. for (index = 0U; index < OSPI_NB_INSTANCE; index++)
  2242. {
  2243. if (OSPIM_GetConfig(index + 1U, &(IOM_cfg[index])) != HAL_OK)
  2244. {
  2245. status = HAL_ERROR;
  2246. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
  2247. }
  2248. }
  2249. if (status == HAL_OK)
  2250. {
  2251. /********** Disable both OctoSPI to configure OctoSPI IO Manager **********/
  2252. if ((OCTOSPI1->CR & OCTOSPI_CR_EN) != 0U)
  2253. {
  2254. CLEAR_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN);
  2255. ospi_enabled |= 0x1U;
  2256. }
  2257. if ((OCTOSPI2->CR & OCTOSPI_CR_EN) != 0U)
  2258. {
  2259. CLEAR_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN);
  2260. ospi_enabled |= 0x2U;
  2261. }
  2262. /***************** Deactivation of previous configuration *****************/
  2263. CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].NCSPort - 1U)], OCTOSPIM_PCR_NCSEN);
  2264. #if defined (OCTOSPIM_CR_MUXEN)
  2265. if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) != 0U)
  2266. {
  2267. /* De-multiplexing should be performed */
  2268. CLEAR_BIT(OCTOSPIM->CR, OCTOSPIM_CR_MUXEN);
  2269. if (other_instance == 1U)
  2270. {
  2271. SET_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort - 1U)], OCTOSPIM_PCR_CLKSRC);
  2272. if (IOM_cfg[other_instance].DQSPort != 0U)
  2273. {
  2274. SET_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort - 1U)], OCTOSPIM_PCR_DQSSRC);
  2275. }
  2276. if (IOM_cfg[other_instance].IOLowPort != HAL_OSPIM_IOPORT_NONE)
  2277. {
  2278. SET_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort - 1U)& OSPI_IOM_PORT_MASK)], \
  2279. OCTOSPIM_PCR_IOLSRC_1);
  2280. }
  2281. if (IOM_cfg[other_instance].IOHighPort != HAL_OSPIM_IOPORT_NONE)
  2282. {
  2283. SET_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort - 1U)& OSPI_IOM_PORT_MASK)], \
  2284. OCTOSPIM_PCR_IOHSRC_1);
  2285. }
  2286. }
  2287. }
  2288. else
  2289. {
  2290. #endif
  2291. if (IOM_cfg[instance].ClkPort != 0U)
  2292. {
  2293. CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].ClkPort - 1U)], OCTOSPIM_PCR_CLKEN);
  2294. if (IOM_cfg[instance].DQSPort != 0U)
  2295. {
  2296. CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].DQSPort - 1U)], OCTOSPIM_PCR_DQSEN);
  2297. }
  2298. if (IOM_cfg[instance].IOLowPort != HAL_OSPIM_IOPORT_NONE)
  2299. {
  2300. CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOLowPort - 1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN);
  2301. }
  2302. if (IOM_cfg[instance].IOHighPort != HAL_OSPIM_IOPORT_NONE)
  2303. {
  2304. CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOHighPort - 1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN);
  2305. }
  2306. }
  2307. #if defined (OCTOSPIM_CR_MUXEN)
  2308. }
  2309. #endif
  2310. /********************* Deactivation of other instance *********************/
  2311. if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) || (cfg->NCSPort == IOM_cfg[other_instance].NCSPort) ||
  2312. ((cfg->DQSPort == IOM_cfg[other_instance].DQSPort) && (cfg->DQSPort != 0U)) ||
  2313. (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) ||
  2314. (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort))
  2315. {
  2316. #if defined (OCTOSPIM_CR_MUXEN)
  2317. if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) &&
  2318. (cfg->DQSPort == IOM_cfg[other_instance].DQSPort) &&
  2319. (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) &&
  2320. (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort))
  2321. {
  2322. /* Multiplexing should be performed */
  2323. SET_BIT(OCTOSPIM->CR, OCTOSPIM_CR_MUXEN);
  2324. }
  2325. else
  2326. {
  2327. #endif
  2328. CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort - 1U)], OCTOSPIM_PCR_CLKEN);
  2329. if (IOM_cfg[other_instance].DQSPort != 0U)
  2330. {
  2331. CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort - 1U)], OCTOSPIM_PCR_DQSEN);
  2332. }
  2333. CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].NCSPort - 1U)], OCTOSPIM_PCR_NCSEN);
  2334. if (IOM_cfg[other_instance].IOLowPort != HAL_OSPIM_IOPORT_NONE)
  2335. {
  2336. CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
  2337. OCTOSPIM_PCR_IOLEN);
  2338. }
  2339. if (IOM_cfg[other_instance].IOHighPort != HAL_OSPIM_IOPORT_NONE)
  2340. {
  2341. CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
  2342. OCTOSPIM_PCR_IOHEN);
  2343. }
  2344. #if defined (OCTOSPIM_CR_MUXEN)
  2345. }
  2346. #endif
  2347. }
  2348. /******************** Activation of new configuration *********************/
  2349. MODIFY_REG(OCTOSPIM->PCR[(cfg->NCSPort - 1U)], (OCTOSPIM_PCR_NCSEN | OCTOSPIM_PCR_NCSSRC),
  2350. (OCTOSPIM_PCR_NCSEN | (instance << OCTOSPIM_PCR_NCSSRC_Pos)));
  2351. #if defined (OCTOSPIM_CR_MUXEN)
  2352. if ((cfg->Req2AckTime - 1U) > ((OCTOSPIM->CR & OCTOSPIM_CR_REQ2ACK_TIME) >> OCTOSPIM_CR_REQ2ACK_TIME_Pos))
  2353. {
  2354. MODIFY_REG(OCTOSPIM->CR, OCTOSPIM_CR_REQ2ACK_TIME, ((cfg->Req2AckTime - 1U) << OCTOSPIM_CR_REQ2ACK_TIME_Pos));
  2355. }
  2356. if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) != 0U)
  2357. {
  2358. MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort - 1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), OCTOSPIM_PCR_CLKEN);
  2359. if (cfg->DQSPort != 0U)
  2360. {
  2361. MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort - 1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC), OCTOSPIM_PCR_DQSEN);
  2362. }
  2363. if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U)
  2364. {
  2365. MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
  2366. (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), OCTOSPIM_PCR_IOLEN);
  2367. }
  2368. else if (cfg->IOLowPort != HAL_OSPIM_IOPORT_NONE)
  2369. {
  2370. MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
  2371. (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), OCTOSPIM_PCR_IOHEN);
  2372. }
  2373. else
  2374. {
  2375. /* Nothing to do */
  2376. }
  2377. if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U)
  2378. {
  2379. MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
  2380. (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0));
  2381. }
  2382. else if (cfg->IOHighPort != HAL_OSPIM_IOPORT_NONE)
  2383. {
  2384. MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
  2385. (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0));
  2386. }
  2387. else
  2388. {
  2389. /* Nothing to do */
  2390. }
  2391. }
  2392. else
  2393. {
  2394. #endif
  2395. MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort - 1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC),
  2396. (OCTOSPIM_PCR_CLKEN | (instance << OCTOSPIM_PCR_CLKSRC_Pos)));
  2397. if (cfg->DQSPort != 0U)
  2398. {
  2399. MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort - 1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC),
  2400. (OCTOSPIM_PCR_DQSEN | (instance << OCTOSPIM_PCR_DQSSRC_Pos)));
  2401. }
  2402. if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U)
  2403. {
  2404. MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
  2405. (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
  2406. (OCTOSPIM_PCR_IOLEN | (instance << (OCTOSPIM_PCR_IOLSRC_Pos + 1U))));
  2407. }
  2408. else if (cfg->IOLowPort != HAL_OSPIM_IOPORT_NONE)
  2409. {
  2410. MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
  2411. (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
  2412. (OCTOSPIM_PCR_IOHEN | (instance << (OCTOSPIM_PCR_IOHSRC_Pos + 1U))));
  2413. }
  2414. else
  2415. {
  2416. /* Nothing to do */
  2417. }
  2418. if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U)
  2419. {
  2420. MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
  2421. (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
  2422. (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0 | (instance << (OCTOSPIM_PCR_IOLSRC_Pos + 1U))));
  2423. }
  2424. else if (cfg->IOHighPort != HAL_OSPIM_IOPORT_NONE)
  2425. {
  2426. MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
  2427. (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
  2428. (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0 | (instance << (OCTOSPIM_PCR_IOHSRC_Pos + 1U))));
  2429. }
  2430. else
  2431. {
  2432. /* Nothing to do */
  2433. }
  2434. #if defined (OCTOSPIM_CR_MUXEN)
  2435. }
  2436. #endif
  2437. /******* Re-enable both OctoSPI after configure OctoSPI IO Manager ********/
  2438. if ((ospi_enabled & 0x1U) != 0U)
  2439. {
  2440. SET_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN);
  2441. }
  2442. if ((ospi_enabled & 0x2U) != 0U)
  2443. {
  2444. SET_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN);
  2445. }
  2446. }
  2447. /* Return function status */
  2448. return status;
  2449. }
  2450. /**
  2451. * @}
  2452. */
  2453. /**
  2454. @cond 0
  2455. */
  2456. /**
  2457. * @brief DMA OSPI process complete callback.
  2458. * @param hdma : DMA handle
  2459. * @retval None
  2460. */
  2461. static void OSPI_DMACplt(DMA_HandleTypeDef *hdma)
  2462. {
  2463. OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef *)(hdma->Parent);
  2464. hospi->XferCount = 0;
  2465. /* Disable the DMA transfer on the OctoSPI side */
  2466. CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
  2467. /* Disable the DMA channel */
  2468. __HAL_DMA_DISABLE(hdma);
  2469. /* Enable the OSPI transfer complete Interrupt */
  2470. __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
  2471. }
  2472. /**
  2473. * @brief DMA OSPI process half complete callback.
  2474. * @param hdma : DMA handle
  2475. * @retval None
  2476. */
  2477. static void OSPI_DMAHalfCplt(DMA_HandleTypeDef *hdma)
  2478. {
  2479. OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef *)(hdma->Parent);
  2480. hospi->XferCount = (hospi->XferCount >> 1);
  2481. if (hospi->State == HAL_OSPI_STATE_BUSY_RX)
  2482. {
  2483. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  2484. hospi->RxHalfCpltCallback(hospi);
  2485. #else
  2486. HAL_OSPI_RxHalfCpltCallback(hospi);
  2487. #endif /*(USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
  2488. }
  2489. else
  2490. {
  2491. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  2492. hospi->TxHalfCpltCallback(hospi);
  2493. #else
  2494. HAL_OSPI_TxHalfCpltCallback(hospi);
  2495. #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
  2496. }
  2497. }
  2498. /**
  2499. * @brief DMA OSPI communication error callback.
  2500. * @param hdma : DMA handle
  2501. * @retval None
  2502. */
  2503. static void OSPI_DMAError(DMA_HandleTypeDef *hdma)
  2504. {
  2505. OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef *)(hdma->Parent);
  2506. hospi->XferCount = 0;
  2507. hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
  2508. /* Disable the DMA transfer on the OctoSPI side */
  2509. CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
  2510. /* Abort the OctoSPI */
  2511. if (HAL_OSPI_Abort_IT(hospi) != HAL_OK)
  2512. {
  2513. /* Disable the interrupts */
  2514. __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
  2515. /* Update state */
  2516. hospi->State = HAL_OSPI_STATE_READY;
  2517. /* Error callback */
  2518. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  2519. hospi->ErrorCallback(hospi);
  2520. #else
  2521. HAL_OSPI_ErrorCallback(hospi);
  2522. #endif /*(USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
  2523. }
  2524. }
  2525. /**
  2526. * @brief DMA OSPI abort complete callback.
  2527. * @param hdma : DMA handle
  2528. * @retval None
  2529. */
  2530. static void OSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma)
  2531. {
  2532. OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef *)(hdma->Parent);
  2533. hospi->XferCount = 0;
  2534. /* Check the state */
  2535. if (hospi->State == HAL_OSPI_STATE_ABORT)
  2536. {
  2537. /* DMA abort called by OctoSPI abort */
  2538. if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
  2539. {
  2540. /* Clear transfer complete flag */
  2541. __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
  2542. /* Enable the transfer complete interrupts */
  2543. __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
  2544. /* Perform an abort of the OctoSPI */
  2545. SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
  2546. }
  2547. else
  2548. {
  2549. /* Update state */
  2550. hospi->State = HAL_OSPI_STATE_READY;
  2551. /* Abort callback */
  2552. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  2553. hospi->AbortCpltCallback(hospi);
  2554. #else
  2555. HAL_OSPI_AbortCpltCallback(hospi);
  2556. #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U) */
  2557. }
  2558. }
  2559. else
  2560. {
  2561. /* DMA abort called due to a transfer error interrupt */
  2562. /* Update state */
  2563. hospi->State = HAL_OSPI_STATE_READY;
  2564. /* Error callback */
  2565. #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
  2566. hospi->ErrorCallback(hospi);
  2567. #else
  2568. HAL_OSPI_ErrorCallback(hospi);
  2569. #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)*/
  2570. }
  2571. }
  2572. /**
  2573. * @brief Wait for a flag state until timeout.
  2574. * @param hospi : OSPI handle
  2575. * @param Flag : Flag checked
  2576. * @param State : Value of the flag expected
  2577. * @param Timeout : Duration of the timeout
  2578. * @param Tickstart : Tick start value
  2579. * @retval HAL status
  2580. */
  2581. static HAL_StatusTypeDef OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef *hospi, uint32_t Flag,
  2582. FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
  2583. {
  2584. /* Wait until flag is in expected state */
  2585. while ((__HAL_OSPI_GET_FLAG(hospi, Flag)) != State)
  2586. {
  2587. /* Check for the Timeout */
  2588. if (Timeout != HAL_MAX_DELAY)
  2589. {
  2590. if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
  2591. {
  2592. hospi->State = HAL_OSPI_STATE_ERROR;
  2593. hospi->ErrorCode |= HAL_OSPI_ERROR_TIMEOUT;
  2594. return HAL_ERROR;
  2595. }
  2596. }
  2597. }
  2598. return HAL_OK;
  2599. }
  2600. /**
  2601. * @brief Configure the registers for the regular command mode.
  2602. * @param hospi : OSPI handle
  2603. * @param cmd : structure that contains the command configuration information
  2604. * @retval HAL status
  2605. */
  2606. static HAL_StatusTypeDef OSPI_ConfigCmd(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd)
  2607. {
  2608. HAL_StatusTypeDef status = HAL_OK;
  2609. __IO uint32_t *ccr_reg;
  2610. __IO uint32_t *tcr_reg;
  2611. __IO uint32_t *ir_reg;
  2612. __IO uint32_t *abr_reg;
  2613. /* Re-initialize the value of the functional mode */
  2614. MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U);
  2615. /* Configure the flash ID */
  2616. if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
  2617. {
  2618. MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FSEL, cmd->FlashId);
  2619. }
  2620. if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)
  2621. {
  2622. ccr_reg = &(hospi->Instance->WCCR);
  2623. tcr_reg = &(hospi->Instance->WTCR);
  2624. ir_reg = &(hospi->Instance->WIR);
  2625. abr_reg = &(hospi->Instance->WABR);
  2626. }
  2627. else
  2628. {
  2629. ccr_reg = &(hospi->Instance->CCR);
  2630. tcr_reg = &(hospi->Instance->TCR);
  2631. ir_reg = &(hospi->Instance->IR);
  2632. abr_reg = &(hospi->Instance->ABR);
  2633. }
  2634. /* Configure the CCR register with DQS and SIOO modes */
  2635. *ccr_reg = (cmd->DQSMode | cmd->SIOOMode);
  2636. if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
  2637. {
  2638. /* Configure the ABR register with alternate bytes value */
  2639. *abr_reg = cmd->AlternateBytes;
  2640. /* Configure the CCR register with alternate bytes communication parameters */
  2641. MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ABMODE | OCTOSPI_CCR_ABDTR | OCTOSPI_CCR_ABSIZE),
  2642. (cmd->AlternateBytesMode | cmd->AlternateBytesDtrMode | cmd->AlternateBytesSize));
  2643. }
  2644. /* Configure the TCR register with the number of dummy cycles */
  2645. MODIFY_REG((*tcr_reg), OCTOSPI_TCR_DCYC, cmd->DummyCycles);
  2646. if (cmd->DataMode != HAL_OSPI_DATA_NONE)
  2647. {
  2648. if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
  2649. {
  2650. /* Configure the DLR register with the number of data */
  2651. hospi->Instance->DLR = (cmd->NbData - 1U);
  2652. }
  2653. }
  2654. if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
  2655. {
  2656. if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
  2657. {
  2658. if (cmd->DataMode != HAL_OSPI_DATA_NONE)
  2659. {
  2660. /* ---- Command with instruction, address and data ---- */
  2661. /* Configure the CCR register with all communication parameters */
  2662. MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE |
  2663. OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE |
  2664. OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR),
  2665. (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
  2666. cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize |
  2667. cmd->DataMode | cmd->DataDtrMode));
  2668. }
  2669. else
  2670. {
  2671. /* ---- Command with instruction and address ---- */
  2672. /* Configure the CCR register with all communication parameters */
  2673. MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE |
  2674. OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE),
  2675. (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
  2676. cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize));
  2677. /* The DHQC bit is linked with DDTR bit which should be activated */
  2678. if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) &&
  2679. (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE))
  2680. {
  2681. MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE);
  2682. }
  2683. }
  2684. /* Configure the IR register with the instruction value */
  2685. *ir_reg = cmd->Instruction;
  2686. /* Configure the AR register with the address value */
  2687. hospi->Instance->AR = cmd->Address;
  2688. }
  2689. else
  2690. {
  2691. if (cmd->DataMode != HAL_OSPI_DATA_NONE)
  2692. {
  2693. /* ---- Command with instruction and data ---- */
  2694. /* Configure the CCR register with all communication parameters */
  2695. MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE |
  2696. OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR),
  2697. (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
  2698. cmd->DataMode | cmd->DataDtrMode));
  2699. }
  2700. else
  2701. {
  2702. /* ---- Command with only instruction ---- */
  2703. /* Configure the CCR register with all communication parameters */
  2704. MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE),
  2705. (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize));
  2706. /* The DHQC bit is linked with DDTR bit which should be activated */
  2707. if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) &&
  2708. (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE))
  2709. {
  2710. MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE);
  2711. }
  2712. }
  2713. /* Configure the IR register with the instruction value */
  2714. *ir_reg = cmd->Instruction;
  2715. }
  2716. }
  2717. else
  2718. {
  2719. if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
  2720. {
  2721. if (cmd->DataMode != HAL_OSPI_DATA_NONE)
  2722. {
  2723. /* ---- Command with address and data ---- */
  2724. /* Configure the CCR register with all communication parameters */
  2725. MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE |
  2726. OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR),
  2727. (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize | cmd->DataMode |
  2728. cmd->DataDtrMode));
  2729. }
  2730. else
  2731. {
  2732. /* ---- Command with only address ---- */
  2733. /* Configure the CCR register with all communication parameters */
  2734. MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE),
  2735. (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize));
  2736. }
  2737. /* Configure the AR register with the instruction value */
  2738. hospi->Instance->AR = cmd->Address;
  2739. }
  2740. else
  2741. {
  2742. /* ---- Invalid command configuration (no instruction, no address) ---- */
  2743. status = HAL_ERROR;
  2744. hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
  2745. }
  2746. }
  2747. /* Return function status */
  2748. return status;
  2749. }
  2750. /**
  2751. * @brief Get the current IOM configuration for an OctoSPI instance.
  2752. * @param instance_nb : number of the instance
  2753. * @param cfg : configuration of the IO Manager for the instance
  2754. * @retval HAL status
  2755. */
  2756. static HAL_StatusTypeDef OSPIM_GetConfig(uint8_t instance_nb, OSPIM_CfgTypeDef *cfg)
  2757. {
  2758. HAL_StatusTypeDef status = HAL_OK;
  2759. uint32_t reg;
  2760. uint32_t value = 0U;
  2761. uint32_t index;
  2762. if ((instance_nb == 0U) || (instance_nb > OSPI_NB_INSTANCE) || (cfg == NULL))
  2763. {
  2764. /* Invalid parameter -> error returned */
  2765. status = HAL_ERROR;
  2766. }
  2767. else
  2768. {
  2769. /* Initialize the structure */
  2770. cfg->ClkPort = 0U;
  2771. cfg->DQSPort = 0U;
  2772. cfg->NCSPort = 0U;
  2773. cfg->IOLowPort = 0U;
  2774. cfg->IOHighPort = 0U;
  2775. if (instance_nb == 2U)
  2776. {
  2777. #if defined (OCTOSPIM_CR_MUXEN)
  2778. if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) == 0U)
  2779. {
  2780. #endif
  2781. value = (OCTOSPIM_PCR_CLKSRC | OCTOSPIM_PCR_DQSSRC | OCTOSPIM_PCR_NCSSRC
  2782. | OCTOSPIM_PCR_IOLSRC_1 | OCTOSPIM_PCR_IOHSRC_1);
  2783. #if defined (OCTOSPIM_CR_MUXEN)
  2784. }
  2785. else
  2786. {
  2787. value = OCTOSPIM_PCR_NCSSRC;
  2788. }
  2789. #endif
  2790. }
  2791. /* Get the information about the instance */
  2792. for (index = 0U; index < OSPI_IOM_NB_PORTS; index ++)
  2793. {
  2794. reg = OCTOSPIM->PCR[index];
  2795. if ((reg & OCTOSPIM_PCR_CLKEN) != 0U)
  2796. {
  2797. /* The clock is enabled on this port */
  2798. if ((reg & OCTOSPIM_PCR_CLKSRC) == (value & OCTOSPIM_PCR_CLKSRC))
  2799. {
  2800. /* The clock correspond to the instance passed as parameter */
  2801. cfg->ClkPort = index + 1U;
  2802. }
  2803. }
  2804. if ((reg & OCTOSPIM_PCR_DQSEN) != 0U)
  2805. {
  2806. /* The DQS is enabled on this port */
  2807. if ((reg & OCTOSPIM_PCR_DQSSRC) == (value & OCTOSPIM_PCR_DQSSRC))
  2808. {
  2809. /* The DQS correspond to the instance passed as parameter */
  2810. cfg->DQSPort = index + 1U;
  2811. }
  2812. }
  2813. if ((reg & OCTOSPIM_PCR_NCSEN) != 0U)
  2814. {
  2815. /* The nCS is enabled on this port */
  2816. if ((reg & OCTOSPIM_PCR_NCSSRC) == (value & OCTOSPIM_PCR_NCSSRC))
  2817. {
  2818. /* The nCS correspond to the instance passed as parameter */
  2819. cfg->NCSPort = index + 1U;
  2820. }
  2821. }
  2822. if ((reg & OCTOSPIM_PCR_IOLEN) != 0U)
  2823. {
  2824. /* The IO Low is enabled on this port */
  2825. if ((reg & OCTOSPIM_PCR_IOLSRC_1) == (value & OCTOSPIM_PCR_IOLSRC_1))
  2826. {
  2827. /* The IO Low correspond to the instance passed as parameter */
  2828. if ((reg & OCTOSPIM_PCR_IOLSRC_0) == 0U)
  2829. {
  2830. cfg->IOLowPort = (OCTOSPIM_PCR_IOLEN | (index + 1U));
  2831. }
  2832. else
  2833. {
  2834. cfg->IOLowPort = (OCTOSPIM_PCR_IOHEN | (index + 1U));
  2835. }
  2836. }
  2837. }
  2838. if ((reg & OCTOSPIM_PCR_IOHEN) != 0U)
  2839. {
  2840. /* The IO High is enabled on this port */
  2841. if ((reg & OCTOSPIM_PCR_IOHSRC_1) == (value & OCTOSPIM_PCR_IOHSRC_1))
  2842. {
  2843. /* The IO High correspond to the instance passed as parameter */
  2844. if ((reg & OCTOSPIM_PCR_IOHSRC_0) == 0U)
  2845. {
  2846. cfg->IOHighPort = (OCTOSPIM_PCR_IOLEN | (index + 1U));
  2847. }
  2848. else
  2849. {
  2850. cfg->IOHighPort = (OCTOSPIM_PCR_IOHEN | (index + 1U));
  2851. }
  2852. }
  2853. }
  2854. }
  2855. }
  2856. /* Return function status */
  2857. return status;
  2858. }
  2859. /**
  2860. @endcond
  2861. */
  2862. /**
  2863. * @}
  2864. */
  2865. #endif /* HAL_OSPI_MODULE_ENABLED */
  2866. /**
  2867. * @}
  2868. */
  2869. /**
  2870. * @}
  2871. */
  2872. #endif /* OCTOSPI || OCTOSPI1 || OCTOSPI2 */