nu_spi.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. /**************************************************************************//**
  2. * @file spi.c
  3. * @brief NUC980 series SPI driver source file
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. * @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
  7. *****************************************************************************/
  8. #include "nuc980.h"
  9. #include "nu_spi.h"
  10. /** @addtogroup Standard_Driver Standard Driver
  11. @{
  12. */
  13. /** @addtogroup SPI_Driver SPI Driver
  14. @{
  15. */
  16. /** @addtogroup SPI_EXPORTED_FUNCTIONS SPI Exported Functions
  17. @{
  18. */
  19. /**
  20. * @brief This function make SPI module be ready to transfer.
  21. * @param[in] spi The pointer of the specified SPI module.
  22. * @param[in] u32MasterSlave Decides the SPI module is operating in master mode or in slave mode. (SPI_SLAVE, SPI_MASTER)
  23. * @param[in] u32SPIMode Decides the transfer timing. (SPI_MODE_0, SPI_MODE_1, SPI_MODE_2, SPI_MODE_3)
  24. * @param[in] u32DataWidth Decides the data width of a SPI transaction.
  25. * @param[in] u32BusClock The expected frequency of SPI bus clock in Hz.
  26. * @return Actual frequency of SPI peripheral clock.
  27. * @details By default, the SPI transfer sequence is MSB first, the slave selection signal is active low and the automatic
  28. * slave selection function is disabled.
  29. * In Slave mode, the u32BusClock shall be NULL and the SPI clock divider setting will be 0.
  30. * The actual clock rate may be different from the target SPI clock rate.
  31. * For example, if the SPI source clock rate is 12 MHz and the target SPI bus clock rate is 7 MHz, the
  32. * actual SPI clock rate will be 6MHz.
  33. * @note If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
  34. * @note If u32BusClock >= system clock frequency, SPI peripheral clock source will be set to APB clock and DIVIDER will be set to 0.
  35. * @note If u32BusClock >= SPI peripheral clock source, DIVIDER will be set to 0.
  36. * @note In slave mode, the SPI peripheral clock rate will be equal to APB clock rate.
  37. */
  38. uint32_t SPI_Open(SPI_T *spi,
  39. uint32_t u32MasterSlave,
  40. uint32_t u32SPIMode,
  41. uint32_t u32DataWidth,
  42. uint32_t u32BusClock)
  43. {
  44. uint32_t u32RetValue = 0U;
  45. if (u32DataWidth == 32U)
  46. {
  47. u32DataWidth = 0U;
  48. }
  49. if (u32MasterSlave == SPI_MASTER)
  50. {
  51. /* Default setting: slave selection signal is active low; disable automatic slave selection function. */
  52. spi->SSCTL = SPI_SS_ACTIVE_LOW;
  53. /* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */
  54. spi->CTL = u32MasterSlave | (u32DataWidth << SPI_CTL_DWIDTH_Pos) | (u32SPIMode) | SPI_CTL_SPIEN_Msk;
  55. /* Set DIVIDER */
  56. spi->CLKDIV = (150000000U / u32BusClock) - 1U;
  57. }
  58. else /* For slave mode, force the SPI peripheral clock rate to equal APB clock rate. */
  59. {
  60. /* Default setting: slave selection signal is low level active. */
  61. spi->SSCTL = SPI_SS_ACTIVE_LOW;
  62. /* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */
  63. spi->CTL = u32MasterSlave | (u32DataWidth << SPI_CTL_DWIDTH_Pos) | (u32SPIMode) | SPI_CTL_SPIEN_Msk;
  64. /* Set DIVIDER = 1, let slave runs at PCLK/2 = 75MHz */
  65. spi->CLKDIV = 1U;
  66. }
  67. return u32RetValue;
  68. }
  69. /**
  70. * @brief Disable SPI controller.
  71. * @param[in] spi The pointer of the specified SPI module.
  72. * @return None
  73. * @details This function will reset SPI controller.
  74. */
  75. void SPI_Close(SPI_T *spi)
  76. {
  77. if (spi == SPI0)
  78. {
  79. /* Reset SPI */
  80. }
  81. else
  82. {
  83. /* Reset SPI */
  84. }
  85. }
  86. /**
  87. * @brief Clear RX FIFO buffer.
  88. * @param[in] spi The pointer of the specified SPI module.
  89. * @return None
  90. * @details This function will clear SPI RX FIFO buffer. The RXEMPTY (SPI_STATUS[8]) will be set to 1.
  91. */
  92. void SPI_ClearRxFIFO(SPI_T *spi)
  93. {
  94. spi->FIFOCTL |= SPI_FIFOCTL_RXFBCLR_Msk;
  95. }
  96. /**
  97. * @brief Clear TX FIFO buffer.
  98. * @param[in] spi The pointer of the specified SPI module.
  99. * @return None
  100. * @details This function will clear SPI TX FIFO buffer. The TXEMPTY (SPI_STATUS[16]) will be set to 1.
  101. * @note The TX shift register will not be cleared.
  102. */
  103. void SPI_ClearTxFIFO(SPI_T *spi)
  104. {
  105. spi->FIFOCTL |= SPI_FIFOCTL_TXFBCLR_Msk;
  106. }
  107. /**
  108. * @brief Disable the automatic slave selection function.
  109. * @param[in] spi The pointer of the specified SPI module.
  110. * @return None
  111. * @details This function will disable the automatic slave selection function and set slave selection signal to inactive state.
  112. */
  113. void SPI_DisableAutoSS(SPI_T *spi)
  114. {
  115. spi->SSCTL &= ~(SPI_SSCTL_AUTOSS_Msk | SPI_SSCTL_SS_Msk);
  116. }
  117. /**
  118. * @brief Enable the automatic slave selection function.
  119. * @param[in] spi The pointer of the specified SPI module.
  120. * @param[in] u32SSPinMask Specifies slave selection pins. (SPI_SS)
  121. * @param[in] u32ActiveLevel Specifies the active level of slave selection signal. (SPI_SS_ACTIVE_HIGH, SPI_SS_ACTIVE_LOW)
  122. * @return None
  123. * @details This function will enable the automatic slave selection function. Only available in Master mode.
  124. * The slave selection pin and the active level will be set in this function.
  125. */
  126. void SPI_EnableAutoSS(SPI_T *spi, uint32_t u32SSPinMask, uint32_t u32ActiveLevel)
  127. {
  128. spi->SSCTL = (spi->SSCTL & (~(SPI_SSCTL_AUTOSS_Msk | SPI_SSCTL_SSACTPOL_Msk | SPI_SSCTL_SS_Msk))) | (u32SSPinMask | u32ActiveLevel | SPI_SSCTL_AUTOSS_Msk);
  129. }
  130. /**
  131. * @brief Configure FIFO threshold setting.
  132. * @param[in] spi The pointer of the specified SPI module.
  133. * @param[in] u32TxThreshold Decides the TX FIFO threshold. It could be 0 ~ 3.
  134. * @param[in] u32RxThreshold Decides the RX FIFO threshold. It could be 0 ~ 3.
  135. * @return None
  136. * @details Set TX FIFO threshold and RX FIFO threshold configurations.
  137. */
  138. void SPI_SetFIFO(SPI_T *spi, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
  139. {
  140. spi->FIFOCTL = (spi->FIFOCTL & ~(SPI_FIFOCTL_TXTH_Msk | SPI_FIFOCTL_RXTH_Msk)) |
  141. (u32TxThreshold << SPI_FIFOCTL_TXTH_Pos) |
  142. (u32RxThreshold << SPI_FIFOCTL_RXTH_Pos);
  143. }
  144. /**
  145. * @brief Get the actual frequency of SPI bus clock. Only available in Master mode.
  146. * @param[in] spi The pointer of the specified SPI module.
  147. * @return Actual SPI bus clock frequency in Hz.
  148. * @details This function will calculate the actual SPI bus clock rate according to the SPInSEL and DIVIDER settings. Only available in Master mode.
  149. */
  150. uint32_t SPI_GetBusClock(SPI_T *spi)
  151. {
  152. return 0;
  153. }
  154. /**
  155. * @brief Set the SPI bus clock.
  156. * @param[in] spi The pointer of the specified SPI module.
  157. * @param[in] u32BusClock The expected frequency of SPI bus clock in Hz.
  158. * @return Actual frequency of SPI bus clock.
  159. */
  160. uint32_t SPI_SetBusClock(SPI_T *spi, uint32_t u32BusClock)
  161. {
  162. /* Set DIVIDER */
  163. if (spi->CTL & SPI_CTL_SLAVE_Msk) //Slave
  164. spi->CLKDIV = 1;
  165. else //Master
  166. spi->CLKDIV = (150000000U / u32BusClock) - 1U;
  167. return SPI_GetBusClock(spi);
  168. }
  169. /**
  170. * @brief Enable interrupt function.
  171. * @param[in] spi The pointer of the specified SPI module.
  172. * @param[in] u32Mask The combination of all related interrupt enable bits.
  173. * Each bit corresponds to a interrupt enable bit.
  174. * This parameter decides which interrupts will be enabled. It is combination of:
  175. * - \ref SPI_UNIT_INT_MASK
  176. * - \ref SPI_SSACT_INT_MASK
  177. * - \ref SPI_SSINACT_INT_MASK
  178. * - \ref SPI_SLVUR_INT_MASK
  179. * - \ref SPI_SLVBE_INT_MASK
  180. * - \ref SPI_TXUF_INT_MASK
  181. * - \ref SPI_FIFO_TXTH_INT_MASK
  182. * - \ref SPI_FIFO_RXTH_INT_MASK
  183. * - \ref SPI_FIFO_RXOV_INT_MASK
  184. * - \ref SPI_FIFO_RXTO_INT_MASK
  185. *
  186. * @return None
  187. * @details Enable SPI related interrupts specified by u32Mask parameter.
  188. */
  189. void SPI_EnableInt(SPI_T *spi, uint32_t u32Mask)
  190. {
  191. /* Enable unit transfer interrupt flag */
  192. if ((u32Mask & SPI_UNIT_INT_MASK) == SPI_UNIT_INT_MASK)
  193. {
  194. spi->CTL |= SPI_CTL_UNITIEN_Msk;
  195. }
  196. /* Enable slave selection signal active interrupt flag */
  197. if ((u32Mask & SPI_SSACT_INT_MASK) == SPI_SSACT_INT_MASK)
  198. {
  199. spi->SSCTL |= SPI_SSCTL_SSACTIEN_Msk;
  200. }
  201. /* Enable slave selection signal inactive interrupt flag */
  202. if ((u32Mask & SPI_SSINACT_INT_MASK) == SPI_SSINACT_INT_MASK)
  203. {
  204. spi->SSCTL |= SPI_SSCTL_SSINAIEN_Msk;
  205. }
  206. /* Enable slave TX under run interrupt flag */
  207. if ((u32Mask & SPI_SLVUR_INT_MASK) == SPI_SLVUR_INT_MASK)
  208. {
  209. spi->SSCTL |= SPI_SSCTL_SLVURIEN_Msk;
  210. }
  211. /* Enable slave bit count error interrupt flag */
  212. if ((u32Mask & SPI_SLVBE_INT_MASK) == SPI_SLVBE_INT_MASK)
  213. {
  214. spi->SSCTL |= SPI_SSCTL_SLVBEIEN_Msk;
  215. }
  216. /* Enable slave TX underflow interrupt flag */
  217. if ((u32Mask & SPI_TXUF_INT_MASK) == SPI_TXUF_INT_MASK)
  218. {
  219. spi->FIFOCTL |= SPI_FIFOCTL_TXUFIEN_Msk;
  220. }
  221. /* Enable TX threshold interrupt flag */
  222. if ((u32Mask & SPI_FIFO_TXTH_INT_MASK) == SPI_FIFO_TXTH_INT_MASK)
  223. {
  224. spi->FIFOCTL |= SPI_FIFOCTL_TXTHIEN_Msk;
  225. }
  226. /* Enable RX threshold interrupt flag */
  227. if ((u32Mask & SPI_FIFO_RXTH_INT_MASK) == SPI_FIFO_RXTH_INT_MASK)
  228. {
  229. spi->FIFOCTL |= SPI_FIFOCTL_RXTHIEN_Msk;
  230. }
  231. /* Enable RX overrun interrupt flag */
  232. if ((u32Mask & SPI_FIFO_RXOV_INT_MASK) == SPI_FIFO_RXOV_INT_MASK)
  233. {
  234. spi->FIFOCTL |= SPI_FIFOCTL_RXOVIEN_Msk;
  235. }
  236. /* Enable RX time-out interrupt flag */
  237. if ((u32Mask & SPI_FIFO_RXTO_INT_MASK) == SPI_FIFO_RXTO_INT_MASK)
  238. {
  239. spi->FIFOCTL |= SPI_FIFOCTL_RXTOIEN_Msk;
  240. }
  241. }
  242. /**
  243. * @brief Disable interrupt function.
  244. * @param[in] spi The pointer of the specified SPI module.
  245. * @param[in] u32Mask The combination of all related interrupt enable bits.
  246. * Each bit corresponds to a interrupt bit.
  247. * This parameter decides which interrupts will be disabled. It is combination of:
  248. * - \ref SPI_UNIT_INT_MASK
  249. * - \ref SPI_SSACT_INT_MASK
  250. * - \ref SPI_SSINACT_INT_MASK
  251. * - \ref SPI_SLVUR_INT_MASK
  252. * - \ref SPI_SLVBE_INT_MASK
  253. * - \ref SPI_TXUF_INT_MASK
  254. * - \ref SPI_FIFO_TXTH_INT_MASK
  255. * - \ref SPI_FIFO_RXTH_INT_MASK
  256. * - \ref SPI_FIFO_RXOV_INT_MASK
  257. * - \ref SPI_FIFO_RXTO_INT_MASK
  258. *
  259. * @return None
  260. * @details Disable SPI related interrupts specified by u32Mask parameter.
  261. */
  262. void SPI_DisableInt(SPI_T *spi, uint32_t u32Mask)
  263. {
  264. /* Disable unit transfer interrupt flag */
  265. if ((u32Mask & SPI_UNIT_INT_MASK) == SPI_UNIT_INT_MASK)
  266. {
  267. spi->CTL &= ~SPI_CTL_UNITIEN_Msk;
  268. }
  269. /* Disable slave selection signal active interrupt flag */
  270. if ((u32Mask & SPI_SSACT_INT_MASK) == SPI_SSACT_INT_MASK)
  271. {
  272. spi->SSCTL &= ~SPI_SSCTL_SSACTIEN_Msk;
  273. }
  274. /* Disable slave selection signal inactive interrupt flag */
  275. if ((u32Mask & SPI_SSINACT_INT_MASK) == SPI_SSINACT_INT_MASK)
  276. {
  277. spi->SSCTL &= ~SPI_SSCTL_SSINAIEN_Msk;
  278. }
  279. /* Disable slave TX under run interrupt flag */
  280. if ((u32Mask & SPI_SLVUR_INT_MASK) == SPI_SLVUR_INT_MASK)
  281. {
  282. spi->SSCTL &= ~SPI_SSCTL_SLVURIEN_Msk;
  283. }
  284. /* Disable slave bit count error interrupt flag */
  285. if ((u32Mask & SPI_SLVBE_INT_MASK) == SPI_SLVBE_INT_MASK)
  286. {
  287. spi->SSCTL &= ~SPI_SSCTL_SLVBEIEN_Msk;
  288. }
  289. /* Disable slave TX underflow interrupt flag */
  290. if ((u32Mask & SPI_TXUF_INT_MASK) == SPI_TXUF_INT_MASK)
  291. {
  292. spi->FIFOCTL &= ~SPI_FIFOCTL_TXUFIEN_Msk;
  293. }
  294. /* Disable TX threshold interrupt flag */
  295. if ((u32Mask & SPI_FIFO_TXTH_INT_MASK) == SPI_FIFO_TXTH_INT_MASK)
  296. {
  297. spi->FIFOCTL &= ~SPI_FIFOCTL_TXTHIEN_Msk;
  298. }
  299. /* Disable RX threshold interrupt flag */
  300. if ((u32Mask & SPI_FIFO_RXTH_INT_MASK) == SPI_FIFO_RXTH_INT_MASK)
  301. {
  302. spi->FIFOCTL &= ~SPI_FIFOCTL_RXTHIEN_Msk;
  303. }
  304. /* Disable RX overrun interrupt flag */
  305. if ((u32Mask & SPI_FIFO_RXOV_INT_MASK) == SPI_FIFO_RXOV_INT_MASK)
  306. {
  307. spi->FIFOCTL &= ~SPI_FIFOCTL_RXOVIEN_Msk;
  308. }
  309. /* Disable RX time-out interrupt flag */
  310. if ((u32Mask & SPI_FIFO_RXTO_INT_MASK) == SPI_FIFO_RXTO_INT_MASK)
  311. {
  312. spi->FIFOCTL &= ~SPI_FIFOCTL_RXTOIEN_Msk;
  313. }
  314. }
  315. /**
  316. * @brief Get interrupt flag.
  317. * @param[in] spi The pointer of the specified SPI module.
  318. * @param[in] u32Mask The combination of all related interrupt sources.
  319. * Each bit corresponds to a interrupt source.
  320. * This parameter decides which interrupt flags will be read. It is combination of:
  321. * - \ref SPI_UNIT_INT_MASK
  322. * - \ref SPI_SSACT_INT_MASK
  323. * - \ref SPI_SSINACT_INT_MASK
  324. * - \ref SPI_SLVUR_INT_MASK
  325. * - \ref SPI_SLVBE_INT_MASK
  326. * - \ref SPI_TXUF_INT_MASK
  327. * - \ref SPI_FIFO_TXTH_INT_MASK
  328. * - \ref SPI_FIFO_RXTH_INT_MASK
  329. * - \ref SPI_FIFO_RXOV_INT_MASK
  330. * - \ref SPI_FIFO_RXTO_INT_MASK
  331. *
  332. * @return Interrupt flags of selected sources.
  333. * @details Get SPI related interrupt flags specified by u32Mask parameter.
  334. */
  335. uint32_t SPI_GetIntFlag(SPI_T *spi, uint32_t u32Mask)
  336. {
  337. uint32_t u32IntFlag = 0U, u32TmpVal;
  338. u32TmpVal = spi->STATUS & SPI_STATUS_UNITIF_Msk;
  339. /* Check unit transfer interrupt flag */
  340. if ((u32Mask & SPI_UNIT_INT_MASK) && (u32TmpVal))
  341. {
  342. u32IntFlag |= SPI_UNIT_INT_MASK;
  343. }
  344. u32TmpVal = spi->STATUS & SPI_STATUS_SSACTIF_Msk;
  345. /* Check slave selection signal active interrupt flag */
  346. if ((u32Mask & SPI_SSACT_INT_MASK) && (u32TmpVal))
  347. {
  348. u32IntFlag |= SPI_SSACT_INT_MASK;
  349. }
  350. u32TmpVal = spi->STATUS & SPI_STATUS_SSINAIF_Msk;
  351. /* Check slave selection signal inactive interrupt flag */
  352. if ((u32Mask & SPI_SSINACT_INT_MASK) && (u32TmpVal))
  353. {
  354. u32IntFlag |= SPI_SSINACT_INT_MASK;
  355. }
  356. u32TmpVal = spi->STATUS & SPI_STATUS_SLVURIF_Msk;
  357. /* Check slave TX under run interrupt flag */
  358. if ((u32Mask & SPI_SLVUR_INT_MASK) && (u32TmpVal))
  359. {
  360. u32IntFlag |= SPI_SLVUR_INT_MASK;
  361. }
  362. u32TmpVal = spi->STATUS & SPI_STATUS_SLVBEIF_Msk;
  363. /* Check slave bit count error interrupt flag */
  364. if ((u32Mask & SPI_SLVBE_INT_MASK) && (u32TmpVal))
  365. {
  366. u32IntFlag |= SPI_SLVBE_INT_MASK;
  367. }
  368. u32TmpVal = spi->STATUS & SPI_STATUS_TXUFIF_Msk;
  369. /* Check slave TX underflow interrupt flag */
  370. if ((u32Mask & SPI_TXUF_INT_MASK) && (u32TmpVal))
  371. {
  372. u32IntFlag |= SPI_TXUF_INT_MASK;
  373. }
  374. u32TmpVal = spi->STATUS & SPI_STATUS_TXTHIF_Msk;
  375. /* Check TX threshold interrupt flag */
  376. if ((u32Mask & SPI_FIFO_TXTH_INT_MASK) && (u32TmpVal))
  377. {
  378. u32IntFlag |= SPI_FIFO_TXTH_INT_MASK;
  379. }
  380. u32TmpVal = spi->STATUS & SPI_STATUS_RXTHIF_Msk;
  381. /* Check RX threshold interrupt flag */
  382. if ((u32Mask & SPI_FIFO_RXTH_INT_MASK) && (u32TmpVal))
  383. {
  384. u32IntFlag |= SPI_FIFO_RXTH_INT_MASK;
  385. }
  386. u32TmpVal = spi->STATUS & SPI_STATUS_RXOVIF_Msk;
  387. /* Check RX overrun interrupt flag */
  388. if ((u32Mask & SPI_FIFO_RXOV_INT_MASK) && (u32TmpVal))
  389. {
  390. u32IntFlag |= SPI_FIFO_RXOV_INT_MASK;
  391. }
  392. u32TmpVal = spi->STATUS & SPI_STATUS_RXTOIF_Msk;
  393. /* Check RX time-out interrupt flag */
  394. if ((u32Mask & SPI_FIFO_RXTO_INT_MASK) && (u32TmpVal))
  395. {
  396. u32IntFlag |= SPI_FIFO_RXTO_INT_MASK;
  397. }
  398. return u32IntFlag;
  399. }
  400. /**
  401. * @brief Clear interrupt flag.
  402. * @param[in] spi The pointer of the specified SPI module.
  403. * @param[in] u32Mask The combination of all related interrupt sources.
  404. * Each bit corresponds to a interrupt source.
  405. * This parameter decides which interrupt flags will be cleared. It could be the combination of:
  406. * - \ref SPI_UNIT_INT_MASK
  407. * - \ref SPI_SSACT_INT_MASK
  408. * - \ref SPI_SSINACT_INT_MASK
  409. * - \ref SPI_SLVUR_INT_MASK
  410. * - \ref SPI_SLVBE_INT_MASK
  411. * - \ref SPI_TXUF_INT_MASK
  412. * - \ref SPI_FIFO_RXOV_INT_MASK
  413. * - \ref SPI_FIFO_RXTO_INT_MASK
  414. *
  415. * @return None
  416. * @details Clear SPI related interrupt flags specified by u32Mask parameter.
  417. */
  418. void SPI_ClearIntFlag(SPI_T *spi, uint32_t u32Mask)
  419. {
  420. if (u32Mask & SPI_UNIT_INT_MASK)
  421. {
  422. spi->STATUS = SPI_STATUS_UNITIF_Msk; /* Clear unit transfer interrupt flag */
  423. }
  424. if (u32Mask & SPI_SSACT_INT_MASK)
  425. {
  426. spi->STATUS = SPI_STATUS_SSACTIF_Msk; /* Clear slave selection signal active interrupt flag */
  427. }
  428. if (u32Mask & SPI_SSINACT_INT_MASK)
  429. {
  430. spi->STATUS = SPI_STATUS_SSINAIF_Msk; /* Clear slave selection signal inactive interrupt flag */
  431. }
  432. if (u32Mask & SPI_SLVUR_INT_MASK)
  433. {
  434. spi->STATUS = SPI_STATUS_SLVURIF_Msk; /* Clear slave TX under run interrupt flag */
  435. }
  436. if (u32Mask & SPI_SLVBE_INT_MASK)
  437. {
  438. spi->STATUS = SPI_STATUS_SLVBEIF_Msk; /* Clear slave bit count error interrupt flag */
  439. }
  440. if (u32Mask & SPI_TXUF_INT_MASK)
  441. {
  442. spi->STATUS = SPI_STATUS_TXUFIF_Msk; /* Clear slave TX underflow interrupt flag */
  443. }
  444. if (u32Mask & SPI_FIFO_RXOV_INT_MASK)
  445. {
  446. spi->STATUS = SPI_STATUS_RXOVIF_Msk; /* Clear RX overrun interrupt flag */
  447. }
  448. if (u32Mask & SPI_FIFO_RXTO_INT_MASK)
  449. {
  450. spi->STATUS = SPI_STATUS_RXTOIF_Msk; /* Clear RX time-out interrupt flag */
  451. }
  452. }
  453. /**
  454. * @brief Get SPI status.
  455. * @param[in] spi The pointer of the specified SPI module.
  456. * @param[in] u32Mask The combination of all related sources.
  457. * Each bit corresponds to a source.
  458. * This parameter decides which flags will be read. It is combination of:
  459. * - \ref SPI_BUSY_MASK
  460. * - \ref SPI_RX_EMPTY_MASK
  461. * - \ref SPI_RX_FULL_MASK
  462. * - \ref SPI_TX_EMPTY_MASK
  463. * - \ref SPI_TX_FULL_MASK
  464. * - \ref SPI_TXRX_RESET_MASK
  465. * - \ref SPI_SPIEN_STS_MASK
  466. * - \ref SPI_SSLINE_STS_MASK
  467. *
  468. * @return Flags of selected sources.
  469. * @details Get SPI related status specified by u32Mask parameter.
  470. */
  471. uint32_t SPI_GetStatus(SPI_T *spi, uint32_t u32Mask)
  472. {
  473. uint32_t u32Flag = 0U, u32TmpValue;
  474. u32TmpValue = spi->STATUS & SPI_STATUS_BUSY_Msk;
  475. /* Check busy status */
  476. if ((u32Mask & SPI_BUSY_MASK) && (u32TmpValue))
  477. {
  478. u32Flag |= SPI_BUSY_MASK;
  479. }
  480. u32TmpValue = spi->STATUS & SPI_STATUS_RXEMPTY_Msk;
  481. /* Check RX empty flag */
  482. if ((u32Mask & SPI_RX_EMPTY_MASK) && (u32TmpValue))
  483. {
  484. u32Flag |= SPI_RX_EMPTY_MASK;
  485. }
  486. u32TmpValue = spi->STATUS & SPI_STATUS_RXFULL_Msk;
  487. /* Check RX full flag */
  488. if ((u32Mask & SPI_RX_FULL_MASK) && (u32TmpValue))
  489. {
  490. u32Flag |= SPI_RX_FULL_MASK;
  491. }
  492. u32TmpValue = spi->STATUS & SPI_STATUS_TXEMPTY_Msk;
  493. /* Check TX empty flag */
  494. if ((u32Mask & SPI_TX_EMPTY_MASK) && (u32TmpValue))
  495. {
  496. u32Flag |= SPI_TX_EMPTY_MASK;
  497. }
  498. u32TmpValue = spi->STATUS & SPI_STATUS_TXFULL_Msk;
  499. /* Check TX full flag */
  500. if ((u32Mask & SPI_TX_FULL_MASK) && (u32TmpValue))
  501. {
  502. u32Flag |= SPI_TX_FULL_MASK;
  503. }
  504. u32TmpValue = spi->STATUS & SPI_STATUS_TXRXRST_Msk;
  505. /* Check TX/RX reset flag */
  506. if ((u32Mask & SPI_TXRX_RESET_MASK) && (u32TmpValue))
  507. {
  508. u32Flag |= SPI_TXRX_RESET_MASK;
  509. }
  510. u32TmpValue = spi->STATUS & SPI_STATUS_SPIENSTS_Msk;
  511. /* Check SPIEN flag */
  512. if ((u32Mask & SPI_SPIEN_STS_MASK) && (u32TmpValue))
  513. {
  514. u32Flag |= SPI_SPIEN_STS_MASK;
  515. }
  516. u32TmpValue = spi->STATUS & SPI_STATUS_SSLINE_Msk;
  517. /* Check SPIx_SS line status */
  518. if ((u32Mask & SPI_SSLINE_STS_MASK) && (u32TmpValue))
  519. {
  520. u32Flag |= SPI_SSLINE_STS_MASK;
  521. }
  522. return u32Flag;
  523. }
  524. /*@}*/ /* end of group SPI_EXPORTED_FUNCTIONS */
  525. /*@}*/ /* end of group SPI_Driver */
  526. /*@}*/ /* end of group Standard_Driver */
  527. /*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/