gd32f4xx_spi.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811
  1. /*!
  2. \file gd32f4xx_spi.c
  3. \brief SPI driver
  4. */
  5. /*
  6. Copyright (C) 2016 GigaDevice
  7. 2016-08-15, V1.0.1, firmware for GD32F4xx
  8. */
  9. #include "gd32f4xx_spi.h"
  10. #include "gd32f4xx_rcu.h"
  11. #define SPI_INIT_MASK ((uint32_t)0x00003040U)
  12. #define I2S_INIT_MASK ((uint32_t)0x0000F047U)
  13. #define I2S_FULL_DUPLEX_MASK ((uint32_t)0x0000F040U)
  14. /*!
  15. \brief SPI and I2S reset
  16. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5),include I2S1_ADD and I2S2_ADD
  17. \param[out] none
  18. \retval none
  19. */
  20. void spi_i2s_deinit(uint32_t spi_periph)
  21. {
  22. switch(spi_periph){
  23. case SPI0:
  24. /* reset SPI0 and I2S0 */
  25. rcu_periph_reset_enable(RCU_SPI0RST);
  26. rcu_periph_reset_disable(RCU_SPI0RST);
  27. break;
  28. case SPI1:
  29. /* reset SPI1,I2S1 and I2S1_ADD */
  30. rcu_periph_reset_enable(RCU_SPI1RST);
  31. rcu_periph_reset_disable(RCU_SPI1RST);
  32. break;
  33. case SPI2:
  34. /* reset SPI2,I2S2 and I2S2_ADD */
  35. rcu_periph_reset_enable(RCU_SPI2RST);
  36. rcu_periph_reset_disable(RCU_SPI2RST);
  37. break;
  38. case SPI3:
  39. /* reset SPI3 and I2S3 */
  40. rcu_periph_reset_enable(RCU_SPI3RST);
  41. rcu_periph_reset_disable(RCU_SPI3RST);
  42. break;
  43. case SPI4:
  44. /* reset SPI4 and I2S4 */
  45. rcu_periph_reset_enable(RCU_SPI4RST);
  46. rcu_periph_reset_disable(RCU_SPI4RST);
  47. break;
  48. case SPI5:
  49. /* reset SPI5 */
  50. rcu_periph_reset_enable(RCU_SPI5RST);
  51. rcu_periph_reset_disable(RCU_SPI5RST);
  52. break;
  53. default :
  54. break;
  55. }
  56. }
  57. /*!
  58. \brief SPI parameter initialization
  59. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  60. \param[in] spi_struct: SPI parameter initialization stuct
  61. members of the structure and the member values are shown as below:
  62. device_mode : SPI_MASTER, SPI_SLAVE.
  63. trans_mode : SPI_TRANSMODE_FULLDUPLEX, SPI_TRANSMODE_RECEIVEONLY,
  64. SPI_TRANSMODE_BDRECEIVE, SPI_TRANSMODE_BDTRANSMIT
  65. frame_size : SPI_FRAMESIZE_16BIT, SPI_FRAMESIZE_8BIT
  66. nss: : SPI_NSS_SOFT, SPI_NSS_HARD
  67. endian : SPI_ENDIAN_MSB, SPI_ENDIAN_LSB
  68. clock_polarity_phase : SPI_CK_PL_LOW_PH_1EDGE, SPI_CK_PL_HIGH_PH_1EDGE
  69. SPI_CK_PL_LOW_PH_2EDGE, SPI_CK_PL_HIGH_PH_2EDGE
  70. prescale : SPI_PSC_n (n=2,4,8,16,32,64,128,256)
  71. \param[out] none
  72. \retval none
  73. */
  74. void spi_init(uint32_t spi_periph, spi_parameter_struct* spi_struct)
  75. {
  76. uint32_t reg = 0U;
  77. reg = SPI_CTL0(spi_periph);
  78. reg &= SPI_INIT_MASK;
  79. /* (1) select SPI as master or slave */
  80. reg |= spi_struct->device_mode;
  81. /* (2) select SPI transfer mode */
  82. reg |= spi_struct->trans_mode;
  83. /* (3) select SPI frame size */
  84. reg |= spi_struct->frame_size;
  85. /* (4) select SPI nss use hardware or software */
  86. reg |= spi_struct->nss;
  87. /* (5) select SPI LSB or MSB */
  88. reg |= spi_struct->endian;
  89. /* (6) select SPI polarity and phase */
  90. reg |= spi_struct->clock_polarity_phase;
  91. /* (7) select SPI prescale to adjust transmit speed */
  92. reg |= spi_struct->prescale;
  93. /* write to SPI_CTL0 register */
  94. SPI_CTL0(spi_periph) = (uint32_t)reg;
  95. SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SSEL);
  96. }
  97. /*!
  98. \brief SPI enable
  99. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  100. \param[out] none
  101. \retval none
  102. */
  103. void spi_enable(uint32_t spi_periph)
  104. {
  105. SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SPIEN;
  106. }
  107. /*!
  108. \brief SPI disable
  109. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  110. \param[out] none
  111. \retval none
  112. */
  113. void spi_disable(uint32_t spi_periph)
  114. {
  115. SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SPIEN);
  116. }
  117. /*!
  118. \brief I2S prescale config
  119. \param[in] spi_periph: SPIx(x=0,1,2,3,4)
  120. \param[in] audiosample:
  121. \arg I2S_AUDIOSAMPLE_8K: audio sample rate is 8khz
  122. \arg I2S_AUDIOSAMPLE_11K: audio sample rate is 11khz
  123. \arg I2S_AUDIOSAMPLE_16K: audio sample rate is 16khz
  124. \arg I2S_AUDIOSAMPLE_22K: audio sample rate is 22khz
  125. \arg I2S_AUDIOSAMPLE_32K: audio sample rate is 32khz
  126. \arg I2S_AUDIOSAMPLE_44K: audio sample rate is 44khz
  127. \arg I2S_AUDIOSAMPLE_48K: audio sample rate is 48khz
  128. \arg I2S_AUDIOSAMPLE_96K: audio sample rate is 96khz
  129. \arg I2S_AUDIOSAMPLE_192K: audio sample rate is 192khz
  130. \param[in] frameformat:
  131. \arg I2S_FRAMEFORMAT_DT16B_CH16B: I2S data length is 16 bit and channel length is 16 bit
  132. \arg I2S_FRAMEFORMAT_DT16B_CH32B: I2S data length is 16 bit and channel length is 32 bit
  133. \arg I2S_FRAMEFORMAT_DT24B_CH32B: I2S data length is 24 bit and channel length is 32 bit
  134. \arg I2S_FRAMEFORMAT_DT32B_CH32B: I2S data length is 32 bit and channel length is 32 bit
  135. \param[in] mckout:
  136. \arg I2S_MCKOUT_ENABLE: I2S master clock output enable
  137. \arg I2S_MCKOUT_DISABLE: I2S master clock output disable
  138. \param[out] none
  139. \retval none
  140. */
  141. void i2s_psc_config(uint32_t spi_periph, uint32_t i2s_audiosample, uint32_t i2s_frameformat, uint32_t i2s_mckout)
  142. {
  143. uint32_t temp_div = 2U, temp_of = 0U;
  144. uint32_t temp = 0U;
  145. uint32_t i2sclock = 0U;
  146. #ifndef I2S_EXTERNAL_CLOCK_IN
  147. uint32_t plli2sm = 0U, plli2sn = 0U, plli2sr = 0U;
  148. #endif /* I2S_EXTERNAL_CLOCK_IN */
  149. /* deinit SPI_I2SPSC register */
  150. SPI_I2SPSC(spi_periph) = 0x0002U;
  151. #ifdef I2S_EXTERNAL_CLOCK_IN
  152. rcu_i2s_clock_config(RCU_I2SSRC_I2S_CKIN);
  153. /* set the I2S clock to the external clock input value */
  154. i2sclock = I2S_EXTERNAL_CLOCK_IN;
  155. #else
  156. /* turn on the oscillator HXTAL */
  157. rcu_osci_on(RCU_HXTAL);
  158. /* wait for oscillator stabilization flags is SET */
  159. rcu_osci_stab_wait(RCU_HXTAL);
  160. /* turn on the PLLI2S */
  161. rcu_osci_on(RCU_PLLI2S_CK);
  162. /* wait for PLLI2S flags is SET */
  163. rcu_osci_stab_wait(RCU_PLLI2S_CK);
  164. /* configure the I2S clock source selection */
  165. rcu_i2s_clock_config(RCU_I2SSRC_PLLI2S);
  166. /* get the RCU_PLL_PLLPSC value */
  167. plli2sm = (uint32_t)(RCU_PLL & RCU_PLL_PLLPSC);
  168. /* get the RCU_PLLI2S_PLLI2SN value */
  169. plli2sn = (uint32_t)((RCU_PLLI2S & RCU_PLLI2S_PLLI2SN) >> 6);
  170. /* get the RCU_PLLI2S_PLLI2SR value */
  171. plli2sr = (uint32_t)((RCU_PLLI2S & RCU_PLLI2S_PLLI2SR) >> 28);
  172. if((RCU_PLL & RCU_PLL_PLLSEL) == RCU_PLLSRC_HXTAL)
  173. {
  174. /* get the I2S source clock value */
  175. i2sclock = (uint32_t)(((HXTAL_VALUE / plli2sm) * plli2sn) / plli2sr);
  176. }
  177. else
  178. { /* get the I2S source clock value */
  179. i2sclock = (uint32_t)(((IRC16M_VALUE / plli2sm) * plli2sn) / plli2sr);
  180. }
  181. #endif /* I2S_EXTERNAL_CLOCK_IN */
  182. /* config the prescaler depending on the mclk output state, the frame format and audio sample rate */
  183. if(I2S_MCKOUT_ENABLE == i2s_mckout){
  184. temp = (uint32_t)(((i2sclock / 256U) * 10U) / i2s_audiosample);
  185. }else{
  186. if(I2S_FRAMEFORMAT_DT16B_CH16B == i2s_frameformat){
  187. temp = (uint32_t)(((i2sclock / 32U) *10U ) / i2s_audiosample);
  188. }else{
  189. temp = (uint32_t)(((i2sclock / 64U) *10U ) / i2s_audiosample);
  190. }
  191. }
  192. /* remove the floating point */
  193. temp = (temp + 5U) / 10U;
  194. temp_of = (temp & 0x00000001U);
  195. temp_div = ((temp - temp_of) / 2U);
  196. temp_of = (temp_of << 8);
  197. /* set the default values */
  198. if((temp_div< 2U) || (temp_div > 255U)){
  199. temp_div = 2U;
  200. temp_of = 0U;
  201. }
  202. /* configure SPI_I2SPSC */
  203. SPI_I2SPSC(spi_periph) = (uint32_t)(temp_div | temp_of | i2s_mckout);
  204. /* clear SPI_I2SCTL_DTLEN and SPI_I2SCTL_CHLEN bits */
  205. SPI_I2SCTL(spi_periph) &= (uint32_t)(~(SPI_I2SCTL_DTLEN|SPI_I2SCTL_CHLEN));
  206. /* configure data frame format */
  207. SPI_I2SCTL(spi_periph) |= (uint32_t)i2s_frameformat;
  208. }
  209. /*!
  210. \brief I2S parameter configuration
  211. \param[in] spi_periph: SPIx(x=0,1,2,3,4)
  212. \param[in] i2s_mode:
  213. \arg I2S_MODE_SLAVETX : I2S slave transmit mode
  214. \arg I2S_MODE_SLAVERX : I2S slave receive mode
  215. \arg I2S_MODE_MASTERTX : I2S master transmit mode
  216. \arg I2S_MODE_MASTERRX : I2S master receive mode
  217. \param[in] i2s_std:
  218. \arg I2S_STD_PHILLIPS : I2S phillips standard
  219. \arg I2S_STD_MSB : I2S MSB standard
  220. \arg I2S_STD_LSB : I2S LSB standard
  221. \arg I2S_STD_PCMSHORT : I2S PCM short standard
  222. \arg I2S_STD_PCMLONG : I2S PCM long standard
  223. \param[in] i2s_ckpl:
  224. \arg I2S_CKPL_LOW : I2S clock polarity low level
  225. \arg I2S_CKPL_HIGH : I2S clock polarity high level
  226. \param[out] none
  227. \retval none
  228. */
  229. void i2s_init(uint32_t spi_periph, uint32_t i2s_mode, uint32_t i2s_standard, uint32_t i2s_ckpl)
  230. {
  231. uint32_t reg= 0U;
  232. reg = SPI_I2SCTL(spi_periph);
  233. reg &= I2S_INIT_MASK;
  234. /* enable I2S mode */
  235. reg |= (uint32_t)SPI_I2SCTL_I2SSEL;
  236. /* select I2S mode */
  237. reg |= (uint32_t)i2s_mode;
  238. /* select I2S standard */
  239. reg |= (uint32_t)i2s_standard;
  240. /* select I2S polarity */
  241. reg |= (uint32_t)i2s_ckpl;
  242. /* write to SPI_I2SCTL register */
  243. SPI_I2SCTL(spi_periph) = (uint32_t)reg;
  244. }
  245. /*!
  246. \brief I2S enable
  247. \param[in] spi_periph: SPIx(x=0,1,2,3,4)
  248. \param[out] none
  249. \retval none
  250. */
  251. void i2s_enable(uint32_t spi_periph)
  252. {
  253. SPI_I2SCTL(spi_periph) |= (uint32_t)SPI_I2SCTL_I2SEN;
  254. }
  255. /*!
  256. \brief I2S disable
  257. \param[in] spi_periph: SPIx(x=0,1,2,3,4)
  258. \param[out] none
  259. \retval none
  260. */
  261. void i2s_disable(uint32_t spi_periph)
  262. {
  263. SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SEN);
  264. }
  265. /*!
  266. \brief SPI nss output enable
  267. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  268. \param[out] none
  269. \retval none
  270. */
  271. void spi_nss_output_enable(uint32_t spi_periph)
  272. {
  273. SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSDRV;
  274. }
  275. /*!
  276. \brief SPI nss output disable
  277. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  278. \param[out] none
  279. \retval none
  280. */
  281. void spi_nss_output_disable(uint32_t spi_periph)
  282. {
  283. SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_NSSDRV);
  284. }
  285. /*!
  286. \brief SPI nss pin high level in software mode
  287. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  288. \param[out] none
  289. \retval none
  290. */
  291. void spi_nss_internal_high(uint32_t spi_periph)
  292. {
  293. SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SWNSS;
  294. }
  295. /*!
  296. \brief SPI nss pin low level in software mode
  297. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  298. \param[out] none
  299. \retval none
  300. */
  301. void spi_nss_internal_low(uint32_t spi_periph)
  302. {
  303. SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SWNSS);
  304. }
  305. /*!
  306. \brief SPI dma send or receive enable
  307. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  308. \param[in] spi_dma:
  309. \arg SPI_DMA_TRANSMIT: enable DMA transmit
  310. \arg SPI_DMA_RECEIVE: enable DMA receive
  311. \param[out] none
  312. \retval none
  313. */
  314. void spi_dma_enable(uint32_t spi_periph, uint8_t spi_dma)
  315. {
  316. if(SPI_DMA_TRANSMIT == spi_dma){
  317. SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMATEN;
  318. }else{
  319. SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMAREN;
  320. }
  321. }
  322. /*!
  323. \brief SPI dma send or receive diable
  324. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  325. \param[in] spi_dma:
  326. \arg SPI_DMA_TRANSMIT: disable DMA transmit
  327. \arg SPI_DMA_RECEIVE: disable DMA receive
  328. \param[out] none
  329. \retval none
  330. */
  331. void spi_dma_disable(uint32_t spi_periph, uint8_t spi_dma)
  332. {
  333. if(SPI_DMA_TRANSMIT == spi_dma){
  334. SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMATEN);
  335. }else{
  336. SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMAREN);
  337. }
  338. }
  339. /*!
  340. \brief configure SPI/I2S data frame format
  341. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  342. \param[in] frame_format:
  343. \arg SPI_FRAMESIZE_16BIT: SPI frame size is 16 bits
  344. \arg SPI_FRAMESIZE_8BIT: SPI frame size is 8 bits
  345. \param[out] none
  346. \retval none
  347. */
  348. void spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format)
  349. {
  350. /* clear SPI_CTL0_FF16 bit */
  351. SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_FF16);
  352. /* confige SPI_CTL0_FF16 bit */
  353. SPI_CTL0(spi_periph) |= (uint32_t)frame_format;
  354. }
  355. /*!
  356. \brief SPI transmit data
  357. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  358. \param[in] data: 16-bit data
  359. \param[out] none
  360. \retval none
  361. */
  362. void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data)
  363. {
  364. SPI_DATA(spi_periph) = (uint32_t)data;
  365. }
  366. /*!
  367. \brief receive data
  368. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  369. \param[out] none
  370. \retval 16-bit data
  371. */
  372. uint16_t spi_i2s_data_receive(uint32_t spi_periph)
  373. {
  374. return ((uint16_t)SPI_DATA(spi_periph));
  375. }
  376. /*!
  377. \brief configure SPI bidirectional transfer direction
  378. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  379. \param[in] transfer_direction:
  380. \arg SPI_BIDIRECTIONAL_TEANSMIT: SPI work in transmit-only mode
  381. \arg SPI_BIDIRECTIONAL_RECEIVE: SPI work in receive-only mode
  382. \retval none
  383. */
  384. void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction)
  385. {
  386. if(SPI_BIDIRECTIONAL_TEANSMIT == transfer_direction){
  387. /* set the transmit only mode */
  388. SPI_CTL0(spi_periph) |= (uint32_t)SPI_BIDIRECTIONAL_TEANSMIT;
  389. }else{
  390. /* set the receive only mode */
  391. SPI_CTL0(spi_periph) &= SPI_BIDIRECTIONAL_RECEIVE;
  392. }
  393. }
  394. /*!
  395. \brief SPI and I2S interrupt enable
  396. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  397. \param[in] spi_i2s_int:
  398. \arg SPI_I2S_INT_TBE: transmit buffer empty interrupt
  399. \arg SPI_I2S_INT_RBNE: receive buffer not empty interrupt
  400. \arg SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error,
  401. transmission underrun error and format error interrupt
  402. \param[out] none
  403. \retval none
  404. */
  405. void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t spi_i2s_int)
  406. {
  407. switch(spi_i2s_int){
  408. case SPI_I2S_INT_TBE:
  409. SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TBEIE;
  410. break;
  411. case SPI_I2S_INT_RBNE:
  412. SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_RBNEIE;
  413. break;
  414. case SPI_I2S_INT_ERR:
  415. SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_ERRIE;
  416. break;
  417. default:
  418. break;
  419. }
  420. }
  421. /*!
  422. \brief SPI and I2S interrupt disable
  423. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  424. \param[in] spi_i2s_int:
  425. \arg SPI_I2S_INT_TBE: transmit buffer empty interrupt
  426. \arg SPI_I2S_INT_RBNE: receive buffer not empty interrupt
  427. \arg SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error,
  428. transmission underrun error and format error interrupt
  429. \param[out] none
  430. \retval none
  431. */
  432. void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t spi_i2s_int)
  433. {
  434. switch(spi_i2s_int){
  435. case SPI_I2S_INT_TBE :
  436. SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TBEIE);
  437. break;
  438. case SPI_I2S_INT_RBNE :
  439. SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_RBNEIE);
  440. break;
  441. case SPI_I2S_INT_ERR :
  442. SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_ERRIE);
  443. break;
  444. default :
  445. break;
  446. }
  447. }
  448. /*!
  449. \brief get interrupt flag status
  450. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  451. \param[in] spi_i2s_int:
  452. \arg SPI_I2S_INT_TBE: transmit buffer empty interrupt
  453. \arg SPI_I2S_INT_RBNE: receive buffer not empty interrupt
  454. \arg SPI_I2S_INT_RXORERR: overrun interrupt
  455. \arg SPI_INT_CONFERR: config error interrupt
  456. \arg SPI_INT_CRCERR: CRC error interrupt
  457. \arg I2S_INT_TXURERR: underrun error interrupt
  458. \arg SPI_I2S_INT_FERR: format error interrupt
  459. \param[out] none
  460. \retval FlagStatus: SET or RESET
  461. */
  462. FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t spi_i2s_int)
  463. {
  464. uint32_t reg1 = SPI_STAT(spi_periph);
  465. uint32_t reg2 = SPI_CTL1(spi_periph);
  466. uint32_t temp1 = 0U;
  467. uint32_t temp2 = 0U;
  468. switch(spi_i2s_int){
  469. case SPI_I2S_INT_TBE :
  470. temp1 = reg1 & SPI_STAT_TBE;
  471. temp2 = reg2 & SPI_CTL1_TBEIE;
  472. break;
  473. case SPI_I2S_INT_RBNE :
  474. temp1 = reg1 & SPI_STAT_RBNE;
  475. temp2 = reg2 & SPI_CTL1_RBNEIE;
  476. break;
  477. case SPI_I2S_INT_RXORERR :
  478. temp1 = reg1 & SPI_STAT_RXORERR;
  479. temp2 = reg2 & SPI_CTL1_ERRIE;
  480. break;
  481. case SPI_INT_CONFERR :
  482. temp1 = reg1 & SPI_STAT_CONFERR;
  483. temp2 = reg2 & SPI_CTL1_ERRIE;
  484. break;
  485. case SPI_INT_CRCERR :
  486. temp1 = reg1 & SPI_STAT_CRCERR;
  487. temp2 = reg2 & SPI_CTL1_ERRIE;
  488. break;
  489. case I2S_INT_TXURERR :
  490. temp1 = reg1 & SPI_STAT_TXURERR;
  491. temp2 = reg2 & SPI_CTL1_ERRIE;
  492. break;
  493. case SPI_I2S_INT_FERR :
  494. temp1 = reg1 & SPI_STAT_FERR;
  495. temp2 = reg2 & SPI_CTL1_ERRIE;
  496. break;
  497. default :
  498. break;
  499. }
  500. if(temp1 && temp2){
  501. return SET;
  502. }else{
  503. return RESET;
  504. }
  505. }
  506. /*!
  507. \brief get flag status
  508. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  509. \param[in] spi_i2s_flag:
  510. \arg SPI_FLAG_TBE: transmit buffer empty flag
  511. \arg SPI_FLAG_RBNE: receive buffer not empty flag
  512. \arg SPI_FLAG_TRANS: transmit on-going flag
  513. \arg SPI_FLAG_RXORERR: receive Overrun flag
  514. \arg SPI_FLAG_CONFERR: mode config error flag
  515. \arg SPI_FLAG_CRCERR: CRC error flag
  516. \arg SPI_FLAG_FERR: format error interrupt flag
  517. \arg I2S_FLAG_TBE: transmit buffer empty flag
  518. \arg I2S_FLAG_RBNE: receive buffer not empty flag
  519. \arg I2S_FLAG_TRANS: transmit on-going flag
  520. \arg I2S_FLAG_RXORERR: overrun flag
  521. \arg I2S_FLAG_TXURERR: underrun error flag
  522. \arg I2S_FLAG_CH: channel side flag
  523. \arg I2S_FLAG_FERR: format error interrupt flag
  524. \param[out] none
  525. \retval FlagStatus: SET or RESET
  526. */
  527. FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t spi_i2s_flag)
  528. {
  529. if(SPI_STAT(spi_periph) & spi_i2s_flag){
  530. return SET;
  531. }else{
  532. return RESET;
  533. }
  534. }
  535. /*!
  536. \brief clear SPI CRC error flag status
  537. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  538. \param[out] none
  539. \retval none
  540. */
  541. void spi_crc_error_clear(uint32_t spi_periph)
  542. {
  543. SPI_STAT(spi_periph) &= (uint32_t)(~SPI_FLAG_CRCERR);
  544. }
  545. /*!
  546. \brief CRC function turn on
  547. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  548. \param[out] none
  549. \retval none
  550. */
  551. void spi_crc_on(uint32_t spi_periph)
  552. {
  553. SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN;
  554. }
  555. /*!
  556. \brief CRC function turn off
  557. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  558. \param[out] none
  559. \retval none
  560. */
  561. void spi_crc_off(uint32_t spi_periph)
  562. {
  563. SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCEN);
  564. }
  565. /*!
  566. \brief CRC polynomial set
  567. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  568. \param[in] crc_poly: CRC polynomial value
  569. \param[out] none
  570. \retval none
  571. */
  572. void spi_crc_polynomial_set(uint32_t spi_periph,uint16_t crc_poly)
  573. {
  574. /* enable SPI CRC */
  575. SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN;
  576. /* set SPI CRC polynomial */
  577. SPI_CRCPOLY(spi_periph) = (uint32_t)crc_poly;
  578. }
  579. /*!
  580. \brief get SPI CRC polynomial
  581. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  582. \param[out] none
  583. \retval 16-bit CRC polynomial
  584. */
  585. uint16_t spi_crc_polynomial_get(uint32_t spi_periph)
  586. {
  587. return ((uint16_t)SPI_CRCPOLY(spi_periph));
  588. }
  589. /*!
  590. \brief SPI next data is CRC value
  591. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  592. \param[out] none
  593. \retval none
  594. */
  595. void spi_crc_next(uint32_t spi_periph)
  596. {
  597. SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCNT;
  598. }
  599. /*!
  600. \brief get SPI CRC send value or receive value
  601. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  602. \param[in] spi_crc:
  603. \arg SPI_CRC_TX: get transmit crc value
  604. \arg SPI_CRC_RX: get receive crc value
  605. \param[out] none
  606. \retval 16-bit CRC value
  607. */
  608. uint16_t spi_crc_get(uint32_t spi_periph,uint8_t spi_crc)
  609. {
  610. if(SPI_CRC_TX == spi_crc){
  611. return ((uint16_t)(SPI_TCRC(spi_periph)));
  612. }else{
  613. return ((uint16_t)(SPI_RCRC(spi_periph)));
  614. }
  615. }
  616. /*!
  617. \brief enable SPI TI mode
  618. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  619. \param[out] none
  620. \retval none
  621. */
  622. void spi_ti_mode_enable(uint32_t spi_periph)
  623. {
  624. SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TMOD;
  625. }
  626. /*!
  627. \brief disable SPI TI mode
  628. \param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
  629. \param[out] none
  630. \retval none
  631. */
  632. void spi_ti_mode_disable(uint32_t spi_periph)
  633. {
  634. SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TMOD);
  635. }
  636. /*!
  637. \brief configure i2s full duplex mode
  638. \param[in] i2s_add_periph: I2Sx_ADD(x=1,2)
  639. \param[in] i2s_mode:
  640. \arg I2S_MODE_SLAVETX : I2S slave transmit mode
  641. \arg I2S_MODE_SLAVERX : I2S slave receive mode
  642. \arg I2S_MODE_MASTERTX : I2S master transmit mode
  643. \arg I2S_MODE_MASTERRX : I2S master receive mode
  644. \param[in] i2s_standard:
  645. \arg I2S_STD_PHILLIPS : I2S phillips standard
  646. \arg I2S_STD_MSB : I2S MSB standard
  647. \arg I2S_STD_LSB : I2S LSB standard
  648. \arg I2S_STD_PCMSHORT : I2S PCM short standard
  649. \arg I2S_STD_PCMLONG : I2S PCM long standard
  650. \param[in] i2s_ckpl:
  651. \arg I2S_CKPL_LOW : I2S clock polarity low level
  652. \arg I2S_CKPL_HIGH : I2S clock polarity high level
  653. \param[in] i2s_frameformat:
  654. \arg I2S_FRAMEFORMAT_DT16B_CH16B: I2S data length is 16 bit and channel length is 16 bit
  655. \arg I2S_FRAMEFORMAT_DT16B_CH32B: I2S data length is 16 bit and channel length is 32 bit
  656. \arg I2S_FRAMEFORMAT_DT24B_CH32B: I2S data length is 24 bit and channel length is 32 bit
  657. \arg I2S_FRAMEFORMAT_DT32B_CH32B: I2S data length is 32 bit and channel length is 32 bit
  658. \param[out] none
  659. \retval none
  660. */
  661. void i2s_full_duplex_mode_config(uint32_t i2s_add_periph, uint32_t i2s_mode, uint32_t i2s_standard,
  662. uint32_t i2s_ckpl, uint32_t i2s_frameformat)
  663. {
  664. uint32_t reg = 0U, tmp = 0U;
  665. reg = I2S_ADD_I2SCTL(i2s_add_periph);
  666. reg &= I2S_FULL_DUPLEX_MASK;
  667. /* get the mode of the extra I2S module I2Sx_ADD */
  668. if((I2S_MODE_MASTERTX == i2s_mode) || (I2S_MODE_SLAVETX == i2s_mode)){
  669. tmp = I2S_MODE_SLAVERX;
  670. }else{
  671. tmp = I2S_MODE_SLAVETX;
  672. }
  673. /* enable I2S mode */
  674. reg |= (uint32_t)SPI_I2SCTL_I2SSEL;
  675. /* select I2S mode */
  676. reg |= (uint32_t)tmp;
  677. /* select I2S standard */
  678. reg |= (uint32_t)i2s_standard;
  679. /* select I2S polarity */
  680. reg |= (uint32_t)i2s_ckpl;
  681. /* configure data frame format */
  682. reg |= (uint32_t)i2s_frameformat;
  683. /* write to SPI_I2SCTL register */
  684. I2S_ADD_I2SCTL(i2s_add_periph) = (uint32_t)reg;
  685. }
  686. /*!
  687. \brief quad wire SPI enable
  688. \param[in] spi_periph: SPIx(only x=5)
  689. \param[out] none
  690. \retval none
  691. */
  692. void qspi_enable(uint32_t spi_periph)
  693. {
  694. SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QMOD;
  695. }
  696. /*!
  697. \brief quad wire SPI disable
  698. \param[in] spi_periph: SPIx(only x=5)
  699. \param[out] none
  700. \retval none
  701. */
  702. void qspi_disable(uint32_t spi_periph)
  703. {
  704. SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QMOD);
  705. }
  706. /*!
  707. \brief quad wire SPI write enable
  708. \param[in] spi_periph: SPIx(only x=5)
  709. \param[out] none
  710. \retval none
  711. */
  712. void qspi_write_enable(uint32_t spi_periph)
  713. {
  714. SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QRD);
  715. }
  716. /*!
  717. \brief quad wire SPI read enable
  718. \param[in] spi_periph: SPIx(only x=5)
  719. \param[out] none
  720. \retval none
  721. */
  722. void qspi_read_enable(uint32_t spi_periph)
  723. {
  724. SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QRD;
  725. }
  726. /*!
  727. \brief SPI_IO2 and SPI_IO3 pin output enable
  728. \param[in] spi_periph: SPIx(only x=5)
  729. \param[out] none
  730. \retval none
  731. */
  732. void qspi_io23_output_enable(uint32_t spi_periph)
  733. {
  734. SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_IO23_DRV;
  735. }
  736. /*!
  737. \brief SPI_IO2 and SPI_IO3 pin output disable
  738. \param[in] spi_periph: SPIx(only x=5)
  739. \param[out] none
  740. \retval none
  741. */
  742. void qspi_io23_output_disable(uint32_t spi_periph)
  743. {
  744. SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_IO23_DRV);
  745. }