n32g45x_qspi.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. /*****************************************************************************
  2. * Copyright (c) 2019, Nations Technologies Inc.
  3. *
  4. * All rights reserved.
  5. * ****************************************************************************
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. *
  10. * - Redistributions of source code must retain the above copyright notice,
  11. * this list of conditions and the disclaimer below.
  12. *
  13. * Nations' name may not be used to endorse or promote products derived from
  14. * this software without specific prior written permission.
  15. *
  16. * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
  17. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  18. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
  19. * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
  20. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  21. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  22. * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  23. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  24. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  25. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. * ****************************************************************************/
  27. /**
  28. * @file n32g45x_qspi.c
  29. * @author Nations
  30. * @version v1.0.1
  31. *
  32. * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved.
  33. */
  34. #include "n32g45x_qspi.h"
  35. /**
  36. * @brief Control QSPI function switch.
  37. * @param cmd select enable or disable QSPI.
  38. */
  39. void QSPI_Cmd(bool cmd)
  40. {
  41. if (cmd != DISABLE)
  42. {
  43. QSPI->SLAVE_EN = QSPI_SLAVE_EN_SEN;
  44. QSPI->EN = QSPI_EN_QEN;
  45. }
  46. else
  47. {
  48. QSPI->SLAVE_EN &= ~QSPI_SLAVE_EN_SEN;
  49. QSPI->EN &= ~QSPI_EN_QEN;
  50. }
  51. }
  52. /**
  53. * @brief Control QSPI XIP function switch.
  54. * @param cmd select enable or disable QSPI XIP.
  55. */
  56. void QSPI_XIP_Cmd(bool cmd)
  57. {
  58. if (cmd != DISABLE)
  59. {
  60. QSPI->XIP_SLAVE_EN = QSPI_XIP_SLAVE_EN_SEN;
  61. }
  62. else
  63. {
  64. QSPI->XIP_SLAVE_EN &= ~QSPI_XIP_SLAVE_EN_SEN;
  65. }
  66. }
  67. /**
  68. * @brief Deinitializes the QSPI peripheral registers to its default reset values.
  69. */
  70. void QSPI_DeInit(void)
  71. {
  72. RCC_EnableAHBPeriphReset(RCC_AHB_PERIPH_QSPI, ENABLE);
  73. RCC_EnableAHBPeriphReset(RCC_AHB_PERIPH_QSPI, DISABLE);
  74. }
  75. /**
  76. * @brief Merge configuration from the buffer of QSPI para struct, then write it into related registers.
  77. * @param QSPI_InitStruct pointer to buffer of QSPI para struct.
  78. */
  79. void QspiInitConfig(QSPI_InitType* QSPI_InitStruct)
  80. {
  81. uint32_t tmpregister = 0;
  82. /* Check the parameters */
  83. assert_param(IS_QSPI_SPI_FRF(QSPI_InitStruct->SPI_FRF));
  84. assert_param(IS_QSPI_CFS(QSPI_InitStruct->CFS));
  85. assert_param(IS_QSPI_SSTE(QSPI_InitStruct->SSTE));
  86. assert_param(IS_QSPI_TMOD(QSPI_InitStruct->TMOD));
  87. assert_param(IS_QSPI_SCPOL(QSPI_InitStruct->SCPOL));
  88. assert_param(IS_QSPI_SCPH(QSPI_InitStruct->SCPH));
  89. assert_param(IS_QSPI_FRF(QSPI_InitStruct->FRF));
  90. assert_param(IS_QSPI_DFS(QSPI_InitStruct->DFS));
  91. assert_param(IS_QSPI_MWMOD(QSPI_InitStruct->MWMOD));
  92. assert_param(IS_QSPI_MC_DIR(QSPI_InitStruct->MC_DIR));
  93. assert_param(IS_QSPI_MHS_EN(QSPI_InitStruct->MHS_EN));
  94. assert_param(IS_QSPI_SES(QSPI_InitStruct->SES));
  95. assert_param(IS_QSPI_SDCN(QSPI_InitStruct->SDCN));
  96. assert_param(IS_QSPI_ENH_CLK_STRETCH_EN(QSPI_InitStruct->ENHANCED_CLK_STRETCH_EN));
  97. assert_param(IS_QSPI_ENH_INST_DDR_EN(QSPI_InitStruct->ENHANCED_INST_DDR_EN));
  98. assert_param(IS_QSPI_ENH_SPI_DDR_EN(QSPI_InitStruct->ENHANCED_SPI_DDR_EN));
  99. assert_param(IS_QSPI_ENH_WAIT_CYCLES(QSPI_InitStruct->ENHANCED_WAIT_CYCLES));
  100. assert_param(IS_QSPI_ENH_INST_L(QSPI_InitStruct->ENHANCED_INST_L));
  101. assert_param(IS_QSPI_ENH_ADDR_LEN(QSPI_InitStruct->ENHANCED_ADDR_LEN));
  102. assert_param(IS_QSPI_ENH_TRANS_TYPE(QSPI_InitStruct->ENHANCED_TRANS_TYPE));
  103. assert_param(IS_QSPI_XIP_MBL(QSPI_InitStruct->XIP_MBL));
  104. assert_param(IS_QSPI_XIP_CT_EN(QSPI_InitStruct->XIP_CT_EN));
  105. assert_param(IS_QSPI_XIP_INST_EN(QSPI_InitStruct->XIP_INST_EN));
  106. assert_param(IS_QSPI_INST_DDR_EN(QSPI_InitStruct->XIP_INST_DDR_EN));
  107. assert_param(IS_QSPI_DDR_EN(QSPI_InitStruct->XIP_DDR_EN));
  108. assert_param(IS_QSPI_XIP_DFS_HC(QSPI_InitStruct->XIP_DFS_HC));
  109. assert_param(IS_QSPI_XIP_WAIT_CYCLES(QSPI_InitStruct->XIP_WAIT_CYCLES));
  110. assert_param(IS_QSPI_XIP_MD_BIT_EN(QSPI_InitStruct->XIP_MD_BITS_EN));
  111. assert_param(IS_QSPI_XIP_INST_L(QSPI_InitStruct->XIP_INST_L));
  112. assert_param(IS_QSPI_XIP_ADDR_LEN(QSPI_InitStruct->XIP_ADDR_LEN));
  113. assert_param(IS_QSPI_XIP_TRANS_TYPE(QSPI_InitStruct->XIP_TRANS_TYPE));
  114. assert_param(IS_QSPI_XIP_FRF(QSPI_InitStruct->XIP_FRF));
  115. assert_param(IS_QSPI_XIP_MODE(QSPI_InitStruct->XIP_MD_BITS));
  116. assert_param(IS_QSPI_XIP_INCR_TOC(QSPI_InitStruct->ITOC));
  117. assert_param(IS_QSPI_XIP_WRAP_TOC(QSPI_InitStruct->WTOC));
  118. assert_param(IS_QSPI_XIP_TOUT(QSPI_InitStruct->XTOUT));
  119. assert_param(IS_QSPI_NDF(QSPI_InitStruct->NDF));
  120. assert_param(IS_QSPI_CLK_DIV(QSPI_InitStruct->CLK_DIV));
  121. assert_param(IS_QSPI_TXFT(QSPI_InitStruct->TXFT));
  122. assert_param(IS_QSPI_RXFT(QSPI_InitStruct->RXFT));
  123. assert_param(IS_QSPI_TXFN(QSPI_InitStruct->TXFN));
  124. assert_param(IS_QSPI_RXFN(QSPI_InitStruct->RXFN));
  125. assert_param(IS_QSPI_DDR_TXDE(QSPI_InitStruct->TXDE));
  126. if((QSPI_InitStruct->SPI_FRF) == QSPI_CTRL0_SPI_FRF_STANDARD_FORMAT)
  127. {
  128. tmpregister = (uint32_t)(QSPI_InitStruct->SPI_FRF | QSPI_InitStruct->CFS | QSPI_InitStruct->SSTE | QSPI_InitStruct->TMOD
  129. | QSPI_InitStruct->SCPOL | QSPI_InitStruct->SCPH | QSPI_InitStruct->FRF | QSPI_InitStruct->DFS);
  130. QSPI->CTRL0 = tmpregister;
  131. tmpregister = 0;
  132. tmpregister = (uint32_t)(QSPI_InitStruct->MWMOD | QSPI_InitStruct->MC_DIR | QSPI_InitStruct->MHS_EN);
  133. QSPI->MW_CTRL = tmpregister;
  134. tmpregister = 0;
  135. tmpregister = (uint32_t)(QSPI_InitStruct->SES | QSPI_InitStruct->SDCN);
  136. QSPI->RS_DELAY = tmpregister;
  137. }
  138. else if((QSPI_InitStruct->SPI_FRF == QSPI_CTRL0_SPI_FRF_DUAL_FORMAT) || (QSPI_InitStruct->SPI_FRF == QSPI_CTRL0_SPI_FRF_QUAD_FORMAT))
  139. {
  140. tmpregister = (uint32_t)(QSPI_InitStruct->SPI_FRF | QSPI_InitStruct->CFS | QSPI_InitStruct->SSTE | QSPI_InitStruct->TMOD
  141. | QSPI_InitStruct->SCPOL | QSPI_InitStruct->SCPH | QSPI_InitStruct->FRF | QSPI_InitStruct->DFS);
  142. QSPI->CTRL0 = tmpregister;
  143. tmpregister = 0;
  144. tmpregister = (uint32_t)(QSPI_InitStruct->MWMOD | QSPI_InitStruct->MC_DIR | QSPI_InitStruct->MHS_EN);
  145. QSPI->MW_CTRL = tmpregister;
  146. tmpregister = 0;
  147. tmpregister = (uint32_t)(QSPI_InitStruct->SES | QSPI_InitStruct->SDCN);
  148. QSPI->RS_DELAY = tmpregister;
  149. tmpregister = 0;
  150. tmpregister = (uint32_t)(QSPI_InitStruct->ENHANCED_CLK_STRETCH_EN | QSPI_InitStruct->ENHANCED_INST_DDR_EN
  151. | QSPI_InitStruct->ENHANCED_SPI_DDR_EN | QSPI_InitStruct->ENHANCED_WAIT_CYCLES | QSPI_InitStruct->ENHANCED_INST_L
  152. | QSPI_InitStruct->ENHANCED_ADDR_LEN | QSPI_InitStruct->ENHANCED_TRANS_TYPE);
  153. QSPI->ENH_CTRL0 = tmpregister;
  154. tmpregister = 0;
  155. tmpregister = (uint32_t)(QSPI_InitStruct->XIP_MBL | QSPI_InitStruct->XIP_CT_EN | QSPI_InitStruct->XIP_INST_EN | QSPI_InitStruct->XIP_INST_DDR_EN
  156. | QSPI_InitStruct->XIP_DDR_EN | QSPI_InitStruct->XIP_DFS_HC | QSPI_InitStruct->XIP_WAIT_CYCLES | QSPI_InitStruct->XIP_MD_BITS_EN
  157. | QSPI_InitStruct->XIP_INST_L | QSPI_InitStruct->XIP_ADDR_LEN | QSPI_InitStruct->XIP_TRANS_TYPE | QSPI_InitStruct->XIP_FRF);
  158. QSPI->XIP_CTRL = tmpregister;
  159. QSPI->XIP_MODE = QSPI_InitStruct->XIP_MD_BITS;
  160. QSPI->XIP_INCR_TOC = QSPI_InitStruct->ITOC;
  161. QSPI->XIP_WRAP_TOC = QSPI_InitStruct->WTOC;
  162. QSPI->XIP_TOUT = QSPI_InitStruct->XTOUT;
  163. }
  164. QSPI->CTRL1 = QSPI_InitStruct->NDF;
  165. QSPI->BAUD = QSPI_InitStruct->CLK_DIV;
  166. QSPI->TXFT = QSPI_InitStruct->TXFT;
  167. QSPI->RXFT = QSPI_InitStruct->RXFT;
  168. QSPI->TXFN = QSPI_InitStruct->TXFN;
  169. QSPI->RXFN = QSPI_InitStruct->RXFN;
  170. QSPI->DDR_TXDE = QSPI_InitStruct->TXDE;
  171. }
  172. /**
  173. * @brief Configure single GPIO port as GPIO_Mode_AF_PP.
  174. * @param GPIOx x can be A to G to select the GPIO port.
  175. * @param Pin This parameter can be GPIO_PIN_0~GPIO_PIN_15.
  176. */
  177. static void QSPI_SingleGpioConfig(GPIO_Module* GPIOx, uint16_t Pin)
  178. {
  179. GPIO_InitType GPIO_InitStructure;
  180. GPIO_InitStructure.Pin = Pin;
  181. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  182. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  183. GPIO_InitPeripheral(GPIOx, &GPIO_InitStructure);
  184. }
  185. /**
  186. * @brief Remap QSPI AFIO group by selecting the pin of NSS.
  187. * @param qspi_nss_port_sel select the pin of NSS.
  188. QSPI_NSS_PORTA_SEL:QSPI remap by PA4~PA7 and PC4~PC5.
  189. QSPI_NSS_PORTC_SEL:QSPI remap by PC10~PC12 and PD0~PD2.
  190. QSPI_NSS_PORTF_SEL:QSPI remap by PF0~PF5.
  191. * @param IO1_Input IO1 Configure as input or not.
  192. * @param IO3_Output IO3 Configure as output or not.
  193. */
  194. void QSPI_GPIO(QSPI_NSS_PORT_SEL qspi_nss_port_sel, bool IO1_Input, bool IO3_Output)
  195. {
  196. GPIO_InitType GPIO_InitStructure;
  197. switch (qspi_nss_port_sel)
  198. {
  199. case QSPI_NSS_PORTA_SEL:
  200. RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA | RCC_APB2_PERIPH_GPIOC | RCC_APB2_PERIPH_AFIO, ENABLE);
  201. RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_QSPI, ENABLE);
  202. GPIO_ConfigPinRemap(GPIO_RMP3_QSPI, DISABLE); //clear two bits of qspi
  203. QSPI_SingleGpioConfig(GPIOA, GPIO_PIN_4); // NSS
  204. QSPI_SingleGpioConfig(GPIOA, GPIO_PIN_5); // SCK
  205. QSPI_SingleGpioConfig(GPIOA, GPIO_PIN_6); // IO0
  206. if (IO1_Input)
  207. {
  208. GPIO_InitStructure.Pin = GPIO_PIN_7; // IO1
  209. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  210. GPIO_InitStructure.GPIO_Speed = GPIO_INPUT;
  211. GPIO_InitPeripheral(GPIOC, &GPIO_InitStructure);
  212. }
  213. else
  214. {
  215. QSPI_SingleGpioConfig(GPIOA, GPIO_PIN_7); // IO1
  216. }
  217. if (IO3_Output)
  218. {
  219. GPIO_InitStructure.Pin = GPIO_PIN_4 | GPIO_PIN_5; // IO2 and IO3
  220. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  221. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  222. GPIO_InitPeripheral(GPIOC, &GPIO_InitStructure);
  223. GPIOC->PBSC |= GPIO_PIN_4 | GPIO_PIN_5;
  224. }
  225. else
  226. {
  227. QSPI_SingleGpioConfig(GPIOC, GPIO_PIN_4); // IO2
  228. QSPI_SingleGpioConfig(GPIOC, GPIO_PIN_5); // IO3
  229. }
  230. break;
  231. case QSPI_NSS_PORTC_SEL:
  232. RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC | RCC_APB2_PERIPH_GPIOD | RCC_APB2_PERIPH_AFIO, ENABLE);
  233. RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_QSPI, ENABLE);
  234. GPIO_ConfigPinRemap(GPIO_RMP3_QSPI, ENABLE);
  235. GPIO_ConfigPinRemap(GPIO_RMP_QSPI_XIP_EN, ENABLE);
  236. QSPI_SingleGpioConfig(GPIOC, GPIO_PIN_10); // NSS
  237. QSPI_SingleGpioConfig(GPIOC, GPIO_PIN_11); // SCK
  238. QSPI_SingleGpioConfig(GPIOC, GPIO_PIN_12); // IO0
  239. if (IO1_Input)
  240. {
  241. GPIO_InitStructure.Pin = GPIO_PIN_0; // IO1
  242. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  243. GPIO_InitStructure.GPIO_Speed = GPIO_INPUT;
  244. GPIO_InitPeripheral(GPIOD, &GPIO_InitStructure);
  245. }
  246. else
  247. {
  248. QSPI_SingleGpioConfig(GPIOD, GPIO_PIN_0); // IO1
  249. }
  250. if (IO3_Output)
  251. {
  252. GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2; // IO2 and IO3
  253. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  254. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  255. GPIO_InitPeripheral(GPIOD, &GPIO_InitStructure);
  256. GPIOD->PBSC |= GPIO_PIN_1 | GPIO_PIN_2;
  257. }
  258. else
  259. {
  260. QSPI_SingleGpioConfig(GPIOD, GPIO_PIN_1); // IO2
  261. QSPI_SingleGpioConfig(GPIOD, GPIO_PIN_2); // IO3
  262. }
  263. break;
  264. case QSPI_NSS_PORTF_SEL:
  265. RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOF | RCC_APB2_PERIPH_AFIO, ENABLE);
  266. RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_QSPI, ENABLE);
  267. GPIO_ConfigPinRemap(GPIO_RMP1_QSPI, ENABLE);
  268. QSPI_SingleGpioConfig(GPIOF, GPIO_PIN_0); // NSS
  269. QSPI_SingleGpioConfig(GPIOF, GPIO_PIN_1); // SCK
  270. QSPI_SingleGpioConfig(GPIOF, GPIO_PIN_2); // IO0
  271. if (IO1_Input)
  272. {
  273. GPIO_InitStructure.Pin = GPIO_PIN_3; // IO1
  274. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  275. GPIO_InitStructure.GPIO_Speed = GPIO_INPUT;
  276. GPIO_InitPeripheral(GPIOF, &GPIO_InitStructure);
  277. }
  278. else
  279. {
  280. QSPI_SingleGpioConfig(GPIOF, GPIO_PIN_3); // IO1
  281. }
  282. if (IO3_Output)
  283. {
  284. GPIO_InitStructure.Pin = GPIO_PIN_4 | GPIO_PIN_5; // IO2 and IO3
  285. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  286. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  287. GPIO_InitPeripheral(GPIOF, &GPIO_InitStructure);
  288. GPIOF->PBSC |= GPIO_PIN_4 | GPIO_PIN_5;
  289. }
  290. else
  291. {
  292. QSPI_SingleGpioConfig(GPIOF, GPIO_PIN_4); // IO2
  293. QSPI_SingleGpioConfig(GPIOF, GPIO_PIN_5); // IO3
  294. }
  295. break;
  296. default:
  297. break;
  298. }
  299. }
  300. /**
  301. * @brief Configuration of QSPI DMA.
  302. * @param Tx transmit or receive data.
  303. QSPI_DMA_CTRL_TX_DMA_EN:transmit data
  304. * @param TxDataLevel dma transmit data level.
  305. */
  306. void QSPI_Tx_DMA_CTRL_Config(uint8_t Cmd,uint8_t TxDataLevel)
  307. {
  308. assert_param(IS_FUNCTIONAL_STATE(Cmd));
  309. assert_param(IS_QSPI_DMATDL_CTRL(TxDataLevel));
  310. if (Cmd)
  311. {
  312. QSPI->DMATDL_CTRL = TxDataLevel;
  313. QSPI->DMA_CTRL |= QSPI_DMA_CTRL_TX_DMA_EN;
  314. }
  315. else
  316. {
  317. QSPI->DMA_CTRL &= ~QSPI_DMA_CTRL_TX_DMA_EN;
  318. }
  319. }
  320. /**
  321. * @brief Configuration of QSPI DMA.
  322. * @param Rx transmit or receive data.
  323. QSPI_DMA_CTRL_RX_DMA_EN:receive data
  324. * @param RxDataLevel dma receive data level.
  325. */
  326. void QSPI_Rx_DMA_CTRL_Config(uint8_t Cmd, uint8_t RxDataLevel)
  327. {
  328. assert_param(IS_FUNCTIONAL_STATE(Cmd));
  329. assert_param(IS_QSPI_DMARDL_CTRL(RxDataLevel));
  330. if (Cmd)
  331. {
  332. QSPI->DMARDL_CTRL = RxDataLevel;
  333. QSPI->DMA_CTRL |= QSPI_DMA_CTRL_RX_DMA_EN;
  334. }
  335. else
  336. {
  337. QSPI->DMA_CTRL &= ~QSPI_DMA_CTRL_RX_DMA_EN;
  338. }
  339. }
  340. /**
  341. * @brief Get the flag of interrupt status register.
  342. * @param FLAG flag of related interrupt register.
  343. */
  344. uint16_t QSPI_GetITStatus(uint16_t FLAG)
  345. {
  346. uint16_t tmp = 0;
  347. tmp = QSPI->ISTS & FLAG;
  348. if (tmp)
  349. return 1;
  350. else
  351. return 0;
  352. }
  353. /**
  354. * @brief Clear the flag of related interrupt register.
  355. * @param FLAG flag of related interrupt register.
  356. */
  357. void QSPI_ClearITFLAG(uint16_t FLAG)
  358. {
  359. if (FLAG == QSPI_ISTS_TXFOIS)
  360. (void)QSPI->TXFOI_CLR;
  361. else if (FLAG == QSPI_ISTS_RXFOIS)
  362. (void)QSPI->RXFOI_CLR;
  363. else if (FLAG == QSPI_ISTS_RXFUIS)
  364. (void)QSPI->RXFUI_CLR;
  365. else if (FLAG == QSPI_ISTS_MMCIS)
  366. (void)QSPI->MMC_CLR;
  367. else if (FLAG == QSPI_ISTS)
  368. (void)QSPI->ICLR;
  369. else
  370. {
  371. }
  372. }
  373. /**
  374. * @brief Clear the flag of related interrupt register.
  375. * @param FLAG flag of XRXFOIC interrupt register.
  376. */
  377. void QSPI_XIP_ClearITFLAG(uint16_t FLAG)
  378. {
  379. if (FLAG == QSPI_XIP_RXFOI_CLR_XRXFOIC)
  380. (void)QSPI->XIP_RXFOI_CLR;
  381. else
  382. {
  383. }
  384. }
  385. /**
  386. * @brief Get QSPI status,busy or not.
  387. * @return 1:QSPI busy;0:QSPI idle.
  388. */
  389. bool GetQspiBusyStatus(void)
  390. {
  391. if ((QSPI->STS & 0x01) == 0x01)
  392. return 1;
  393. return 0;
  394. }
  395. /**
  396. * @brief Check transmit fifo full or not.
  397. * @return 1: Transmit fifo full;0: Transmit fifo not full.
  398. */
  399. bool GetQspiTxDataBusyStatus(void)
  400. {
  401. if ((QSPI->STS & 0x02) == 0x00)
  402. return 1;
  403. return 0;
  404. }
  405. /**
  406. * @brief Check transmit fifo empty or not.
  407. * @return 1: Transmit fifo empty;0: Transmit fifo not empty.
  408. */
  409. bool GetQspiTxDataEmptyStatus(void)
  410. {
  411. if ((QSPI->STS & 0x04) == 0x04)
  412. return 1;
  413. return 0;
  414. }
  415. /**
  416. * @brief Check receive fifo have data or not.
  417. * @return 1:Receive fifo have data;0:Receive fifo empty.
  418. */
  419. bool GetQspiRxHaveDataStatus(void)
  420. {
  421. if ((QSPI->STS & 0x08) == 0x08)
  422. return 1;
  423. return 0;
  424. }
  425. /**
  426. * @brief Check receive fifo full or not.
  427. * @return 1: Receive fifo full;0: Receive fifo not full.
  428. */
  429. bool GetQspiRxDataFullStatus(void)
  430. {
  431. if ((QSPI->STS & 0x10) == 0x10)
  432. return 1;
  433. return 0;
  434. }
  435. /**
  436. * @brief Check data conflict error or not.
  437. * @return 1: Data conflict error;0: No data conflict error.
  438. */
  439. bool GetQspiDataConflictErrorStatus(void)
  440. {
  441. if ((QSPI->STS & 0x40) == 0x40)
  442. return 1;
  443. return 0;
  444. }
  445. /**
  446. * @brief Write one data direct to QSPI DAT0 register to send.
  447. * @param SendData: data to be send.
  448. */
  449. void QspiSendWord(uint32_t SendData)
  450. {
  451. QSPI->DAT0 = SendData;
  452. }
  453. /**
  454. * @brief Read one data from QSPI DAT0 register.
  455. * @return the value of QSPI DAT0 register.
  456. */
  457. uint32_t QspiReadWord(void)
  458. {
  459. return QSPI->DAT0;
  460. }
  461. /**
  462. * @brief Get Pointer of QSPI DAT0 register.
  463. * @return the pointer of QSPI DAT0 register.
  464. */
  465. uint32_t QspiGetDataPointer(void)
  466. {
  467. return (uint32_t)&QSPI->DAT0;
  468. }
  469. /**
  470. * @brief Read value from QSPI RXFN register which shows the number of the data from receive fifo.
  471. * @return the number of the data from receive fifo.
  472. */
  473. uint32_t QspiReadRxFifoNum(void)
  474. {
  475. return QSPI->RXFN;
  476. }
  477. /**
  478. * @brief Read DAT0 register to clear fifo.
  479. */
  480. void ClrFifo(void)
  481. {
  482. uint32_t timeout = 0;
  483. while (GetQspiRxHaveDataStatus())
  484. {
  485. QspiReadWord();
  486. if(++timeout >= 200)
  487. {
  488. break;
  489. }
  490. }
  491. }
  492. /**
  493. * @brief Get data from fifo.
  494. * @param pData pointer to buffer of getting fifo data.
  495. * @param Len length of getting fifo data.
  496. */
  497. uint32_t GetFifoData(uint32_t* pData, uint32_t Len)
  498. {
  499. uint32_t cnt;
  500. for (cnt = 0; cnt < Len; cnt++)
  501. {
  502. if (GetQspiRxHaveDataStatus())
  503. {
  504. *pData++ = QspiReadWord();
  505. }
  506. else
  507. {
  508. return QSPI_NULL;
  509. }
  510. }
  511. return QSPI_SUCCESS;
  512. }
  513. /**
  514. * @brief Send words out from source data buffer and get returned datas into destination data buffer.
  515. * @param pSrcData pointer to buffer of sending datas.
  516. * @param pDstData pointer to buffer of getting returned datas.
  517. * @param cnt number of sending datas.
  518. */
  519. void QspiSendAndGetWords(uint32_t* pSrcData, uint32_t* pDstData, uint32_t cnt)
  520. {
  521. uint32_t num = 0;
  522. uint32_t timeout = 0;
  523. while (num < cnt)
  524. {
  525. QspiSendWord(*(pSrcData++));
  526. num++;
  527. }
  528. while (!GetQspiRxHaveDataStatus())
  529. {
  530. if(++timeout >= QSPI_TIME_OUT_CNT)
  531. {
  532. break;
  533. }
  534. }
  535. timeout = 0;
  536. while (QSPI->RXFN < cnt)
  537. {
  538. if(++timeout >= QSPI_TIME_OUT_CNT)
  539. {
  540. break;
  541. }
  542. }
  543. num = 0;
  544. while (num < cnt)
  545. {
  546. *(pDstData++) = QspiReadWord();
  547. num++;
  548. }
  549. }
  550. /**
  551. * @brief Send one word data and get returned words into destination data buffer.
  552. * @param WrData one word to be sent.
  553. * @param pRdData pointer to buffer of getting returned datas.
  554. * @param LastRd whether go on to get returned datas.
  555. 1:go on to get returned datas.
  556. 0:end to get returned datas.
  557. */
  558. uint32_t QspiSendWordAndGetWords(uint32_t WrData, uint32_t* pRdData, uint8_t LastRd)
  559. {
  560. uint32_t timeout1 = 0;
  561. QspiSendWord(WrData); //trammit
  562. *pRdData = QspiReadWord();
  563. if(LastRd != 0)
  564. {
  565. while(!GetQspiRxHaveDataStatus()) //wait for data
  566. {
  567. if(++timeout1 >= QSPI_TIME_OUT_CNT)
  568. {
  569. return QSPI_NULL; //time out
  570. }
  571. }
  572. *pRdData = QspiReadWord(); //read data
  573. return QSPI_SUCCESS;
  574. }
  575. return QSPI_NULL;
  576. }