hv_drv_Spi.c 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398
  1. /**
  2. * @file hv_drv_Spi.c
  3. * @brief SPI drviver layer file.
  4. *
  5. * @author HiView SoC Software Team
  6. * @version 1.0.0
  7. * @date 2023-06-19
  8. * @copyright Copyright(c),2023-6, Hiview Software. All rights reserved.
  9. * </table>
  10. */
  11. #include "hv_vos_Comm.h"
  12. #include "hv_comm_Assert.h"
  13. #include "hv_chip_Config.h"
  14. #include "hv_comm_Define.h"
  15. #include "hv_drv_Spi.h"
  16. struct _SpiSelf
  17. {
  18. SpiInitParam stInitParam; /* SPI communication parameters */
  19. UINT32 uiBaseOffset; /* SPI addr offset*/
  20. UCHAR8 *pucCmdAddr; /*!< Pointer to spi command and address buffer.*/
  21. USHORT16 usCmdAddrSize; /*!< Spi command and address size. */
  22. UCHAR8 *pucTxBuff; /* Pointer to SPI Tx transfer Buffer */
  23. USHORT16 usTxXferSize; /* SPI Tx transfer size */
  24. USHORT16 usTxXferCount; /* SPI Tx transfer counter */
  25. UCHAR8 *pucRxBuff; /* Pointer to SPI Rx transfer Buffer */
  26. USHORT16 usRxXferSize; /* SPI Rx transfer size */
  27. USHORT16 usRxXferCount; /* SPI Rx transfer counter */
  28. USHORT16 usDumSize; /*!< The Dummy size of receive. */
  29. SpiState enState; /* SPI communication state */
  30. SpiError enErrorCode; /* SPI Error code */
  31. SpiTransState enTransCompleteFlag; /* SPI Transmit Complete flag */
  32. DmaSelf *pstDmaTx; /* SPI Send Dma */
  33. DmaSelf *pstDmaRx; /* SPI Receive Dma */
  34. };
  35. static SpiSelf s_Spi = {0};
  36. static VOID Hv_Spi_ModeSelect(const SpiSelf* pstSelf)
  37. {
  38. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  39. {
  40. HV_W32_FIELD_EX(CPU_SYS_SPI0_MODE_CTL0, pstSelf->uiBaseOffset, reg_ssi_master, 1);
  41. }
  42. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  43. {
  44. HV_W32_FIELD_EX(CPU_SYS_SPI0_MODE_CTL0, pstSelf->uiBaseOffset, reg_ssi_master, 0);
  45. }
  46. }
  47. static UCHAR8 Hv_Spi_GetFlag(const SpiSelf *pstSelf, SpiFlag enFlag)
  48. {
  49. UINT32 val = 0;
  50. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  51. {
  52. val = HV_R32(CPU_SYS_SPI0_M_SR + pstSelf->uiBaseOffset);
  53. }
  54. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  55. {
  56. val = HV_R32(CPU_SYS_SPI0_S_SR + pstSelf->uiBaseOffset);
  57. }
  58. return (((val & enFlag) == enFlag) ? 1 : 0);
  59. }
  60. static Status Hv_Spi_WaitOnFlagUntilTimeout(SpiSelf *pstSelf, SpiFlag enflag, UINT32 uiStatus, UINT32 uiTimeout)
  61. {
  62. UINT64 ullTickstart = 0;
  63. ullTickstart = Hv_Vos_GetTick();
  64. if (uiStatus == HV_SET)
  65. {
  66. while (Hv_Spi_GetFlag(pstSelf, enflag) == 0)/* Wait the flag set*/
  67. {
  68. if ((uiTimeout == 0) || ((Hv_Vos_GetTick() - ullTickstart ) > uiTimeout))
  69. {
  70. pstSelf->enErrorCode = SPI_ERROR_TIMEOUT;
  71. pstSelf->enState = SPI_STATE_READY;
  72. return HV_TIMEOUT;
  73. }
  74. }
  75. }
  76. else
  77. {
  78. while (Hv_Spi_GetFlag(pstSelf, enflag) == 1)/* Wait the flag reset*/
  79. {
  80. if ((uiTimeout == 0) || ((Hv_Vos_GetTick() - ullTickstart ) > uiTimeout))
  81. {
  82. pstSelf->enErrorCode = SPI_ERROR_TIMEOUT;
  83. pstSelf->enState = SPI_STATE_READY;
  84. return HV_TIMEOUT;
  85. }
  86. }
  87. }
  88. return HV_SUCCESS;
  89. }
  90. static VOID Hv_Spi_Enable(const SpiSelf* pstSelf)
  91. {
  92. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  93. {
  94. HV_W32_FIELD_EX(CPU_SYS_SPI0_M_SSIENR, pstSelf->uiBaseOffset, SSI_EN, 1);
  95. }
  96. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  97. {
  98. HV_W32_FIELD_EX(CPU_SYS_SPI0_S_SSIENR, pstSelf->uiBaseOffset, SSI_EN, 1);
  99. }
  100. }
  101. static VOID Hv_Spi_Disable(const SpiSelf *pstSelf)
  102. {
  103. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  104. {
  105. HV_W32_FIELD_EX(CPU_SYS_SPI0_M_SSIENR, pstSelf->uiBaseOffset, SSI_EN, 0); /* Enable spi0 master */
  106. }
  107. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  108. {
  109. HV_W32_FIELD_EX(CPU_SYS_SPI0_S_SSIENR, pstSelf->uiBaseOffset, SSI_EN, 0); /* Enable spi0 slave */
  110. }
  111. return;
  112. }
  113. static VOID Hv_Spi_MaskInt(const SpiSelf *pstSelf)
  114. {
  115. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  116. {
  117. HV_W32(CPU_SYS_SPI0_M_IMR + pstSelf->uiBaseOffset, 0x00);
  118. }
  119. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  120. {
  121. HV_W32(CPU_SYS_SPI0_S_IMR + pstSelf->uiBaseOffset, 0x00);
  122. }
  123. return;
  124. }
  125. static VOID Hv_Spi_InterruptEnable(const SpiSelf *pstSelf, UINT32 uiIntType)
  126. {
  127. UINT32 uiVal = 0;
  128. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  129. {
  130. uiVal = HV_R32(CPU_SYS_SPI0_M_IMR + pstSelf->uiBaseOffset);
  131. uiVal |= uiIntType;
  132. HV_W32(CPU_SYS_SPI0_M_IMR + pstSelf->uiBaseOffset, uiVal);
  133. } else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  134. {
  135. uiVal = HV_R32(CPU_SYS_SPI0_S_IMR + pstSelf->uiBaseOffset);
  136. uiVal |= uiIntType;
  137. HV_W32(CPU_SYS_SPI0_S_IMR + pstSelf->uiBaseOffset, uiVal);
  138. }
  139. else
  140. {
  141. //do nothing
  142. }
  143. }
  144. static VOID Hv_Spi_InterruptDisable(const SpiSelf *pstSelf, UINT32 uiIntType)
  145. {
  146. UINT32 uiVal = 0;
  147. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  148. {
  149. uiVal = HV_R32(CPU_SYS_SPI0_M_IMR + pstSelf->uiBaseOffset);
  150. uiVal &= ~uiIntType;
  151. HV_W32(CPU_SYS_SPI0_M_IMR + pstSelf->uiBaseOffset, uiVal);
  152. }
  153. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  154. {
  155. uiVal = HV_R32(CPU_SYS_SPI0_S_IMR + pstSelf->uiBaseOffset);
  156. uiVal &= ~uiIntType;
  157. HV_W32(CPU_SYS_SPI0_S_IMR + pstSelf->uiBaseOffset, uiVal);
  158. }
  159. else
  160. {
  161. //do nothing
  162. }
  163. }
  164. static UINT32 Hv_Spi_GetIntStateVal(const SpiSelf *pstSelf)
  165. {
  166. UINT32 uiVal = 0;
  167. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  168. {
  169. uiVal = HV_R32(CPU_SYS_SPI0_M_ISR + pstSelf->uiBaseOffset);
  170. }
  171. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  172. {
  173. uiVal = HV_R32(CPU_SYS_SPI0_S_ISR + pstSelf->uiBaseOffset);
  174. }
  175. return uiVal;
  176. }
  177. static UCHAR8 Hv_Spi_GetTxFifoLevel(const SpiSelf *pstSelf)
  178. {
  179. UCHAR8 uiVal = 0;
  180. HV_R32_DECL_VAR();
  181. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  182. {
  183. uiVal = HV_R32_FIELD_EX(CPU_SYS_SPI0_M_TXFLR, pstSelf->uiBaseOffset, TXTFL) & 0x1f;
  184. }
  185. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  186. {
  187. uiVal = HV_R32_FIELD_EX(CPU_SYS_SPI0_S_TXFLR, pstSelf->uiBaseOffset, TXTFL) & 0x1f;
  188. }
  189. return uiVal;
  190. }
  191. static UCHAR8 Hv_Spi_GetRxFifoLevel(const SpiSelf *pstSelf)
  192. {
  193. UCHAR8 uiVal = 0;
  194. HV_R32_DECL_VAR();
  195. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  196. {
  197. uiVal = HV_R32_FIELD_EX(CPU_SYS_SPI0_M_RXFLR, pstSelf->uiBaseOffset, RXTFL) & 0x1f;
  198. }
  199. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  200. {
  201. uiVal = HV_R32_FIELD_EX(CPU_SYS_SPI0_S_RXFLR, pstSelf->uiBaseOffset, RXTFL) & 0x1f;
  202. }
  203. return uiVal;
  204. }
  205. static VOID Hv_Spi_CsAlwaysLowSet(const SpiSelf *pstSelf)
  206. {
  207. UINT32 uiVal = 0;
  208. uiVal = HV_R32(CPU_SYS_SPI0_MODE_CTL0 + pstSelf->uiBaseOffset);
  209. cpu_sys_spi0_mode_ctl0(uiVal)->cs_oe_ctrl = 1;
  210. cpu_sys_spi0_mode_ctl0(uiVal)->reg_cs_oe = 1;
  211. cpu_sys_spi0_mode_ctl0(uiVal)->sck_oe_ctrl = 1;
  212. cpu_sys_spi0_mode_ctl0(uiVal)->reg_sck_oe = 1;
  213. cpu_sys_spi0_mode_ctl0(uiVal)->mosi_oe_ctrl = 1;
  214. cpu_sys_spi0_mode_ctl0(uiVal)->reg_mosi_oe = 1;
  215. HV_W32(CPU_SYS_SPI0_MODE_CTL0 + pstSelf->uiBaseOffset, uiVal);
  216. return;
  217. }
  218. static VOID Hv_Spi_CsAlwaysLowRelease(const SpiSelf *pstSelf)
  219. {
  220. UINT32 uiVal = 0;
  221. uiVal = HV_R32(CPU_SYS_SPI0_MODE_CTL0 + pstSelf->uiBaseOffset);
  222. cpu_sys_spi0_mode_ctl0(uiVal)->cs_oe_ctrl = 0;
  223. cpu_sys_spi0_mode_ctl0(uiVal)->reg_cs_oe = 0;
  224. cpu_sys_spi0_mode_ctl0(uiVal)->sck_oe_ctrl = 0;
  225. cpu_sys_spi0_mode_ctl0(uiVal)->reg_sck_oe = 0;
  226. cpu_sys_spi0_mode_ctl0(uiVal)->mosi_oe_ctrl = 0;
  227. cpu_sys_spi0_mode_ctl0(uiVal)->reg_mosi_oe = 0;
  228. HV_W32(CPU_SYS_SPI0_MODE_CTL0 + pstSelf->uiBaseOffset, uiVal);
  229. return;
  230. }
  231. static UCHAR8* Hv_Spi_TransmitOne(const SpiSelf *pstSelf, UINT32 uiCmdDataRegAddr, UCHAR8* pucData)
  232. {
  233. UCHAR8 ucToDR0Val = 0;
  234. UINT32 uiToDR0Val = 0;
  235. if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
  236. {
  237. ucToDR0Val = *pucData++;
  238. uiToDR0Val = (UINT32)ucToDR0Val;
  239. }
  240. else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32)
  241. {
  242. uiToDR0Val = CHANGE_TO_U32_BE(pucData);
  243. pucData = pucData + 4;
  244. }
  245. else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_16)
  246. {
  247. uiToDR0Val = CHANGE_TO_U16_BE(pucData);
  248. pucData = pucData + 2;
  249. }
  250. HV_W32(uiCmdDataRegAddr, uiToDR0Val);
  251. return pucData;
  252. }
  253. static UCHAR8* Hv_Spi_ReceiveOne(const SpiSelf *pstSelf, UINT32 uiCmdDataRegAddr, UCHAR8* pucData)
  254. {
  255. UINT32 uiFromDR0Val = HV_R32(uiCmdDataRegAddr);
  256. if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
  257. {
  258. *pucData++ = (UCHAR8)((uiFromDR0Val ) & 0xff);
  259. }
  260. else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32)
  261. {
  262. *((UINT32*)(pucData)) = HV_SWAP32(uiFromDR0Val);//CHANGE_ENDIAN_U32(uiFromDR0Val);
  263. pucData = pucData + 4;
  264. }
  265. else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_16)
  266. {
  267. *((USHORT16*)(pucData)) = CHANGE_ENDIAN_U16((uiFromDR0Val) & 0xffff);
  268. pucData = pucData + 2;
  269. }
  270. return pucData;
  271. }
  272. static Status Hv_Spi_IntTransmitCpltCallback(SpiSelf *pstSelf)
  273. {
  274. if (Hv_Spi_WaitOnFlagUntilTimeout(pstSelf, SPI_FLAG_TFE, HV_SET, HV_SPI_TIMEOUT) != HV_SUCCESS)
  275. {
  276. return HV_TIMEOUT;
  277. }
  278. if (pstSelf->stInitParam.enCsCtlMode != SPI_CSMODE_ALWAYS_LOW)
  279. {
  280. if (Hv_Spi_WaitOnFlagUntilTimeout(pstSelf, SPI_FLAG_BUSY, HV_RESET, HV_SPI_TIMEOUT) != HV_SUCCESS)
  281. {
  282. return HV_TIMEOUT;
  283. }
  284. }
  285. pstSelf->enState = SPI_STATE_READY;
  286. pstSelf->enTransCompleteFlag = SPI_TRANS_END;
  287. if (pstSelf->stInitParam.pfSpiCpltCallback != NULL)
  288. {
  289. pstSelf->stInitParam.pfSpiCpltCallback(SPI_TRANSMIT, (VOID*)pstSelf);
  290. }
  291. return HV_SUCCESS;
  292. }
  293. static Status Hv_Spi_IntReceiveCpltCallback(SpiSelf *pstSelf)
  294. {
  295. if ((pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  296. && (pstSelf->stInitParam.enCsCtlMode != SPI_CSMODE_ALWAYS_LOW))
  297. {
  298. if (Hv_Spi_WaitOnFlagUntilTimeout(pstSelf, SPI_FLAG_BUSY, HV_RESET, HV_SPI_TIMEOUT) != HV_SUCCESS)
  299. {
  300. return HV_TIMEOUT;
  301. }
  302. }
  303. pstSelf->enState = SPI_STATE_READY;
  304. pstSelf->enTransCompleteFlag = SPI_TRANS_END;
  305. if (pstSelf->stInitParam.pfSpiCpltCallback != NULL)
  306. {
  307. pstSelf->stInitParam.pfSpiCpltCallback(SPI_RECEIVE, (VOID*)pstSelf);
  308. }
  309. return HV_SUCCESS;
  310. }
  311. static Status Hv_Spi_IntTransmitHandler(SpiSelf *pstSelf)
  312. {
  313. UINT32 i = 0;
  314. UINT32 uiTxFifoSurplusLev = 0;
  315. UINT32 uiTxDataNumOnce = 0;
  316. UINT32 uiTxDataTotalNum = pstSelf->usCmdAddrSize + pstSelf->usTxXferSize;
  317. UCHAR8 *pucTxData = NULL;
  318. UINT32 uiCmdDataRegAddr = 0;
  319. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  320. {
  321. uiCmdDataRegAddr = CPU_SYS_SPI0_M_DR0 + pstSelf->uiBaseOffset;
  322. }
  323. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  324. {
  325. uiCmdDataRegAddr = CPU_SYS_SPI0_S_DR0 + pstSelf->uiBaseOffset;
  326. }
  327. if (pstSelf->enState == SPI_STATE_BUSY_TX)
  328. {
  329. if (pstSelf->usTxXferSize != 0)
  330. {
  331. if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
  332. {
  333. pucTxData = &pstSelf->pucTxBuff[pstSelf->usTxXferCount];
  334. }
  335. else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_16)
  336. {
  337. pucTxData = &pstSelf->pucTxBuff[2 * pstSelf->usTxXferCount];
  338. }
  339. else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32)
  340. {
  341. pucTxData = &pstSelf->pucTxBuff[4 * pstSelf->usTxXferCount];
  342. }
  343. else
  344. {
  345. //do nothing
  346. }
  347. }
  348. }
  349. uiTxFifoSurplusLev = HV_SPI_FIFO_DEPTH - Hv_Spi_GetTxFifoLevel(pstSelf);
  350. uiTxDataNumOnce = (uiTxDataTotalNum > uiTxFifoSurplusLev) ? uiTxFifoSurplusLev : uiTxDataTotalNum;
  351. for (i = 0; i < uiTxDataNumOnce; i++)
  352. {
  353. if (pstSelf->usCmdAddrSize == 0)
  354. {
  355. if (pstSelf->enState == SPI_STATE_BUSY_TX)
  356. {
  357. pucTxData = Hv_Spi_TransmitOne(pstSelf, uiCmdDataRegAddr, pucTxData);
  358. pstSelf->usTxXferCount++;
  359. }
  360. else if (pstSelf->enState == SPI_STATE_BUSY_RX)
  361. {
  362. UCHAR8 ucDummy[4] = {0};
  363. Hv_Spi_TransmitOne(pstSelf, uiCmdDataRegAddr, ucDummy);
  364. }
  365. pstSelf->usTxXferSize--;
  366. uiCmdDataRegAddr = uiCmdDataRegAddr + 4;
  367. }
  368. else
  369. {
  370. pstSelf->pucCmdAddr = Hv_Spi_TransmitOne(pstSelf, uiCmdDataRegAddr, pstSelf->pucCmdAddr);
  371. pstSelf->usCmdAddrSize--;
  372. uiCmdDataRegAddr = uiCmdDataRegAddr + 4;
  373. }
  374. }
  375. if ((pstSelf->usCmdAddrSize + pstSelf->usTxXferSize) == 0)
  376. {
  377. UINT32 uiIntFlag = 0;
  378. uiIntFlag = SPI_INTERRUPT_TXEIR | SPI_INTERRUPT_TXOIR;
  379. Hv_Spi_InterruptDisable(pstSelf, uiIntFlag);
  380. if (pstSelf->enState == SPI_STATE_BUSY_TX)
  381. {
  382. Hv_Spi_IntTransmitCpltCallback(pstSelf);
  383. }
  384. }
  385. return HV_SUCCESS;
  386. }
  387. static Status Hv_Spi_IntReceiveHandler(SpiSelf *pstSelf)
  388. {
  389. UINT32 i = 0;
  390. UINT32 uiRxFifoDataLev = 0;
  391. UCHAR8 *pucRxData = NULL;
  392. UCHAR8 ucDumSize[4] = {0};
  393. UINT32 uiCmdDataRegAddrBase = 0;
  394. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  395. {
  396. uiCmdDataRegAddrBase = CPU_SYS_SPI0_M_DR0 + pstSelf->uiBaseOffset;
  397. }
  398. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  399. {
  400. uiCmdDataRegAddrBase = CPU_SYS_SPI0_S_DR0 + pstSelf->uiBaseOffset;
  401. }
  402. if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
  403. {
  404. pucRxData = &pstSelf->pucRxBuff[pstSelf->usRxXferCount];
  405. }
  406. else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_16)
  407. {
  408. pucRxData = &pstSelf->pucRxBuff[2 * pstSelf->usRxXferCount];
  409. }
  410. else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32)
  411. {
  412. pucRxData = &pstSelf->pucRxBuff[4 * pstSelf->usRxXferCount];
  413. }
  414. uiRxFifoDataLev = Hv_Spi_GetRxFifoLevel(pstSelf);
  415. for (i = 0; i < uiRxFifoDataLev; i++)
  416. {
  417. if (pstSelf->usDumSize != 0)
  418. {
  419. Hv_Spi_ReceiveOne(pstSelf,uiCmdDataRegAddrBase, ucDumSize);
  420. pstSelf->usDumSize--;
  421. }
  422. else
  423. {
  424. pucRxData = Hv_Spi_ReceiveOne(pstSelf, uiCmdDataRegAddrBase, pucRxData);
  425. pstSelf->usRxXferCount++;
  426. }
  427. pstSelf->usRxXferSize--;
  428. }
  429. if (pstSelf->usRxXferSize == 0)
  430. {
  431. UINT32 uiIntFlag = 0;
  432. uiIntFlag = SPI_INTERRUPT_RXFIR|SPI_INTERRUPT_RXUIR|SPI_INTERRUPT_RXOIR;
  433. Hv_Spi_InterruptDisable(pstSelf, uiIntFlag);
  434. Hv_Spi_IntReceiveCpltCallback(pstSelf);
  435. }
  436. return HV_SUCCESS;
  437. }
  438. HV_VOS_ISR_RESULT_E Hv_Spi_IrqHandler(UINT32 uiIrqNum, VOID *pArg)
  439. {
  440. UINT32 uiIntStaVal = 0;
  441. SpiSelf *pstSelf;
  442. HV_UNUSED(uiIrqNum);
  443. pstSelf = (SpiSelf *)pArg;
  444. uiIntStaVal = Hv_Spi_GetIntStateVal(pstSelf);
  445. if (uiIntStaVal & SPI_INTERRUPT_TXEIR)
  446. {
  447. // HV_LOGI("Now enter tx int.\n");
  448. Hv_Spi_IntTransmitHandler(pstSelf);
  449. }
  450. if (uiIntStaVal & SPI_INTERRUPT_RXFIR)
  451. {
  452. //HV_LOGI("Now enter rx int.\n");
  453. Hv_Spi_IntReceiveHandler(pstSelf);
  454. }
  455. if (uiIntStaVal & SPI_INTERRUPT_TXOIR)
  456. {
  457. }
  458. if (uiIntStaVal & SPI_INTERRUPT_RXUIR)
  459. {
  460. }
  461. if (uiIntStaVal & SPI_INTERRUPT_RXOIR)
  462. {
  463. }
  464. if (uiIntStaVal & SPI_INTERRUPT_MSTIR)
  465. {
  466. }
  467. return HV_VOS_ISR_HANDLED;
  468. }
  469. static VOID Hv_Spi_ConfigDmaTxReg(SpiSelf *pstSelf, UINT32 uiEnFlag, UINT32 uiSpiTxDmaThres)
  470. {
  471. Hv_Spi_Disable(pstSelf);
  472. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  473. {
  474. HV_W32_FIELD_EX(CPU_SYS_SPI0_M_DMACR, pstSelf->uiBaseOffset, TDMAE, uiEnFlag);
  475. HV_W32_FIELD_EX(CPU_SYS_SPI0_M_DMATDLR, pstSelf->uiBaseOffset, DMATDL, uiSpiTxDmaThres);
  476. }
  477. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  478. {
  479. HV_W32_FIELD_EX(CPU_SYS_SPI0_S_DMACR, pstSelf->uiBaseOffset, TDMAE, uiEnFlag);
  480. HV_W32_FIELD_EX(CPU_SYS_SPI0_S_DMATDLR, pstSelf->uiBaseOffset, DMATDL, uiSpiTxDmaThres);
  481. }
  482. }
  483. static VOID Hv_Spi_ConfigDmaRxReg(SpiSelf *pstSelf, UINT32 uiEnFlag, UINT32 uiSpiRxDmaThres)
  484. {
  485. Hv_Spi_Disable(pstSelf);
  486. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  487. {
  488. HV_W32_FIELD_EX(CPU_SYS_SPI0_M_DMACR, pstSelf->uiBaseOffset, RDMAE, uiEnFlag);
  489. HV_W32_FIELD_EX(CPU_SYS_SPI0_M_DMARDLR, pstSelf->uiBaseOffset, DMARDL, uiSpiRxDmaThres);
  490. }
  491. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  492. {
  493. HV_W32_FIELD_EX(CPU_SYS_SPI0_S_DMACR, pstSelf->uiBaseOffset, RDMAE, uiEnFlag);
  494. HV_W32_FIELD_EX(CPU_SYS_SPI0_S_DMARDLR, pstSelf->uiBaseOffset, DMARDL, uiSpiRxDmaThres);
  495. }
  496. }
  497. static Status Hv_Spi_DmaTransmitCpltCallback(DmaSelf* pstArg)
  498. {
  499. SpiSelf* pstSelf = (SpiSelf *)Hv_Cal_Dma_GetParent(pstArg);
  500. Hv_Cal_Dma_XferCallbackUnBond(pstSelf->pstDmaTx);
  501. if (pstSelf->enState == SPI_STATE_BUSY_TX)
  502. {
  503. if (Hv_Spi_WaitOnFlagUntilTimeout(pstSelf, SPI_FLAG_TFE, HV_SET, HV_SPI_TIMEOUT) != HV_SUCCESS)
  504. {
  505. return HV_TIMEOUT;
  506. }
  507. if (pstSelf->stInitParam.enCsCtlMode != SPI_CSMODE_ALWAYS_LOW)
  508. {
  509. if (Hv_Spi_WaitOnFlagUntilTimeout(pstSelf, SPI_FLAG_BUSY, HV_RESET, HV_SPI_TIMEOUT) != HV_SUCCESS)
  510. {
  511. return HV_TIMEOUT;
  512. }
  513. }
  514. Hv_Spi_Disable(pstSelf);
  515. Hv_Spi_ConfigDmaTxReg(pstSelf, SPI_DMATX_DISABLE, HV_SPI_DMA_TX_THRESHOLD);
  516. Hv_Vos_InvalidAllDCache();
  517. pstSelf->enState = SPI_STATE_READY;
  518. pstSelf->enTransCompleteFlag = SPI_TRANS_END;
  519. if (pstSelf->stInitParam.pfSpiCpltCallback != NULL)
  520. {
  521. pstSelf->stInitParam.pfSpiCpltCallback(SPI_TRANSMIT, (VOID*)pstSelf);
  522. }
  523. }
  524. return HV_SUCCESS;
  525. }
  526. static Status Hv_Spi_DmaReceiveCpltCallback(DmaSelf* pArg)
  527. {
  528. SpiSelf* pstSelf = (SpiSelf *)Hv_Cal_Dma_GetParent(pArg);
  529. if ((pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  530. && (pstSelf->stInitParam.enCsCtlMode != SPI_CSMODE_ALWAYS_LOW))
  531. {
  532. if (Hv_Spi_WaitOnFlagUntilTimeout(pstSelf, SPI_FLAG_BUSY, HV_RESET, 1000) != HV_SUCCESS)
  533. {
  534. return HV_TIMEOUT;
  535. }
  536. }
  537. Hv_Spi_Disable(pstSelf);
  538. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  539. {
  540. Hv_Spi_ConfigDmaTxReg(pstSelf, SPI_DMATX_DISABLE, HV_SPI_DMA_TX_THRESHOLD);
  541. }
  542. Hv_Spi_ConfigDmaRxReg(pstSelf, SPI_DMARX_DISABLE, HV_SPI_DMA_RX_THRESHOLD);
  543. Hv_Cal_Dma_XferCallbackUnBond(pstSelf->pstDmaRx);
  544. Hv_Vos_InvalidAllDCache();
  545. pstSelf->enState = SPI_STATE_READY;
  546. pstSelf->enTransCompleteFlag = SPI_TRANS_END;
  547. if (pstSelf->stInitParam.pfSpiCpltCallback != NULL)
  548. {
  549. pstSelf->stInitParam.pfSpiCpltCallback(SPI_RECEIVE, (VOID*)pstSelf);
  550. }
  551. return HV_SUCCESS;
  552. }
  553. /**@brief Get spi state
  554. * @param self pointer to spi structure
  555. * @retval spi state
  556. */
  557. UCHAR8 Hv_Drv_Spi_GetState(const SpiSelf* pstSelf)
  558. {
  559. return pstSelf->enState;
  560. }
  561. /**@brief Set spi transmit DMA
  562. * @param self pointer to spi structure.
  563. * @param transmit DMA structure
  564. * @retval none
  565. */
  566. VOID Hv_Drv_Spi_SetDmaTx(SpiSelf *pstSelf, DmaSelf *pstDmaTx)
  567. {
  568. pstSelf->pstDmaTx = pstDmaTx;
  569. Hv_Cal_Dma_SetParent(pstDmaTx, (VOID*)pstSelf);
  570. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  571. {
  572. Hv_Cal_Dma_SetDstAddr(pstDmaTx, CPU_SYS_SPI0_M_DR0 + pstSelf->uiBaseOffset);
  573. }
  574. else
  575. {
  576. Hv_Cal_Dma_SetDstAddr(pstDmaTx, CPU_SYS_SPI0_S_DR0 + pstSelf->uiBaseOffset);
  577. }
  578. if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
  579. {
  580. Hv_Cal_Dma_SetSrcFrameSize(pstDmaTx, DMA_DATA_SIZE_32Bits);
  581. Hv_Cal_Dma_SetDstFrameSize(pstDmaTx, DMA_DATA_SIZE_8Bits);
  582. }
  583. return;
  584. }
  585. /**@brief Set spi receive DMA
  586. * @param self pointer to spi structure.
  587. * @param receive DMA structure
  588. * @retval none
  589. */
  590. VOID Hv_Drv_Spi_SetDmaRx(SpiSelf *pstSelf, DmaSelf *pstDmaRx)
  591. {
  592. pstSelf->pstDmaRx = pstDmaRx;
  593. Hv_Cal_Dma_SetParent(pstDmaRx,(VOID*)pstSelf);
  594. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  595. {
  596. Hv_Cal_Dma_SetSrcAddr(pstDmaRx, CPU_SYS_SPI0_M_DR0 + pstSelf->uiBaseOffset);
  597. }
  598. else
  599. {
  600. Hv_Cal_Dma_SetSrcAddr(pstDmaRx, CPU_SYS_SPI0_S_DR0 + pstSelf->uiBaseOffset);
  601. }
  602. if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
  603. {
  604. Hv_Cal_Dma_SetSrcFrameSize(pstDmaRx, DMA_DATA_SIZE_8Bits);
  605. Hv_Cal_Dma_SetDstFrameSize(pstDmaRx, DMA_DATA_SIZE_32Bits);
  606. }
  607. return;
  608. }
  609. /**@brief Bond the complete callback
  610. * @param self pointer to spi structure.
  611. * @param CallbackFunc callback defined by user
  612. * @retval none
  613. */
  614. VOID Hv_Drv_Spi_SetCpltCallBack(SpiSelf *pstSelf, SpiCpltCallback pfCallbackFunc)
  615. {
  616. pstSelf->stInitParam.pfSpiCpltCallback = pfCallbackFunc;
  617. }
  618. /**@brief Set the spi direction
  619. * @param self pointer to spi structure.
  620. * @param enDirection
  621. * @retval none
  622. */
  623. VOID Hv_Drv_Spi_SetDirection(SpiSelf *pstSelf, SpiDirection enDirection)
  624. {
  625. Hv_Spi_Disable(pstSelf);
  626. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  627. {
  628. HV_W32_FIELD_EX(CPU_SYS_SPI0_M_CTRLR0, pstSelf->uiBaseOffset, TMOD, enDirection);
  629. }
  630. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  631. {
  632. HV_W32_FIELD_EX(CPU_SYS_SPI0_S_CTRLR0, pstSelf->uiBaseOffset, TMOD, enDirection);
  633. }
  634. pstSelf->stInitParam.enDirection = enDirection;
  635. return;
  636. }
  637. /**@brief Set spi data frame size
  638. * @param self pointer to spi structure.
  639. * @param enFrameWidth Indicates how many bits of data are serially transmitted in a frame.
  640. * @retval none
  641. */
  642. VOID Hv_Drv_Spi_SetBitsWidth(SpiSelf *pstSelf, SpiBandWidth enFrameWidth)
  643. {
  644. Hv_Spi_Disable(pstSelf);
  645. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  646. {
  647. HV_W32_FIELD_EX(CPU_SYS_SPI0_M_CTRLR0, pstSelf->uiBaseOffset, DFS_32, (UINT32)enFrameWidth);
  648. }
  649. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  650. {
  651. HV_W32_FIELD_EX(CPU_SYS_SPI0_S_CTRLR0, pstSelf->uiBaseOffset, DFS_32, (UINT32)enFrameWidth);
  652. }
  653. pstSelf->stInitParam.enDataSize = enFrameWidth;
  654. return;
  655. }
  656. /**@brief Set spi the baudrate
  657. * @param self pointer to spi structure.
  658. * @param BaudRate baudrate which will set as SCKDV.
  659. * @retval none
  660. */
  661. VOID Hv_Drv_Spi_SetBaudRate(SpiSelf *pstSelf, SPiDivRatio enDivRatio)
  662. {
  663. Hv_Spi_Disable(pstSelf);
  664. HV_W32_FIELD_EX(CPU_SYS_SPI0_M_BAUDR, pstSelf->uiBaseOffset, SCKDV, (UINT32)enDivRatio);
  665. pstSelf->stInitParam.enBaudRatePrescaler = enDivRatio;
  666. return;
  667. }
  668. /**@brief Initializes the SPI according to the specified parameters and create the associated handle.
  669. * @param initParam pointer to the configuration information for SPI module.
  670. * @return spi handler
  671. */
  672. SpiSelf* Hv_Drv_Spi_Init(SpiInitParam *pstInitParam)
  673. {
  674. SpiSelf *pstSelf = NULL;
  675. HV_ASSERT_VALID_PTR_RET(pstInitParam, NULL);
  676. HV_ASSERT_TRUE_RET((pstInitParam->enCsCtlMode < SPI_CSMODE_MAX), NULL);
  677. pstSelf = &s_Spi;
  678. HV_MEMCPY(&pstSelf->stInitParam, pstInitParam, sizeof(*pstInitParam));
  679. pstSelf->uiBaseOffset = 0;
  680. Hv_Spi_ModeSelect(pstSelf);
  681. Hv_Spi_Disable(pstSelf);
  682. Hv_Spi_MaskInt(pstSelf);
  683. if (pstInitParam->enMode == SPI_MODE_MASTER)
  684. {
  685. rs_cpu_sys_spi0_m_ctrlr0 regCtrl0Val = {0}; /* Config spi0 master ctrl0 reg*/
  686. regCtrl0Val.FRF = 0;
  687. regCtrl0Val.SCPH = pstInitParam->enClkPhase;
  688. regCtrl0Val.SCPOL = pstInitParam->enClkPolarity;
  689. regCtrl0Val.TMOD = pstInitParam->enDirection;
  690. regCtrl0Val.SRL = 0;
  691. regCtrl0Val.DFS_32 = pstInitParam->enDataSize;
  692. regCtrl0Val.SPI_FRF = 0;
  693. regCtrl0Val.SSTE = 0;/* No toggle*/
  694. HV_W32_REG(CPU_SYS_SPI0_M_CTRLR0 + pstSelf->uiBaseOffset, regCtrl0Val);
  695. HV_W32(CPU_SYS_SPI0_M_BAUDR + pstSelf->uiBaseOffset, pstInitParam->enBaudRatePrescaler);
  696. HV_W32_FIELD_EX(CPU_SYS_SPI0_M_TXFTLR, pstSelf->uiBaseOffset, TFT, 8);
  697. HV_W32_FIELD_EX(CPU_SYS_SPI0_M_RXFTLR, pstSelf->uiBaseOffset, RFT, 0);
  698. HV_W32(CPU_SYS_SPI0_M_CTRLR1 + pstSelf->uiBaseOffset, 0x03);
  699. HV_W32_FIELD_EX(CPU_SYS_SPI0_M_SER, pstSelf->uiBaseOffset, SER, 1);
  700. }
  701. else if (pstInitParam->enMode == SPI_MODE_SLAVE)
  702. {
  703. rs_cpu_sys_spi0_s_ctrlr0 regCtrl0Val = {0};/* Config spi0 slave ctrl0 reg*/
  704. regCtrl0Val.FRF = 0;
  705. regCtrl0Val.SCPH = pstInitParam->enClkPhase; /* if need to config */
  706. regCtrl0Val.SCPOL = pstInitParam->enClkPolarity;
  707. regCtrl0Val.TMOD = pstInitParam->enDirection;
  708. regCtrl0Val.SLV_OE = 0;
  709. regCtrl0Val.SRL = 0;
  710. regCtrl0Val.DFS_32 = pstInitParam->enDataSize;
  711. regCtrl0Val.SPI_FRF = 0;
  712. regCtrl0Val.SSTE = 0;
  713. HV_W32_REG(CPU_SYS_SPI0_S_CTRLR0 + pstSelf->uiBaseOffset, regCtrl0Val);
  714. HV_W32_FIELD_EX(CPU_SYS_SPI0_S_TXFTLR, pstSelf->uiBaseOffset, TFT, 8);
  715. HV_W32_FIELD_EX(CPU_SYS_SPI0_S_RXFTLR, pstSelf->uiBaseOffset, RFT, 0);
  716. }
  717. HV_W32_FIELD_EX(CPU_SYS_SPI0_M_RX_SAMPLE_DLY, pstSelf->uiBaseOffset, RSD, 1);
  718. Hv_Vos_ConfigIrq(HV_CHIP_IRQ_SPI0, HV_TRUE, 0);
  719. Hv_Vos_AttachIsr(HV_CHIP_IRQ_SPI0, Hv_Spi_IrqHandler, pstSelf);
  720. Hv_Vos_UnmaskIrq(HV_CHIP_IRQ_SPI0);
  721. if (pstSelf->stInitParam.enCsCtlMode == SPI_CSMODE_ALWAYS_LOW)
  722. {
  723. Hv_Spi_CsAlwaysLowSet(pstSelf);
  724. }
  725. pstSelf->enState = SPI_STATE_READY;
  726. pstSelf->enErrorCode = SPI_ERROR_NONE;
  727. return pstSelf;
  728. }
  729. /**@brief De-initializes the SPI.
  730. * @param self pointer to spi structure.
  731. * @retval result
  732. */
  733. Status Hv_Drv_Spi_Cleanup(SpiSelf *pstSelf)
  734. {
  735. Hv_Vos_MaskIrq(HV_CHIP_IRQ_SPI0);
  736. Hv_Vos_DetachIsr(HV_CHIP_IRQ_SPI0, Hv_Spi_IrqHandler);
  737. if (pstSelf->stInitParam.enCsCtlMode == SPI_CSMODE_ALWAYS_LOW)
  738. {
  739. Hv_Spi_CsAlwaysLowRelease(pstSelf);
  740. }
  741. Hv_Spi_Disable(pstSelf);
  742. pstSelf->enErrorCode = SPI_ERROR_NONE;
  743. pstSelf->enState = SPI_STATE_RESET;
  744. return HV_SUCCESS;
  745. }
  746. /**@brief Transmit an amount of data in blocking mode
  747. * @param self pointer to spi structure
  748. * @param pucCmdAddr pointer to command buffer
  749. * @param pucTxData pointer to data buffer
  750. * @param usDataSize amount of data to be sent
  751. * @param uiTimeout Timeout duration
  752. * @retval result
  753. */
  754. Status Hv_Drv_Spi_PollingTransmit(SpiSelf *pstSelf, UCHAR8 *pucCmdAddr, USHORT16 usCmdAddrSize,
  755. UCHAR8 *pucTxData, USHORT16 usDataSize, UINT32 uiTimeout)
  756. {
  757. UINT32 i = 0;
  758. UINT32 uiTxFifoSurplusLev = 0;
  759. UINT32 uiTxDataNumOnce = 0;
  760. USHORT16 usCmdAddrSizeTemp = 0;
  761. USHORT16 usDataSizeTemp = 0;
  762. USHORT16 usTxTotalSize = 0;
  763. UINT32 uiCmdDataRegAddrBase = 0;
  764. UINT32 uiCmdDataRegAddr = 0;
  765. HV_UNUSED(uiTimeout);
  766. if (pstSelf->enState == SPI_STATE_READY)
  767. {
  768. if (((pucCmdAddr == NULL ) && (pucTxData == NULL))
  769. || ((usCmdAddrSize == 0) && (usDataSize == 0)))
  770. {
  771. return HV_FAILURE;
  772. }
  773. if ((pstSelf->stInitParam.enDirection != SPI_DIRECTION_TXRX)
  774. && (pstSelf->stInitParam.enDirection != SPI_DIRECTION_TX))
  775. {
  776. return HV_FAILURE;
  777. }
  778. if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
  779. {
  780. usCmdAddrSizeTemp = usCmdAddrSize;
  781. usDataSizeTemp = usDataSize;
  782. }
  783. else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_16)
  784. {
  785. usCmdAddrSizeTemp = usCmdAddrSize / 2;
  786. usDataSizeTemp = usDataSize / 2;
  787. }
  788. else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32)
  789. {
  790. usCmdAddrSizeTemp = usCmdAddrSize / 4;
  791. usDataSizeTemp = usDataSize / 4;
  792. }
  793. if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  794. {
  795. HV_ASSERT(pucCmdAddr == NULL);
  796. HV_ASSERT(usCmdAddrSizeTemp == 0);
  797. }
  798. usTxTotalSize = usCmdAddrSizeTemp + usDataSizeTemp;
  799. pstSelf->enState = SPI_STATE_BUSY_TX;
  800. pstSelf->enErrorCode = SPI_ERROR_NONE;
  801. Hv_Spi_Enable(pstSelf);
  802. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  803. {
  804. uiCmdDataRegAddrBase = CPU_SYS_SPI0_M_DR0 + pstSelf->uiBaseOffset;
  805. uiCmdDataRegAddr = uiCmdDataRegAddrBase;
  806. }
  807. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)/*Preventing from TXE Erro*/
  808. {
  809. uiCmdDataRegAddrBase = CPU_SYS_SPI0_S_DR0 + pstSelf->uiBaseOffset;
  810. uiCmdDataRegAddr = uiCmdDataRegAddrBase;
  811. pucTxData = Hv_Spi_TransmitOne(pstSelf, uiCmdDataRegAddr, pucTxData);
  812. uiCmdDataRegAddr = uiCmdDataRegAddr + 4;
  813. pstSelf->usTxXferSize--;
  814. }
  815. while (usTxTotalSize > 0)
  816. {
  817. uiTxFifoSurplusLev = HV_SPI_FIFO_DEPTH - Hv_Spi_GetTxFifoLevel(pstSelf);
  818. uiTxDataNumOnce = (usTxTotalSize > uiTxFifoSurplusLev) ? uiTxFifoSurplusLev : usTxTotalSize;
  819. for (i = 0; i < uiTxDataNumOnce; i++)
  820. {
  821. if (usCmdAddrSizeTemp == 0)
  822. {
  823. pucTxData = Hv_Spi_TransmitOne(pstSelf, uiCmdDataRegAddr, pucTxData);
  824. }
  825. else
  826. {
  827. pucCmdAddr = Hv_Spi_TransmitOne(pstSelf, uiCmdDataRegAddr, pucCmdAddr);
  828. usCmdAddrSizeTemp--;
  829. }
  830. uiCmdDataRegAddr = uiCmdDataRegAddr + 4;
  831. if ((uiCmdDataRegAddr - uiCmdDataRegAddrBase) == HV_SPI_DR_ADDR_RANGE_TOTAL)
  832. {
  833. uiCmdDataRegAddr = uiCmdDataRegAddrBase;
  834. }
  835. usTxTotalSize--;
  836. }
  837. }
  838. if (Hv_Spi_WaitOnFlagUntilTimeout(pstSelf, SPI_FLAG_TFE, HV_SET, HV_SPI_TIMEOUT) != HV_SUCCESS)
  839. {
  840. return HV_TIMEOUT;
  841. }
  842. if (pstSelf->stInitParam.enCsCtlMode != SPI_CSMODE_ALWAYS_LOW)
  843. {
  844. if (Hv_Spi_WaitOnFlagUntilTimeout(pstSelf, SPI_FLAG_BUSY, HV_RESET, HV_SPI_TIMEOUT) != HV_SUCCESS)
  845. {
  846. return HV_TIMEOUT;
  847. }
  848. }
  849. pstSelf->enState = SPI_STATE_READY;
  850. Hv_Spi_Disable(pstSelf);
  851. return HV_SUCCESS;
  852. }
  853. else
  854. {
  855. return HV_BUSY;
  856. }
  857. }
  858. /**@brief Transmit an amount of data in no-blocking mode with interrupt
  859. * @param self pointer to spi structure
  860. * @param pucCmdAddr pointer to command buffer
  861. * @param pucTxData pointer to data buffer
  862. * @param usDataSize amount of data to be sent
  863. * @retval result
  864. */
  865. Status Hv_Drv_Spi_IntTransmit(SpiSelf *pstSelf, UCHAR8 *pucCmdAddr, USHORT16 usCmdAddrSize, UCHAR8 *pucTxData, USHORT16 usDataSize)
  866. {
  867. UINT32 uiIntFlag = 0;
  868. USHORT16 usCmdAddrSizeTemp = 0;
  869. USHORT16 usDataSizeTemp = 0;
  870. if (pstSelf->enState == SPI_STATE_READY)
  871. {
  872. if (((pucCmdAddr == NULL ) && (pucTxData == NULL))
  873. || ((usCmdAddrSize == 0) && (usDataSize == 0)))
  874. {
  875. return HV_FAILURE;
  876. }
  877. if ((pstSelf->stInitParam.enDirection != SPI_DIRECTION_TXRX)
  878. && (pstSelf->stInitParam.enDirection != SPI_DIRECTION_TX))
  879. {
  880. return HV_FAILURE;
  881. }
  882. if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
  883. {
  884. usCmdAddrSizeTemp = usCmdAddrSize;
  885. usDataSizeTemp = usDataSize;
  886. }
  887. else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_16)
  888. {
  889. usCmdAddrSizeTemp = usCmdAddrSize / 2;
  890. usDataSizeTemp = usDataSize / 2;
  891. }else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32)
  892. {
  893. usCmdAddrSizeTemp = usCmdAddrSize / 4;
  894. usDataSizeTemp = usDataSize / 4;
  895. }
  896. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  897. {
  898. pstSelf->pucCmdAddr = pucCmdAddr;
  899. pstSelf->usCmdAddrSize = usCmdAddrSizeTemp;
  900. }
  901. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  902. {
  903. HV_ASSERT(pucCmdAddr == NULL);
  904. HV_ASSERT(usCmdAddrSizeTemp == 0);
  905. }
  906. pstSelf->pucTxBuff = pucTxData;
  907. pstSelf->usTxXferSize = usDataSizeTemp;
  908. pstSelf->usTxXferCount = 0;
  909. pstSelf->enState = SPI_STATE_BUSY_TX;
  910. pstSelf->enErrorCode = SPI_ERROR_NONE;
  911. pstSelf->enTransCompleteFlag = SPI_TRANS_IN_PROCESS;
  912. uiIntFlag = SPI_INTERRUPT_TXEIR | SPI_INTERRUPT_TXOIR;
  913. Hv_Spi_InterruptEnable(pstSelf, uiIntFlag);
  914. Hv_Spi_Enable(pstSelf);
  915. return HV_SUCCESS;
  916. }
  917. else
  918. {
  919. return HV_BUSY;
  920. }
  921. }
  922. /**@brief Transmit an amount of data in no-blocking mode with DMA
  923. * @param self pointer to spi structure
  924. * @param pucData pointer to data buffer
  925. * @param usDataSize amount of data to be sent
  926. * @retval result
  927. */
  928. Status Hv_Drv_Spi_DmaTransmit(SpiSelf *pstSelf, UCHAR8* pucData, USHORT16 usDataSize)
  929. {
  930. USHORT16 usBlockSize = 0;
  931. if (pstSelf->enState == SPI_STATE_READY)
  932. {
  933. if ((pstSelf->stInitParam.enDirection != SPI_DIRECTION_TXRX)
  934. && (pstSelf->stInitParam.enDirection != SPI_DIRECTION_TX))
  935. {
  936. return HV_FAILURE;
  937. }
  938. if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
  939. {
  940. HV_ASSERT((usDataSize % 4) == 0);
  941. usBlockSize = usDataSize / 4;
  942. }else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32){
  943. HV_ASSERT((usDataSize % 4) == 0);
  944. usBlockSize = usDataSize / 4;
  945. }
  946. Hv_Spi_ConfigDmaTxReg(pstSelf, SPI_DMATX_ENABLE, HV_SPI_DMA_TX_THRESHOLD);
  947. Hv_Spi_Enable(pstSelf);
  948. Hv_Cal_Dma_XferCallbackBond(pstSelf->pstDmaTx, Hv_Spi_DmaTransmitCpltCallback);
  949. Hv_Cal_Dma_SetBlockSize(pstSelf->pstDmaTx, usBlockSize);
  950. Hv_Cal_Dma_SetSrcAddr(pstSelf->pstDmaTx, (UINT32)pucData);
  951. pstSelf->enState = SPI_STATE_BUSY_TX;
  952. pstSelf->enErrorCode = SPI_ERROR_NONE;
  953. pstSelf->enTransCompleteFlag = SPI_TRANS_IN_PROCESS;
  954. Hv_Cal_Dma_ChannelEn(pstSelf->pstDmaTx);
  955. return HV_SUCCESS;
  956. }
  957. else
  958. {
  959. return HV_BUSY;
  960. }
  961. }
  962. /**@brief Receive an amount of data in blocking mode
  963. * @param self pointer to spi structure
  964. * @param pucCmdAddr pointer to command buffer
  965. * @param pucRxData pointer to data buffer
  966. * @param usDataSize amount of data to be sent
  967. * @param uiTimeout Timeout duration
  968. * @retval result
  969. */
  970. Status Hv_Drv_Spi_PollingReceive(SpiSelf *pstSelf, UCHAR8 *pucCmdAddr, USHORT16 usCmdAddrSize,
  971. UCHAR8 *pucRxData, USHORT16 usDataSize, UINT32 uiTimeout)
  972. {
  973. UINT32 uiLoop = 0;
  974. UINT32 uiTxFifoSurplusLev = 0;
  975. UINT32 uiTxDataNumOnce = 0;
  976. UINT32 uiRxFifoDataLev = 0;
  977. UCHAR8 ucDummy[4] = {0};
  978. UINT32 uiDummySize = 0;
  979. UINT64 ullTickstart = Hv_Vos_GetTick();
  980. USHORT16 usCmdAddrSizeTemp = 0;
  981. USHORT16 usDataSizeTemp = 0;
  982. USHORT16 usTxTotalSize = 0;
  983. UINT32 uiCmdDataRegAddrBase = 0;
  984. UINT32 uiCmdDataRegAddr = 0;
  985. if (pstSelf->enState == SPI_STATE_READY)
  986. {
  987. if ((pstSelf->stInitParam.enDirection != SPI_DIRECTION_TXRX)
  988. && (pstSelf->stInitParam.enDirection != SPI_DIRECTION_RX))
  989. {
  990. return HV_FAILURE;
  991. }
  992. if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
  993. {
  994. usCmdAddrSizeTemp = usCmdAddrSize;
  995. usDataSizeTemp = usDataSize;
  996. }
  997. else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_16)
  998. {
  999. usCmdAddrSizeTemp = usCmdAddrSize / 2;
  1000. usDataSizeTemp = usDataSize / 2;
  1001. }
  1002. else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32)
  1003. {
  1004. usCmdAddrSizeTemp = usCmdAddrSize / 4;
  1005. usDataSizeTemp = usDataSize / 4;
  1006. }
  1007. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  1008. {
  1009. if (usDataSize != 0)
  1010. {
  1011. uiDummySize = usCmdAddrSizeTemp;
  1012. }
  1013. usTxTotalSize = usCmdAddrSizeTemp + usDataSizeTemp;
  1014. pstSelf->usRxXferSize = usCmdAddrSizeTemp + usDataSizeTemp;
  1015. uiCmdDataRegAddrBase = CPU_SYS_SPI0_M_DR0 + pstSelf->uiBaseOffset;
  1016. uiCmdDataRegAddr = uiCmdDataRegAddrBase;
  1017. }
  1018. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  1019. {
  1020. HV_ASSERT(pucCmdAddr == NULL);
  1021. HV_ASSERT(usCmdAddrSize == 0);
  1022. pstSelf->usRxXferSize = usDataSizeTemp;
  1023. uiCmdDataRegAddrBase = CPU_SYS_SPI0_S_DR0 + pstSelf->uiBaseOffset;
  1024. uiCmdDataRegAddr = uiCmdDataRegAddrBase;
  1025. }
  1026. pstSelf->enState = SPI_STATE_BUSY_RX;
  1027. pstSelf->enErrorCode = SPI_ERROR_NONE;
  1028. Hv_Spi_Enable(pstSelf);
  1029. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER) /*read more need read at the moment*/
  1030. {
  1031. while (usTxTotalSize > 0)
  1032. {
  1033. uiTxFifoSurplusLev = HV_SPI_FIFO_DEPTH - Hv_Spi_GetTxFifoLevel(pstSelf);
  1034. uiTxDataNumOnce = (usTxTotalSize > uiTxFifoSurplusLev)? uiTxFifoSurplusLev : usTxTotalSize;
  1035. for (uiLoop = 0; uiLoop < uiTxDataNumOnce; uiLoop++)
  1036. {
  1037. if (usCmdAddrSizeTemp == 0)
  1038. {
  1039. Hv_Spi_TransmitOne(pstSelf, uiCmdDataRegAddr, ucDummy);
  1040. uiCmdDataRegAddr = uiCmdDataRegAddr + 4;
  1041. }
  1042. else
  1043. {
  1044. pucCmdAddr = Hv_Spi_TransmitOne(pstSelf, uiCmdDataRegAddr, pucCmdAddr);
  1045. usCmdAddrSizeTemp--;
  1046. uiCmdDataRegAddr = uiCmdDataRegAddr + 4;
  1047. }
  1048. if ((uiCmdDataRegAddr - uiCmdDataRegAddrBase) == HV_SPI_DR_ADDR_RANGE_TOTAL)
  1049. {
  1050. uiCmdDataRegAddr = uiCmdDataRegAddrBase;
  1051. }
  1052. usTxTotalSize--;
  1053. }
  1054. uiRxFifoDataLev = Hv_Spi_GetRxFifoLevel(pstSelf);
  1055. if (uiRxFifoDataLev > pstSelf->usRxXferSize)
  1056. {
  1057. uiRxFifoDataLev = pstSelf->usRxXferSize;
  1058. }
  1059. for (uiLoop = 0; uiLoop < uiRxFifoDataLev; uiLoop++)
  1060. {
  1061. if (uiDummySize == 0)
  1062. {
  1063. pucRxData = Hv_Spi_ReceiveOne(pstSelf, uiCmdDataRegAddrBase, pucRxData);
  1064. }
  1065. else
  1066. {
  1067. Hv_Spi_ReceiveOne(pstSelf, uiCmdDataRegAddrBase, ucDummy);
  1068. uiDummySize--;
  1069. }
  1070. pstSelf->usRxXferSize--;
  1071. }
  1072. }
  1073. }
  1074. while (pstSelf->usRxXferSize > 0)
  1075. {
  1076. uiRxFifoDataLev = Hv_Spi_GetRxFifoLevel(pstSelf);
  1077. if (uiRxFifoDataLev > pstSelf->usRxXferSize)
  1078. {
  1079. uiRxFifoDataLev = pstSelf->usRxXferSize;
  1080. }
  1081. for (uiLoop = 0; uiLoop < uiRxFifoDataLev; uiLoop++)
  1082. {
  1083. if (uiDummySize == 0)
  1084. {
  1085. pucRxData = Hv_Spi_ReceiveOne(pstSelf, uiCmdDataRegAddrBase, pucRxData);
  1086. }
  1087. else
  1088. {
  1089. Hv_Spi_ReceiveOne(pstSelf, uiCmdDataRegAddrBase, ucDummy);
  1090. uiDummySize--;
  1091. }
  1092. pstSelf->usRxXferSize--;
  1093. }
  1094. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  1095. {
  1096. if ((Hv_Vos_GetTick() - ullTickstart) > uiTimeout)
  1097. {
  1098. return HV_TIMEOUT;
  1099. }
  1100. }
  1101. }
  1102. if ((pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  1103. && (pstSelf->stInitParam.enCsCtlMode != SPI_CSMODE_ALWAYS_LOW))
  1104. {
  1105. if (Hv_Spi_WaitOnFlagUntilTimeout(pstSelf, SPI_FLAG_BUSY, HV_RESET, HV_SPI_TIMEOUT) != HV_SUCCESS)
  1106. {
  1107. return HV_TIMEOUT;
  1108. }
  1109. }
  1110. pstSelf->enState = SPI_STATE_READY;
  1111. Hv_Spi_Disable(pstSelf);
  1112. return HV_SUCCESS;
  1113. }
  1114. else
  1115. {
  1116. return HV_BUSY;
  1117. }
  1118. }
  1119. /**@brief Receive an amount of data in no-blocking mode with interrupt
  1120. * @param self pointer to spi structure
  1121. * @param pCmd pointer to command buffer
  1122. * @param pRxData pointer to data buffer
  1123. * @param size amount of data to be sent
  1124. * @retval result
  1125. */
  1126. Status Hv_Drv_Spi_IntReceive(SpiSelf *pstSelf, UCHAR8 *pucCmdAddr, USHORT16 usCmdAddrSize,
  1127. UCHAR8 *pucRxData,USHORT16 usDataSize)
  1128. {
  1129. UINT32 uiIntFlag = 0;
  1130. USHORT16 usCmdAddrSizeTemp = 0;
  1131. USHORT16 usDataSizeTemp = 0;
  1132. if (pstSelf->enState == SPI_STATE_READY)
  1133. {
  1134. if ((pstSelf->stInitParam.enDirection != SPI_DIRECTION_TXRX)
  1135. && (pstSelf->stInitParam.enDirection != SPI_DIRECTION_RX))
  1136. {
  1137. return HV_FAILURE;
  1138. }
  1139. if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
  1140. {
  1141. usCmdAddrSizeTemp = usCmdAddrSize;
  1142. usDataSizeTemp = usDataSize;
  1143. }
  1144. else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_16)
  1145. {
  1146. usCmdAddrSizeTemp = usCmdAddrSize / 2;
  1147. usDataSizeTemp = usDataSize / 2;
  1148. }
  1149. else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32)
  1150. {
  1151. usCmdAddrSizeTemp = usCmdAddrSize / 4;
  1152. usDataSizeTemp = usDataSize / 4;
  1153. }
  1154. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  1155. {
  1156. pstSelf->usDumSize= usCmdAddrSizeTemp;
  1157. pstSelf->usCmdAddrSize = usCmdAddrSizeTemp;
  1158. pstSelf->pucCmdAddr = pucCmdAddr;
  1159. pstSelf->pucTxBuff = NULL;
  1160. pstSelf->usTxXferSize = usDataSizeTemp;
  1161. pstSelf->usTxXferCount = 0;
  1162. }
  1163. else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
  1164. {
  1165. HV_ASSERT(pucCmdAddr == NULL);
  1166. HV_ASSERT(usCmdAddrSize == 0);
  1167. }
  1168. pstSelf->pucRxBuff = pucRxData;
  1169. pstSelf->usRxXferSize = usDataSizeTemp + pstSelf->usDumSize;
  1170. pstSelf->usRxXferCount = 0;
  1171. pstSelf->enState = SPI_STATE_BUSY_RX;
  1172. pstSelf->enErrorCode = SPI_ERROR_NONE;
  1173. pstSelf->enTransCompleteFlag = SPI_TRANS_IN_PROCESS;
  1174. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  1175. {
  1176. uiIntFlag = SPI_INTERRUPT_TXEIR | SPI_INTERRUPT_TXOIR | SPI_INTERRUPT_RXFIR | SPI_INTERRUPT_RXOIR | SPI_INTERRUPT_RXUIR;
  1177. } else {
  1178. uiIntFlag = SPI_INTERRUPT_RXFIR | SPI_INTERRUPT_RXOIR | SPI_INTERRUPT_RXUIR;
  1179. }
  1180. Hv_Spi_InterruptEnable(pstSelf, uiIntFlag);
  1181. Hv_Spi_Enable(pstSelf);
  1182. return HV_SUCCESS;
  1183. }
  1184. else
  1185. {
  1186. return HV_BUSY;
  1187. }
  1188. }
  1189. /**@brief Receive an amount of data in no-blocking mode with DMA
  1190. * @param self pointer to spi structure
  1191. * @param pucCmd pointer to command buffer
  1192. * @param pucRxData pointer to data buffer
  1193. * @param usDataSize amount of data to be sent
  1194. * @retval result
  1195. */
  1196. Status Hv_Drv_Spi_DmaReceive(SpiSelf *pstSelf, UCHAR8 *pucCmd, UCHAR8* pucRxData, USHORT16 usDataSize)
  1197. {
  1198. UINT32 uiTxBlockSize = 0;
  1199. UINT32 uiRxBlockSize = 0;
  1200. if (pstSelf->enState == SPI_STATE_READY)
  1201. {
  1202. if ((pstSelf->stInitParam.enDirection != SPI_DIRECTION_TXRX)
  1203. && (pstSelf->stInitParam.enDirection != SPI_DIRECTION_RX))
  1204. {
  1205. return HV_FAILURE;
  1206. }
  1207. if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
  1208. {
  1209. HV_ASSERT((usDataSize % 4) == 0);
  1210. uiTxBlockSize = usDataSize / 4;
  1211. uiRxBlockSize = usDataSize;
  1212. }
  1213. else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32)
  1214. {
  1215. uiTxBlockSize = usDataSize / 4;
  1216. uiRxBlockSize = usDataSize / 4;
  1217. }
  1218. Hv_Cal_Dma_XferCallbackBond(pstSelf->pstDmaRx, Hv_Spi_DmaReceiveCpltCallback);
  1219. Hv_Cal_Dma_SetBlockSize(pstSelf->pstDmaRx, uiRxBlockSize);
  1220. Hv_Cal_Dma_SetDstAddr(pstSelf->pstDmaRx, (UINT32)pucRxData);
  1221. Hv_Cal_Dma_ChannelEn(pstSelf->pstDmaRx);
  1222. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  1223. {
  1224. Hv_Spi_ConfigDmaTxReg(pstSelf, SPI_DMATX_ENABLE, HV_SPI_DMA_TX_THRESHOLD);
  1225. }
  1226. Hv_Spi_ConfigDmaRxReg(pstSelf, SPI_DMARX_ENABLE, HV_SPI_DMA_RX_THRESHOLD);
  1227. Hv_Spi_Enable(pstSelf);
  1228. pstSelf->enState = SPI_STATE_BUSY_RX;
  1229. pstSelf->enErrorCode = SPI_ERROR_NONE;
  1230. pstSelf->enTransCompleteFlag = SPI_TRANS_IN_PROCESS;
  1231. if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
  1232. {
  1233. Hv_Cal_Dma_XferCallbackBond(pstSelf->pstDmaTx, Hv_Spi_DmaTransmitCpltCallback);
  1234. Hv_Cal_Dma_SetBlockSize(pstSelf->pstDmaTx, uiTxBlockSize);
  1235. Hv_Cal_Dma_SetSrcAddr(pstSelf->pstDmaTx, (UINT32)pucCmd);
  1236. Hv_Cal_Dma_ChannelEn(pstSelf->pstDmaTx);
  1237. }
  1238. return HV_SUCCESS;
  1239. }
  1240. else
  1241. {
  1242. return HV_BUSY;
  1243. }
  1244. }
  1245. /**@brief check spi transfer complete yes or not
  1246. * @param self pointer to spi structure
  1247. * @retval HV_TRUE/HV_FALSE
  1248. */
  1249. BOOL Hv_Drv_Spi_TransferIsComplete(SpiSelf *pstSelf)
  1250. {
  1251. if (pstSelf->enTransCompleteFlag == SPI_TRANS_IN_PROCESS)
  1252. {
  1253. return HV_FALSE;
  1254. }
  1255. else if (pstSelf->enTransCompleteFlag == SPI_TRANS_END)
  1256. {
  1257. return HV_TRUE;
  1258. }
  1259. return HV_FALSE;
  1260. }
  1261. /**@brief read spi rx fifo data
  1262. * @param self pointer to spi structure
  1263. * @retval none
  1264. */
  1265. VOID Hv_Drv_Spi_SaveModeReadEmptyFifo(SpiSelf *pstSelf)
  1266. {
  1267. UINT32 i = 0;
  1268. UINT32 uiRxFifoDataLev = 0;
  1269. UCHAR8 ucDataTmp[128] = {0};
  1270. //UINT32 uiData = 0;
  1271. UINT32 uiCmdDataRegAddrBase = 0;
  1272. uiCmdDataRegAddrBase = CPU_SYS_SPI0_S_DR0 + pstSelf->uiBaseOffset;
  1273. uiRxFifoDataLev = Hv_Spi_GetRxFifoLevel(pstSelf);
  1274. if (uiRxFifoDataLev > pstSelf->usRxXferSize)
  1275. {
  1276. uiRxFifoDataLev = pstSelf->usRxXferSize;
  1277. }
  1278. for (i = 0; i < uiRxFifoDataLev; i++)
  1279. {
  1280. Hv_Spi_ReceiveOne(pstSelf, uiCmdDataRegAddrBase, ucDataTmp);
  1281. //uiData = *((UINT32 *)cmdDataRegAddrBase);
  1282. }
  1283. return;
  1284. }