quec_boot_spi.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. /* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA").
  2. * All rights reserved.
  3. *
  4. * This software is supplied "AS IS" without any warranties.
  5. * RDA assumes no responsibility or liability for the use of the software,
  6. * conveys no license or title under any patent, copyright, or mask work
  7. * right to the product. RDA reserves the right to make changes in the
  8. * software without notification. RDA also make no representation or
  9. * warranty that such application will be suitable for the specified use
  10. * without further testing or modification.
  11. */
  12. #ifndef _QUEC_BOOT_SPI_H_
  13. #define _QUEC_BOOT_SPI_H_
  14. #include <stdint.h>
  15. #include <stdbool.h>
  16. #include <stddef.h>
  17. #include "ql_api_common.h"
  18. #include "quec_boot_pin_cfg.h"
  19. #ifdef __cplusplus
  20. extern "C" {
  21. #endif
  22. #include "quec_pin_index.h"
  23. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  24. spi api接口
  25. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  26. //boot中不支持DMA模式
  27. #define QL_BOOT_SPI_DMA_IRQ_SIZE 512 //QL_SPI_DMA_IRQ模式最多只有512个字节,8850此参数无意义。
  28. #define QL_BOOT_SPI_DMA_ADDR_ALIN 32 //QL_SPI_DMA_IRQ和QL_SPI_DMA_POLLING模式,地址必须32字节对齐
  29. /*========================================================================
  30. * Variable Definition
  31. *========================================================================*/
  32. /**************************** error code about ql spi/flash/nandflash/norflash ***************************/
  33. typedef enum
  34. {
  35. QL_BOOT_SPI_SUCCESS = 0,
  36. QL_BOOT_SPI_ERROR = 1 | (QL_COMPONENT_BSP_SPI << 16), //SPI总线其他错误
  37. QL_BOOT_SPI_PARAM_TYPE_ERROR, //参数类型错误
  38. QL_BOOT_SPI_PARAM_DATA_ERROR, //参数数据错误
  39. QL_BOOT_SPI_PARAM_ACQUIRE_ERROR, //参数无法获取
  40. QL_BOOT_SPI_PARAM_NULL_ERROR, //参数NULL错误
  41. QL_BOOT_SPI_DEV_NOT_ACQUIRE_ERROR, //无法获取SPI总线
  42. QL_BOOT_SPI_PARAM_LENGTH_ERROR, //参数长度错误
  43. QL_BOOT_SPI_MALLOC_MEM_ERROR, //申请内存错误
  44. QL_BOOT_SPI_FLASH_NOT_FLASH_CONN_ERROR, //没有接入FLASH芯片
  45. QL_BOOT_SPI_FLASH_NOT_SUPPORT_ERROR, //FLASH型号不支持
  46. QL_BOOT_SPI_FLASH_OP_NOT_SUPPORT_ERROR, //FLASH型号不支持此操作
  47. QL_BOOT_SPI_FLASH_ECC_ERROR, //nand flash ecc error
  48. QL_BOOT_SPI_FLASH_PROGRAM_ERROR, //flash program error
  49. QL_BOOT_SPI_FLASH_ERASE_ERROR, //flash erase error
  50. QL_BOOT_NAND_SPI_INIT_ERR,
  51. QL_BOOT_NAND_READ_DATA_ERR,
  52. QL_BOOT_NAND_WRITE_DATA_ERR,
  53. QL_BOOT_NAND_READ_ECC_2BIT_ERR,
  54. QL_BOOT_NAND_READ_ECC_1BIT_ERR,
  55. QL_BOOT_NAND_WRITE_STATUS_ERR,
  56. QL_BOOT_NAND_ERASE_ERR,
  57. QL_BOOT_NAND_ERASE_STATUS_ERR,
  58. QL_BOOT_NOR_GET_FLASH_PROPS_ERR,
  59. QL_BOOT_NOR_NOT_SUPPORT_ERROR,
  60. QL_BOOT_NOR_WAIT_WRITE_FINISH_TIMEOUT_ERR,
  61. }ql_boot_errcode_spi_e;
  62. typedef enum
  63. {
  64. QL_BOOT_SPI_CS0 = 0, //选择cs0为SPI片选CS引脚
  65. QL_BOOT_SPI_CS1, //选择cs1为SPI片选CS引脚
  66. QL_BOOT_SPI_CS2, //选择cs2为SPI片选CS引脚,not use now
  67. QL_BOOT_SPI_CS3, //选择cs3为SPI片选CS引脚,not use now
  68. QL_BOOT_SPI_GPIO, //使用控制GPIO的方式来控制CS功能。注意,对应的CS引脚不要再配置成SPI CS功能,需要配置成GPIO
  69. }ql_boot_spi_cs_sel_e;
  70. typedef enum
  71. {
  72. QL_BOOT_SPI_INPUT_FALSE, //SPI不允许输入(读取)
  73. QL_BOOT_SPI_INPUT_TURE, //SPI允许输入(读取)
  74. }ql_boot_spi_input_mode_e;
  75. typedef enum
  76. {
  77. QL_BOOT_SPI_CS_ACTIVE_HIGH, //SPI总线操作时,CS脚为高
  78. QL_BOOT_SPI_CS_ACTIVE_LOW, //SPI总线操作时,CS脚为低
  79. } ql_boot_spi_cs_pol_e;
  80. typedef enum
  81. {
  82. QL_BOOT_SPI_CPOL_LOW = 0, //SPI未使能时,CLK线为低电平,第一个边沿是上升沿
  83. QL_BOOT_SPI_CPOL_HIGH, //SPI未使能时,CLK线为高电平,第一个边沿是下降沿
  84. } ql_boot_spi_cpol_pol_e;
  85. typedef enum
  86. {
  87. QL_BOOT_SPI_CPHA_1Edge, //MOSI延时一个边沿,CLK和MISO延时两个边沿,即发送的数据先准备好,才有CLK
  88. QL_BOOT_SPI_CPHA_2Edge, //MOSI延时两个边沿,CLK延时2个边沿,MISO延时3个边沿。数据和CLK同时准备好
  89. }ql_boot_spi_cpha_pol_e;
  90. //SPI mode0:ql_spi_cpol_pol_e选择QL_SPI_CPOL_LOW,ql_spi_cpha_pol_e选择QL_SPI_CPHA_1Edge
  91. //SPI mode1:ql_spi_cpol_pol_e选择QL_SPI_CPOL_LOW,ql_spi_cpha_pol_e选择QL_SPI_CPHA_2Edge
  92. //SPI mode2:ql_spi_cpol_pol_e选择QL_SPI_CPOL_HIGH,ql_spi_cpha_pol_e选择QL_SPI_CPHA_1Edge
  93. //SPI mode3:ql_spi_cpol_pol_e选择QL_SPI_CPOL_HIGH,ql_spi_cpha_pol_e选择QL_SPI_CPHA_2Edge
  94. typedef enum
  95. {
  96. QL_BOOT_SPI_DI_0 = 0, //选择DI0为数据输入引脚,not use now
  97. QL_BOOT_SPI_DI_1, //选择DI1为数据输入引脚
  98. QL_BOOT_SPI_DI_2, //选择DI2为数据输入引脚,not use now
  99. }ql_boot_spi_input_sel_e;
  100. typedef enum
  101. {
  102. QL_BOOT_SPI_DIRECT_POLLING = 0, //FIFO读写,轮询等待。
  103. QL_BOOT_SPI_DIRECT_IRQ, //FIFO读写,中断通知,not use now
  104. QL_BOOT_SPI_DMA_POLLING, //DMA读写,轮询等待。此模式下,和SD卡不能同时使用。使能SD卡情形下,申请DMA通道失败,SPI初始化会失败
  105. QL_BOOT_SPI_DMA_IRQ, //DMA读写,中断通知,not use now
  106. }ql_boot_spi_transfer_mode_e;
  107. //spi_sck = clk_spi/2(n+1)
  108. //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;
  109. //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;
  110. typedef enum
  111. {
  112. QL_BOOT_SPI_CLK_INVALID=-1, //无效时钟选择
  113. QL_BOOT_SPI_CLK_97_656KHZ_MIN = 97656, //时钟:97.656K
  114. QL_BOOT_SPI_CLK_100KHZ = 100000, //时钟:100K
  115. QL_BOOT_SPI_CLK_812_5KHZ = 812500, //时钟:812.5K
  116. QL_BOOT_SPI_CLK_1_3MHZ = 1300000, //时钟:1.3M
  117. QL_BOOT_SPI_CLK_1_625MHZ = 1625000, //时钟:1.625M
  118. QL_BOOT_SPI_CLK_1_5625MHZ = QL_BOOT_SPI_CLK_1_625MHZ,//时钟:1.5625M 8850不支持,如果选择实际是1.625M
  119. QL_BOOT_SPI_CLK_2MHZ = 2000000, //时钟:2M
  120. QL_BOOT_SPI_CLK_3_25MHZ = 3250000, //时钟:3.25M
  121. QL_BOOT_SPI_CLK_4_333MHZ = 4333000, //时钟:4.333M
  122. QL_BOOT_SPI_CLK_6_6MHZ = 6600000, //时钟:6.6M
  123. QL_BOOT_SPI_CLK_11_93MHZ = 11930000, //时钟:11.93M
  124. QL_BOOT_SPI_CLK_13MHZ = 13000000, //时钟:13M
  125. QL_BOOT_SPI_CLK_13_92MHZ = 13920000, //时钟:13.92M
  126. QL_BOOT_SPI_CLK_16_7MHZ = 16700000, //时钟:16.7M
  127. QL_BOOT_SPI_CLK_20_875MHZ = 20875000, //时钟:20.875M
  128. QL_BOOT_SPI_CLK_27_83MHZ = 27830000, //时钟:27.83M
  129. QL_BOOT_SPI_CLK_25MHZ = QL_BOOT_SPI_CLK_27_83MHZ, //时钟:25M 8850不支持,如果选择25M实际是27.83M
  130. QL_BOOT_SPI_CLK_41_75MHZ = 41750000, //时钟:41.75M 不建议使用
  131. QL_BOOT_SPI_CLK_50MHZ_MAX = 50000000, //时钟:50M 8850不支持
  132. }ql_boot_spi_clk_e;
  133. typedef struct
  134. {
  135. ql_boot_spi_input_mode_e input_mode;
  136. ql_boot_spi_port_e port;
  137. unsigned int framesize;
  138. ql_boot_spi_clk_e spiclk;
  139. ql_boot_spi_cs_pol_e cs_polarity0;
  140. ql_boot_spi_cs_pol_e cs_polarity1;
  141. ql_boot_spi_cpol_pol_e cpol;
  142. ql_boot_spi_cpha_pol_e cpha;
  143. ql_boot_spi_input_sel_e input_sel;
  144. ql_boot_spi_transfer_mode_e transmode;
  145. ql_boot_spi_cs_sel_e cs;
  146. int cs_gpio;
  147. } ql_boot_spi_config_s;
  148. /*========================================================================
  149. * function Definition
  150. *========================================================================*/
  151. /*****************************************************************
  152. * Function: quec_boot_spi_pin_init
  153. *
  154. * Description:
  155. * 设置相关pin脚的复用功能为spi功能
  156. *
  157. * Parameters:
  158. * port [in] SPI总线选择
  159. *
  160. * Return:ql_boot_errcode_pin_e
  161. *
  162. *****************************************************************/
  163. ql_boot_errcode_pin_e quec_boot_spi_pin_init(ql_boot_spi_port_e port);
  164. /*****************************************************************
  165. * Function: ql_boot_spi_init
  166. *
  167. * Description:
  168. * 初始化SPI总线
  169. *
  170. * Parameters:
  171. * port [in] SPI总线选择
  172. * transmode [in] SPI总线工作的传输模式,仅支持QL_SPI_DIRECT_POLLING模式
  173. * spiclk [in] SPI总线传输速率配置
  174. *
  175. * Return:ql_boot_errcode_spi_e
  176. *
  177. *****************************************************************/
  178. ql_boot_errcode_spi_e ql_boot_spi_init(ql_boot_spi_port_e port, ql_boot_spi_transfer_mode_e transmode, ql_boot_spi_clk_e spiclk);
  179. /*****************************************************************
  180. * Function: ql_boot_spi_init_ext
  181. *
  182. * Description:
  183. * 初始化SPI总线,与ql_boot_spi_init相比,有更多的配置选择
  184. *
  185. * Parameters:
  186. * spi_config [in] SPI总线配置
  187. *
  188. * Return:ql_boot_errcode_spi_e
  189. *
  190. *****************************************************************/
  191. ql_boot_errcode_spi_e ql_boot_spi_init_ext(ql_boot_spi_config_s spi_config);
  192. /*****************************************************************
  193. * Function: ql_boot_spi_read_follow_write
  194. *
  195. * Description:
  196. * 对SPI总线执行写和读2个操作
  197. * first write and after read.with the two operation,the cs is always low
  198. *
  199. * Parameters:
  200. * port [in] SPI总线选择
  201. * outbuf [in] 写入的数据
  202. * outlen [in] 写入的数据长度
  203. * inbuf [out] 读取的数据
  204. * inlen [in] 需要读取的数据长度
  205. *
  206. * Return:ql_boot_errcode_spi_e
  207. *
  208. *****************************************************************/
  209. ql_boot_errcode_spi_e ql_boot_spi_read_follow_write(ql_boot_spi_port_e port, unsigned char *outbuf, unsigned int outlen, unsigned char *inbuf, unsigned int inlen);
  210. /*****************************************************************
  211. * Function: ql_boot_spi_write_read
  212. *
  213. * Description:
  214. * write and read simultaneously,use the same clock。调用此接口前后,需要使用ql_spi_cs_low,ql_spi_cs_high,ql_spi_cs_auto控制CS引脚。
  215. * 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.
  216. *
  217. * Parameters:
  218. * port [in] SPI bus select
  219. * inbuf [in] the data will be read and saved to inbuf
  220. * outbuf [out] the data will be write and send to the SPI bus
  221. * len [in] data length,same length with write data and read data
  222. *
  223. * Return:ql_boot_errcode_spi_e
  224. *
  225. *****************************************************************/
  226. ql_boot_errcode_spi_e ql_boot_spi_write_read(ql_boot_spi_port_e port, unsigned char *inbuf, unsigned char *outbuf, unsigned int len);
  227. /*****************************************************************
  228. * Function: ql_boot_spi_read
  229. *
  230. * Description:
  231. * 对SPI总线执行读操作。调用此接口前后,需要使用ql_spi_cs_low,ql_spi_cs_high,ql_spi_cs_auto控制CS引脚。
  232. * 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.
  233. *
  234. * Parameters:
  235. * port [in] SPI总线选择
  236. * buf [out] 读取的数据
  237. * len [in] 需要读取的数据长度
  238. *
  239. * Return:ql_boot_errcode_spi_e
  240. *
  241. *****************************************************************/
  242. ql_boot_errcode_spi_e ql_boot_spi_read(ql_boot_spi_port_e port, unsigned char *buf, unsigned int len);
  243. /*****************************************************************
  244. * Function: ql_boot_spi_write
  245. *
  246. * Description:
  247. * 对SPI总线执行写操作。调用此接口前后,需要使用ql_spi_cs_low,ql_spi_cs_high,ql_spi_cs_auto控制CS引脚。
  248. * 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.
  249. *
  250. * Parameters:
  251. * port [in] SPI总线选择
  252. * buf [in] 写入的数据
  253. * len [in] 写入的数据长度
  254. *
  255. * Return:ql_boot_errcode_spi_e
  256. *
  257. *****************************************************************/
  258. ql_boot_errcode_spi_e ql_boot_spi_write(ql_boot_spi_port_e port, unsigned char *buf, unsigned int len);
  259. /*****************************************************************
  260. * Function: ql_boot_spi_release
  261. *
  262. * Description:
  263. * 释放SPI总线
  264. *
  265. * Parameters:
  266. * port [in] SPI总线选择
  267. *
  268. * Return:ql_boot_errcode_spi_e
  269. *
  270. *****************************************************************/
  271. ql_boot_errcode_spi_e ql_boot_spi_release(ql_boot_spi_port_e port);
  272. /*****************************************************************
  273. * Function: ql_boot_spi_cs_low
  274. *
  275. * Description:
  276. * 对SPI总线的CS引脚强制拉低
  277. *
  278. * Parameters:
  279. * port [in] SPI总线选择
  280. *
  281. * Return:ql_boot_errcode_spi_e
  282. *
  283. *****************************************************************/
  284. ql_boot_errcode_spi_e ql_boot_spi_cs_low(ql_boot_spi_port_e port);
  285. /*****************************************************************
  286. * Function: ql_boot_spi_cs_high
  287. *
  288. * Description:
  289. * 对SPI总线的CS引脚强制拉高
  290. *
  291. * Parameters:
  292. * port [in] SPI总线选择
  293. *
  294. * Return:ql_boot_errcode_spi_e
  295. *
  296. *****************************************************************/
  297. ql_boot_errcode_spi_e ql_boot_spi_cs_high(ql_boot_spi_port_e port);
  298. /*****************************************************************
  299. * Function: ql_boot_spi_cs_auto
  300. *
  301. * Description:
  302. * SPI总线的CS引脚恢复成系统控制,系统默认CS引脚由系统控制
  303. *
  304. * Parameters:
  305. * port [in] SPI总线选择
  306. *
  307. * Return:ql_boot_errcode_spi_e
  308. *
  309. *****************************************************************/
  310. ql_boot_errcode_spi_e ql_boot_spi_cs_auto(ql_boot_spi_port_e port);
  311. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  312. spi flash api接口
  313. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  314. typedef struct
  315. {
  316. ql_boot_spi_port_e port; //SPI总线选择
  317. ql_boot_spi_clk_e spiclk; //SPI时钟配置
  318. ql_boot_spi_input_sel_e input_sel; //SPI输入引脚选择
  319. ql_boot_spi_transfer_mode_e transmode; //SPI工作模式,目前仅支持QL_SPI_DIRECT_POLLING
  320. ql_boot_spi_cs_sel_e cs; //SPI片选CS引脚选择
  321. int cs_gpio; //SPI CS使用GPIO来控制
  322. } ql_boot_spi_flash_config_s;
  323. #define QL_BOOT_FLASH_WRITE_ENABLE 0x06
  324. #define QL_BOOT_FLASH_READ_DEVID 0x9F
  325. typedef enum
  326. {
  327. QL_BOOT_SPI_FLASH_NOR_FLASH = 0, //nor flash
  328. QL_BOOT_SPI_FLASH_NAND_FLASH, //nand flash
  329. }ql_boot_spi_flash_type_e;
  330. typedef enum
  331. {
  332. QUEC_BOOT_NOR_FLASH_WAIT_DELAY_NONE = 0, //不需要释放CPU,读写操作,扇区,块擦除
  333. QUEC_BOOT_NOR_FLASH_WAIT_DELAY, //擦除整个芯片需要释放CPU,有些芯片擦除整个芯片耗时超过3S
  334. }quec_boot_spi_nor_flash_wait_mode_e;
  335. /*****************************************************************
  336. * Function: ql_spi_flash_init_ext
  337. *
  338. * Description:
  339. * 扩展初始化SPI FLASH,与ql_spi_flash_init有更多的设置选项,,调用此函数前,必须使用ql_pin_set_func设置好SPI引脚
  340. *
  341. * Parameters:
  342. * flash_config [in] SPI flash配置参数
  343. *
  344. * Return:ql_boot_errcode_spi_e
  345. *
  346. *****************************************************************/
  347. ql_boot_errcode_spi_e ql_boot_spi_flash_init_ext(ql_boot_spi_flash_config_s flash_config);
  348. /*****************************************************************
  349. * Function: ql_spi_flash_enable_write
  350. *
  351. * Description:
  352. * 使能flash操作,注意,此API没有等待操作完成,发送06指令
  353. *
  354. * Parameters:
  355. * port [in] SPI总线选择
  356. *
  357. * Return:ql_boot_errcode_spi_e
  358. *
  359. *****************************************************************/
  360. ql_boot_errcode_spi_e ql_boot_spi_flash_enable_write(ql_boot_spi_port_e port);
  361. #ifdef __cplusplus
  362. } /*"C" */
  363. #endif
  364. #endif