ql_api_spi.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. /** @file
  2. ql_api_spi.h
  3. @brief
  4. This file is used to define bt api for different Quectel Project.
  5. */
  6. /*================================================================
  7. Copyright (c) 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
  8. Quectel Wireless Solution Proprietary and Confidential.
  9. =================================================================*/
  10. /*=================================================================
  11. EDIT HISTORY FOR MODULE
  12. This section contains comments describing changes made to the module.
  13. Notice that changes are listed in reverse chronological order.
  14. WHEN WHO WHAT, WHERE, WHY
  15. ------------ ------- -------------------------------------------------------------------------------
  16. =================================================================*/
  17. #ifndef QL_API_SPI_H
  18. #define QL_API_SPI_H
  19. #include "ql_api_common.h"
  20. #ifdef __cplusplus
  21. extern "C" {
  22. #endif
  23. #include "quec_pin_index.h"
  24. #include "ql_gpio.h"
  25. /*========================================================================
  26. * Variable Definition
  27. *========================================================================*/
  28. #define QL_CUR_SPI1_CS_PIN QUEC_PIN_SPI1_CS
  29. #define QL_CUR_SPI1_CS_FUNC QUEC_PIN_SPI1_FUNC
  30. #define QL_CUR_SPI1_CLK_PIN QUEC_PIN_SPI1_CLK
  31. #define QL_CUR_SPI1_CLK_FUNC QUEC_PIN_SPI1_FUNC
  32. #define QL_CUR_SPI1_DO_PIN QUEC_PIN_SPI1_MOSI
  33. #define QL_CUR_SPI1_DO_FUNC QUEC_PIN_SPI1_FUNC
  34. #define QL_CUR_SPI1_DI_PIN QUEC_PIN_SPI1_MISO
  35. #define QL_CUR_SPI1_DI_FUNC QUEC_PIN_SPI1_FUNC
  36. #define QL_CUR_SPI2_CS_PIN QUEC_PIN_SPI2_CS
  37. #define QL_CUR_SPI2_CS_FUNC QUEC_PIN_SPI2_FUNC
  38. #define QL_CUR_SPI2_CLK_PIN QUEC_PIN_SPI2_CLK
  39. #define QL_CUR_SPI2_CLK_FUNC QUEC_PIN_SPI2_FUNC
  40. #define QL_CUR_SPI2_DO_PIN QUEC_PIN_SPI2_MOSI
  41. #define QL_CUR_SPI2_DO_FUNC QUEC_PIN_SPI2_FUNC
  42. #define QL_CUR_SPI2_DI_PIN QUEC_PIN_SPI2_MISO
  43. #define QL_CUR_SPI2_DI_FUNC QUEC_PIN_SPI2_FUNC
  44. //8910 spi dma缓存大小是512字节,可以一次传输最大512字节的数据。
  45. //#define QL_SPI_DMA_IRQ_SIZE 512 //QL_SPI_DMA_IRQ模式最多只有512个字节
  46. //#define QL_SPI_DMA_ADDR_ALIN 32 //QL_SPI_DMA_IRQ和QL_SPI_DMA_POLLING模式,cache为32字节对齐
  47. //#define QL_SPI_FIFO_SIZE 16 //SPI的发送和接收FIFO都是16的长度
  48. //8850 spi dma没有缓存,所以dma每次最多只能传输一个FIFO的大小(32字节),如果使用dma中断模式,会每32字节进一次中断。
  49. #define QL_SPI_DMA_IRQ_SIZE 512 //QL_SPI_DMA_IRQ模式最多只有512个字节,8850此参数无意义。
  50. #define QL_SPI_DMA_ADDR_ALIN 32 //QL_SPI_DMA_IRQ和QL_SPI_DMA_POLLING模式,地址必须32字节对齐
  51. #define QL_SPI_FIFO_SIZE 32 //SPI的发送和接收FIFO都是32的长度
  52. /**************************** error code about ql spi ***************************/
  53. typedef enum
  54. {
  55. QL_SPI_SUCCESS = 0,
  56. QL_SPI_ERROR = 1 | (QL_COMPONENT_BSP_SPI << 16), //SPI总线其他错误
  57. QL_SPI_PARAM_TYPE_ERROR, //参数类型错误
  58. QL_SPI_PARAM_DATA_ERROR, //参数数据错误
  59. QL_SPI_PARAM_ACQUIRE_ERROR, //参数无法获取
  60. QL_SPI_PARAM_NULL_ERROR, //参数NULL错误
  61. QL_SPI_DEV_NOT_ACQUIRE_ERROR, //无法获取SPI总线
  62. QL_SPI_PARAM_LENGTH_ERROR, //参数长度错误
  63. QL_SPI_MALLOC_MEM_ERROR, //申请内存错误
  64. QL_SPI_ADDR_ALIGNED_ERROR, //地址不是4字节对齐
  65. QL_SPI_MUTEX_CREATE_ERROR, //互斥锁创建失败报错
  66. QL_SPI_MUTEX_LOCK_ERROR, //互斥锁上锁超时报错
  67. QL_SPI_SET_GPIO_ERROR, //设置GPIO出错
  68. QL_SPI_DEV_BUSY_ERROR, //设备忙出错
  69. }ql_errcode_spi_e;
  70. typedef enum
  71. {
  72. QL_SPI_CS0 = 0, //选择cs0为SPI片选CS引脚
  73. QL_SPI_CS1, //选择cs1为SPI片选CS引脚
  74. QL_SPI_CS2, //选择cs2为SPI片选CS引脚,not use now
  75. QL_SPI_CS3, //选择cs3为SPI片选CS引脚,not use now
  76. QL_SPI_GPIO, //使用控制GPIO的方式来控制CS功能。注意,对应的CS引脚不要再配置成SPI CS功能,需要配置成GPIO
  77. }ql_spi_cs_sel_e;
  78. typedef enum
  79. {
  80. QL_SPI_INPUT_FALSE, //SPI不允许输入(读取)
  81. QL_SPI_INPUT_TRUE, //SPI允许输入(读取)
  82. }ql_spi_input_mode_e;
  83. typedef enum
  84. {
  85. QL_SPI_PORT1, //SPI1总线
  86. QL_SPI_PORT2, //SPI2总线
  87. }ql_spi_port_e;
  88. typedef enum
  89. {
  90. QL_SPI_CS_ACTIVE_HIGH, //SPI总线操作时,CS脚为高
  91. QL_SPI_CS_ACTIVE_LOW, //SPI总线操作时,CS脚为低
  92. } ql_spi_cs_pol_e;
  93. typedef enum
  94. {
  95. QL_SPI_CPOL_LOW = 0, //SPI未使能时,CLK线为低电平,第一个边沿是上升沿
  96. QL_SPI_CPOL_HIGH, //SPI未使能时,CLK线为高电平,第一个边沿是下降沿
  97. } ql_spi_cpol_pol_e;
  98. typedef enum
  99. {
  100. QL_SPI_CPHA_1Edge, //MOSI延时一个边沿,CLK和MISO延时两个边沿,即发送的数据先准备好,才有CLK
  101. QL_SPI_CPHA_2Edge, //MOSI延时两个边沿,CLK延时2个边沿,MISO延时3个边沿。数据和CLK同时准备好
  102. }ql_spi_cpha_pol_e;
  103. //SPI mode0:ql_spi_cpol_pol_e选择QL_SPI_CPOL_LOW,ql_spi_cpha_pol_e选择QL_SPI_CPHA_1Edge
  104. //SPI mode1:ql_spi_cpol_pol_e选择QL_SPI_CPOL_LOW,ql_spi_cpha_pol_e选择QL_SPI_CPHA_2Edge
  105. //SPI mode2:ql_spi_cpol_pol_e选择QL_SPI_CPOL_HIGH,ql_spi_cpha_pol_e选择QL_SPI_CPHA_1Edge
  106. //SPI mode3:ql_spi_cpol_pol_e选择QL_SPI_CPOL_HIGH,ql_spi_cpha_pol_e选择QL_SPI_CPHA_2Edge
  107. typedef enum
  108. {
  109. QL_SPI_DI_0 = 0, //选择DI0为数据输入引脚,not use now
  110. QL_SPI_DI_1, //选择DI1为数据输入引脚
  111. QL_SPI_DI_2, //选择DI2为数据输入引脚,not use now
  112. }ql_spi_input_sel_e;
  113. typedef enum
  114. {
  115. QL_SPI_DIRECT_POLLING = 0, //FIFO读写,轮询等待。
  116. QL_SPI_DIRECT_IRQ, //FIFO读写,中断通知,not use now
  117. QL_SPI_DMA_POLLING, //DMA读写,轮询等待。此模式下,和SD卡不能同时使用。使能SD卡情形下,申请DMA通道失败,SPI初始化会失败
  118. QL_SPI_DMA_IRQ, //DMA读写,中断通知,最大支持512个字节
  119. }ql_spi_transfer_mode_e;
  120. //spi_sck = clk_spi/2(n+1)
  121. //clk_spi=167M,n=0,spi_sck=83.5M;n=1,spi_sck=41.75M;n=2,spi_sck=27.83M;n=3,spi_sck=20.875M;n=4,spi_sck=16.7M;n=5,spi_sck=13.92M;n=6,spi_sck=11.93M;
  122. //clk_spi=26M,n=0,spi_sck=13M;n=1,spi_sck=6.6M;n=2,spi_sck=4.333M;;n=3,spi_sck=3.25M;n=4,spi_sck=2.6M;n=5,spi_sck=2M;n=6,spi_sck=1.857M;n=7,spi_sck=1.625M;n=8,spi_sck=1.444M;n=9,spi_sck=1.3M;n=10,spi_sck=1.182M;
  123. typedef enum
  124. {
  125. QL_SPI_CLK_INVALID=-1, //无效时钟选择
  126. QL_SPI_CLK_97_656KHZ_MIN = 97656, //时钟:97.656K
  127. QL_SPI_CLK_100KHZ = 100000, //时钟:100K
  128. QL_SPI_CLK_812_5KHZ = 812500, //时钟:812.5K
  129. QL_SPI_CLK_1_3MHZ = 1300000, //时钟:1.3M
  130. QL_SPI_CLK_1_625MHZ = 1625000, //时钟:1.625M
  131. QL_SPI_CLK_1_5625MHZ = QL_SPI_CLK_1_625MHZ, //时钟:1.5625M 8850不支持,如果选择实际是1.625M
  132. QL_SPI_CLK_2MHZ = 2000000, //时钟:2M
  133. QL_SPI_CLK_3_25MHZ = 3250000, //时钟:3.25M
  134. QL_SPI_CLK_4_333MHZ = 4333000, //时钟:4.333M
  135. QL_SPI_CLK_6_6MHZ = 6600000, //时钟:6.6M
  136. QL_SPI_CLK_11_93MHZ = 11930000, //时钟:11.93M
  137. QL_SPI_CLK_13MHZ = 13000000, //时钟:13M
  138. QL_SPI_CLK_13_92MHZ = 13920000, //时钟:13.92M
  139. QL_SPI_CLK_16_7MHZ = 16700000, //时钟:16.7M
  140. QL_SPI_CLK_20_875MHZ = 20875000, //时钟:20.875M
  141. QL_SPI_CLK_27_83MHZ = 27830000, //时钟:27.83M
  142. QL_SPI_CLK_25MHZ = QL_SPI_CLK_27_83MHZ, //时钟:25M 8850不支持,如果选择25M实际是27.83M
  143. QL_SPI_CLK_41_75MHZ = 41750000, //时钟:41.75M 不建议使用
  144. QL_SPI_CLK_50MHZ_MAX = 50000000, //时钟:50M 8850不支持
  145. }ql_spi_clk_e;
  146. typedef enum
  147. {
  148. QL_SPI_CLK_DELAY_0 = 0, //无delay, 默认状态
  149. QL_SPI_CLK_DELAY_1, //MISO delay一个边沿采用
  150. }ql_spi_clk_delay_e;
  151. typedef enum
  152. {
  153. QL_SPI_NOT_RELEASE, //使用完SPI总线不释放SPI总线
  154. QL_SPI_RELEASE, //使用完SPI总线会释放SPI总线,下次使用需要重新init
  155. }ql_spi_release_e;
  156. typedef struct
  157. {
  158. ql_spi_input_mode_e input_mode;
  159. ql_spi_port_e port;
  160. unsigned int framesize;
  161. ql_spi_clk_e spiclk;
  162. ql_spi_cs_pol_e cs_polarity0;
  163. ql_spi_cs_pol_e cs_polarity1;
  164. ql_spi_cpol_pol_e cpol;
  165. ql_spi_cpha_pol_e cpha;
  166. ql_spi_input_sel_e input_sel;
  167. ql_spi_transfer_mode_e transmode;
  168. ql_spi_cs_sel_e cs;
  169. ql_GpioNum cs_gpio;
  170. ql_spi_clk_delay_e clk_delay; //此参数在8850上没有实际意义
  171. ql_spi_release_e release_flag; //使用完SPI总线,是否需要释放总线
  172. } ql_spi_config_s;
  173. typedef struct
  174. {
  175. unsigned int rx_ovf : 1;
  176. unsigned int tx_th : 1;
  177. unsigned int tx_dma_done : 1;
  178. unsigned int rx_th : 1;
  179. unsigned int rx_dma_done : 1;
  180. unsigned int tx_threshold : 5; //5bit:[0-31]对应0到31档的阈值
  181. unsigned int rx_threshold : 5; //5bit:[0-31]对应0到31档的阈值
  182. }ql_spi_irq_s;
  183. typedef void (*ql_spi_callback)(ql_spi_irq_s cause);
  184. /*========================================================================
  185. * function Definition
  186. *========================================================================*/
  187. /*****************************************************************
  188. * Function: ql_spi_init
  189. *
  190. * Description:
  191. * 初始化SPI总线
  192. *
  193. * Parameters:
  194. * port [in] SPI总线选择
  195. * transmode [in] SPI总线工作的传输模式,仅支持QL_SPI_DIRECT_POLLING模式
  196. * spiclk [in] SPI总线传输速率配置
  197. *
  198. * Return:ql_errcode_spi_e
  199. *
  200. *****************************************************************/
  201. ql_errcode_spi_e ql_spi_init(ql_spi_port_e port, ql_spi_transfer_mode_e transmode, ql_spi_clk_e spiclk);
  202. /*****************************************************************
  203. * Function: ql_spi_init_ext
  204. *
  205. * Description:
  206. * 初始化SPI总线,与ql_spi_init相比,有更多的配置选择
  207. *
  208. * Parameters:
  209. * spi_config [in] SPI总线配置
  210. *
  211. * Return:ql_errcode_spi_e
  212. *
  213. *****************************************************************/
  214. ql_errcode_spi_e ql_spi_init_ext(ql_spi_config_s spi_config);
  215. /*****************************************************************
  216. * Function: ql_spi_read_follow_write
  217. *
  218. * Description:
  219. * 对SPI总线执行写和读2个操作,不支持QL_SPI_DMA_IRQ模式
  220. * first write and after read.with the two operation,the cs is always low.not support QL_SPI_DMA_IRQ mode
  221. *
  222. * Parameters:
  223. * port [in] SPI总线选择
  224. * outbuf [in] 写入的数据
  225. * outlen [in] 写入的数据长度
  226. * inbuf [out] 读取的数据
  227. * inlen [in] 需要读取的数据长度
  228. *
  229. * Return:ql_errcode_spi_e
  230. *
  231. *****************************************************************/
  232. ql_errcode_spi_e ql_spi_read_follow_write(ql_spi_port_e port, unsigned char *outbuf, unsigned int outlen, unsigned char *inbuf, unsigned int inlen);
  233. /*****************************************************************
  234. * Function: ql_spi_write_read
  235. *
  236. * Description:
  237. * write and read simultaneously,use the same clock。调用此接口前后,需要使用ql_spi_cs_low,ql_spi_cs_high,ql_spi_cs_auto控制CS引脚。
  238. * Before and after calling this API, you need to use ql_spi_cs_low, ql_spi_cs_high, and ql_spi_cs_auto to control the CS pin.
  239. *
  240. * Parameters:
  241. * port [in] SPI bus select
  242. * inbuf [in] the data will be read and saved to inbuf
  243. * outbuf [out] the data will be write and send to the SPI bus
  244. * len [in] data length,same length with write data and read data
  245. *
  246. * Return:ql_errcode_spi_e
  247. *
  248. *****************************************************************/
  249. ql_errcode_spi_e ql_spi_write_read(ql_spi_port_e port, unsigned char *inbuf, unsigned char *outbuf, unsigned int len);
  250. /*****************************************************************
  251. * Function: ql_spi_read
  252. *
  253. * Description:
  254. * 对SPI总线执行读操作。调用此接口前后,需要使用ql_spi_cs_low,ql_spi_cs_high,ql_spi_cs_auto控制CS引脚。
  255. * Before and after calling this API, you need to use ql_spi_cs_low, ql_spi_cs_high, and ql_spi_cs_auto to control the CS pin.
  256. *
  257. * Parameters:
  258. * port [in] SPI总线选择
  259. * buf [out] 读取的数据
  260. * len [in] 需要读取的数据长度
  261. *
  262. * Return:ql_errcode_spi_e
  263. *
  264. *****************************************************************/
  265. ql_errcode_spi_e ql_spi_read(ql_spi_port_e port, unsigned char *buf, unsigned int len);
  266. /*****************************************************************
  267. * Function: ql_spi_write
  268. *
  269. * Description:
  270. * 对SPI总线执行写操作。调用此接口前后,需要使用ql_spi_cs_low,ql_spi_cs_high,ql_spi_cs_auto控制CS引脚。
  271. * Before and after calling this API, you need to use ql_spi_cs_low, ql_spi_cs_high, and ql_spi_cs_auto to control the CS pin.
  272. *
  273. * Parameters:
  274. * port [in] SPI总线选择
  275. * buf [in] 写入的数据
  276. * len [in] 写入的数据长度
  277. *
  278. * Return:ql_errcode_spi_e
  279. *
  280. *****************************************************************/
  281. ql_errcode_spi_e ql_spi_write(ql_spi_port_e port, unsigned char *buf, unsigned int len);
  282. /*****************************************************************
  283. * Function: ql_spi_release
  284. *
  285. * Description:
  286. * 释放SPI总线
  287. *
  288. * Parameters:
  289. * port [in] SPI总线选择
  290. *
  291. * Return:ql_errcode_spi_e
  292. *
  293. *****************************************************************/
  294. ql_errcode_spi_e ql_spi_release(ql_spi_port_e port);
  295. /*****************************************************************
  296. * Function: ql_spi_cs_low
  297. *
  298. * Description:
  299. * 对SPI总线的CS引脚强制拉低
  300. *
  301. * Parameters:
  302. * port [in] SPI总线选择
  303. *
  304. * Return:ql_errcode_spi_e
  305. *
  306. *****************************************************************/
  307. ql_errcode_spi_e ql_spi_cs_low(ql_spi_port_e port);
  308. /*****************************************************************
  309. * Function: ql_spi_cs_high
  310. *
  311. * Description:
  312. * 对SPI总线的CS引脚强制拉高
  313. *
  314. * Parameters:
  315. * port [in] SPI总线选择
  316. *
  317. * Return:ql_errcode_spi_e
  318. *
  319. *****************************************************************/
  320. ql_errcode_spi_e ql_spi_cs_high(ql_spi_port_e port);
  321. /*****************************************************************
  322. * Function: ql_spi_cs_auto
  323. *
  324. * Description:
  325. * SPI总线的CS引脚恢复成系统控制,系统默认CS引脚由系统控制
  326. *
  327. * Parameters:
  328. * port [in] SPI总线选择
  329. *
  330. * Return:ql_errcode_spi_e
  331. *
  332. *****************************************************************/
  333. ql_errcode_spi_e ql_spi_cs_auto(ql_spi_port_e port);
  334. /*****************************************************************
  335. * Function: ql_spi_set_irq,8850不支持此接口
  336. *
  337. * Description:
  338. * 设置SPI总线中断回调函数
  339. *
  340. * Parameters:
  341. * port [in] SPI总线选择
  342. * mask [in] 中断配置
  343. * callfunc [in] 中断回调函数
  344. *
  345. * Return:ql_errcode_spi_e
  346. *
  347. *****************************************************************/
  348. ql_errcode_spi_e ql_spi_set_irq(ql_spi_port_e port, ql_spi_irq_s mask, ql_spi_callback callfunc);
  349. /*****************************************************************
  350. * Function: ql_spi_get_tx_fifo_free
  351. *
  352. * Description:
  353. * 获取发送FIFO的空闲数目,FIFO为16的帧长度,8850不支持此接口
  354. *
  355. * Parameters:
  356. * port [in] SPI总线选择
  357. * tx_free [out] FIFO里的空闲数目
  358. *
  359. * Return:ql_errcode_spi_e
  360. *
  361. *****************************************************************/
  362. ql_errcode_spi_e ql_spi_get_tx_fifo_free(ql_spi_port_e port, unsigned int *tx_free);
  363. /*****************************************************************
  364. * Function: ql_spi_request_sys_clk
  365. *
  366. * Description:
  367. * SPI不允许进入慢时钟,要和ql_spi_release_sys_clk配套使用。QL_SPI_DMA_IRQ模式下,进入慢时钟会将CLK的频率变小
  368. *
  369. * Parameters:
  370. * port [in] SPI总线选择
  371. *
  372. * Return:ql_errcode_spi_e
  373. *
  374. *****************************************************************/
  375. ql_errcode_spi_e ql_spi_request_sys_clk(ql_spi_port_e port);
  376. /*****************************************************************
  377. * Function: ql_spi_release_sys_clk
  378. *
  379. * Description:
  380. * SPI允许进入慢时钟。QL_SPI_DMA_IRQ模式下,进入慢时钟会将CLK的频率变小
  381. *
  382. * Parameters:
  383. * port [in] SPI总线选择
  384. *
  385. * Return:ql_errcode_spi_e
  386. *
  387. *****************************************************************/
  388. ql_errcode_spi_e ql_spi_release_sys_clk(ql_spi_port_e port);
  389. #ifdef __cplusplus
  390. } /*"C" */
  391. #endif
  392. #endif /* QL_API_SPI_H */