wm_hostspi.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573
  1. /**
  2. * @file wm_hostspi.c
  3. *
  4. * @brief host spi Driver Module
  5. *
  6. * @author dave
  7. *
  8. * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
  9. */
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13. #include "wm_regs.h"
  14. #include "wm_irq.h"
  15. #include "wm_gpio.h"
  16. #include "wm_hostspi.h"
  17. #include "wm_dma.h"
  18. #include "wm_dbg.h"
  19. #include "wm_mem.h"
  20. #include "wm_cpu.h"
  21. #include "wm_spi_hal.h"
  22. #include "wm_wl_task.h"
  23. #include "tls_common.h"
  24. #include "core_804.h"
  25. #include "wm_pmu.h"
  26. #define ATTRIBUTE_ISR __attribute__((isr))
  27. static struct tls_spi_port *spi_port = NULL;
  28. #define MSG_QUEUE_SIZE (8)
  29. #define SPI_SCHEDULER_STK_SIZE (256)
  30. static u32 *spi_scheduler_stk = NULL;
  31. void tls_spi_queue_send(u32 msg);
  32. #define SPI_SCHED_MSG_START_ENGINE (1)
  33. #define SPI_SCHED_MSG_TX_FIFO_READY (2)
  34. #define SPI_SCHED_MSG_RX_FIFO_READY (3)
  35. #define SPI_SCHED_MSG_TRANSFER_COMPLETE (4)
  36. #define SPI_SCHED_MSG_EXIT (5)
  37. #define SPI_SCHED_MSG_END (6)
  38. static void spi_start_transfer(u32 transfer_bytes);
  39. int tls_spi_async(struct tls_spi_message *message);
  40. int tls_spi_sync(struct tls_spi_message *message);
  41. #ifdef SPI_USE_DMA
  42. unsigned char *SPI_DMA_CMD_ADDR = NULL;
  43. unsigned char *SPI_DMA_BUF_ADDR = NULL;
  44. static void SpiMasterInit(u8 mode, u8 cs_active, u32 fclk)
  45. {
  46. tls_sys_clk sysclk;
  47. SPIM_CHCFG_REG = SPI_CLEAR_FIFOS;
  48. while (SPIM_CHCFG_REG & SPI_CLEAR_FIFOS) cs_active = cs_active;
  49. tls_sys_clk_get(&sysclk); //获取实际频率
  50. SPIM_CLKCFG_REG = sysclk.apbclk*UNIT_MHZ/(fclk*2) - 1;;
  51. SPIM_SPICFG_REG = 0;
  52. SPIM_SPICFG_REG = SPI_FRAME_FORMAT_MOTO | SPI_SET_MASTER_SLAVE(SPI_MASTER) | mode;
  53. SPIM_INTEN_REG = 0xff; /* Disable INT */
  54. if (SPI_DMA_CMD_ADDR == NULL)
  55. {
  56. SPI_DMA_CMD_ADDR = tls_mem_alloc(SPI_DMA_CMD_MAX_SIZE);
  57. if (SPI_DMA_CMD_ADDR == NULL)
  58. {
  59. return;
  60. }
  61. }
  62. if (SPI_DMA_BUF_ADDR == NULL)
  63. {
  64. SPI_DMA_BUF_ADDR = tls_mem_alloc(SPI_DMA_BUF_MAX_SIZE);
  65. if (SPI_DMA_BUF_ADDR == NULL)
  66. {
  67. tls_mem_free(SPI_DMA_CMD_ADDR);
  68. SPI_DMA_CMD_ADDR = NULL;
  69. return;
  70. }
  71. }
  72. tls_dma_init();
  73. }
  74. int spiWaitIdle(void)
  75. {
  76. unsigned long regVal;
  77. unsigned long timeout = 0;
  78. do
  79. {
  80. timeout++;
  81. if (timeout > 0x4FFFFF) // 5s
  82. return TLS_SPI_STATUS_EBUSY;
  83. regVal = SPIM_SPISTATUS_REG;
  84. }
  85. while (regVal & (1 << 12));
  86. return TLS_SPI_STATUS_OK;
  87. }
  88. static int SpiDmaBlockWrite(u8 * data, u32 len, u8 ifusecmd, u32 cmd)
  89. {
  90. unsigned char dmaCh = 0;
  91. struct tls_dma_descriptor DmaDesc;
  92. u32 txlen, txlenbk;
  93. u32 i, blocknum, blocksize = 0;
  94. int ret = TLS_SPI_STATUS_OK;
  95. int txcmdover = 0;
  96. if (NULL == data)
  97. {
  98. return TLS_SPI_STATUS_EINVAL;
  99. }
  100. if (spiWaitIdle())
  101. return TLS_SPI_STATUS_EBUSY;
  102. SPIM_CHCFG_REG = SPI_CLEAR_FIFOS;
  103. while (SPIM_CHCFG_REG & SPI_CLEAR_FIFOS);
  104. if (ifusecmd)
  105. SPIM_TXDATA_REG = cmd;
  106. if (len % 4)
  107. {
  108. txlen = len & 0xfffffffc; // 不够字的最后单独发
  109. }
  110. else
  111. {
  112. txlen = len;
  113. }
  114. txlenbk = txlen;
  115. if (txlen > 0)
  116. {
  117. blocknum = txlen / SPI_DMA_MAX_TRANS_SIZE;
  118. /* Request DMA Channel */
  119. dmaCh = tls_dma_request(1,TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_LSSPI_TX) |
  120. TLS_DMA_FLAGS_HARD_MODE);
  121. for (i = 0; i <= blocknum; i++)
  122. {
  123. DmaDesc.src_addr = (int) (data + i * SPI_DMA_MAX_TRANS_SIZE);
  124. DmaDesc.dest_addr = HR_SPI_TXDATA_REG;
  125. blocksize = (txlen > SPI_DMA_MAX_TRANS_SIZE) ? SPI_DMA_MAX_TRANS_SIZE : txlen;
  126. if (0 == blocksize)
  127. break;
  128. DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_SRC_ADD_INC |
  129. TLS_DMA_DESC_CTRL_DATA_SIZE_WORD |
  130. TLS_DMA_DESC_CTRL_TOTAL_BYTES(blocksize);
  131. DmaDesc.valid = TLS_DMA_DESC_VALID;
  132. DmaDesc.next = NULL;
  133. tls_dma_start(dmaCh, &DmaDesc, 0);
  134. /* Enable SPI TX DMA */
  135. SPIM_MODECFG_REG = SPI_RX_TRIGGER_LEVEL(0) | SPI_TX_TRIGGER_LEVEL(0) | SPI_TX_DMA_ON;
  136. SPIM_SPITIMEOUT_REG = SPI_TIMER_EN | SPI_TIME_OUT((u32) 0xffff);
  137. if (ifusecmd && 0 == i)
  138. {
  139. SPIM_CHCFG_REG = SPI_FORCE_SPI_CS_OUT | SPI_TX_CHANNEL_ON |
  140. SPI_CONTINUE_MODE | SPI_START |
  141. SPI_VALID_CLKS_NUM(((blocksize + 4) * 8));
  142. txcmdover = 1;
  143. }
  144. else
  145. SPIM_CHCFG_REG = SPI_FORCE_SPI_CS_OUT | SPI_TX_CHANNEL_ON | SPI_CONTINUE_MODE |
  146. SPI_START | SPI_VALID_CLKS_NUM((blocksize * 8));
  147. if (spiWaitIdle())
  148. {
  149. ret = TLS_SPI_STATUS_EBUSY;
  150. break;
  151. }
  152. /* Wait Dma Channel Complete and Free Dma channel */
  153. if (tls_dma_wait_complt(dmaCh))
  154. {
  155. ret = TLS_SPI_STATUS_EBUSY;
  156. break;
  157. }
  158. txlen -= blocksize;
  159. }
  160. tls_dma_free(dmaCh);
  161. }
  162. // tx 不够一个整字的几个字节
  163. if (len > txlenbk)
  164. {
  165. u32 word32 = 0;
  166. int temp = 0;
  167. for (i = 0; i < (len - txlenbk); i++)
  168. {
  169. word32 |= (data[txlenbk + i] << (i * 8));
  170. }
  171. SPIM_TXDATA_REG = word32;
  172. SPIM_MODECFG_REG = SPI_RX_TRIGGER_LEVEL(0) | SPI_TX_TRIGGER_LEVEL(0);
  173. SPIM_SPITIMEOUT_REG = SPI_TIMER_EN | SPI_TIME_OUT((u32) 0xffff);
  174. if (ifusecmd && 0 == txcmdover) // 需要发送命令,但是命令还没有发送出去,发送的字节数需要增加4
  175. temp = 4;
  176. SPIM_CHCFG_REG = SPI_FORCE_SPI_CS_OUT | SPI_TX_CHANNEL_ON | SPI_CONTINUE_MODE |
  177. SPI_START | SPI_VALID_CLKS_NUM(((temp + len - txlenbk) * 8));
  178. if (spiWaitIdle())
  179. {
  180. ret = TLS_SPI_STATUS_EBUSY;
  181. }
  182. }
  183. SPIM_CHCFG_REG = 0x00000000;
  184. SPIM_MODECFG_REG = 0x00000000;
  185. SPIM_SPITIMEOUT_REG = 0x00000000;
  186. return ret;
  187. }
  188. static int SpiDmaBlockRead(u8 * data, u32 len, u8 * txdata, u8 txlen)
  189. {
  190. unsigned char dmaCh = 0;
  191. struct tls_dma_descriptor DmaDesc;
  192. u32 word32 = 0;
  193. u32 i;
  194. u32 rxlen, rxlenbk;
  195. u8 blocknum;
  196. u32 blocksize = 0;
  197. int ret = TLS_SPI_STATUS_OK;
  198. // printf("\nentry SpiDmaBlockRead\n");
  199. if (NULL == data)
  200. {
  201. return TLS_SPI_STATUS_EINVAL;
  202. }
  203. if (spiWaitIdle())
  204. {
  205. return TLS_SPI_STATUS_EBUSY;
  206. }
  207. SPIM_CHCFG_REG = SPI_CLEAR_FIFOS;
  208. while (SPIM_CHCFG_REG & SPI_CLEAR_FIFOS);
  209. if (len % 4)
  210. {
  211. rxlen = len & 0xfffffffc; // 不够字的最后单独取
  212. }
  213. else
  214. {
  215. rxlen = len;
  216. }
  217. rxlenbk = rxlen;
  218. blocknum = rxlen / SPI_DMA_MAX_TRANS_SIZE;
  219. if (txlen > 0 && txlen <= 32)
  220. {
  221. for (i = 0; i < txlen; i++)
  222. {
  223. if ((i > 0) && (0 == i % 4))
  224. {
  225. SPIM_TXDATA_REG = word32;
  226. word32 = 0;
  227. }
  228. word32 |= (txdata[i] << ((i % 4) * 8));
  229. }
  230. SPIM_TXDATA_REG = word32;
  231. }
  232. /* Request DMA Channel */
  233. dmaCh = tls_dma_request(1,TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_LSSPI_RX) |
  234. TLS_DMA_FLAGS_HARD_MODE);
  235. DmaDesc.src_addr = HR_SPI_RXDATA_REG;
  236. for (i = 0; i <= blocknum; i++)
  237. {
  238. if (rxlenbk > 0)
  239. {
  240. // 说明接收的数据大于4
  241. // printf("\ni =%d\n",i);
  242. DmaDesc.dest_addr = (int) (data + i * SPI_DMA_MAX_TRANS_SIZE);
  243. blocksize = (rxlen > SPI_DMA_MAX_TRANS_SIZE) ? SPI_DMA_MAX_TRANS_SIZE : rxlen;
  244. if (0 == blocksize)
  245. break;
  246. // printf("\nblocksize= %d\n",blocksize);
  247. DmaDesc.dma_ctrl =
  248. TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 |
  249. TLS_DMA_DESC_CTRL_DATA_SIZE_WORD |
  250. TLS_DMA_DESC_CTRL_TOTAL_BYTES(blocksize);
  251. // word32 = DmaDesc.dma_ctrl;
  252. // printf("\ndma ctrl = %x\n",DmaDesc.dma_ctrl);
  253. DmaDesc.valid = TLS_DMA_DESC_VALID;
  254. DmaDesc.next = NULL;
  255. tls_dma_start(dmaCh, &DmaDesc, 0);
  256. /* Enable SPI RX DMA */
  257. SPIM_MODECFG_REG = SPI_RX_TRIGGER_LEVEL(0) | SPI_TX_TRIGGER_LEVEL(0) |
  258. SPI_RX_DMA_ON;
  259. }
  260. else
  261. {
  262. SPIM_MODECFG_REG = SPI_RX_TRIGGER_LEVEL(0) | SPI_TX_TRIGGER_LEVEL(0); // rx数据少于4个byte,不用开DMA
  263. }
  264. SPIM_SPITIMEOUT_REG = SPI_TIMER_EN | SPI_TIME_OUT((u32) 0xffff);
  265. if (0 == blocknum)
  266. {
  267. SPIM_CHCFG_REG =
  268. SPI_FORCE_SPI_CS_OUT | SPI_RX_CHANNEL_ON | SPI_TX_CHANNEL_ON |
  269. SPI_CONTINUE_MODE | SPI_START |
  270. SPI_VALID_CLKS_NUM(((len + txlen) * 8)) | SPI_RX_INVALID_BITS(txlen *8);
  271. }
  272. else
  273. {
  274. if (0 == i) // 第一次需要打开TX
  275. {
  276. SPIM_CHCFG_REG =
  277. SPI_FORCE_SPI_CS_OUT | SPI_RX_CHANNEL_ON | SPI_TX_CHANNEL_ON
  278. | SPI_CONTINUE_MODE | SPI_START |
  279. SPI_VALID_CLKS_NUM(((blocksize + txlen) *8)) | SPI_RX_INVALID_BITS(txlen * 8);
  280. }
  281. else if (i == blocknum)
  282. {
  283. SPIM_CHCFG_REG =
  284. SPI_FORCE_SPI_CS_OUT | SPI_RX_CHANNEL_ON | SPI_CONTINUE_MODE
  285. | SPI_START | SPI_VALID_CLKS_NUM((blocksize + len - rxlenbk) * 8);
  286. }
  287. else
  288. {
  289. SPIM_CHCFG_REG =
  290. SPI_FORCE_SPI_CS_OUT | SPI_RX_CHANNEL_ON | SPI_CONTINUE_MODE
  291. | SPI_START | SPI_VALID_CLKS_NUM(blocksize * 8);
  292. }
  293. }
  294. if (spiWaitIdle())
  295. {
  296. ret = TLS_SPI_STATUS_EBUSY;
  297. break;
  298. }
  299. /* Wait Dma Channel Complete and Free Dma channel */
  300. if (tls_dma_wait_complt(dmaCh))
  301. {
  302. ret = TLS_SPI_STATUS_EBUSY;
  303. break;
  304. }
  305. rxlen -= blocksize;
  306. }
  307. tls_dma_free(dmaCh);
  308. if (len > rxlenbk) // 取最后的不够一个字的几个byte
  309. {
  310. word32 = SPIM_RXDATA_REG;
  311. *((int *) data + rxlenbk / 4) = word32;
  312. }
  313. SPIM_CHCFG_REG = 0x00000000;
  314. SPIM_MODECFG_REG = 0x00000000;
  315. SPIM_SPITIMEOUT_REG = 0x00000000;
  316. return ret;
  317. }
  318. #endif
  319. /**
  320. * @brief This function is used to set SPI transfer mode.
  321. *
  322. * @param[in] type is the transfer type.
  323. * type == SPI_BYTE_TRANSFER byte transfer
  324. * type == SPI_WORD_TRANSFER word transfer
  325. * type == SPI_DMA_TRANSFER DMA transfer
  326. *
  327. * @return None
  328. *
  329. * @note None
  330. */
  331. void tls_spi_trans_type(u8 type)
  332. {
  333. spi_port->transtype = type;
  334. if (SPI_WORD_TRANSFER == type)
  335. {
  336. spi_set_endian(0);
  337. }
  338. else if (SPI_DMA_TRANSFER == type)
  339. {
  340. #ifdef SPI_USE_DMA
  341. SpiMasterInit(spi_port->mode, TLS_SPI_CS_LOW, spi_port->speed_hz);
  342. #endif
  343. }
  344. }
  345. static void spi_message_init(struct tls_spi_message *m)
  346. {
  347. memset(m, 0, sizeof(*m));
  348. dl_list_init(&m->transfers);
  349. }
  350. static void spi_complete(void *arg)
  351. {
  352. tls_os_sem_t *sem;
  353. sem = (tls_os_sem_t *) arg;
  354. tls_os_sem_release(sem);
  355. }
  356. static u32 spi_fill_txfifo(struct tls_spi_transfer *current_transfer,
  357. u32 current_remaining_bytes)
  358. {
  359. u8 fifo_level;
  360. u16 rw_words;
  361. u16 rw_bytes;
  362. u8 data8;
  363. u8 i;
  364. u32 data32 = 0;
  365. u32 tx_remaining_bytes;
  366. if ((current_transfer == NULL) || (current_remaining_bytes == 0))
  367. return 0;
  368. tx_remaining_bytes = current_remaining_bytes;
  369. // printf("ready to write to fifo size - %d.\n", tx_remaining_bytes);
  370. spi_get_status(NULL, NULL, &fifo_level);
  371. // TLS_DBGPRT_SPI("\nfifo_level 0= %d\n",fifo_level);
  372. rw_words =
  373. ((fifo_level > tx_remaining_bytes) ? tx_remaining_bytes : fifo_level) / 4;
  374. rw_bytes =
  375. ((fifo_level > tx_remaining_bytes) ? tx_remaining_bytes : fifo_level) % 4;
  376. // TLS_DBGPRT_SPI("write to spi fifo words - %d, bytes - %d.\n", rw_words,
  377. // rw_bytes);
  378. //下面代码17us
  379. for (i = 0; i < rw_words; i++)
  380. {
  381. if (current_transfer->tx_buf)
  382. {
  383. if (SPI_BYTE_TRANSFER == spi_port->transtype)
  384. {
  385. data32 = 0;
  386. data32 |= ((u8 *) current_transfer->tx_buf +
  387. (current_transfer->len - tx_remaining_bytes))[0] << 24;
  388. data32 |= ((u8 *) current_transfer->tx_buf +
  389. (current_transfer->len - tx_remaining_bytes))[1] << 16;
  390. data32 |= ((u8 *) current_transfer->tx_buf +
  391. (current_transfer->len - tx_remaining_bytes))[2] << 8;
  392. data32 |= ((u8 *) current_transfer->tx_buf +
  393. (current_transfer->len - tx_remaining_bytes))[3] << 0;
  394. }
  395. else if (SPI_WORD_TRANSFER == spi_port->transtype)
  396. {
  397. data32 = *((u32 *) ((u8 *) current_transfer->tx_buf +
  398. current_transfer->len - tx_remaining_bytes));
  399. }
  400. }
  401. else
  402. {
  403. data32 = 0xffffffff;
  404. }
  405. TLS_DBGPRT_SPI_INFO("spi fifo[%d]: 0x%x.\n", i, data32);
  406. spi_data_put(data32);
  407. tx_remaining_bytes -= 4;
  408. }
  409. if (rw_bytes)
  410. {
  411. data32 = 0;
  412. for (i = 0; i < rw_bytes; i++)
  413. {
  414. if (current_transfer->tx_buf)
  415. {
  416. data8 = ((u8 *) current_transfer->tx_buf)[current_transfer->len -
  417. tx_remaining_bytes];
  418. }
  419. else
  420. {
  421. data8 = 0xff;
  422. }
  423. if (SPI_BYTE_TRANSFER == spi_port->transtype)
  424. data32 |= data8 << ((3 - i) * 8);
  425. else if (SPI_WORD_TRANSFER == spi_port->transtype)
  426. {
  427. data32 |= data8 << (i * 8);
  428. }
  429. tx_remaining_bytes -= 1;
  430. }
  431. TLS_DBGPRT_SPI_INFO("spi_fifo: 0x%x.\n", data32);
  432. spi_data_put(data32);
  433. }
  434. return (current_remaining_bytes - tx_remaining_bytes);
  435. }
  436. static u32 spi_get_rxfifo(struct tls_spi_transfer *current_transfer,
  437. u32 current_remaining_bytes)
  438. {
  439. u8 fifo_level;
  440. u8 rw_words;
  441. u8 rw_bytes;
  442. u8 data8 = 0;
  443. u8 i;
  444. u32 data32;
  445. u32 rx_remaining_bytes;
  446. if ((current_transfer == NULL) || (current_remaining_bytes == 0))
  447. return 0;
  448. rx_remaining_bytes = current_remaining_bytes;
  449. spi_get_status(NULL, &fifo_level, NULL);
  450. // TLS_DBGPRT_SPI("rx fifo level: %d.\n", fifo_level);
  451. rw_words = fifo_level / 4;
  452. rw_bytes = fifo_level % 4;
  453. // TLS_DBGPRT_SPI("rx data: %d words, %d bytes.\n", rw_words, rw_bytes);
  454. //下面代码大概10us
  455. for (i = 0; i < rw_words; i++)
  456. {
  457. data32 = spi_data_get();
  458. // TLS_DBGPRT_SPI("rx data[%d](w): 0x%08x.\n", i, data32);
  459. if (current_transfer->rx_buf)
  460. {
  461. if (SPI_BYTE_TRANSFER == spi_port->transtype)
  462. {
  463. data32 = swap_32(data32);
  464. (((u8 *) current_transfer->rx_buf +
  465. (current_transfer->len - rx_remaining_bytes)))[0] = (u8) data32;
  466. (((u8 *) current_transfer->rx_buf +
  467. (current_transfer->len - rx_remaining_bytes)))[1] = (u8) (data32 >> 8);
  468. (((u8 *) current_transfer->rx_buf +
  469. (current_transfer->len - rx_remaining_bytes)))[2] = (u8) (data32 >> 16);
  470. (((u8 *) current_transfer->rx_buf +
  471. (current_transfer->len - rx_remaining_bytes)))[3] = (u8) (data32 >> 24);
  472. }
  473. else if (SPI_WORD_TRANSFER == spi_port->transtype)
  474. {
  475. *((u32 *) ((u8 *) current_transfer->rx_buf +
  476. current_transfer->len - rx_remaining_bytes)) = data32;
  477. }
  478. }
  479. rx_remaining_bytes -= 4;
  480. }
  481. if (rw_bytes)
  482. {
  483. data32 = spi_data_get();
  484. // TLS_DBGPRT_SPI("\nrx data=%x\n",data32);
  485. if (current_transfer->rx_buf)
  486. {
  487. for (i = 0; i < rw_bytes; i++)
  488. {
  489. if (SPI_BYTE_TRANSFER == spi_port->transtype)
  490. data8 = (u8) (data32 >> ((3 - i) * 8));
  491. else if (SPI_WORD_TRANSFER == spi_port->transtype)
  492. data8 = (u8) (data32 >> (i * 8));
  493. // TLS_DBGPRT_SPI("rx data[%d](b): 0x%02x.\n", i, data8);
  494. ((u8 *) current_transfer->rx_buf)[current_transfer->len -rx_remaining_bytes] = data8;
  495. rx_remaining_bytes -= 1;
  496. }
  497. }
  498. else
  499. {
  500. rx_remaining_bytes -= rw_bytes;
  501. }
  502. }
  503. return (current_remaining_bytes - rx_remaining_bytes);
  504. }
  505. static struct tls_spi_transfer *spi_next_transfer(struct tls_spi_message
  506. *current_message)
  507. {
  508. if (current_message == NULL)
  509. {
  510. return NULL;
  511. }
  512. return dl_list_first(&current_message->transfers, struct tls_spi_transfer, transfer_list);
  513. }
  514. static struct tls_spi_message *spi_next_message(void)
  515. {
  516. struct tls_spi_message *current_message;
  517. current_message =
  518. dl_list_first(&spi_port->wait_queue, struct tls_spi_message, queue);
  519. if (current_message == NULL)
  520. {
  521. return NULL;
  522. }
  523. spi_port->current_transfer = spi_next_transfer(current_message);
  524. current_message->status = SPI_MESSAGE_STATUS_INPROGRESS;
  525. return current_message;
  526. }
  527. int gSpiCsFlag = 0;
  528. static void spi_start_transfer(u32 transfer_bytes)
  529. {
  530. if (spi_port->reconfig)
  531. {
  532. TLS_DBGPRT_SPI_INFO("reconfig the spi master controller.\n");
  533. spi_set_mode(spi_port->mode);
  534. spi_set_chipselect_mode(spi_port->cs_active);
  535. spi_set_sclk(spi_port->speed_hz);
  536. spi_port->reconfig = 0;
  537. }
  538. spi_set_sclk_length(transfer_bytes * 8, 0);
  539. // if(0 == gSpiCsFlag)
  540. {
  541. spi_set_chipselect_mode(SPI_CS_ACTIVE_MODE);
  542. }
  543. spi_sclk_start();
  544. }
  545. static void spi_continue_transfer(void)
  546. {
  547. struct tls_spi_message *current_message;
  548. struct tls_spi_transfer *current_transfer;
  549. u32 transfer_bytes;
  550. current_message = spi_port->current_message;
  551. current_transfer = spi_port->current_transfer;
  552. if ((current_message == NULL) || (current_transfer == NULL))
  553. {
  554. return;
  555. }
  556. transfer_bytes =
  557. spi_get_rxfifo(current_transfer, spi_port->current_remaining_bytes);
  558. spi_port->current_remaining_bytes -= transfer_bytes;
  559. if (spi_port->current_remaining_bytes == 0)
  560. {
  561. tls_os_sem_acquire(spi_port->lock, 0);
  562. dl_list_del(&current_transfer->transfer_list);
  563. spi_port->current_transfer =
  564. spi_next_transfer(spi_port->current_message);
  565. if (spi_port->current_transfer == NULL)
  566. {
  567. // tls_sys_clk_set(CPU_CLK_40M);
  568. spi_set_chipselect_mode(SPI_CS_INACTIVE_MODE);
  569. current_message->status = SPI_MESSAGE_STATUS_DONE;
  570. dl_list_del(&current_message->queue);
  571. spi_port->current_message = spi_next_message();
  572. }
  573. tls_os_sem_release(spi_port->lock);
  574. // TLS_DBGPRT_SPI("get the next spi transfer pair.\n");
  575. current_transfer = spi_port->current_transfer;
  576. if (current_transfer != NULL)
  577. {
  578. spi_port->current_remaining_bytes = current_transfer->len;
  579. }
  580. }
  581. transfer_bytes =
  582. spi_fill_txfifo(current_transfer, spi_port->current_remaining_bytes);
  583. if (transfer_bytes)
  584. {
  585. spi_start_transfer(transfer_bytes);
  586. }
  587. if (current_message->status == SPI_MESSAGE_STATUS_DONE)
  588. {
  589. // TLS_DBGPRT_SPI("current spi transaction finish and notify the
  590. // submitter.\n");
  591. current_message->complete(current_message->context);
  592. }
  593. }
  594. static void spi_scheduler(void *data)
  595. {
  596. u8 err;
  597. u32 msg;
  598. u32 transfer_bytes;
  599. struct tls_spi_transfer *current_transfer;
  600. while (1)
  601. {
  602. err = tls_os_queue_receive(spi_port->msg_queue, (void **) &msg, 4, 0);
  603. if (err == TLS_OS_SUCCESS)
  604. {
  605. switch (msg)
  606. {
  607. case SPI_SCHED_MSG_START_ENGINE:
  608. // tls_sys_clk_set(CPU_CLK_80M); //80MHZ
  609. if (spi_port->current_message)
  610. {
  611. TLS_DBGPRT_WARNING
  612. ("spi transaction scheduler is running now!\n");
  613. break;
  614. }
  615. TLS_DBGPRT_SPI_INFO
  616. ("acquire the first transaction message in waiting queue.\n");
  617. tls_os_sem_acquire(spi_port->lock, 0);
  618. spi_port->current_message = spi_next_message();
  619. tls_os_sem_release(spi_port->lock);
  620. // TLS_DBGPRT_SPI("acquire the first transfer pair in the
  621. // current transaction message.\n");
  622. current_transfer = spi_port->current_transfer;
  623. if (current_transfer == NULL)
  624. {
  625. break;
  626. }
  627. spi_port->current_remaining_bytes = current_transfer->len;
  628. // TLS_DBGPRT_SPI("current transfer lenght - %d.\n",
  629. // spi_port->current_remaining_bytes);
  630. TLS_DBGPRT_SPI_INFO("fill the tx fifo.\n");
  631. transfer_bytes = spi_fill_txfifo(current_transfer, spi_port->current_remaining_bytes);
  632. TLS_DBGPRT_SPI_INFO("start the spi transfer - %d.\n", transfer_bytes);
  633. spi_start_transfer(transfer_bytes);
  634. break;
  635. case SPI_SCHED_MSG_TX_FIFO_READY:
  636. TLS_DBGPRT_SPI_INFO("process SPI_SCHED_MSG_TX_FIFO_READY.\n");
  637. break;
  638. case SPI_SCHED_MSG_RX_FIFO_READY:
  639. TLS_DBGPRT_SPI_INFO("process SPI_SCHED_MSG_RX_FIFO_READY.\n");
  640. break;
  641. case SPI_SCHED_MSG_TRANSFER_COMPLETE:
  642. spi_continue_transfer();
  643. break;
  644. case SPI_SCHED_MSG_EXIT:
  645. break;
  646. default:
  647. break;
  648. }
  649. }
  650. }
  651. }
  652. ATTRIBUTE_ISR void SPI_LS_IRQHandler(void)
  653. {
  654. u32 int_status;
  655. u32 int_mask;
  656. csi_kernel_intrpt_enter();
  657. int_status = spi_get_int_status();
  658. // printf("\nspi int sta=%x\n",int_status);
  659. spi_clear_int_status(int_status);
  660. int_mask = spi_int_mask();
  661. int_status &= ~int_mask;
  662. // printf("spi interrupt - 0x%x.\n", int_status);
  663. if (int_status & SPI_INT_TX_FIFO_RDY)
  664. {
  665. tls_spi_queue_send(SPI_SCHED_MSG_TX_FIFO_READY);
  666. }
  667. if (int_status & SPI_INT_RX_FIFO_RDY)
  668. {
  669. tls_spi_queue_send(SPI_SCHED_MSG_RX_FIFO_READY);
  670. }
  671. if (int_status & SPI_INT_TRANSFER_DONE)
  672. {
  673. if (SPI_WORD_TRANSFER == spi_port->transtype)
  674. {
  675. spi_continue_transfer();
  676. }
  677. else
  678. {
  679. tls_spi_queue_send(SPI_SCHED_MSG_TRANSFER_COMPLETE);
  680. }
  681. }
  682. csi_kernel_intrpt_exit();
  683. }
  684. /**
  685. * @brief This function is used to setup the spi CPOL,CPHA,cs signal and clock.
  686. *
  687. * @param[in] mode is CPOL and CPHA type defined in TLS_SPI_MODE_0 to TLS_SPI_MODE_3
  688. * @param[in] cs_active is cs mode, defined as TLS_SPI_CS_LOW or TLS_SPI_CS_HIGH
  689. * @param[in] fclk is spi clock,the unit is HZ.
  690. *
  691. * @retval TLS_SPI_STATUS_OK if setup success
  692. * @retval TLS_SPI_STATUS_EMODENOSUPPORT if mode is not support
  693. * @retval TLS_SPI_STATUS_EINVAL if cs_active is not support
  694. * @retval TLS_SPI_STATUS_ECLKNOSUPPORT if fclk is not support
  695. *
  696. * @note None
  697. */
  698. int tls_spi_setup(u8 mode, u8 cs_active, u32 fclk)
  699. {
  700. tls_sys_clk sysclk;
  701. if ((spi_port->mode == mode) && (spi_port->cs_active == cs_active)
  702. && (spi_port->speed_hz == fclk))
  703. {
  704. TLS_DBGPRT_WARNING
  705. ("@mode, @cs_activer, @fclk is the same as settings of the current spi master driver!\n");
  706. return TLS_SPI_STATUS_OK;
  707. }
  708. switch (mode)
  709. {
  710. case TLS_SPI_MODE_0:
  711. case TLS_SPI_MODE_1:
  712. case TLS_SPI_MODE_2:
  713. case TLS_SPI_MODE_3:
  714. spi_port->mode = mode;
  715. break;
  716. default:
  717. TLS_DBGPRT_ERR("@mode is invalid!\n");
  718. return TLS_SPI_STATUS_EMODENOSUPPORT;
  719. }
  720. if ((cs_active != TLS_SPI_CS_HIGH) && (cs_active != TLS_SPI_CS_LOW))
  721. {
  722. TLS_DBGPRT_ERR("@cs_active is invalid!\n");
  723. return TLS_SPI_STATUS_EINVAL;
  724. }
  725. else
  726. {
  727. spi_port->cs_active = cs_active;
  728. }
  729. tls_sys_clk_get(&sysclk);
  730. if ((fclk < TLS_SPI_FCLK_MIN) || (fclk > sysclk.apbclk*UNIT_MHZ/2)) //TLS_SPI_FCLK_MAX
  731. {
  732. TLS_DBGPRT_ERR("@fclk is invalid!\n");
  733. return TLS_SPI_STATUS_ECLKNOSUPPORT;
  734. }
  735. else
  736. {
  737. spi_port->speed_hz = fclk;
  738. }
  739. #ifdef SPI_USE_DMA
  740. if (SPI_DMA_TRANSFER == spi_port->transtype)
  741. {
  742. SpiMasterInit(mode, TLS_SPI_CS_LOW, fclk);
  743. return TLS_SPI_STATUS_OK;
  744. }
  745. #endif
  746. spi_port->reconfig = 1;
  747. return TLS_SPI_STATUS_OK;
  748. }
  749. /**
  750. * @brief This function is used to synchronous write command then read data by SPI.
  751. *
  752. * @param[in] txbuf is the write data buffer.
  753. * @param[in] n_tx is the write data length.
  754. * @param[in] rxbuf is the read data buffer.
  755. * @param[in] n_rx is the read data length.
  756. *
  757. * @retval TLS_SPI_STATUS_OK if write success.
  758. * @retval TLS_SPI_STATUS_EINVAL if argument is invalid.
  759. * @retval TLS_SPI_STATUS_ENOMEM if there is no enough memory.
  760. * @retval TLS_SPI_STATUS_ESHUTDOWN if SPI driver does not installed.
  761. *
  762. * @note None
  763. */
  764. int tls_spi_read_with_cmd(const u8 * txbuf, u32 n_tx, u8 * rxbuf, u32 n_rx)
  765. {
  766. int status;
  767. struct tls_spi_message message;
  768. struct tls_spi_transfer x[2];
  769. if ((txbuf == NULL) || (n_tx == 0) || (rxbuf == NULL) || (n_rx == 0))
  770. {
  771. return TLS_SPI_STATUS_EINVAL;
  772. }
  773. #ifdef SPI_USE_DMA
  774. if (SPI_DMA_TRANSFER == spi_port->transtype)
  775. {
  776. if (n_rx > SPI_DMA_BUF_MAX_SIZE || n_tx > SPI_DMA_CMD_MAX_SIZE)
  777. {
  778. TLS_DBGPRT_ERR("\nread length too long\n");
  779. return TLS_SPI_STATUS_EINVAL;
  780. }
  781. tls_os_sem_acquire(spi_port->lock, 0);
  782. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_LSPI);
  783. if (SPI_DMA_CMD_ADDR && SPI_DMA_BUF_ADDR)
  784. {
  785. MEMCPY((u8 *) SPI_DMA_CMD_ADDR, txbuf, n_tx);
  786. SpiDmaBlockRead((u8 *) SPI_DMA_BUF_ADDR, n_rx, (u8 *) SPI_DMA_CMD_ADDR,
  787. n_tx);
  788. MEMCPY(rxbuf, (u8 *) SPI_DMA_BUF_ADDR, n_rx);
  789. status = TLS_SPI_STATUS_OK;
  790. }
  791. else
  792. {
  793. status = TLS_SPI_STATUS_ENOMEM;
  794. }
  795. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_LSPI);
  796. tls_os_sem_release(spi_port->lock);
  797. return status;
  798. }
  799. #endif
  800. spi_message_init(&message);
  801. memset(x, 0, sizeof(x));
  802. if (n_tx)
  803. {
  804. x[0].len = n_tx;
  805. x[0].tx_buf = txbuf;
  806. dl_list_add_tail(&message.transfers, &x[0].transfer_list);
  807. }
  808. if (n_rx)
  809. {
  810. x[1].len = n_rx;
  811. x[1].rx_buf = rxbuf;
  812. dl_list_add_tail(&message.transfers, &x[1].transfer_list);
  813. }
  814. /* do the i/o. */
  815. status = tls_spi_sync(&message);
  816. return status;
  817. }
  818. /**
  819. * @brief This function is used to synchronous read data by SPI.
  820. *
  821. * @param[in] buf is the buffer for saving SPI data.
  822. * @param[in] len is the data length.
  823. *
  824. * @retval TLS_SPI_STATUS_OK if write success.
  825. * @retval TLS_SPI_STATUS_EINVAL if argument is invalid.
  826. * @retval TLS_SPI_STATUS_ENOMEM if there is no enough memory.
  827. * @retval TLS_SPI_STATUS_ESHUTDOWN if SPI driver does not installed.
  828. *
  829. * @note None
  830. */
  831. int tls_spi_read(u8 * buf, u32 len)
  832. {
  833. struct tls_spi_transfer t;
  834. struct tls_spi_message m;
  835. if ((buf == NULL) || (len == 0))
  836. {
  837. return TLS_SPI_STATUS_EINVAL;
  838. }
  839. #ifdef SPI_USE_DMA
  840. if (SPI_DMA_TRANSFER == spi_port->transtype)
  841. {
  842. u32 data32 = 0;
  843. u16 rxBitLen;
  844. u32 rdval1 = 0;
  845. u32 i;
  846. tls_os_sem_acquire(spi_port->lock, 0);
  847. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_LSPI);
  848. // 直接传输,这样做的原因是DMA不能连续读取4个字节以内的数据,SPI FIFO读取单位为word
  849. if (len <= 4)
  850. {
  851. SPIM_CHCFG_REG = SPI_CLEAR_FIFOS;
  852. while (SPIM_CHCFG_REG & SPI_CLEAR_FIFOS);
  853. rxBitLen = 8 * len;
  854. rdval1 =
  855. SPI_FORCE_SPI_CS_OUT | SPI_CS_LOW | SPI_TX_CHANNEL_ON |
  856. SPI_RX_CHANNEL_ON | SPI_CONTINUE_MODE | SPI_START |
  857. SPI_VALID_CLKS_NUM(rxBitLen);
  858. SPIM_CHCFG_REG = rdval1;
  859. spiWaitIdle();
  860. SPIM_CHCFG_REG |= SPI_CS_HIGH;
  861. data32 = SPIM_RXDATA_REG;
  862. for (i = 0; i < len; i++)
  863. {
  864. *(buf + i) = (u8) (data32 >> i * 8);
  865. }
  866. SPIM_CHCFG_REG = 0x00000000;
  867. SPIM_MODECFG_REG = 0x00000000;
  868. }
  869. else // DMA传输
  870. {
  871. if (len > SPI_DMA_BUF_MAX_SIZE)
  872. {
  873. TLS_DBGPRT_ERR("\nread len too long\n");
  874. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_LSPI);
  875. tls_os_sem_release(spi_port->lock);
  876. return TLS_SPI_STATUS_EINVAL;
  877. }
  878. if (SPI_DMA_BUF_ADDR)
  879. {
  880. SpiDmaBlockRead((u8 *) SPI_DMA_BUF_ADDR, len, NULL, 0);
  881. MEMCPY(buf, (u8 *) SPI_DMA_BUF_ADDR, len);
  882. }
  883. else
  884. {
  885. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_LSPI);
  886. tls_os_sem_release(spi_port->lock);
  887. return TLS_SPI_STATUS_ENOMEM;
  888. }
  889. }
  890. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_LSPI);
  891. tls_os_sem_release(spi_port->lock);
  892. return TLS_SPI_STATUS_OK;
  893. }
  894. #endif
  895. memset(&t, 0, sizeof(t));
  896. t.rx_buf = buf;
  897. t.len = len;
  898. spi_message_init(&m);
  899. dl_list_add_tail(&m.transfers, &t.transfer_list);
  900. return tls_spi_sync(&m);
  901. }
  902. /**
  903. * @brief This function is used to synchronous write data by SPI.
  904. *
  905. * @param[in] buf is the user data.
  906. * @param[in] len is the data length.
  907. *
  908. * @retval TLS_SPI_STATUS_OK if write success.
  909. * @retval TLS_SPI_STATUS_EINVAL if argument is invalid.
  910. * @retval TLS_SPI_STATUS_ENOMEM if there is no enough memory.
  911. * @retval TLS_SPI_STATUS_ESHUTDOWN if SPI driver does not installed.
  912. *
  913. * @note None
  914. */
  915. int tls_spi_write(const u8 * buf, u32 len)
  916. {
  917. struct tls_spi_transfer t;
  918. struct tls_spi_message m;
  919. if ((buf == NULL) || (len == 0))
  920. {
  921. return TLS_SPI_STATUS_EINVAL;
  922. }
  923. #ifdef SPI_USE_DMA
  924. if (SPI_DMA_TRANSFER == spi_port->transtype)
  925. {
  926. u32 data32 = 0;
  927. u16 txBitLen;
  928. u32 rdval1 = 0;
  929. u32 i;
  930. tls_os_sem_acquire(spi_port->lock, 0);
  931. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_LSPI);
  932. if (len <= 4) // 直接传输,这样做的原因是DMA不能连续传输少于4个字节的数据,SPI
  933. {
  934. SPIM_CHCFG_REG = SPI_CLEAR_FIFOS;
  935. while (SPIM_CHCFG_REG & SPI_CLEAR_FIFOS);
  936. for (i = 0; i < len; i++)
  937. {
  938. data32 |= (((u8) (buf[i])) << (i * 8));
  939. }
  940. SPIM_TXDATA_REG = data32;
  941. txBitLen = 8 * len;
  942. rdval1 =
  943. SPI_FORCE_SPI_CS_OUT | SPI_CS_LOW | SPI_TX_CHANNEL_ON |
  944. SPI_RX_CHANNEL_ON | SPI_CONTINUE_MODE | SPI_START |
  945. SPI_VALID_CLKS_NUM(txBitLen);
  946. SPIM_CHCFG_REG = rdval1;
  947. spiWaitIdle();
  948. SPIM_CHCFG_REG |= SPI_CS_HIGH;
  949. SPIM_CHCFG_REG = 0x00000000;
  950. SPIM_MODECFG_REG = 0x00000000;
  951. }
  952. else // DMA传输
  953. {
  954. if (len > SPI_DMA_BUF_MAX_SIZE)
  955. {
  956. TLS_DBGPRT_ERR("\nwrite len too long\n");
  957. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_LSPI);
  958. tls_os_sem_release(spi_port->lock);
  959. return TLS_SPI_STATUS_EINVAL;
  960. }
  961. if (SPI_DMA_BUF_ADDR)
  962. {
  963. MEMCPY((u8 *) SPI_DMA_BUF_ADDR, buf, len);
  964. SpiDmaBlockWrite((u8 *) SPI_DMA_BUF_ADDR, len, 0, 0);
  965. }
  966. else
  967. {
  968. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_LSPI);
  969. tls_os_sem_release(spi_port->lock);
  970. return TLS_SPI_STATUS_ENOMEM;
  971. }
  972. }
  973. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_LSPI);
  974. tls_os_sem_release(spi_port->lock);
  975. return TLS_SPI_STATUS_OK;
  976. }
  977. #endif
  978. memset(&t, 0, sizeof(t));
  979. t.tx_buf = buf;
  980. t.len = len;
  981. spi_message_init(&m);
  982. dl_list_add_tail(&m.transfers, &t.transfer_list);
  983. return tls_spi_sync(&m);
  984. }
  985. /**
  986. * @brief This function is used to synchronous write 32bit command then write data by SPI.
  987. *
  988. * @param[in] cmd is the command data.
  989. * @param[in] n_cmd is the command len,can not bigger than four
  990. * @param[in] txbuf is the write data buffer.
  991. * @param[in] n_tx is the write data length.
  992. *
  993. * @retval TLS_SPI_STATUS_OK if write success.
  994. * @retval TLS_SPI_STATUS_EINVAL if argument is invalid.
  995. * @retval TLS_SPI_STATUS_ENOMEM if there is no enough memory.
  996. * @retval TLS_SPI_STATUS_ESHUTDOWN if SPI driver does not installed.
  997. *
  998. * @note None
  999. */
  1000. int tls_spi_write_with_cmd(const u8 * cmd, u32 n_cmd, const u8 * txbuf,
  1001. u32 n_tx)
  1002. {
  1003. int status;
  1004. struct tls_spi_message message;
  1005. struct tls_spi_transfer x[2];
  1006. if ((cmd == NULL) || (n_cmd == 0) || (txbuf == NULL) || (n_tx == 0))
  1007. {
  1008. return TLS_SPI_STATUS_EINVAL;
  1009. }
  1010. #ifdef SPI_USE_DMA
  1011. if (SPI_DMA_TRANSFER == spi_port->transtype)
  1012. {
  1013. if (n_tx > SPI_DMA_BUF_MAX_SIZE)
  1014. {
  1015. TLS_DBGPRT_ERR("\nwriten len too long\n");
  1016. return TLS_SPI_STATUS_EINVAL;
  1017. }
  1018. tls_os_sem_acquire(spi_port->lock, 0);
  1019. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_LSPI);
  1020. if (SPI_DMA_BUF_ADDR)
  1021. {
  1022. MEMCPY((u8 *) SPI_DMA_BUF_ADDR, (u8 *) cmd, n_cmd);
  1023. MEMCPY((u8 *) (SPI_DMA_BUF_ADDR + n_cmd), txbuf, n_tx);
  1024. SpiDmaBlockWrite((u8 *) SPI_DMA_BUF_ADDR, (n_cmd + n_tx), 0, 0);
  1025. status = TLS_SPI_STATUS_OK;
  1026. }
  1027. else
  1028. {
  1029. status = TLS_SPI_STATUS_ENOMEM;
  1030. }
  1031. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_LSPI);
  1032. tls_os_sem_release(spi_port->lock);
  1033. return status;
  1034. }
  1035. #endif
  1036. spi_message_init(&message);
  1037. memset(x, 0, sizeof(x));
  1038. if (n_cmd)
  1039. {
  1040. x[0].len = n_cmd;
  1041. x[0].tx_buf = (const void *) cmd;
  1042. dl_list_add_tail(&message.transfers, &x[0].transfer_list);
  1043. }
  1044. if (n_tx)
  1045. {
  1046. x[1].len = n_tx;
  1047. x[1].tx_buf = txbuf;
  1048. dl_list_add_tail(&message.transfers, &x[1].transfer_list);
  1049. }
  1050. /* do the i/o. */
  1051. status = tls_spi_sync(&message);
  1052. return status;
  1053. }
  1054. /**
  1055. * @brief
  1056. *
  1057. * @param message
  1058. *
  1059. * @return
  1060. */
  1061. int tls_spi_sync(struct tls_spi_message *message)
  1062. {
  1063. int status;
  1064. u8 err;
  1065. tls_os_sem_t *sem;
  1066. err = tls_os_sem_create(&sem, 0);
  1067. if (err != TLS_OS_SUCCESS)
  1068. {
  1069. TLS_DBGPRT_ERR
  1070. ("create spi transaction synchronizing semaphore fail!\n");
  1071. return TLS_SPI_STATUS_ENOMEM;
  1072. }
  1073. message->context = (void *) sem;
  1074. message->complete = spi_complete;
  1075. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_LSPI);
  1076. status = tls_spi_async(message);
  1077. if (status == TLS_SPI_STATUS_OK)
  1078. {
  1079. TLS_DBGPRT_SPI_INFO("waiting spi transaction finishing!\n");
  1080. tls_os_sem_acquire(sem, 0);
  1081. }
  1082. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_LSPI);
  1083. tls_os_sem_delete(sem);
  1084. message->context = NULL;
  1085. message->complete = NULL;
  1086. return status;
  1087. }
  1088. /**
  1089. * @brief
  1090. *
  1091. * @param message
  1092. *
  1093. * @return
  1094. */
  1095. int tls_spi_async(struct tls_spi_message *message)
  1096. {
  1097. u8 need_sched;
  1098. struct tls_spi_transfer *transfer;
  1099. if (spi_port == NULL)
  1100. {
  1101. TLS_DBGPRT_ERR("spi master driver module not beed installed!\n");
  1102. return TLS_SPI_STATUS_ESHUTDOWN;
  1103. }
  1104. if ((message == NULL) || (dl_list_empty(&message->transfers)))
  1105. {
  1106. TLS_DBGPRT_ERR("@message is NULL or @message->transfers is empty!\n");
  1107. return TLS_SPI_STATUS_EINVAL;
  1108. }
  1109. dl_list_for_each(transfer, &message->transfers, struct tls_spi_transfer,
  1110. transfer_list)
  1111. {
  1112. if (transfer->len == 0)
  1113. {
  1114. TLS_DBGPRT_ERR("\"@transfer->len\" belong to @message is 0!\n");
  1115. return TLS_SPI_STATUS_EINVAL;
  1116. }
  1117. }
  1118. tls_os_sem_acquire(spi_port->lock, 0);
  1119. if (dl_list_empty(&spi_port->wait_queue))
  1120. {
  1121. need_sched = 1;
  1122. }
  1123. else
  1124. {
  1125. need_sched = 0;
  1126. }
  1127. message->status = SPI_MESSAGE_STATUS_IDLE;
  1128. dl_list_add_tail(&spi_port->wait_queue, &message->queue);
  1129. tls_os_sem_release(spi_port->lock);
  1130. if (need_sched == 1)
  1131. {
  1132. tls_spi_queue_send(SPI_SCHED_MSG_START_ENGINE);
  1133. }
  1134. return TLS_SPI_STATUS_OK;
  1135. }
  1136. /**
  1137. * @brief This function is used to initialize the SPI master driver.
  1138. *
  1139. * @param[in] None
  1140. *
  1141. * @retval TLS_SPI_STATUS_OK if initialize success
  1142. * @retval TLS_SPI_STATUS_EBUSY if SPI is already initialized
  1143. * @retval TLS_SPI_STATUS_ENOMEM if malloc SPI memory fail
  1144. *
  1145. * @note None
  1146. */
  1147. int tls_spi_init(void)
  1148. {
  1149. u8 err;
  1150. struct tls_spi_port *port;
  1151. if (spi_port != NULL)
  1152. {
  1153. TLS_DBGPRT_ERR("spi driver module has been installed!\n");
  1154. return TLS_SPI_STATUS_EBUSY;
  1155. }
  1156. TLS_DBGPRT_SPI_INFO("initialize spi master driver module.\n");
  1157. port = (struct tls_spi_port *) tls_mem_alloc(sizeof(struct tls_spi_port));
  1158. if (port == NULL)
  1159. {
  1160. TLS_DBGPRT_ERR("allocate \"struct tls_spi_port\" fail!\n");
  1161. return TLS_SPI_STATUS_ENOMEM;
  1162. }
  1163. memset(port, 0, sizeof(struct tls_spi_port));
  1164. err = tls_os_sem_create(&port->lock, 1);
  1165. if (err != TLS_OS_SUCCESS)
  1166. {
  1167. TLS_DBGPRT_ERR("create semaphore @spi_port->lock fail!\n");
  1168. tls_mem_free(port);
  1169. return TLS_SPI_STATUS_ENOMEM;
  1170. }
  1171. port->speed_hz = SPI_DEFAULT_SPEED; /* 默认2M */
  1172. port->cs_active = SPI_CS_ACTIVE_MODE;
  1173. port->mode = SPI_DEFAULT_MODE; /* CPHA = 0,CPOL = 0 */
  1174. port->reconfig = 0;
  1175. dl_list_init(&port->wait_queue);
  1176. port->current_message = NULL;
  1177. port->current_remaining_transfer = 0;
  1178. port->current_transfer = NULL;
  1179. port->current_remaining_bytes = 0;
  1180. spi_port = port;
  1181. TLS_DBGPRT_SPI_INFO("initialize spi master controller.\n");
  1182. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_LSPI);
  1183. spi_clear_fifo();
  1184. spi_set_endian(1);
  1185. tls_spi_trans_type(SPI_BYTE_TRANSFER);
  1186. spi_set_mode(spi_port->mode);
  1187. spi_set_chipselect_mode(SPI_CS_INACTIVE_MODE); /* cs=1 ,片选无效 */
  1188. spi_force_cs_out(1); /* 片选由软件控制 */
  1189. spi_set_sclk(spi_port->speed_hz);
  1190. spi_set_tx_trigger_level(0);
  1191. spi_set_rx_trigger_level(7);
  1192. spi_set_rx_channel(1);
  1193. spi_set_tx_channel(1);
  1194. spi_unmask_int(SPI_INT_TRANSFER_DONE /* | SPI_INT_RX_FIFO_RDY |SPI_INT_TX_FIFO_RDY */ );
  1195. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_LSPI);
  1196. TLS_DBGPRT_SPI_INFO("register spi master interrupt handler.\n");
  1197. tls_irq_enable(SPI_LS_IRQn);
  1198. TLS_DBGPRT_SPI_INFO("spi master driver module initialization finish.\n");
  1199. return TLS_SPI_STATUS_OK;
  1200. }
  1201. int tls_spi_task_init(void)
  1202. {
  1203. u8 err;
  1204. if (NULL == spi_port)
  1205. {
  1206. return TLS_SPI_STATUS_ENOMEM;
  1207. }
  1208. if (spi_port->msg_queue)
  1209. {
  1210. return TLS_SPI_STATUS_OK;
  1211. }
  1212. err = tls_os_queue_create(&spi_port->msg_queue, MSG_QUEUE_SIZE);
  1213. if (err != TLS_OS_SUCCESS)
  1214. {
  1215. TLS_DBGPRT_ERR("create message queue @spi_port->msg_queue fail!\n");
  1216. return TLS_SPI_STATUS_ENOMEM;
  1217. }
  1218. spi_scheduler_stk = tls_mem_alloc(SPI_SCHEDULER_STK_SIZE * sizeof(u32));
  1219. if (NULL == spi_scheduler_stk)
  1220. {
  1221. //tls_os_queue_delete(spi_port->msg_queue);
  1222. TLS_DBGPRT_ERR("spi_scheduler_stk allocated fail!\n");
  1223. return TLS_SPI_STATUS_ENOMEM;
  1224. }
  1225. err = tls_os_task_create(NULL, "hostspi",
  1226. spi_scheduler,
  1227. (void *) spi_port,
  1228. (void *) spi_scheduler_stk,
  1229. SPI_SCHEDULER_STK_SIZE * sizeof(u32),
  1230. TLS_SPI_SCHEDULER_TASK_PRIO, 0);
  1231. if (err != TLS_OS_SUCCESS)
  1232. {
  1233. TLS_DBGPRT_ERR("create spi master driver scheduler task fail!\n");
  1234. //tls_os_queue_delete(spi_port->msg_queue);
  1235. tls_mem_free(spi_scheduler_stk);
  1236. spi_scheduler_stk = NULL;
  1237. return TLS_SPI_STATUS_ENOMEM;
  1238. }
  1239. return TLS_SPI_STATUS_OK;
  1240. }
  1241. void tls_spi_queue_send(u32 msg)
  1242. {
  1243. if (TLS_SPI_STATUS_OK == tls_spi_task_init())
  1244. {
  1245. tls_os_queue_send(spi_port->msg_queue,
  1246. (void *) msg, 4);
  1247. }
  1248. }
  1249. /**
  1250. * @brief
  1251. *
  1252. * @return
  1253. */
  1254. int tls_spi_exit(void)
  1255. {
  1256. TLS_DBGPRT_SPI_INFO("Not support spi master driver module uninstalled!\n");
  1257. return TLS_SPI_STATUS_EPERM;
  1258. }
  1259. /**********************************************************************************************************
  1260. * Description: This function is used to select SPI slave type.
  1261. *
  1262. * Arguments : slave is the slave type,defined as follow:
  1263. * slave == SPI_SLAVE_FLASH :flash
  1264. * slave == SPI_SLAVE_CARD : sd card
  1265. *
  1266. * Returns : Before communicate with different SPI device, must call the function.
  1267. **********************************************************************************************************/
  1268. void tls_spi_slave_sel(u16 slave)
  1269. {
  1270. // u16 ret;
  1271. /*gpio0控制cs信号*/
  1272. tls_gpio_cfg((enum tls_io_name) SPI_SLAVE_CONTROL_PIN, WM_GPIO_DIR_OUTPUT,
  1273. WM_GPIO_ATTR_FLOATING);
  1274. if (SPI_SLAVE_FLASH == slave)
  1275. {
  1276. tls_gpio_write((enum tls_io_name) SPI_SLAVE_CONTROL_PIN, 0);
  1277. // ret = tls_gpio_read(SPI_SLAVE_CONTROL_PIN);
  1278. // printf("\nflash gpio 0 ===%d\n",ret);
  1279. }
  1280. else if (SPI_SLAVE_CARD == slave)
  1281. {
  1282. tls_gpio_write((enum tls_io_name) SPI_SLAVE_CONTROL_PIN, 1);
  1283. // ret = tls_gpio_read(SPI_SLAVE_CONTROL_PIN);
  1284. // printf("\ncard gpio 0 ===%d\n",ret);
  1285. }
  1286. }
  1287. /**********************************************************************************************************
  1288. * Description: This function is used to spi data tx/rx without irq.
  1289. *
  1290. * Arguments : data_out-------data to be sent to slave
  1291. * data_in -------data to be received from slave
  1292. * num_out -------number to be sent to slave unit:byte
  1293. * num_in -------number to be received from slave unit:byte
  1294. * Returns : Before communicate with different SPI device, must call the function.
  1295. **********************************************************************************************************/
  1296. int32_t tls_spi_xfer(const void *data_out, void *data_in, uint32_t num_out, uint32_t num_in)
  1297. {
  1298. int ret = 0;
  1299. uint32_t length = 0;
  1300. uint32_t remain_length ;
  1301. uint32_t int_status;
  1302. struct tls_spi_transfer tls_transfer;
  1303. uint32_t tot_num = 0;
  1304. if (data_in == NULL || num_out == 0 || num_in == 0 || data_out == NULL) {
  1305. return -1;
  1306. }
  1307. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_LSPI);
  1308. tls_transfer.tx_buf = data_out;
  1309. tls_transfer.rx_buf = data_in;
  1310. tot_num = (num_out > num_in) ? num_out : num_in;
  1311. remain_length = tot_num;
  1312. tls_transfer.len = tot_num;
  1313. tls_irq_disable(SPI_LS_IRQn);
  1314. //spi_set_rx_channel(1);
  1315. //spi_set_tx_channel(1);
  1316. length = spi_fill_txfifo(&tls_transfer, remain_length);
  1317. spi_set_sclk_length(length * 8, 0);
  1318. spi_sclk_start();
  1319. while (remain_length > 0)
  1320. {
  1321. while (spi_get_busy_status() == 1);
  1322. length = spi_get_rxfifo(&tls_transfer, remain_length);
  1323. remain_length -= length;
  1324. if (remain_length == 0)
  1325. {
  1326. while (spi_get_busy_status() == 1);
  1327. break;
  1328. }
  1329. while (spi_get_busy_status() == 1);
  1330. length = spi_fill_txfifo(&tls_transfer, remain_length);
  1331. if (length)
  1332. {
  1333. spi_set_sclk_length(length * 8, 0);
  1334. spi_sclk_start();
  1335. }
  1336. }
  1337. while (spi_get_busy_status() == 1);
  1338. int_status = spi_get_int_status();
  1339. spi_clear_int_status(int_status);
  1340. tls_irq_enable(SPI_LS_IRQn);
  1341. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_LSPI);
  1342. return (ret == TLS_SPI_STATUS_OK) ? 0 : -1;
  1343. }
  1344. int tls_spi_set_speed(u32 fclk) {
  1345. if (spi_port->speed_hz == fclk)
  1346. return 0;
  1347. tls_sys_clk sysclk;
  1348. tls_sys_clk_get(&sysclk);
  1349. if ((fclk < TLS_SPI_FCLK_MIN) || (fclk > sysclk.apbclk*UNIT_MHZ/2)) //TLS_SPI_FCLK_MAX
  1350. {
  1351. TLS_DBGPRT_ERR("@fclk is invalid!\n");
  1352. return TLS_SPI_STATUS_ECLKNOSUPPORT;
  1353. }
  1354. else
  1355. {
  1356. spi_port->speed_hz = fclk;
  1357. }
  1358. #ifdef SPI_USE_DMA
  1359. if (SPI_DMA_TRANSFER == spi_port->transtype)
  1360. {
  1361. SpiMasterInit(spi_port->mode, TLS_SPI_CS_LOW, fclk);
  1362. return TLS_SPI_STATUS_OK;
  1363. }
  1364. #endif
  1365. spi_port->reconfig = 1;
  1366. return TLS_SPI_STATUS_OK;
  1367. }