spi.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. /* Copyright 2018 Canaan Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #ifndef _DRIVER_SPI_H
  16. #define _DRIVER_SPI_H
  17. #include <stddef.h>
  18. #include <stdint.h>
  19. #include "dmac.h"
  20. #ifdef __cplusplus
  21. extern "C" {
  22. #endif
  23. /* clang-format off */
  24. typedef struct _spi
  25. {
  26. /* SPI Control Register 0 (0x00)*/
  27. volatile uint32_t ctrlr0;
  28. /* SPI Control Register 1 (0x04)*/
  29. volatile uint32_t ctrlr1;
  30. /* SPI Enable Register (0x08)*/
  31. volatile uint32_t ssienr;
  32. /* SPI Microwire Control Register (0x0c)*/
  33. volatile uint32_t mwcr;
  34. /* SPI Slave Enable Register (0x10)*/
  35. volatile uint32_t ser;
  36. /* SPI Baud Rate Select (0x14)*/
  37. volatile uint32_t baudr;
  38. /* SPI Transmit FIFO Threshold Level (0x18)*/
  39. volatile uint32_t txftlr;
  40. /* SPI Receive FIFO Threshold Level (0x1c)*/
  41. volatile uint32_t rxftlr;
  42. /* SPI Transmit FIFO Level Register (0x20)*/
  43. volatile uint32_t txflr;
  44. /* SPI Receive FIFO Level Register (0x24)*/
  45. volatile uint32_t rxflr;
  46. /* SPI Status Register (0x28)*/
  47. volatile uint32_t sr;
  48. /* SPI Interrupt Mask Register (0x2c)*/
  49. volatile uint32_t imr;
  50. /* SPI Interrupt Status Register (0x30)*/
  51. volatile uint32_t isr;
  52. /* SPI Raw Interrupt Status Register (0x34)*/
  53. volatile uint32_t risr;
  54. /* SPI Transmit FIFO Overflow Interrupt Clear Register (0x38)*/
  55. volatile uint32_t txoicr;
  56. /* SPI Receive FIFO Overflow Interrupt Clear Register (0x3c)*/
  57. volatile uint32_t rxoicr;
  58. /* SPI Receive FIFO Underflow Interrupt Clear Register (0x40)*/
  59. volatile uint32_t rxuicr;
  60. /* SPI Multi-Master Interrupt Clear Register (0x44)*/
  61. volatile uint32_t msticr;
  62. /* SPI Interrupt Clear Register (0x48)*/
  63. volatile uint32_t icr;
  64. /* SPI DMA Control Register (0x4c)*/
  65. volatile uint32_t dmacr;
  66. /* SPI DMA Transmit Data Level (0x50)*/
  67. volatile uint32_t dmatdlr;
  68. /* SPI DMA Receive Data Level (0x54)*/
  69. volatile uint32_t dmardlr;
  70. /* SPI Identification Register (0x58)*/
  71. volatile uint32_t idr;
  72. /* SPI DWC_ssi component version (0x5c)*/
  73. volatile uint32_t ssic_version_id;
  74. /* SPI Data Register 0-36 (0x60 -- 0xec)*/
  75. volatile uint32_t dr[36];
  76. /* SPI RX Sample Delay Register (0xf0)*/
  77. volatile uint32_t rx_sample_delay;
  78. /* SPI SPI Control Register (0xf4)*/
  79. volatile uint32_t spi_ctrlr0;
  80. /* reserved (0xf8)*/
  81. volatile uint32_t resv;
  82. /* SPI XIP Mode bits (0xfc)*/
  83. volatile uint32_t xip_mode_bits;
  84. /* SPI XIP INCR transfer opcode (0x100)*/
  85. volatile uint32_t xip_incr_inst;
  86. /* SPI XIP WRAP transfer opcode (0x104)*/
  87. volatile uint32_t xip_wrap_inst;
  88. /* SPI XIP Control Register (0x108)*/
  89. volatile uint32_t xip_ctrl;
  90. /* SPI XIP Slave Enable Register (0x10c)*/
  91. volatile uint32_t xip_ser;
  92. /* SPI XIP Receive FIFO Overflow Interrupt Clear Register (0x110)*/
  93. volatile uint32_t xrxoicr;
  94. /* SPI XIP time out register for continuous transfers (0x114)*/
  95. volatile uint32_t xip_cnt_time_out;
  96. volatile uint32_t endian;
  97. } __attribute__((packed, aligned(4))) spi_t;
  98. /* clang-format on */
  99. typedef enum _spi_device_num
  100. {
  101. SPI_DEVICE_0,
  102. SPI_DEVICE_1,
  103. SPI_DEVICE_2,
  104. SPI_DEVICE_3,
  105. SPI_DEVICE_MAX,
  106. } spi_device_num_t;
  107. typedef enum _spi_work_mode
  108. {
  109. SPI_WORK_MODE_0,
  110. SPI_WORK_MODE_1,
  111. SPI_WORK_MODE_2,
  112. SPI_WORK_MODE_3,
  113. } spi_work_mode_t;
  114. typedef enum _spi_frame_format
  115. {
  116. SPI_FF_STANDARD,
  117. SPI_FF_DUAL,
  118. SPI_FF_QUAD,
  119. SPI_FF_OCTAL
  120. } spi_frame_format_t;
  121. typedef enum _spi_instruction_address_trans_mode
  122. {
  123. SPI_AITM_STANDARD,
  124. SPI_AITM_ADDR_STANDARD,
  125. SPI_AITM_AS_FRAME_FORMAT
  126. } spi_instruction_address_trans_mode_t;
  127. typedef enum _spi_transfer_mode
  128. {
  129. SPI_TMOD_TRANS_RECV,
  130. SPI_TMOD_TRANS,
  131. SPI_TMOD_RECV,
  132. SPI_TMOD_EEROM
  133. } spi_transfer_mode_t;
  134. typedef enum _spi_transfer_width
  135. {
  136. SPI_TRANS_CHAR = 0x1,
  137. SPI_TRANS_SHORT = 0x2,
  138. SPI_TRANS_INT = 0x4,
  139. } spi_transfer_width_t;
  140. typedef enum _spi_chip_select
  141. {
  142. SPI_CHIP_SELECT_0,
  143. SPI_CHIP_SELECT_1,
  144. SPI_CHIP_SELECT_2,
  145. SPI_CHIP_SELECT_3,
  146. SPI_CHIP_SELECT_MAX,
  147. } spi_chip_select_t;
  148. typedef enum
  149. {
  150. WRITE_CONFIG,
  151. READ_CONFIG,
  152. WRITE_DATA_BYTE,
  153. READ_DATA_BYTE,
  154. WRITE_DATA_BLOCK,
  155. READ_DATA_BLOCK,
  156. } spi_slave_command_e;
  157. typedef struct
  158. {
  159. uint8_t cmd;
  160. uint8_t err;
  161. uint32_t addr;
  162. uint32_t len;
  163. } spi_slave_command_t;
  164. typedef enum
  165. {
  166. IDLE,
  167. COMMAND,
  168. TRANSFER,
  169. } spi_slave_status_e;
  170. typedef int (*spi_slave_receive_callback_t)(void *ctx);
  171. typedef struct _spi_slave_instance
  172. {
  173. uint8_t int_pin;
  174. uint8_t ready_pin;
  175. dmac_channel_number_t dmac_channel;
  176. uint8_t dfs;
  177. uint8_t slv_oe;
  178. uint8_t work_mode;
  179. size_t data_bit_length;
  180. volatile spi_slave_status_e status;
  181. volatile spi_slave_command_t command;
  182. volatile uint8_t *config_ptr;
  183. uint32_t config_len;
  184. spi_slave_receive_callback_t callback;
  185. uint8_t is_dual;
  186. uint8_t mosi_pin;
  187. uint8_t miso_pin;
  188. } spi_slave_instance_t;
  189. typedef struct _spi_data_t
  190. {
  191. dmac_channel_number_t tx_channel;
  192. dmac_channel_number_t rx_channel;
  193. uint32_t *tx_buf;
  194. size_t tx_len;
  195. uint32_t *rx_buf;
  196. size_t rx_len;
  197. spi_transfer_mode_t transfer_mode;
  198. bool fill_mode;
  199. } spi_data_t;
  200. extern volatile spi_t *const spi[4];
  201. /**
  202. * @brief Set spi configuration
  203. *
  204. * @param[in] spi_num Spi bus number
  205. * @param[in] mode Spi mode
  206. * @param[in] frame_format Spi frame format
  207. * @param[in] data_bit_length Spi data bit length
  208. * @param[in] endian 0:little-endian 1:big-endian
  209. *
  210. * @return Void
  211. */
  212. void spi_init(spi_device_num_t spi_num, spi_work_mode_t work_mode, spi_frame_format_t frame_format,
  213. size_t data_bit_length, uint32_t endian);
  214. /**
  215. * @brief Set multiline configuration
  216. *
  217. * @param[in] spi_num Spi bus number
  218. * @param[in] instruction_length Instruction length
  219. * @param[in] address_length Address length
  220. * @param[in] wait_cycles Wait cycles
  221. * @param[in] instruction_address_trans_mode Spi transfer mode
  222. *
  223. */
  224. void spi_init_non_standard(spi_device_num_t spi_num, uint32_t instruction_length, uint32_t address_length,
  225. uint32_t wait_cycles, spi_instruction_address_trans_mode_t instruction_address_trans_mode);
  226. /**
  227. * @brief Spi send data
  228. *
  229. * @param[in] spi_num Spi bus number
  230. * @param[in] chip_select Spi chip select
  231. * @param[in] cmd_buff Spi command buffer point
  232. * @param[in] cmd_len Spi command length
  233. * @param[in] tx_buff Spi transmit buffer point
  234. * @param[in] tx_len Spi transmit buffer length
  235. *
  236. * @return Result
  237. * - 0 Success
  238. * - Other Fail
  239. */
  240. void spi_send_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *cmd_buff,
  241. size_t cmd_len, const uint8_t *tx_buff, size_t tx_len);
  242. /**
  243. * @brief Spi receive data
  244. *
  245. * @param[in] spi_num Spi bus number
  246. * @param[in] chip_select Spi chip select
  247. * @param[in] cmd_buff Spi command buffer point
  248. * @param[in] cmd_len Spi command length
  249. * @param[in] rx_buff Spi receive buffer point
  250. * @param[in] rx_len Spi receive buffer length
  251. *
  252. * @return Result
  253. * - 0 Success
  254. * - Other Fail
  255. */
  256. void spi_receive_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *cmd_buff,
  257. size_t cmd_len, uint8_t *rx_buff, size_t rx_len);
  258. /**
  259. * @brief Spi special receive data
  260. *
  261. * @param[in] spi_num Spi bus number
  262. * @param[in] chip_select Spi chip select
  263. * @param[in] cmd_buff Spi command buffer point
  264. * @param[in] cmd_len Spi command length
  265. * @param[in] rx_buff Spi receive buffer point
  266. * @param[in] rx_len Spi receive buffer length
  267. *
  268. * @return Result
  269. * - 0 Success
  270. * - Other Fail
  271. */
  272. void spi_receive_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *cmd_buff,
  273. size_t cmd_len, uint8_t *rx_buff, size_t rx_len);
  274. /**
  275. * @brief Spi special send data
  276. *
  277. * @param[in] spi_num Spi bus number
  278. * @param[in] chip_select Spi chip select
  279. * @param[in] cmd_buff Spi command buffer point
  280. * @param[in] cmd_len Spi command length
  281. * @param[in] tx_buff Spi transmit buffer point
  282. * @param[in] tx_len Spi transmit buffer length
  283. *
  284. * @return Result
  285. * - 0 Success
  286. * - Other Fail
  287. */
  288. void spi_send_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *cmd_buff,
  289. size_t cmd_len, const uint8_t *tx_buff, size_t tx_len);
  290. /**
  291. * @brief Spi send data by dma
  292. *
  293. * @param[in] channel_num Dmac channel number
  294. * @param[in] spi_num Spi bus number
  295. * @param[in] chip_select Spi chip select
  296. * @param[in] cmd_buff Spi command buffer point
  297. * @param[in] cmd_len Spi command length
  298. * @param[in] tx_buff Spi transmit buffer point
  299. * @param[in] tx_len Spi transmit buffer length
  300. *
  301. * @return Result
  302. * - 0 Success
  303. * - Other Fail
  304. */
  305. void spi_send_data_standard_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num,
  306. spi_chip_select_t chip_select,
  307. const uint8_t *cmd_buff, size_t cmd_len, const uint8_t *tx_buff, size_t tx_len);
  308. /**
  309. * @brief Spi receive data by dma
  310. *
  311. * @param[in] w_channel_num Dmac write channel number
  312. * @param[in] r_channel_num Dmac read channel number
  313. * @param[in] spi_num Spi bus number
  314. * @param[in] chip_select Spi chip select
  315. * @param[in] cmd_buff Spi command buffer point
  316. * @param[in] cmd_len Spi command length
  317. * @param[in] rx_buff Spi receive buffer point
  318. * @param[in] rx_len Spi receive buffer length
  319. *
  320. * @return Result
  321. * - 0 Success
  322. * - Other Fail
  323. */
  324. void spi_receive_data_standard_dma(dmac_channel_number_t dma_send_channel_num,
  325. dmac_channel_number_t dma_receive_channel_num,
  326. spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *cmd_buff,
  327. size_t cmd_len, uint8_t *rx_buff, size_t rx_len);
  328. /**
  329. * @brief Spi special send data by dma
  330. *
  331. * @param[in] channel_num Dmac channel number
  332. * @param[in] spi_num Spi bus number
  333. * @param[in] chip_select Spi chip select
  334. * @param[in] cmd_buff Spi command buffer point
  335. * @param[in] cmd_len Spi command length
  336. * @param[in] tx_buff Spi transmit buffer point
  337. * @param[in] tx_len Spi transmit buffer length
  338. *
  339. * @return Result
  340. * - 0 Success
  341. * - Other Fail
  342. */
  343. void spi_send_data_multiple_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num,
  344. spi_chip_select_t chip_select,
  345. const uint32_t *cmd_buff, size_t cmd_len, const uint8_t *tx_buff, size_t tx_len);
  346. /**
  347. * @brief Spi special receive data by dma
  348. *
  349. * @param[in] dma_send_channel_num Dmac write channel number
  350. * @param[in] dma_receive_channel_num Dmac read channel number
  351. * @param[in] spi_num Spi bus number
  352. * @param[in] chip_select Spi chip select
  353. * @param[in] cmd_buff Spi command buffer point
  354. * @param[in] cmd_len Spi command length
  355. * @param[in] rx_buff Spi receive buffer point
  356. * @param[in] rx_len Spi receive buffer length
  357. *
  358. * @return Result
  359. * - 0 Success
  360. * - Other Fail
  361. */
  362. void spi_receive_data_multiple_dma(dmac_channel_number_t dma_send_channel_num,
  363. dmac_channel_number_t dma_receive_channel_num,
  364. spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *cmd_buff,
  365. size_t cmd_len, uint8_t *rx_buff, size_t rx_len);
  366. /**
  367. * @brief Spi fill dma
  368. *
  369. * @param[in] channel_num Dmac channel number
  370. * @param[in] spi_num Spi bus number
  371. * @param[in] chip_select Spi chip select
  372. * @param[in] tx_buff Spi command buffer point
  373. * @param[in] tx_len Spi command length
  374. *
  375. * @return Result
  376. * - 0 Success
  377. * - Other Fail
  378. */
  379. void spi_fill_data_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, spi_chip_select_t chip_select,
  380. const uint32_t *tx_buff, size_t tx_len);
  381. /**
  382. * @brief Spi normal send by dma
  383. *
  384. * @param[in] channel_num Dmac channel number
  385. * @param[in] spi_num Spi bus number
  386. * @param[in] chip_select Spi chip select
  387. * @param[in] tx_buff Spi transmit buffer point
  388. * @param[in] tx_len Spi transmit buffer length
  389. * @param[in] stw Spi transfer width
  390. *
  391. * @return Result
  392. * - 0 Success
  393. * - Other Fail
  394. */
  395. void spi_send_data_normal_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num,
  396. spi_chip_select_t chip_select,
  397. const void *tx_buff, size_t tx_len, spi_transfer_width_t spi_transfer_width);
  398. /**
  399. * @brief Spi normal send by dma
  400. *
  401. * @param[in] spi_num Spi bus number
  402. * @param[in] spi_clk Spi clock rate
  403. *
  404. * @return The real spi clock rate
  405. */
  406. uint32_t spi_set_clk_rate(spi_device_num_t spi_num, uint32_t spi_clk);
  407. /**
  408. * @brief Spi full duplex send receive data by dma
  409. *
  410. * @param[in] dma_send_channel_num Dmac write channel number
  411. * @param[in] dma_receive_channel_num Dmac read channel number
  412. * @param[in] spi_num Spi bus number
  413. * @param[in] chip_select Spi chip select
  414. * @param[in] tx_buf Spi send buffer
  415. * @param[in] tx_len Spi send buffer length
  416. * @param[in] rx_buf Spi receive buffer
  417. * @param[in] rx_len Spi receive buffer length
  418. *
  419. */
  420. void spi_dup_send_receive_data_dma(dmac_channel_number_t dma_send_channel_num,
  421. dmac_channel_number_t dma_receive_channel_num,
  422. spi_device_num_t spi_num, spi_chip_select_t chip_select,
  423. const uint8_t *tx_buf, size_t tx_len, uint8_t *rx_buf, size_t rx_len);
  424. /**
  425. * @brief Set spi slave configuration
  426. *
  427. * @param[in] int_pin SPI master starts sending data interrupt.
  428. * @param[in] ready_pin SPI slave ready.
  429. * @param[in] dmac_channel Dmac channel number for block.
  430. * @param[in] data_bit_length Spi data bit length
  431. * @param[in] data SPI slave device data buffer.
  432. * @param[in] len The length of SPI slave device data buffer.
  433. * @param[in] callback Callback of spi slave.
  434. *
  435. * @return Void
  436. */
  437. void spi_slave_config(uint8_t int_pin, uint8_t ready_pin, dmac_channel_number_t dmac_channel, size_t data_bit_length, uint8_t *data, uint32_t len, spi_slave_receive_callback_t callback);
  438. void spi_slave_dual_config(uint8_t int_pin,
  439. uint8_t ready_pin,
  440. uint8_t mosi_pin,
  441. uint8_t miso_pin,
  442. dmac_channel_number_t dmac_channel,
  443. size_t data_bit_length,
  444. uint8_t *data,
  445. uint32_t len,
  446. spi_slave_receive_callback_t callback);
  447. /**
  448. * @brief Spi handle transfer data operations
  449. *
  450. * @param[in] spi_num Spi bus number
  451. * @param[in] chip_select Spi chip select
  452. * @param[in] data Spi transfer data information
  453. * @param[in] cb Spi DMA callback
  454. *
  455. */
  456. void spi_handle_data_dma(spi_device_num_t spi_num, spi_chip_select_t chip_select, spi_data_t data, plic_interrupt_t *cb);
  457. #ifdef __cplusplus
  458. }
  459. #endif
  460. #endif /* _DRIVER_SPI_H */