lib_spi.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. /**
  2. ******************************************************************************
  3. * @file lib_spi.c
  4. * @author Application Team
  5. * @version V1.1.0
  6. * @date 2019-10-28
  7. * @brief SPI library.
  8. ******************************************************************************
  9. * @attention
  10. *
  11. ******************************************************************************
  12. */
  13. #include "lib_spi.h"
  14. #define SPI_MISC_RSTValue (0UL)
  15. /**
  16. * @brief Initializes SPI peripheral registers to their default reset values(Reset SPI FIFO when this function is called).
  17. * @param SPIx:SPI1~SPI3
  18. * @retval None
  19. */
  20. void SPI_DeviceInit(SPI_Type *SPIx)
  21. {
  22. __IO uint32_t dummy_data = 0UL;
  23. /* Check parameters */
  24. assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
  25. /* Disable SPI */
  26. SPIx->CTRL = 0;
  27. /* SPI soft reset */
  28. SPIx->CTRL |= SPI_CTRL_RST;
  29. SPIx->CTRL &= ~SPI_CTRL_RST;
  30. /* Clear flag */
  31. dummy_data = SPIx->RXDAT;
  32. dummy_data += 1;
  33. SPIx->TXSTS = SPI_TXSTS_TXIF|SPI_TXSTS_DMATXDONE;
  34. SPIx->RXSTS = SPI_RXSTS_RXIF;
  35. /* write default values */
  36. SPIx->MISC = SPI_MISC_RSTValue;
  37. }
  38. /**
  39. * @brief Fills each SPI_InitType member with its default value.
  40. * @param InitStruct: pointer to an SPI_InitType structure which will be initialized.
  41. * @retval None
  42. */
  43. void SPI_StructInit(SPI_InitType *InitStruct)
  44. {
  45. /*--------------- Reset SPI init structure parameters values ---------------*/
  46. /* Initialize the ClockDivision member */
  47. InitStruct->ClockDivision = SPI_CLKDIV_2;
  48. /* Initialize the CSNSoft member */
  49. InitStruct->CSNSoft = SPI_CSNSOFT_DISABLE;
  50. /* Initialize the Mode member */
  51. InitStruct->Mode = SPI_MODE_MASTER;
  52. /* Initialize the SPH member */
  53. InitStruct->SPH = SPI_SPH_0;
  54. /* Initialize the SPO member */
  55. InitStruct->SPO = SPI_SPO_0;
  56. /* Initialize the SWAP member */
  57. InitStruct->SWAP = SPI_SWAP_DISABLE;
  58. }
  59. /**
  60. * @brief Initializes SPI.
  61. * @param SPIx:SPI1~SPI3
  62. InitStruct: SPI configuration.
  63. Mode:
  64. SPI_MODE_MASTER
  65. SPI_MODE_SLAVE
  66. SPH:
  67. SPI_SPH_0
  68. SPI_SPH_1
  69. SPO:
  70. SPI_SPO_0
  71. SPI_SPO_1
  72. ClockDivision:
  73. SPI_CLKDIV_2
  74. SPI_CLKDIV_4
  75. SPI_CLKDIV_8
  76. SPI_CLKDIV_16
  77. SPI_CLKDIV_32
  78. SPI_CLKDIV_64
  79. SPI_CLKDIV_128
  80. CSNSoft:
  81. SPI_CSNSOFT_ENABLE
  82. SPI_CSNSOFT_DISABLE
  83. SWAP:
  84. SPI_SWAP_ENABLE
  85. SPI_SWAP_DISABLE
  86. * @retval None
  87. */
  88. void SPI_Init(SPI_Type *SPIx, SPI_InitType *InitStruct)
  89. {
  90. uint32_t tmp;
  91. /* Check parameters */
  92. assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
  93. assert_parameters(IS_SPI_MODE(InitStruct->Mode));
  94. assert_parameters(IS_SPI_SPH(InitStruct->SPH));
  95. assert_parameters(IS_SPI_SPO(InitStruct->SPO));
  96. assert_parameters(IS_SPI_CLKDIV(InitStruct->ClockDivision));
  97. assert_parameters(IS_SPI_CSN(InitStruct->CSNSoft));
  98. assert_parameters(IS_SPI_SWAP(InitStruct->SWAP));
  99. tmp = SPIx->CTRL;
  100. tmp &= ~(SPI_CTRL_MOD\
  101. |SPI_CTRL_SCKPHA\
  102. |SPI_CTRL_SCKPOL\
  103. |SPI_CTRL_CSGPIO\
  104. |SPI_CTRL_SWAP\
  105. |SPI_CTRL_SCKSEL);
  106. tmp |= (InitStruct->Mode\
  107. |InitStruct->SPH\
  108. |InitStruct->SPO\
  109. |InitStruct->CSNSoft\
  110. |InitStruct->SWAP\
  111. |InitStruct->ClockDivision);
  112. SPIx->CTRL = tmp;
  113. }
  114. /**
  115. * @brief Enables or disables SPI.
  116. * @param SPIx:SPI1~SPI3
  117. NewState:
  118. ENABLE
  119. DISABLE
  120. * @retval None
  121. */
  122. void SPI_Cmd(SPI_Type *SPIx, uint32_t NewState)
  123. {
  124. /* Check parameters */
  125. assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
  126. assert_parameters(IS_FUNCTIONAL_STATE(NewState));
  127. if (NewState == ENABLE)
  128. SPIx->CTRL |= SPI_CTRL_EN;
  129. else
  130. SPIx->CTRL &= ~SPI_CTRL_EN;
  131. }
  132. /**
  133. * @brief Enables or disables SPI interrupt.
  134. * @param SPIx:SPI1~SPI3
  135. INTMask: can use the '|' operator
  136. SPI_INT_TX
  137. SPI_INT_RX
  138. NewState:
  139. ENABLE
  140. DISABLE
  141. * @retval None
  142. */
  143. void SPI_INTConfig(SPI_Type *SPIx, uint32_t INTMask, uint32_t NewState)
  144. {
  145. uint32_t tmp;
  146. /* Check parameters */
  147. assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
  148. assert_parameters(IS_SPI_INT(INTMask));
  149. assert_parameters(IS_FUNCTIONAL_STATE(NewState));
  150. if (INTMask & 0x80000000)
  151. {
  152. INTMask &= 0xFFFF;
  153. tmp = SPIx->TXSTS;
  154. tmp &= ~SPI_TXSTS_TXIF;
  155. if (NewState == ENABLE)
  156. {
  157. tmp |= INTMask;
  158. SPIx->TXSTS = tmp;
  159. }
  160. else
  161. {
  162. tmp &= ~INTMask;
  163. SPIx->TXSTS = tmp;
  164. }
  165. }
  166. if (INTMask & 0x40000000)
  167. {
  168. INTMask &= 0xFFFF;
  169. tmp = SPIx->RXSTS;
  170. tmp &= ~SPI_RXSTS_RXIF;
  171. if (NewState == ENABLE)
  172. {
  173. tmp |= INTMask;
  174. SPIx->RXSTS = tmp;
  175. }
  176. else
  177. {
  178. tmp &= ~INTMask;
  179. SPIx->RXSTS = tmp;
  180. }
  181. }
  182. }
  183. /**
  184. * @brief Gets SPI status flag.
  185. * @param SPIx:SPI1~SPI3
  186. Status:
  187. SPI_STS_TXIF
  188. SPI_STS_TXEMPTY
  189. SPI_STS_TXFUR
  190. SPI_STS_DMATXDONE
  191. SPI_STS_RXIF
  192. SPI_STS_RXFULL
  193. SPI_STS_RXFOV
  194. SPI_STS_BSY
  195. SPI_STS_RFF
  196. SPI_STS_RNE
  197. SPI_STS_TNF
  198. SPI_STS_TFE
  199. * @retval Flag status.
  200. */
  201. uint8_t SPI_GetStatus(SPI_Type *SPIx, uint32_t Status)
  202. {
  203. /* Check parameters */
  204. assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
  205. assert_parameters(IS_SPI_STSR(Status));
  206. if ((Status&0xE0000000) == 0x80000000)
  207. {
  208. if (Status&SPIx->TXSTS)
  209. return 1;
  210. else
  211. return 0;
  212. }
  213. else if ((Status&0xE0000000) == 0x40000000)
  214. {
  215. if (Status&SPIx->RXSTS)
  216. return 1;
  217. else
  218. return 0;
  219. }
  220. else
  221. {
  222. if (Status&SPIx->MISC)
  223. return 1;
  224. else
  225. return 0;
  226. }
  227. }
  228. /**
  229. * @brief Clears SPI status flag.
  230. * @param SPIx:SPI1~SPI3
  231. Status: can use the '|' operator
  232. SPI_STS_TXIF
  233. SPI_STS_RXIF
  234. SPI_STS_DMATXDONE
  235. * @retval None
  236. */
  237. void SPI_ClearStatus(SPI_Type *SPIx, uint32_t Status)
  238. {
  239. uint32_t tmp = 0UL;
  240. /* Check parameters */
  241. assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
  242. assert_parameters(IS_SPI_STSC(Status));
  243. if (Status & 0x80000000)
  244. {
  245. Status &= 0xFFFF;
  246. tmp = SPIx->TXSTS;
  247. tmp &= ~(SPI_TXSTS_DMATXDONE | SPI_TXSTS_TXIF);
  248. tmp |= Status;
  249. SPIx->TXSTS = tmp;
  250. }
  251. if (Status & 0x40000000)
  252. {
  253. Status &= 0xFFFF;
  254. SPIx->RXSTS |= Status;
  255. }
  256. }
  257. /**
  258. * @brief Loads send data register.
  259. * @param SPIx:SPI1~SPI3
  260. ch: data write to send data register
  261. * @retval None
  262. */
  263. void SPI_SendData(SPI_Type *SPIx, uint8_t ch)
  264. {
  265. /* Check parameters */
  266. assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
  267. SPIx->TXDAT = ch;
  268. }
  269. /**
  270. * @brief Reads receive data register.
  271. * @param SPIx:SPI1~SPI3
  272. * @retval receive data value
  273. */
  274. uint8_t SPI_ReceiveData(SPI_Type *SPIx)
  275. {
  276. /* Check parameters */
  277. assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
  278. return (SPIx->RXDAT);
  279. }
  280. /**
  281. * @brief Configures transmit fifo level.
  282. * @param SPIx:SPI1~SPI3
  283. FIFOLevel:
  284. SPI_TXFLEV_0
  285. SPI_TXFLEV_1
  286. SPI_TXFLEV_2
  287. SPI_TXFLEV_3
  288. SPI_TXFLEV_4
  289. SPI_TXFLEV_5
  290. SPI_TXFLEV_6
  291. SPI_TXFLEV_7
  292. * @retval None
  293. */
  294. void SPI_TransmitFIFOLevelConfig(SPI_Type *SPIx, uint32_t FIFOLevel)
  295. {
  296. uint32_t tmp;
  297. /* Check parameters */
  298. assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
  299. assert_parameters(IS_SPI_TXFLEV(FIFOLevel));
  300. tmp = SPIx->TXSTS;
  301. tmp &= ~(SPI_TXSTS_TXFLEV | SPI_TXSTS_TXIF|SPI_TXSTS_DMATXDONE);
  302. tmp |= FIFOLevel;
  303. SPIx->TXSTS = tmp;
  304. }
  305. /**
  306. * @brief Configures receive fifo level.
  307. * @param SPIx:SPI1~SPI3
  308. FIFOLevel:
  309. SPI_RXFLEV_0
  310. SPI_RXFLEV_1
  311. SPI_RXFLEV_2
  312. SPI_RXFLEV_3
  313. SPI_RXFLEV_4
  314. SPI_RXFLEV_5
  315. SPI_RXFLEV_6
  316. SPI_RXFLEV_7
  317. * @retval None
  318. */
  319. void SPI_ReceiveFIFOLevelConfig(SPI_Type *SPIx, uint32_t FIFOLevel)
  320. {
  321. uint32_t tmp;
  322. /* Check parameters */
  323. assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
  324. assert_parameters(IS_SPI_RXFLEV(FIFOLevel));
  325. tmp = SPIx->RXSTS;
  326. tmp &= ~(SPI_RXSTS_RXFLEV | SPI_RXSTS_RXIF);
  327. tmp |= FIFOLevel;
  328. SPIx->RXSTS = tmp;
  329. }
  330. /**
  331. * @brief Gets transmit fifo level.
  332. * @param SPIx:SPI1~SPI3
  333. * @retval Transmit fifo level.
  334. */
  335. uint8_t SPI_GetTransmitFIFOLevel(SPI_Type *SPIx)
  336. {
  337. /* Check parameters */
  338. assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
  339. return (SPIx->TXSTS & SPI_TXSTS_TXFFLAG);
  340. }
  341. /**
  342. * @brief Gets receive fifo level.
  343. * @param SPIx:SPI1~SPI3
  344. * @retval Receive fifo level.
  345. */
  346. uint8_t SPI_GetReceiveFIFOLevel(SPI_Type *SPIx)
  347. {
  348. /* Check parameters */
  349. assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
  350. return (SPIx->RXSTS & SPI_RXSTS_RXFFLAG);
  351. }
  352. /**
  353. * @brief Enables or disables FIFO smart mode.
  354. * @param SPIx:SPI1~SPI3
  355. NewState:
  356. ENABLE
  357. DISABLE
  358. * @retval None
  359. */
  360. void SPI_SmartModeCmd(SPI_Type *SPIx, uint32_t NewState)
  361. {
  362. /* Check parameters */
  363. assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
  364. assert_parameters(IS_FUNCTIONAL_STATE(NewState));
  365. if (NewState == ENABLE)
  366. {
  367. SPIx->MISC |= SPI_MISC_SMART;
  368. }
  369. else
  370. {
  371. SPIx->MISC &= ~SPI_MISC_SMART;
  372. }
  373. }
  374. /**
  375. * @brief Enables or disables FIFO over write mode.
  376. * @param SPIx:SPI1~SPI3
  377. NewState:
  378. ENABLE
  379. DISABLE
  380. * @retval None
  381. */
  382. void SPI_OverWriteModeCmd(SPI_Type *SPIx, uint32_t NewState)
  383. {
  384. /* Check parameters */
  385. assert_parameters(IS_SPI_ALL_INSTANCE(SPIx));
  386. assert_parameters(IS_FUNCTIONAL_STATE(NewState));
  387. if (NewState == ENABLE)
  388. {
  389. SPIx->MISC |= SPI_MISC_OVER;
  390. }
  391. else
  392. {
  393. SPIx->MISC &= ~SPI_MISC_OVER;
  394. }
  395. }
  396. /*********************************** END OF FILE ******************************/