hpm_spi_drv.h 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212
  1. /*
  2. * Copyright (c) 2021 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_SPI_DRV_H
  8. #define HPM_SPI_DRV_H
  9. #include "hpm_spi_regs.h"
  10. #include "hpm_soc_feature.h"
  11. /**
  12. * @brief SPI driver APIs
  13. * @defgroup spi_interface SPI driver APIs
  14. * @ingroup io_interfaces
  15. * @{
  16. */
  17. /**
  18. * @brief spi dma enable
  19. */
  20. typedef enum {
  21. spi_tx_dma_enable = SPI_CTRL_TXDMAEN_MASK,
  22. spi_rx_dma_enable = SPI_CTRL_RXDMAEN_MASK
  23. } spi_dma_enable_t;
  24. /**
  25. * @brief spi interrupt mask
  26. */
  27. typedef enum {
  28. spi_rx_fifo_overflow_int = SPI_INTREN_RXFIFOORINTEN_MASK,
  29. spi_tx_fifo_underflow_int = SPI_INTREN_TXFIFOURINTEN_MASK,
  30. spi_rx_fifo_threshold_int = SPI_INTREN_RXFIFOINTEN_MASK,
  31. spi_tx_fifo_threshold_int = SPI_INTREN_TXFIFOINTEN_MASK,
  32. spi_end_int = SPI_INTREN_ENDINTEN_MASK,
  33. spi_slave_cmd_int = SPI_INTREN_SLVCMDEN_MASK,
  34. } spi_interrupt_t;
  35. /**
  36. * @brief spi mode selection
  37. */
  38. typedef enum {
  39. spi_master_mode = 0,
  40. spi_slave_mode
  41. } spi_mode_selection_t;
  42. /**
  43. * @brief spi clock polarity
  44. */
  45. typedef enum {
  46. spi_sclk_low_idle = 0,
  47. spi_sclk_high_idle
  48. } spi_sclk_idle_state_t;
  49. /**
  50. * @brief spi clock phase
  51. */
  52. typedef enum {
  53. spi_sclk_sampling_odd_clk_edges = 0,
  54. spi_sclk_sampling_even_clk_edges
  55. } spi_sclk_sampling_clk_edges_t;
  56. /**
  57. * @brief spi cs to sclk edge duration
  58. */
  59. typedef enum {
  60. spi_cs2sclk_half_sclk_1 = 0,
  61. spi_cs2sclk_half_sclk_2,
  62. spi_cs2sclk_half_sclk_3,
  63. spi_cs2sclk_half_sclk_4
  64. } spi_cs2sclk_duration_t;
  65. /**
  66. * @brief spi cs high level duration
  67. */
  68. typedef enum {
  69. spi_csht_half_sclk_1 = 0,
  70. spi_csht_half_sclk_2,
  71. spi_csht_half_sclk_3,
  72. spi_csht_half_sclk_4,
  73. spi_csht_half_sclk_5,
  74. spi_csht_half_sclk_6,
  75. spi_csht_half_sclk_7,
  76. spi_csht_half_sclk_8,
  77. spi_csht_half_sclk_9,
  78. spi_csht_half_sclk_10,
  79. spi_csht_half_sclk_11,
  80. spi_csht_half_sclk_12,
  81. spi_csht_half_sclk_13,
  82. spi_csht_half_sclk_14,
  83. spi_csht_half_sclk_15,
  84. spi_csht_half_sclk_16,
  85. } spi_csht_duration_t;
  86. /**
  87. * @brief spi address phase format
  88. */
  89. typedef enum {
  90. spi_address_phase_format_single_io_mode = 0,
  91. spi_address_phase_format_dualquad_io_mode
  92. } spi_addr_phase_format_t;
  93. /**
  94. * @brief spi transfer mode
  95. */
  96. typedef enum {
  97. spi_trans_write_read_together = 0,
  98. spi_trans_write_only,
  99. spi_trans_read_only,
  100. spi_trans_write_read,
  101. spi_trans_read_write,
  102. spi_trans_write_dummy_read,
  103. spi_trans_read_dummy_write,
  104. spi_trans_no_data,
  105. spi_trans_dummy_write,
  106. spi_trans_dummy_read
  107. } spi_trans_mode_t;
  108. /**
  109. * @brief spi data phase format
  110. */
  111. typedef enum {
  112. spi_single_io_mode = 0,
  113. spi_dual_io_mode,
  114. spi_quad_io_mode,
  115. } spi_data_phase_format_t;
  116. /**
  117. * @brief spi token value
  118. */
  119. typedef enum {
  120. spi_token_value_0x00 = 0,
  121. spi_token_value_0x69
  122. } spi_token_value_t;
  123. /**
  124. * @brief spi dummy count
  125. */
  126. typedef enum {
  127. spi_dummy_count_1 = 0,
  128. spi_dummy_count_2,
  129. spi_dummy_count_3,
  130. spi_dummy_count_4
  131. } spi_dummy_count_t;
  132. typedef enum {
  133. msb_first = 0,
  134. lsb_first,
  135. } spi_shift_direction_t;
  136. /**
  137. * @brief spi master interface timing config structure
  138. */
  139. typedef struct {
  140. uint32_t clk_src_freq_in_hz;
  141. uint32_t sclk_freq_in_hz;
  142. uint8_t cs2sclk;
  143. uint8_t csht;
  144. } spi_master_timing_config_t;
  145. /**
  146. * @brief spi interface timing config structure
  147. */
  148. typedef struct {
  149. spi_master_timing_config_t master_config;
  150. } spi_timing_config_t;
  151. /**
  152. * @brief spi master transfer format config structure
  153. */
  154. typedef struct {
  155. uint8_t addr_len_in_bytes;
  156. } spi_master_format_config_t;
  157. /**
  158. * @brief spi common format config structure
  159. */
  160. typedef struct {
  161. uint8_t data_len_in_bits;
  162. bool data_merge;
  163. bool mosi_bidir;
  164. bool lsb;
  165. uint8_t mode;
  166. uint8_t cpol;
  167. uint8_t cpha;
  168. } spi_common_format_config_t;
  169. /**
  170. * @brief spi format config structure
  171. */
  172. typedef struct {
  173. spi_master_format_config_t master_config;
  174. spi_common_format_config_t common_config;
  175. } spi_format_config_t;
  176. /**
  177. * @brief spi master transfer control config structure
  178. */
  179. typedef struct {
  180. bool cmd_enable;
  181. bool addr_enable;
  182. uint8_t addr_phase_fmt;
  183. bool token_enable;
  184. uint8_t token_value;
  185. } spi_master_control_config_t;
  186. /**
  187. * @brief spi slave transfer control config structure
  188. */
  189. typedef struct {
  190. bool slave_data_only;
  191. } spi_slave_control_config_t;
  192. /**
  193. * @brief spi common transfer control config structure
  194. */
  195. typedef struct {
  196. bool tx_dma_enable;
  197. bool rx_dma_enable;
  198. uint8_t trans_mode;
  199. uint8_t data_phase_fmt;
  200. uint8_t dummy_cnt;
  201. #if defined(HPM_IP_FEATURE_SPI_CS_SELECT) && (HPM_IP_FEATURE_SPI_CS_SELECT == 1)
  202. uint8_t cs_index;
  203. #endif
  204. } spi_common_control_config_t; /*!< value in spi_cs_index_t */
  205. /**
  206. * @brief spi control config structure
  207. */
  208. typedef struct {
  209. spi_master_control_config_t master_config;
  210. spi_slave_control_config_t slave_config;
  211. spi_common_control_config_t common_config;
  212. } spi_control_config_t;
  213. #if defined(HPM_IP_FEATURE_SPI_CS_SELECT) && (HPM_IP_FEATURE_SPI_CS_SELECT == 1)
  214. typedef enum {
  215. spi_cs_0 = 1,
  216. spi_cs_1 = 2,
  217. spi_cs_2 = 4,
  218. spi_cs_3 = 8,
  219. } spi_cs_index_t;
  220. #endif
  221. typedef enum {
  222. addrlen_8bit = 0,
  223. addrlen_16bit,
  224. addrlen_24bit,
  225. addrlen_32bit
  226. } spi_address_len_t;
  227. #if defined(HPM_IP_FEATURE_SPI_SUPPORT_DIRECTIO) && (HPM_IP_FEATURE_SPI_SUPPORT_DIRECTIO == 1)
  228. typedef enum {
  229. hold_pin = 0,
  230. wp_pin,
  231. miso_pin,
  232. mosi_pin,
  233. sclk_pin,
  234. cs_pin
  235. } spi_directio_pin_t;
  236. #endif
  237. #if defined(__cplusplus)
  238. extern "C" {
  239. #endif /* __cplusplus */
  240. /**
  241. * @brief spi master get default timing config
  242. *
  243. * @param [out] config spi_timing_config_t
  244. */
  245. void spi_master_get_default_timing_config(spi_timing_config_t *config);
  246. /**
  247. * @brief spi master get default format config
  248. *
  249. * @param [out] config spi_format_config_t
  250. */
  251. void spi_master_get_default_format_config(spi_format_config_t *config);
  252. /**
  253. * @brief spi master get default control config
  254. *
  255. * @param [out] config spi_control_config_t
  256. */
  257. void spi_master_get_default_control_config(spi_control_config_t *config);
  258. /**
  259. * @brief spi slave get default format config
  260. *
  261. * @param [out] config spi_format_config_t
  262. */
  263. void spi_slave_get_default_format_config(spi_format_config_t *config);
  264. /**
  265. * @brief spi slave get default control config
  266. *
  267. * @param [out] config spi_control_config_t
  268. */
  269. void spi_slave_get_default_control_config(spi_control_config_t *config);
  270. /**
  271. * @brief spi master timing initialization
  272. *
  273. * @param [in] ptr SPI base address
  274. * @param [in] config spi_timing_config_t
  275. * @retval hpm_stat_t status_invalid_argument or status_success
  276. */
  277. hpm_stat_t spi_master_timing_init(SPI_Type *ptr, spi_timing_config_t *config);
  278. /**
  279. * @brief spi format initialization
  280. *
  281. * @param [in] ptr SPI base address
  282. * @param [in] config spi_format_config_t
  283. */
  284. void spi_format_init(SPI_Type *ptr, spi_format_config_t *config);
  285. /**
  286. * @brief spi transfer
  287. *
  288. * @param [in] ptr SPI base address
  289. * @param [in] config spi_control_config_t
  290. * @param [in,out] cmd spi transfer command address
  291. * @param [in] addr spi transfer target address
  292. * @param [in] wbuff spi sent data buff address
  293. * @param [in] wcount spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
  294. * @param [out] rbuff spi receive data buff address
  295. * @param [in] rcount spi receive data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
  296. * @retval hpm_stat_t status_success if spi transfer without any error
  297. */
  298. hpm_stat_t spi_transfer(SPI_Type *ptr,
  299. spi_control_config_t *config,
  300. uint8_t *cmd, uint32_t *addr,
  301. uint8_t *wbuff, uint32_t wcount, uint8_t *rbuff, uint32_t rcount);
  302. /**
  303. * @brief spi setup dma transfer
  304. *
  305. * @param [in] ptr SPI base address
  306. * @param [in] config spi_control_config_t
  307. * @param [in] cmd spi transfer command address
  308. * @param [in] addr spi transfer target address
  309. * @param [in] wcount spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
  310. * @param [in] rcount spi receive data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
  311. * @retval hpm_stat_t status_success if spi setup dma transfer without any error
  312. */
  313. hpm_stat_t spi_setup_dma_transfer(SPI_Type *ptr,
  314. spi_control_config_t *config,
  315. uint8_t *cmd, uint32_t *addr,
  316. uint32_t wcount, uint32_t rcount);
  317. /**
  318. * @brief spi wait for idle status
  319. *
  320. * @note on slave mode, if CS signal is asserted, take it as busy; if SPI CS signal is de-asserted, take it as idle.
  321. *
  322. * @param [in] ptr SPI base address
  323. * @retval hpm_stat_t status_success if spi in idle status
  324. */
  325. hpm_stat_t spi_wait_for_idle_status(SPI_Type *ptr);
  326. /**
  327. * @brief spi wait for busy status
  328. *
  329. * @note on slave mode, if CS signal is asserted, take it as busy; if SPI CS signal is de-asserted, take it as idle.
  330. *
  331. * @param [in] ptr SPI base address
  332. * @retval hpm_stat_t status_success if spi in busy status
  333. */
  334. hpm_stat_t spi_wait_for_busy_status(SPI_Type *ptr);
  335. /**
  336. * @brief SPI set TX FIFO threshold
  337. *
  338. * This function configures SPI TX FIFO threshold.
  339. *
  340. * @param ptr SPI base address.
  341. * @param threshold The FIFO threshold value, the value should not greater than FIFO size.
  342. */
  343. static inline void spi_set_tx_fifo_threshold(SPI_Type *ptr, uint32_t threshold)
  344. {
  345. ptr->CTRL = (ptr->CTRL & ~SPI_CTRL_TXTHRES_MASK) | SPI_CTRL_TXTHRES_SET(threshold);
  346. }
  347. /**
  348. * @brief SPI set RX FIFO threshold
  349. *
  350. * This function configures SPI RX FIFO threshold.
  351. *
  352. * @param ptr SPI base address.
  353. * @param threshold The FIFO threshold value, the value should not greater than FIFO size.
  354. */
  355. static inline void spi_set_rx_fifo_threshold(SPI_Type *ptr, uint32_t threshold)
  356. {
  357. ptr->CTRL = (ptr->CTRL & ~SPI_CTRL_RXTHRES_MASK) | SPI_CTRL_RXTHRES_SET(threshold);
  358. }
  359. /**
  360. * @brief Enables the SPI DMA request.
  361. *
  362. * This function configures the Rx and Tx DMA mask of the SPI. The parameters are base and a DMA mask.
  363. *
  364. * @param ptr SPI base address.
  365. * @param mask The dma enable mask; Use the spi_dma_enable_t.
  366. */
  367. static inline void spi_enable_dma(SPI_Type *ptr, uint32_t mask)
  368. {
  369. ptr->CTRL |= mask;
  370. }
  371. /*!
  372. * @brief Disables the SPI DMA request.
  373. *
  374. * This function configures the Rx and Tx DMA mask of the SPI. The parameters are base and a DMA mask.
  375. *
  376. * @param ptr SPI base address.
  377. * @param mask The dma enable mask; Use the spi_dma_enable_t.
  378. */
  379. static inline void spi_disable_dma(SPI_Type *ptr, uint32_t mask)
  380. {
  381. ptr->CTRL &= ~mask;
  382. }
  383. /**
  384. * @brief Get the SPI interrupt status.
  385. *
  386. * This function gets interrupt status of the SPI.
  387. *
  388. * @param ptr SPI base address.
  389. * @retval SPI interrupt status register value
  390. */
  391. static inline uint32_t spi_get_interrupt_status(SPI_Type *ptr)
  392. {
  393. return ptr->INTRST;
  394. }
  395. /**
  396. * @brief Clear the SPI interrupt status.
  397. *
  398. * This function clears interrupt status of the SPI.
  399. *
  400. * @param ptr SPI base address.
  401. * @param mask The interrupt mask; Use the spi_interrupt_t.
  402. *
  403. */
  404. static inline void spi_clear_interrupt_status(SPI_Type *ptr, uint32_t mask)
  405. {
  406. /* write 1 to clear */
  407. ptr->INTRST = mask;
  408. }
  409. /**
  410. * @brief Enables the SPI interrupt.
  411. *
  412. * This function configures interrupt of the SPI. The parameters are base and a interrupt mask.
  413. *
  414. * @param ptr SPI base address.
  415. * @param mask The interrupt mask; Use the spi_interrupt_t.
  416. */
  417. static inline void spi_enable_interrupt(SPI_Type *ptr, uint32_t mask)
  418. {
  419. ptr->INTREN |= mask;
  420. }
  421. /*!
  422. * @brief Disables the SPI interrupt.
  423. *
  424. * This function configures interrupt of the SPI. The parameters are base and a interrupt mask.
  425. *
  426. * @param ptr SPI base address.
  427. * @param mask The interrupt mask; Use the spi_interrupt_t.
  428. */
  429. static inline void spi_disable_interrupt(SPI_Type *ptr, uint32_t mask)
  430. {
  431. ptr->INTREN &= ~mask;
  432. }
  433. /**
  434. * @brief spi write and read data
  435. *
  436. * @note Call this function after SPI CONTROL is configured by spi_control_init.
  437. * The order of reading and writing is controlled by spi_control_init.
  438. *
  439. * @param [in] ptr SPI base address
  440. * @param [in] data_len_in_bytes data length in bytes
  441. * @param [in] wbuff spi sent data buff address
  442. * @param [in] wcount spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
  443. * @param [out] rbuff spi receive data buff address
  444. * @param [in] rcount spi receive data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
  445. * @retval hpm_stat_t status_success if spi transfer without any error
  446. */
  447. hpm_stat_t spi_write_read_data(SPI_Type *ptr, uint8_t data_len_in_bytes, uint8_t *wbuff, uint32_t wcount, uint8_t *rbuff, uint32_t rcount);
  448. /**
  449. * @brief spi read data
  450. *
  451. * @note Call this function after SPI CONTROL is configured by spi_control_init.
  452. *
  453. * @param [in] ptr SPI base address
  454. * @param [in] data_len_in_bytes data length in bytes
  455. * @param [out] buff spi receive data buff address
  456. * @param [in] count spi receive data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
  457. * @retval hpm_stat_t status_success if spi transfer without any error
  458. */
  459. hpm_stat_t spi_read_data(SPI_Type *ptr, uint8_t data_len_in_bytes, uint8_t *buff, uint32_t count);
  460. /**
  461. * @brief spi write data
  462. *
  463. * @note Call this function after SPI CONTROL is configured by spi_control_init.
  464. *
  465. * @param [in] ptr SPI base address
  466. * @param [in] data_len_in_bytes data length in bytes
  467. * @param [in] buff spi sent data buff address
  468. * @param [in] count spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
  469. * @retval hpm_stat_t status_success if spi transfer without any error
  470. */
  471. hpm_stat_t spi_write_data(SPI_Type *ptr, uint8_t data_len_in_bytes, uint8_t *buff, uint32_t count);
  472. /**
  473. * @brief spi write command
  474. *
  475. * Writing operations on this register will trigger SPI transfers, call this function on master mode.
  476. *
  477. * @param [in] ptr SPI base address
  478. * @param [in] mode spi mode, use the spi_mode_selection_t
  479. * @param [in] config point to spi_control_config_t
  480. * @param [in] cmd command data address
  481. * @retval hpm_stat_t status_success if spi transfer without any error
  482. */
  483. hpm_stat_t spi_write_command(SPI_Type *ptr, spi_mode_selection_t mode, spi_control_config_t *config, uint8_t *cmd);
  484. /**
  485. * @brief spi read command
  486. *
  487. * On slave mode, the command field of the last received SPI transaction is stored in this SPI Command Register
  488. *
  489. * @param [in] ptr SPI base address
  490. * @param [in] mode spi mode, use the spi_mode_selection_t
  491. * @param [in] config point to spi_control_config_t
  492. * @param [out] cmd command data address
  493. * @retval hpm_stat_t status_success if spi transfer without any error
  494. */
  495. hpm_stat_t spi_read_command(SPI_Type *ptr, spi_mode_selection_t mode, spi_control_config_t *config, uint8_t *cmd);
  496. /**
  497. * @brief spi write address
  498. *
  499. * @note Call this function on master mode.
  500. *
  501. * @param [in] ptr SPI base address
  502. * @param [in] mode spi mode, use the spi_mode_selection_t
  503. * @param [in] config point to spi_control_config_t
  504. * @param [in] addr point to address
  505. * @retval hpm_stat_t status_success if spi transfer without any error
  506. */
  507. hpm_stat_t spi_write_address(SPI_Type *ptr, spi_mode_selection_t mode, spi_control_config_t *config, uint32_t *addr);
  508. /**
  509. * @brief spi control initialization
  510. *
  511. * @param [in] ptr SPI base address
  512. * @param [in] config point to spi_control_config_t
  513. * @param [in] wcount spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
  514. * @param [in] rcount spi receive count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
  515. * @retval hpm_stat_t status_success if spi transfer without any error
  516. */
  517. hpm_stat_t spi_control_init(SPI_Type *ptr, spi_control_config_t *config, uint32_t wcount, uint32_t rcount);
  518. /**
  519. * @brief Get the SPI data length in bits.
  520. *
  521. * @param ptr SPI base address.
  522. * @retval SPI data length in bits
  523. */
  524. static inline uint8_t spi_get_data_length_in_bits(SPI_Type *ptr)
  525. {
  526. return ((ptr->TRANSFMT & SPI_TRANSFMT_DATALEN_MASK) >> SPI_TRANSFMT_DATALEN_SHIFT) + 1;
  527. }
  528. /**
  529. * @brief Get the SPI data length in bytes.
  530. *
  531. * @param ptr SPI base address.
  532. * @retval SPI data length in bytes
  533. */
  534. static inline uint8_t spi_get_data_length_in_bytes(SPI_Type *ptr)
  535. {
  536. return ((spi_get_data_length_in_bits(ptr) + 7U) / 8U);
  537. }
  538. /**
  539. * @brief SPI get active status.
  540. *
  541. * @param ptr SPI base address.
  542. * @retval bool true for active, false for inactive
  543. */
  544. static inline bool spi_is_active(SPI_Type *ptr)
  545. {
  546. return ((ptr->STATUS & SPI_STATUS_SPIACTIVE_MASK) == SPI_STATUS_SPIACTIVE_MASK) ? true : false;
  547. }
  548. /**
  549. * @brief SPI enable tx dma
  550. *
  551. * @param ptr SPI base address
  552. */
  553. static inline void spi_enable_tx_dma(SPI_Type *ptr)
  554. {
  555. ptr->CTRL |= SPI_CTRL_TXDMAEN_MASK;
  556. }
  557. /**
  558. * @brief SPI disable tx dma
  559. *
  560. * @param ptr SPI base address
  561. */
  562. static inline void spi_disable_tx_dma(SPI_Type *ptr)
  563. {
  564. ptr->CTRL &= ~SPI_CTRL_TXDMAEN_MASK;
  565. }
  566. /**
  567. * @brief SPI enable rx dma
  568. *
  569. * @param ptr SPI base address
  570. */
  571. static inline void spi_enable_rx_dma(SPI_Type *ptr)
  572. {
  573. ptr->CTRL |= SPI_CTRL_RXDMAEN_MASK;
  574. }
  575. /**
  576. * @brief SPI disable rx dma
  577. *
  578. * @param ptr SPI base address
  579. */
  580. static inline void spi_disable_rx_dma(SPI_Type *ptr)
  581. {
  582. ptr->CTRL &= ~SPI_CTRL_RXDMAEN_MASK;
  583. }
  584. /**
  585. * @brief SPI slave get sent data count
  586. *
  587. * @param ptr SPI base address
  588. * @retval uint32_t data count
  589. */
  590. static inline uint32_t spi_slave_get_sent_data_count(SPI_Type *ptr)
  591. {
  592. #if defined(HPM_IP_FEATURE_SPI_NEW_TRANS_COUNT) && (HPM_IP_FEATURE_SPI_NEW_TRANS_COUNT == 1)
  593. return ptr->SLVDATAWCNT;
  594. #else
  595. return SPI_SLVDATACNT_WCNT_GET(ptr->SLVDATACNT);
  596. #endif
  597. }
  598. /**
  599. * @brief SPI slave get received data count
  600. *
  601. * @param ptr SPI base address
  602. * @retval uint32_t data count
  603. */
  604. static inline uint32_t spi_slave_get_received_data_count(SPI_Type *ptr)
  605. {
  606. #if defined(HPM_IP_FEATURE_SPI_NEW_TRANS_COUNT) && (HPM_IP_FEATURE_SPI_NEW_TRANS_COUNT == 1)
  607. return ptr->SLVDATARCNT;
  608. #else
  609. return SPI_SLVDATACNT_RCNT_GET(ptr->SLVDATACNT);
  610. #endif
  611. }
  612. /**
  613. * @brief set spi clock phase
  614. *
  615. * @param [in] ptr SPI base address
  616. * @param [in] clock_phase clock phase enum
  617. */
  618. static inline void spi_set_clock_phase(SPI_Type *ptr, spi_sclk_sampling_clk_edges_t clock_phase)
  619. {
  620. ptr->TRANSFMT = (ptr->TRANSFMT & ~SPI_TRANSFMT_CPHA_MASK) | SPI_TRANSFMT_CPHA_SET(clock_phase);
  621. }
  622. /**
  623. * @brief get spi clock phase
  624. *
  625. * @param [in] ptr SPI base address
  626. * @retval spi_sclk_sampling_clk_edges_t spi_sclk_sampling_odd_clk_edges if CPHA is 0
  627. */
  628. static inline spi_sclk_sampling_clk_edges_t spi_get_clock_phase(SPI_Type *ptr)
  629. {
  630. return (spi_sclk_sampling_clk_edges_t)SPI_TRANSFMT_CPHA_GET(ptr->TRANSFMT);
  631. }
  632. /**
  633. * @brief set spi clock polarity
  634. *
  635. * @param [in] ptr SPI base address
  636. * @param [in] clock_polarity clock polarity enum
  637. */
  638. static inline void spi_set_clock_polarity(SPI_Type *ptr, spi_sclk_idle_state_t clock_polarity)
  639. {
  640. ptr->TRANSFMT = (ptr->TRANSFMT & ~SPI_TRANSFMT_CPOL_MASK) | SPI_TRANSFMT_CPOL_SET(clock_polarity);
  641. }
  642. /**
  643. * @brief get spi clock phase
  644. *
  645. * @param [in] ptr SPI base address
  646. * @retval spi_sclk_idle_state_t spi_sclk_low_idle if CPOL is 0
  647. */
  648. static inline spi_sclk_idle_state_t spi_get_clock_polarity(SPI_Type *ptr)
  649. {
  650. return (spi_sclk_idle_state_t)SPI_TRANSFMT_CPOL_GET(ptr->TRANSFMT);
  651. }
  652. /**
  653. * @brief set spi the length of each data unit in bits
  654. *
  655. * @param [in] ptr SPI base address
  656. * @param [in] nbits the actual bits number of a data
  657. * @retval hpm_stat_t status_success if spi transfer without any error
  658. */
  659. static inline hpm_stat_t spi_set_data_bits(SPI_Type *ptr, uint8_t nbits)
  660. {
  661. if (nbits > 32) {
  662. return status_invalid_argument;
  663. } else {
  664. ptr->TRANSFMT = (ptr->TRANSFMT & ~SPI_TRANSFMT_DATALEN_MASK) | SPI_TRANSFMT_DATALEN_SET(nbits - 1);
  665. return status_success;
  666. }
  667. }
  668. /**
  669. * @brief SPI transmit fifo reset
  670. *
  671. * @param ptr SPI base address
  672. */
  673. static inline void spi_transmit_fifo_reset(SPI_Type *ptr)
  674. {
  675. ptr->CTRL |= SPI_CTRL_TXFIFORST_MASK;
  676. }
  677. /**
  678. * @brief SPI receive fifo reset
  679. *
  680. * @param ptr SPI base address
  681. */
  682. static inline void spi_receive_fifo_reset(SPI_Type *ptr)
  683. {
  684. ptr->CTRL |= SPI_CTRL_RXFIFORST_MASK;
  685. }
  686. /**
  687. * @brief SPI reset
  688. *
  689. * @param ptr SPI base address
  690. */
  691. static inline void spi_reset(SPI_Type *ptr)
  692. {
  693. ptr->CTRL |= SPI_CTRL_SPIRST_MASK;
  694. }
  695. /**
  696. * @brief set spi the length of address
  697. *
  698. * @param [in] ptr SPI base address
  699. * @param [in] addrlen address lenth enum
  700. */
  701. static inline void spi_set_address_len(SPI_Type *ptr, spi_address_len_t addrlen)
  702. {
  703. ptr->TRANSFMT = (ptr->TRANSFMT & ~SPI_TRANSFMT_ADDRLEN_MASK) | SPI_TRANSFMT_ADDRLEN_SET(addrlen);
  704. }
  705. /**
  706. * @brief Enable SPI data merge
  707. *
  708. * @param [in] ptr SPI base address
  709. */
  710. static inline void spi_enable_data_merge(SPI_Type *ptr)
  711. {
  712. ptr->TRANSFMT |= SPI_TRANSFMT_DATAMERGE_MASK;
  713. }
  714. /**
  715. * @brief Disable SPI data merge
  716. *
  717. * @param [in] ptr SPI base address
  718. */
  719. static inline void spi_disable_data_merge(SPI_Type *ptr)
  720. {
  721. ptr->TRANSFMT &= ~SPI_TRANSFMT_DATAMERGE_MASK;
  722. }
  723. #if defined(HPM_IP_FEATURE_SPI_SUPPORT_DIRECTIO) && (HPM_IP_FEATURE_SPI_SUPPORT_DIRECTIO == 1)
  724. /**
  725. * @brief enable specific pin output for spi directio
  726. *
  727. * @note must be used spi_enable_directio API before enable output function
  728. *
  729. * @param [in] ptr SPI base address
  730. * @param [in] pin spi_directio_pin_t enum
  731. */
  732. hpm_stat_t spi_directio_enable_output(SPI_Type *ptr, spi_directio_pin_t pin);
  733. /**
  734. * @brief disable specific pin output for spi directio
  735. *
  736. * @param [in] ptr SPI base address
  737. * @param [in] pin spi_directio_pin_t enum
  738. */
  739. hpm_stat_t spi_directio_disable_output(SPI_Type *ptr, spi_directio_pin_t pin);
  740. /**
  741. * @brief write specified pin level for spi directio
  742. *
  743. * @param [in] ptr SPI base address
  744. * @param [in] pin spi_directio_pin_t enum
  745. * @param [in] high Pin level set to high when it is set to true
  746. */
  747. hpm_stat_t spi_directio_write(SPI_Type *ptr, spi_directio_pin_t pin, bool high);
  748. /**
  749. * @brief Read specified pin level for spi directio
  750. *
  751. * @param [in] ptr SPI base address
  752. * @param pin spi_directio_pin_t enum
  753. *
  754. * @return Pin status
  755. */
  756. uint8_t spi_directio_read(SPI_Type *ptr, spi_directio_pin_t pin);
  757. /**
  758. * @brief Enable SPI directIO control function
  759. *
  760. * @note if SPI transmission is required, the function must be disable
  761. *
  762. * @param [in] ptr SPI base address
  763. */
  764. static inline void spi_enable_directio(SPI_Type *ptr)
  765. {
  766. ptr->DIRECTIO |= SPI_DIRECTIO_DIRECTIOEN_MASK;
  767. }
  768. /**
  769. * @brief Disable SPI directIO control function
  770. *
  771. * @param [in] ptr SPI base address
  772. */
  773. static inline void spi_disable_directio(SPI_Type *ptr)
  774. {
  775. ptr->DIRECTIO &= ~SPI_DIRECTIO_DIRECTIOEN_MASK;
  776. }
  777. /**
  778. * @brief get whether spi directio function is enabled
  779. *
  780. * @param [in] ptr SPI base address
  781. *
  782. * @return if pi directio function is enable, it will return 1
  783. */
  784. static inline uint8_t spi_get_directio_enable_status(SPI_Type *ptr)
  785. {
  786. return SPI_DIRECTIO_DIRECTIOEN_GET(ptr->DIRECTIO);
  787. }
  788. #endif
  789. /**
  790. * @brief Get valid data size in receive FIFO
  791. *
  792. * @param [in] ptr SPI base address
  793. *
  794. * @return rx fifo valid data size
  795. */
  796. static inline uint8_t spi_get_rx_fifo_valid_data_size(SPI_Type *ptr)
  797. {
  798. return ((SPI_STATUS_RXNUM_7_6_GET(ptr->STATUS) << 5) | SPI_STATUS_RXNUM_5_0_GET(ptr->STATUS));
  799. }
  800. /**
  801. * @brief Get valid data size in transmit FIFO
  802. *
  803. * @param [in] ptr SPI base address
  804. *
  805. * @return tx fifo valid data size
  806. */
  807. static inline uint8_t spi_get_tx_fifo_valid_data_size(SPI_Type *ptr)
  808. {
  809. return ((SPI_STATUS_TXNUM_7_6_GET(ptr->STATUS) << 5) | SPI_STATUS_TXNUM_5_0_GET(ptr->STATUS));
  810. }
  811. /**
  812. * @brief Get SPI RXFIFO size
  813. *
  814. * @param [in] ptr SPI base address
  815. *
  816. * @return RXFIFO size, the unit is word
  817. */
  818. static inline uint8_t spi_get_rx_fifo_size(SPI_Type *ptr)
  819. {
  820. uint8_t size = SPI_CONFIG_RXFIFOSIZE_GET(ptr->CONFIG);
  821. return (2 << size);
  822. }
  823. /**
  824. * @brief Get SPI TXFIFO size
  825. *
  826. * @param [in] ptr SPI base address
  827. *
  828. * @return TXFIFO size, the unit is word
  829. */
  830. static inline uint8_t spi_get_tx_fifo_size(SPI_Type *ptr)
  831. {
  832. uint8_t size = SPI_CONFIG_TXFIFOSIZE_GET(ptr->CONFIG);
  833. return (2 << size);
  834. }
  835. /**
  836. * @brief SPI slave enable only date mode
  837. *
  838. * @note This mode only works in the uni-directional regular (single) mode
  839. * @param [in] ptr SPI base address
  840. */
  841. static inline void spi_slave_enable_data_only(SPI_Type *ptr)
  842. {
  843. ptr->TRANSCTRL |= SPI_TRANSCTRL_SLVDATAONLY_MASK;
  844. }
  845. /**
  846. * @brief SPI slave disable only date mode
  847. *
  848. * @param [in] ptr SPI base address
  849. */
  850. static inline void spi_slave_disable_data_only(SPI_Type *ptr)
  851. {
  852. ptr->TRANSCTRL &= ~SPI_TRANSCTRL_SLVDATAONLY_MASK;
  853. }
  854. /**
  855. * @brief SPI master enable command phase
  856. *
  857. * @param [in] ptr SPI base address
  858. */
  859. static inline void spi_master_enable_command_phase(SPI_Type *ptr)
  860. {
  861. ptr->TRANSCTRL |= SPI_TRANSCTRL_CMDEN_MASK;
  862. }
  863. /**
  864. * @brief SPI master disable command phase
  865. *
  866. * @param [in] ptr SPI base address
  867. */
  868. static inline void spi_master_disable_command_phase(SPI_Type *ptr)
  869. {
  870. ptr->TRANSCTRL &= ~SPI_TRANSCTRL_CMDEN_MASK;
  871. }
  872. /**
  873. * @brief SPI master enable address phase
  874. *
  875. * @param [in] ptr SPI base address
  876. */
  877. static inline void spi_master_enable_address_phase(SPI_Type *ptr)
  878. {
  879. ptr->TRANSCTRL |= SPI_TRANSCTRL_ADDREN_MASK;
  880. }
  881. /**
  882. * @brief SPI master disable address phase
  883. *
  884. * @param [in] ptr SPI base address
  885. */
  886. static inline void spi_master_disable_address_phase(SPI_Type *ptr)
  887. {
  888. ptr->TRANSCTRL &= ~SPI_TRANSCTRL_ADDREN_MASK;
  889. }
  890. /**
  891. * @brief SPI master set address phase format
  892. *
  893. * @param [in] ptr SPI base address
  894. * @param [in] format spi_addr_phase_format_t enum
  895. */
  896. static inline void spi_master_set_address_phase_format(SPI_Type *ptr, spi_addr_phase_format_t format)
  897. {
  898. ptr->TRANSCTRL = (ptr->TRANSCTRL & ~SPI_TRANSCTRL_ADDRFMT_MASK) | SPI_TRANSCTRL_ADDRFMT_SET(format);
  899. }
  900. /**
  901. * @brief SPI master set transfer mode
  902. *
  903. * @param [in] ptr SPI base address
  904. * @param [in] mode spi_trans_mode_t enum
  905. */
  906. static inline void spi_set_transfer_mode(SPI_Type *ptr, spi_trans_mode_t mode)
  907. {
  908. ptr->TRANSCTRL = (ptr->TRANSCTRL & ~SPI_TRANSCTRL_TRANSMODE_MASK) | SPI_TRANSCTRL_TRANSMODE_SET(mode);
  909. }
  910. /**
  911. * @brief SPI master enable token transfer
  912. *
  913. * @param [in] ptr SPI base address
  914. */
  915. static inline void spi_master_enable_token_transfer(SPI_Type *ptr)
  916. {
  917. ptr->TRANSCTRL |= SPI_TRANSCTRL_TOKENEN_MASK;
  918. }
  919. /**
  920. * @brief SPI master disable token transfer
  921. *
  922. * @param [in] ptr SPI base address
  923. */
  924. static inline void spi_master_disable_token_transfer(SPI_Type *ptr)
  925. {
  926. ptr->TRANSCTRL &= ~SPI_TRANSCTRL_TOKENEN_MASK;
  927. }
  928. /**
  929. * @brief SPI master set transfer count for write data
  930. *
  931. * @param [in] ptr SPI base address
  932. * @param [in] count the number of units of data to be transmitted to the SPI bus from the Data
  933. */
  934. static inline void spi_set_write_data_count(SPI_Type *ptr, uint32_t count)
  935. {
  936. #if defined(HPM_IP_FEATURE_SPI_NEW_TRANS_COUNT) && (HPM_IP_FEATURE_SPI_NEW_TRANS_COUNT == 1)
  937. ptr->WR_TRANS_CNT = (count - 1);
  938. #else
  939. ptr->TRANSCTRL = (ptr->TRANSCTRL & ~SPI_TRANSCTRL_WRTRANCNT_MASK) | SPI_TRANSCTRL_WRTRANCNT_SET(count - 1);
  940. #endif
  941. }
  942. /**
  943. * @brief SPI master set transfer count for read data
  944. *
  945. * @param [in] ptr SPI base address
  946. * @param [in] count the number of units of data to be received from SPI bus and stored to the Data
  947. */
  948. static inline void spi_set_read_data_count(SPI_Type *ptr, uint32_t count)
  949. {
  950. #if defined(HPM_IP_FEATURE_SPI_NEW_TRANS_COUNT) && (HPM_IP_FEATURE_SPI_NEW_TRANS_COUNT == 1)
  951. ptr->RD_TRANS_CNT = (count - 1);
  952. #else
  953. ptr->TRANSCTRL = (ptr->TRANSCTRL & ~SPI_TRANSCTRL_RDTRANCNT_MASK) | SPI_TRANSCTRL_RDTRANCNT_SET(count - 1);
  954. #endif
  955. }
  956. /**
  957. * @brief SPI master set the value of the one-byte special token following the address phase for SPI read transfers
  958. *
  959. * @param [in] ptr SPI base address
  960. * @param [in] value spi_token_value_t enum
  961. */
  962. static inline void spi_master_set_token_value(SPI_Type *ptr, spi_token_value_t value)
  963. {
  964. ptr->TRANSCTRL = (ptr->TRANSCTRL & ~SPI_TRANSCTRL_TOKENVALUE_MASK) | SPI_TRANSCTRL_TOKENVALUE_SET(value);
  965. }
  966. /**
  967. * @brief SPI master set dummy data count
  968. *
  969. * @param [in] ptr SPI base address
  970. * @param [in] count spi_dummy_count_t enum
  971. */
  972. static inline void spi_set_dummy_count(SPI_Type *ptr, spi_dummy_count_t count)
  973. {
  974. ptr->TRANSCTRL = (ptr->TRANSCTRL & ~SPI_TRANSCTRL_DUMMYCNT_MASK) | SPI_TRANSCTRL_DUMMYCNT_SET(count);
  975. }
  976. /**
  977. * @brief SPI master set the minimum time between the edges of SPI CS and the edges of SCLK
  978. *
  979. * @param [in] ptr SPI base address
  980. * @param [in] duration spi_cs2sclk_duration_t enum
  981. */
  982. static inline void spi_master_set_cs2sclk_timing(SPI_Type *ptr, spi_cs2sclk_duration_t duration)
  983. {
  984. ptr->TIMING = (ptr->TIMING & ~SPI_TIMING_CS2SCLK_MASK) | SPI_TIMING_CS2SCLK_SET(duration);
  985. }
  986. /**
  987. * @brief SPI master get the minimum time between the edges of SPI CS and the edges of SCLK
  988. *
  989. * @param [in] ptr SPI base address
  990. * @retval spi_cs2sclk_duration_t enum
  991. */
  992. static inline spi_cs2sclk_duration_t spi_master_get_cs2sclk_timing(SPI_Type *ptr)
  993. {
  994. return (spi_cs2sclk_duration_t)SPI_TIMING_CS2SCLK_GET(ptr->TIMING);
  995. }
  996. /**
  997. * @brief SPI master set the minimum time that SPI CS should stay HIGH.
  998. *
  999. * @param [in] ptr SPI base address
  1000. * @param [in] duration spi_csht_duration_t enum
  1001. */
  1002. static inline void spi_master_set_csht_timing(SPI_Type *ptr, spi_csht_duration_t duration)
  1003. {
  1004. ptr->TIMING = (ptr->TIMING & ~SPI_TIMING_CSHT_MASK) | SPI_TIMING_CSHT_SET(duration);
  1005. }
  1006. /**
  1007. * @brief SPI master get the minimum time that SPI CS should stay HIGH.
  1008. *
  1009. * @param [in] ptr SPI base address
  1010. * @retval spi_csht_duration_t enum
  1011. */
  1012. static inline spi_csht_duration_t spi_master_get_csht_timing(SPI_Type *ptr)
  1013. {
  1014. return (spi_csht_duration_t)SPI_TIMING_CSHT_GET(ptr->TIMING);
  1015. }
  1016. /**
  1017. * @brief SPI master set the clock frequency ratio between the clock source and SPI SCLK
  1018. *
  1019. * @param [in] ptr SPI base address
  1020. * @param [in] div the frequency ratio value
  1021. */
  1022. static inline void spi_master_set_sclk_div(SPI_Type *ptr, uint8_t div)
  1023. {
  1024. ptr->TIMING = (ptr->TIMING & ~SPI_TIMING_SCLK_DIV_MASK) | SPI_TIMING_SCLK_DIV_SET(div);
  1025. }
  1026. /**
  1027. * @brief SPI master get the clock frequency ratio between the clock source and SPI SCLK
  1028. *
  1029. * @param [in] ptr SPI base address
  1030. *
  1031. * @retval return the frequency ratio value
  1032. */
  1033. static inline uint8_t spi_master_get_sclk_div(SPI_Type *ptr)
  1034. {
  1035. return SPI_TIMING_SCLK_DIV_GET(ptr->TIMING);
  1036. }
  1037. /**
  1038. * @brief SPI slave set the user defined status flags
  1039. *
  1040. * @note in Non-SlvDataOnly, the command is read status command, such as 0x05\0x15\0x25 command
  1041. *
  1042. * @param [in] ptr SPI base address
  1043. * @param [in] user_status user status value
  1044. */
  1045. static inline void spi_slave_set_user_status(SPI_Type *ptr, uint16_t user_status)
  1046. {
  1047. ptr->SLVST = (ptr->SLVST & ~SPI_SLVST_USR_STATUS_MASK) | SPI_SLVST_USR_STATUS_SET(user_status);
  1048. }
  1049. /**
  1050. * @brief SPI master set data phase format
  1051. *
  1052. * @param [in] ptr SPI base address
  1053. * @param [in] format spi_data_phase_format_t enum
  1054. */
  1055. static inline void spi_master_set_data_phase_format(SPI_Type *ptr, spi_data_phase_format_t format)
  1056. {
  1057. ptr->TRANSCTRL = (ptr->TRANSCTRL & ~SPI_TRANSCTRL_DUALQUAD_MASK) | SPI_TRANSCTRL_DUALQUAD_SET(format);
  1058. }
  1059. /**
  1060. * @brief SPI master get data phase format
  1061. *
  1062. * @param [in] ptr SPI base address
  1063. *
  1064. * @retval return the data phase format
  1065. */
  1066. static inline spi_data_phase_format_t spi_master_get_data_phase_format(SPI_Type *ptr)
  1067. {
  1068. return (spi_data_phase_format_t)SPI_TRANSCTRL_DUALQUAD_GET(ptr->TRANSCTRL);
  1069. }
  1070. /**
  1071. * @brief set spi shift direction
  1072. *
  1073. * @param [in] ptr SPI base address
  1074. * @param [in] shift_direction shift direction enum
  1075. */
  1076. static inline void spi_set_shift_direction(SPI_Type *ptr, spi_shift_direction_t shift_direction)
  1077. {
  1078. ptr->TRANSFMT = (ptr->TRANSFMT & ~SPI_TRANSFMT_LSB_MASK) | SPI_TRANSFMT_LSB_SET(shift_direction);
  1079. }
  1080. /**
  1081. * @brief get spi shift direction
  1082. *
  1083. * @param [in] ptr SPI base address
  1084. * @retval spi_shift_direction_t msb_first if frist MSB
  1085. */
  1086. static inline spi_shift_direction_t spi_get_shift_direction(SPI_Type *ptr)
  1087. {
  1088. return (spi_shift_direction_t)SPI_TRANSFMT_LSB_GET(ptr->TRANSFMT);
  1089. }
  1090. /**
  1091. * @}
  1092. */
  1093. #if defined(__cplusplus)
  1094. }
  1095. #endif /* __cplusplus */
  1096. #endif /* HPM_SPI_DRV_H */