hpm_spi.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /*
  2. * Copyright (c) 2022 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_COMPONENT_SPI_H
  8. #define HPM_COMPONENT_SPI_H
  9. #include "hpm_common.h"
  10. #include "hpm_spi_drv.h"
  11. #ifdef HPMSOC_HAS_HPMSDK_DMAV2
  12. #include "hpm_dmav2_drv.h"
  13. #else
  14. #include "hpm_dma_drv.h"
  15. #endif
  16. #include "hpm_dmamux_drv.h"
  17. #include "hpm_misc.h"
  18. #include "hpm_l1c_drv.h"
  19. #ifndef SPI_CS_ACTIVE
  20. #define SPI_CS_ACTIVE 0
  21. #endif
  22. #ifndef USE_DMA_MGR
  23. #define USE_DMA_MGR (0U)
  24. #endif
  25. /* Every transaction can be delineated by 3 dma descriptions: SPI control, SPI cmd, SPI data */
  26. #define SPI_DMA_DESC_COUNT_PER_TRANS (3U)
  27. typedef struct {
  28. DMA_Type *dma_ptr;
  29. DMAMUX_Type *dmamux_ptr;
  30. uint8_t rx_dma_ch;
  31. uint8_t tx_dma_ch;
  32. uint8_t rx_dmamux_ch;
  33. uint8_t tx_dmamux_ch;
  34. uint8_t rx_req;
  35. uint8_t tx_req;
  36. uint8_t data_width;
  37. } spi_dma_context_t;
  38. typedef struct {
  39. SPI_Type *ptr;
  40. uint32_t cs_pin;
  41. uint8_t cmd;
  42. uint8_t *rx_buff;
  43. uint8_t *tx_buff;
  44. uint8_t running_core;
  45. uint32_t addr;
  46. uint32_t rx_size;
  47. uint32_t rx_count;
  48. uint32_t tx_size;
  49. uint32_t tx_count;
  50. uint32_t data_len_in_byte;
  51. uint32_t per_trans_max;
  52. uint32_t *spi_transctrl;
  53. void (*write_cs)(uint32_t cs_pin, uint8_t state);
  54. spi_dma_context_t dma_context;
  55. dma_linked_descriptor_t *dma_linked_descriptor;
  56. } spi_context_t;
  57. /**
  58. * @brief spi configuration init structure
  59. */
  60. typedef struct {
  61. spi_mode_selection_t mode; /*!< the spi operating mode */
  62. spi_data_phase_format_t io_mode; /*!< the spi data line mode */
  63. spi_sclk_idle_state_t clk_polarity; /*!< CPOL */
  64. spi_sclk_sampling_clk_edges_t clk_phase; /*!< CPHA */
  65. spi_shift_direction_t direction; /*!< MSB or LSB data shift direction */
  66. uint8_t data_len; /*!< the unit is bit (1~32bit) */
  67. bool data_merge; /*!< data Merge mode*/
  68. } spi_initialize_config_t;
  69. #if USE_DMA_MGR
  70. typedef void (*spi_dma_complete_cb)(uint32_t channel);
  71. #endif
  72. #ifdef __cplusplus
  73. extern "C" {
  74. #endif
  75. /**
  76. * @brief hpm_spi setup dma transfer
  77. *
  78. * @note if the transferred data count more than SPI_SOC_TRANSFER_COUNT_MAX, this API will using
  79. * DMA chain descriptors to link SPI transmission.
  80. *
  81. * @param[in] spi_context A pointer to the struct of "spi_context_t"
  82. * @param[in] spi_config A pointer to the struct of "spi_control_config_t"
  83. * @retval status_success if SPI transfers data successfully.
  84. */
  85. hpm_stat_t hpm_spi_setup_dma_transfer(spi_context_t *context, spi_control_config_t *config);
  86. /*
  87. * SPI release gpio pin if gpio use for SPI CS function
  88. */
  89. /**
  90. * @brief hpm_spi releases gpio cs pin after SPI transfer completed
  91. *
  92. * @param[in] spi_context A pointer to the struct of "spi_context_t"
  93. * @retval status_success if SPI releases gpio cs pin successfully.
  94. */
  95. hpm_stat_t hpm_spi_release_gpio_cs(spi_context_t *context);
  96. /**
  97. * @brief spi get default init config
  98. *
  99. * @note it's no command/address/token phase, only data phase.
  100. *
  101. * @param [out] config spi_init_config_t
  102. */
  103. void hpm_spi_get_default_init_config(spi_initialize_config_t *config);
  104. /**
  105. * @brief initialize for spi
  106. *
  107. * @note it's no command/address/token phase, only data phase.
  108. *
  109. * @param [in] ptr SPI base address
  110. * @param [in] config spi_init_config_t struct
  111. * @retval hpm_stat_t status_success if spi in busy status
  112. */
  113. hpm_stat_t hpm_spi_initialize(SPI_Type *ptr, spi_initialize_config_t *config);
  114. /**
  115. * @brief set spi sclk frequency for spi master
  116. *
  117. * @param [in] ptr SPI base address
  118. * @param [in] freq spi sclk frequency
  119. * @retval hpm_stat_t status_success if spi in busy status
  120. */
  121. hpm_stat_t hpm_spi_set_sclk_frequency(SPI_Type *ptr, uint32_t freq);
  122. /**
  123. * @brief transmit and receive block for spi
  124. *
  125. * @note it's no command/address/token phase, only data phase.
  126. *
  127. * @param [in] ptr SPI base address
  128. * @param [in] wbuff spi sent data buff address
  129. * @param [out] rbuff spi receive data buff address
  130. * @param [in] size spi sent data count(word unit), not greater than SPI_SOC_TRANSFER_COUNT_MAX
  131. * @param [in] timeout wait time. unit is millisecond
  132. * @retval hpm_stat_t status_success if spi in busy status
  133. */
  134. hpm_stat_t hpm_spi_transmit_receive_blocking(SPI_Type *ptr, uint8_t *wbuff, uint8_t *rbuff, uint32_t size, uint32_t timeout);
  135. /**
  136. * @brief receive block for spi
  137. *
  138. * @note it's no command/address/token phase, only data phase.
  139. *
  140. * @param [in] ptr SPI base address
  141. * @param [out] buff spi receive data buff address
  142. * @param [in] size spi sent data count(word unit), not greater than SPI_SOC_TRANSFER_COUNT_MAX
  143. * @param [in] timeout wait time. unit is millisecond
  144. * @retval hpm_stat_t status_success if spi in busy status
  145. */
  146. hpm_stat_t hpm_spi_receive_blocking(SPI_Type *ptr, uint8_t *buff, uint32_t size, uint32_t timeout);
  147. /**
  148. * @brief transmit block for spi
  149. *
  150. * @note it's no command/address/token phase, only data phase.
  151. *
  152. * @param [in] ptr SPI base address
  153. * @param [in] buff spi sent data buff address
  154. * @param [in] size spi sent data count(word unit), not greater than SPI_SOC_TRANSFER_COUNT_MAX
  155. * @param [in] timeout wait time. unit is millisecond
  156. * @retval hpm_stat_t status_success if spi in busy status
  157. */
  158. hpm_stat_t hpm_spi_transmit_blocking(SPI_Type *ptr, uint8_t *buff, uint32_t size, uint32_t timeout);
  159. /**
  160. * @brief transmit and receive setup dma for spi
  161. *
  162. * @note it's no command/address/token phase, only data phase.
  163. * main configuration spi dma related, call this API after configuring DMA best
  164. *
  165. * @param [in] ptr SPI base address
  166. * @param [in] size spi sent and receive data count(word unit), not greater than SPI_SOC_TRANSFER_COUNT_MAX
  167. * @retval hpm_stat_t status_success if spi in busy status
  168. */
  169. hpm_stat_t hpm_spi_transmit_receive_setup_dma(SPI_Type *ptr, uint32_t size);
  170. /**
  171. * @brief receive setup dma for spi
  172. *
  173. * @note it's no command/address/token phase, only data phase.
  174. * main configuration spi dma related, call this API after configuring DMA best
  175. *
  176. * @param [in] ptr SPI base address
  177. * @param [in] size spi receive data count(word unit), not greater than SPI_SOC_TRANSFER_COUNT_MAX
  178. * @retval hpm_stat_t status_success if spi in busy status
  179. */
  180. hpm_stat_t hpm_spi_receive_setup_dma(SPI_Type *ptr, uint32_t size);
  181. /**
  182. * @brief transmit setup dma for spi
  183. *
  184. * @note it's no command/address/token phase, only data phase.
  185. * main configuration spi dma related, call this API after configuring DMA best
  186. *
  187. * @param [in] ptr SPI base address
  188. * @param [in] size spi transmit data count(word unit), not greater than SPI_SOC_TRANSFER_COUNT_MAX
  189. * @retval hpm_stat_t status_success if spi in busy status
  190. */
  191. hpm_stat_t hpm_spi_transmit_setup_dma(SPI_Type *ptr, uint32_t size);
  192. #if USE_DMA_MGR
  193. /**
  194. * @brief Install callback for SPI DMA channel transmit and receive complete
  195. *
  196. * @note it's no command/address/token phase, only data phase.
  197. *
  198. * @param [in] ptr SPI base address
  199. * @param [in] tx_complete callback for SPI TX DMA
  200. * @param [in] rx_complete callback for SPI RX DMA
  201. * @retval hpm_stat_t status_success if spi in busy status
  202. */
  203. hpm_stat_t hpm_spi_dma_install_callback(SPI_Type *ptr,
  204. spi_dma_complete_cb tx_complete,
  205. spi_dma_complete_cb rx_complete);
  206. /**
  207. * @brief transmit and receive noblock for spi
  208. *
  209. * @note it's no command/address/token phase, only data phase. use dma
  210. *
  211. * @param [in] ptr SPI base address
  212. * @param [in] wbuff spi sent data buff address
  213. * @param [out] rbuff spi receive data buff address
  214. * @param [in] size spi sent data count(word unit), not greater than SPI_SOC_TRANSFER_COUNT_MAX
  215. * @retval hpm_stat_t status_success if spi in busy status
  216. */
  217. hpm_stat_t hpm_spi_transmit_receive_nonblocking(SPI_Type *ptr, uint8_t *wbuff, uint8_t *rbuff, uint32_t size);
  218. /**
  219. * @brief receive noblock for spi
  220. *
  221. * @note it's no command/address/token phase, only data phase. use dma
  222. *
  223. * @param [in] ptr SPI base address
  224. * @param [out] buff spi receive data buff address
  225. * @param [in] size spi sent data count(word unit), not greater than SPI_SOC_TRANSFER_COUNT_MAX
  226. * @retval hpm_stat_t status_success if spi in busy status
  227. */
  228. hpm_stat_t hpm_spi_receive_nonblocking(SPI_Type *ptr, uint8_t *buff, uint32_t size);
  229. /**
  230. * @brief transmit noblock for spi
  231. *
  232. * @note it's no command/address/token phase, only data phase. use dma
  233. *
  234. * @param [in] ptr SPI base address
  235. * @param [in] buff spi sent data buff address
  236. * @param [in] size spi sent data count(word unit), not greater than SPI_SOC_TRANSFER_COUNT_MAX
  237. * @retval hpm_stat_t status_success if spi in busy status
  238. */
  239. hpm_stat_t hpm_spi_transmit_nonblocking(SPI_Type *ptr, uint8_t *buff, uint32_t size);
  240. #endif
  241. #ifdef __cplusplus
  242. }
  243. #endif
  244. #endif /* HPM_COMPONENT_SPI_H */