fsl_lpspi.c 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851
  1. /*
  2. * The Clear BSD License
  3. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  4. * Copyright 2016-2017 NXP
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without modification,
  8. * are permitted (subject to the limitations in the disclaimer below) provided
  9. * that the following conditions are met:
  10. *
  11. * o Redistributions of source code must retain the above copyright notice, this list
  12. * of conditions and the following disclaimer.
  13. *
  14. * o Redistributions in binary form must reproduce the above copyright notice, this
  15. * list of conditions and the following disclaimer in the documentation and/or
  16. * other materials provided with the distribution.
  17. *
  18. * o Neither the name of the copyright holder nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  24. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  25. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  27. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #include "fsl_lpspi.h"
  35. /*******************************************************************************
  36. * Definitions
  37. ******************************************************************************/
  38. /* Component ID definition, used by tools. */
  39. #ifndef FSL_COMPONENT_ID
  40. #define FSL_COMPONENT_ID "platform.drivers.lpspi"
  41. #endif
  42. /*!
  43. * @brief Default watermark values.
  44. *
  45. * The default watermarks are set to zero.
  46. */
  47. enum _lpspi_default_watermarks
  48. {
  49. kLpspiDefaultTxWatermark = 0,
  50. kLpspiDefaultRxWatermark = 0,
  51. };
  52. /*! @brief Typedef for master interrupt handler. */
  53. typedef void (*lpspi_master_isr_t)(LPSPI_Type *base, lpspi_master_handle_t *handle);
  54. /*! @brief Typedef for slave interrupt handler. */
  55. typedef void (*lpspi_slave_isr_t)(LPSPI_Type *base, lpspi_slave_handle_t *handle);
  56. /*******************************************************************************
  57. * Prototypes
  58. ******************************************************************************/
  59. /*!
  60. * @brief Configures the LPSPI peripheral chip select polarity.
  61. *
  62. * This function takes in the desired peripheral chip select (Pcs) and it's corresponding desired polarity and
  63. * configures the Pcs signal to operate with the desired characteristic.
  64. *
  65. * @param base LPSPI peripheral address.
  66. * @param pcs The particular peripheral chip select (parameter value is of type lpspi_which_pcs_t) for which we wish to
  67. * apply the active high or active low characteristic.
  68. * @param activeLowOrHigh The setting for either "active high, inactive low (0)" or "active low, inactive high(1)" of
  69. * type lpspi_pcs_polarity_config_t.
  70. */
  71. static void LPSPI_SetOnePcsPolarity(LPSPI_Type *base,
  72. lpspi_which_pcs_t pcs,
  73. lpspi_pcs_polarity_config_t activeLowOrHigh);
  74. /*!
  75. * @brief Combine the write data for 1 byte to 4 bytes.
  76. * This is not a public API.
  77. */
  78. static uint32_t LPSPI_CombineWriteData(uint8_t *txData, uint32_t bytesEachWrite, bool isByteSwap);
  79. /*!
  80. * @brief Separate the read data for 1 byte to 4 bytes.
  81. * This is not a public API.
  82. */
  83. static void LPSPI_SeparateReadData(uint8_t *rxData, uint32_t readData, uint32_t bytesEachRead, bool isByteSwap);
  84. /*!
  85. * @brief Master fill up the TX FIFO with data.
  86. * This is not a public API.
  87. */
  88. static void LPSPI_MasterTransferFillUpTxFifo(LPSPI_Type *base, lpspi_master_handle_t *handle);
  89. /*!
  90. * @brief Master finish up a transfer.
  91. * It would call back if there is callback function and set the state to idle.
  92. * This is not a public API.
  93. */
  94. static void LPSPI_MasterTransferComplete(LPSPI_Type *base, lpspi_master_handle_t *handle);
  95. /*!
  96. * @brief Slave fill up the TX FIFO with data.
  97. * This is not a public API.
  98. */
  99. static void LPSPI_SlaveTransferFillUpTxFifo(LPSPI_Type *base, lpspi_slave_handle_t *handle);
  100. /*!
  101. * @brief Slave finish up a transfer.
  102. * It would call back if there is callback function and set the state to idle.
  103. * This is not a public API.
  104. */
  105. static void LPSPI_SlaveTransferComplete(LPSPI_Type *base, lpspi_slave_handle_t *handle);
  106. /*!
  107. * @brief LPSPI common interrupt handler.
  108. *
  109. * @param handle pointer to s_lpspiHandle which stores the transfer state.
  110. */
  111. static void LPSPI_CommonIRQHandler(LPSPI_Type *base, void *param);
  112. /*******************************************************************************
  113. * Variables
  114. ******************************************************************************/
  115. /* Defines constant value arrays for the baud rate pre-scalar and scalar divider values.*/
  116. static const uint8_t s_baudratePrescaler[] = {1, 2, 4, 8, 16, 32, 64, 128};
  117. /*! @brief Pointers to lpspi bases for each instance. */
  118. static LPSPI_Type *const s_lpspiBases[] = LPSPI_BASE_PTRS;
  119. /*! @brief Pointers to lpspi IRQ number for each instance. */
  120. static const IRQn_Type s_lpspiIRQ[] = LPSPI_IRQS;
  121. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  122. /*! @brief Pointers to lpspi clocks for each instance. */
  123. static const clock_ip_name_t s_lpspiClocks[] = LPSPI_CLOCKS;
  124. #if defined(LPSPI_PERIPH_CLOCKS)
  125. static const clock_ip_name_t s_LpspiPeriphClocks[] = LPSPI_PERIPH_CLOCKS;
  126. #endif
  127. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  128. /*! @brief Pointers to lpspi handles for each instance. */
  129. static void *s_lpspiHandle[ARRAY_SIZE(s_lpspiBases)] = {NULL};
  130. /*! @brief Pointer to master IRQ handler for each instance. */
  131. static lpspi_master_isr_t s_lpspiMasterIsr;
  132. /*! @brief Pointer to slave IRQ handler for each instance. */
  133. static lpspi_slave_isr_t s_lpspiSlaveIsr;
  134. /* @brief Dummy data for each instance. This data is used when user's tx buffer is NULL*/
  135. volatile uint8_t g_lpspiDummyData[ARRAY_SIZE(s_lpspiBases)] = {0};
  136. /**********************************************************************************************************************
  137. * Code
  138. *********************************************************************************************************************/
  139. uint32_t LPSPI_GetInstance(LPSPI_Type *base)
  140. {
  141. uint8_t instance = 0;
  142. /* Find the instance index from base address mappings. */
  143. for (instance = 0; instance < ARRAY_SIZE(s_lpspiBases); instance++)
  144. {
  145. if (s_lpspiBases[instance] == base)
  146. {
  147. break;
  148. }
  149. }
  150. assert(instance < ARRAY_SIZE(s_lpspiBases));
  151. return instance;
  152. }
  153. void LPSPI_SetDummyData(LPSPI_Type *base, uint8_t dummyData)
  154. {
  155. uint32_t instance = LPSPI_GetInstance(base);
  156. g_lpspiDummyData[instance] = dummyData;
  157. }
  158. void LPSPI_MasterInit(LPSPI_Type *base, const lpspi_master_config_t *masterConfig, uint32_t srcClock_Hz)
  159. {
  160. assert(masterConfig);
  161. uint32_t tcrPrescaleValue = 0;
  162. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  163. uint32_t instance = LPSPI_GetInstance(base);
  164. /* Enable LPSPI clock */
  165. CLOCK_EnableClock(s_lpspiClocks[instance]);
  166. #if defined(LPSPI_PERIPH_CLOCKS)
  167. CLOCK_EnableClock(s_LpspiPeriphClocks[instance]);
  168. #endif
  169. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  170. /* Reset to known status */
  171. LPSPI_Reset(base);
  172. /* Set LPSPI to master */
  173. LPSPI_SetMasterSlaveMode(base, kLPSPI_Master);
  174. /* Set specific PCS to active high or low */
  175. LPSPI_SetOnePcsPolarity(base, masterConfig->whichPcs, masterConfig->pcsActiveHighOrLow);
  176. /* Set Configuration Register 1 related setting.*/
  177. base->CFGR1 = (base->CFGR1 & ~(LPSPI_CFGR1_OUTCFG_MASK | LPSPI_CFGR1_PINCFG_MASK | LPSPI_CFGR1_NOSTALL_MASK)) |
  178. LPSPI_CFGR1_OUTCFG(masterConfig->dataOutConfig) | LPSPI_CFGR1_PINCFG(masterConfig->pinCfg) |
  179. LPSPI_CFGR1_NOSTALL(0);
  180. /* Set baudrate and delay times*/
  181. LPSPI_MasterSetBaudRate(base, masterConfig->baudRate, srcClock_Hz, &tcrPrescaleValue);
  182. /* Set default watermarks */
  183. LPSPI_SetFifoWatermarks(base, kLpspiDefaultTxWatermark, kLpspiDefaultRxWatermark);
  184. /* Set Transmit Command Register*/
  185. base->TCR = LPSPI_TCR_CPOL(masterConfig->cpol) | LPSPI_TCR_CPHA(masterConfig->cpha) |
  186. LPSPI_TCR_LSBF(masterConfig->direction) | LPSPI_TCR_FRAMESZ(masterConfig->bitsPerFrame - 1) |
  187. LPSPI_TCR_PRESCALE(tcrPrescaleValue) | LPSPI_TCR_PCS(masterConfig->whichPcs);
  188. LPSPI_Enable(base, true);
  189. LPSPI_MasterSetDelayTimes(base, masterConfig->pcsToSckDelayInNanoSec, kLPSPI_PcsToSck, srcClock_Hz);
  190. LPSPI_MasterSetDelayTimes(base, masterConfig->lastSckToPcsDelayInNanoSec, kLPSPI_LastSckToPcs, srcClock_Hz);
  191. LPSPI_MasterSetDelayTimes(base, masterConfig->betweenTransferDelayInNanoSec, kLPSPI_BetweenTransfer, srcClock_Hz);
  192. LPSPI_SetDummyData(base, LPSPI_DUMMY_DATA);
  193. }
  194. void LPSPI_MasterGetDefaultConfig(lpspi_master_config_t *masterConfig)
  195. {
  196. assert(masterConfig);
  197. masterConfig->baudRate = 500000;
  198. masterConfig->bitsPerFrame = 8;
  199. masterConfig->cpol = kLPSPI_ClockPolarityActiveHigh;
  200. masterConfig->cpha = kLPSPI_ClockPhaseFirstEdge;
  201. masterConfig->direction = kLPSPI_MsbFirst;
  202. masterConfig->pcsToSckDelayInNanoSec = 1000000000 / masterConfig->baudRate * 2;
  203. masterConfig->lastSckToPcsDelayInNanoSec = 1000000000 / masterConfig->baudRate * 2;
  204. masterConfig->betweenTransferDelayInNanoSec = 1000000000 / masterConfig->baudRate * 2;
  205. masterConfig->whichPcs = kLPSPI_Pcs0;
  206. masterConfig->pcsActiveHighOrLow = kLPSPI_PcsActiveLow;
  207. masterConfig->pinCfg = kLPSPI_SdiInSdoOut;
  208. masterConfig->dataOutConfig = kLpspiDataOutRetained;
  209. }
  210. void LPSPI_SlaveInit(LPSPI_Type *base, const lpspi_slave_config_t *slaveConfig)
  211. {
  212. assert(slaveConfig);
  213. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  214. uint32_t instance = LPSPI_GetInstance(base);
  215. /* Enable LPSPI clock */
  216. CLOCK_EnableClock(s_lpspiClocks[instance]);
  217. #if defined(LPSPI_PERIPH_CLOCKS)
  218. CLOCK_EnableClock(s_LpspiPeriphClocks[instance]);
  219. #endif
  220. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  221. /* Reset to known status */
  222. LPSPI_Reset(base);
  223. LPSPI_SetMasterSlaveMode(base, kLPSPI_Slave);
  224. LPSPI_SetOnePcsPolarity(base, slaveConfig->whichPcs, slaveConfig->pcsActiveHighOrLow);
  225. base->CFGR1 = (base->CFGR1 & ~(LPSPI_CFGR1_OUTCFG_MASK | LPSPI_CFGR1_PINCFG_MASK)) |
  226. LPSPI_CFGR1_OUTCFG(slaveConfig->dataOutConfig) | LPSPI_CFGR1_PINCFG(slaveConfig->pinCfg);
  227. LPSPI_SetFifoWatermarks(base, kLpspiDefaultTxWatermark, kLpspiDefaultRxWatermark);
  228. base->TCR = LPSPI_TCR_CPOL(slaveConfig->cpol) | LPSPI_TCR_CPHA(slaveConfig->cpha) |
  229. LPSPI_TCR_LSBF(slaveConfig->direction) | LPSPI_TCR_FRAMESZ(slaveConfig->bitsPerFrame - 1);
  230. /* This operation will set the dummy data for edma transfer, no effect in interrupt way. */
  231. LPSPI_SetDummyData(base, LPSPI_DUMMY_DATA);
  232. LPSPI_Enable(base, true);
  233. }
  234. void LPSPI_SlaveGetDefaultConfig(lpspi_slave_config_t *slaveConfig)
  235. {
  236. assert(slaveConfig);
  237. slaveConfig->bitsPerFrame = 8; /*!< Bits per frame, minimum 8, maximum 4096.*/
  238. slaveConfig->cpol = kLPSPI_ClockPolarityActiveHigh; /*!< Clock polarity. */
  239. slaveConfig->cpha = kLPSPI_ClockPhaseFirstEdge; /*!< Clock phase. */
  240. slaveConfig->direction = kLPSPI_MsbFirst; /*!< MSB or LSB data shift direction. */
  241. slaveConfig->whichPcs = kLPSPI_Pcs0; /*!< Desired Peripheral Chip Select (pcs) */
  242. slaveConfig->pcsActiveHighOrLow = kLPSPI_PcsActiveLow; /*!< Desired PCS active high or low */
  243. slaveConfig->pinCfg = kLPSPI_SdiInSdoOut;
  244. slaveConfig->dataOutConfig = kLpspiDataOutRetained;
  245. }
  246. void LPSPI_Reset(LPSPI_Type *base)
  247. {
  248. /* Reset all internal logic and registers, except the Control Register. Remains set until cleared by software.*/
  249. base->CR |= LPSPI_CR_RST_MASK;
  250. /* Software reset doesn't reset the CR, so manual reset the FIFOs */
  251. base->CR |= LPSPI_CR_RRF_MASK | LPSPI_CR_RTF_MASK;
  252. /* Master logic is not reset and module is disabled.*/
  253. base->CR = 0x00U;
  254. }
  255. void LPSPI_Deinit(LPSPI_Type *base)
  256. {
  257. /* Reset to default value */
  258. LPSPI_Reset(base);
  259. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  260. uint32_t instance = LPSPI_GetInstance(base);
  261. /* Enable LPSPI clock */
  262. CLOCK_DisableClock(s_lpspiClocks[instance]);
  263. #if defined(LPSPI_PERIPH_CLOCKS)
  264. CLOCK_DisableClock(s_LpspiPeriphClocks[instance]);
  265. #endif
  266. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  267. }
  268. static void LPSPI_SetOnePcsPolarity(LPSPI_Type *base,
  269. lpspi_which_pcs_t pcs,
  270. lpspi_pcs_polarity_config_t activeLowOrHigh)
  271. {
  272. uint32_t cfgr1Value = 0;
  273. /* Clear the PCS polarity bit */
  274. cfgr1Value = base->CFGR1 & ~(1U << (LPSPI_CFGR1_PCSPOL_SHIFT + pcs));
  275. /* Configure the PCS polarity bit according to the activeLowOrHigh setting */
  276. base->CFGR1 = cfgr1Value | ((uint32_t)activeLowOrHigh << (LPSPI_CFGR1_PCSPOL_SHIFT + pcs));
  277. }
  278. uint32_t LPSPI_MasterSetBaudRate(LPSPI_Type *base,
  279. uint32_t baudRate_Bps,
  280. uint32_t srcClock_Hz,
  281. uint32_t *tcrPrescaleValue)
  282. {
  283. assert(tcrPrescaleValue);
  284. /* For master mode configuration only, if slave mode detected, return 0.
  285. * Also, the LPSPI module needs to be disabled first, if enabled, return 0
  286. */
  287. if ((!LPSPI_IsMaster(base)) || (base->CR & LPSPI_CR_MEN_MASK))
  288. {
  289. return 0;
  290. }
  291. uint32_t prescaler, bestPrescaler;
  292. uint32_t scaler, bestScaler;
  293. uint32_t realBaudrate, bestBaudrate;
  294. uint32_t diff, min_diff;
  295. uint32_t desiredBaudrate = baudRate_Bps;
  296. /* find combination of prescaler and scaler resulting in baudrate closest to the
  297. * requested value
  298. */
  299. min_diff = 0xFFFFFFFFU;
  300. /* Set to maximum divisor value bit settings so that if baud rate passed in is less
  301. * than the minimum possible baud rate, then the SPI will be configured to the lowest
  302. * possible baud rate
  303. */
  304. bestPrescaler = 7;
  305. bestScaler = 255;
  306. bestBaudrate = 0; /* required to avoid compilation warning */
  307. /* In all for loops, if min_diff = 0, the exit for loop*/
  308. for (prescaler = 0; (prescaler < 8) && min_diff; prescaler++)
  309. {
  310. for (scaler = 0; (scaler < 256) && min_diff; scaler++)
  311. {
  312. realBaudrate = (srcClock_Hz / (s_baudratePrescaler[prescaler] * (scaler + 2U)));
  313. /* calculate the baud rate difference based on the conditional statement
  314. * that states that the calculated baud rate must not exceed the desired baud rate
  315. */
  316. if (desiredBaudrate >= realBaudrate)
  317. {
  318. diff = desiredBaudrate - realBaudrate;
  319. if (min_diff > diff)
  320. {
  321. /* a better match found */
  322. min_diff = diff;
  323. bestPrescaler = prescaler;
  324. bestScaler = scaler;
  325. bestBaudrate = realBaudrate;
  326. }
  327. }
  328. }
  329. }
  330. /* Write the best baud rate scalar to the CCR.
  331. * Note, no need to check for error since we've already checked to make sure the module is
  332. * disabled and in master mode. Also, there is a limit on the maximum divider so we will not
  333. * exceed this.
  334. */
  335. base->CCR = (base->CCR & ~LPSPI_CCR_SCKDIV_MASK) | LPSPI_CCR_SCKDIV(bestScaler);
  336. /* return the best prescaler value for user to use later */
  337. *tcrPrescaleValue = bestPrescaler;
  338. /* return the actual calculated baud rate */
  339. return bestBaudrate;
  340. }
  341. void LPSPI_MasterSetDelayScaler(LPSPI_Type *base, uint32_t scaler, lpspi_delay_type_t whichDelay)
  342. {
  343. /*These settings are only relevant in master mode */
  344. switch (whichDelay)
  345. {
  346. case kLPSPI_PcsToSck:
  347. base->CCR = (base->CCR & (~LPSPI_CCR_PCSSCK_MASK)) | LPSPI_CCR_PCSSCK(scaler);
  348. break;
  349. case kLPSPI_LastSckToPcs:
  350. base->CCR = (base->CCR & (~LPSPI_CCR_SCKPCS_MASK)) | LPSPI_CCR_SCKPCS(scaler);
  351. break;
  352. case kLPSPI_BetweenTransfer:
  353. base->CCR = (base->CCR & (~LPSPI_CCR_DBT_MASK)) | LPSPI_CCR_DBT(scaler);
  354. break;
  355. default:
  356. assert(false);
  357. break;
  358. }
  359. }
  360. uint32_t LPSPI_MasterSetDelayTimes(LPSPI_Type *base,
  361. uint32_t delayTimeInNanoSec,
  362. lpspi_delay_type_t whichDelay,
  363. uint32_t srcClock_Hz)
  364. {
  365. uint64_t realDelay, bestDelay;
  366. uint32_t scaler, bestScaler;
  367. uint32_t diff, min_diff;
  368. uint64_t initialDelayNanoSec;
  369. uint32_t clockDividedPrescaler;
  370. /* For delay between transfer, an additional scaler value is needed */
  371. uint32_t additionalScaler = 0;
  372. /*As the RM note, the LPSPI baud rate clock is itself divided by the PRESCALE setting, which can vary between
  373. * transfers.*/
  374. clockDividedPrescaler =
  375. srcClock_Hz / s_baudratePrescaler[(base->TCR & LPSPI_TCR_PRESCALE_MASK) >> LPSPI_TCR_PRESCALE_SHIFT];
  376. /* Find combination of prescaler and scaler resulting in the delay closest to the requested value.*/
  377. min_diff = 0xFFFFFFFFU;
  378. /* Initialize scaler to max value to generate the max delay */
  379. bestScaler = 0xFFU;
  380. /* Calculate the initial (min) delay and maximum possible delay based on the specific delay as
  381. * the delay divisors are slightly different based on which delay we are configuring.
  382. */
  383. if (whichDelay == kLPSPI_BetweenTransfer)
  384. {
  385. /* First calculate the initial, default delay, note min delay is 2 clock cycles. Due to large size of
  386. calculated values (uint64_t), we need to break up the calculation into several steps to ensure
  387. accurate calculated results
  388. */
  389. initialDelayNanoSec = 1000000000U;
  390. initialDelayNanoSec *= 2U;
  391. initialDelayNanoSec /= clockDividedPrescaler;
  392. /* Calculate the maximum delay */
  393. bestDelay = 1000000000U;
  394. bestDelay *= 257U; /* based on DBT+2, or 255 + 2 */
  395. bestDelay /= clockDividedPrescaler;
  396. additionalScaler = 1U;
  397. }
  398. else
  399. {
  400. /* First calculate the initial, default delay, min delay is 1 clock cycle. Due to large size of calculated
  401. values (uint64_t), we need to break up the calculation into several steps to ensure accurate calculated
  402. results.
  403. */
  404. initialDelayNanoSec = 1000000000U;
  405. initialDelayNanoSec /= clockDividedPrescaler;
  406. /* Calculate the maximum delay */
  407. bestDelay = 1000000000U;
  408. bestDelay *= 256U; /* based on SCKPCS+1 or PCSSCK+1, or 255 + 1 */
  409. bestDelay /= clockDividedPrescaler;
  410. additionalScaler = 0;
  411. }
  412. /* If the initial, default delay is already greater than the desired delay, then
  413. * set the delay to their initial value (0) and return the delay. In other words,
  414. * there is no way to decrease the delay value further.
  415. */
  416. if (initialDelayNanoSec >= delayTimeInNanoSec)
  417. {
  418. LPSPI_MasterSetDelayScaler(base, 0, whichDelay);
  419. return initialDelayNanoSec;
  420. }
  421. /* If min_diff = 0, the exit for loop */
  422. for (scaler = 0; (scaler < 256U) && min_diff; scaler++)
  423. {
  424. /* Calculate the real delay value as we cycle through the scaler values.
  425. Due to large size of calculated values (uint64_t), we need to break up the
  426. calculation into several steps to ensure accurate calculated results
  427. */
  428. realDelay = 1000000000U;
  429. realDelay *= (scaler + 1 + additionalScaler);
  430. realDelay /= clockDividedPrescaler;
  431. /* calculate the delay difference based on the conditional statement
  432. * that states that the calculated delay must not be less then the desired delay
  433. */
  434. if (realDelay >= delayTimeInNanoSec)
  435. {
  436. diff = realDelay - delayTimeInNanoSec;
  437. if (min_diff > diff)
  438. {
  439. /* a better match found */
  440. min_diff = diff;
  441. bestScaler = scaler;
  442. bestDelay = realDelay;
  443. }
  444. }
  445. }
  446. /* write the best scaler value for the delay */
  447. LPSPI_MasterSetDelayScaler(base, bestScaler, whichDelay);
  448. /* return the actual calculated delay value (in ns) */
  449. return bestDelay;
  450. }
  451. /*Transactional APIs -- Master*/
  452. void LPSPI_MasterTransferCreateHandle(LPSPI_Type *base,
  453. lpspi_master_handle_t *handle,
  454. lpspi_master_transfer_callback_t callback,
  455. void *userData)
  456. {
  457. assert(handle);
  458. /* Zero the handle. */
  459. memset(handle, 0, sizeof(*handle));
  460. s_lpspiHandle[LPSPI_GetInstance(base)] = handle;
  461. /* Set irq handler. */
  462. s_lpspiMasterIsr = LPSPI_MasterTransferHandleIRQ;
  463. handle->callback = callback;
  464. handle->userData = userData;
  465. }
  466. bool LPSPI_CheckTransferArgument(lpspi_transfer_t *transfer, uint32_t bitsPerFrame, uint32_t bytesPerFrame)
  467. {
  468. assert(transfer);
  469. /* If the transfer count is zero, then return immediately.*/
  470. if (transfer->dataSize == 0)
  471. {
  472. return false;
  473. }
  474. /* If both send buffer and receive buffer is null */
  475. if ((!(transfer->txData)) && (!(transfer->rxData)))
  476. {
  477. return false;
  478. }
  479. /*The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4 .
  480. *For bytesPerFrame greater than 4 situation:
  481. *the transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not integer multiples of 4 ,
  482. *otherwise , the transfer data size can be integer multiples of bytesPerFrame.
  483. */
  484. if (bytesPerFrame <= 4)
  485. {
  486. if ((transfer->dataSize % bytesPerFrame) != 0)
  487. {
  488. return false;
  489. }
  490. }
  491. else
  492. {
  493. if ((bytesPerFrame % 4U) != 0)
  494. {
  495. if (transfer->dataSize != bytesPerFrame)
  496. {
  497. return false;
  498. }
  499. }
  500. else
  501. {
  502. if ((transfer->dataSize % bytesPerFrame) != 0)
  503. {
  504. return false;
  505. }
  506. }
  507. }
  508. return true;
  509. }
  510. status_t LPSPI_MasterTransferBlocking(LPSPI_Type *base, lpspi_transfer_t *transfer)
  511. {
  512. assert(transfer);
  513. uint32_t bitsPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) + 1;
  514. uint32_t bytesPerFrame = (bitsPerFrame + 7) / 8;
  515. uint32_t temp = 0U;
  516. uint8_t dummyData = g_lpspiDummyData[LPSPI_GetInstance(base)];
  517. if (!LPSPI_CheckTransferArgument(transfer, bitsPerFrame, bytesPerFrame))
  518. {
  519. return kStatus_InvalidArgument;
  520. }
  521. /* Check that LPSPI is not busy.*/
  522. if (LPSPI_GetStatusFlags(base) & kLPSPI_ModuleBusyFlag)
  523. {
  524. return kStatus_LPSPI_Busy;
  525. }
  526. uint8_t *txData = transfer->txData;
  527. uint8_t *rxData = transfer->rxData;
  528. uint32_t txRemainingByteCount = transfer->dataSize;
  529. uint32_t rxRemainingByteCount = transfer->dataSize;
  530. uint8_t bytesEachWrite;
  531. uint8_t bytesEachRead;
  532. uint32_t readData = 0;
  533. uint32_t wordToSend =
  534. ((uint32_t)dummyData) | ((uint32_t)dummyData << 8) | ((uint32_t)dummyData << 16) | ((uint32_t)dummyData << 24);
  535. /*The TX and RX FIFO sizes are always the same*/
  536. uint32_t fifoSize = LPSPI_GetRxFifoSize(base);
  537. uint32_t whichPcs = (transfer->configFlags & LPSPI_MASTER_PCS_MASK) >> LPSPI_MASTER_PCS_SHIFT;
  538. bool isPcsContinuous = (bool)(transfer->configFlags & kLPSPI_MasterPcsContinuous);
  539. bool isRxMask = false;
  540. bool isByteSwap = (bool)(transfer->configFlags & kLPSPI_MasterByteSwap);
  541. LPSPI_FlushFifo(base, true, true);
  542. LPSPI_ClearStatusFlags(base, kLPSPI_AllStatusFlag);
  543. if (!rxData)
  544. {
  545. isRxMask = true;
  546. }
  547. LPSPI_Enable(base, false);
  548. base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
  549. /* Check if using 3-wire mode and the txData is NULL, set the output pin to tristated. */
  550. temp = base->CFGR1;
  551. temp &= LPSPI_CFGR1_PINCFG_MASK;
  552. if ((temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdiInSdiOut)) || (temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdoInSdoOut)))
  553. {
  554. if (!txData)
  555. {
  556. base->CFGR1 |= LPSPI_CFGR1_OUTCFG_MASK;
  557. }
  558. /* The 3-wire mode can't send and receive data at the same time. */
  559. if ((txData) && (rxData))
  560. {
  561. return kStatus_InvalidArgument;
  562. }
  563. }
  564. LPSPI_Enable(base, true);
  565. base->TCR =
  566. (base->TCR & ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK | LPSPI_TCR_PCS_MASK)) |
  567. LPSPI_TCR_CONT(isPcsContinuous) | LPSPI_TCR_CONTC(0) | LPSPI_TCR_RXMSK(isRxMask) | LPSPI_TCR_PCS(whichPcs);
  568. if (bytesPerFrame <= 4)
  569. {
  570. bytesEachWrite = bytesPerFrame;
  571. bytesEachRead = bytesPerFrame;
  572. }
  573. else
  574. {
  575. bytesEachWrite = 4;
  576. bytesEachRead = 4;
  577. }
  578. /*Write the TX data until txRemainingByteCount is equal to 0 */
  579. while (txRemainingByteCount > 0)
  580. {
  581. if (txRemainingByteCount < bytesEachWrite)
  582. {
  583. bytesEachWrite = txRemainingByteCount;
  584. }
  585. /*Wait until TX FIFO is not full*/
  586. while (LPSPI_GetTxFifoCount(base) == fifoSize)
  587. {
  588. }
  589. if (txData)
  590. {
  591. wordToSend = LPSPI_CombineWriteData(txData, bytesEachWrite, isByteSwap);
  592. txData += bytesEachWrite;
  593. }
  594. LPSPI_WriteData(base, wordToSend);
  595. txRemainingByteCount -= bytesEachWrite;
  596. /*Check whether there is RX data in RX FIFO . Read out the RX data so that the RX FIFO would not overrun.*/
  597. if (rxData)
  598. {
  599. while (LPSPI_GetRxFifoCount(base))
  600. {
  601. readData = LPSPI_ReadData(base);
  602. if (rxRemainingByteCount < bytesEachRead)
  603. {
  604. bytesEachRead = rxRemainingByteCount;
  605. }
  606. LPSPI_SeparateReadData(rxData, readData, bytesEachRead, isByteSwap);
  607. rxData += bytesEachRead;
  608. rxRemainingByteCount -= bytesEachRead;
  609. }
  610. }
  611. }
  612. /* After write all the data in TX FIFO , should write the TCR_CONTC to 0 to de-assert the PCS. Note that TCR
  613. * register also use the TX FIFO.
  614. */
  615. while ((LPSPI_GetTxFifoCount(base) == fifoSize))
  616. {
  617. }
  618. base->TCR = (base->TCR & ~(LPSPI_TCR_CONTC_MASK));
  619. /*Read out the RX data in FIFO*/
  620. if (rxData)
  621. {
  622. while (rxRemainingByteCount > 0)
  623. {
  624. while (LPSPI_GetRxFifoCount(base))
  625. {
  626. readData = LPSPI_ReadData(base);
  627. if (rxRemainingByteCount < bytesEachRead)
  628. {
  629. bytesEachRead = rxRemainingByteCount;
  630. }
  631. LPSPI_SeparateReadData(rxData, readData, bytesEachRead, isByteSwap);
  632. rxData += bytesEachRead;
  633. rxRemainingByteCount -= bytesEachRead;
  634. }
  635. }
  636. }
  637. else
  638. {
  639. /* If no RX buffer, then transfer is not complete until transfer complete flag sets */
  640. while (!(LPSPI_GetStatusFlags(base) & kLPSPI_TransferCompleteFlag))
  641. {
  642. }
  643. }
  644. return kStatus_Success;
  645. }
  646. status_t LPSPI_MasterTransferNonBlocking(LPSPI_Type *base, lpspi_master_handle_t *handle, lpspi_transfer_t *transfer)
  647. {
  648. assert(handle);
  649. assert(transfer);
  650. uint32_t bitsPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) + 1;
  651. uint32_t bytesPerFrame = (bitsPerFrame + 7) / 8;
  652. uint32_t temp = 0U;
  653. uint8_t dummyData = g_lpspiDummyData[LPSPI_GetInstance(base)];
  654. if (!LPSPI_CheckTransferArgument(transfer, bitsPerFrame, bytesPerFrame))
  655. {
  656. return kStatus_InvalidArgument;
  657. }
  658. /* Check that we're not busy.*/
  659. if (handle->state == kLPSPI_Busy)
  660. {
  661. return kStatus_LPSPI_Busy;
  662. }
  663. handle->state = kLPSPI_Busy;
  664. bool isRxMask = false;
  665. uint8_t txWatermark;
  666. uint32_t whichPcs = (transfer->configFlags & LPSPI_MASTER_PCS_MASK) >> LPSPI_MASTER_PCS_SHIFT;
  667. handle->txData = transfer->txData;
  668. handle->rxData = transfer->rxData;
  669. handle->txRemainingByteCount = transfer->dataSize;
  670. handle->rxRemainingByteCount = transfer->dataSize;
  671. handle->totalByteCount = transfer->dataSize;
  672. handle->writeTcrInIsr = false;
  673. handle->writeRegRemainingTimes = (transfer->dataSize / bytesPerFrame) * ((bytesPerFrame + 3) / 4);
  674. handle->readRegRemainingTimes = handle->writeRegRemainingTimes;
  675. handle->txBuffIfNull =
  676. ((uint32_t)dummyData) | ((uint32_t)dummyData << 8) | ((uint32_t)dummyData << 16) | ((uint32_t)dummyData << 24);
  677. /*The TX and RX FIFO sizes are always the same*/
  678. handle->fifoSize = LPSPI_GetRxFifoSize(base);
  679. handle->isPcsContinuous = (bool)(transfer->configFlags & kLPSPI_MasterPcsContinuous);
  680. handle->isByteSwap = (bool)(transfer->configFlags & kLPSPI_MasterByteSwap);
  681. /*Set the RX and TX watermarks to reduce the ISR times.*/
  682. if (handle->fifoSize > 1)
  683. {
  684. txWatermark = 1;
  685. handle->rxWatermark = handle->fifoSize - 2;
  686. }
  687. else
  688. {
  689. txWatermark = 0;
  690. handle->rxWatermark = 0;
  691. }
  692. LPSPI_SetFifoWatermarks(base, txWatermark, handle->rxWatermark);
  693. LPSPI_Enable(base, false);
  694. /*Transfers will stall when transmit FIFO is empty or receive FIFO is full. */
  695. base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
  696. /* Check if using 3-wire mode and the txData is NULL, set the output pin to tristated. */
  697. temp = base->CFGR1;
  698. temp &= LPSPI_CFGR1_PINCFG_MASK;
  699. if ((temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdiInSdiOut)) || (temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdoInSdoOut)))
  700. {
  701. if (!handle->txData)
  702. {
  703. base->CFGR1 |= LPSPI_CFGR1_OUTCFG_MASK;
  704. }
  705. /* The 3-wire mode can't send and receive data at the same time. */
  706. if ((handle->txData) && (handle->rxData))
  707. {
  708. return kStatus_InvalidArgument;
  709. }
  710. }
  711. LPSPI_Enable(base, true);
  712. /*Flush FIFO , clear status , disable all the inerrupts.*/
  713. LPSPI_FlushFifo(base, true, true);
  714. LPSPI_ClearStatusFlags(base, kLPSPI_AllStatusFlag);
  715. LPSPI_DisableInterrupts(base, kLPSPI_AllInterruptEnable);
  716. /* If there is not rxData , can mask the receive data (receive data is not stored in receive FIFO).
  717. * For master transfer , we'd better not masked the transmit data in TCR since the transfer flow is hard to
  718. * controlled by software.*/
  719. if (handle->rxData == NULL)
  720. {
  721. isRxMask = true;
  722. handle->rxRemainingByteCount = 0;
  723. }
  724. base->TCR =
  725. (base->TCR & ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK | LPSPI_TCR_PCS_MASK)) |
  726. LPSPI_TCR_CONT(handle->isPcsContinuous) | LPSPI_TCR_CONTC(0) | LPSPI_TCR_RXMSK(isRxMask) |
  727. LPSPI_TCR_PCS(whichPcs);
  728. /*Calculate the bytes for write/read the TX/RX register each time*/
  729. if (bytesPerFrame <= 4)
  730. {
  731. handle->bytesEachWrite = bytesPerFrame;
  732. handle->bytesEachRead = bytesPerFrame;
  733. }
  734. else
  735. {
  736. handle->bytesEachWrite = 4;
  737. handle->bytesEachRead = 4;
  738. }
  739. /* Enable the NVIC for LPSPI peripheral. Note that below code is useless if the LPSPI interrupt is in INTMUX ,
  740. * and you should also enable the INTMUX interupt in your application.
  741. */
  742. EnableIRQ(s_lpspiIRQ[LPSPI_GetInstance(base)]);
  743. /*TCR is also shared the FIFO , so wait for TCR written.*/
  744. while (LPSPI_GetTxFifoCount(base) != 0)
  745. {
  746. }
  747. /*Fill up the TX data in FIFO */
  748. LPSPI_MasterTransferFillUpTxFifo(base, handle);
  749. /* Since SPI is a synchronous interface, we only need to enable the RX interrupt if there is RX data.
  750. * The IRQ handler will get the status of RX and TX interrupt flags.
  751. */
  752. if (handle->rxData)
  753. {
  754. /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise there
  755. *is not RX interrupt for the last datas because the RX count is not greater than rxWatermark.
  756. */
  757. if ((handle->readRegRemainingTimes) <= handle->rxWatermark)
  758. {
  759. base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) | LPSPI_FCR_RXWATER(handle->readRegRemainingTimes - 1);
  760. }
  761. LPSPI_EnableInterrupts(base, kLPSPI_RxInterruptEnable);
  762. }
  763. else
  764. {
  765. LPSPI_EnableInterrupts(base, kLPSPI_TxInterruptEnable);
  766. }
  767. return kStatus_Success;
  768. }
  769. static void LPSPI_MasterTransferFillUpTxFifo(LPSPI_Type *base, lpspi_master_handle_t *handle)
  770. {
  771. assert(handle);
  772. uint32_t wordToSend = 0;
  773. /* Make sure the difference in remaining TX and RX byte counts does not exceed FIFO depth
  774. * and that the number of TX FIFO entries does not exceed the FIFO depth.
  775. * But no need to make the protection if there is no rxData.
  776. */
  777. while ((LPSPI_GetTxFifoCount(base) < (handle->fifoSize)) &&
  778. (((handle->readRegRemainingTimes - handle->writeRegRemainingTimes) < handle->fifoSize) ||
  779. (handle->rxData == NULL)))
  780. {
  781. if (handle->txRemainingByteCount < handle->bytesEachWrite)
  782. {
  783. handle->bytesEachWrite = handle->txRemainingByteCount;
  784. }
  785. if (handle->txData)
  786. {
  787. wordToSend = LPSPI_CombineWriteData(handle->txData, handle->bytesEachWrite, handle->isByteSwap);
  788. handle->txData += handle->bytesEachWrite;
  789. }
  790. else
  791. {
  792. wordToSend = handle->txBuffIfNull;
  793. }
  794. /*Write the word to TX register*/
  795. LPSPI_WriteData(base, wordToSend);
  796. /*Decrease the write TX register times.*/
  797. --handle->writeRegRemainingTimes;
  798. /*Decrease the remaining TX byte count.*/
  799. handle->txRemainingByteCount -= handle->bytesEachWrite;
  800. if (handle->txRemainingByteCount == 0)
  801. {
  802. /* If PCS is continuous, update TCR to de-assert PCS */
  803. if (handle->isPcsContinuous)
  804. {
  805. /* Only write to the TCR if the FIFO has room */
  806. if ((LPSPI_GetTxFifoCount(base) < (handle->fifoSize)))
  807. {
  808. base->TCR = (base->TCR & ~(LPSPI_TCR_CONTC_MASK));
  809. handle->writeTcrInIsr = false;
  810. }
  811. /* Else, set a global flag to tell the ISR to do write to the TCR */
  812. else
  813. {
  814. handle->writeTcrInIsr = true;
  815. }
  816. }
  817. break;
  818. }
  819. }
  820. }
  821. static void LPSPI_MasterTransferComplete(LPSPI_Type *base, lpspi_master_handle_t *handle)
  822. {
  823. assert(handle);
  824. /* Disable interrupt requests*/
  825. LPSPI_DisableInterrupts(base, kLPSPI_AllInterruptEnable);
  826. handle->state = kLPSPI_Idle;
  827. if (handle->callback)
  828. {
  829. handle->callback(base, handle, kStatus_Success, handle->userData);
  830. }
  831. }
  832. status_t LPSPI_MasterTransferGetCount(LPSPI_Type *base, lpspi_master_handle_t *handle, size_t *count)
  833. {
  834. assert(handle);
  835. if (!count)
  836. {
  837. return kStatus_InvalidArgument;
  838. }
  839. /* Catch when there is not an active transfer. */
  840. if (handle->state != kLPSPI_Busy)
  841. {
  842. *count = 0;
  843. return kStatus_NoTransferInProgress;
  844. }
  845. size_t remainingByte;
  846. if (handle->rxData)
  847. {
  848. remainingByte = handle->rxRemainingByteCount;
  849. }
  850. else
  851. {
  852. remainingByte = handle->txRemainingByteCount;
  853. }
  854. *count = handle->totalByteCount - remainingByte;
  855. return kStatus_Success;
  856. }
  857. void LPSPI_MasterTransferAbort(LPSPI_Type *base, lpspi_master_handle_t *handle)
  858. {
  859. assert(handle);
  860. /* Disable interrupt requests*/
  861. LPSPI_DisableInterrupts(base, kLPSPI_AllInterruptEnable);
  862. LPSPI_Reset(base);
  863. handle->state = kLPSPI_Idle;
  864. handle->txRemainingByteCount = 0;
  865. handle->rxRemainingByteCount = 0;
  866. }
  867. void LPSPI_MasterTransferHandleIRQ(LPSPI_Type *base, lpspi_master_handle_t *handle)
  868. {
  869. assert(handle);
  870. uint32_t readData;
  871. if (handle->rxData != NULL)
  872. {
  873. if (handle->rxRemainingByteCount)
  874. {
  875. /* First, disable the interrupts to avoid potentially triggering another interrupt
  876. * while reading out the RX FIFO as more data may be coming into the RX FIFO. We'll
  877. * re-enable the interrupts based on the LPSPI state after reading out the FIFO.
  878. */
  879. LPSPI_DisableInterrupts(base, kLPSPI_RxInterruptEnable);
  880. while ((LPSPI_GetRxFifoCount(base)) && (handle->rxRemainingByteCount))
  881. {
  882. /*Read out the data*/
  883. readData = LPSPI_ReadData(base);
  884. /*Decrease the read RX register times.*/
  885. --handle->readRegRemainingTimes;
  886. if (handle->rxRemainingByteCount < handle->bytesEachRead)
  887. {
  888. handle->bytesEachRead = handle->rxRemainingByteCount;
  889. }
  890. LPSPI_SeparateReadData(handle->rxData, readData, handle->bytesEachRead, handle->isByteSwap);
  891. handle->rxData += handle->bytesEachRead;
  892. /*Decrease the remaining RX byte count.*/
  893. handle->rxRemainingByteCount -= handle->bytesEachRead;
  894. }
  895. /* Re-enable the interrupts only if rxCount indicates there is more data to receive,
  896. * else we may get a spurious interrupt.
  897. * */
  898. if (handle->rxRemainingByteCount)
  899. {
  900. /* Set the TDF and RDF interrupt enables simultaneously to avoid race conditions */
  901. LPSPI_EnableInterrupts(base, kLPSPI_RxInterruptEnable);
  902. }
  903. }
  904. /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise there
  905. *is not RX interrupt for the last datas because the RX count is not greater than rxWatermark.
  906. */
  907. if ((handle->readRegRemainingTimes) <= (handle->rxWatermark))
  908. {
  909. base->FCR =
  910. (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) |
  911. LPSPI_FCR_RXWATER((handle->readRegRemainingTimes > 1) ? (handle->readRegRemainingTimes - 1U) : (0U));
  912. }
  913. }
  914. if (handle->txRemainingByteCount)
  915. {
  916. LPSPI_MasterTransferFillUpTxFifo(base, handle);
  917. }
  918. else
  919. {
  920. if ((LPSPI_GetTxFifoCount(base) < (handle->fifoSize)))
  921. {
  922. if ((handle->isPcsContinuous) && (handle->writeTcrInIsr))
  923. {
  924. base->TCR = (base->TCR & ~(LPSPI_TCR_CONTC_MASK));
  925. handle->writeTcrInIsr = false;
  926. }
  927. }
  928. }
  929. if ((handle->txRemainingByteCount == 0) && (handle->rxRemainingByteCount == 0) && (!handle->writeTcrInIsr))
  930. {
  931. /* If no RX buffer, then transfer is not complete until transfer complete flag sets */
  932. if (handle->rxData == NULL)
  933. {
  934. if (LPSPI_GetStatusFlags(base) & kLPSPI_TransferCompleteFlag)
  935. {
  936. /* Complete the transfer and disable the interrupts */
  937. LPSPI_MasterTransferComplete(base, handle);
  938. }
  939. else
  940. {
  941. LPSPI_EnableInterrupts(base, kLPSPI_TransferCompleteInterruptEnable);
  942. LPSPI_DisableInterrupts(base, kLPSPI_TxInterruptEnable | kLPSPI_RxInterruptEnable);
  943. }
  944. }
  945. else
  946. {
  947. /* Complete the transfer and disable the interrupts */
  948. LPSPI_MasterTransferComplete(base, handle);
  949. }
  950. }
  951. }
  952. /*Transactional APIs -- Slave*/
  953. void LPSPI_SlaveTransferCreateHandle(LPSPI_Type *base,
  954. lpspi_slave_handle_t *handle,
  955. lpspi_slave_transfer_callback_t callback,
  956. void *userData)
  957. {
  958. assert(handle);
  959. /* Zero the handle. */
  960. memset(handle, 0, sizeof(*handle));
  961. s_lpspiHandle[LPSPI_GetInstance(base)] = handle;
  962. /* Set irq handler. */
  963. s_lpspiSlaveIsr = LPSPI_SlaveTransferHandleIRQ;
  964. handle->callback = callback;
  965. handle->userData = userData;
  966. }
  967. status_t LPSPI_SlaveTransferNonBlocking(LPSPI_Type *base, lpspi_slave_handle_t *handle, lpspi_transfer_t *transfer)
  968. {
  969. assert(handle);
  970. assert(transfer);
  971. uint32_t bitsPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) + 1;
  972. uint32_t bytesPerFrame = (bitsPerFrame + 7) / 8;
  973. uint32_t temp = 0U;
  974. if (!LPSPI_CheckTransferArgument(transfer, bitsPerFrame, bytesPerFrame))
  975. {
  976. return kStatus_InvalidArgument;
  977. }
  978. /* Check that we're not busy.*/
  979. if (handle->state == kLPSPI_Busy)
  980. {
  981. return kStatus_LPSPI_Busy;
  982. }
  983. handle->state = kLPSPI_Busy;
  984. bool isRxMask = false;
  985. bool isTxMask = false;
  986. uint32_t whichPcs = (transfer->configFlags & LPSPI_SLAVE_PCS_MASK) >> LPSPI_SLAVE_PCS_SHIFT;
  987. handle->txData = transfer->txData;
  988. handle->rxData = transfer->rxData;
  989. handle->txRemainingByteCount = transfer->dataSize;
  990. handle->rxRemainingByteCount = transfer->dataSize;
  991. handle->totalByteCount = transfer->dataSize;
  992. handle->writeRegRemainingTimes = (transfer->dataSize / bytesPerFrame) * ((bytesPerFrame + 3) / 4);
  993. handle->readRegRemainingTimes = handle->writeRegRemainingTimes;
  994. /*The TX and RX FIFO sizes are always the same*/
  995. handle->fifoSize = LPSPI_GetRxFifoSize(base);
  996. handle->isByteSwap = (bool)(transfer->configFlags & kLPSPI_SlaveByteSwap);
  997. /*Set the RX and TX watermarks to reduce the ISR times.*/
  998. uint8_t txWatermark;
  999. if (handle->fifoSize > 1)
  1000. {
  1001. txWatermark = 1;
  1002. handle->rxWatermark = handle->fifoSize - 2;
  1003. }
  1004. else
  1005. {
  1006. txWatermark = 0;
  1007. handle->rxWatermark = 0;
  1008. }
  1009. LPSPI_SetFifoWatermarks(base, txWatermark, handle->rxWatermark);
  1010. /* Check if using 3-wire mode and the txData is NULL, set the output pin to tristated. */
  1011. temp = base->CFGR1;
  1012. temp &= LPSPI_CFGR1_PINCFG_MASK;
  1013. if ((temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdiInSdiOut)) || (temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdoInSdoOut)))
  1014. {
  1015. if (!handle->txData)
  1016. {
  1017. LPSPI_Enable(base, false);
  1018. base->CFGR1 |= LPSPI_CFGR1_OUTCFG_MASK;
  1019. LPSPI_Enable(base, true);
  1020. }
  1021. /* The 3-wire mode can't send and receive data at the same time. */
  1022. if ((handle->txData) && (handle->rxData))
  1023. {
  1024. return kStatus_InvalidArgument;
  1025. }
  1026. }
  1027. /*Flush FIFO , clear status , disable all the inerrupts.*/
  1028. LPSPI_FlushFifo(base, true, true);
  1029. LPSPI_ClearStatusFlags(base, kLPSPI_AllStatusFlag);
  1030. LPSPI_DisableInterrupts(base, kLPSPI_AllInterruptEnable);
  1031. /*If there is not rxData , can mask the receive data (receive data is not stored in receive FIFO).*/
  1032. if (handle->rxData == NULL)
  1033. {
  1034. isRxMask = true;
  1035. handle->rxRemainingByteCount = 0;
  1036. }
  1037. /*If there is not txData , can mask the transmit data (no data is loaded from transmit FIFO and output pin
  1038. * is tristated).
  1039. */
  1040. if (handle->txData == NULL)
  1041. {
  1042. isTxMask = true;
  1043. handle->txRemainingByteCount = 0;
  1044. }
  1045. base->TCR = (base->TCR &
  1046. ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK | LPSPI_TCR_TXMSK_MASK |
  1047. LPSPI_TCR_PCS_MASK)) |
  1048. LPSPI_TCR_CONT(0) | LPSPI_TCR_CONTC(0) | LPSPI_TCR_RXMSK(isRxMask) | LPSPI_TCR_TXMSK(isTxMask) |
  1049. LPSPI_TCR_PCS(whichPcs);
  1050. /*Calculate the bytes for write/read the TX/RX register each time*/
  1051. if (bytesPerFrame <= 4)
  1052. {
  1053. handle->bytesEachWrite = bytesPerFrame;
  1054. handle->bytesEachRead = bytesPerFrame;
  1055. }
  1056. else
  1057. {
  1058. handle->bytesEachWrite = 4;
  1059. handle->bytesEachRead = 4;
  1060. }
  1061. /* Enable the NVIC for LPSPI peripheral. Note that below code is useless if the LPSPI interrupt is in INTMUX ,
  1062. * and you should also enable the INTMUX interupt in your application.
  1063. */
  1064. EnableIRQ(s_lpspiIRQ[LPSPI_GetInstance(base)]);
  1065. /*TCR is also shared the FIFO , so wait for TCR written.*/
  1066. while (LPSPI_GetTxFifoCount(base) != 0)
  1067. {
  1068. }
  1069. /*Fill up the TX data in FIFO */
  1070. if (handle->txData)
  1071. {
  1072. LPSPI_SlaveTransferFillUpTxFifo(base, handle);
  1073. }
  1074. /* Since SPI is a synchronous interface, we only need to enable the RX interrupt if there is RX data.
  1075. * The IRQ handler will get the status of RX and TX interrupt flags.
  1076. */
  1077. if (handle->rxData)
  1078. {
  1079. /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise there
  1080. *is not RX interrupt for the last datas because the RX count is not greater than rxWatermark.
  1081. */
  1082. if ((handle->readRegRemainingTimes) <= handle->rxWatermark)
  1083. {
  1084. base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) | LPSPI_FCR_RXWATER(handle->readRegRemainingTimes - 1);
  1085. }
  1086. LPSPI_EnableInterrupts(base, kLPSPI_RxInterruptEnable);
  1087. }
  1088. else
  1089. {
  1090. LPSPI_EnableInterrupts(base, kLPSPI_TxInterruptEnable);
  1091. }
  1092. if (handle->rxData)
  1093. {
  1094. /* RX FIFO overflow request enable */
  1095. LPSPI_EnableInterrupts(base, kLPSPI_ReceiveErrorInterruptEnable);
  1096. }
  1097. if (handle->txData)
  1098. {
  1099. /* TX FIFO underflow request enable */
  1100. LPSPI_EnableInterrupts(base, kLPSPI_TransmitErrorInterruptEnable);
  1101. }
  1102. return kStatus_Success;
  1103. }
  1104. static void LPSPI_SlaveTransferFillUpTxFifo(LPSPI_Type *base, lpspi_slave_handle_t *handle)
  1105. {
  1106. assert(handle);
  1107. uint32_t wordToSend = 0;
  1108. while (LPSPI_GetTxFifoCount(base) < (handle->fifoSize))
  1109. {
  1110. if (handle->txRemainingByteCount < handle->bytesEachWrite)
  1111. {
  1112. handle->bytesEachWrite = handle->txRemainingByteCount;
  1113. }
  1114. wordToSend = LPSPI_CombineWriteData(handle->txData, handle->bytesEachWrite, handle->isByteSwap);
  1115. handle->txData += handle->bytesEachWrite;
  1116. /*Decrease the remaining TX byte count.*/
  1117. handle->txRemainingByteCount -= handle->bytesEachWrite;
  1118. /*Write the word to TX register*/
  1119. LPSPI_WriteData(base, wordToSend);
  1120. if (handle->txRemainingByteCount == 0)
  1121. {
  1122. break;
  1123. }
  1124. }
  1125. }
  1126. static void LPSPI_SlaveTransferComplete(LPSPI_Type *base, lpspi_slave_handle_t *handle)
  1127. {
  1128. assert(handle);
  1129. status_t status = 0;
  1130. /* Disable interrupt requests*/
  1131. LPSPI_DisableInterrupts(base, kLPSPI_AllInterruptEnable);
  1132. if (handle->state == kLPSPI_Error)
  1133. {
  1134. status = kStatus_LPSPI_Error;
  1135. }
  1136. else
  1137. {
  1138. status = kStatus_Success;
  1139. }
  1140. handle->state = kLPSPI_Idle;
  1141. if (handle->callback)
  1142. {
  1143. handle->callback(base, handle, status, handle->userData);
  1144. }
  1145. }
  1146. status_t LPSPI_SlaveTransferGetCount(LPSPI_Type *base, lpspi_slave_handle_t *handle, size_t *count)
  1147. {
  1148. assert(handle);
  1149. if (!count)
  1150. {
  1151. return kStatus_InvalidArgument;
  1152. }
  1153. /* Catch when there is not an active transfer. */
  1154. if (handle->state != kLPSPI_Busy)
  1155. {
  1156. *count = 0;
  1157. return kStatus_NoTransferInProgress;
  1158. }
  1159. size_t remainingByte;
  1160. if (handle->rxData)
  1161. {
  1162. remainingByte = handle->rxRemainingByteCount;
  1163. }
  1164. else
  1165. {
  1166. remainingByte = handle->txRemainingByteCount;
  1167. }
  1168. *count = handle->totalByteCount - remainingByte;
  1169. return kStatus_Success;
  1170. }
  1171. void LPSPI_SlaveTransferAbort(LPSPI_Type *base, lpspi_slave_handle_t *handle)
  1172. {
  1173. assert(handle);
  1174. /* Disable interrupt requests*/
  1175. LPSPI_DisableInterrupts(base, kLPSPI_TxInterruptEnable | kLPSPI_RxInterruptEnable);
  1176. LPSPI_Reset(base);
  1177. handle->state = kLPSPI_Idle;
  1178. handle->txRemainingByteCount = 0;
  1179. handle->rxRemainingByteCount = 0;
  1180. }
  1181. void LPSPI_SlaveTransferHandleIRQ(LPSPI_Type *base, lpspi_slave_handle_t *handle)
  1182. {
  1183. assert(handle);
  1184. uint32_t readData; /* variable to store word read from RX FIFO */
  1185. uint32_t wordToSend; /* variable to store word to write to TX FIFO */
  1186. if (handle->rxData != NULL)
  1187. {
  1188. if (handle->rxRemainingByteCount > 0)
  1189. {
  1190. while (LPSPI_GetRxFifoCount(base))
  1191. {
  1192. /*Read out the data*/
  1193. readData = LPSPI_ReadData(base);
  1194. /*Decrease the read RX register times.*/
  1195. --handle->readRegRemainingTimes;
  1196. if (handle->rxRemainingByteCount < handle->bytesEachRead)
  1197. {
  1198. handle->bytesEachRead = handle->rxRemainingByteCount;
  1199. }
  1200. LPSPI_SeparateReadData(handle->rxData, readData, handle->bytesEachRead, handle->isByteSwap);
  1201. handle->rxData += handle->bytesEachRead;
  1202. /*Decrease the remaining RX byte count.*/
  1203. handle->rxRemainingByteCount -= handle->bytesEachRead;
  1204. if ((handle->txRemainingByteCount > 0) && (handle->txData != NULL))
  1205. {
  1206. if (handle->txRemainingByteCount < handle->bytesEachWrite)
  1207. {
  1208. handle->bytesEachWrite = handle->txRemainingByteCount;
  1209. }
  1210. wordToSend = LPSPI_CombineWriteData(handle->txData, handle->bytesEachWrite, handle->isByteSwap);
  1211. handle->txData += handle->bytesEachWrite;
  1212. /*Decrease the remaining TX byte count.*/
  1213. handle->txRemainingByteCount -= handle->bytesEachWrite;
  1214. /*Write the word to TX register*/
  1215. LPSPI_WriteData(base, wordToSend);
  1216. }
  1217. if (handle->rxRemainingByteCount == 0)
  1218. {
  1219. break;
  1220. }
  1221. }
  1222. }
  1223. /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise there
  1224. *is not RX interrupt for the last datas because the RX count is not greater than rxWatermark.
  1225. */
  1226. if ((handle->readRegRemainingTimes) <= (handle->rxWatermark))
  1227. {
  1228. base->FCR =
  1229. (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) |
  1230. LPSPI_FCR_RXWATER((handle->readRegRemainingTimes > 1) ? (handle->readRegRemainingTimes - 1U) : (0U));
  1231. }
  1232. }
  1233. else if ((handle->txRemainingByteCount) && (handle->txData != NULL))
  1234. {
  1235. LPSPI_SlaveTransferFillUpTxFifo(base, handle);
  1236. }
  1237. else
  1238. {
  1239. __NOP();
  1240. }
  1241. if ((handle->txRemainingByteCount == 0) && (handle->rxRemainingByteCount == 0))
  1242. {
  1243. /* If no RX buffer, then transfer is not complete until transfer complete flag sets and the TX FIFO empty*/
  1244. if (handle->rxData == NULL)
  1245. {
  1246. if ((LPSPI_GetStatusFlags(base) & kLPSPI_FrameCompleteFlag) && (LPSPI_GetTxFifoCount(base) == 0))
  1247. {
  1248. /* Complete the transfer and disable the interrupts */
  1249. LPSPI_SlaveTransferComplete(base, handle);
  1250. }
  1251. else
  1252. {
  1253. LPSPI_ClearStatusFlags(base, kLPSPI_FrameCompleteFlag);
  1254. LPSPI_EnableInterrupts(base, kLPSPI_FrameCompleteInterruptEnable);
  1255. LPSPI_DisableInterrupts(base, kLPSPI_TxInterruptEnable | kLPSPI_RxInterruptEnable);
  1256. }
  1257. }
  1258. else
  1259. {
  1260. /* Complete the transfer and disable the interrupts */
  1261. LPSPI_SlaveTransferComplete(base, handle);
  1262. }
  1263. }
  1264. /* Catch tx fifo underflow conditions, service only if tx under flow interrupt enabled */
  1265. if ((LPSPI_GetStatusFlags(base) & kLPSPI_TransmitErrorFlag) && (base->IER & LPSPI_IER_TEIE_MASK))
  1266. {
  1267. LPSPI_ClearStatusFlags(base, kLPSPI_TransmitErrorFlag);
  1268. /* Change state to error and clear flag */
  1269. if (handle->txData)
  1270. {
  1271. handle->state = kLPSPI_Error;
  1272. }
  1273. handle->errorCount++;
  1274. }
  1275. /* Catch rx fifo overflow conditions, service only if rx over flow interrupt enabled */
  1276. if ((LPSPI_GetStatusFlags(base) & kLPSPI_ReceiveErrorFlag) && (base->IER & LPSPI_IER_REIE_MASK))
  1277. {
  1278. LPSPI_ClearStatusFlags(base, kLPSPI_ReceiveErrorFlag);
  1279. /* Change state to error and clear flag */
  1280. if (handle->txData)
  1281. {
  1282. handle->state = kLPSPI_Error;
  1283. }
  1284. handle->errorCount++;
  1285. }
  1286. }
  1287. static uint32_t LPSPI_CombineWriteData(uint8_t *txData, uint32_t bytesEachWrite, bool isByteSwap)
  1288. {
  1289. assert(txData);
  1290. uint32_t wordToSend = 0;
  1291. switch (bytesEachWrite)
  1292. {
  1293. case 1:
  1294. wordToSend = *txData;
  1295. ++txData;
  1296. break;
  1297. case 2:
  1298. if (!isByteSwap)
  1299. {
  1300. wordToSend = *txData;
  1301. ++txData;
  1302. wordToSend |= (unsigned)(*txData) << 8U;
  1303. ++txData;
  1304. }
  1305. else
  1306. {
  1307. wordToSend = (unsigned)(*txData) << 8U;
  1308. ++txData;
  1309. wordToSend |= *txData;
  1310. ++txData;
  1311. }
  1312. break;
  1313. case 3:
  1314. if (!isByteSwap)
  1315. {
  1316. wordToSend = *txData;
  1317. ++txData;
  1318. wordToSend |= (unsigned)(*txData) << 8U;
  1319. ++txData;
  1320. wordToSend |= (unsigned)(*txData) << 16U;
  1321. ++txData;
  1322. }
  1323. else
  1324. {
  1325. wordToSend = (unsigned)(*txData) << 16U;
  1326. ++txData;
  1327. wordToSend |= (unsigned)(*txData) << 8U;
  1328. ++txData;
  1329. wordToSend |= *txData;
  1330. ++txData;
  1331. }
  1332. break;
  1333. case 4:
  1334. if (!isByteSwap)
  1335. {
  1336. wordToSend = *txData;
  1337. ++txData;
  1338. wordToSend |= (unsigned)(*txData) << 8U;
  1339. ++txData;
  1340. wordToSend |= (unsigned)(*txData) << 16U;
  1341. ++txData;
  1342. wordToSend |= (unsigned)(*txData) << 24U;
  1343. ++txData;
  1344. }
  1345. else
  1346. {
  1347. wordToSend = (unsigned)(*txData) << 24U;
  1348. ++txData;
  1349. wordToSend |= (unsigned)(*txData) << 16U;
  1350. ++txData;
  1351. wordToSend |= (unsigned)(*txData) << 8U;
  1352. ++txData;
  1353. wordToSend |= *txData;
  1354. ++txData;
  1355. }
  1356. break;
  1357. default:
  1358. assert(false);
  1359. break;
  1360. }
  1361. return wordToSend;
  1362. }
  1363. static void LPSPI_SeparateReadData(uint8_t *rxData, uint32_t readData, uint32_t bytesEachRead, bool isByteSwap)
  1364. {
  1365. assert(rxData);
  1366. switch (bytesEachRead)
  1367. {
  1368. case 1:
  1369. *rxData = readData;
  1370. ++rxData;
  1371. break;
  1372. case 2:
  1373. if (!isByteSwap)
  1374. {
  1375. *rxData = readData;
  1376. ++rxData;
  1377. *rxData = readData >> 8;
  1378. ++rxData;
  1379. }
  1380. else
  1381. {
  1382. *rxData = readData >> 8;
  1383. ++rxData;
  1384. *rxData = readData;
  1385. ++rxData;
  1386. }
  1387. break;
  1388. case 3:
  1389. if (!isByteSwap)
  1390. {
  1391. *rxData = readData;
  1392. ++rxData;
  1393. *rxData = readData >> 8;
  1394. ++rxData;
  1395. *rxData = readData >> 16;
  1396. ++rxData;
  1397. }
  1398. else
  1399. {
  1400. *rxData = readData >> 16;
  1401. ++rxData;
  1402. *rxData = readData >> 8;
  1403. ++rxData;
  1404. *rxData = readData;
  1405. ++rxData;
  1406. }
  1407. break;
  1408. case 4:
  1409. if (!isByteSwap)
  1410. {
  1411. *rxData = readData;
  1412. ++rxData;
  1413. *rxData = readData >> 8;
  1414. ++rxData;
  1415. *rxData = readData >> 16;
  1416. ++rxData;
  1417. *rxData = readData >> 24;
  1418. ++rxData;
  1419. }
  1420. else
  1421. {
  1422. *rxData = readData >> 24;
  1423. ++rxData;
  1424. *rxData = readData >> 16;
  1425. ++rxData;
  1426. *rxData = readData >> 8;
  1427. ++rxData;
  1428. *rxData = readData;
  1429. ++rxData;
  1430. }
  1431. break;
  1432. default:
  1433. assert(false);
  1434. break;
  1435. }
  1436. }
  1437. static void LPSPI_CommonIRQHandler(LPSPI_Type *base, void *param)
  1438. {
  1439. if (LPSPI_IsMaster(base))
  1440. {
  1441. s_lpspiMasterIsr(base, (lpspi_master_handle_t *)param);
  1442. }
  1443. else
  1444. {
  1445. s_lpspiSlaveIsr(base, (lpspi_slave_handle_t *)param);
  1446. }
  1447. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1448. exception return operation might vector to incorrect interrupt */
  1449. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1450. __DSB();
  1451. #endif
  1452. }
  1453. #if defined(LPSPI0)
  1454. void LPSPI0_DriverIRQHandler(void)
  1455. {
  1456. assert(s_lpspiHandle[0]);
  1457. LPSPI_CommonIRQHandler(LPSPI0, s_lpspiHandle[0]);
  1458. }
  1459. #endif
  1460. #if defined(LPSPI1)
  1461. void LPSPI1_DriverIRQHandler(void)
  1462. {
  1463. assert(s_lpspiHandle[1]);
  1464. LPSPI_CommonIRQHandler(LPSPI1, s_lpspiHandle[1]);
  1465. }
  1466. #endif
  1467. #if defined(LPSPI2)
  1468. void LPSPI2_DriverIRQHandler(void)
  1469. {
  1470. assert(s_lpspiHandle[2]);
  1471. LPSPI_CommonIRQHandler(LPSPI2, s_lpspiHandle[2]);
  1472. }
  1473. #endif
  1474. #if defined(LPSPI3)
  1475. void LPSPI3_DriverIRQHandler(void)
  1476. {
  1477. assert(s_lpspiHandle[3]);
  1478. LPSPI_CommonIRQHandler(LPSPI3, s_lpspiHandle[3]);
  1479. }
  1480. #endif
  1481. #if defined(LPSPI4)
  1482. void LPSPI4_DriverIRQHandler(void)
  1483. {
  1484. assert(s_lpspiHandle[4]);
  1485. LPSPI_CommonIRQHandler(LPSPI4, s_lpspiHandle[4]);
  1486. }
  1487. #endif
  1488. #if defined(LPSPI5)
  1489. void LPSPI5_DriverIRQHandler(void)
  1490. {
  1491. assert(s_lpspiHandle[5]);
  1492. LPSPI_CommonIRQHandler(LPSPI5, s_lpspiHandle[5]);
  1493. }
  1494. #endif
  1495. #if defined(DMA__LPSPI0)
  1496. void DMA_SPI0_INT_DriverIRQHandler(void)
  1497. {
  1498. assert(s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI0)]);
  1499. LPSPI_CommonIRQHandler(DMA__LPSPI0, s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI0)]);
  1500. }
  1501. #endif
  1502. #if defined(DMA__LPSPI1)
  1503. void DMA_SPI1_INT_DriverIRQHandler(void)
  1504. {
  1505. assert(s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI1)]);
  1506. LPSPI_CommonIRQHandler(DMA__LPSPI1, s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI1)]);
  1507. }
  1508. #endif
  1509. #if defined(DMA__LPSPI2)
  1510. void DMA_SPI2_INT_DriverIRQHandler(void)
  1511. {
  1512. assert(s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI2)]);
  1513. LPSPI_CommonIRQHandler(DMA__LPSPI2, s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI2)]);
  1514. }
  1515. #endif
  1516. #if defined(DMA__LPSPI3)
  1517. void DMA_SPI3_INT_DriverIRQHandler(void)
  1518. {
  1519. assert(s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI3)]);
  1520. LPSPI_CommonIRQHandler(DMA__LPSPI3, s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI3)]);
  1521. }
  1522. #endif
  1523. #if defined(ADMA__LPSPI0)
  1524. void ADMA_SPI0_INT_DriverIRQHandler(void)
  1525. {
  1526. assert(s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI0)]);
  1527. LPSPI_CommonIRQHandler(ADMA__LPSPI0, s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI0)]);
  1528. }
  1529. #endif
  1530. #if defined(ADMA__LPSPI1)
  1531. void ADMA_SPI1_INT_DriverIRQHandler(void)
  1532. {
  1533. assert(s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI1)]);
  1534. LPSPI_CommonIRQHandler(ADMA__LPSPI1, s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI1)]);
  1535. }
  1536. #endif
  1537. #if defined(ADMA__LPSPI2)
  1538. void ADMA_SPI2_INT_DriverIRQHandler(void)
  1539. {
  1540. assert(s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI2)]);
  1541. LPSPI_CommonIRQHandler(ADMA__LPSPI2, s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI2)]);
  1542. }
  1543. #endif
  1544. #if defined(ADMA__LPSPI3)
  1545. void ADMA_SPI3_INT_DriverIRQHandler(void)
  1546. {
  1547. assert(s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI3)]);
  1548. LPSPI_CommonIRQHandler(ADMA__LPSPI3, s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI3)]);
  1549. }
  1550. #endif