fsl_flexio_spi.c 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
  1. /*
  2. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2020 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include "fsl_flexio_spi.h"
  9. /*******************************************************************************
  10. * Definitions
  11. ******************************************************************************/
  12. /* Component ID definition, used by tools. */
  13. #ifndef FSL_COMPONENT_ID
  14. #define FSL_COMPONENT_ID "platform.drivers.flexio_spi"
  15. #endif
  16. /*! @brief FLEXIO SPI transfer state, which is used for SPI transactiaonl APIs' internal state. */
  17. enum _flexio_spi_transfer_states
  18. {
  19. kFLEXIO_SPI_Idle = 0x0U, /*!< Nothing in the transmitter/receiver's queue. */
  20. kFLEXIO_SPI_Busy, /*!< Transmiter/Receive's queue is not finished. */
  21. };
  22. /*******************************************************************************
  23. * Prototypes
  24. ******************************************************************************/
  25. /*!
  26. * @brief Send a piece of data for SPI.
  27. *
  28. * This function computes the number of data to be written into D register or Tx FIFO,
  29. * and write the data into it. At the same time, this function updates the values in
  30. * master handle structure.
  31. *
  32. * @param base pointer to FLEXIO_SPI_Type structure
  33. * @param handle Pointer to SPI master handle structure.
  34. */
  35. static void FLEXIO_SPI_TransferSendTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle);
  36. /*!
  37. * @brief Receive a piece of data for SPI master.
  38. *
  39. * This function computes the number of data to receive from D register or Rx FIFO,
  40. * and write the data to destination address. At the same time, this function updates
  41. * the values in master handle structure.
  42. *
  43. * @param base pointer to FLEXIO_SPI_Type structure
  44. * @param handle Pointer to SPI master handle structure.
  45. */
  46. static void FLEXIO_SPI_TransferReceiveTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle);
  47. /*******************************************************************************
  48. * Variables
  49. ******************************************************************************/
  50. /*******************************************************************************
  51. * Codes
  52. ******************************************************************************/
  53. static uint32_t FLEXIO_SPI_GetInstance(FLEXIO_SPI_Type *base)
  54. {
  55. return FLEXIO_GetInstance(base->flexioBase);
  56. }
  57. static void FLEXIO_SPI_TransferSendTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle)
  58. {
  59. uint16_t tmpData = FLEXIO_SPI_DUMMYDATA;
  60. if (handle->txData != NULL)
  61. {
  62. /* Transmit data and update tx size/buff. */
  63. if (handle->bytePerFrame == 1U)
  64. {
  65. tmpData = *(handle->txData);
  66. handle->txData++;
  67. }
  68. else
  69. {
  70. if (handle->direction == kFLEXIO_SPI_MsbFirst)
  71. {
  72. tmpData = (uint16_t)(handle->txData[0]) << 8U;
  73. tmpData += handle->txData[1];
  74. }
  75. else
  76. {
  77. tmpData = (uint16_t)(handle->txData[1]) << 8U;
  78. tmpData += handle->txData[0];
  79. }
  80. handle->txData += 2U;
  81. }
  82. }
  83. else
  84. {
  85. tmpData = FLEXIO_SPI_DUMMYDATA;
  86. }
  87. handle->txRemainingBytes -= handle->bytePerFrame;
  88. FLEXIO_SPI_WriteData(base, handle->direction, tmpData);
  89. if (0U == handle->txRemainingBytes)
  90. {
  91. FLEXIO_SPI_DisableInterrupts(base, (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable);
  92. }
  93. }
  94. static void FLEXIO_SPI_TransferReceiveTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle)
  95. {
  96. uint16_t tmpData;
  97. tmpData = FLEXIO_SPI_ReadData(base, handle->direction);
  98. if (handle->rxData != NULL)
  99. {
  100. if (handle->bytePerFrame == 1U)
  101. {
  102. *handle->rxData = (uint8_t)tmpData;
  103. handle->rxData++;
  104. }
  105. else
  106. {
  107. if (handle->direction == kFLEXIO_SPI_MsbFirst)
  108. {
  109. *handle->rxData = (uint8_t)(tmpData >> 8);
  110. handle->rxData++;
  111. *handle->rxData = (uint8_t)tmpData;
  112. }
  113. else
  114. {
  115. *handle->rxData = (uint8_t)tmpData;
  116. handle->rxData++;
  117. *handle->rxData = (uint8_t)(tmpData >> 8);
  118. }
  119. handle->rxData++;
  120. }
  121. }
  122. handle->rxRemainingBytes -= handle->bytePerFrame;
  123. }
  124. /*!
  125. * brief Ungates the FlexIO clock, resets the FlexIO module, configures the FlexIO SPI master hardware,
  126. * and configures the FlexIO SPI with FlexIO SPI master configuration. The
  127. * configuration structure can be filled by the user, or be set with default values
  128. * by the FLEXIO_SPI_MasterGetDefaultConfig().
  129. *
  130. * note 1.FlexIO SPI master only support CPOL = 0, which means clock inactive low.
  131. * 2.For FlexIO SPI master, the input valid time is 1.5 clock cycles, for slave the output valid time
  132. * is 2.5 clock cycles. So if FlexIO SPI master communicates with other spi IPs, the maximum baud
  133. * rate is FlexIO clock frequency divided by 2*2=4. If FlexIO SPI master communicates with FlexIO
  134. * SPI slave, the maximum baud rate is FlexIO clock frequency divided by (1.5+2.5)*2=8.
  135. *
  136. * Example
  137. code
  138. FLEXIO_SPI_Type spiDev = {
  139. .flexioBase = FLEXIO,
  140. .SDOPinIndex = 0,
  141. .SDIPinIndex = 1,
  142. .SCKPinIndex = 2,
  143. .CSnPinIndex = 3,
  144. .shifterIndex = {0,1},
  145. .timerIndex = {0,1}
  146. };
  147. flexio_spi_master_config_t config = {
  148. .enableMaster = true,
  149. .enableInDoze = false,
  150. .enableInDebug = true,
  151. .enableFastAccess = false,
  152. .baudRate_Bps = 500000,
  153. .phase = kFLEXIO_SPI_ClockPhaseFirstEdge,
  154. .direction = kFLEXIO_SPI_MsbFirst,
  155. .dataMode = kFLEXIO_SPI_8BitMode
  156. };
  157. FLEXIO_SPI_MasterInit(&spiDev, &config, srcClock_Hz);
  158. endcode
  159. *
  160. * param base Pointer to the FLEXIO_SPI_Type structure.
  161. * param masterConfig Pointer to the flexio_spi_master_config_t structure.
  162. * param srcClock_Hz FlexIO source clock in Hz.
  163. */
  164. void FLEXIO_SPI_MasterInit(FLEXIO_SPI_Type *base, flexio_spi_master_config_t *masterConfig, uint32_t srcClock_Hz)
  165. {
  166. assert(base != NULL);
  167. assert(masterConfig != NULL);
  168. flexio_shifter_config_t shifterConfig;
  169. flexio_timer_config_t timerConfig;
  170. uint32_t ctrlReg = 0;
  171. uint16_t timerDiv = 0;
  172. uint16_t timerCmp = 0;
  173. /* Clear the shifterConfig & timerConfig struct. */
  174. (void)memset(&shifterConfig, 0, sizeof(shifterConfig));
  175. (void)memset(&timerConfig, 0, sizeof(timerConfig));
  176. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  177. /* Ungate flexio clock. */
  178. CLOCK_EnableClock(s_flexioClocks[FLEXIO_SPI_GetInstance(base)]);
  179. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  180. /* Configure FLEXIO SPI Master */
  181. ctrlReg = base->flexioBase->CTRL;
  182. ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
  183. ctrlReg |= (FLEXIO_CTRL_DBGE(masterConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(masterConfig->enableFastAccess) |
  184. FLEXIO_CTRL_FLEXEN(masterConfig->enableMaster));
  185. if (!masterConfig->enableInDoze)
  186. {
  187. ctrlReg |= FLEXIO_CTRL_DOZEN_MASK;
  188. }
  189. base->flexioBase->CTRL = ctrlReg;
  190. /* Do hardware configuration. */
  191. /* 1. Configure the shifter 0 for tx. */
  192. shifterConfig.timerSelect = base->timerIndex[0];
  193. shifterConfig.pinConfig = kFLEXIO_PinConfigOutput;
  194. shifterConfig.pinSelect = base->SDOPinIndex;
  195. shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
  196. shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
  197. shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
  198. if (masterConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
  199. {
  200. shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
  201. shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable;
  202. shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
  203. }
  204. else
  205. {
  206. shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
  207. shifterConfig.shifterStop = kFLEXIO_ShifterStopBitLow;
  208. shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift;
  209. }
  210. FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig);
  211. /* 2. Configure the shifter 1 for rx. */
  212. shifterConfig.timerSelect = base->timerIndex[0];
  213. shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
  214. shifterConfig.pinSelect = base->SDIPinIndex;
  215. shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
  216. shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive;
  217. shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
  218. shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable;
  219. shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
  220. if (masterConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
  221. {
  222. shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
  223. }
  224. else
  225. {
  226. shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
  227. }
  228. FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig);
  229. /*3. Configure the timer 0 for SCK. */
  230. timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
  231. timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
  232. timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
  233. timerConfig.pinConfig = kFLEXIO_PinConfigOutput;
  234. timerConfig.pinSelect = base->SCKPinIndex;
  235. timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
  236. timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit;
  237. timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset;
  238. timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
  239. timerConfig.timerReset = kFLEXIO_TimerResetNever;
  240. timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
  241. timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh;
  242. timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable;
  243. timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
  244. timerDiv = (uint16_t)(srcClock_Hz / masterConfig->baudRate_Bps);
  245. timerDiv = timerDiv / 2U - 1U;
  246. timerCmp = ((uint16_t)masterConfig->dataMode * 2U - 1U) << 8U;
  247. timerCmp |= timerDiv;
  248. timerConfig.timerCompare = timerCmp;
  249. FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig);
  250. /* 4. Configure the timer 1 for CSn. */
  251. timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_TIMn(base->timerIndex[0]);
  252. timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh;
  253. timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
  254. timerConfig.pinConfig = kFLEXIO_PinConfigOutput;
  255. timerConfig.pinSelect = base->CSnPinIndex;
  256. timerConfig.pinPolarity = kFLEXIO_PinActiveLow;
  257. timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
  258. timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
  259. timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
  260. timerConfig.timerReset = kFLEXIO_TimerResetNever;
  261. timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable;
  262. timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable;
  263. timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled;
  264. timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled;
  265. timerConfig.timerCompare = 0xFFFFU;
  266. FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig);
  267. }
  268. /*!
  269. * brief Resets the FlexIO SPI timer and shifter config.
  270. *
  271. * param base Pointer to the FLEXIO_SPI_Type.
  272. */
  273. void FLEXIO_SPI_MasterDeinit(FLEXIO_SPI_Type *base)
  274. {
  275. base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = 0;
  276. base->flexioBase->SHIFTCTL[base->shifterIndex[0]] = 0;
  277. base->flexioBase->SHIFTCFG[base->shifterIndex[1]] = 0;
  278. base->flexioBase->SHIFTCTL[base->shifterIndex[1]] = 0;
  279. base->flexioBase->TIMCFG[base->timerIndex[0]] = 0;
  280. base->flexioBase->TIMCMP[base->timerIndex[0]] = 0;
  281. base->flexioBase->TIMCTL[base->timerIndex[0]] = 0;
  282. base->flexioBase->TIMCFG[base->timerIndex[1]] = 0;
  283. base->flexioBase->TIMCMP[base->timerIndex[1]] = 0;
  284. base->flexioBase->TIMCTL[base->timerIndex[1]] = 0;
  285. }
  286. /*!
  287. * brief Gets the default configuration to configure the FlexIO SPI master. The configuration
  288. * can be used directly by calling the FLEXIO_SPI_MasterConfigure().
  289. * Example:
  290. code
  291. flexio_spi_master_config_t masterConfig;
  292. FLEXIO_SPI_MasterGetDefaultConfig(&masterConfig);
  293. endcode
  294. * param masterConfig Pointer to the flexio_spi_master_config_t structure.
  295. */
  296. void FLEXIO_SPI_MasterGetDefaultConfig(flexio_spi_master_config_t *masterConfig)
  297. {
  298. assert(masterConfig != NULL);
  299. /* Initializes the configure structure to zero. */
  300. (void)memset(masterConfig, 0, sizeof(*masterConfig));
  301. masterConfig->enableMaster = true;
  302. masterConfig->enableInDoze = false;
  303. masterConfig->enableInDebug = true;
  304. masterConfig->enableFastAccess = false;
  305. /* Default baud rate 500kbps. */
  306. masterConfig->baudRate_Bps = 500000U;
  307. /* Default CPHA = 0. */
  308. masterConfig->phase = kFLEXIO_SPI_ClockPhaseFirstEdge;
  309. /* Default bit count at 8. */
  310. masterConfig->dataMode = kFLEXIO_SPI_8BitMode;
  311. }
  312. /*!
  313. * brief Ungates the FlexIO clock, resets the FlexIO module, configures the FlexIO SPI slave hardware
  314. * configuration, and configures the FlexIO SPI with FlexIO SPI slave configuration. The
  315. * configuration structure can be filled by the user, or be set with default values
  316. * by the FLEXIO_SPI_SlaveGetDefaultConfig().
  317. *
  318. * note 1.Only one timer is needed in the FlexIO SPI slave. As a result, the second timer index is ignored.
  319. * 2.FlexIO SPI slave only support CPOL = 0, which means clock inactive low.
  320. * 3.For FlexIO SPI master, the input valid time is 1.5 clock cycles, for slave the output valid time
  321. * is 2.5 clock cycles. So if FlexIO SPI slave communicates with other spi IPs, the maximum baud
  322. * rate is FlexIO clock frequency divided by 3*2=6. If FlexIO SPI slave communicates with FlexIO
  323. * SPI master, the maximum baud rate is FlexIO clock frequency divided by (1.5+2.5)*2=8.
  324. * Example
  325. code
  326. FLEXIO_SPI_Type spiDev = {
  327. .flexioBase = FLEXIO,
  328. .SDOPinIndex = 0,
  329. .SDIPinIndex = 1,
  330. .SCKPinIndex = 2,
  331. .CSnPinIndex = 3,
  332. .shifterIndex = {0,1},
  333. .timerIndex = {0}
  334. };
  335. flexio_spi_slave_config_t config = {
  336. .enableSlave = true,
  337. .enableInDoze = false,
  338. .enableInDebug = true,
  339. .enableFastAccess = false,
  340. .phase = kFLEXIO_SPI_ClockPhaseFirstEdge,
  341. .direction = kFLEXIO_SPI_MsbFirst,
  342. .dataMode = kFLEXIO_SPI_8BitMode
  343. };
  344. FLEXIO_SPI_SlaveInit(&spiDev, &config);
  345. endcode
  346. * param base Pointer to the FLEXIO_SPI_Type structure.
  347. * param slaveConfig Pointer to the flexio_spi_slave_config_t structure.
  348. */
  349. void FLEXIO_SPI_SlaveInit(FLEXIO_SPI_Type *base, flexio_spi_slave_config_t *slaveConfig)
  350. {
  351. assert((base != NULL) && (slaveConfig != NULL));
  352. flexio_shifter_config_t shifterConfig;
  353. flexio_timer_config_t timerConfig;
  354. uint32_t ctrlReg = 0;
  355. /* Clear the shifterConfig & timerConfig struct. */
  356. (void)memset(&shifterConfig, 0, sizeof(shifterConfig));
  357. (void)memset(&timerConfig, 0, sizeof(timerConfig));
  358. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  359. /* Ungate flexio clock. */
  360. CLOCK_EnableClock(s_flexioClocks[FLEXIO_SPI_GetInstance(base)]);
  361. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  362. /* Configure FLEXIO SPI Slave */
  363. ctrlReg = base->flexioBase->CTRL;
  364. ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
  365. ctrlReg |= (FLEXIO_CTRL_DBGE(slaveConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(slaveConfig->enableFastAccess) |
  366. FLEXIO_CTRL_FLEXEN(slaveConfig->enableSlave));
  367. if (!slaveConfig->enableInDoze)
  368. {
  369. ctrlReg |= FLEXIO_CTRL_DOZEN_MASK;
  370. }
  371. base->flexioBase->CTRL = ctrlReg;
  372. /* Do hardware configuration. */
  373. /* 1. Configure the shifter 0 for tx. */
  374. shifterConfig.timerSelect = base->timerIndex[0];
  375. shifterConfig.pinConfig = kFLEXIO_PinConfigOutput;
  376. shifterConfig.pinSelect = base->SDOPinIndex;
  377. shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
  378. shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
  379. shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
  380. shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable;
  381. if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
  382. {
  383. shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
  384. shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
  385. }
  386. else
  387. {
  388. shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
  389. shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift;
  390. }
  391. FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig);
  392. /* 2. Configure the shifter 1 for rx. */
  393. shifterConfig.timerSelect = base->timerIndex[0];
  394. shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
  395. shifterConfig.pinSelect = base->SDIPinIndex;
  396. shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
  397. shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive;
  398. shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
  399. shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable;
  400. shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
  401. if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
  402. {
  403. shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
  404. }
  405. else
  406. {
  407. shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
  408. }
  409. FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig);
  410. /*3. Configure the timer 0 for shift clock. */
  411. timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->CSnPinIndex);
  412. timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
  413. timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
  414. timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
  415. timerConfig.pinSelect = base->SCKPinIndex;
  416. timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
  417. timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
  418. timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset;
  419. timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput;
  420. timerConfig.timerReset = kFLEXIO_TimerResetNever;
  421. timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerRisingEdge;
  422. timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled;
  423. if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
  424. {
  425. /* The configuration kFLEXIO_TimerDisableOnTimerCompare only support continuous
  426. PCS access, change to kFLEXIO_TimerDisableNever to enable discontinuous PCS access. */
  427. timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
  428. timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled;
  429. }
  430. else
  431. {
  432. timerConfig.timerDisable = kFLEXIO_TimerDisableOnTriggerFallingEdge;
  433. timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
  434. }
  435. timerConfig.timerCompare = (uint32_t)slaveConfig->dataMode * 2U - 1U;
  436. FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig);
  437. }
  438. /*!
  439. * brief Gates the FlexIO clock.
  440. *
  441. * param base Pointer to the FLEXIO_SPI_Type.
  442. */
  443. void FLEXIO_SPI_SlaveDeinit(FLEXIO_SPI_Type *base)
  444. {
  445. FLEXIO_SPI_MasterDeinit(base);
  446. }
  447. /*!
  448. * brief Gets the default configuration to configure the FlexIO SPI slave. The configuration
  449. * can be used directly for calling the FLEXIO_SPI_SlaveConfigure().
  450. * Example:
  451. code
  452. flexio_spi_slave_config_t slaveConfig;
  453. FLEXIO_SPI_SlaveGetDefaultConfig(&slaveConfig);
  454. endcode
  455. * param slaveConfig Pointer to the flexio_spi_slave_config_t structure.
  456. */
  457. void FLEXIO_SPI_SlaveGetDefaultConfig(flexio_spi_slave_config_t *slaveConfig)
  458. {
  459. assert(slaveConfig != NULL);
  460. /* Initializes the configure structure to zero. */
  461. (void)memset(slaveConfig, 0, sizeof(*slaveConfig));
  462. slaveConfig->enableSlave = true;
  463. slaveConfig->enableInDoze = false;
  464. slaveConfig->enableInDebug = true;
  465. slaveConfig->enableFastAccess = false;
  466. /* Default CPHA = 0. */
  467. slaveConfig->phase = kFLEXIO_SPI_ClockPhaseFirstEdge;
  468. /* Default bit count at 8. */
  469. slaveConfig->dataMode = kFLEXIO_SPI_8BitMode;
  470. }
  471. /*!
  472. * brief Enables the FlexIO SPI interrupt.
  473. *
  474. * This function enables the FlexIO SPI interrupt.
  475. *
  476. * param base Pointer to the FLEXIO_SPI_Type structure.
  477. * param mask interrupt source. The parameter can be any combination of the following values:
  478. * arg kFLEXIO_SPI_RxFullInterruptEnable
  479. * arg kFLEXIO_SPI_TxEmptyInterruptEnable
  480. */
  481. void FLEXIO_SPI_EnableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask)
  482. {
  483. if ((mask & (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable) != 0U)
  484. {
  485. FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[0]);
  486. }
  487. if ((mask & (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable) != 0U)
  488. {
  489. FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[1]);
  490. }
  491. }
  492. /*!
  493. * brief Disables the FlexIO SPI interrupt.
  494. *
  495. * This function disables the FlexIO SPI interrupt.
  496. *
  497. * param base Pointer to the FLEXIO_SPI_Type structure.
  498. * param mask interrupt source The parameter can be any combination of the following values:
  499. * arg kFLEXIO_SPI_RxFullInterruptEnable
  500. * arg kFLEXIO_SPI_TxEmptyInterruptEnable
  501. */
  502. void FLEXIO_SPI_DisableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask)
  503. {
  504. if ((mask & (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable) != 0U)
  505. {
  506. FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[0]);
  507. }
  508. if ((mask & (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable) != 0U)
  509. {
  510. FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[1]);
  511. }
  512. }
  513. /*!
  514. * brief Enables/disables the FlexIO SPI transmit DMA. This function enables/disables the FlexIO SPI Tx DMA,
  515. * which means that asserting the kFLEXIO_SPI_TxEmptyFlag does/doesn't trigger the DMA request.
  516. *
  517. * param base Pointer to the FLEXIO_SPI_Type structure.
  518. * param mask SPI DMA source.
  519. * param enable True means enable DMA, false means disable DMA.
  520. */
  521. void FLEXIO_SPI_EnableDMA(FLEXIO_SPI_Type *base, uint32_t mask, bool enable)
  522. {
  523. if ((mask & (uint32_t)kFLEXIO_SPI_TxDmaEnable) != 0U)
  524. {
  525. FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1UL << base->shifterIndex[0], enable);
  526. }
  527. if ((mask & (uint32_t)kFLEXIO_SPI_RxDmaEnable) != 0U)
  528. {
  529. FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1UL << base->shifterIndex[1], enable);
  530. }
  531. }
  532. /*!
  533. * brief Gets FlexIO SPI status flags.
  534. *
  535. * param base Pointer to the FLEXIO_SPI_Type structure.
  536. * return status flag; Use the status flag to AND the following flag mask and get the status.
  537. * arg kFLEXIO_SPI_TxEmptyFlag
  538. * arg kFLEXIO_SPI_RxEmptyFlag
  539. */
  540. uint32_t FLEXIO_SPI_GetStatusFlags(FLEXIO_SPI_Type *base)
  541. {
  542. uint32_t shifterStatus = FLEXIO_GetShifterStatusFlags(base->flexioBase);
  543. uint32_t status = 0;
  544. status = ((shifterStatus & (1UL << base->shifterIndex[0])) >> base->shifterIndex[0]);
  545. status |= (((shifterStatus & (1UL << base->shifterIndex[1])) >> (base->shifterIndex[1])) << 1U);
  546. return status;
  547. }
  548. /*!
  549. * brief Clears FlexIO SPI status flags.
  550. *
  551. * param base Pointer to the FLEXIO_SPI_Type structure.
  552. * param mask status flag
  553. * The parameter can be any combination of the following values:
  554. * arg kFLEXIO_SPI_TxEmptyFlag
  555. * arg kFLEXIO_SPI_RxEmptyFlag
  556. */
  557. void FLEXIO_SPI_ClearStatusFlags(FLEXIO_SPI_Type *base, uint32_t mask)
  558. {
  559. if ((mask & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag) != 0U)
  560. {
  561. FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1UL << base->shifterIndex[0]);
  562. }
  563. if ((mask & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag) != 0U)
  564. {
  565. FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1UL << base->shifterIndex[1]);
  566. }
  567. }
  568. /*!
  569. * brief Sets baud rate for the FlexIO SPI transfer, which is only used for the master.
  570. *
  571. * param base Pointer to the FLEXIO_SPI_Type structure.
  572. * param baudRate_Bps Baud Rate needed in Hz.
  573. * param srcClockHz SPI source clock frequency in Hz.
  574. */
  575. void FLEXIO_SPI_MasterSetBaudRate(FLEXIO_SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcClockHz)
  576. {
  577. uint16_t timerDiv = 0;
  578. uint16_t timerCmp = 0;
  579. FLEXIO_Type *flexioBase = base->flexioBase;
  580. /* Set TIMCMP[7:0] = (baud rate divider / 2) - 1.*/
  581. timerDiv = (uint16_t)(srcClockHz / baudRate_Bps);
  582. timerDiv = timerDiv / 2U - 1U;
  583. timerCmp = (uint16_t)(flexioBase->TIMCMP[base->timerIndex[0]]);
  584. timerCmp &= 0xFF00U;
  585. timerCmp |= timerDiv;
  586. flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp;
  587. }
  588. /*!
  589. * brief Sends a buffer of data bytes.
  590. *
  591. * note This function blocks using the polling method until all bytes have been sent.
  592. *
  593. * param base Pointer to the FLEXIO_SPI_Type structure.
  594. * param direction Shift direction of MSB first or LSB first.
  595. * param buffer The data bytes to send.
  596. * param size The number of data bytes to send.
  597. * retval kStatus_Success Successfully create the handle.
  598. * retval kStatus_FLEXIO_SPI_Timeout The transfer timed out and was aborted.
  599. */
  600. status_t FLEXIO_SPI_WriteBlocking(FLEXIO_SPI_Type *base,
  601. flexio_spi_shift_direction_t direction,
  602. const uint8_t *buffer,
  603. size_t size)
  604. {
  605. assert(buffer != NULL);
  606. assert(size != 0U);
  607. #if SPI_RETRY_TIMES
  608. uint32_t waitTimes;
  609. #endif
  610. while (0U != size--)
  611. {
  612. /* Wait until data transfer complete. */
  613. #if SPI_RETRY_TIMES
  614. waitTimes = SPI_RETRY_TIMES;
  615. while ((0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag)) &&
  616. (0U != --waitTimes))
  617. #else
  618. while (0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag))
  619. #endif
  620. {
  621. }
  622. #if SPI_RETRY_TIMES
  623. if (waitTimes == 0U)
  624. {
  625. return kStatus_FLEXIO_SPI_Timeout;
  626. }
  627. #endif
  628. FLEXIO_SPI_WriteData(base, direction, *buffer++);
  629. }
  630. return kStatus_Success;
  631. }
  632. /*!
  633. * brief Receives a buffer of bytes.
  634. *
  635. * note This function blocks using the polling method until all bytes have been received.
  636. *
  637. * param base Pointer to the FLEXIO_SPI_Type structure.
  638. * param direction Shift direction of MSB first or LSB first.
  639. * param buffer The buffer to store the received bytes.
  640. * param size The number of data bytes to be received.
  641. * param direction Shift direction of MSB first or LSB first.
  642. * retval kStatus_Success Successfully create the handle.
  643. * retval kStatus_FLEXIO_SPI_Timeout The transfer timed out and was aborted.
  644. */
  645. status_t FLEXIO_SPI_ReadBlocking(FLEXIO_SPI_Type *base,
  646. flexio_spi_shift_direction_t direction,
  647. uint8_t *buffer,
  648. size_t size)
  649. {
  650. assert(buffer != NULL);
  651. assert(size != 0U);
  652. #if SPI_RETRY_TIMES
  653. uint32_t waitTimes;
  654. #endif
  655. while (0U != size--)
  656. {
  657. /* Wait until data transfer complete. */
  658. #if SPI_RETRY_TIMES
  659. waitTimes = SPI_RETRY_TIMES;
  660. while ((0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag)) &&
  661. (0U != --waitTimes))
  662. #else
  663. while (0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag))
  664. #endif
  665. {
  666. }
  667. #if SPI_RETRY_TIMES
  668. if (waitTimes == 0U)
  669. {
  670. return kStatus_FLEXIO_SPI_Timeout;
  671. }
  672. #endif
  673. *buffer++ = (uint8_t)FLEXIO_SPI_ReadData(base, direction);
  674. }
  675. return kStatus_Success;
  676. }
  677. /*!
  678. * brief Receives a buffer of bytes.
  679. *
  680. * note This function blocks via polling until all bytes have been received.
  681. *
  682. * param base pointer to FLEXIO_SPI_Type structure
  683. * param xfer FlexIO SPI transfer structure, see #flexio_spi_transfer_t.
  684. * retval kStatus_Success Successfully create the handle.
  685. * retval kStatus_FLEXIO_SPI_Timeout The transfer timed out and was aborted.
  686. */
  687. status_t FLEXIO_SPI_MasterTransferBlocking(FLEXIO_SPI_Type *base, flexio_spi_transfer_t *xfer)
  688. {
  689. flexio_spi_shift_direction_t direction;
  690. uint8_t bytesPerFrame;
  691. uint32_t dataMode = 0;
  692. uint16_t timerCmp = (uint16_t)(base->flexioBase->TIMCMP[base->timerIndex[0]]);
  693. uint16_t tmpData = FLEXIO_SPI_DUMMYDATA;
  694. #if SPI_RETRY_TIMES
  695. uint32_t waitTimes;
  696. #endif
  697. timerCmp &= 0x00FFU;
  698. /* Configure the values in handle. */
  699. switch (xfer->flags)
  700. {
  701. case (uint8_t)kFLEXIO_SPI_8bitMsb:
  702. dataMode = (8UL * 2UL - 1UL) << 8U;
  703. bytesPerFrame = 1U;
  704. direction = kFLEXIO_SPI_MsbFirst;
  705. break;
  706. case (uint8_t)kFLEXIO_SPI_8bitLsb:
  707. dataMode = (8UL * 2UL - 1UL) << 8U;
  708. bytesPerFrame = 1U;
  709. direction = kFLEXIO_SPI_LsbFirst;
  710. break;
  711. case (uint8_t)kFLEXIO_SPI_16bitMsb:
  712. dataMode = (16UL * 2UL - 1UL) << 8U;
  713. bytesPerFrame = 2U;
  714. direction = kFLEXIO_SPI_MsbFirst;
  715. break;
  716. case (uint8_t)kFLEXIO_SPI_16bitLsb:
  717. dataMode = (16UL * 2UL - 1UL) << 8U;
  718. bytesPerFrame = 2U;
  719. direction = kFLEXIO_SPI_LsbFirst;
  720. break;
  721. default:
  722. dataMode = (8UL * 2UL - 1UL) << 8U;
  723. bytesPerFrame = 1U;
  724. direction = kFLEXIO_SPI_MsbFirst;
  725. assert(true);
  726. break;
  727. }
  728. dataMode |= timerCmp;
  729. /* Configure transfer size. */
  730. base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
  731. while (xfer->dataSize != 0U)
  732. {
  733. /* Wait until data transfer complete. */
  734. #if SPI_RETRY_TIMES
  735. waitTimes = SPI_RETRY_TIMES;
  736. while ((0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag)) &&
  737. (0U != --waitTimes))
  738. #else
  739. while (0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag))
  740. #endif
  741. {
  742. }
  743. #if SPI_RETRY_TIMES
  744. if (waitTimes == 0U)
  745. {
  746. return kStatus_FLEXIO_SPI_Timeout;
  747. }
  748. #endif
  749. if (xfer->txData != NULL)
  750. {
  751. /* Transmit data and update tx size/buff. */
  752. if (bytesPerFrame == 1U)
  753. {
  754. tmpData = *(xfer->txData);
  755. xfer->txData++;
  756. }
  757. else
  758. {
  759. if (direction == kFLEXIO_SPI_MsbFirst)
  760. {
  761. tmpData = (uint16_t)(xfer->txData[0]) << 8U;
  762. tmpData += xfer->txData[1];
  763. }
  764. else
  765. {
  766. tmpData = (uint16_t)(xfer->txData[1]) << 8U;
  767. tmpData += xfer->txData[0];
  768. }
  769. xfer->txData += 2U;
  770. }
  771. }
  772. else
  773. {
  774. tmpData = FLEXIO_SPI_DUMMYDATA;
  775. }
  776. xfer->dataSize -= bytesPerFrame;
  777. FLEXIO_SPI_WriteData(base, direction, tmpData);
  778. #if SPI_RETRY_TIMES
  779. waitTimes = SPI_RETRY_TIMES;
  780. while ((0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag)) &&
  781. (0U != --waitTimes))
  782. #else
  783. while (0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag))
  784. #endif
  785. {
  786. }
  787. #if SPI_RETRY_TIMES
  788. if (waitTimes == 0U)
  789. {
  790. return kStatus_FLEXIO_SPI_Timeout;
  791. }
  792. #endif
  793. tmpData = FLEXIO_SPI_ReadData(base, direction);
  794. if (xfer->rxData != NULL)
  795. {
  796. if (bytesPerFrame == 1U)
  797. {
  798. *xfer->rxData = (uint8_t)tmpData;
  799. xfer->rxData++;
  800. }
  801. else
  802. {
  803. if (direction == kFLEXIO_SPI_MsbFirst)
  804. {
  805. *xfer->rxData = (uint8_t)(tmpData >> 8);
  806. xfer->rxData++;
  807. *xfer->rxData = (uint8_t)tmpData;
  808. }
  809. else
  810. {
  811. *xfer->rxData = (uint8_t)tmpData;
  812. xfer->rxData++;
  813. *xfer->rxData = (uint8_t)(tmpData >> 8);
  814. }
  815. xfer->rxData++;
  816. }
  817. }
  818. }
  819. return kStatus_Success;
  820. }
  821. /*!
  822. * brief Initializes the FlexIO SPI Master handle, which is used in transactional functions.
  823. *
  824. * param base Pointer to the FLEXIO_SPI_Type structure.
  825. * param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
  826. * param callback The callback function.
  827. * param userData The parameter of the callback function.
  828. * retval kStatus_Success Successfully create the handle.
  829. * retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
  830. */
  831. status_t FLEXIO_SPI_MasterTransferCreateHandle(FLEXIO_SPI_Type *base,
  832. flexio_spi_master_handle_t *handle,
  833. flexio_spi_master_transfer_callback_t callback,
  834. void *userData)
  835. {
  836. assert(handle != NULL);
  837. IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
  838. /* Zero the handle. */
  839. (void)memset(handle, 0, sizeof(*handle));
  840. /* Register callback and userData. */
  841. handle->callback = callback;
  842. handle->userData = userData;
  843. /* Clear pending NVIC IRQ before enable NVIC IRQ. */
  844. NVIC_ClearPendingIRQ(flexio_irqs[FLEXIO_SPI_GetInstance(base)]);
  845. /* Enable interrupt in NVIC. */
  846. (void)EnableIRQ(flexio_irqs[FLEXIO_SPI_GetInstance(base)]);
  847. /* Save the context in global variables to support the double weak mechanism. */
  848. return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_SPI_MasterTransferHandleIRQ);
  849. }
  850. /*!
  851. * brief Master transfer data using IRQ.
  852. *
  853. * This function sends data using IRQ. This is a non-blocking function, which returns
  854. * right away. When all data is sent out/received, the callback function is called.
  855. *
  856. * param base Pointer to the FLEXIO_SPI_Type structure.
  857. * param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
  858. * param xfer FlexIO SPI transfer structure. See #flexio_spi_transfer_t.
  859. * retval kStatus_Success Successfully start a transfer.
  860. * retval kStatus_InvalidArgument Input argument is invalid.
  861. * retval kStatus_FLEXIO_SPI_Busy SPI is not idle, is running another transfer.
  862. */
  863. status_t FLEXIO_SPI_MasterTransferNonBlocking(FLEXIO_SPI_Type *base,
  864. flexio_spi_master_handle_t *handle,
  865. flexio_spi_transfer_t *xfer)
  866. {
  867. assert(handle != NULL);
  868. assert(xfer != NULL);
  869. uint32_t dataMode = 0;
  870. uint16_t timerCmp = (uint16_t)base->flexioBase->TIMCMP[base->timerIndex[0]];
  871. uint16_t tmpData = FLEXIO_SPI_DUMMYDATA;
  872. timerCmp &= 0x00FFU;
  873. /* Check if SPI is busy. */
  874. if (handle->state == (uint32_t)kFLEXIO_SPI_Busy)
  875. {
  876. return kStatus_FLEXIO_SPI_Busy;
  877. }
  878. /* Check if the argument is legal. */
  879. if ((xfer->txData == NULL) && (xfer->rxData == NULL))
  880. {
  881. return kStatus_InvalidArgument;
  882. }
  883. /* Configure the values in handle */
  884. switch (xfer->flags)
  885. {
  886. case (uint8_t)kFLEXIO_SPI_8bitMsb:
  887. dataMode = (8UL * 2UL - 1UL) << 8U;
  888. handle->bytePerFrame = 1U;
  889. handle->direction = kFLEXIO_SPI_MsbFirst;
  890. break;
  891. case (uint8_t)kFLEXIO_SPI_8bitLsb:
  892. dataMode = (8UL * 2UL - 1UL) << 8U;
  893. handle->bytePerFrame = 1U;
  894. handle->direction = kFLEXIO_SPI_LsbFirst;
  895. break;
  896. case (uint8_t)kFLEXIO_SPI_16bitMsb:
  897. dataMode = (16UL * 2UL - 1UL) << 8U;
  898. handle->bytePerFrame = 2U;
  899. handle->direction = kFLEXIO_SPI_MsbFirst;
  900. break;
  901. case (uint8_t)kFLEXIO_SPI_16bitLsb:
  902. dataMode = (16UL * 2UL - 1UL) << 8U;
  903. handle->bytePerFrame = 2U;
  904. handle->direction = kFLEXIO_SPI_LsbFirst;
  905. break;
  906. default:
  907. dataMode = (8UL * 2UL - 1UL) << 8U;
  908. handle->bytePerFrame = 1U;
  909. handle->direction = kFLEXIO_SPI_MsbFirst;
  910. assert(true);
  911. break;
  912. }
  913. dataMode |= timerCmp;
  914. /* Configure transfer size. */
  915. base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
  916. handle->state = (uint32_t)kFLEXIO_SPI_Busy;
  917. handle->txData = xfer->txData;
  918. handle->rxData = xfer->rxData;
  919. handle->rxRemainingBytes = xfer->dataSize;
  920. /* Save total transfer size. */
  921. handle->transferSize = xfer->dataSize;
  922. /* Send first byte of data to trigger the rx interrupt. */
  923. if (handle->txData != NULL)
  924. {
  925. /* Transmit data and update tx size/buff. */
  926. if (handle->bytePerFrame == 1U)
  927. {
  928. tmpData = *(handle->txData);
  929. handle->txData++;
  930. }
  931. else
  932. {
  933. if (handle->direction == kFLEXIO_SPI_MsbFirst)
  934. {
  935. tmpData = (uint16_t)(handle->txData[0]) << 8U;
  936. tmpData += handle->txData[1];
  937. }
  938. else
  939. {
  940. tmpData = (uint16_t)(handle->txData[1]) << 8U;
  941. tmpData += handle->txData[0];
  942. }
  943. handle->txData += 2U;
  944. }
  945. }
  946. else
  947. {
  948. tmpData = FLEXIO_SPI_DUMMYDATA;
  949. }
  950. handle->txRemainingBytes = xfer->dataSize - handle->bytePerFrame;
  951. FLEXIO_SPI_WriteData(base, handle->direction, tmpData);
  952. /* Enable transmit and receive interrupt to handle rx. */
  953. FLEXIO_SPI_EnableInterrupts(base, (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable);
  954. return kStatus_Success;
  955. }
  956. /*!
  957. * brief Gets the data transfer status which used IRQ.
  958. *
  959. * param base Pointer to the FLEXIO_SPI_Type structure.
  960. * param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
  961. * param count Number of bytes transferred so far by the non-blocking transaction.
  962. * retval kStatus_InvalidArgument count is Invalid.
  963. * retval kStatus_Success Successfully return the count.
  964. */
  965. status_t FLEXIO_SPI_MasterTransferGetCount(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle, size_t *count)
  966. {
  967. assert(handle != NULL);
  968. if (NULL == count)
  969. {
  970. return kStatus_InvalidArgument;
  971. }
  972. /* Return remaing bytes in different cases. */
  973. if (handle->rxData != NULL)
  974. {
  975. *count = handle->transferSize - handle->rxRemainingBytes;
  976. }
  977. else
  978. {
  979. *count = handle->transferSize - handle->txRemainingBytes;
  980. }
  981. return kStatus_Success;
  982. }
  983. /*!
  984. * brief Aborts the master data transfer, which used IRQ.
  985. *
  986. * param base Pointer to the FLEXIO_SPI_Type structure.
  987. * param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
  988. */
  989. void FLEXIO_SPI_MasterTransferAbort(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle)
  990. {
  991. assert(handle != NULL);
  992. FLEXIO_SPI_DisableInterrupts(base, (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable);
  993. FLEXIO_SPI_DisableInterrupts(base, (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable);
  994. /* Transfer finished, set the state to idle. */
  995. handle->state = (uint32_t)kFLEXIO_SPI_Idle;
  996. /* Clear the internal state. */
  997. handle->rxRemainingBytes = 0;
  998. handle->txRemainingBytes = 0;
  999. }
  1000. /*!
  1001. * brief FlexIO SPI master IRQ handler function.
  1002. *
  1003. * param spiType Pointer to the FLEXIO_SPI_Type structure.
  1004. * param spiHandle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
  1005. */
  1006. void FLEXIO_SPI_MasterTransferHandleIRQ(void *spiType, void *spiHandle)
  1007. {
  1008. assert(spiHandle != NULL);
  1009. flexio_spi_master_handle_t *handle = (flexio_spi_master_handle_t *)spiHandle;
  1010. FLEXIO_SPI_Type *base;
  1011. uint32_t status;
  1012. if (handle->state == (uint32_t)kFLEXIO_SPI_Idle)
  1013. {
  1014. return;
  1015. }
  1016. base = (FLEXIO_SPI_Type *)spiType;
  1017. status = FLEXIO_SPI_GetStatusFlags(base);
  1018. /* Handle rx. */
  1019. if (((status & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag) != 0U) && (handle->rxRemainingBytes != 0U))
  1020. {
  1021. FLEXIO_SPI_TransferReceiveTransaction(base, handle);
  1022. }
  1023. /* Handle tx. */
  1024. if (((status & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag) != 0U) && (handle->txRemainingBytes != 0U))
  1025. {
  1026. FLEXIO_SPI_TransferSendTransaction(base, handle);
  1027. }
  1028. /* All the transfer finished. */
  1029. if ((handle->txRemainingBytes == 0U) && (handle->rxRemainingBytes == 0U))
  1030. {
  1031. FLEXIO_SPI_MasterTransferAbort(base, handle);
  1032. if (handle->callback != NULL)
  1033. {
  1034. (handle->callback)(base, handle, kStatus_FLEXIO_SPI_Idle, handle->userData);
  1035. }
  1036. }
  1037. }
  1038. /*!
  1039. * brief Initializes the FlexIO SPI Slave handle, which is used in transactional functions.
  1040. *
  1041. * param base Pointer to the FLEXIO_SPI_Type structure.
  1042. * param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state.
  1043. * param callback The callback function.
  1044. * param userData The parameter of the callback function.
  1045. * retval kStatus_Success Successfully create the handle.
  1046. * retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
  1047. */
  1048. status_t FLEXIO_SPI_SlaveTransferCreateHandle(FLEXIO_SPI_Type *base,
  1049. flexio_spi_slave_handle_t *handle,
  1050. flexio_spi_slave_transfer_callback_t callback,
  1051. void *userData)
  1052. {
  1053. assert(handle != NULL);
  1054. IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
  1055. /* Zero the handle. */
  1056. (void)memset(handle, 0, sizeof(*handle));
  1057. /* Register callback and userData. */
  1058. handle->callback = callback;
  1059. handle->userData = userData;
  1060. /* Clear pending NVIC IRQ before enable NVIC IRQ. */
  1061. NVIC_ClearPendingIRQ(flexio_irqs[FLEXIO_SPI_GetInstance(base)]);
  1062. /* Enable interrupt in NVIC. */
  1063. (void)EnableIRQ(flexio_irqs[FLEXIO_SPI_GetInstance(base)]);
  1064. /* Save the context in global variables to support the double weak mechanism. */
  1065. return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_SPI_SlaveTransferHandleIRQ);
  1066. }
  1067. /*!
  1068. * brief Slave transfer data using IRQ.
  1069. *
  1070. * This function sends data using IRQ. This is a non-blocking function, which returns
  1071. * right away. When all data is sent out/received, the callback function is called.
  1072. * param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state.
  1073. *
  1074. * param base Pointer to the FLEXIO_SPI_Type structure.
  1075. * param xfer FlexIO SPI transfer structure. See #flexio_spi_transfer_t.
  1076. * retval kStatus_Success Successfully start a transfer.
  1077. * retval kStatus_InvalidArgument Input argument is invalid.
  1078. * retval kStatus_FLEXIO_SPI_Busy SPI is not idle; it is running another transfer.
  1079. */
  1080. status_t FLEXIO_SPI_SlaveTransferNonBlocking(FLEXIO_SPI_Type *base,
  1081. flexio_spi_slave_handle_t *handle,
  1082. flexio_spi_transfer_t *xfer)
  1083. {
  1084. assert(handle != NULL);
  1085. assert(xfer != NULL);
  1086. uint32_t dataMode = 0;
  1087. /* Check if SPI is busy. */
  1088. if (handle->state == (uint32_t)kFLEXIO_SPI_Busy)
  1089. {
  1090. return kStatus_FLEXIO_SPI_Busy;
  1091. }
  1092. /* Check if the argument is legal. */
  1093. if ((xfer->txData == NULL) && (xfer->rxData == NULL))
  1094. {
  1095. return kStatus_InvalidArgument;
  1096. }
  1097. /* Configure the values in handle */
  1098. switch (xfer->flags)
  1099. {
  1100. case (uint8_t)kFLEXIO_SPI_8bitMsb:
  1101. dataMode = 8U * 2U - 1U;
  1102. handle->bytePerFrame = 1U;
  1103. handle->direction = kFLEXIO_SPI_MsbFirst;
  1104. break;
  1105. case (uint8_t)kFLEXIO_SPI_8bitLsb:
  1106. dataMode = 8U * 2U - 1U;
  1107. handle->bytePerFrame = 1U;
  1108. handle->direction = kFLEXIO_SPI_LsbFirst;
  1109. break;
  1110. case (uint8_t)kFLEXIO_SPI_16bitMsb:
  1111. dataMode = 16U * 2U - 1U;
  1112. handle->bytePerFrame = 2U;
  1113. handle->direction = kFLEXIO_SPI_MsbFirst;
  1114. break;
  1115. case (uint8_t)kFLEXIO_SPI_16bitLsb:
  1116. dataMode = 16U * 2U - 1U;
  1117. handle->bytePerFrame = 2U;
  1118. handle->direction = kFLEXIO_SPI_LsbFirst;
  1119. break;
  1120. default:
  1121. dataMode = 8U * 2U - 1U;
  1122. handle->bytePerFrame = 1U;
  1123. handle->direction = kFLEXIO_SPI_MsbFirst;
  1124. assert(true);
  1125. break;
  1126. }
  1127. /* Configure transfer size. */
  1128. base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
  1129. handle->state = (uint32_t)kFLEXIO_SPI_Busy;
  1130. handle->txData = xfer->txData;
  1131. handle->rxData = xfer->rxData;
  1132. handle->txRemainingBytes = xfer->dataSize;
  1133. handle->rxRemainingBytes = xfer->dataSize;
  1134. /* Save total transfer size. */
  1135. handle->transferSize = xfer->dataSize;
  1136. /* Enable transmit and receive interrupt to handle tx and rx. */
  1137. FLEXIO_SPI_EnableInterrupts(base, (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable);
  1138. FLEXIO_SPI_EnableInterrupts(base, (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable);
  1139. return kStatus_Success;
  1140. }
  1141. /*!
  1142. * brief FlexIO SPI slave IRQ handler function.
  1143. *
  1144. * param spiType Pointer to the FLEXIO_SPI_Type structure.
  1145. * param spiHandle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state.
  1146. */
  1147. void FLEXIO_SPI_SlaveTransferHandleIRQ(void *spiType, void *spiHandle)
  1148. {
  1149. assert(spiHandle != NULL);
  1150. flexio_spi_master_handle_t *handle = (flexio_spi_master_handle_t *)spiHandle;
  1151. FLEXIO_SPI_Type *base;
  1152. uint32_t status;
  1153. if (handle->state == (uint32_t)kFLEXIO_SPI_Idle)
  1154. {
  1155. return;
  1156. }
  1157. base = (FLEXIO_SPI_Type *)spiType;
  1158. status = FLEXIO_SPI_GetStatusFlags(base);
  1159. /* Handle tx. */
  1160. if (((status & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag) != 0U) && (handle->txRemainingBytes != 0U))
  1161. {
  1162. FLEXIO_SPI_TransferSendTransaction(base, handle);
  1163. }
  1164. /* Handle rx. */
  1165. if (((status & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag) != 0U) && (handle->rxRemainingBytes != 0U))
  1166. {
  1167. FLEXIO_SPI_TransferReceiveTransaction(base, handle);
  1168. }
  1169. /* All the transfer finished. */
  1170. if ((handle->txRemainingBytes == 0U) && (handle->rxRemainingBytes == 0U))
  1171. {
  1172. FLEXIO_SPI_SlaveTransferAbort(base, handle);
  1173. if (handle->callback != NULL)
  1174. {
  1175. (handle->callback)(base, handle, kStatus_FLEXIO_SPI_Idle, handle->userData);
  1176. }
  1177. }
  1178. }