spi.c 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442
  1. /**************************************************************************//**
  2. * @file spi.c
  3. * @version V3.00
  4. * @brief M480 series SPI driver source file
  5. *
  6. * @copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
  7. *****************************************************************************/
  8. #include "NuMicro.h"
  9. /** @addtogroup Standard_Driver Standard Driver
  10. @{
  11. */
  12. /** @addtogroup SPI_Driver SPI Driver
  13. @{
  14. */
  15. /** @addtogroup SPI_EXPORTED_FUNCTIONS SPI Exported Functions
  16. @{
  17. */
  18. static uint32_t SPII2S_GetSourceClockFreq(SPI_T *i2s);
  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 u32ClkSrc = 0U, u32Div, u32HCLKFreq, u32RetValue=0U;
  45. /* Disable I2S mode */
  46. spi->I2SCTL &= ~SPI_I2SCTL_I2SEN_Msk;
  47. if(u32DataWidth == 32U)
  48. {
  49. u32DataWidth = 0U;
  50. }
  51. /* Get system clock frequency */
  52. u32HCLKFreq = CLK_GetHCLKFreq();
  53. if(u32MasterSlave == SPI_MASTER)
  54. {
  55. /* Default setting: slave selection signal is active low; disable automatic slave selection function. */
  56. spi->SSCTL = SPI_SS_ACTIVE_LOW;
  57. /* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */
  58. spi->CTL = u32MasterSlave | (u32DataWidth << SPI_CTL_DWIDTH_Pos) | (u32SPIMode) | SPI_CTL_SPIEN_Msk;
  59. if(u32BusClock >= u32HCLKFreq)
  60. {
  61. /* Select PCLK as the clock source of SPI */
  62. if(spi == SPI0)
  63. {
  64. CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK1;
  65. }
  66. else if(spi == SPI1)
  67. {
  68. CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK0;
  69. }
  70. else if(spi == SPI2)
  71. {
  72. CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI2SEL_Msk)) | CLK_CLKSEL2_SPI2SEL_PCLK1;
  73. }
  74. else
  75. {
  76. CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI3SEL_Msk)) | CLK_CLKSEL2_SPI3SEL_PCLK0;
  77. }
  78. }
  79. /* Check clock source of SPI */
  80. if(spi == SPI0)
  81. {
  82. if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HXT)
  83. {
  84. u32ClkSrc = __HXT; /* Clock source is HXT */
  85. }
  86. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PLL)
  87. {
  88. u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
  89. }
  90. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PCLK1)
  91. {
  92. /* Clock source is PCLK1 */
  93. u32ClkSrc = CLK_GetPCLK1Freq();
  94. }
  95. else
  96. {
  97. u32ClkSrc = __HIRC; /* Clock source is HIRC */
  98. }
  99. }
  100. else if(spi == SPI1)
  101. {
  102. if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HXT)
  103. {
  104. u32ClkSrc = __HXT; /* Clock source is HXT */
  105. }
  106. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PLL)
  107. {
  108. u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
  109. }
  110. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PCLK0)
  111. {
  112. /* Clock source is PCLK0 */
  113. u32ClkSrc = CLK_GetPCLK0Freq();
  114. }
  115. else
  116. {
  117. u32ClkSrc = __HIRC; /* Clock source is HIRC */
  118. }
  119. }
  120. else if(spi == SPI2)
  121. {
  122. if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_HXT)
  123. {
  124. u32ClkSrc = __HXT; /* Clock source is HXT */
  125. }
  126. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_PLL)
  127. {
  128. u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
  129. }
  130. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_PCLK1)
  131. {
  132. u32ClkSrc = CLK_GetPCLK1Freq();
  133. }
  134. else
  135. {
  136. u32ClkSrc = __HIRC; /* Clock source is HIRC */
  137. }
  138. }
  139. else
  140. {
  141. if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI3SEL_Msk) == CLK_CLKSEL2_SPI3SEL_HXT)
  142. {
  143. u32ClkSrc = __HXT; /* Clock source is HXT */
  144. }
  145. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI3SEL_Msk) == CLK_CLKSEL2_SPI3SEL_PLL)
  146. {
  147. u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
  148. }
  149. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI3SEL_Msk) == CLK_CLKSEL2_SPI3SEL_PCLK0)
  150. {
  151. /* Clock source is PCLK0 */
  152. u32ClkSrc = CLK_GetPCLK0Freq();
  153. }
  154. else
  155. {
  156. u32ClkSrc = __HIRC; /* Clock source is HIRC */
  157. }
  158. }
  159. if(u32BusClock >= u32HCLKFreq)
  160. {
  161. /* Set DIVIDER = 0 */
  162. spi->CLKDIV = 0U;
  163. /* Return master peripheral clock rate */
  164. u32RetValue = u32ClkSrc;
  165. }
  166. else if(u32BusClock >= u32ClkSrc)
  167. {
  168. /* Set DIVIDER = 0 */
  169. spi->CLKDIV = 0U;
  170. /* Return master peripheral clock rate */
  171. u32RetValue = u32ClkSrc;
  172. }
  173. else if(u32BusClock == 0U)
  174. {
  175. /* Set DIVIDER to the maximum value 0xFF. f_spi = f_spi_clk_src / (DIVIDER + 1) */
  176. spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk;
  177. /* Return master peripheral clock rate */
  178. u32RetValue = (u32ClkSrc / (0xFFU + 1U));
  179. }
  180. else
  181. {
  182. u32Div = (((u32ClkSrc * 10U) / u32BusClock + 5U) / 10U) - 1U; /* Round to the nearest integer */
  183. if(u32Div > 0xFFU)
  184. {
  185. u32Div = 0xFFU;
  186. spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk;
  187. /* Return master peripheral clock rate */
  188. u32RetValue = (u32ClkSrc / (0xFFU + 1U));
  189. }
  190. else
  191. {
  192. spi->CLKDIV = (spi->CLKDIV & (~SPI_CLKDIV_DIVIDER_Msk)) | (u32Div << SPI_CLKDIV_DIVIDER_Pos);
  193. /* Return master peripheral clock rate */
  194. u32RetValue = (u32ClkSrc / (u32Div + 1U));
  195. }
  196. }
  197. }
  198. else /* For slave mode, force the SPI peripheral clock rate to equal APB clock rate. */
  199. {
  200. /* Default setting: slave selection signal is low level active. */
  201. spi->SSCTL = SPI_SS_ACTIVE_LOW;
  202. /* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */
  203. spi->CTL = u32MasterSlave | (u32DataWidth << SPI_CTL_DWIDTH_Pos) | (u32SPIMode) | SPI_CTL_SPIEN_Msk;
  204. /* Set DIVIDER = 0 */
  205. spi->CLKDIV = 0U;
  206. /* Select PCLK as the clock source of SPI */
  207. if(spi == SPI0)
  208. {
  209. CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK1;
  210. /* Return slave peripheral clock rate */
  211. u32RetValue = CLK_GetPCLK1Freq();
  212. }
  213. else if(spi == SPI1)
  214. {
  215. CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK0;
  216. /* Return slave peripheral clock rate */
  217. u32RetValue = CLK_GetPCLK0Freq();
  218. }
  219. else if(spi == SPI2)
  220. {
  221. CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI2SEL_Msk)) | CLK_CLKSEL2_SPI2SEL_PCLK1;
  222. /* Return slave peripheral clock rate */
  223. u32RetValue = CLK_GetPCLK1Freq();
  224. }
  225. else
  226. {
  227. CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI3SEL_Msk)) | CLK_CLKSEL2_SPI3SEL_PCLK0;
  228. /* Return slave peripheral clock rate */
  229. u32RetValue = CLK_GetPCLK0Freq();
  230. }
  231. }
  232. return u32RetValue;
  233. }
  234. /**
  235. * @brief Disable SPI controller.
  236. * @param[in] spi The pointer of the specified SPI module.
  237. * @return None
  238. * @details This function will reset SPI controller.
  239. */
  240. void SPI_Close(SPI_T *spi)
  241. {
  242. if(spi == SPI0)
  243. {
  244. /* Reset SPI */
  245. SYS->IPRST1 |= SYS_IPRST1_SPI0RST_Msk;
  246. SYS->IPRST1 &= ~SYS_IPRST1_SPI0RST_Msk;
  247. }
  248. else if(spi == SPI1)
  249. {
  250. /* Reset SPI */
  251. SYS->IPRST1 |= SYS_IPRST1_SPI1RST_Msk;
  252. SYS->IPRST1 &= ~SYS_IPRST1_SPI1RST_Msk;
  253. }
  254. else if(spi == SPI2)
  255. {
  256. /* Reset SPI */
  257. SYS->IPRST1 |= SYS_IPRST1_SPI2RST_Msk;
  258. SYS->IPRST1 &= ~SYS_IPRST1_SPI2RST_Msk;
  259. }
  260. else
  261. {
  262. /* Reset SPI */
  263. SYS->IPRST2 |= SYS_IPRST2_SPI3RST_Msk;
  264. SYS->IPRST2 &= ~SYS_IPRST2_SPI3RST_Msk;
  265. }
  266. }
  267. /**
  268. * @brief Clear RX FIFO buffer.
  269. * @param[in] spi The pointer of the specified SPI module.
  270. * @return None
  271. * @details This function will clear SPI RX FIFO buffer. The RXEMPTY (SPI_STATUS[8]) will be set to 1.
  272. */
  273. void SPI_ClearRxFIFO(SPI_T *spi)
  274. {
  275. spi->FIFOCTL |= SPI_FIFOCTL_RXFBCLR_Msk;
  276. }
  277. /**
  278. * @brief Clear TX FIFO buffer.
  279. * @param[in] spi The pointer of the specified SPI module.
  280. * @return None
  281. * @details This function will clear SPI TX FIFO buffer. The TXEMPTY (SPI_STATUS[16]) will be set to 1.
  282. * @note The TX shift register will not be cleared.
  283. */
  284. void SPI_ClearTxFIFO(SPI_T *spi)
  285. {
  286. spi->FIFOCTL |= SPI_FIFOCTL_TXFBCLR_Msk;
  287. }
  288. /**
  289. * @brief Disable the automatic slave selection function.
  290. * @param[in] spi The pointer of the specified SPI module.
  291. * @return None
  292. * @details This function will disable the automatic slave selection function and set slave selection signal to inactive state.
  293. */
  294. void SPI_DisableAutoSS(SPI_T *spi)
  295. {
  296. spi->SSCTL &= ~(SPI_SSCTL_AUTOSS_Msk | SPI_SSCTL_SS_Msk);
  297. }
  298. /**
  299. * @brief Enable the automatic slave selection function.
  300. * @param[in] spi The pointer of the specified SPI module.
  301. * @param[in] u32SSPinMask Specifies slave selection pins. (SPI_SS)
  302. * @param[in] u32ActiveLevel Specifies the active level of slave selection signal. (SPI_SS_ACTIVE_HIGH, SPI_SS_ACTIVE_LOW)
  303. * @return None
  304. * @details This function will enable the automatic slave selection function. Only available in Master mode.
  305. * The slave selection pin and the active level will be set in this function.
  306. */
  307. void SPI_EnableAutoSS(SPI_T *spi, uint32_t u32SSPinMask, uint32_t u32ActiveLevel)
  308. {
  309. spi->SSCTL = (spi->SSCTL & (~(SPI_SSCTL_AUTOSS_Msk | SPI_SSCTL_SSACTPOL_Msk | SPI_SSCTL_SS_Msk))) | (u32SSPinMask | u32ActiveLevel | SPI_SSCTL_AUTOSS_Msk);
  310. }
  311. /**
  312. * @brief Set the SPI bus clock.
  313. * @param[in] spi The pointer of the specified SPI module.
  314. * @param[in] u32BusClock The expected frequency of SPI bus clock in Hz.
  315. * @return Actual frequency of SPI bus clock.
  316. * @details This function is only available in Master mode. The actual clock rate may be different from the target SPI bus clock rate.
  317. * For example, if the SPI source clock rate is 12 MHz and the target SPI bus clock rate is 7 MHz, the actual SPI bus clock
  318. * rate will be 6 MHz.
  319. * @note If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
  320. * @note If u32BusClock >= system clock frequency, SPI peripheral clock source will be set to APB clock and DIVIDER will be set to 0.
  321. * @note If u32BusClock >= SPI peripheral clock source, DIVIDER will be set to 0.
  322. */
  323. uint32_t SPI_SetBusClock(SPI_T *spi, uint32_t u32BusClock)
  324. {
  325. uint32_t u32ClkSrc, u32HCLKFreq;
  326. uint32_t u32Div, u32RetValue;
  327. /* Get system clock frequency */
  328. u32HCLKFreq = CLK_GetHCLKFreq();
  329. if(u32BusClock >= u32HCLKFreq)
  330. {
  331. /* Select PCLK as the clock source of SPI */
  332. if(spi == SPI0)
  333. CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK1;
  334. else if(spi == SPI1)
  335. CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK0;
  336. else if(spi == SPI2)
  337. CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI2SEL_Msk)) | CLK_CLKSEL2_SPI2SEL_PCLK1;
  338. else
  339. CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI3SEL_Msk)) | CLK_CLKSEL2_SPI3SEL_PCLK0;
  340. }
  341. /* Check clock source of SPI */
  342. if(spi == SPI0)
  343. {
  344. if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HXT)
  345. {
  346. u32ClkSrc = __HXT; /* Clock source is HXT */
  347. }
  348. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PLL)
  349. {
  350. u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
  351. }
  352. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PCLK1)
  353. {
  354. /* Clock source is PCLK1 */
  355. u32ClkSrc = CLK_GetPCLK1Freq();
  356. }
  357. else
  358. {
  359. u32ClkSrc = __HIRC; /* Clock source is HIRC */
  360. }
  361. }
  362. else if(spi == SPI1)
  363. {
  364. if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HXT)
  365. {
  366. u32ClkSrc = __HXT; /* Clock source is HXT */
  367. }
  368. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PLL)
  369. {
  370. u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
  371. }
  372. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PCLK0)
  373. {
  374. /* Clock source is PCLK0 */
  375. u32ClkSrc = CLK_GetPCLK0Freq();
  376. }
  377. else
  378. {
  379. u32ClkSrc = __HIRC; /* Clock source is HIRC */
  380. }
  381. }
  382. else if(spi == SPI2)
  383. {
  384. if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_HXT)
  385. {
  386. u32ClkSrc = __HXT; /* Clock source is HXT */
  387. }
  388. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_PLL)
  389. {
  390. u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
  391. }
  392. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_PCLK1)
  393. {
  394. /* Clock source is PCLK1 */
  395. u32ClkSrc = CLK_GetPCLK1Freq();
  396. }
  397. else
  398. {
  399. u32ClkSrc = __HIRC; /* Clock source is HIRC */
  400. }
  401. }
  402. else
  403. {
  404. if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI3SEL_Msk) == CLK_CLKSEL2_SPI3SEL_HXT)
  405. {
  406. u32ClkSrc = __HXT; /* Clock source is HXT */
  407. }
  408. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI3SEL_Msk) == CLK_CLKSEL2_SPI3SEL_PLL)
  409. {
  410. u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
  411. }
  412. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI3SEL_Msk) == CLK_CLKSEL2_SPI3SEL_PCLK0)
  413. {
  414. /* Clock source is PCLK0 */
  415. u32ClkSrc = CLK_GetPCLK0Freq();
  416. }
  417. else
  418. {
  419. u32ClkSrc = __HIRC; /* Clock source is HIRC */
  420. }
  421. }
  422. if(u32BusClock >= u32HCLKFreq)
  423. {
  424. /* Set DIVIDER = 0 */
  425. spi->CLKDIV = 0U;
  426. /* Return master peripheral clock rate */
  427. u32RetValue = u32ClkSrc;
  428. }
  429. else if(u32BusClock >= u32ClkSrc)
  430. {
  431. /* Set DIVIDER = 0 */
  432. spi->CLKDIV = 0U;
  433. /* Return master peripheral clock rate */
  434. u32RetValue = u32ClkSrc;
  435. }
  436. else if(u32BusClock == 0U)
  437. {
  438. /* Set DIVIDER to the maximum value 0xFF. f_spi = f_spi_clk_src / (DIVIDER + 1) */
  439. spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk;
  440. /* Return master peripheral clock rate */
  441. u32RetValue = (u32ClkSrc / (0xFFU + 1U));
  442. }
  443. else
  444. {
  445. u32Div = (((u32ClkSrc * 10U) / u32BusClock + 5U) / 10U) - 1U; /* Round to the nearest integer */
  446. if(u32Div > 0x1FFU)
  447. {
  448. u32Div = 0x1FFU;
  449. spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk;
  450. /* Return master peripheral clock rate */
  451. u32RetValue = (u32ClkSrc / (0xFFU + 1U));
  452. }
  453. else
  454. {
  455. spi->CLKDIV = (spi->CLKDIV & (~SPI_CLKDIV_DIVIDER_Msk)) | (u32Div << SPI_CLKDIV_DIVIDER_Pos);
  456. /* Return master peripheral clock rate */
  457. u32RetValue = (u32ClkSrc / (u32Div + 1U));
  458. }
  459. }
  460. return u32RetValue;
  461. }
  462. /**
  463. * @brief Configure FIFO threshold setting.
  464. * @param[in] spi The pointer of the specified SPI module.
  465. * @param[in] u32TxThreshold Decides the TX FIFO threshold. It could be 0 ~ 3.
  466. * @param[in] u32RxThreshold Decides the RX FIFO threshold. It could be 0 ~ 3.
  467. * @return None
  468. * @details Set TX FIFO threshold and RX FIFO threshold configurations.
  469. */
  470. void SPI_SetFIFO(SPI_T *spi, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
  471. {
  472. spi->FIFOCTL = (spi->FIFOCTL & ~(SPI_FIFOCTL_TXTH_Msk | SPI_FIFOCTL_RXTH_Msk)) |
  473. (u32TxThreshold << SPI_FIFOCTL_TXTH_Pos) |
  474. (u32RxThreshold << SPI_FIFOCTL_RXTH_Pos);
  475. }
  476. /**
  477. * @brief Get the actual frequency of SPI bus clock. Only available in Master mode.
  478. * @param[in] spi The pointer of the specified SPI module.
  479. * @return Actual SPI bus clock frequency in Hz.
  480. * @details This function will calculate the actual SPI bus clock rate according to the SPInSEL and DIVIDER settings. Only available in Master mode.
  481. */
  482. uint32_t SPI_GetBusClock(SPI_T *spi)
  483. {
  484. uint32_t u32Div;
  485. uint32_t u32ClkSrc;
  486. /* Get DIVIDER setting */
  487. u32Div = (spi->CLKDIV & SPI_CLKDIV_DIVIDER_Msk) >> SPI_CLKDIV_DIVIDER_Pos;
  488. /* Check clock source of SPI */
  489. if(spi == SPI0)
  490. {
  491. if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HXT)
  492. {
  493. u32ClkSrc = __HXT; /* Clock source is HXT */
  494. }
  495. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PLL)
  496. {
  497. u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
  498. }
  499. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PCLK1)
  500. {
  501. /* Clock source is PCLK1 */
  502. u32ClkSrc = CLK_GetPCLK1Freq();
  503. }
  504. else
  505. {
  506. u32ClkSrc = __HIRC; /* Clock source is HIRC */
  507. }
  508. }
  509. else if(spi == SPI1)
  510. {
  511. if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HXT)
  512. {
  513. u32ClkSrc = __HXT; /* Clock source is HXT */
  514. }
  515. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PLL)
  516. {
  517. u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
  518. }
  519. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PCLK0)
  520. {
  521. /* Clock source is PCLK0 */
  522. u32ClkSrc = CLK_GetPCLK0Freq();
  523. }
  524. else
  525. {
  526. u32ClkSrc = __HIRC; /* Clock source is HIRC */
  527. }
  528. }
  529. else if(spi == SPI2)
  530. {
  531. if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_HXT)
  532. {
  533. u32ClkSrc = __HXT; /* Clock source is HXT */
  534. }
  535. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_PLL)
  536. {
  537. u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
  538. }
  539. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_PCLK1)
  540. {
  541. /* Clock source is PCLK1 */
  542. u32ClkSrc = CLK_GetPCLK1Freq();
  543. }
  544. else
  545. {
  546. u32ClkSrc = __HIRC; /* Clock source is HIRC */
  547. }
  548. }
  549. else
  550. {
  551. if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI3SEL_Msk) == CLK_CLKSEL2_SPI3SEL_HXT)
  552. {
  553. u32ClkSrc = __HXT; /* Clock source is HXT */
  554. }
  555. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI3SEL_Msk) == CLK_CLKSEL2_SPI3SEL_PLL)
  556. {
  557. u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
  558. }
  559. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI3SEL_Msk) == CLK_CLKSEL2_SPI3SEL_PCLK0)
  560. {
  561. /* Clock source is PCLK0 */
  562. u32ClkSrc = CLK_GetPCLK0Freq();
  563. }
  564. else
  565. {
  566. u32ClkSrc = __HIRC; /* Clock source is HIRC */
  567. }
  568. }
  569. /* Return SPI bus clock rate */
  570. return (u32ClkSrc / (u32Div + 1U));
  571. }
  572. /**
  573. * @brief Enable interrupt function.
  574. * @param[in] spi The pointer of the specified SPI module.
  575. * @param[in] u32Mask The combination of all related interrupt enable bits.
  576. * Each bit corresponds to a interrupt enable bit.
  577. * This parameter decides which interrupts will be enabled. It is combination of:
  578. * - \ref SPI_UNIT_INT_MASK
  579. * - \ref SPI_SSACT_INT_MASK
  580. * - \ref SPI_SSINACT_INT_MASK
  581. * - \ref SPI_SLVUR_INT_MASK
  582. * - \ref SPI_SLVBE_INT_MASK
  583. * - \ref SPI_TXUF_INT_MASK
  584. * - \ref SPI_FIFO_TXTH_INT_MASK
  585. * - \ref SPI_FIFO_RXTH_INT_MASK
  586. * - \ref SPI_FIFO_RXOV_INT_MASK
  587. * - \ref SPI_FIFO_RXTO_INT_MASK
  588. *
  589. * @return None
  590. * @details Enable SPI related interrupts specified by u32Mask parameter.
  591. */
  592. void SPI_EnableInt(SPI_T *spi, uint32_t u32Mask)
  593. {
  594. /* Enable unit transfer interrupt flag */
  595. if((u32Mask & SPI_UNIT_INT_MASK) == SPI_UNIT_INT_MASK)
  596. {
  597. spi->CTL |= SPI_CTL_UNITIEN_Msk;
  598. }
  599. /* Enable slave selection signal active interrupt flag */
  600. if((u32Mask & SPI_SSACT_INT_MASK) == SPI_SSACT_INT_MASK)
  601. {
  602. spi->SSCTL |= SPI_SSCTL_SSACTIEN_Msk;
  603. }
  604. /* Enable slave selection signal inactive interrupt flag */
  605. if((u32Mask & SPI_SSINACT_INT_MASK) == SPI_SSINACT_INT_MASK)
  606. {
  607. spi->SSCTL |= SPI_SSCTL_SSINAIEN_Msk;
  608. }
  609. /* Enable slave TX under run interrupt flag */
  610. if((u32Mask & SPI_SLVUR_INT_MASK) == SPI_SLVUR_INT_MASK)
  611. {
  612. spi->SSCTL |= SPI_SSCTL_SLVURIEN_Msk;
  613. }
  614. /* Enable slave bit count error interrupt flag */
  615. if((u32Mask & SPI_SLVBE_INT_MASK) == SPI_SLVBE_INT_MASK)
  616. {
  617. spi->SSCTL |= SPI_SSCTL_SLVBEIEN_Msk;
  618. }
  619. /* Enable slave TX underflow interrupt flag */
  620. if((u32Mask & SPI_TXUF_INT_MASK) == SPI_TXUF_INT_MASK)
  621. {
  622. spi->FIFOCTL |= SPI_FIFOCTL_TXUFIEN_Msk;
  623. }
  624. /* Enable TX threshold interrupt flag */
  625. if((u32Mask & SPI_FIFO_TXTH_INT_MASK) == SPI_FIFO_TXTH_INT_MASK)
  626. {
  627. spi->FIFOCTL |= SPI_FIFOCTL_TXTHIEN_Msk;
  628. }
  629. /* Enable RX threshold interrupt flag */
  630. if((u32Mask & SPI_FIFO_RXTH_INT_MASK) == SPI_FIFO_RXTH_INT_MASK)
  631. {
  632. spi->FIFOCTL |= SPI_FIFOCTL_RXTHIEN_Msk;
  633. }
  634. /* Enable RX overrun interrupt flag */
  635. if((u32Mask & SPI_FIFO_RXOV_INT_MASK) == SPI_FIFO_RXOV_INT_MASK)
  636. {
  637. spi->FIFOCTL |= SPI_FIFOCTL_RXOVIEN_Msk;
  638. }
  639. /* Enable RX time-out interrupt flag */
  640. if((u32Mask & SPI_FIFO_RXTO_INT_MASK) == SPI_FIFO_RXTO_INT_MASK)
  641. {
  642. spi->FIFOCTL |= SPI_FIFOCTL_RXTOIEN_Msk;
  643. }
  644. }
  645. /**
  646. * @brief Disable interrupt function.
  647. * @param[in] spi The pointer of the specified SPI module.
  648. * @param[in] u32Mask The combination of all related interrupt enable bits.
  649. * Each bit corresponds to a interrupt bit.
  650. * This parameter decides which interrupts will be disabled. It is combination of:
  651. * - \ref SPI_UNIT_INT_MASK
  652. * - \ref SPI_SSACT_INT_MASK
  653. * - \ref SPI_SSINACT_INT_MASK
  654. * - \ref SPI_SLVUR_INT_MASK
  655. * - \ref SPI_SLVBE_INT_MASK
  656. * - \ref SPI_TXUF_INT_MASK
  657. * - \ref SPI_FIFO_TXTH_INT_MASK
  658. * - \ref SPI_FIFO_RXTH_INT_MASK
  659. * - \ref SPI_FIFO_RXOV_INT_MASK
  660. * - \ref SPI_FIFO_RXTO_INT_MASK
  661. *
  662. * @return None
  663. * @details Disable SPI related interrupts specified by u32Mask parameter.
  664. */
  665. void SPI_DisableInt(SPI_T *spi, uint32_t u32Mask)
  666. {
  667. /* Disable unit transfer interrupt flag */
  668. if((u32Mask & SPI_UNIT_INT_MASK) == SPI_UNIT_INT_MASK)
  669. {
  670. spi->CTL &= ~SPI_CTL_UNITIEN_Msk;
  671. }
  672. /* Disable slave selection signal active interrupt flag */
  673. if((u32Mask & SPI_SSACT_INT_MASK) == SPI_SSACT_INT_MASK)
  674. {
  675. spi->SSCTL &= ~SPI_SSCTL_SSACTIEN_Msk;
  676. }
  677. /* Disable slave selection signal inactive interrupt flag */
  678. if((u32Mask & SPI_SSINACT_INT_MASK) == SPI_SSINACT_INT_MASK)
  679. {
  680. spi->SSCTL &= ~SPI_SSCTL_SSINAIEN_Msk;
  681. }
  682. /* Disable slave TX under run interrupt flag */
  683. if((u32Mask & SPI_SLVUR_INT_MASK) == SPI_SLVUR_INT_MASK)
  684. {
  685. spi->SSCTL &= ~SPI_SSCTL_SLVURIEN_Msk;
  686. }
  687. /* Disable slave bit count error interrupt flag */
  688. if((u32Mask & SPI_SLVBE_INT_MASK) == SPI_SLVBE_INT_MASK)
  689. {
  690. spi->SSCTL &= ~SPI_SSCTL_SLVBEIEN_Msk;
  691. }
  692. /* Disable slave TX underflow interrupt flag */
  693. if((u32Mask & SPI_TXUF_INT_MASK) == SPI_TXUF_INT_MASK)
  694. {
  695. spi->FIFOCTL &= ~SPI_FIFOCTL_TXUFIEN_Msk;
  696. }
  697. /* Disable TX threshold interrupt flag */
  698. if((u32Mask & SPI_FIFO_TXTH_INT_MASK) == SPI_FIFO_TXTH_INT_MASK)
  699. {
  700. spi->FIFOCTL &= ~SPI_FIFOCTL_TXTHIEN_Msk;
  701. }
  702. /* Disable RX threshold interrupt flag */
  703. if((u32Mask & SPI_FIFO_RXTH_INT_MASK) == SPI_FIFO_RXTH_INT_MASK)
  704. {
  705. spi->FIFOCTL &= ~SPI_FIFOCTL_RXTHIEN_Msk;
  706. }
  707. /* Disable RX overrun interrupt flag */
  708. if((u32Mask & SPI_FIFO_RXOV_INT_MASK) == SPI_FIFO_RXOV_INT_MASK)
  709. {
  710. spi->FIFOCTL &= ~SPI_FIFOCTL_RXOVIEN_Msk;
  711. }
  712. /* Disable RX time-out interrupt flag */
  713. if((u32Mask & SPI_FIFO_RXTO_INT_MASK) == SPI_FIFO_RXTO_INT_MASK)
  714. {
  715. spi->FIFOCTL &= ~SPI_FIFOCTL_RXTOIEN_Msk;
  716. }
  717. }
  718. /**
  719. * @brief Get interrupt flag.
  720. * @param[in] spi The pointer of the specified SPI module.
  721. * @param[in] u32Mask The combination of all related interrupt sources.
  722. * Each bit corresponds to a interrupt source.
  723. * This parameter decides which interrupt flags will be read. It is combination of:
  724. * - \ref SPI_UNIT_INT_MASK
  725. * - \ref SPI_SSACT_INT_MASK
  726. * - \ref SPI_SSINACT_INT_MASK
  727. * - \ref SPI_SLVUR_INT_MASK
  728. * - \ref SPI_SLVBE_INT_MASK
  729. * - \ref SPI_TXUF_INT_MASK
  730. * - \ref SPI_FIFO_TXTH_INT_MASK
  731. * - \ref SPI_FIFO_RXTH_INT_MASK
  732. * - \ref SPI_FIFO_RXOV_INT_MASK
  733. * - \ref SPI_FIFO_RXTO_INT_MASK
  734. *
  735. * @return Interrupt flags of selected sources.
  736. * @details Get SPI related interrupt flags specified by u32Mask parameter.
  737. */
  738. uint32_t SPI_GetIntFlag(SPI_T *spi, uint32_t u32Mask)
  739. {
  740. uint32_t u32IntFlag = 0U, u32TmpVal;
  741. u32TmpVal = spi->STATUS & SPI_STATUS_UNITIF_Msk;
  742. /* Check unit transfer interrupt flag */
  743. if((u32Mask & SPI_UNIT_INT_MASK) && (u32TmpVal))
  744. {
  745. u32IntFlag |= SPI_UNIT_INT_MASK;
  746. }
  747. u32TmpVal = spi->STATUS & SPI_STATUS_SSACTIF_Msk;
  748. /* Check slave selection signal active interrupt flag */
  749. if((u32Mask & SPI_SSACT_INT_MASK) && (u32TmpVal))
  750. {
  751. u32IntFlag |= SPI_SSACT_INT_MASK;
  752. }
  753. u32TmpVal = spi->STATUS & SPI_STATUS_SSINAIF_Msk;
  754. /* Check slave selection signal inactive interrupt flag */
  755. if((u32Mask & SPI_SSINACT_INT_MASK) && (u32TmpVal))
  756. {
  757. u32IntFlag |= SPI_SSINACT_INT_MASK;
  758. }
  759. u32TmpVal = spi->STATUS & SPI_STATUS_SLVURIF_Msk;
  760. /* Check slave TX under run interrupt flag */
  761. if((u32Mask & SPI_SLVUR_INT_MASK) && (u32TmpVal))
  762. {
  763. u32IntFlag |= SPI_SLVUR_INT_MASK;
  764. }
  765. u32TmpVal = spi->STATUS & SPI_STATUS_SLVBEIF_Msk;
  766. /* Check slave bit count error interrupt flag */
  767. if((u32Mask & SPI_SLVBE_INT_MASK) && (u32TmpVal))
  768. {
  769. u32IntFlag |= SPI_SLVBE_INT_MASK;
  770. }
  771. u32TmpVal = spi->STATUS & SPI_STATUS_TXUFIF_Msk;
  772. /* Check slave TX underflow interrupt flag */
  773. if((u32Mask & SPI_TXUF_INT_MASK) && (u32TmpVal))
  774. {
  775. u32IntFlag |= SPI_TXUF_INT_MASK;
  776. }
  777. u32TmpVal = spi->STATUS & SPI_STATUS_TXTHIF_Msk;
  778. /* Check TX threshold interrupt flag */
  779. if((u32Mask & SPI_FIFO_TXTH_INT_MASK) && (u32TmpVal))
  780. {
  781. u32IntFlag |= SPI_FIFO_TXTH_INT_MASK;
  782. }
  783. u32TmpVal = spi->STATUS & SPI_STATUS_RXTHIF_Msk;
  784. /* Check RX threshold interrupt flag */
  785. if((u32Mask & SPI_FIFO_RXTH_INT_MASK) && (u32TmpVal))
  786. {
  787. u32IntFlag |= SPI_FIFO_RXTH_INT_MASK;
  788. }
  789. u32TmpVal = spi->STATUS & SPI_STATUS_RXOVIF_Msk;
  790. /* Check RX overrun interrupt flag */
  791. if((u32Mask & SPI_FIFO_RXOV_INT_MASK) && (u32TmpVal))
  792. {
  793. u32IntFlag |= SPI_FIFO_RXOV_INT_MASK;
  794. }
  795. u32TmpVal = spi->STATUS & SPI_STATUS_RXTOIF_Msk;
  796. /* Check RX time-out interrupt flag */
  797. if((u32Mask & SPI_FIFO_RXTO_INT_MASK) && (u32TmpVal))
  798. {
  799. u32IntFlag |= SPI_FIFO_RXTO_INT_MASK;
  800. }
  801. return u32IntFlag;
  802. }
  803. /**
  804. * @brief Clear interrupt flag.
  805. * @param[in] spi The pointer of the specified SPI module.
  806. * @param[in] u32Mask The combination of all related interrupt sources.
  807. * Each bit corresponds to a interrupt source.
  808. * This parameter decides which interrupt flags will be cleared. It could be the combination of:
  809. * - \ref SPI_UNIT_INT_MASK
  810. * - \ref SPI_SSACT_INT_MASK
  811. * - \ref SPI_SSINACT_INT_MASK
  812. * - \ref SPI_SLVUR_INT_MASK
  813. * - \ref SPI_SLVBE_INT_MASK
  814. * - \ref SPI_TXUF_INT_MASK
  815. * - \ref SPI_FIFO_RXOV_INT_MASK
  816. * - \ref SPI_FIFO_RXTO_INT_MASK
  817. *
  818. * @return None
  819. * @details Clear SPI related interrupt flags specified by u32Mask parameter.
  820. */
  821. void SPI_ClearIntFlag(SPI_T *spi, uint32_t u32Mask)
  822. {
  823. if(u32Mask & SPI_UNIT_INT_MASK)
  824. {
  825. spi->STATUS = SPI_STATUS_UNITIF_Msk; /* Clear unit transfer interrupt flag */
  826. }
  827. if(u32Mask & SPI_SSACT_INT_MASK)
  828. {
  829. spi->STATUS = SPI_STATUS_SSACTIF_Msk; /* Clear slave selection signal active interrupt flag */
  830. }
  831. if(u32Mask & SPI_SSINACT_INT_MASK)
  832. {
  833. spi->STATUS = SPI_STATUS_SSINAIF_Msk; /* Clear slave selection signal inactive interrupt flag */
  834. }
  835. if(u32Mask & SPI_SLVUR_INT_MASK)
  836. {
  837. spi->STATUS = SPI_STATUS_SLVURIF_Msk; /* Clear slave TX under run interrupt flag */
  838. }
  839. if(u32Mask & SPI_SLVBE_INT_MASK)
  840. {
  841. spi->STATUS = SPI_STATUS_SLVBEIF_Msk; /* Clear slave bit count error interrupt flag */
  842. }
  843. if(u32Mask & SPI_TXUF_INT_MASK)
  844. {
  845. spi->STATUS = SPI_STATUS_TXUFIF_Msk; /* Clear slave TX underflow interrupt flag */
  846. }
  847. if(u32Mask & SPI_FIFO_RXOV_INT_MASK)
  848. {
  849. spi->STATUS = SPI_STATUS_RXOVIF_Msk; /* Clear RX overrun interrupt flag */
  850. }
  851. if(u32Mask & SPI_FIFO_RXTO_INT_MASK)
  852. {
  853. spi->STATUS = SPI_STATUS_RXTOIF_Msk; /* Clear RX time-out interrupt flag */
  854. }
  855. }
  856. /**
  857. * @brief Get SPI status.
  858. * @param[in] spi The pointer of the specified SPI module.
  859. * @param[in] u32Mask The combination of all related sources.
  860. * Each bit corresponds to a source.
  861. * This parameter decides which flags will be read. It is combination of:
  862. * - \ref SPI_BUSY_MASK
  863. * - \ref SPI_RX_EMPTY_MASK
  864. * - \ref SPI_RX_FULL_MASK
  865. * - \ref SPI_TX_EMPTY_MASK
  866. * - \ref SPI_TX_FULL_MASK
  867. * - \ref SPI_TXRX_RESET_MASK
  868. * - \ref SPI_SPIEN_STS_MASK
  869. * - \ref SPI_SSLINE_STS_MASK
  870. *
  871. * @return Flags of selected sources.
  872. * @details Get SPI related status specified by u32Mask parameter.
  873. */
  874. uint32_t SPI_GetStatus(SPI_T *spi, uint32_t u32Mask)
  875. {
  876. uint32_t u32Flag = 0U, u32TmpValue;
  877. u32TmpValue = spi->STATUS & SPI_STATUS_BUSY_Msk;
  878. /* Check busy status */
  879. if((u32Mask & SPI_BUSY_MASK) && (u32TmpValue))
  880. {
  881. u32Flag |= SPI_BUSY_MASK;
  882. }
  883. u32TmpValue = spi->STATUS & SPI_STATUS_RXEMPTY_Msk;
  884. /* Check RX empty flag */
  885. if((u32Mask & SPI_RX_EMPTY_MASK) && (u32TmpValue))
  886. {
  887. u32Flag |= SPI_RX_EMPTY_MASK;
  888. }
  889. u32TmpValue = spi->STATUS & SPI_STATUS_RXFULL_Msk;
  890. /* Check RX full flag */
  891. if((u32Mask & SPI_RX_FULL_MASK) && (u32TmpValue))
  892. {
  893. u32Flag |= SPI_RX_FULL_MASK;
  894. }
  895. u32TmpValue = spi->STATUS & SPI_STATUS_TXEMPTY_Msk;
  896. /* Check TX empty flag */
  897. if((u32Mask & SPI_TX_EMPTY_MASK) && (u32TmpValue))
  898. {
  899. u32Flag |= SPI_TX_EMPTY_MASK;
  900. }
  901. u32TmpValue = spi->STATUS & SPI_STATUS_TXFULL_Msk;
  902. /* Check TX full flag */
  903. if((u32Mask & SPI_TX_FULL_MASK) && (u32TmpValue))
  904. {
  905. u32Flag |= SPI_TX_FULL_MASK;
  906. }
  907. u32TmpValue = spi->STATUS & SPI_STATUS_TXRXRST_Msk;
  908. /* Check TX/RX reset flag */
  909. if((u32Mask & SPI_TXRX_RESET_MASK) && (u32TmpValue))
  910. {
  911. u32Flag |= SPI_TXRX_RESET_MASK;
  912. }
  913. u32TmpValue = spi->STATUS & SPI_STATUS_SPIENSTS_Msk;
  914. /* Check SPIEN flag */
  915. if((u32Mask & SPI_SPIEN_STS_MASK) && (u32TmpValue))
  916. {
  917. u32Flag |= SPI_SPIEN_STS_MASK;
  918. }
  919. u32TmpValue = spi->STATUS & SPI_STATUS_SSLINE_Msk;
  920. /* Check SPIx_SS line status */
  921. if((u32Mask & SPI_SSLINE_STS_MASK) && (u32TmpValue))
  922. {
  923. u32Flag |= SPI_SSLINE_STS_MASK;
  924. }
  925. return u32Flag;
  926. }
  927. /**
  928. * @brief This function is used to get I2S source clock frequency.
  929. * @param[in] i2s The pointer of the specified I2S module.
  930. * @return I2S source clock frequency (Hz).
  931. * @details Return the source clock frequency according to the setting of SPI0SEL (CLKSEL2[27:26]).
  932. */
  933. static uint32_t SPII2S_GetSourceClockFreq(SPI_T *i2s)
  934. {
  935. uint32_t u32Freq;
  936. if(i2s == SPI0)
  937. {
  938. if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HXT)
  939. {
  940. u32Freq = __HXT; /* Clock source is HXT */
  941. }
  942. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PLL)
  943. {
  944. u32Freq = CLK_GetPLLClockFreq(); /* Clock source is PLL */
  945. }
  946. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PCLK1)
  947. {
  948. /* Clock source is PCLK1 */
  949. u32Freq = CLK_GetPCLK1Freq();
  950. }
  951. else
  952. {
  953. u32Freq = __HIRC; /* Clock source is HIRC */
  954. }
  955. }
  956. else if(i2s == SPI1)
  957. {
  958. if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HXT)
  959. {
  960. u32Freq = __HXT; /* Clock source is HXT */
  961. }
  962. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PLL)
  963. {
  964. u32Freq = CLK_GetPLLClockFreq(); /* Clock source is PLL */
  965. }
  966. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PCLK0)
  967. {
  968. /* Clock source is PCLK0 */
  969. u32Freq = CLK_GetPCLK0Freq();
  970. }
  971. else
  972. {
  973. u32Freq = __HIRC; /* Clock source is HIRC */
  974. }
  975. }
  976. else if(i2s == SPI2)
  977. {
  978. if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_HXT)
  979. {
  980. u32Freq = __HXT; /* Clock source is HXT */
  981. }
  982. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_PLL)
  983. {
  984. u32Freq = CLK_GetPLLClockFreq(); /* Clock source is PLL */
  985. }
  986. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_PCLK1)
  987. {
  988. /* Clock source is PCLK1 */
  989. u32Freq = CLK_GetPCLK1Freq();
  990. }
  991. else
  992. {
  993. u32Freq = __HIRC; /* Clock source is HIRC */
  994. }
  995. }
  996. else
  997. {
  998. if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI3SEL_Msk) == CLK_CLKSEL2_SPI3SEL_HXT)
  999. {
  1000. u32Freq = __HXT; /* Clock source is HXT */
  1001. }
  1002. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI3SEL_Msk) == CLK_CLKSEL2_SPI3SEL_PLL)
  1003. {
  1004. u32Freq = CLK_GetPLLClockFreq(); /* Clock source is PLL */
  1005. }
  1006. else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI3SEL_Msk) == CLK_CLKSEL2_SPI3SEL_PCLK0)
  1007. {
  1008. /* Clock source is PCLK0 */
  1009. u32Freq = CLK_GetPCLK0Freq();
  1010. }
  1011. else
  1012. {
  1013. u32Freq = __HIRC; /* Clock source is HIRC */
  1014. }
  1015. }
  1016. return u32Freq;
  1017. }
  1018. /**
  1019. * @brief This function configures some parameters of I2S interface for general purpose use.
  1020. * @param[in] i2s The pointer of the specified I2S module.
  1021. * @param[in] u32MasterSlave I2S operation mode. Valid values are listed below.
  1022. * - \ref SPII2S_MODE_MASTER
  1023. * - \ref SPII2S_MODE_SLAVE
  1024. * @param[in] u32SampleRate Sample rate
  1025. * @param[in] u32WordWidth Data length. Valid values are listed below.
  1026. * - \ref SPII2S_DATABIT_8
  1027. * - \ref SPII2S_DATABIT_16
  1028. * - \ref SPII2S_DATABIT_24
  1029. * - \ref SPII2S_DATABIT_32
  1030. * @param[in] u32Channels Audio format. Valid values are listed below.
  1031. * - \ref SPII2S_MONO
  1032. * - \ref SPII2S_STEREO
  1033. * @param[in] u32DataFormat Data format. Valid values are listed below.
  1034. * - \ref SPII2S_FORMAT_I2S
  1035. * - \ref SPII2S_FORMAT_MSB
  1036. * - \ref SPII2S_FORMAT_PCMA
  1037. * - \ref SPII2S_FORMAT_PCMB
  1038. * @return Real sample rate of master mode or peripheral clock rate of slave mode.
  1039. * @details This function will reset SPI/I2S controller and configure I2S controller according to the input parameters.
  1040. * Set TX FIFO threshold to 2 and RX FIFO threshold to 1. Both the TX and RX functions will be enabled.
  1041. * The actual sample rate may be different from the target sample rate. The real sample rate will be returned for reference.
  1042. * @note In slave mode, the SPI peripheral clock rate will be equal to APB clock rate.
  1043. */
  1044. uint32_t SPII2S_Open(SPI_T *i2s, uint32_t u32MasterSlave, uint32_t u32SampleRate, uint32_t u32WordWidth, uint32_t u32Channels, uint32_t u32DataFormat)
  1045. {
  1046. uint32_t u32Divider;
  1047. uint32_t u32BitRate, u32SrcClk, u32RetValue;
  1048. /* Reset SPI/I2S */
  1049. if(i2s == SPI0)
  1050. {
  1051. SYS->IPRST1 |= SYS_IPRST1_SPI0RST_Msk;
  1052. SYS->IPRST1 &= ~SYS_IPRST1_SPI0RST_Msk;
  1053. }
  1054. else if(i2s == SPI1)
  1055. {
  1056. SYS->IPRST1 |= SYS_IPRST1_SPI1RST_Msk;
  1057. SYS->IPRST1 &= ~SYS_IPRST1_SPI1RST_Msk;
  1058. }
  1059. else if(i2s == SPI2)
  1060. {
  1061. SYS->IPRST1 |= SYS_IPRST1_SPI2RST_Msk;
  1062. SYS->IPRST1 &= ~SYS_IPRST1_SPI2RST_Msk;
  1063. }
  1064. else
  1065. {
  1066. SYS->IPRST2 |= SYS_IPRST2_SPI3RST_Msk;
  1067. SYS->IPRST2 &= ~SYS_IPRST2_SPI3RST_Msk;
  1068. }
  1069. /* Configure I2S controller */
  1070. i2s->I2SCTL = u32MasterSlave | u32WordWidth | u32Channels | u32DataFormat;
  1071. /* Set TX FIFO threshold to 2 and RX FIFO threshold to 1 */
  1072. i2s->FIFOCTL = SPII2S_FIFO_TX_LEVEL_WORD_2 | SPII2S_FIFO_RX_LEVEL_WORD_2;
  1073. if(u32MasterSlave == SPI_MASTER)
  1074. {
  1075. /* Get the source clock rate */
  1076. u32SrcClk = SPII2S_GetSourceClockFreq(i2s);
  1077. /* Calculate the bit clock rate */
  1078. u32BitRate = u32SampleRate * ((u32WordWidth >> SPI_I2SCTL_WDWIDTH_Pos) + 1U) * 16U;
  1079. u32Divider = ((u32SrcClk / u32BitRate) >> 1U) - 1U;
  1080. //u32Divider = ((((u32SrcClk * 10UL / u32BitRate) >> 1U) + 5UL) / 10UL) - 1U;
  1081. /* Set BCLKDIV setting */
  1082. i2s->I2SCLK = (i2s->I2SCLK & ~SPI_I2SCLK_BCLKDIV_Msk) | (u32Divider << SPI_I2SCLK_BCLKDIV_Pos);
  1083. /* Calculate bit clock rate */
  1084. u32BitRate = u32SrcClk / ((u32Divider + 1U) * 2U);
  1085. /* Calculate real sample rate */
  1086. u32SampleRate = u32BitRate / (((u32WordWidth >> SPI_I2SCTL_WDWIDTH_Pos) + 1U) * 16U);
  1087. /* Enable TX function, RX function and I2S mode. */
  1088. i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
  1089. /* Return the real sample rate */
  1090. u32RetValue = u32SampleRate;
  1091. }
  1092. else
  1093. {
  1094. /* Set BCLKDIV = 0 */
  1095. i2s->I2SCLK &= ~SPI_I2SCLK_BCLKDIV_Msk;
  1096. if(i2s == SPI0)
  1097. {
  1098. /* Set the peripheral clock rate to equal APB clock rate */
  1099. CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK1;
  1100. /* Enable TX function, RX function and I2S mode. */
  1101. i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
  1102. /* Return slave peripheral clock rate */
  1103. u32RetValue = CLK_GetPCLK1Freq();
  1104. }
  1105. else if(i2s == SPI1)
  1106. {
  1107. /* Set the peripheral clock rate to equal APB clock rate */
  1108. CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK0;
  1109. /* Enable TX function, RX function and I2S mode. */
  1110. i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
  1111. /* Return slave peripheral clock rate */
  1112. u32RetValue = CLK_GetPCLK0Freq();
  1113. }
  1114. else if(i2s == SPI2)
  1115. {
  1116. /* Set the peripheral clock rate to equal APB clock rate */
  1117. CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI2SEL_Msk)) | CLK_CLKSEL2_SPI2SEL_PCLK1;
  1118. /* Enable TX function, RX function and I2S mode. */
  1119. i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
  1120. /* Return slave peripheral clock rate */
  1121. u32RetValue = CLK_GetPCLK1Freq();
  1122. }
  1123. else
  1124. {
  1125. /* Set the peripheral clock rate to equal APB clock rate */
  1126. CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI3SEL_Msk)) | CLK_CLKSEL2_SPI3SEL_PCLK0;
  1127. /* Enable TX function, RX function and I2S mode. */
  1128. i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
  1129. /* Return slave peripheral clock rate */
  1130. u32RetValue = CLK_GetPCLK0Freq();
  1131. }
  1132. }
  1133. return u32RetValue;
  1134. }
  1135. /**
  1136. * @brief Disable I2S function.
  1137. * @param[in] i2s The pointer of the specified I2S module.
  1138. * @return None
  1139. * @details Disable I2S function.
  1140. */
  1141. void SPII2S_Close(SPI_T *i2s)
  1142. {
  1143. i2s->I2SCTL &= ~SPI_I2SCTL_I2SEN_Msk;
  1144. }
  1145. /**
  1146. * @brief Enable interrupt function.
  1147. * @param[in] i2s The pointer of the specified I2S module.
  1148. * @param[in] u32Mask The combination of all related interrupt enable bits.
  1149. * Each bit corresponds to a interrupt source. Valid values are listed below.
  1150. * - \ref SPII2S_FIFO_TXTH_INT_MASK
  1151. * - \ref SPII2S_FIFO_RXTH_INT_MASK
  1152. * - \ref SPII2S_FIFO_RXOV_INT_MASK
  1153. * - \ref SPII2S_FIFO_RXTO_INT_MASK
  1154. * - \ref SPII2S_TXUF_INT_MASK
  1155. * - \ref SPII2S_RIGHT_ZC_INT_MASK
  1156. * - \ref SPII2S_LEFT_ZC_INT_MASK
  1157. * @return None
  1158. * @details This function enables the interrupt according to the u32Mask parameter.
  1159. */
  1160. void SPII2S_EnableInt(SPI_T *i2s, uint32_t u32Mask)
  1161. {
  1162. /* Enable TX threshold interrupt flag */
  1163. if((u32Mask & SPII2S_FIFO_TXTH_INT_MASK) == SPII2S_FIFO_TXTH_INT_MASK)
  1164. {
  1165. i2s->FIFOCTL |= SPI_FIFOCTL_TXTHIEN_Msk;
  1166. }
  1167. /* Enable RX threshold interrupt flag */
  1168. if((u32Mask & SPII2S_FIFO_RXTH_INT_MASK) == SPII2S_FIFO_RXTH_INT_MASK)
  1169. {
  1170. i2s->FIFOCTL |= SPI_FIFOCTL_RXTHIEN_Msk;
  1171. }
  1172. /* Enable RX overrun interrupt flag */
  1173. if((u32Mask & SPII2S_FIFO_RXOV_INT_MASK) == SPII2S_FIFO_RXOV_INT_MASK)
  1174. {
  1175. i2s->FIFOCTL |= SPI_FIFOCTL_RXOVIEN_Msk;
  1176. }
  1177. /* Enable RX time-out interrupt flag */
  1178. if((u32Mask & SPII2S_FIFO_RXTO_INT_MASK) == SPII2S_FIFO_RXTO_INT_MASK)
  1179. {
  1180. i2s->FIFOCTL |= SPI_FIFOCTL_RXTOIEN_Msk;
  1181. }
  1182. /* Enable TX underflow interrupt flag */
  1183. if((u32Mask & SPII2S_TXUF_INT_MASK) == SPII2S_TXUF_INT_MASK)
  1184. {
  1185. i2s->FIFOCTL |= SPI_FIFOCTL_TXUFIEN_Msk;
  1186. }
  1187. /* Enable right channel zero cross interrupt flag */
  1188. if((u32Mask & SPII2S_RIGHT_ZC_INT_MASK) == SPII2S_RIGHT_ZC_INT_MASK)
  1189. {
  1190. i2s->I2SCTL |= SPI_I2SCTL_RZCIEN_Msk;
  1191. }
  1192. /* Enable left channel zero cross interrupt flag */
  1193. if((u32Mask & SPII2S_LEFT_ZC_INT_MASK) == SPII2S_LEFT_ZC_INT_MASK)
  1194. {
  1195. i2s->I2SCTL |= SPI_I2SCTL_LZCIEN_Msk;
  1196. }
  1197. }
  1198. /**
  1199. * @brief Disable interrupt function.
  1200. * @param[in] i2s The pointer of the specified I2S module.
  1201. * @param[in] u32Mask The combination of all related interrupt enable bits.
  1202. * Each bit corresponds to a interrupt source. Valid values are listed below.
  1203. * - \ref SPII2S_FIFO_TXTH_INT_MASK
  1204. * - \ref SPII2S_FIFO_RXTH_INT_MASK
  1205. * - \ref SPII2S_FIFO_RXOV_INT_MASK
  1206. * - \ref SPII2S_FIFO_RXTO_INT_MASK
  1207. * - \ref SPII2S_TXUF_INT_MASK
  1208. * - \ref SPII2S_RIGHT_ZC_INT_MASK
  1209. * - \ref SPII2S_LEFT_ZC_INT_MASK
  1210. * @return None
  1211. * @details This function disables the interrupt according to the u32Mask parameter.
  1212. */
  1213. void SPII2S_DisableInt(SPI_T *i2s, uint32_t u32Mask)
  1214. {
  1215. /* Disable TX threshold interrupt flag */
  1216. if((u32Mask & SPII2S_FIFO_TXTH_INT_MASK) == SPII2S_FIFO_TXTH_INT_MASK)
  1217. {
  1218. i2s->FIFOCTL &= ~SPI_FIFOCTL_TXTHIEN_Msk;
  1219. }
  1220. /* Disable RX threshold interrupt flag */
  1221. if((u32Mask & SPII2S_FIFO_RXTH_INT_MASK) == SPII2S_FIFO_RXTH_INT_MASK)
  1222. {
  1223. i2s->FIFOCTL &= ~SPI_FIFOCTL_RXTHIEN_Msk;
  1224. }
  1225. /* Disable RX overrun interrupt flag */
  1226. if((u32Mask & SPII2S_FIFO_RXOV_INT_MASK) == SPII2S_FIFO_RXOV_INT_MASK)
  1227. {
  1228. i2s->FIFOCTL &= ~SPI_FIFOCTL_RXOVIEN_Msk;
  1229. }
  1230. /* Disable RX time-out interrupt flag */
  1231. if((u32Mask & SPII2S_FIFO_RXTO_INT_MASK) == SPII2S_FIFO_RXTO_INT_MASK)
  1232. {
  1233. i2s->FIFOCTL &= ~SPI_FIFOCTL_RXTOIEN_Msk;
  1234. }
  1235. /* Disable TX underflow interrupt flag */
  1236. if((u32Mask & SPII2S_TXUF_INT_MASK) == SPII2S_TXUF_INT_MASK)
  1237. {
  1238. i2s->FIFOCTL &= ~SPI_FIFOCTL_TXUFIEN_Msk;
  1239. }
  1240. /* Disable right channel zero cross interrupt flag */
  1241. if((u32Mask & SPII2S_RIGHT_ZC_INT_MASK) == SPII2S_RIGHT_ZC_INT_MASK)
  1242. {
  1243. i2s->I2SCTL &= ~SPI_I2SCTL_RZCIEN_Msk;
  1244. }
  1245. /* Disable left channel zero cross interrupt flag */
  1246. if((u32Mask & SPII2S_LEFT_ZC_INT_MASK) == SPII2S_LEFT_ZC_INT_MASK)
  1247. {
  1248. i2s->I2SCTL &= ~SPI_I2SCTL_LZCIEN_Msk;
  1249. }
  1250. }
  1251. /**
  1252. * @brief Enable master clock (MCLK).
  1253. * @param[in] i2s The pointer of the specified I2S module.
  1254. * @param[in] u32BusClock The target MCLK clock rate.
  1255. * @return Actual MCLK clock rate
  1256. * @details Set the master clock rate according to u32BusClock parameter and enable master clock output.
  1257. * The actual master clock rate may be different from the target master clock rate. The real master clock rate will be returned for reference.
  1258. */
  1259. uint32_t SPII2S_EnableMCLK(SPI_T *i2s, uint32_t u32BusClock)
  1260. {
  1261. uint32_t u32Divider;
  1262. uint32_t u32SrcClk, u32RetValue;
  1263. u32SrcClk = SPII2S_GetSourceClockFreq(i2s);
  1264. if(u32BusClock == u32SrcClk)
  1265. {
  1266. u32Divider = 0U;
  1267. }
  1268. else
  1269. {
  1270. u32Divider = (u32SrcClk / u32BusClock) >> 1U;
  1271. /* MCLKDIV is a 6-bit width configuration. The maximum value is 0x3F. */
  1272. if(u32Divider > 0x3FU)
  1273. {
  1274. u32Divider = 0x3FU;
  1275. }
  1276. }
  1277. /* Write u32Divider to MCLKDIV (SPI_I2SCLK[5:0]) */
  1278. i2s->I2SCLK = (i2s->I2SCLK & ~SPI_I2SCLK_MCLKDIV_Msk) | (u32Divider << SPI_I2SCLK_MCLKDIV_Pos);
  1279. /* Enable MCLK output */
  1280. i2s->I2SCTL |= SPI_I2SCTL_MCLKEN_Msk;
  1281. if(u32Divider == 0U)
  1282. {
  1283. u32RetValue = u32SrcClk; /* If MCLKDIV=0, master clock rate is equal to the source clock rate. */
  1284. }
  1285. else
  1286. {
  1287. u32RetValue = ((u32SrcClk >> 1U) / u32Divider); /* If MCLKDIV>0, master clock rate = source clock rate / (MCLKDIV * 2) */
  1288. }
  1289. return u32RetValue;
  1290. }
  1291. /**
  1292. * @brief Disable master clock (MCLK).
  1293. * @param[in] i2s The pointer of the specified I2S module.
  1294. * @return None
  1295. * @details Clear MCLKEN bit of SPI_I2SCTL register to disable master clock output.
  1296. */
  1297. void SPII2S_DisableMCLK(SPI_T *i2s)
  1298. {
  1299. i2s->I2SCTL &= ~SPI_I2SCTL_MCLKEN_Msk;
  1300. }
  1301. /**
  1302. * @brief Configure FIFO threshold setting.
  1303. * @param[in] i2s The pointer of the specified I2S module.
  1304. * @param[in] u32TxThreshold Decides the TX FIFO threshold. It could be 0 ~ 3.
  1305. * @param[in] u32RxThreshold Decides the RX FIFO threshold. It could be 0 ~ 3.
  1306. * @return None
  1307. * @details Set TX FIFO threshold and RX FIFO threshold configurations.
  1308. */
  1309. void SPII2S_SetFIFO(SPI_T *i2s, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
  1310. {
  1311. i2s->FIFOCTL = (i2s->FIFOCTL & ~(SPI_FIFOCTL_TXTH_Msk | SPI_FIFOCTL_RXTH_Msk)) |
  1312. (u32TxThreshold << SPI_FIFOCTL_TXTH_Pos) |
  1313. (u32RxThreshold << SPI_FIFOCTL_RXTH_Pos);
  1314. }
  1315. /*@}*/ /* end of group SPI_EXPORTED_FUNCTIONS */
  1316. /*@}*/ /* end of group SPI_Driver */
  1317. /*@}*/ /* end of group Standard_Driver */
  1318. /*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/