wm_hspi.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. /**
  2. * @file wm_hspi.c
  3. *
  4. * @brief High speed spi slave Module
  5. *
  6. * @author dave
  7. *
  8. * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
  9. */
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include "wm_hspi.h"
  14. #include "wm_regs.h"
  15. #include "wm_config.h"
  16. #include "wm_mem.h"
  17. #include "wm_osal.h"
  18. #include "wm_irq.h"
  19. //#include "lwip/mem.h"
  20. #include "wm_io.h"
  21. #if TLS_CONFIG_HS_SPI
  22. struct tls_slave_hspi g_slave_hspi;
  23. #define SET_BIT(x) (1UL << (x))
  24. void hspi_free_rxdesc(struct tls_hspi_rx_desc *rx_desc);
  25. void hspi_rx_init(struct tls_slave_hspi *hspi)
  26. {
  27. struct tls_hspi_rx_desc *hspi_rx_desc;
  28. int i;
  29. /* set current availble rx desc pointer */
  30. hspi_rx_desc = (struct tls_hspi_rx_desc *) HSPI_RX_DESC_BASE_ADDR;
  31. hspi->curr_rx_desc = hspi_rx_desc;
  32. /* initialize rx descriptor content */
  33. for (i = 0; i < HSPI_RX_DESC_NUM; i++)
  34. {
  35. /* initialize tx descriptors */
  36. if (i < HSPI_RXBUF_NUM)
  37. {
  38. hspi_rx_desc->valid_ctrl = SET_BIT(31);
  39. hspi_rx_desc->buf_addr = HSPI_RXBUF_BASE_ADDR + i * HSPI_RXBUF_SIZE;
  40. }
  41. else
  42. {
  43. /* indicate this descriptor is can't use by hspi */
  44. hspi_rx_desc->valid_ctrl = 0;
  45. /* point to null */
  46. hspi_rx_desc->buf_addr = 0x0;
  47. }
  48. if (i == (HSPI_RX_DESC_NUM - 1))
  49. {
  50. hspi_rx_desc->next_desc_addr = (u32) HSPI_RX_DESC_BASE_ADDR;
  51. }
  52. else
  53. {
  54. hspi_rx_desc->next_desc_addr = (u32) (hspi_rx_desc + 1);
  55. }
  56. hspi_rx_desc++;
  57. }
  58. }
  59. void hspi_tx_init(struct tls_slave_hspi *hspi)
  60. {
  61. struct tls_hspi_tx_desc *hspi_tx_desc;
  62. int i;
  63. hspi_tx_desc = (struct tls_hspi_tx_desc *) HSPI_TX_DESC_BASE_ADDR;
  64. hspi->curr_tx_desc = hspi_tx_desc;
  65. for (i = 0; i < HSPI_TX_DESC_NUM; i++)
  66. {
  67. hspi_tx_desc->valid_ctrl = 0;
  68. hspi_tx_desc->buf_info = 0;
  69. #if HSPI_TX_MEM_MALLOC
  70. hspi_tx_desc->txbuf_addr = NULL;
  71. hspi_tx_desc->buf_addr[0] = 0;
  72. #else
  73. hspi_tx_desc->buf_addr[0] = HSPI_TXBUF_BASE_ADDR + i * HSPI_TXBUF_SIZE;
  74. #endif
  75. hspi_tx_desc->buf_addr[1] = 0;
  76. hspi_tx_desc->buf_addr[2] = 0;
  77. if (i == (HSPI_TX_DESC_NUM - 1))
  78. {
  79. hspi_tx_desc->next_desc_addr = (u32) HSPI_TX_DESC_BASE_ADDR;
  80. }
  81. else
  82. {
  83. hspi_tx_desc->next_desc_addr = (u32) (hspi_tx_desc + 1);
  84. }
  85. hspi_tx_desc++;
  86. }
  87. }
  88. static int slave_spi_rx_data(struct tls_slave_hspi *hspi)
  89. {
  90. struct tls_hspi_rx_desc *rx_desc;
  91. /* get rx descriptor */
  92. rx_desc = hspi->curr_rx_desc;
  93. while (!(rx_desc->valid_ctrl & SET_BIT(31)))
  94. {
  95. if (hspi->rx_data_callback)
  96. hspi->rx_data_callback((char *) rx_desc->buf_addr);
  97. hspi_free_rxdesc(rx_desc);
  98. rx_desc = (struct tls_hspi_rx_desc *) rx_desc->next_desc_addr;
  99. hspi->curr_rx_desc = rx_desc;
  100. }
  101. return 0;
  102. }
  103. void SDIO_RX_IRQHandler(void)
  104. {
  105. struct tls_slave_hspi *hspi = (struct tls_slave_hspi *) &g_slave_hspi;
  106. #if HSPI_TX_MEM_MALLOC
  107. hspi->txdoneflag = 1;
  108. #endif
  109. if (hspi->tx_data_callback)
  110. hspi->tx_data_callback((char *) hspi->curr_tx_desc->buf_addr);
  111. /* clear interrupt */
  112. tls_reg_write32(HR_SDIO_INT_SRC, SDIO_WP_INT_SRC_DATA_UP);
  113. }
  114. void SDIO_TX_IRQHandler(void)
  115. {
  116. struct tls_slave_hspi *hspi = (struct tls_slave_hspi *) &g_slave_hspi;
  117. //用户模式下,直接给出数据,链表的操作不对外开放,避免造成链表操作错误
  118. if (hspi->ifusermode)
  119. {
  120. slave_spi_rx_data(hspi);
  121. }
  122. else
  123. {
  124. if (hspi->rx_data_callback)
  125. hspi->rx_data_callback((char *) hspi->curr_rx_desc->buf_addr);
  126. }
  127. /* clear interrupt */
  128. tls_reg_write32(HR_SDIO_INT_SRC, SDIO_WP_INT_SRC_DATA_DOWN);
  129. }
  130. void SDIO_RX_CMD_IRQHandler(void)
  131. {
  132. struct tls_slave_hspi *hspi = (struct tls_slave_hspi *) &g_slave_hspi;
  133. if (hspi->rx_cmd_callback)
  134. hspi->rx_cmd_callback((char *) SDIO_CMD_RXBUF_ADDR);
  135. if (hspi->ifusermode) // 用户模式下,数据给出去之后,寄存器由驱动自己操作
  136. {
  137. tls_reg_write32(HR_SDIO_DOWNCMDVALID, 0x1);
  138. }
  139. /* clear interrupt */
  140. tls_reg_write32(HR_SDIO_INT_SRC, SDIO_WP_INT_SRC_CMD_DOWN);
  141. }
  142. ATTRIBUTE_ISR void HSPI_IRQHandler(void)
  143. {
  144. printf("spi HS irqhandle\n");
  145. }
  146. ATTRIBUTE_ISR void SDIOA_IRQHandler(void)
  147. {
  148. u32 int_src = tls_reg_read32(HR_SDIO_INT_SRC);
  149. csi_kernel_intrpt_enter();
  150. if(int_src & SDIO_WP_INT_SRC_CMD_DOWN)
  151. {
  152. SDIO_RX_CMD_IRQHandler();
  153. }
  154. else if(int_src & SDIO_WP_INT_SRC_DATA_UP)
  155. {
  156. SDIO_RX_IRQHandler();
  157. }
  158. else if(int_src & SDIO_WP_INT_SRC_DATA_DOWN)
  159. {
  160. SDIO_TX_IRQHandler();
  161. }
  162. else if(int_src & SDIO_WP_INT_SRC_CMD_UP)
  163. {
  164. tls_reg_write32(HR_SDIO_INT_SRC, SDIO_WP_INT_SRC_CMD_UP);
  165. }
  166. csi_kernel_intrpt_exit();
  167. }
  168. void hspi_free_rxdesc(struct tls_hspi_rx_desc *rx_desc)
  169. {
  170. rx_desc->valid_ctrl = SET_BIT(31);
  171. /* 设置hspi/sdio tx enable寄存器,让sdio硬件知道有可用的tx descriptor */
  172. tls_reg_write32(HR_SDIO_TXEN, SET_BIT(0));
  173. }
  174. void hspi_regs_cfg(void)
  175. {
  176. tls_reg_write32(HR_HSPI_CLEAR_FIFO, 0x1); /* Clear data up&down interrput
  177. */
  178. tls_reg_write32(HR_HSPI_SPI_CFG, 0); /* CPOL=0, CPHA=0, Small-Endian */
  179. tls_reg_write32(HR_HSPI_MODE_CFG, 0x0);
  180. tls_reg_write32(HR_HSPI_INT_MASK, 0x03);
  181. tls_reg_write32(HR_HSPI_INT_STTS, 0x03);
  182. }
  183. void sdio_init_cis(void)
  184. {
  185. tls_reg_write32(FN0_TPL_FUNCID, 0x000C0221);
  186. tls_reg_write32(FN0_TPL_FUNCE, 0x00000422);
  187. tls_reg_write32(FN0_TPL_FUNCE_MAXBLK, 0x04203208);
  188. tls_reg_write32(FN0_TPL_MANFID_MID, 0x53470296);
  189. tls_reg_write32(FN0_TPL_END, 0x000000ff);
  190. tls_reg_write32(FN1_TPL_FUNCID, 0x000C0221);
  191. tls_reg_write32(FN1_TPL_FUNCE, 0x01012a22);
  192. tls_reg_write32(FN1_TPL_FUNCE_VER, 0x00000011);
  193. tls_reg_write32(FN1_TPL_FUNCE_NSN, 0x02000000);
  194. tls_reg_write32(FN1_TPL_FUNCE_CSASIZE, 0x08000300);
  195. tls_reg_write32(FN1_TPL_FUNCE_OCR, 0x00FF8000);
  196. tls_reg_write32(FN1_TPL_FUNCE_MINPWR, 0x010f0a08);
  197. tls_reg_write32(FN1_TPL_FUNCE_STANDBY, 0x00000101);
  198. tls_reg_write32(FN1_TPL_FUNCE_OPTBW, 0x00000000);
  199. tls_reg_write32(FN1_TPL_FUNCE_NTIMEOUT, 0x00000000);
  200. tls_reg_write32(FN1_TPL_FUNCE_AVGPWR, 0x00000000);
  201. tls_reg_write32(FN1_TPL_FUNCE_AVGPWR + 4, 0x00000000);
  202. tls_reg_write32(FN1_TPL_END, 0x000000ff);
  203. }
  204. void hsdio_regs_cfg(void)
  205. {
  206. u32 v;
  207. sdio_init_cis();
  208. tls_reg_write32(HR_SDIO_CIS0, SDIO_CIS0_ADDR - 0x1000);
  209. tls_reg_write32(HR_SDIO_CIS1, SDIO_CIS1_ADDR - 0x2000);
  210. v = tls_reg_read32(HR_SDIO_CIA);
  211. tls_reg_write32(HR_SDIO_CIA, (v & 0xFFFFF000) | 0x232);
  212. /* set sdio ready */
  213. tls_reg_write32(HR_SDIO_PROG, 0x02FD);
  214. }
  215. /**
  216. * @brief This function is used to initial HSPI register.
  217. *
  218. * @param[in] None
  219. *
  220. * @retval 0 success
  221. * @retval other failed
  222. *
  223. * @note When the system is initialized, the function has been called, so users can not call the function.
  224. */
  225. int tls_slave_spi_init(void)
  226. {
  227. struct tls_slave_hspi *hspi;
  228. hspi = &g_slave_hspi;
  229. memset(hspi, 0, sizeof(struct tls_slave_hspi));
  230. hspi_rx_init(hspi);
  231. hspi_tx_init(hspi);
  232. // tls_set_high_speed_interface_type(HSPI_INTERFACE_SPI);
  233. /* regiseter hspi tx rx cmd interrupt handler */
  234. /* setting hw interrupt module isr enable regiset */
  235. tls_irq_enable(SDIO_IRQn);
  236. tls_irq_enable(SPI_HS_IRQn);
  237. /********************************************
  238. * setting hspi wrapper registers
  239. *********************************************/
  240. /* hspi data down(rx) */
  241. tls_reg_write32(HR_SDIO_TXBD_ADDR, HSPI_RX_DESC_BASE_ADDR);
  242. tls_reg_write32(HR_SDIO_TXBD_LINKEN, 1);
  243. tls_reg_write32(HR_SDIO_TXEN, 1);
  244. /* hspi data up (tx) */
  245. tls_reg_write32(HR_SDIO_RXBD_ADDR, HSPI_TX_DESC_BASE_ADDR);
  246. tls_reg_write32(HR_SDIO_RXBD_LINKEN, 1);
  247. /* hspi cmd down */
  248. tls_reg_write32(HR_SDIO_CMD_ADDR, SDIO_CMD_RXBUF_ADDR);
  249. tls_reg_write32(HR_SDIO_CMD_SIZE, SDIO_CMD_RXBUF_SIZE);
  250. tls_reg_write32(HR_SDIO_DOWNCMDVALID, 0x1);
  251. /* enable sdio module register */
  252. tls_reg_write32(HR_SDIO_INT_MASK, 0x00);
  253. return 0;
  254. }
  255. /**
  256. * @brief This function is used to set high speed interface type.
  257. *
  258. * @param[in] type is the interface type. HSPI_INTERFACE_SPI or HSPI_INTERFACE_SDIO
  259. *
  260. * @return None
  261. *
  262. * @note None
  263. */
  264. void tls_set_high_speed_interface_type(int type)
  265. {
  266. if (HSPI_INTERFACE_SPI == type)
  267. {
  268. hspi_regs_cfg();
  269. }
  270. else if (HSPI_INTERFACE_SDIO == type)
  271. {
  272. hsdio_regs_cfg();
  273. }
  274. }
  275. /**
  276. * @brief This function is used to enable or disable user mode.
  277. *
  278. * @param[in] ifenable TRUE or FALSE
  279. *
  280. * @return None
  281. *
  282. * @note If the user enables the user mode, RICM instruction in the system will not be used by SPI.
  283. * If the user wants to use the SPI interface as other use, need to enable the user mode.
  284. * This function must be called before the register function.
  285. */
  286. void tls_set_hspi_user_mode(u8 ifenable)
  287. {
  288. struct tls_slave_hspi *hspi = &g_slave_hspi;
  289. hspi->ifusermode = ifenable;
  290. if (ifenable)
  291. {
  292. hspi->rx_cmd_callback = NULL;
  293. hspi->rx_data_callback = NULL;
  294. hspi->tx_data_callback = NULL;
  295. }
  296. }
  297. /**
  298. * @brief This function is used to register hspi rx command interrupt.
  299. *
  300. * @param[in] rx_cmd_callback is the hspi rx interrupt call back function.
  301. *
  302. * @return None
  303. *
  304. * @note None
  305. */
  306. void tls_hspi_rx_cmd_callback_register(s16(*rx_cmd_callback) (char *buf))
  307. {
  308. g_slave_hspi.rx_cmd_callback = rx_cmd_callback;
  309. }
  310. /**
  311. * @brief This function is used to register hspi rx data interrupt.
  312. *
  313. * @param[in] rx_data_callback is the hspi rx interrupt call back function.
  314. *
  315. * @return None
  316. *
  317. * @note None
  318. */
  319. void tls_hspi_rx_data_callback_register(s16(*rx_data_callback) (char *buf))
  320. {
  321. g_slave_hspi.rx_data_callback = rx_data_callback;
  322. }
  323. /**
  324. * @brief This function is used to register hspi tx data interrupt.
  325. *
  326. * @param[in] tx_data_callback is the hspi tx interrupt call back function.
  327. *
  328. * @return None
  329. *
  330. * @note None
  331. */
  332. void tls_hspi_tx_data_callback_register(s16(*tx_data_callback) (char *buf))
  333. {
  334. g_slave_hspi.tx_data_callback = tx_data_callback;
  335. }
  336. /**
  337. * @brief This function is used to transfer data.
  338. *
  339. * @param[in] txbuf is a buf for saving user data.
  340. * @param[in] len is the data length.
  341. *
  342. * @retval transfer data len success
  343. * @retval 0 failed
  344. *
  345. * @note None
  346. */
  347. int tls_hspi_tx_data(char *txbuf, int len)
  348. {
  349. struct tls_hspi_tx_desc *tx_desc;
  350. int totallen = len;
  351. int txlen;
  352. if (NULL == txbuf || len <= 0 || len > (HSPI_TXBUF_SIZE * HSPI_TX_DESC_NUM))
  353. {
  354. printf("\nhspi tx param error\n");
  355. return 0;
  356. }
  357. tx_desc = g_slave_hspi.curr_tx_desc;
  358. while (1)
  359. {
  360. if ((tx_desc->valid_ctrl & SET_BIT(31)) == 0)
  361. break;
  362. tls_os_time_delay(1);
  363. }
  364. while (!(tx_desc->valid_ctrl & SET_BIT(31)))
  365. {
  366. txlen = (totallen > HSPI_TXBUF_SIZE) ? HSPI_TXBUF_SIZE : totallen;
  367. #if HSPI_TX_MEM_MALLOC
  368. if (tx_desc->txbuf_addr != NULL)
  369. {
  370. printf("\nhspi txbuf not null,error %x\n", tx_desc->txbuf_addr);
  371. if (tx_desc->txbuf_addr == tx_desc->buf_addr[0])
  372. {
  373. mem_free((void *) tx_desc->txbuf_addr);
  374. tx_desc->txbuf_addr = NULL;
  375. }
  376. else // 不应该出现
  377. {
  378. printf("\nhspi tx mem error\n");
  379. break;
  380. }
  381. }
  382. tx_desc->txbuf_addr = (u32) mem_malloc(txlen + 1);
  383. if (NULL == tx_desc->txbuf_addr)
  384. {
  385. printf("\nhspi tx data malloc error\n");
  386. break;
  387. }
  388. tx_desc->buf_addr[0] = tx_desc->txbuf_addr;
  389. #endif
  390. MEMCPY((char *) tx_desc->buf_addr[0], txbuf, txlen);
  391. tx_desc->buf_info = txlen << 12;
  392. tx_desc->valid_ctrl = SET_BIT(31);
  393. tls_reg_write32(HR_SDIO_RXEN, 0x01);
  394. tx_desc = (struct tls_hspi_tx_desc *) tx_desc->next_desc_addr;
  395. g_slave_hspi.curr_tx_desc = tx_desc;
  396. totallen -= txlen;
  397. if (totallen <= 0)
  398. break;
  399. }
  400. return (len - totallen);
  401. }
  402. #endif