spi.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  1. /**
  2. * @file spi.c
  3. * @author chipsea
  4. * @brief Contains all functions support for spi driver
  5. * @version 0.1
  6. * @date 2020-11-30
  7. * @copyright Copyright (c) 2020, CHIPSEA Co., Ltd.
  8. * @note
  9. */
  10. #include "sdk_config.h"
  11. #include "rom_sym_def.h"
  12. #include "gpio.h"
  13. #include "error.h"
  14. #include <string.h>
  15. #include "pwrmgr.h"
  16. #include "clock.h"
  17. #include "log.h"
  18. #include "spi.h"
  19. #include "dma.h"
  20. #include "jump_function.h"
  21. #define DMAC_USE 1
  22. /**
  23. * @struct SpiBufCtl_t
  24. * @brief spi buffer information
  25. */
  26. typedef struct {
  27. uint16_t bufOffset;
  28. uint16_t bufSize;
  29. uint8_t* buf;
  30. } SpiBufCtl_t;
  31. /**
  32. * @struct SpiCtl_t
  33. * @brief spi control information
  34. */
  35. typedef struct {
  36. bool enable;
  37. spi_Cfg_t cfg;
  38. uint8_t busy;
  39. SpiBufCtl_t txBufCtl;
  40. SpiBufCtl_t rxBufCtl; //It's valid when role is master
  41. } SpiCtl_t;
  42. static SpiCtl_t spiCtl[2];
  43. #define SPI_USE_TIMEOUT 1
  44. #define SPI_OP_TIMEOUT 1000 //100ms for an Byte operation
  45. #if(SPI_USE_TIMEOUT == 1)
  46. #define SPI_INIT_TOUT(to) int to = hal_systick()
  47. #define SPI_CHECK_TOUT(to, timeout) {if(hal_ms_intv(to) > timeout){return ERR_TIMEOUT;}}
  48. #else
  49. #define SPI_INIT_TOUT(to)
  50. #define SPI_CHECK_TOUT(to, timeout)
  51. #endif
  52. static void HalSpiWriteFifo(AP_SSI_TypeDef* SPIx, uint8_t len, uint8_t* tx_rx_ptr)
  53. {
  54. uint8_t i=0;
  55. HAL_ENTER_CRITICAL_SECTION();
  56. while(i<len)
  57. {
  58. SPIx->DataReg = *(tx_rx_ptr+i);
  59. i++;
  60. }
  61. HAL_EXIT_CRITICAL_SECTION();
  62. }
  63. void HalSpiIntEnable(SPI_INDEX_e index, uint32_t mask)
  64. {
  65. if(index == SPI0)
  66. {
  67. AP_SPI0->IMR = mask & 0x11;
  68. JUMP_FUNCTION(SPI0_IRQ_HANDLER) = (uint32_t)&HalSpi0IRQHandler;
  69. }
  70. else
  71. {
  72. AP_SPI1->IMR = mask & 0x11;
  73. JUMP_FUNCTION(SPI1_IRQ_HANDLER) = (uint32_t)&HalSpi1IRQHandler;
  74. }
  75. NVIC_EnableIRQ((IRQn_Type)(SPI0_IRQn + index));
  76. NVIC_SetPriority((IRQn_Type)(SPI0_IRQn + index), IRQ_PRIO_HAL);
  77. }
  78. static void HalSpiIntDisable(SPI_INDEX_e index)
  79. {
  80. NVIC_DisableIRQ((IRQn_Type)(SPI0_IRQn + index));
  81. if(index == SPI0)
  82. {
  83. AP_SPI0->IMR = 0x00;
  84. }
  85. else
  86. {
  87. AP_SPI1->IMR = 0x00;
  88. }
  89. }
  90. static void HalSpiMasterHandle(SPI_INDEX_e id, AP_SSI_TypeDef* SPIx)
  91. {
  92. volatile uint8_t spi_irs_status;
  93. spi_evt_t evt;
  94. uint8_t i, cnt;
  95. spi_irs_status = SPIx->ISR;
  96. if(spi_irs_status & TRANSMIT_FIFO_EMPTY)
  97. {
  98. cnt = 8 - SPIx->TXFLR;
  99. for(i = 0; i< cnt; i++)
  100. {
  101. if(spiCtl[id].txBufCtl.bufOffset >= spiCtl[id].txBufCtl.bufSize)
  102. {
  103. SPIx->IMR = 0x10;
  104. if(spiCtl[id].cfg.force_cs == true)
  105. {
  106. while(SPIx->SR & 0x01);
  107. HalGpioFmuxEnable(spiCtl[id].cfg.ssn_pin, Bit_ENABLE);
  108. }
  109. spiCtl[id].busy = false;
  110. evt.id = id;
  111. evt.evt = SPI_TX_COMPLETED;
  112. if(spiCtl[id].cfg.evt_handler)
  113. {
  114. spiCtl[id].cfg.evt_handler(&evt);
  115. }
  116. break;
  117. }
  118. if(spiCtl[id].txBufCtl.buf)
  119. {
  120. SPIx->DataReg = spiCtl[id].txBufCtl.buf[spiCtl[id].txBufCtl.bufOffset++];
  121. }
  122. else
  123. {
  124. if(!(spi_irs_status & RECEIVE_FIFO_FULL))
  125. {
  126. if(spiCtl[id].rxBufCtl.buf)
  127. {
  128. spiCtl[id].rxBufCtl.buf[spiCtl[id].rxBufCtl.bufOffset++] = SPIx->DataReg;
  129. }
  130. }
  131. spiCtl[id].txBufCtl.bufOffset++;
  132. SPIx->DataReg = 0;
  133. }
  134. }
  135. }
  136. if(spi_irs_status & RECEIVE_FIFO_FULL)
  137. {
  138. cnt = SPIx->RXFTLR + 1;
  139. for(i = 0; i< cnt; i++)
  140. {
  141. if(spiCtl[id].rxBufCtl.buf)
  142. {
  143. spiCtl[id].rxBufCtl.buf[spiCtl[id].rxBufCtl.bufOffset++] = SPIx->DataReg;
  144. }
  145. else
  146. {
  147. VOID (SPIx->DataReg & 0xff);
  148. }
  149. }
  150. if(spiCtl[id].rxBufCtl.bufOffset >= spiCtl[id].rxBufCtl.bufSize)
  151. {
  152. if(spiCtl[id].cfg.force_cs == true)
  153. HalGpioFmuxEnable(spiCtl[id].cfg.ssn_pin, Bit_ENABLE);
  154. spiCtl[id].busy = false;
  155. spiCtl[id].rxBufCtl.buf = NULL;
  156. spiCtl[id].rxBufCtl.bufOffset = 0;
  157. evt.id = id;
  158. evt.evt = SPI_RX_COMPLETED;
  159. hal_pwrmgr_unlock((MODULE_e)(MOD_SPI0 + id));
  160. if(spiCtl[id].cfg.evt_handler)
  161. {
  162. spiCtl[id].cfg.evt_handler(&evt);
  163. }
  164. }
  165. if(spiCtl[id].txBufCtl.bufOffset >= spiCtl[id].txBufCtl.bufSize)
  166. {
  167. spiCtl[id].busy = false;
  168. evt.id = id;
  169. evt.evt = SPI_TX_COMPLETED;
  170. if(spiCtl[id].cfg.evt_handler)
  171. {
  172. spiCtl[id].cfg.evt_handler(&evt);
  173. }
  174. }
  175. }
  176. }
  177. static void HalSpiSlaveHandle(SPI_INDEX_e id, AP_SSI_TypeDef* SPIx)
  178. {
  179. volatile uint8_t spi_irs_status;
  180. spi_evt_t evt;
  181. uint16_t i, cnt;
  182. spi_irs_status = SPIx->ISR;
  183. if(spi_irs_status & TRANSMIT_FIFO_EMPTY)
  184. {
  185. cnt = 8 - SPIx->TXFLR;
  186. for(i = 0; i< cnt; i++)
  187. {
  188. if(spiCtl[id].txBufCtl.bufOffset >= spiCtl[id].txBufCtl.bufSize)
  189. {
  190. SPIx->DataReg = 0;
  191. SPIx->IMR = 0x10;
  192. break;
  193. }
  194. if(spiCtl[id].txBufCtl.buf && spiCtl[id].busy)
  195. {
  196. SPIx->DataReg = spiCtl[id].txBufCtl.buf[spiCtl[id].txBufCtl.bufOffset++];
  197. }
  198. else
  199. {
  200. SPIx->DataReg = 0;
  201. }
  202. }
  203. }
  204. if(spi_irs_status & RECEIVE_FIFO_FULL)
  205. {
  206. volatile uint32_t garbage;
  207. cnt = SPIx->RXFLR;
  208. if(spiCtl[id].rxBufCtl.buf)
  209. {
  210. for(i = 0; i< cnt; i++)
  211. {
  212. if(spiCtl[id].rxBufCtl.bufSize > spiCtl[id].rxBufCtl.bufOffset)
  213. spiCtl[id].rxBufCtl.buf[spiCtl[id].rxBufCtl.bufOffset++] = SPIx->DataReg;
  214. else
  215. garbage = SPIx->DataReg;
  216. }
  217. }
  218. else if(!spiCtl[id].busy)
  219. {
  220. uint8_t rxbuf[16];
  221. for(i = 0; i< cnt; i++)
  222. {
  223. *(rxbuf+i) = SPIx->DataReg;
  224. }
  225. evt.id = id;
  226. evt.evt = SPI_RX_DATA_S;
  227. evt.data = rxbuf;
  228. evt.len = cnt;
  229. spiCtl[id].cfg.evt_handler(&evt);
  230. }
  231. else
  232. {
  233. garbage = SPIx->DataReg;
  234. spiCtl[id].rxBufCtl.bufOffset += cnt;
  235. }
  236. if(spiCtl[id].busy && spiCtl[id].rxBufCtl.bufOffset >= spiCtl[id].txBufCtl.bufSize)
  237. {
  238. spiCtl[id].busy = false;
  239. spiCtl[id].txBufCtl.buf = NULL;
  240. spiCtl[id].txBufCtl.bufOffset = 0;
  241. spiCtl[id].rxBufCtl.bufOffset = 0;
  242. evt.id = id;
  243. evt.evt = SPI_TX_COMPLETED;
  244. spiCtl[id].cfg.evt_handler(&evt);
  245. }
  246. }
  247. }
  248. /**************************************************************************************
  249. @fn HalSpi0IRQHandler
  250. @brief This function process for spi0 interrupt,when use int please consummate its callbackfunction
  251. input parameters
  252. @param None.
  253. output parameters
  254. @param None.
  255. @return None.
  256. **************************************************************************************/
  257. void __attribute__((used)) HalSpi0IRQHandler(void)
  258. {
  259. if(!spiCtl[0].enable)
  260. return;
  261. if(spiCtl[0].cfg.is_slave)
  262. HalSpiSlaveHandle(SPI0, AP_SPI0);
  263. else
  264. HalSpiMasterHandle(SPI0, AP_SPI0);
  265. }
  266. /**************************************************************************************
  267. @fn HalSpi1IRQHandler
  268. @brief This function process for spi1 interrupt,when use int please consummate its callbackfunction
  269. input parameters
  270. @param None.
  271. output parameters
  272. @param None.
  273. @return None.
  274. **************************************************************************************/
  275. void __attribute__((used)) HalSpi1IRQHandler(void)
  276. {
  277. if(!spiCtl[1].enable)
  278. return;
  279. if(spiCtl[1].cfg.is_slave)
  280. HalSpiSlaveHandle(SPI1, AP_SPI1);
  281. else
  282. HalSpiMasterHandle(SPI1, AP_SPI1);
  283. }
  284. /**************************************************************************************
  285. @fn HalSpiPinInit
  286. @brief This function process for spi pin initial(4 lines);You can use two spi,spi0 and spi1,should programe by USE_AP_SPIX
  287. input parameters
  288. @param GPIO_Pin_e sck_pin: define sclk pin
  289. GPIO_Pin_e ssn_pin: define ssn pin
  290. GPIO_Pin_e tx_pin: define transmit pin;when use as master,it's mosi pin;corresponding,use as slave,it's miso
  291. GPIO_Pin_e rx_pin: define receive pin;when use as master,it's miso pin;corresponding,use as slave,it's mosi
  292. output parameters
  293. @param None.
  294. @return None.
  295. **************************************************************************************/
  296. static void HalSpiPinInit(SPI_INDEX_e index, GpioPin_t sck_pin, GpioPin_t ssn_pin, GpioPin_t tx_pin, GpioPin_t rx_pin)
  297. {
  298. HalGpioFmuxConfig(sck_pin, (gpio_fmux_e)(FMUX_SPI_0_SCK+index*4));
  299. HalGpioFmuxConfig(ssn_pin, (gpio_fmux_e)(FMUX_SPI_0_SSN+index*4));
  300. HalGpioFmuxConfig(tx_pin, (gpio_fmux_e)(FMUX_SPI_0_TX+index*4));
  301. HalGpioFmuxConfig(rx_pin, (gpio_fmux_e)(FMUX_SPI_0_RX+index*4));
  302. }
  303. static void HalSpiPinDeinit(GpioPin_t sck_pin, GpioPin_t ssn_pin, GpioPin_t tx_pin, GpioPin_t rx_pin)
  304. {
  305. HalGpioFmuxEnable(sck_pin, Bit_DISABLE);
  306. HalGpioFmuxEnable(ssn_pin, Bit_DISABLE);
  307. HalGpioFmuxEnable(tx_pin, Bit_DISABLE);
  308. HalGpioFmuxEnable(rx_pin, Bit_DISABLE);
  309. }
  310. #if DMAC_USE
  311. static void HalConfigDmaSpiTx(AP_SSI_TypeDef* SPIx, uint8_t* tx_buf, uint16_t tx_len)
  312. {
  313. uint8_t index = 0;
  314. DMA_CH_CFG_t cfgc;
  315. if(SPIx == AP_SPI1)
  316. {
  317. index = 1;
  318. }
  319. SPIx->DMACR &= 0x01;
  320. cfgc.transf_size = tx_len;
  321. cfgc.sinc = DMA_INC_INC;
  322. if(spiCtl[index].cfg.spi_dfsmod == SPI_1BYTE)
  323. {
  324. cfgc.src_tr_width = DMA_WIDTH_BYTE;
  325. cfgc.dst_tr_width = DMA_WIDTH_BYTE;
  326. }
  327. else
  328. {
  329. cfgc.src_tr_width = DMA_WIDTH_HALFWORD;
  330. cfgc.dst_tr_width = DMA_WIDTH_HALFWORD;
  331. }
  332. cfgc.src_msize = DMA_BSIZE_1;
  333. cfgc.src_addr = (uint32_t)tx_buf;
  334. cfgc.dinc = DMA_INC_NCHG;
  335. cfgc.dst_msize = DMA_BSIZE_1;
  336. cfgc.dst_addr = (uint32_t)&(SPIx->DataReg);
  337. cfgc.enable_int = true;
  338. HalDMAConfigChannel(SPI_DMAC_CH, &cfgc);
  339. HalDMAStartChannel(SPI_DMAC_CH);
  340. SPIx->DMACR |= 0x02;
  341. SPIx->DMATDLR = 0;
  342. }
  343. static void HalConfigDmaSpiRx(AP_SSI_TypeDef* SPIx, uint8_t* rx_buf, uint16_t rx_len)
  344. {
  345. DMA_CH_CFG_t cfgc;
  346. SPIx->DMACR &= 0x02;
  347. cfgc.transf_size = rx_len;
  348. cfgc.sinc = DMA_INC_NCHG;
  349. cfgc.src_tr_width = DMA_WIDTH_BYTE;
  350. cfgc.src_msize = DMA_BSIZE_1;
  351. cfgc.src_addr = (uint32_t)&(SPIx->DataReg);
  352. cfgc.dinc = DMA_INC_INC;
  353. cfgc.dst_tr_width = DMA_WIDTH_BYTE;
  354. cfgc.dst_msize = DMA_BSIZE_1;
  355. cfgc.dst_addr = (uint32_t)rx_buf;
  356. cfgc.enable_int = true;
  357. HalDMAConfigChannel(SPI_DMAC_CH, &cfgc);
  358. HalDMAStartChannel(SPI_DMAC_CH);
  359. SPIx->DMACR |= 0x01;
  360. SPIx->DMARDLR = 0;
  361. }
  362. #endif
  363. static ErrCode_t HalSpiXmitPolling(AP_SSI_TypeDef* SPIx, uint8_t* tx_buf, uint8_t* rx_buf, uint16_t len)
  364. {
  365. uint16_t tmp_len, i;
  366. uint16_t tx_size, rx_size;
  367. #if DMAC_USE
  368. SPI_INDEX_e index = SPI0;
  369. if(SPIx == AP_SPI1)
  370. {
  371. index = SPI1;
  372. }
  373. #endif
  374. tx_size = len;
  375. rx_size = len;
  376. SPI_INIT_TOUT(to);
  377. #if DMAC_USE
  378. if(rx_buf && spiCtl[index].cfg.dma_rx_enable)
  379. {
  380. HalConfigDmaSpiRx(SPIx, rx_buf, rx_size);
  381. }
  382. else if(tx_buf && spiCtl[index].cfg.dma_tx_enable)
  383. {
  384. HalConfigDmaSpiTx(SPIx, tx_buf, tx_size);
  385. }
  386. #endif
  387. while(1)
  388. {
  389. #if DMAC_USE
  390. if( (SPIx->SR&TX_FIFO_NOT_FULL) && (!(spiCtl[index].cfg.dma_tx_enable)) )
  391. #else
  392. if(SPIx->SR & TX_FIFO_NOT_FULL && tx_size)
  393. #endif
  394. {
  395. tmp_len = 8-SPIx->TXFLR;
  396. if(tmp_len > tx_size)
  397. tmp_len = tx_size;
  398. for(i=0; i<tmp_len; i++)
  399. {
  400. SPIx->DataReg = (tx_buf!=NULL)?(*(tx_buf+len-tx_size+i)):0;
  401. }
  402. tx_size -= tmp_len;
  403. }
  404. #if DMAC_USE
  405. if( ((rx_buf == NULL) && ((tx_size == 0)||(tx_size && (spiCtl[index].cfg.dma_tx_enable)))) ||
  406. ((rx_buf != NULL) && (tx_size == 0) && (spiCtl[index].cfg.dma_rx_enable)) )
  407. break;
  408. else if( (rx_buf != NULL) && (!(spiCtl[index].cfg.dma_rx_enable)) )
  409. #else
  410. if((rx_size == 0) && ((tx_size == 0)))
  411. break;
  412. else if(rx_size)
  413. #endif
  414. {
  415. if(SPIx->RXFLR)
  416. {
  417. tmp_len = SPIx->RXFLR;
  418. for(i = 0; i< tmp_len; i++)
  419. {
  420. *rx_buf++= SPIx->DataReg;
  421. }
  422. rx_size -= tmp_len;
  423. }
  424. if(rx_size == 0)
  425. break;
  426. }
  427. SPI_CHECK_TOUT(to, SPI_OP_TIMEOUT);
  428. }
  429. #if DMAC_USE
  430. if((spiCtl[index].cfg.dma_rx_enable) || (spiCtl[index].cfg.dma_tx_enable))
  431. {
  432. HalDMAStatusControl(SPI_DMAC_CH);
  433. }
  434. #endif
  435. while(SPIx->SR & SPI_BUSY)
  436. {
  437. SPI_CHECK_TOUT(to, SPI_OP_TIMEOUT);
  438. }
  439. return ERR_NONE;
  440. }
  441. static ErrCode_t HalSpiDisable(SPI_INDEX_e index)
  442. {
  443. if(index >SPI1)
  444. {
  445. return ERR_NOT_SUPPORTED;
  446. }
  447. hal_clk_gate_disable((MODULE_e)(MOD_SPI0 + index));
  448. HalSpiPinDeinit(spiCtl[index].cfg.sclk_pin, spiCtl[index].cfg.ssn_pin, spiCtl[index].cfg.MOSI, spiCtl[index].cfg.MISO);
  449. osal_memset(&spiCtl[index], 0, sizeof(spiCtl));
  450. return ERR_NONE;
  451. }
  452. static void HalSpi0SleepHandler(void)
  453. {
  454. if(spiCtl[0].enable)
  455. {
  456. HalSpiDisable(SPI0);
  457. }
  458. }
  459. static void HalSpi1SleepHandler(void)
  460. {
  461. if(spiCtl[1].enable)
  462. {
  463. HalSpiDisable(SPI1);
  464. }
  465. }
  466. static void HalSpi0WakeupHandler(void)
  467. {
  468. NVIC_SetPriority((IRQn_Type)SPI0_IRQn, IRQ_PRIO_HAL);
  469. }
  470. static void HalSpi1WakeupHandler(void)
  471. {
  472. NVIC_SetPriority((IRQn_Type)SPI1_IRQn, IRQ_PRIO_HAL);
  473. }
  474. void HalSpiTmodSet(AP_SSI_TypeDef* SPIx, SPI_TMOD_e mod)
  475. {
  476. SPIx->SSIEN = 0;
  477. subWriteReg(&SPIx->CR0,9,8,mod);
  478. SPIx->SSIEN = 1;
  479. }
  480. void HalSpiDfsSet(SPI_INDEX_e index, SPI_DFS_e mod)
  481. {
  482. AP_SSI_TypeDef* SPIx = NULL;
  483. SPIx = (index == SPI0) ? AP_SPI0 : AP_SPI1;
  484. SPIx->SSIEN = 0;
  485. subWriteReg(&SPIx->CR0,3,0,mod);
  486. SPIx->SSIEN = 1;
  487. spiCtl[index].cfg.spi_dfsmod = mod;
  488. }
  489. void HalSpiNdfSet(AP_SSI_TypeDef* SPIx, uint16_t len)
  490. {
  491. SPIx->SSIEN = 0;
  492. SPIx->CR1 = len-1;
  493. SPIx->SSIEN = 1;
  494. }
  495. ErrCode_t HalSpiMasterTransfer(AP_SSI_TypeDef* SPIx, SPI_TMOD_e mod, uint8_t* tx_buf, uint8_t* rx_buf, uint16_t len)
  496. {
  497. int ret;
  498. SPI_INDEX_e index = SPI0;
  499. if(SPIx != AP_SPI0 && SPIx != AP_SPI1)
  500. {
  501. return ERR_NOT_SUPPORTED;
  502. }
  503. if(mod > SPI_RXD)
  504. {
  505. return ERR_IO_CONFILCT;
  506. }
  507. if(len == 0 || (tx_buf == NULL && rx_buf == NULL))
  508. {
  509. return ERR_INVALID_DATA;
  510. }
  511. if(SPIx == AP_SPI1)
  512. {
  513. index = SPI1;
  514. }
  515. if(!spiCtl[index].enable)
  516. {
  517. return ERR_NOT_REGISTED;
  518. }
  519. if(spiCtl[index].busy)
  520. {
  521. return ERR_BUSY;
  522. }
  523. spiCtl[index].txBufCtl.buf = tx_buf;
  524. spiCtl[index].txBufCtl.bufOffset = 0;
  525. spiCtl[index].txBufCtl.bufSize = len;
  526. spiCtl[index].rxBufCtl.buf = rx_buf;
  527. spiCtl[index].rxBufCtl.bufOffset = 0;
  528. spiCtl[index].rxBufCtl.bufSize = len;
  529. HalSpiTmodSet(SPIx, mod);
  530. if(mod > SPI_TXD) //spi receive only or eeprom read,should set read data len(ndf)
  531. {
  532. HalSpiNdfSet(SPIx, len);
  533. }
  534. if(spiCtl[index].cfg.force_cs == true)
  535. {
  536. HalGpioFmuxEnable(spiCtl[index].cfg.ssn_pin,Bit_DISABLE);
  537. HalGpioSet(spiCtl[index].cfg.ssn_pin, Bit_DISABLE);
  538. HalGpioPinInit(spiCtl[index].cfg.ssn_pin, GPIO_OUTPUT);
  539. }
  540. if(spiCtl[index].cfg.int_mode == false)
  541. {
  542. ret = HalSpiXmitPolling(SPIx, tx_buf, rx_buf, len);
  543. if(spiCtl[index].cfg.force_cs == true)
  544. {
  545. HalGpioFmuxEnable(spiCtl[index].cfg.ssn_pin,Bit_ENABLE);
  546. }
  547. if(ret)
  548. {
  549. return ERR_TIMEOUT;
  550. }
  551. }
  552. else
  553. {
  554. HalSpiIntDisable(index);
  555. if(SPIx->SR & TX_FIFO_NOT_FULL)
  556. {
  557. uint8_t dummy[8] = {0};
  558. hal_pwrmgr_lock((MODULE_e)(MOD_SPI0 + index));
  559. spiCtl[index].txBufCtl.bufOffset = (len >= 8)?8:len;
  560. // Ssix->RXFTLR = _tx_len - 1;
  561. HalSpiWriteFifo(SPIx, spiCtl[index].txBufCtl.bufOffset, (tx_buf!=NULL)?tx_buf:dummy);
  562. }
  563. spiCtl[index].busy = true;
  564. HalSpiIntEnable(index, 0x11);
  565. }
  566. return ERR_NONE;
  567. }
  568. ErrCode_t HalSpiSlaveTxPrepare(AP_SSI_TypeDef* SPIx, uint8_t* tx_buf, uint16_t len)
  569. {
  570. SPI_INDEX_e index = SPI0;
  571. if(SPIx != AP_SPI0 && SPIx != AP_SPI1)
  572. {
  573. return ERR_NOT_SUPPORTED;
  574. }
  575. if(tx_buf == NULL || len ==0)
  576. {
  577. return ERR_INVALID_DATA;
  578. }
  579. if(SPIx == AP_SPI1)
  580. {
  581. index = SPI1;
  582. }
  583. spiCtl[index].txBufCtl.buf = tx_buf;
  584. spiCtl[index].txBufCtl.bufSize = len;
  585. spiCtl[index].txBufCtl.bufOffset = 0;
  586. spiCtl[index].rxBufCtl.buf = NULL;
  587. spiCtl[index].rxBufCtl.bufOffset = 0;
  588. if(SPIx->SR & 0x10)
  589. {
  590. SPIx->IMR |= BIT(0);
  591. return ERR_NONE;
  592. }
  593. if(len > 8 - SPIx->TXFLR)
  594. {
  595. len = 8 - SPIx->TXFLR;
  596. }
  597. for(uint8_t i=0; i<len; i++)
  598. {
  599. SPIx->DataReg = tx_buf[i];
  600. }
  601. spiCtl[index].txBufCtl.bufOffset = len;
  602. SPIx->IMR |= BIT(0);
  603. spiCtl[index].busy = true;
  604. return ERR_NONE;
  605. }
  606. ErrCode_t HalSpiSetIntMode(SPI_INDEX_e index, bool en)
  607. {
  608. if(index > SPI1)
  609. {
  610. return ERR_DATA_SIZE;
  611. }
  612. spiCtl[index].cfg.int_mode = en;
  613. if(en)
  614. {
  615. HalSpiIntEnable(index, 0x10);
  616. }
  617. else
  618. {
  619. HalSpiIntDisable(index);
  620. }
  621. return ERR_NONE;
  622. }
  623. ErrCode_t HalSpiSetForceCs(SPI_INDEX_e index, bool en)
  624. {
  625. if(index > SPI1)
  626. {
  627. return ERR_NOT_SUPPORTED;
  628. }
  629. spiCtl[index].cfg.force_cs = en;
  630. return ERR_NONE;
  631. }
  632. bool HalSpiGetTransmitState(SPI_INDEX_e index)
  633. {
  634. AP_SSI_TypeDef* SPIx = NULL;
  635. SPIx = (index == SPI0) ? AP_SPI0 : AP_SPI1;
  636. return (SPIx->SR&SPI_BUSY)||spiCtl[index].busy;
  637. }
  638. ErrCode_t HalSpiMasterConfig(AP_SSI_TypeDef* SPIx, spi_Cfg_t *cfg)
  639. {
  640. uint16_t baud_temp;
  641. SPI_INDEX_e index = SPI0;
  642. int pclk = clk_get_pclk();
  643. if(SPIx != AP_SPI0 && SPIx != AP_SPI1)
  644. {
  645. return ERR_NOT_SUPPORTED;
  646. }
  647. if(cfg->is_slave)
  648. {
  649. return ERR_IO_CONFILCT;
  650. }
  651. if(cfg->sclk_pin >=GPIO_NUM || cfg->sclk_pin == cfg->ssn_pin || cfg->sclk_pin == cfg->MOSI || cfg->sclk_pin == cfg->MISO)
  652. {
  653. return ERR_IO_CONFILCT;
  654. }
  655. if(cfg->ssn_pin>=GPIO_NUM || cfg->ssn_pin == cfg->MOSI || cfg->ssn_pin == cfg->MISO)
  656. {
  657. return ERR_IO_CONFILCT;
  658. }
  659. if(cfg->MOSI>=GPIO_NUM || cfg->MOSI == cfg->MISO)
  660. {
  661. return ERR_IO_CONFILCT;
  662. }
  663. // if(cfg->MISO>=GPIO_NUM)
  664. // {
  665. // return ERR_IO_CONFILCT;
  666. // }
  667. if(cfg->spi_tmod>SPI_RXD)
  668. {
  669. return ERR_NOT_SUPPORTED;
  670. }
  671. if(cfg->spi_scmod>SPI_MODE3)
  672. {
  673. return ERR_NOT_SUPPORTED;
  674. }
  675. if(cfg->spi_dfsmod < SPI_MINBYTE || cfg->spi_dfsmod > SPI_MAXBYTE)
  676. {
  677. return ERR_NOT_SUPPORTED;
  678. }
  679. if(SPIx == AP_SPI1)
  680. {
  681. index = SPI1;
  682. }
  683. osal_memcpy(&spiCtl[index].cfg, cfg, sizeof(spi_Cfg_t));
  684. spiCtl[index].busy = false;
  685. spiCtl[index].enable = true;
  686. spiCtl[index].cfg.is_slave = false;
  687. hal_clk_gate_enable((MODULE_e)(MOD_SPI0+index));
  688. HalSpiPinInit(index, cfg->sclk_pin, cfg->ssn_pin, cfg->MOSI, cfg->MISO);
  689. SPIx->SSIEN = 0; //DISABLE_SPI;
  690. SPI_MASTER_SELECT(index);
  691. SPIx->CR0= ((SPIx->CR0) & 0xfffffc30)|((unsigned int)(spiCtl[index].cfg.spi_dfsmod))|(cfg->spi_scmod<<6)|(cfg->spi_tmod<<8);
  692. baud_temp = (pclk + (cfg->baudrate>>1)) / cfg->baudrate;
  693. if(baud_temp<2)
  694. {
  695. baud_temp = 2;
  696. }
  697. else if(baud_temp>65534)
  698. {
  699. baud_temp =65534;
  700. }
  701. SPIx->BAUDR= baud_temp; // set clock(round)
  702. SPIx->TXFTLR=4; // set fifo threshold to triggle interrupt
  703. SPIx->RXFTLR=0;
  704. SPIx->IMR = 0x00;
  705. SPIx->SER=1; //enable slave device
  706. SPIx->SSIEN = 1; //ENABLE_SPI;
  707. if(cfg->int_mode)
  708. HalSpiIntEnable(index, 0x10);
  709. else
  710. HalSpiIntDisable(index);
  711. return ERR_NONE;
  712. }
  713. ErrCode_t HalSpiSlaveConfig(AP_SSI_TypeDef* SPIx, spi_Cfg_t *cfg)
  714. {
  715. SPI_INDEX_e index = SPI0;
  716. if(SPIx != AP_SPI0 && SPIx != AP_SPI1)
  717. {
  718. return ERR_NOT_SUPPORTED;
  719. }
  720. if(!cfg->is_slave)
  721. {
  722. return ERR_IO_CONFILCT;
  723. }
  724. if(cfg->sclk_pin >=GPIO_NUM || cfg->sclk_pin == cfg->ssn_pin || cfg->sclk_pin == cfg->MOSI || cfg->sclk_pin == cfg->MISO)
  725. {
  726. return ERR_IO_CONFILCT;
  727. }
  728. if(cfg->ssn_pin>=GPIO_NUM || cfg->ssn_pin == cfg->MOSI || cfg->ssn_pin == cfg->MISO)
  729. {
  730. return ERR_IO_CONFILCT;
  731. }
  732. if(cfg->MOSI>=GPIO_NUM || cfg->MOSI == cfg->MISO)
  733. {
  734. return ERR_IO_CONFILCT;
  735. }
  736. if(cfg->MISO>=GPIO_NUM)
  737. {
  738. return ERR_IO_CONFILCT;
  739. }
  740. if(cfg->spi_tmod>SPI_RXD)
  741. {
  742. return ERR_NOT_SUPPORTED;
  743. }
  744. if(cfg->spi_scmod>SPI_MODE3)
  745. {
  746. return ERR_NOT_SUPPORTED;
  747. }
  748. if(cfg->spi_dfsmod < SPI_MINBYTE || cfg->spi_dfsmod > SPI_MAXBYTE)
  749. {
  750. return ERR_NOT_SUPPORTED;
  751. }
  752. if(SPIx == AP_SPI1)
  753. {
  754. index = SPI1;
  755. }
  756. osal_memcpy(&spiCtl[index].cfg, cfg, sizeof(spi_Cfg_t));
  757. spiCtl[index].busy = false;
  758. spiCtl[index].enable = true;
  759. spiCtl[index].cfg.is_slave = true;
  760. hal_clk_gate_enable((MODULE_e)(MOD_SPI0 + index));
  761. if(spiCtl[index].cfg.int_mode)
  762. HalSpiIntEnable(index, 0x11);
  763. else
  764. HalSpiIntDisable(index);
  765. HalSpiPinInit(index, spiCtl[index].cfg.sclk_pin, spiCtl[index].cfg.ssn_pin, spiCtl[index].cfg.MISO, spiCtl[index].cfg.MOSI);
  766. SPIx->SSIEN = 0; //disable SPI
  767. SPI_SLAVE_SELECT(index);
  768. SPIx->CR0 = ((SPIx->CR0 & 0xfffffc30) | ((unsigned int)(spiCtl[index].cfg.spi_dfsmod)) | ((unsigned int)(spiCtl[index].cfg.spi_scmod) << 6) | ((unsigned int)SPI_TRXD << 8)) ;
  769. SPIx->TXFTLR = 4;
  770. SPIx->RXFTLR = 0;
  771. SPIx->SSIEN = 1;
  772. return ERR_NONE;
  773. }
  774. /**************************************************************************************
  775. @fn HalSpiDeinit
  776. @brief This function will deinit the spi you select.
  777. input parameters
  778. @param hal_spi_t* spi_ptr: spi module handle.
  779. output parameters
  780. @param None.
  781. @return
  782. SUCCESS
  783. ERR_INVALID_PARAM
  784. **************************************************************************************/
  785. ErrCode_t HalSpiDeinit(SPI_INDEX_e index)
  786. {
  787. if(index >SPI1)
  788. {
  789. return ERR_NOT_SUPPORTED;
  790. }
  791. HalSpiDisable(index);
  792. if(index == SPI0)
  793. {
  794. hal_pwrmgr_unregister(MOD_SPI0);
  795. }
  796. else if(index == SPI1)
  797. {
  798. hal_pwrmgr_unregister(MOD_SPI1);
  799. }
  800. return ERR_NONE;
  801. }
  802. /**************************************************************************************
  803. @fn HalSpiInit
  804. @brief it is used to init spi module.
  805. input parameters
  806. @param None
  807. output parameters
  808. @param None.
  809. @return None.
  810. **************************************************************************************/
  811. ErrCode_t HalSpiInit(SPI_INDEX_e channel)
  812. {
  813. ErrCode_t ret = ERR_NONE;
  814. if(channel == SPI0)
  815. {
  816. ret = hal_pwrmgr_register(MOD_SPI0, HalSpi0SleepHandler, HalSpi0WakeupHandler);
  817. if(ret == ERR_NONE)
  818. osal_memset(&spiCtl[0], 0, sizeof(SpiCtl_t));
  819. return ret;
  820. }
  821. else if(channel == SPI1)
  822. {
  823. ret = hal_pwrmgr_register(MOD_SPI1, HalSpi1SleepHandler, HalSpi1WakeupHandler);
  824. if(ret == ERR_NONE)
  825. osal_memset(&spiCtl[1], 0, sizeof(SpiCtl_t));
  826. return ret;
  827. }
  828. return ERR_INVALID_PARAM;
  829. }
  830. #if DMAC_USE
  831. ErrCode_t HalSpiDmaSet(SPI_INDEX_e index, bool ten, bool ren)
  832. {
  833. if(index >SPI1)
  834. {
  835. return ERR_NOT_SUPPORTED;
  836. }
  837. spiCtl[index].cfg.dma_rx_enable = ren;
  838. spiCtl[index].cfg.dma_tx_enable = ten;
  839. return ERR_NONE;
  840. }
  841. #endif