fsl_lpspi.c 81 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314
  1. /*
  2. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2020,2021 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include "fsl_lpspi.h"
  9. /*******************************************************************************
  10. * Definitions
  11. ******************************************************************************/
  12. /* Component ID definition, used by tools. */
  13. #ifndef FSL_COMPONENT_ID
  14. #define FSL_COMPONENT_ID "platform.drivers.lpspi"
  15. #endif
  16. /*!
  17. * @brief Default watermark values.
  18. *
  19. * The default watermarks are set to zero.
  20. */
  21. enum _lpspi_default_watermarks
  22. {
  23. kLpspiDefaultTxWatermark = 0,
  24. kLpspiDefaultRxWatermark = 0,
  25. };
  26. /*! @brief Typedef for master interrupt handler. */
  27. typedef void (*lpspi_master_isr_t)(LPSPI_Type *base, lpspi_master_handle_t *handle);
  28. /*! @brief Typedef for slave interrupt handler. */
  29. typedef void (*lpspi_slave_isr_t)(LPSPI_Type *base, lpspi_slave_handle_t *handle);
  30. /*******************************************************************************
  31. * Prototypes
  32. ******************************************************************************/
  33. /*!
  34. * @brief Configures the LPSPI peripheral chip select polarity.
  35. *
  36. * This function takes in the desired peripheral chip select (Pcs) and it's corresponding desired polarity and
  37. * configures the Pcs signal to operate with the desired characteristic.
  38. *
  39. * @param base LPSPI peripheral address.
  40. * @param pcs The particular peripheral chip select (parameter value is of type lpspi_which_pcs_t) for which we wish to
  41. * apply the active high or active low characteristic.
  42. * @param activeLowOrHigh The setting for either "active high, inactive low (0)" or "active low, inactive high(1)" of
  43. * type lpspi_pcs_polarity_config_t.
  44. */
  45. static void LPSPI_SetOnePcsPolarity(LPSPI_Type *base,
  46. lpspi_which_pcs_t pcs,
  47. lpspi_pcs_polarity_config_t activeLowOrHigh);
  48. /*!
  49. * @brief Combine the write data for 1 byte to 4 bytes.
  50. * This is not a public API.
  51. */
  52. static uint32_t LPSPI_CombineWriteData(uint8_t *txData, uint8_t bytesEachWrite, bool isByteSwap);
  53. /*!
  54. * @brief Separate the read data for 1 byte to 4 bytes.
  55. * This is not a public API.
  56. */
  57. static void LPSPI_SeparateReadData(uint8_t *rxData, uint32_t readData, uint8_t bytesEachRead, bool isByteSwap);
  58. /*!
  59. * @brief Wait for tx FIFO to be empty.
  60. * This is not a public API.
  61. * @param base LPSPI peripheral address.
  62. * @return true for the tx FIFO is ready, false is not.
  63. */
  64. static bool LPSPI_TxFifoReady(LPSPI_Type *base);
  65. /*!
  66. * @brief Master fill up the TX FIFO with data.
  67. * This is not a public API.
  68. */
  69. static void LPSPI_MasterTransferFillUpTxFifo(LPSPI_Type *base, lpspi_master_handle_t *handle);
  70. /*!
  71. * @brief Master finish up a transfer.
  72. * It would call back if there is callback function and set the state to idle.
  73. * This is not a public API.
  74. */
  75. static void LPSPI_MasterTransferComplete(LPSPI_Type *base, lpspi_master_handle_t *handle);
  76. /*!
  77. * @brief Slave fill up the TX FIFO with data.
  78. * This is not a public API.
  79. */
  80. static void LPSPI_SlaveTransferFillUpTxFifo(LPSPI_Type *base, lpspi_slave_handle_t *handle);
  81. /*!
  82. * @brief Slave finish up a transfer.
  83. * It would call back if there is callback function and set the state to idle.
  84. * This is not a public API.
  85. */
  86. static void LPSPI_SlaveTransferComplete(LPSPI_Type *base, lpspi_slave_handle_t *handle);
  87. /*!
  88. * @brief LPSPI common interrupt handler.
  89. *
  90. * @param handle pointer to s_lpspiHandle which stores the transfer state.
  91. */
  92. static void LPSPI_CommonIRQHandler(LPSPI_Type *base, void *param);
  93. /*******************************************************************************
  94. * Variables
  95. ******************************************************************************/
  96. /* Defines constant value arrays for the baud rate pre-scalar and scalar divider values.*/
  97. static const uint8_t s_baudratePrescaler[] = {1, 2, 4, 8, 16, 32, 64, 128};
  98. /*! @brief Pointers to lpspi bases for each instance. */
  99. static LPSPI_Type *const s_lpspiBases[] = LPSPI_BASE_PTRS;
  100. /*! @brief Pointers to lpspi IRQ number for each instance. */
  101. static const IRQn_Type s_lpspiIRQ[] = LPSPI_IRQS;
  102. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  103. /*! @brief Pointers to lpspi clocks for each instance. */
  104. static const clock_ip_name_t s_lpspiClocks[] = LPSPI_CLOCKS;
  105. #if defined(LPSPI_PERIPH_CLOCKS)
  106. static const clock_ip_name_t s_LpspiPeriphClocks[] = LPSPI_PERIPH_CLOCKS;
  107. #endif
  108. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  109. /*! @brief Pointers to lpspi handles for each instance. */
  110. static void *s_lpspiHandle[ARRAY_SIZE(s_lpspiBases)];
  111. /*! @brief Pointer to master IRQ handler for each instance. */
  112. static lpspi_master_isr_t s_lpspiMasterIsr;
  113. /*! @brief Pointer to slave IRQ handler for each instance. */
  114. static lpspi_slave_isr_t s_lpspiSlaveIsr;
  115. /* @brief Dummy data for each instance. This data is used when user's tx buffer is NULL*/
  116. volatile uint8_t g_lpspiDummyData[ARRAY_SIZE(s_lpspiBases)] = {0};
  117. /**********************************************************************************************************************
  118. * Code
  119. *********************************************************************************************************************/
  120. /*!
  121. * brief Get the LPSPI instance from peripheral base address.
  122. *
  123. * param base LPSPI peripheral base address.
  124. * return LPSPI instance.
  125. */
  126. uint32_t LPSPI_GetInstance(LPSPI_Type *base)
  127. {
  128. uint8_t instance = 0;
  129. /* Find the instance index from base address mappings. */
  130. for (instance = 0; instance < ARRAY_SIZE(s_lpspiBases); instance++)
  131. {
  132. if (s_lpspiBases[instance] == base)
  133. {
  134. break;
  135. }
  136. }
  137. assert(instance < ARRAY_SIZE(s_lpspiBases));
  138. return instance;
  139. }
  140. /*!
  141. * brief Set up the dummy data.
  142. *
  143. * param base LPSPI peripheral address.
  144. * param dummyData Data to be transferred when tx buffer is NULL.
  145. * Note:
  146. * This API has no effect when LPSPI in slave interrupt mode, because driver
  147. * will set the TXMSK bit to 1 if txData is NULL, no data is loaded from transmit
  148. * FIFO and output pin is tristated.
  149. */
  150. void LPSPI_SetDummyData(LPSPI_Type *base, uint8_t dummyData)
  151. {
  152. uint32_t instance = LPSPI_GetInstance(base);
  153. g_lpspiDummyData[instance] = dummyData;
  154. }
  155. /*!
  156. * brief Initializes the LPSPI master.
  157. *
  158. * param base LPSPI peripheral address.
  159. * param masterConfig Pointer to structure lpspi_master_config_t.
  160. * param srcClock_Hz Module source input clock in Hertz
  161. */
  162. void LPSPI_MasterInit(LPSPI_Type *base, const lpspi_master_config_t *masterConfig, uint32_t srcClock_Hz)
  163. {
  164. assert(masterConfig != NULL);
  165. uint32_t tcrPrescaleValue = 0;
  166. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  167. uint32_t instance = LPSPI_GetInstance(base);
  168. /* Enable LPSPI clock */
  169. (void)CLOCK_EnableClock(s_lpspiClocks[instance]);
  170. #if defined(LPSPI_PERIPH_CLOCKS)
  171. (void)CLOCK_EnableClock(s_LpspiPeriphClocks[instance]);
  172. #endif
  173. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  174. /* Set LPSPI to master */
  175. LPSPI_SetMasterSlaveMode(base, kLPSPI_Master);
  176. /* Set specific PCS to active high or low */
  177. LPSPI_SetOnePcsPolarity(base, masterConfig->whichPcs, masterConfig->pcsActiveHighOrLow);
  178. /* Set Configuration Register 1 related setting.*/
  179. base->CFGR1 = (base->CFGR1 & ~(LPSPI_CFGR1_OUTCFG_MASK | LPSPI_CFGR1_PINCFG_MASK | LPSPI_CFGR1_NOSTALL_MASK)) |
  180. LPSPI_CFGR1_OUTCFG(masterConfig->dataOutConfig) | LPSPI_CFGR1_PINCFG(masterConfig->pinCfg) |
  181. LPSPI_CFGR1_NOSTALL(0);
  182. /* Set baudrate and delay times*/
  183. (void)LPSPI_MasterSetBaudRate(base, masterConfig->baudRate, srcClock_Hz, &tcrPrescaleValue);
  184. /* Set default watermarks */
  185. LPSPI_SetFifoWatermarks(base, (uint32_t)kLpspiDefaultTxWatermark, (uint32_t)kLpspiDefaultRxWatermark);
  186. /* Set Transmit Command Register*/
  187. base->TCR = LPSPI_TCR_CPOL(masterConfig->cpol) | LPSPI_TCR_CPHA(masterConfig->cpha) |
  188. LPSPI_TCR_LSBF(masterConfig->direction) | LPSPI_TCR_FRAMESZ(masterConfig->bitsPerFrame - 1U) |
  189. LPSPI_TCR_PRESCALE(tcrPrescaleValue) | LPSPI_TCR_PCS(masterConfig->whichPcs);
  190. LPSPI_Enable(base, true);
  191. (void)LPSPI_MasterSetDelayTimes(base, masterConfig->pcsToSckDelayInNanoSec, kLPSPI_PcsToSck, srcClock_Hz);
  192. (void)LPSPI_MasterSetDelayTimes(base, masterConfig->lastSckToPcsDelayInNanoSec, kLPSPI_LastSckToPcs, srcClock_Hz);
  193. (void)LPSPI_MasterSetDelayTimes(base, masterConfig->betweenTransferDelayInNanoSec, kLPSPI_BetweenTransfer,
  194. srcClock_Hz);
  195. LPSPI_SetDummyData(base, LPSPI_DUMMY_DATA);
  196. }
  197. /*!
  198. * brief Sets the lpspi_master_config_t structure to default values.
  199. *
  200. * This API initializes the configuration structure for LPSPI_MasterInit().
  201. * The initialized structure can remain unchanged in LPSPI_MasterInit(), or can be modified
  202. * before calling the LPSPI_MasterInit().
  203. * Example:
  204. * code
  205. * lpspi_master_config_t masterConfig;
  206. * LPSPI_MasterGetDefaultConfig(&masterConfig);
  207. * endcode
  208. * param masterConfig pointer to lpspi_master_config_t structure
  209. */
  210. void LPSPI_MasterGetDefaultConfig(lpspi_master_config_t *masterConfig)
  211. {
  212. assert(masterConfig != NULL);
  213. /* Initializes the configure structure to zero. */
  214. (void)memset(masterConfig, 0, sizeof(*masterConfig));
  215. masterConfig->baudRate = 500000;
  216. masterConfig->bitsPerFrame = 8;
  217. masterConfig->cpol = kLPSPI_ClockPolarityActiveHigh;
  218. masterConfig->cpha = kLPSPI_ClockPhaseFirstEdge;
  219. masterConfig->direction = kLPSPI_MsbFirst;
  220. masterConfig->pcsToSckDelayInNanoSec = 1000000000U / masterConfig->baudRate * 2U;
  221. masterConfig->lastSckToPcsDelayInNanoSec = 1000000000U / masterConfig->baudRate * 2U;
  222. masterConfig->betweenTransferDelayInNanoSec = 1000000000U / masterConfig->baudRate * 2U;
  223. masterConfig->whichPcs = kLPSPI_Pcs0;
  224. masterConfig->pcsActiveHighOrLow = kLPSPI_PcsActiveLow;
  225. masterConfig->pinCfg = kLPSPI_SdiInSdoOut;
  226. masterConfig->dataOutConfig = kLpspiDataOutRetained;
  227. }
  228. /*!
  229. * brief LPSPI slave configuration.
  230. *
  231. * param base LPSPI peripheral address.
  232. * param slaveConfig Pointer to a structure lpspi_slave_config_t.
  233. */
  234. void LPSPI_SlaveInit(LPSPI_Type *base, const lpspi_slave_config_t *slaveConfig)
  235. {
  236. assert(slaveConfig != NULL);
  237. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  238. uint32_t instance = LPSPI_GetInstance(base);
  239. /* Enable LPSPI clock */
  240. (void)CLOCK_EnableClock(s_lpspiClocks[instance]);
  241. #if defined(LPSPI_PERIPH_CLOCKS)
  242. (void)CLOCK_EnableClock(s_LpspiPeriphClocks[instance]);
  243. #endif
  244. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  245. LPSPI_SetMasterSlaveMode(base, kLPSPI_Slave);
  246. LPSPI_SetOnePcsPolarity(base, slaveConfig->whichPcs, slaveConfig->pcsActiveHighOrLow);
  247. base->CFGR1 = (base->CFGR1 & ~(LPSPI_CFGR1_OUTCFG_MASK | LPSPI_CFGR1_PINCFG_MASK)) |
  248. LPSPI_CFGR1_OUTCFG(slaveConfig->dataOutConfig) | LPSPI_CFGR1_PINCFG(slaveConfig->pinCfg);
  249. LPSPI_SetFifoWatermarks(base, (uint32_t)kLpspiDefaultTxWatermark, (uint32_t)kLpspiDefaultRxWatermark);
  250. base->TCR = LPSPI_TCR_CPOL(slaveConfig->cpol) | LPSPI_TCR_CPHA(slaveConfig->cpha) |
  251. LPSPI_TCR_LSBF(slaveConfig->direction) | LPSPI_TCR_FRAMESZ(slaveConfig->bitsPerFrame - 1U);
  252. /* This operation will set the dummy data for edma transfer, no effect in interrupt way. */
  253. LPSPI_SetDummyData(base, LPSPI_DUMMY_DATA);
  254. LPSPI_Enable(base, true);
  255. }
  256. /*!
  257. * brief Sets the lpspi_slave_config_t structure to default values.
  258. *
  259. * This API initializes the configuration structure for LPSPI_SlaveInit().
  260. * The initialized structure can remain unchanged in LPSPI_SlaveInit() or can be modified
  261. * before calling the LPSPI_SlaveInit().
  262. * Example:
  263. * code
  264. * lpspi_slave_config_t slaveConfig;
  265. * LPSPI_SlaveGetDefaultConfig(&slaveConfig);
  266. * endcode
  267. * param slaveConfig pointer to lpspi_slave_config_t structure.
  268. */
  269. void LPSPI_SlaveGetDefaultConfig(lpspi_slave_config_t *slaveConfig)
  270. {
  271. assert(slaveConfig != NULL);
  272. /* Initializes the configure structure to zero. */
  273. (void)memset(slaveConfig, 0, sizeof(*slaveConfig));
  274. slaveConfig->bitsPerFrame = 8; /*!< Bits per frame, minimum 8, maximum 4096.*/
  275. slaveConfig->cpol = kLPSPI_ClockPolarityActiveHigh; /*!< Clock polarity. */
  276. slaveConfig->cpha = kLPSPI_ClockPhaseFirstEdge; /*!< Clock phase. */
  277. slaveConfig->direction = kLPSPI_MsbFirst; /*!< MSB or LSB data shift direction. */
  278. slaveConfig->whichPcs = kLPSPI_Pcs0; /*!< Desired Peripheral Chip Select (pcs) */
  279. slaveConfig->pcsActiveHighOrLow = kLPSPI_PcsActiveLow; /*!< Desired PCS active high or low */
  280. slaveConfig->pinCfg = kLPSPI_SdiInSdoOut;
  281. slaveConfig->dataOutConfig = kLpspiDataOutRetained;
  282. }
  283. /*!
  284. * brief Restores the LPSPI peripheral to reset state. Note that this function
  285. * sets all registers to reset state. As a result, the LPSPI module can't work after calling
  286. * this API.
  287. * param base LPSPI peripheral address.
  288. */
  289. void LPSPI_Reset(LPSPI_Type *base)
  290. {
  291. /* Reset all internal logic and registers, except the Control Register. Remains set until cleared by software.*/
  292. base->CR |= LPSPI_CR_RST_MASK;
  293. /* Software reset doesn't reset the CR, so manual reset the FIFOs */
  294. base->CR |= LPSPI_CR_RRF_MASK | LPSPI_CR_RTF_MASK;
  295. /* Master logic is not reset and module is disabled.*/
  296. base->CR = 0x00U;
  297. }
  298. /*!
  299. * brief De-initializes the LPSPI peripheral. Call this API to disable the LPSPI clock.
  300. * param base LPSPI peripheral address.
  301. */
  302. void LPSPI_Deinit(LPSPI_Type *base)
  303. {
  304. /* Reset to default value */
  305. LPSPI_Reset(base);
  306. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  307. uint32_t instance = LPSPI_GetInstance(base);
  308. /* Enable LPSPI clock */
  309. (void)CLOCK_DisableClock(s_lpspiClocks[instance]);
  310. #if defined(LPSPI_PERIPH_CLOCKS)
  311. (void)CLOCK_DisableClock(s_LpspiPeriphClocks[instance]);
  312. #endif
  313. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  314. }
  315. static void LPSPI_SetOnePcsPolarity(LPSPI_Type *base,
  316. lpspi_which_pcs_t pcs,
  317. lpspi_pcs_polarity_config_t activeLowOrHigh)
  318. {
  319. uint32_t cfgr1Value = 0;
  320. /* Clear the PCS polarity bit */
  321. cfgr1Value = base->CFGR1 & ~(1UL << (LPSPI_CFGR1_PCSPOL_SHIFT + (uint32_t)pcs));
  322. /* Configure the PCS polarity bit according to the activeLowOrHigh setting */
  323. base->CFGR1 = cfgr1Value | ((uint32_t)activeLowOrHigh << (LPSPI_CFGR1_PCSPOL_SHIFT + (uint32_t)pcs));
  324. }
  325. /*!
  326. * brief Sets the LPSPI baud rate in bits per second.
  327. *
  328. * This function takes in the desired bitsPerSec (baud rate) and calculates the nearest
  329. * possible baud rate without exceeding the desired baud rate and returns the
  330. * calculated baud rate in bits-per-second. It requires the caller to provide
  331. * the frequency of the module source clock (in Hertz). Note that the baud rate
  332. * does not go into effect until the Transmit Control Register (TCR) is programmed
  333. * with the prescale value. Hence, this function returns the prescale tcrPrescaleValue
  334. * parameter for later programming in the TCR. The higher level
  335. * peripheral driver should alert the user of an out of range baud rate input.
  336. *
  337. * Note that the LPSPI module must first be disabled before configuring this.
  338. * Note that the LPSPI module must be configured for master mode before configuring this.
  339. *
  340. * param base LPSPI peripheral address.
  341. * param baudRate_Bps The desired baud rate in bits per second.
  342. * param srcClock_Hz Module source input clock in Hertz.
  343. * param tcrPrescaleValue The TCR prescale value needed to program the TCR.
  344. * return The actual calculated baud rate. This function may also return a "0" if the
  345. * LPSPI is not configured for master mode or if the LPSPI module is not disabled.
  346. */
  347. uint32_t LPSPI_MasterSetBaudRate(LPSPI_Type *base,
  348. uint32_t baudRate_Bps,
  349. uint32_t srcClock_Hz,
  350. uint32_t *tcrPrescaleValue)
  351. {
  352. assert(tcrPrescaleValue != NULL);
  353. /* For master mode configuration only, if slave mode detected, return 0.
  354. * Also, the LPSPI module needs to be disabled first, if enabled, return 0
  355. */
  356. if ((!LPSPI_IsMaster(base)) || ((base->CR & LPSPI_CR_MEN_MASK) != 0U))
  357. {
  358. return 0U;
  359. }
  360. uint32_t prescaler, bestPrescaler;
  361. uint32_t scaler, bestScaler;
  362. uint32_t realBaudrate, bestBaudrate;
  363. uint32_t diff, min_diff;
  364. uint32_t desiredBaudrate = baudRate_Bps;
  365. /* find combination of prescaler and scaler resulting in baudrate closest to the
  366. * requested value
  367. */
  368. min_diff = 0xFFFFFFFFU;
  369. /* Set to maximum divisor value bit settings so that if baud rate passed in is less
  370. * than the minimum possible baud rate, then the SPI will be configured to the lowest
  371. * possible baud rate
  372. */
  373. bestPrescaler = 7;
  374. bestScaler = 255;
  375. bestBaudrate = 0; /* required to avoid compilation warning */
  376. /* In all for loops, if min_diff = 0, the exit for loop*/
  377. for (prescaler = 0U; prescaler < 8U; prescaler++)
  378. {
  379. if (min_diff == 0U)
  380. {
  381. break;
  382. }
  383. for (scaler = 0U; scaler < 256U; scaler++)
  384. {
  385. if (min_diff == 0U)
  386. {
  387. break;
  388. }
  389. realBaudrate = (srcClock_Hz / (s_baudratePrescaler[prescaler] * (scaler + 2U)));
  390. /* calculate the baud rate difference based on the conditional statement
  391. * that states that the calculated baud rate must not exceed the desired baud rate
  392. */
  393. if (desiredBaudrate >= realBaudrate)
  394. {
  395. diff = desiredBaudrate - realBaudrate;
  396. if (min_diff > diff)
  397. {
  398. /* a better match found */
  399. min_diff = diff;
  400. bestPrescaler = prescaler;
  401. bestScaler = scaler;
  402. bestBaudrate = realBaudrate;
  403. }
  404. }
  405. }
  406. }
  407. /* Write the best baud rate scalar to the CCR.
  408. * Note, no need to check for error since we've already checked to make sure the module is
  409. * disabled and in master mode. Also, there is a limit on the maximum divider so we will not
  410. * exceed this.
  411. */
  412. #if defined(FSL_FEATURE_LPSPI_HAS_CCR1) && FSL_FEATURE_LPSPI_HAS_CCR1
  413. /* When CCR1 is present, the CCR[DBT] and CCR[SCKDIV] is write only, all read will return 0
  414. The real DBT and SCKDIV can be obtained in CCR1, CCR[DBT]=CCR1[SCKSCK] and CCR[SCKDIV]=CCR1[SCKHLD]+CCR1[SCKSET]
  415. So when changing either CCR[DBT] or CCR[SCKDIV] make sure the other value is not overwritten by 0 */
  416. base->CCR = base->CCR | LPSPI_CCR_DBT((base->CCR1 & LPSPI_CCR1_SCKSCK_MASK) >> LPSPI_CCR1_SCKSCK_SHIFT) |
  417. LPSPI_CCR_SCKDIV(bestScaler);
  418. #else
  419. base->CCR = (base->CCR & ~LPSPI_CCR_SCKDIV_MASK) | LPSPI_CCR_SCKDIV(bestScaler);
  420. #endif /* FSL_FEATURE_LPSPI_HAS_CCR1 */
  421. /* return the best prescaler value for user to use later */
  422. *tcrPrescaleValue = bestPrescaler;
  423. /* return the actual calculated baud rate */
  424. return bestBaudrate;
  425. }
  426. /*!
  427. * brief Manually configures a specific LPSPI delay parameter (module must be disabled to
  428. * change the delay values).
  429. *
  430. * This function configures the following:
  431. * SCK to PCS delay, or
  432. * PCS to SCK delay, or
  433. * The configurations must occur between the transfer delay.
  434. *
  435. * The delay names are available in type lpspi_delay_type_t.
  436. *
  437. * The user passes the desired delay along with the delay value.
  438. * This allows the user to directly set the delay values if they have
  439. * pre-calculated them or if they simply wish to manually increment the value.
  440. *
  441. * Note that the LPSPI module must first be disabled before configuring this.
  442. * Note that the LPSPI module must be configured for master mode before configuring this.
  443. *
  444. * param base LPSPI peripheral address.
  445. * param scaler The 8-bit delay value 0x00 to 0xFF (255).
  446. * param whichDelay The desired delay to configure, must be of type lpspi_delay_type_t.
  447. */
  448. void LPSPI_MasterSetDelayScaler(LPSPI_Type *base, uint32_t scaler, lpspi_delay_type_t whichDelay)
  449. {
  450. /*These settings are only relevant in master mode */
  451. #if defined(FSL_FEATURE_LPSPI_HAS_CCR1) && FSL_FEATURE_LPSPI_HAS_CCR1
  452. /* When CCR1 is present, the CCR[DBT] and CCR[SCKDIV] is write only, all read will return 0
  453. The real DBT and SCKDIV can be obtained in CCR1, CCR[DBT]=CCR1[SCKSCK] and CCR[SCKDIV]=CCR1[SCKHLD]+CCR1[SCKSET]
  454. So when changing either CCR[DBT] or CCR[SCKDIV] make sure the other value is not overwritten by 0 */
  455. uint32_t dbt = (base->CCR1 & LPSPI_CCR1_SCKSCK_MASK) >> LPSPI_CCR1_SCKSCK_SHIFT;
  456. uint32_t sckdiv = (base->CCR1 & LPSPI_CCR1_SCKHLD_MASK) >> LPSPI_CCR1_SCKHLD_SHIFT;
  457. sckdiv += (base->CCR1 & LPSPI_CCR1_SCKSET_MASK) >> LPSPI_CCR1_SCKSET_SHIFT;
  458. switch (whichDelay)
  459. {
  460. case kLPSPI_PcsToSck:
  461. base->CCR = (base->CCR & (~LPSPI_CCR_PCSSCK_MASK)) | LPSPI_CCR_PCSSCK(scaler) | LPSPI_CCR_DBT(dbt) |
  462. LPSPI_CCR_SCKDIV(sckdiv);
  463. break;
  464. case kLPSPI_LastSckToPcs:
  465. base->CCR = (base->CCR & (~LPSPI_CCR_SCKPCS_MASK)) | LPSPI_CCR_SCKPCS(scaler) | LPSPI_CCR_DBT(dbt) |
  466. LPSPI_CCR_SCKDIV(sckdiv);
  467. break;
  468. case kLPSPI_BetweenTransfer:
  469. base->CCR = base->CCR | LPSPI_CCR_DBT(scaler) | LPSPI_CCR_SCKDIV(sckdiv);
  470. #else
  471. switch (whichDelay)
  472. {
  473. case kLPSPI_PcsToSck:
  474. base->CCR = (base->CCR & (~LPSPI_CCR_PCSSCK_MASK)) | LPSPI_CCR_PCSSCK(scaler);
  475. break;
  476. case kLPSPI_LastSckToPcs:
  477. base->CCR = (base->CCR & (~LPSPI_CCR_SCKPCS_MASK)) | LPSPI_CCR_SCKPCS(scaler);
  478. break;
  479. case kLPSPI_BetweenTransfer:
  480. base->CCR = (base->CCR & (~LPSPI_CCR_DBT_MASK)) | LPSPI_CCR_DBT(scaler);
  481. #endif /* FSL_FEATURE_LPSPI_HAS_CCR1 */
  482. break;
  483. default:
  484. assert(false);
  485. break;
  486. }
  487. }
  488. /*!
  489. * brief Calculates the delay based on the desired delay input in nanoseconds (module must be
  490. * disabled to change the delay values).
  491. *
  492. * This function calculates the values for the following:
  493. * SCK to PCS delay, or
  494. * PCS to SCK delay, or
  495. * The configurations must occur between the transfer delay.
  496. *
  497. * The delay names are available in type lpspi_delay_type_t.
  498. *
  499. * The user passes the desired delay and the desired delay value in
  500. * nano-seconds. The function calculates the value needed for the desired delay parameter
  501. * and returns the actual calculated delay because an exact delay match may not be possible. In this
  502. * case, the closest match is calculated without going below the desired delay value input.
  503. * It is possible to input a very large delay value that exceeds the capability of the part, in
  504. * which case the maximum supported delay is returned. It is up to the higher level
  505. * peripheral driver to alert the user of an out of range delay input.
  506. *
  507. * Note that the LPSPI module must be configured for master mode before configuring this. And note that
  508. * the delayTime = LPSPI_clockSource / (PRESCALE * Delay_scaler).
  509. *
  510. * param base LPSPI peripheral address.
  511. * param delayTimeInNanoSec The desired delay value in nano-seconds.
  512. * param whichDelay The desired delay to configuration, which must be of type lpspi_delay_type_t.
  513. * param srcClock_Hz Module source input clock in Hertz.
  514. * return actual Calculated delay value in nano-seconds.
  515. */
  516. uint32_t LPSPI_MasterSetDelayTimes(LPSPI_Type *base,
  517. uint32_t delayTimeInNanoSec,
  518. lpspi_delay_type_t whichDelay,
  519. uint32_t srcClock_Hz)
  520. {
  521. uint64_t realDelay, bestDelay;
  522. uint32_t scaler, bestScaler;
  523. uint32_t diff, min_diff;
  524. uint64_t initialDelayNanoSec;
  525. uint32_t clockDividedPrescaler;
  526. /* For delay between transfer, an additional scaler value is needed */
  527. uint32_t additionalScaler = 0;
  528. /*As the RM note, the LPSPI baud rate clock is itself divided by the PRESCALE setting, which can vary between
  529. * transfers.*/
  530. clockDividedPrescaler =
  531. srcClock_Hz / s_baudratePrescaler[(base->TCR & LPSPI_TCR_PRESCALE_MASK) >> LPSPI_TCR_PRESCALE_SHIFT];
  532. /* Find combination of prescaler and scaler resulting in the delay closest to the requested value.*/
  533. min_diff = 0xFFFFFFFFU;
  534. /* Initialize scaler to max value to generate the max delay */
  535. bestScaler = 0xFFU;
  536. /* Calculate the initial (min) delay and maximum possible delay based on the specific delay as
  537. * the delay divisors are slightly different based on which delay we are configuring.
  538. */
  539. if (whichDelay == kLPSPI_BetweenTransfer)
  540. {
  541. /* First calculate the initial, default delay, note min delay is 2 clock cycles. Due to large size of
  542. calculated values (uint64_t), we need to break up the calculation into several steps to ensure
  543. accurate calculated results
  544. */
  545. initialDelayNanoSec = 1000000000U;
  546. initialDelayNanoSec *= 2U;
  547. initialDelayNanoSec /= clockDividedPrescaler;
  548. /* Calculate the maximum delay */
  549. bestDelay = 1000000000U;
  550. bestDelay *= 257U; /* based on DBT+2, or 255 + 2 */
  551. bestDelay /= clockDividedPrescaler;
  552. additionalScaler = 1U;
  553. }
  554. else
  555. {
  556. /* First calculate the initial, default delay, min delay is 1 clock cycle. Due to large size of calculated
  557. values (uint64_t), we need to break up the calculation into several steps to ensure accurate calculated
  558. results.
  559. */
  560. initialDelayNanoSec = 1000000000U;
  561. initialDelayNanoSec /= clockDividedPrescaler;
  562. /* Calculate the maximum delay */
  563. bestDelay = 1000000000U;
  564. bestDelay *= 256U; /* based on SCKPCS+1 or PCSSCK+1, or 255 + 1 */
  565. bestDelay /= clockDividedPrescaler;
  566. additionalScaler = 0U;
  567. }
  568. /* If the initial, default delay is already greater than the desired delay, then
  569. * set the delay to their initial value (0) and return the delay. In other words,
  570. * there is no way to decrease the delay value further.
  571. */
  572. if (initialDelayNanoSec >= delayTimeInNanoSec)
  573. {
  574. LPSPI_MasterSetDelayScaler(base, 0, whichDelay);
  575. return (uint32_t)initialDelayNanoSec;
  576. }
  577. /* If min_diff = 0, the exit for loop */
  578. for (scaler = 0U; scaler < 256U; scaler++)
  579. {
  580. if (min_diff == 0U)
  581. {
  582. break;
  583. }
  584. /* Calculate the real delay value as we cycle through the scaler values.
  585. Due to large size of calculated values (uint64_t), we need to break up the
  586. calculation into several steps to ensure accurate calculated results
  587. */
  588. realDelay = 1000000000U;
  589. realDelay *= ((uint64_t)scaler + 1UL + (uint64_t)additionalScaler);
  590. realDelay /= clockDividedPrescaler;
  591. /* calculate the delay difference based on the conditional statement
  592. * that states that the calculated delay must not be less then the desired delay
  593. */
  594. if (realDelay >= delayTimeInNanoSec)
  595. {
  596. diff = (uint32_t)(realDelay - (uint64_t)delayTimeInNanoSec);
  597. if (min_diff > diff)
  598. {
  599. /* a better match found */
  600. min_diff = diff;
  601. bestScaler = scaler;
  602. bestDelay = realDelay;
  603. }
  604. }
  605. }
  606. /* write the best scaler value for the delay */
  607. LPSPI_MasterSetDelayScaler(base, bestScaler, whichDelay);
  608. /* return the actual calculated delay value (in ns) */
  609. return (uint32_t)bestDelay;
  610. }
  611. /*Transactional APIs -- Master*/
  612. /*!
  613. * brief Initializes the LPSPI master handle.
  614. *
  615. * This function initializes the LPSPI handle, which can be used for other LPSPI transactional APIs. Usually, for a
  616. * specified LPSPI instance, call this API once to get the initialized handle.
  617. * param base LPSPI peripheral address.
  618. * param handle LPSPI handle pointer to lpspi_master_handle_t.
  619. * param callback DSPI callback.
  620. * param userData callback function parameter.
  621. */
  622. void LPSPI_MasterTransferCreateHandle(LPSPI_Type *base,
  623. lpspi_master_handle_t *handle,
  624. lpspi_master_transfer_callback_t callback,
  625. void *userData)
  626. {
  627. assert(handle != NULL);
  628. /* Zero the handle. */
  629. (void)memset(handle, 0, sizeof(*handle));
  630. s_lpspiHandle[LPSPI_GetInstance(base)] = handle;
  631. /* Set irq handler. */
  632. s_lpspiMasterIsr = LPSPI_MasterTransferHandleIRQ;
  633. handle->callback = callback;
  634. handle->userData = userData;
  635. }
  636. /*!
  637. * brief Check the argument for transfer .
  638. *
  639. * param base LPSPI peripheral address.
  640. * param transfer the transfer struct to be used.
  641. * param isEdma True to check for EDMA transfer, false to check interrupt non-blocking transfer
  642. * return Return true for right and false for wrong.
  643. */
  644. bool LPSPI_CheckTransferArgument(LPSPI_Type *base, lpspi_transfer_t *transfer, bool isEdma)
  645. {
  646. assert(transfer != NULL);
  647. uint32_t bitsPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) + 1U;
  648. uint32_t bytesPerFrame = (bitsPerFrame + 7U) / 8U;
  649. uint32_t temp = (base->CFGR1 & LPSPI_CFGR1_PINCFG_MASK);
  650. /* If the transfer count is zero, then return immediately.*/
  651. if (transfer->dataSize == 0U)
  652. {
  653. return false;
  654. }
  655. /* If both send buffer and receive buffer is null */
  656. if ((NULL == (transfer->txData)) && (NULL == (transfer->rxData)))
  657. {
  658. return false;
  659. }
  660. /*The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4 .
  661. *For bytesPerFrame greater than 4 situation:
  662. *the transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not integer multiples of 4 ,
  663. *otherwise , the transfer data size can be integer multiples of bytesPerFrame.
  664. */
  665. if (bytesPerFrame <= 4U)
  666. {
  667. if ((transfer->dataSize % bytesPerFrame) != 0U)
  668. {
  669. return false;
  670. }
  671. }
  672. else
  673. {
  674. if ((bytesPerFrame % 4U) != 0U)
  675. {
  676. if (transfer->dataSize != bytesPerFrame)
  677. {
  678. return false;
  679. }
  680. }
  681. else
  682. {
  683. if ((transfer->dataSize % bytesPerFrame) != 0U)
  684. {
  685. return false;
  686. }
  687. }
  688. }
  689. /* Check if using 3-wire mode and the txData is NULL, set the output pin to tristated. */
  690. if ((temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdiInSdiOut)) || (temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdoInSdoOut)))
  691. {
  692. /* The 3-wire mode can't send and receive data at the same time. */
  693. if ((transfer->txData != NULL) && (transfer->rxData != NULL))
  694. {
  695. return false;
  696. }
  697. if (NULL == transfer->txData)
  698. {
  699. base->CFGR1 |= LPSPI_CFGR1_OUTCFG_MASK;
  700. }
  701. }
  702. if (isEdma && ((bytesPerFrame % 4U) == 3U))
  703. {
  704. return false;
  705. }
  706. return true;
  707. }
  708. /*!
  709. * brief LPSPI master transfer data using a polling method.
  710. *
  711. * This function transfers data using a polling method. This is a blocking function, which does not return until all
  712. * transfers have been completed.
  713. *
  714. * Note:
  715. * The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4.
  716. * For bytesPerFrame greater than 4:
  717. * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not integer multiples of 4.
  718. * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
  719. *
  720. * param base LPSPI peripheral address.
  721. * param transfer pointer to lpspi_transfer_t structure.
  722. * return status of status_t.
  723. */
  724. status_t LPSPI_MasterTransferBlocking(LPSPI_Type *base, lpspi_transfer_t *transfer)
  725. {
  726. assert(transfer != NULL);
  727. /* Check that LPSPI is not busy.*/
  728. if ((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_ModuleBusyFlag) != 0U)
  729. {
  730. return kStatus_LPSPI_Busy;
  731. }
  732. LPSPI_Enable(base, false);
  733. /* Check arguements */
  734. if (!LPSPI_CheckTransferArgument(base, transfer, false))
  735. {
  736. return kStatus_InvalidArgument;
  737. }
  738. LPSPI_FlushFifo(base, true, true);
  739. LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_AllStatusFlag);
  740. /* Variables */
  741. bool isTxMask = false;
  742. bool isByteSwap = ((transfer->configFlags & (uint32_t)kLPSPI_MasterByteSwap) != 0U);
  743. uint8_t bytesEachWrite;
  744. uint8_t bytesEachRead;
  745. uint8_t *txData = transfer->txData;
  746. uint8_t *rxData = transfer->rxData;
  747. uint8_t dummyData = g_lpspiDummyData[LPSPI_GetInstance(base)];
  748. uint32_t readData = 0U;
  749. uint32_t txRemainingByteCount = transfer->dataSize;
  750. uint32_t rxRemainingByteCount = transfer->dataSize;
  751. uint32_t wordToSend =
  752. ((uint32_t)dummyData) | ((uint32_t)dummyData << 8) | ((uint32_t)dummyData << 16) | ((uint32_t)dummyData << 24);
  753. /*The TX and RX FIFO sizes are always the same*/
  754. uint32_t fifoSize = LPSPI_GetRxFifoSize(base);
  755. uint32_t bytesPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) / 8U + 1U;
  756. /* No need to configure PCS continous if the transfer byte count is smaller than frame size */
  757. bool isPcsContinuous = (((transfer->configFlags & (uint32_t)kLPSPI_MasterPcsContinuous) != 0U) &&
  758. (bytesPerFrame < transfer->dataSize));
  759. uint32_t rxFifoMaxBytes = MIN(bytesPerFrame, 4U) * fifoSize;
  760. uint32_t whichPcs = (transfer->configFlags & LPSPI_MASTER_PCS_MASK) >> LPSPI_MASTER_PCS_SHIFT;
  761. uint32_t temp = (base->CFGR1 & LPSPI_CFGR1_PINCFG_MASK);
  762. #if SPI_RETRY_TIMES
  763. uint32_t waitTimes;
  764. #endif
  765. /* Mask tx data in half duplex mode */
  766. if (((temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdiInSdiOut)) || (temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdoInSdoOut))) &&
  767. (txData == NULL))
  768. {
  769. isTxMask = true;
  770. }
  771. base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
  772. LPSPI_Enable(base, true);
  773. /* Configure transfer control register. */
  774. base->TCR = (base->TCR & ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK |
  775. LPSPI_TCR_TXMSK_MASK | LPSPI_TCR_PCS_MASK)) |
  776. LPSPI_TCR_PCS(whichPcs);
  777. /*TCR is also shared the FIFO, so wait for TCR written.*/
  778. if (!LPSPI_TxFifoReady(base))
  779. {
  780. return kStatus_LPSPI_Timeout;
  781. }
  782. /* PCS should be configured separately from the other bits, otherwise it will not take effect. */
  783. base->TCR |= LPSPI_TCR_CONT(isPcsContinuous) | LPSPI_TCR_CONTC(isPcsContinuous) | LPSPI_TCR_RXMSK(NULL == rxData);
  784. /*TCR is also shared the FIFO, so wait for TCR written.*/
  785. if (!LPSPI_TxFifoReady(base))
  786. {
  787. return kStatus_LPSPI_Timeout;
  788. }
  789. if (bytesPerFrame <= 4U)
  790. {
  791. bytesEachWrite = (uint8_t)bytesPerFrame;
  792. bytesEachRead = (uint8_t)bytesPerFrame;
  793. }
  794. else
  795. {
  796. bytesEachWrite = 4U;
  797. bytesEachRead = 4U;
  798. }
  799. /*Write the TX data until txRemainingByteCount is equal to 0 */
  800. while (txRemainingByteCount > 0U)
  801. {
  802. if (txRemainingByteCount < bytesEachWrite)
  803. {
  804. bytesEachWrite = (uint8_t)txRemainingByteCount;
  805. }
  806. /*Wait until TX FIFO is not full*/
  807. #if SPI_RETRY_TIMES
  808. waitTimes = SPI_RETRY_TIMES;
  809. while ((LPSPI_GetTxFifoCount(base) == fifoSize) && (--waitTimes != 0U))
  810. #else
  811. while (LPSPI_GetTxFifoCount(base) == fifoSize)
  812. #endif
  813. {
  814. }
  815. #if SPI_RETRY_TIMES
  816. if (waitTimes == 0U)
  817. {
  818. return kStatus_LPSPI_Timeout;
  819. }
  820. #endif
  821. /* To prevent rxfifo overflow, ensure transmitting and receiving are executed in parallel */
  822. if (((NULL == rxData) || (rxRemainingByteCount - txRemainingByteCount) < rxFifoMaxBytes))
  823. {
  824. if (isTxMask)
  825. {
  826. /* When TCR[TXMSK]=1, transfer is initiate by writting a new command word to TCR. TCR[TXMSK] is cleared
  827. by hardware every time when TCR[FRAMESZ] bit of data is transfered.
  828. In this case TCR[TXMSK] should be set to initiate each transfer. */
  829. base->TCR |= LPSPI_TCR_TXMSK_MASK;
  830. if (isPcsContinuous && (txRemainingByteCount == bytesPerFrame))
  831. {
  832. /* For the last piece of frame size of data, if is PCS continous mode(TCR[CONT]), TCR[CONTC] should
  833. * be cleared to de-assert the PCS. Be sure to clear the TXMSK as well otherwise another FRAMESZ
  834. * of data will be received. */
  835. base->TCR &= ~(LPSPI_TCR_CONTC_MASK | LPSPI_TCR_CONT_MASK | LPSPI_TCR_TXMSK_MASK);
  836. }
  837. txRemainingByteCount -= bytesPerFrame;
  838. }
  839. else
  840. {
  841. if (txData != NULL)
  842. {
  843. wordToSend = LPSPI_CombineWriteData(txData, bytesEachWrite, isByteSwap);
  844. txData += bytesEachWrite;
  845. }
  846. /* Otherwise push data to tx FIFO to initiate transfer */
  847. LPSPI_WriteData(base, wordToSend);
  848. txRemainingByteCount -= bytesEachWrite;
  849. }
  850. }
  851. /* Check whether there is RX data in RX FIFO . Read out the RX data so that the RX FIFO would not overrun. */
  852. if ((rxData != NULL) && (rxRemainingByteCount != 0U))
  853. {
  854. /* To ensure parallel execution in 3-wire mode, after writting 1 to TXMSK to generate clock of
  855. bytesPerFrame's data wait until bytesPerFrame's data is received. */
  856. while (isTxMask && (LPSPI_GetRxFifoCount(base) == 0U))
  857. {
  858. }
  859. #if SPI_RETRY_TIMES
  860. waitTimes = SPI_RETRY_TIMES;
  861. while ((LPSPI_GetRxFifoCount(base) != 0U) && (--waitTimes != 0U))
  862. #else
  863. while (LPSPI_GetRxFifoCount(base) != 0U)
  864. #endif
  865. {
  866. readData = LPSPI_ReadData(base);
  867. if (rxRemainingByteCount < bytesEachRead)
  868. {
  869. bytesEachRead = (uint8_t)rxRemainingByteCount;
  870. }
  871. LPSPI_SeparateReadData(rxData, readData, bytesEachRead, isByteSwap);
  872. rxData += bytesEachRead;
  873. rxRemainingByteCount -= bytesEachRead;
  874. }
  875. #if SPI_RETRY_TIMES
  876. if (waitTimes == 0U)
  877. {
  878. return kStatus_LPSPI_Timeout;
  879. }
  880. #endif
  881. }
  882. }
  883. if (isPcsContinuous && !isTxMask)
  884. {
  885. /* In PCS continous mode(TCR[CONT]), after write all the data in TX FIFO, TCR[CONTC] and TCR[CONT] should be
  886. cleared to de-assert the PCS. Note that TCR register also use the TX FIFO. Also CONTC should be cleared when
  887. tx is not masked, otherwise written to TCR register with TXMSK bit wet will initiate a new transfer. */
  888. #if SPI_RETRY_TIMES
  889. waitTimes = SPI_RETRY_TIMES;
  890. while ((LPSPI_GetTxFifoCount(base) == fifoSize) && (--waitTimes != 0U))
  891. #else
  892. while (LPSPI_GetTxFifoCount(base) == fifoSize)
  893. #endif
  894. {
  895. }
  896. #if SPI_RETRY_TIMES
  897. if (waitTimes == 0U)
  898. {
  899. return kStatus_LPSPI_Timeout;
  900. }
  901. #endif
  902. base->TCR = (base->TCR & ~(LPSPI_TCR_CONTC_MASK | LPSPI_TCR_CONT_MASK));
  903. }
  904. /*Read out the RX data in FIFO*/
  905. if (rxData != NULL)
  906. {
  907. while (rxRemainingByteCount > 0U)
  908. {
  909. #if SPI_RETRY_TIMES
  910. waitTimes = SPI_RETRY_TIMES;
  911. while ((LPSPI_GetRxFifoCount(base) != 0U) && (--waitTimes != 0U))
  912. #else
  913. while (LPSPI_GetRxFifoCount(base) != 0U)
  914. #endif
  915. {
  916. readData = LPSPI_ReadData(base);
  917. if (rxRemainingByteCount < bytesEachRead)
  918. {
  919. bytesEachRead = (uint8_t)rxRemainingByteCount;
  920. }
  921. LPSPI_SeparateReadData(rxData, readData, bytesEachRead, isByteSwap);
  922. rxData += bytesEachRead;
  923. rxRemainingByteCount -= bytesEachRead;
  924. }
  925. #if SPI_RETRY_TIMES
  926. if (waitTimes == 0U)
  927. {
  928. return kStatus_LPSPI_Timeout;
  929. }
  930. #endif
  931. }
  932. }
  933. else
  934. {
  935. /* If no RX buffer, then transfer is not complete until transfer complete flag sets */
  936. #if SPI_RETRY_TIMES
  937. waitTimes = SPI_RETRY_TIMES;
  938. while (((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_TransferCompleteFlag) == 0U) && (--waitTimes != 0U))
  939. #else
  940. while ((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_TransferCompleteFlag) == 0U)
  941. #endif
  942. {
  943. }
  944. #if SPI_RETRY_TIMES
  945. if (waitTimes == 0U)
  946. {
  947. return kStatus_LPSPI_Timeout;
  948. }
  949. #endif
  950. }
  951. return kStatus_Success;
  952. }
  953. /*!
  954. * brief LPSPI master transfer data using an interrupt method.
  955. *
  956. * This function transfers data using an interrupt method. This is a non-blocking function, which returns right away.
  957. * When all data is transferred, the callback function is called.
  958. *
  959. * Note:
  960. * The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4.
  961. * For bytesPerFrame greater than 4:
  962. * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not integer multiples of 4.
  963. * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
  964. *
  965. * param base LPSPI peripheral address.
  966. * param handle pointer to lpspi_master_handle_t structure which stores the transfer state.
  967. * param transfer pointer to lpspi_transfer_t structure.
  968. * return status of status_t.
  969. */
  970. status_t LPSPI_MasterTransferNonBlocking(LPSPI_Type *base, lpspi_master_handle_t *handle, lpspi_transfer_t *transfer)
  971. {
  972. assert(handle != NULL);
  973. assert(transfer != NULL);
  974. /* Check that we're not busy.*/
  975. if (handle->state == (uint8_t)kLPSPI_Busy)
  976. {
  977. return kStatus_LPSPI_Busy;
  978. }
  979. LPSPI_Enable(base, false);
  980. /* Check arguements */
  981. if (!LPSPI_CheckTransferArgument(base, transfer, false))
  982. {
  983. return kStatus_InvalidArgument;
  984. }
  985. /* Flush FIFO, clear status, disable all the interrupts. */
  986. LPSPI_FlushFifo(base, true, true);
  987. LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_AllStatusFlag);
  988. LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable);
  989. /* Variables */
  990. bool isRxMask = false;
  991. uint8_t txWatermark;
  992. uint8_t dummyData = g_lpspiDummyData[LPSPI_GetInstance(base)];
  993. uint32_t tmpTimes;
  994. uint32_t whichPcs = (transfer->configFlags & LPSPI_MASTER_PCS_MASK) >> LPSPI_MASTER_PCS_SHIFT;
  995. uint32_t temp = (base->CFGR1 & LPSPI_CFGR1_PINCFG_MASK);
  996. /* Assign the original value for members of transfer handle. */
  997. handle->state = (uint8_t)kLPSPI_Busy;
  998. handle->txData = transfer->txData;
  999. handle->rxData = transfer->rxData;
  1000. handle->txRemainingByteCount = transfer->dataSize;
  1001. handle->rxRemainingByteCount = transfer->dataSize;
  1002. handle->totalByteCount = transfer->dataSize;
  1003. handle->writeTcrInIsr = false;
  1004. handle->bytesPerFrame = (uint16_t)((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) / 8U + 1U;
  1005. /* No need to configure PCS continous if the transfer byte count is smaller than frame size */
  1006. bool isPcsContinuous = (((transfer->configFlags & (uint32_t)kLPSPI_MasterPcsContinuous) != 0U) &&
  1007. (transfer->dataSize > handle->bytesPerFrame));
  1008. handle->writeRegRemainingTimes =
  1009. (transfer->dataSize / (uint32_t)handle->bytesPerFrame) * (((uint32_t)handle->bytesPerFrame + 3U) / 4U);
  1010. handle->readRegRemainingTimes = handle->writeRegRemainingTimes;
  1011. handle->txBuffIfNull =
  1012. ((uint32_t)dummyData) | ((uint32_t)dummyData << 8) | ((uint32_t)dummyData << 16) | ((uint32_t)dummyData << 24);
  1013. /*The TX and RX FIFO sizes are always the same*/
  1014. handle->fifoSize = LPSPI_GetRxFifoSize(base);
  1015. handle->isPcsContinuous = isPcsContinuous;
  1016. handle->isByteSwap = ((transfer->configFlags & (uint32_t)kLPSPI_MasterByteSwap) != 0U);
  1017. /*Calculate the bytes for write/read the TX/RX register each time*/
  1018. if (handle->bytesPerFrame <= 4U)
  1019. {
  1020. handle->bytesEachWrite = (uint8_t)handle->bytesPerFrame;
  1021. handle->bytesEachRead = (uint8_t)handle->bytesPerFrame;
  1022. }
  1023. else
  1024. {
  1025. handle->bytesEachWrite = 4U;
  1026. handle->bytesEachRead = 4U;
  1027. }
  1028. /*Set the RX and TX watermarks to reduce the ISR times.*/
  1029. if (handle->fifoSize > 1U)
  1030. {
  1031. txWatermark = 1U;
  1032. handle->rxWatermark = handle->fifoSize - 2U;
  1033. }
  1034. else
  1035. {
  1036. txWatermark = 0U;
  1037. handle->rxWatermark = 0U;
  1038. }
  1039. LPSPI_SetFifoWatermarks(base, txWatermark, handle->rxWatermark);
  1040. /* If there is no rxData, mask the receive data so that receive data is not stored in receive FIFO. */
  1041. if (handle->rxData == NULL)
  1042. {
  1043. isRxMask = true;
  1044. handle->rxRemainingByteCount = 0;
  1045. }
  1046. /* Mask tx data in half duplex mode since the tx/rx share the same pin, so that the data received from slave is not
  1047. * interfered. */
  1048. if (((temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdiInSdiOut)) || (temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdoInSdoOut))) &&
  1049. (handle->txData == NULL))
  1050. {
  1051. handle->isTxMask = true;
  1052. }
  1053. /*Transfers will stall when transmit FIFO is empty or receive FIFO is full. */
  1054. base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
  1055. /* Enable module for following configuration of TCR to take effect. */
  1056. LPSPI_Enable(base, true);
  1057. /* Configure transfer control register. */
  1058. base->TCR = (base->TCR & ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK |
  1059. LPSPI_TCR_TXMSK_MASK | LPSPI_TCR_PCS_MASK)) |
  1060. LPSPI_TCR_PCS(whichPcs);
  1061. /*TCR is also shared the FIFO , so wait for TCR written.*/
  1062. if (!LPSPI_TxFifoReady(base))
  1063. {
  1064. return kStatus_LPSPI_Timeout;
  1065. }
  1066. /* PCS should be configured separately from the other bits, otherwise it will not take effect. */
  1067. base->TCR |= LPSPI_TCR_CONT(isPcsContinuous) | LPSPI_TCR_CONTC(isPcsContinuous) | LPSPI_TCR_RXMSK(isRxMask);
  1068. /* Enable the NVIC for LPSPI peripheral. Note that below code is useless if the LPSPI interrupt is in INTMUX ,
  1069. * and you should also enable the INTMUX interupt in your application.
  1070. */
  1071. (void)EnableIRQ(s_lpspiIRQ[LPSPI_GetInstance(base)]);
  1072. /*TCR is also shared the FIFO , so wait for TCR written.*/
  1073. if (!LPSPI_TxFifoReady(base))
  1074. {
  1075. return kStatus_LPSPI_Timeout;
  1076. }
  1077. if (handle->isTxMask)
  1078. {
  1079. /* When TCR[TXMSK]=1, transfer is initiate by writting a new command word to TCR. TCR[TXMSK] is cleared by
  1080. hardware every time when TCR[FRAMESZ] bit of data is transfered. In this case TCR[TXMSK] should be set to
  1081. initiate each transfer. */
  1082. base->TCR |= LPSPI_TCR_TXMSK_MASK;
  1083. handle->txRemainingByteCount -= (uint32_t)handle->bytesPerFrame;
  1084. }
  1085. else
  1086. {
  1087. /* Fill up the TX data in FIFO to initiate transfer */
  1088. LPSPI_MasterTransferFillUpTxFifo(base, handle);
  1089. }
  1090. /* Since SPI is a synchronous interface, we only need to enable the RX interrupt if there is RX data.
  1091. * The IRQ handler will get the status of RX and TX interrupt flags.
  1092. */
  1093. if (handle->rxData != NULL)
  1094. {
  1095. if (handle->isTxMask)
  1096. {
  1097. /* if tx data is masked, transfer is initiated by writing 1 to TCR[TXMSK] and TCR[FRMESZ] bits of data is
  1098. read. If rx water mark is set larger than TCR[FRMESZ], rx interrupt will not be generated. Lower the rx
  1099. water mark setting */
  1100. if ((handle->bytesPerFrame / 4U) < (uint16_t)handle->rxWatermark)
  1101. {
  1102. handle->rxWatermark =
  1103. (uint8_t)(handle->bytesPerFrame / 4U) > 0U ? (uint8_t)(handle->bytesPerFrame / 4U - 1U) : 0U;
  1104. base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) | LPSPI_FCR_RXWATER(handle->rxWatermark);
  1105. }
  1106. }
  1107. else
  1108. {
  1109. /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise
  1110. *there is not RX interrupt for the last datas because the RX count is not greater than rxWatermark.
  1111. */
  1112. tmpTimes = handle->readRegRemainingTimes;
  1113. if (tmpTimes <= handle->rxWatermark)
  1114. {
  1115. base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) | LPSPI_FCR_RXWATER(tmpTimes - 1U);
  1116. }
  1117. }
  1118. LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_RxInterruptEnable);
  1119. }
  1120. else
  1121. {
  1122. LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable);
  1123. }
  1124. return kStatus_Success;
  1125. }
  1126. static void LPSPI_MasterTransferFillUpTxFifo(LPSPI_Type *base, lpspi_master_handle_t *handle)
  1127. {
  1128. assert(handle != NULL);
  1129. uint32_t wordToSend = 0;
  1130. uint8_t fifoSize = handle->fifoSize;
  1131. uint32_t writeRegRemainingTimes = handle->writeRegRemainingTimes;
  1132. uint32_t readRegRemainingTimes = handle->readRegRemainingTimes;
  1133. size_t txRemainingByteCount = handle->txRemainingByteCount;
  1134. uint8_t bytesEachWrite = handle->bytesEachWrite;
  1135. bool isByteSwap = handle->isByteSwap;
  1136. /* Make sure the difference in remaining TX and RX byte counts does not exceed FIFO depth
  1137. * and that the number of TX FIFO entries does not exceed the FIFO depth.
  1138. * But no need to make the protection if there is no rxData.
  1139. */
  1140. while ((LPSPI_GetTxFifoCount(base) < fifoSize) &&
  1141. (((readRegRemainingTimes - writeRegRemainingTimes) < (uint32_t)fifoSize) || (handle->rxData == NULL)))
  1142. {
  1143. if (txRemainingByteCount < (size_t)bytesEachWrite)
  1144. {
  1145. handle->bytesEachWrite = (uint8_t)txRemainingByteCount;
  1146. bytesEachWrite = handle->bytesEachWrite;
  1147. }
  1148. if (handle->txData != NULL)
  1149. {
  1150. wordToSend = LPSPI_CombineWriteData(handle->txData, bytesEachWrite, isByteSwap);
  1151. handle->txData += bytesEachWrite;
  1152. }
  1153. else
  1154. {
  1155. wordToSend = handle->txBuffIfNull;
  1156. }
  1157. /*Write the word to TX register*/
  1158. LPSPI_WriteData(base, wordToSend);
  1159. /*Decrease the write TX register times.*/
  1160. --handle->writeRegRemainingTimes;
  1161. writeRegRemainingTimes = handle->writeRegRemainingTimes;
  1162. /*Decrease the remaining TX byte count.*/
  1163. handle->txRemainingByteCount -= (size_t)bytesEachWrite;
  1164. txRemainingByteCount = handle->txRemainingByteCount;
  1165. if (handle->txRemainingByteCount == 0U)
  1166. {
  1167. /* If PCS is continuous, update TCR to de-assert PCS */
  1168. if (handle->isPcsContinuous)
  1169. {
  1170. /* Only write to the TCR if the FIFO has room */
  1171. if (LPSPI_GetTxFifoCount(base) < fifoSize)
  1172. {
  1173. base->TCR = (base->TCR & ~(LPSPI_TCR_CONTC_MASK));
  1174. handle->writeTcrInIsr = false;
  1175. }
  1176. /* Else, set a global flag to tell the ISR to do write to the TCR */
  1177. else
  1178. {
  1179. handle->writeTcrInIsr = true;
  1180. }
  1181. }
  1182. break;
  1183. }
  1184. }
  1185. }
  1186. static void LPSPI_MasterTransferComplete(LPSPI_Type *base, lpspi_master_handle_t *handle)
  1187. {
  1188. assert(handle != NULL);
  1189. /* Disable interrupt requests*/
  1190. LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable);
  1191. handle->state = (uint8_t)kLPSPI_Idle;
  1192. if (handle->callback != NULL)
  1193. {
  1194. handle->callback(base, handle, kStatus_Success, handle->userData);
  1195. }
  1196. }
  1197. /*!
  1198. * brief Gets the master transfer remaining bytes.
  1199. *
  1200. * This function gets the master transfer remaining bytes.
  1201. *
  1202. * param base LPSPI peripheral address.
  1203. * param handle pointer to lpspi_master_handle_t structure which stores the transfer state.
  1204. * param count Number of bytes transferred so far by the non-blocking transaction.
  1205. * return status of status_t.
  1206. */
  1207. status_t LPSPI_MasterTransferGetCount(LPSPI_Type *base, lpspi_master_handle_t *handle, size_t *count)
  1208. {
  1209. assert(handle != NULL);
  1210. if (NULL == count)
  1211. {
  1212. return kStatus_InvalidArgument;
  1213. }
  1214. /* Catch when there is not an active transfer. */
  1215. if (handle->state != (uint8_t)kLPSPI_Busy)
  1216. {
  1217. *count = 0;
  1218. return kStatus_NoTransferInProgress;
  1219. }
  1220. size_t remainingByte;
  1221. if (handle->rxData != NULL)
  1222. {
  1223. remainingByte = handle->rxRemainingByteCount;
  1224. }
  1225. else
  1226. {
  1227. remainingByte = handle->txRemainingByteCount;
  1228. }
  1229. *count = handle->totalByteCount - remainingByte;
  1230. return kStatus_Success;
  1231. }
  1232. /*!
  1233. * brief LPSPI master abort transfer which uses an interrupt method.
  1234. *
  1235. * This function aborts a transfer which uses an interrupt method.
  1236. *
  1237. * param base LPSPI peripheral address.
  1238. * param handle pointer to lpspi_master_handle_t structure which stores the transfer state.
  1239. */
  1240. void LPSPI_MasterTransferAbort(LPSPI_Type *base, lpspi_master_handle_t *handle)
  1241. {
  1242. assert(handle != NULL);
  1243. /* Disable interrupt requests*/
  1244. LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable);
  1245. LPSPI_Reset(base);
  1246. handle->state = (uint8_t)kLPSPI_Idle;
  1247. handle->txRemainingByteCount = 0;
  1248. handle->rxRemainingByteCount = 0;
  1249. }
  1250. /*!
  1251. * brief LPSPI Master IRQ handler function.
  1252. *
  1253. * This function processes the LPSPI transmit and receive IRQ.
  1254. *
  1255. * param base LPSPI peripheral address.
  1256. * param handle pointer to lpspi_master_handle_t structure which stores the transfer state.
  1257. */
  1258. void LPSPI_MasterTransferHandleIRQ(LPSPI_Type *base, lpspi_master_handle_t *handle)
  1259. {
  1260. assert(handle != NULL);
  1261. uint32_t readData;
  1262. uint8_t bytesEachRead = handle->bytesEachRead;
  1263. bool isByteSwap = handle->isByteSwap;
  1264. uint32_t readRegRemainingTimes = handle->readRegRemainingTimes;
  1265. if (handle->rxData != NULL)
  1266. {
  1267. if (handle->rxRemainingByteCount != 0U)
  1268. {
  1269. /* First, disable the interrupts to avoid potentially triggering another interrupt
  1270. * while reading out the RX FIFO as more data may be coming into the RX FIFO. We'll
  1271. * re-enable the interrupts based on the LPSPI state after reading out the FIFO.
  1272. */
  1273. LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_RxInterruptEnable);
  1274. while ((LPSPI_GetRxFifoCount(base) != 0U) && (handle->rxRemainingByteCount != 0U))
  1275. {
  1276. /*Read out the data*/
  1277. readData = LPSPI_ReadData(base);
  1278. /*Decrease the read RX register times.*/
  1279. --handle->readRegRemainingTimes;
  1280. readRegRemainingTimes = handle->readRegRemainingTimes;
  1281. if (handle->rxRemainingByteCount < (size_t)bytesEachRead)
  1282. {
  1283. handle->bytesEachRead = (uint8_t)(handle->rxRemainingByteCount);
  1284. bytesEachRead = handle->bytesEachRead;
  1285. }
  1286. LPSPI_SeparateReadData(handle->rxData, readData, bytesEachRead, isByteSwap);
  1287. handle->rxData += bytesEachRead;
  1288. /*Decrease the remaining RX byte count.*/
  1289. handle->rxRemainingByteCount -= (size_t)bytesEachRead;
  1290. }
  1291. /* Re-enable the interrupts only if rxCount indicates there is more data to receive,
  1292. * else we may get a spurious interrupt.
  1293. * */
  1294. if (handle->rxRemainingByteCount != 0U)
  1295. {
  1296. /* Set the TDF and RDF interrupt enables simultaneously to avoid race conditions */
  1297. LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_RxInterruptEnable);
  1298. }
  1299. }
  1300. /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise there
  1301. *is not RX interrupt for the last datas because the RX count is not greater than rxWatermark.
  1302. */
  1303. if (readRegRemainingTimes <= (uint32_t)handle->rxWatermark)
  1304. {
  1305. base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) |
  1306. LPSPI_FCR_RXWATER((readRegRemainingTimes > 1U) ? (readRegRemainingTimes - 1U) : (0U));
  1307. }
  1308. }
  1309. if (handle->txRemainingByteCount != 0U)
  1310. {
  1311. if (handle->isTxMask)
  1312. {
  1313. /* When TCR[TXMSK]=1, transfer is initiate by writting a new command word to TCR. TCR[TXMSK] is cleared by
  1314. hardware every time when TCR[FRAMESZ] bit of data is transfered.
  1315. In this case TCR[TXMSK] should be set to initiate each transfer. */
  1316. base->TCR |= LPSPI_TCR_TXMSK_MASK;
  1317. if ((handle->txRemainingByteCount == (uint32_t)handle->bytesPerFrame) && (handle->isPcsContinuous))
  1318. {
  1319. /* For the last piece of frame size of data, if is PCS continous mode(TCR[CONT]), TCR[CONTC] should
  1320. * be cleared to de-assert the PCS. Be sure to clear the TXMSK as well otherwise another FRAMESZ
  1321. * of data will be received. */
  1322. base->TCR &= ~(LPSPI_TCR_CONTC_MASK | LPSPI_TCR_CONT_MASK | LPSPI_TCR_TXMSK_MASK);
  1323. }
  1324. handle->txRemainingByteCount -= (uint32_t)handle->bytesPerFrame;
  1325. }
  1326. else
  1327. {
  1328. LPSPI_MasterTransferFillUpTxFifo(base, handle);
  1329. }
  1330. }
  1331. else
  1332. {
  1333. if ((LPSPI_GetTxFifoCount(base) < (handle->fifoSize)))
  1334. {
  1335. if ((handle->isPcsContinuous) && (handle->writeTcrInIsr) && (!handle->isTxMask))
  1336. {
  1337. base->TCR = (base->TCR & ~(LPSPI_TCR_CONTC_MASK));
  1338. handle->writeTcrInIsr = false;
  1339. }
  1340. }
  1341. }
  1342. if ((handle->txRemainingByteCount == 0U) && (handle->rxRemainingByteCount == 0U) && (!handle->writeTcrInIsr))
  1343. {
  1344. /* If no RX buffer, then transfer is not complete until transfer complete flag sets */
  1345. if (handle->rxData == NULL)
  1346. {
  1347. if ((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_TransferCompleteFlag) != 0U)
  1348. {
  1349. LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_TransferCompleteFlag);
  1350. /* Complete the transfer and disable the interrupts */
  1351. LPSPI_MasterTransferComplete(base, handle);
  1352. }
  1353. else
  1354. {
  1355. LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_TransferCompleteInterruptEnable);
  1356. LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable | (uint32_t)kLPSPI_RxInterruptEnable);
  1357. }
  1358. }
  1359. else
  1360. {
  1361. /* Complete the transfer and disable the interrupts */
  1362. LPSPI_MasterTransferComplete(base, handle);
  1363. }
  1364. }
  1365. }
  1366. /*Transactional APIs -- Slave*/
  1367. /*!
  1368. * brief Initializes the LPSPI slave handle.
  1369. *
  1370. * This function initializes the LPSPI handle, which can be used for other LPSPI transactional APIs. Usually, for a
  1371. * specified LPSPI instance, call this API once to get the initialized handle.
  1372. *
  1373. * param base LPSPI peripheral address.
  1374. * param handle LPSPI handle pointer to lpspi_slave_handle_t.
  1375. * param callback DSPI callback.
  1376. * param userData callback function parameter.
  1377. */
  1378. void LPSPI_SlaveTransferCreateHandle(LPSPI_Type *base,
  1379. lpspi_slave_handle_t *handle,
  1380. lpspi_slave_transfer_callback_t callback,
  1381. void *userData)
  1382. {
  1383. assert(handle != NULL);
  1384. /* Zero the handle. */
  1385. (void)memset(handle, 0, sizeof(*handle));
  1386. s_lpspiHandle[LPSPI_GetInstance(base)] = handle;
  1387. /* Set irq handler. */
  1388. s_lpspiSlaveIsr = LPSPI_SlaveTransferHandleIRQ;
  1389. handle->callback = callback;
  1390. handle->userData = userData;
  1391. }
  1392. /*!
  1393. * brief LPSPI slave transfer data using an interrupt method.
  1394. *
  1395. * This function transfer data using an interrupt method. This is a non-blocking function, which returns right away.
  1396. * When all data is transferred, the callback function is called.
  1397. *
  1398. * Note:
  1399. * The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4.
  1400. * For bytesPerFrame greater than 4:
  1401. * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not an integer multiple of 4.
  1402. * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
  1403. *
  1404. * param base LPSPI peripheral address.
  1405. * param handle pointer to lpspi_slave_handle_t structure which stores the transfer state.
  1406. * param transfer pointer to lpspi_transfer_t structure.
  1407. * return status of status_t.
  1408. */
  1409. status_t LPSPI_SlaveTransferNonBlocking(LPSPI_Type *base, lpspi_slave_handle_t *handle, lpspi_transfer_t *transfer)
  1410. {
  1411. assert(handle != NULL);
  1412. assert(transfer != NULL);
  1413. /* Check that we're not busy.*/
  1414. if (handle->state == (uint8_t)kLPSPI_Busy)
  1415. {
  1416. return kStatus_LPSPI_Busy;
  1417. }
  1418. LPSPI_Enable(base, false);
  1419. /* Check arguements */
  1420. if (!LPSPI_CheckTransferArgument(base, transfer, false))
  1421. {
  1422. return kStatus_InvalidArgument;
  1423. }
  1424. /* Flush FIFO, clear status, disable all the inerrupts. */
  1425. LPSPI_FlushFifo(base, true, true);
  1426. LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_AllStatusFlag);
  1427. LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable);
  1428. /* Variables */
  1429. bool isRxMask = false;
  1430. bool isTxMask = false;
  1431. uint8_t txWatermark;
  1432. uint32_t readRegRemainingTimes;
  1433. uint32_t whichPcs = (transfer->configFlags & LPSPI_SLAVE_PCS_MASK) >> LPSPI_SLAVE_PCS_SHIFT;
  1434. uint32_t bytesPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) / 8U + 1U;
  1435. /* Assign the original value for members of transfer handle. */
  1436. handle->state = (uint8_t)kLPSPI_Busy;
  1437. handle->txData = transfer->txData;
  1438. handle->rxData = transfer->rxData;
  1439. handle->txRemainingByteCount = transfer->dataSize;
  1440. handle->rxRemainingByteCount = transfer->dataSize;
  1441. handle->totalByteCount = transfer->dataSize;
  1442. handle->writeRegRemainingTimes = (transfer->dataSize / bytesPerFrame) * ((bytesPerFrame + 3U) / 4U);
  1443. handle->readRegRemainingTimes = handle->writeRegRemainingTimes;
  1444. /*The TX and RX FIFO sizes are always the same*/
  1445. handle->fifoSize = LPSPI_GetRxFifoSize(base);
  1446. handle->isByteSwap = ((transfer->configFlags & (uint32_t)kLPSPI_SlaveByteSwap) != 0U);
  1447. /*Calculate the bytes for write/read the TX/RX register each time*/
  1448. if (bytesPerFrame <= 4U)
  1449. {
  1450. handle->bytesEachWrite = (uint8_t)bytesPerFrame;
  1451. handle->bytesEachRead = (uint8_t)bytesPerFrame;
  1452. }
  1453. else
  1454. {
  1455. handle->bytesEachWrite = 4U;
  1456. handle->bytesEachRead = 4U;
  1457. }
  1458. /* Set proper RX and TX watermarks to reduce the ISR response times. */
  1459. if (handle->fifoSize > 1U)
  1460. {
  1461. txWatermark = 1U;
  1462. handle->rxWatermark = handle->fifoSize - 2U;
  1463. }
  1464. else
  1465. {
  1466. txWatermark = 0U;
  1467. handle->rxWatermark = 0U;
  1468. }
  1469. LPSPI_SetFifoWatermarks(base, txWatermark, handle->rxWatermark);
  1470. /* If there is no rxData, mask the receive data so that receive data is not stored in receive FIFO. */
  1471. if (handle->rxData == NULL)
  1472. {
  1473. isRxMask = true;
  1474. handle->rxRemainingByteCount = 0U;
  1475. }
  1476. /* If there is no txData, mask the transmit data so that no data is loaded from transmit FIFO and output pin
  1477. * is tristated. */
  1478. if (handle->txData == NULL)
  1479. {
  1480. isTxMask = true;
  1481. handle->txRemainingByteCount = 0U;
  1482. }
  1483. /* Enable module for following configuration of TCR to take effect. */
  1484. LPSPI_Enable(base, true);
  1485. base->TCR = (base->TCR & ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK |
  1486. LPSPI_TCR_TXMSK_MASK | LPSPI_TCR_PCS_MASK)) |
  1487. LPSPI_TCR_RXMSK(isRxMask) | LPSPI_TCR_TXMSK(isTxMask) | LPSPI_TCR_PCS(whichPcs);
  1488. /* Enable the NVIC for LPSPI peripheral. Note that below code is useless if the LPSPI interrupt is in INTMUX ,
  1489. * and you should also enable the INTMUX interupt in your application.
  1490. */
  1491. (void)EnableIRQ(s_lpspiIRQ[LPSPI_GetInstance(base)]);
  1492. /*TCR is also shared the FIFO, so wait for TCR written.*/
  1493. if (!LPSPI_TxFifoReady(base))
  1494. {
  1495. return kStatus_LPSPI_Timeout;
  1496. }
  1497. /* Fill up the TX data in FIFO */
  1498. if (handle->txData != NULL)
  1499. {
  1500. LPSPI_SlaveTransferFillUpTxFifo(base, handle);
  1501. }
  1502. /* Since SPI is a synchronous interface, we only need to enable the RX interrupt if there is RX data.
  1503. * The IRQ handler will get the status of RX and TX interrupt flags.
  1504. */
  1505. if (handle->rxData != NULL)
  1506. {
  1507. /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise there
  1508. *is not RX interrupt for the last datas because the RX count is not greater than rxWatermark.
  1509. */
  1510. readRegRemainingTimes = handle->readRegRemainingTimes;
  1511. if (readRegRemainingTimes <= (uint32_t)handle->rxWatermark)
  1512. {
  1513. base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) | LPSPI_FCR_RXWATER(readRegRemainingTimes - 1U);
  1514. }
  1515. /* RX request and FIFO overflow request enable */
  1516. LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_RxInterruptEnable | (uint32_t)kLPSPI_ReceiveErrorInterruptEnable);
  1517. }
  1518. else
  1519. {
  1520. LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable);
  1521. }
  1522. if (handle->txData != NULL)
  1523. {
  1524. /* TX FIFO underflow request enable */
  1525. LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_TransmitErrorInterruptEnable);
  1526. }
  1527. return kStatus_Success;
  1528. }
  1529. static void LPSPI_SlaveTransferFillUpTxFifo(LPSPI_Type *base, lpspi_slave_handle_t *handle)
  1530. {
  1531. assert(handle != NULL);
  1532. uint32_t wordToSend = 0U;
  1533. uint8_t bytesEachWrite = handle->bytesEachWrite;
  1534. bool isByteSwap = handle->isByteSwap;
  1535. while (LPSPI_GetTxFifoCount(base) < (handle->fifoSize))
  1536. {
  1537. if (handle->txRemainingByteCount < (size_t)bytesEachWrite)
  1538. {
  1539. handle->bytesEachWrite = (uint8_t)handle->txRemainingByteCount;
  1540. bytesEachWrite = handle->bytesEachWrite;
  1541. }
  1542. wordToSend = LPSPI_CombineWriteData(handle->txData, bytesEachWrite, isByteSwap);
  1543. handle->txData += bytesEachWrite;
  1544. /*Decrease the remaining TX byte count.*/
  1545. handle->txRemainingByteCount -= (size_t)bytesEachWrite;
  1546. /*Write the word to TX register*/
  1547. LPSPI_WriteData(base, wordToSend);
  1548. if (handle->txRemainingByteCount == 0U)
  1549. {
  1550. break;
  1551. }
  1552. }
  1553. }
  1554. static void LPSPI_SlaveTransferComplete(LPSPI_Type *base, lpspi_slave_handle_t *handle)
  1555. {
  1556. assert(handle != NULL);
  1557. status_t status = kStatus_Success;
  1558. /* Disable interrupt requests*/
  1559. LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable);
  1560. if (handle->state == (uint8_t)kLPSPI_Error)
  1561. {
  1562. status = kStatus_LPSPI_Error;
  1563. }
  1564. else
  1565. {
  1566. status = kStatus_Success;
  1567. }
  1568. handle->state = (uint8_t)kLPSPI_Idle;
  1569. if (handle->callback != NULL)
  1570. {
  1571. handle->callback(base, handle, status, handle->userData);
  1572. }
  1573. }
  1574. /*!
  1575. * brief Gets the slave transfer remaining bytes.
  1576. *
  1577. * This function gets the slave transfer remaining bytes.
  1578. *
  1579. * param base LPSPI peripheral address.
  1580. * param handle pointer to lpspi_slave_handle_t structure which stores the transfer state.
  1581. * param count Number of bytes transferred so far by the non-blocking transaction.
  1582. * return status of status_t.
  1583. */
  1584. status_t LPSPI_SlaveTransferGetCount(LPSPI_Type *base, lpspi_slave_handle_t *handle, size_t *count)
  1585. {
  1586. assert(handle != NULL);
  1587. if (NULL == count)
  1588. {
  1589. return kStatus_InvalidArgument;
  1590. }
  1591. /* Catch when there is not an active transfer. */
  1592. if (handle->state != (uint8_t)kLPSPI_Busy)
  1593. {
  1594. *count = 0;
  1595. return kStatus_NoTransferInProgress;
  1596. }
  1597. size_t remainingByte;
  1598. if (handle->rxData != NULL)
  1599. {
  1600. remainingByte = handle->rxRemainingByteCount;
  1601. }
  1602. else
  1603. {
  1604. remainingByte = handle->txRemainingByteCount;
  1605. }
  1606. *count = handle->totalByteCount - remainingByte;
  1607. return kStatus_Success;
  1608. }
  1609. /*!
  1610. * brief LPSPI slave aborts a transfer which uses an interrupt method.
  1611. *
  1612. * This function aborts a transfer which uses an interrupt method.
  1613. *
  1614. * param base LPSPI peripheral address.
  1615. * param handle pointer to lpspi_slave_handle_t structure which stores the transfer state.
  1616. */
  1617. void LPSPI_SlaveTransferAbort(LPSPI_Type *base, lpspi_slave_handle_t *handle)
  1618. {
  1619. assert(handle != NULL);
  1620. /* Disable interrupt requests*/
  1621. LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable | (uint32_t)kLPSPI_RxInterruptEnable);
  1622. LPSPI_Reset(base);
  1623. handle->state = (uint8_t)kLPSPI_Idle;
  1624. handle->txRemainingByteCount = 0U;
  1625. handle->rxRemainingByteCount = 0U;
  1626. }
  1627. /*!
  1628. * brief LPSPI Slave IRQ handler function.
  1629. *
  1630. * This function processes the LPSPI transmit and receives an IRQ.
  1631. *
  1632. * param base LPSPI peripheral address.
  1633. * param handle pointer to lpspi_slave_handle_t structure which stores the transfer state.
  1634. */
  1635. void LPSPI_SlaveTransferHandleIRQ(LPSPI_Type *base, lpspi_slave_handle_t *handle)
  1636. {
  1637. assert(handle != NULL);
  1638. uint32_t readData; /* variable to store word read from RX FIFO */
  1639. uint8_t bytesEachRead = handle->bytesEachRead;
  1640. bool isByteSwap = handle->isByteSwap;
  1641. uint32_t readRegRemainingTimes;
  1642. if (handle->rxData != NULL)
  1643. {
  1644. if (handle->rxRemainingByteCount > 0U)
  1645. {
  1646. while (LPSPI_GetRxFifoCount(base) != 0U)
  1647. {
  1648. /*Read out the data*/
  1649. readData = LPSPI_ReadData(base);
  1650. /*Decrease the read RX register times.*/
  1651. --handle->readRegRemainingTimes;
  1652. if (handle->rxRemainingByteCount < (size_t)bytesEachRead)
  1653. {
  1654. handle->bytesEachRead = (uint8_t)handle->rxRemainingByteCount;
  1655. bytesEachRead = handle->bytesEachRead;
  1656. }
  1657. LPSPI_SeparateReadData(handle->rxData, readData, bytesEachRead, isByteSwap);
  1658. handle->rxData += bytesEachRead;
  1659. /*Decrease the remaining RX byte count.*/
  1660. handle->rxRemainingByteCount -= (size_t)bytesEachRead;
  1661. if ((handle->txRemainingByteCount > 0U) && (handle->txData != NULL))
  1662. {
  1663. LPSPI_SlaveTransferFillUpTxFifo(base, handle);
  1664. }
  1665. if (handle->rxRemainingByteCount == 0U)
  1666. {
  1667. break;
  1668. }
  1669. }
  1670. }
  1671. /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise there
  1672. *is not RX interrupt for the last datas because the RX count is not greater than rxWatermark.
  1673. */
  1674. readRegRemainingTimes = handle->readRegRemainingTimes;
  1675. if (readRegRemainingTimes <= (uint32_t)handle->rxWatermark)
  1676. {
  1677. base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) |
  1678. LPSPI_FCR_RXWATER((readRegRemainingTimes > 1U) ? (readRegRemainingTimes - 1U) : (0U));
  1679. }
  1680. }
  1681. if ((handle->rxData == NULL) && (handle->txRemainingByteCount != 0U) && (handle->txData != NULL))
  1682. {
  1683. LPSPI_SlaveTransferFillUpTxFifo(base, handle);
  1684. }
  1685. if ((handle->txRemainingByteCount == 0U) && (handle->rxRemainingByteCount == 0U))
  1686. {
  1687. /* If no RX buffer, then transfer is not complete until transfer complete flag sets and the TX FIFO empty*/
  1688. if (handle->rxData == NULL)
  1689. {
  1690. if (((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_FrameCompleteFlag) != 0U) &&
  1691. (LPSPI_GetTxFifoCount(base) == 0U))
  1692. {
  1693. LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_FrameCompleteFlag);
  1694. /* Complete the transfer and disable the interrupts */
  1695. LPSPI_SlaveTransferComplete(base, handle);
  1696. }
  1697. else
  1698. {
  1699. LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_FrameCompleteFlag);
  1700. LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_FrameCompleteInterruptEnable);
  1701. LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable | (uint32_t)kLPSPI_RxInterruptEnable);
  1702. }
  1703. }
  1704. else
  1705. {
  1706. /* Complete the transfer and disable the interrupts */
  1707. LPSPI_SlaveTransferComplete(base, handle);
  1708. }
  1709. }
  1710. /* Catch tx fifo underflow conditions, service only if tx under flow interrupt enabled */
  1711. if (((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_TransmitErrorFlag) != 0U) &&
  1712. ((base->IER & LPSPI_IER_TEIE_MASK) != 0U))
  1713. {
  1714. LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_TransmitErrorFlag);
  1715. /* Change state to error and clear flag */
  1716. if (handle->txData != NULL)
  1717. {
  1718. handle->state = (uint8_t)kLPSPI_Error;
  1719. }
  1720. handle->errorCount++;
  1721. }
  1722. /* Catch rx fifo overflow conditions, service only if rx over flow interrupt enabled */
  1723. if (((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_ReceiveErrorFlag) != 0U) &&
  1724. ((base->IER & LPSPI_IER_REIE_MASK) != 0U))
  1725. {
  1726. LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_ReceiveErrorFlag);
  1727. /* Change state to error and clear flag */
  1728. if (handle->txData != NULL)
  1729. {
  1730. handle->state = (uint8_t)kLPSPI_Error;
  1731. }
  1732. handle->errorCount++;
  1733. }
  1734. }
  1735. static uint32_t LPSPI_CombineWriteData(uint8_t *txData, uint8_t bytesEachWrite, bool isByteSwap)
  1736. {
  1737. assert(txData != NULL);
  1738. uint32_t wordToSend = 0U;
  1739. switch (bytesEachWrite)
  1740. {
  1741. case 1:
  1742. wordToSend = *txData;
  1743. ++txData;
  1744. break;
  1745. case 2:
  1746. if (!isByteSwap)
  1747. {
  1748. wordToSend = *txData;
  1749. ++txData;
  1750. wordToSend |= (unsigned)(*txData) << 8U;
  1751. ++txData;
  1752. }
  1753. else
  1754. {
  1755. wordToSend = (unsigned)(*txData) << 8U;
  1756. ++txData;
  1757. wordToSend |= *txData;
  1758. ++txData;
  1759. }
  1760. break;
  1761. case 3:
  1762. if (!isByteSwap)
  1763. {
  1764. wordToSend = *txData;
  1765. ++txData;
  1766. wordToSend |= (unsigned)(*txData) << 8U;
  1767. ++txData;
  1768. wordToSend |= (unsigned)(*txData) << 16U;
  1769. ++txData;
  1770. }
  1771. else
  1772. {
  1773. wordToSend = (unsigned)(*txData) << 16U;
  1774. ++txData;
  1775. wordToSend |= (unsigned)(*txData) << 8U;
  1776. ++txData;
  1777. wordToSend |= *txData;
  1778. ++txData;
  1779. }
  1780. break;
  1781. case 4:
  1782. if (!isByteSwap)
  1783. {
  1784. wordToSend = *txData;
  1785. ++txData;
  1786. wordToSend |= (unsigned)(*txData) << 8U;
  1787. ++txData;
  1788. wordToSend |= (unsigned)(*txData) << 16U;
  1789. ++txData;
  1790. wordToSend |= (unsigned)(*txData) << 24U;
  1791. ++txData;
  1792. }
  1793. else
  1794. {
  1795. wordToSend = (unsigned)(*txData) << 24U;
  1796. ++txData;
  1797. wordToSend |= (unsigned)(*txData) << 16U;
  1798. ++txData;
  1799. wordToSend |= (unsigned)(*txData) << 8U;
  1800. ++txData;
  1801. wordToSend |= *txData;
  1802. ++txData;
  1803. }
  1804. break;
  1805. default:
  1806. assert(false);
  1807. break;
  1808. }
  1809. return wordToSend;
  1810. }
  1811. static void LPSPI_SeparateReadData(uint8_t *rxData, uint32_t readData, uint8_t bytesEachRead, bool isByteSwap)
  1812. {
  1813. assert(rxData != NULL);
  1814. switch (bytesEachRead)
  1815. {
  1816. case 1:
  1817. *rxData = (uint8_t)readData;
  1818. ++rxData;
  1819. break;
  1820. case 2:
  1821. if (!isByteSwap)
  1822. {
  1823. *rxData = (uint8_t)readData;
  1824. ++rxData;
  1825. *rxData = (uint8_t)(readData >> 8);
  1826. ++rxData;
  1827. }
  1828. else
  1829. {
  1830. *rxData = (uint8_t)(readData >> 8);
  1831. ++rxData;
  1832. *rxData = (uint8_t)readData;
  1833. ++rxData;
  1834. }
  1835. break;
  1836. case 3:
  1837. if (!isByteSwap)
  1838. {
  1839. *rxData = (uint8_t)readData;
  1840. ++rxData;
  1841. *rxData = (uint8_t)(readData >> 8);
  1842. ++rxData;
  1843. *rxData = (uint8_t)(readData >> 16);
  1844. ++rxData;
  1845. }
  1846. else
  1847. {
  1848. *rxData = (uint8_t)(readData >> 16);
  1849. ++rxData;
  1850. *rxData = (uint8_t)(readData >> 8);
  1851. ++rxData;
  1852. *rxData = (uint8_t)readData;
  1853. ++rxData;
  1854. }
  1855. break;
  1856. case 4:
  1857. if (!isByteSwap)
  1858. {
  1859. *rxData = (uint8_t)readData;
  1860. ++rxData;
  1861. *rxData = (uint8_t)(readData >> 8);
  1862. ++rxData;
  1863. *rxData = (uint8_t)(readData >> 16);
  1864. ++rxData;
  1865. *rxData = (uint8_t)(readData >> 24);
  1866. ++rxData;
  1867. }
  1868. else
  1869. {
  1870. *rxData = (uint8_t)(readData >> 24);
  1871. ++rxData;
  1872. *rxData = (uint8_t)(readData >> 16);
  1873. ++rxData;
  1874. *rxData = (uint8_t)(readData >> 8);
  1875. ++rxData;
  1876. *rxData = (uint8_t)readData;
  1877. ++rxData;
  1878. }
  1879. break;
  1880. default:
  1881. assert(false);
  1882. break;
  1883. }
  1884. }
  1885. static bool LPSPI_TxFifoReady(LPSPI_Type *base)
  1886. {
  1887. #if SPI_RETRY_TIMES
  1888. uint32_t waitTimes = SPI_RETRY_TIMES;
  1889. while (((uint8_t)LPSPI_GetTxFifoCount(base) != 0U) && (--waitTimes != 0U))
  1890. #else
  1891. while ((uint8_t)LPSPI_GetTxFifoCount(base) != 0U)
  1892. #endif
  1893. {
  1894. }
  1895. #if SPI_RETRY_TIMES
  1896. if (waitTimes == 0U)
  1897. {
  1898. return false;
  1899. }
  1900. #endif
  1901. return true;
  1902. }
  1903. static void LPSPI_CommonIRQHandler(LPSPI_Type *base, void *param)
  1904. {
  1905. if (LPSPI_IsMaster(base))
  1906. {
  1907. s_lpspiMasterIsr(base, (lpspi_master_handle_t *)param);
  1908. }
  1909. else
  1910. {
  1911. s_lpspiSlaveIsr(base, (lpspi_slave_handle_t *)param);
  1912. }
  1913. SDK_ISR_EXIT_BARRIER;
  1914. }
  1915. #if defined(LPSPI0)
  1916. void LPSPI0_DriverIRQHandler(void);
  1917. void LPSPI0_DriverIRQHandler(void)
  1918. {
  1919. assert(s_lpspiHandle[0] != NULL);
  1920. LPSPI_CommonIRQHandler(LPSPI0, s_lpspiHandle[0]);
  1921. }
  1922. #endif
  1923. #if defined(LPSPI1)
  1924. void LPSPI1_DriverIRQHandler(void);
  1925. void LPSPI1_DriverIRQHandler(void)
  1926. {
  1927. assert(s_lpspiHandle[1] != NULL);
  1928. LPSPI_CommonIRQHandler(LPSPI1, s_lpspiHandle[1]);
  1929. }
  1930. #endif
  1931. #if defined(LPSPI2)
  1932. void LPSPI2_DriverIRQHandler(void);
  1933. void LPSPI2_DriverIRQHandler(void)
  1934. {
  1935. assert(s_lpspiHandle[2] != NULL);
  1936. LPSPI_CommonIRQHandler(LPSPI2, s_lpspiHandle[2]);
  1937. }
  1938. #endif
  1939. #if defined(LPSPI3)
  1940. void LPSPI3_DriverIRQHandler(void);
  1941. void LPSPI3_DriverIRQHandler(void)
  1942. {
  1943. assert(s_lpspiHandle[3] != NULL);
  1944. LPSPI_CommonIRQHandler(LPSPI3, s_lpspiHandle[3]);
  1945. }
  1946. #endif
  1947. #if defined(LPSPI4)
  1948. void LPSPI4_DriverIRQHandler(void);
  1949. void LPSPI4_DriverIRQHandler(void)
  1950. {
  1951. assert(s_lpspiHandle[4] != NULL);
  1952. LPSPI_CommonIRQHandler(LPSPI4, s_lpspiHandle[4]);
  1953. }
  1954. #endif
  1955. #if defined(LPSPI5)
  1956. void LPSPI5_DriverIRQHandler(void);
  1957. void LPSPI5_DriverIRQHandler(void)
  1958. {
  1959. assert(s_lpspiHandle[5] != NULL);
  1960. LPSPI_CommonIRQHandler(LPSPI5, s_lpspiHandle[5]);
  1961. }
  1962. #endif
  1963. #if defined(DMA__LPSPI0)
  1964. void DMA_SPI0_INT_DriverIRQHandler(void);
  1965. void DMA_SPI0_INT_DriverIRQHandler(void)
  1966. {
  1967. assert(s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI0)] != NULL);
  1968. LPSPI_CommonIRQHandler(DMA__LPSPI0, s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI0)]);
  1969. }
  1970. #endif
  1971. #if defined(DMA__LPSPI1)
  1972. void DMA_SPI1_INT_DriverIRQHandler(void);
  1973. void DMA_SPI1_INT_DriverIRQHandler(void)
  1974. {
  1975. assert(s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI1)] != NULL);
  1976. LPSPI_CommonIRQHandler(DMA__LPSPI1, s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI1)]);
  1977. }
  1978. #endif
  1979. #if defined(DMA__LPSPI2)
  1980. void DMA_SPI2_INT_DriverIRQHandler(void);
  1981. void DMA_SPI2_INT_DriverIRQHandler(void)
  1982. {
  1983. assert(s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI2)] != NULL);
  1984. LPSPI_CommonIRQHandler(DMA__LPSPI2, s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI2)]);
  1985. }
  1986. #endif
  1987. #if defined(DMA__LPSPI3)
  1988. void DMA_SPI3_INT_DriverIRQHandler(void);
  1989. void DMA_SPI3_INT_DriverIRQHandler(void)
  1990. {
  1991. assert(s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI3)] != NULL);
  1992. LPSPI_CommonIRQHandler(DMA__LPSPI3, s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI3)]);
  1993. }
  1994. #endif
  1995. #if defined(ADMA__LPSPI0)
  1996. void ADMA_SPI0_INT_DriverIRQHandler(void);
  1997. void ADMA_SPI0_INT_DriverIRQHandler(void)
  1998. {
  1999. assert(s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI0)] != NULL);
  2000. LPSPI_CommonIRQHandler(ADMA__LPSPI0, s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI0)]);
  2001. }
  2002. #endif
  2003. #if defined(ADMA__LPSPI1)
  2004. void ADMA_SPI1_INT_DriverIRQHandler(void);
  2005. void ADMA_SPI1_INT_DriverIRQHandler(void)
  2006. {
  2007. assert(s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI1)] != NULL);
  2008. LPSPI_CommonIRQHandler(ADMA__LPSPI1, s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI1)]);
  2009. }
  2010. #endif
  2011. #if defined(ADMA__LPSPI2)
  2012. void ADMA_SPI2_INT_DriverIRQHandler(void);
  2013. void ADMA_SPI2_INT_DriverIRQHandler(void)
  2014. {
  2015. assert(s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI2)] != NULL);
  2016. LPSPI_CommonIRQHandler(ADMA__LPSPI2, s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI2)]);
  2017. }
  2018. #endif
  2019. #if defined(ADMA__LPSPI3)
  2020. void ADMA_SPI3_INT_DriverIRQHandler(void);
  2021. void ADMA_SPI3_INT_DriverIRQHandler(void)
  2022. {
  2023. assert(s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI3)] != NULL);
  2024. LPSPI_CommonIRQHandler(ADMA__LPSPI3, s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI3)]);
  2025. }
  2026. #endif