gd32f30x_spi.c 23 KB

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