bsp_spi_master.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855
  1. /*----------------------------------------------------------------------------------------------------
  2. INCLUDE HEADE FILES
  3. ----------------------------------------------------------------------------------------------------*/
  4. #include "Platform.h"
  5. #include "bsp_register_macro.h"
  6. #define TH25D_20UA //紫光青藤的flash 型号
  7. /*----------------------------------------------------------------------------------------------------
  8. SPI COMMAND
  9. -----------------------------------------------------------------------------------------------------*/
  10. #define CMD_READ_DATA 0x03
  11. #define CMD_READ_STATUS 0x05
  12. #define CMD_CHIP_ERASE 0xc7
  13. #define CMD_WRITE_ENABLE 0x06
  14. #define CMD_PAGE_PROGRAM 0x02
  15. #define CMD_BLOCK_ERASE 0xD8
  16. #define CMD_SECTOR_ERASE 0x20
  17. #define CMD_PAGE_ERASE 0x81
  18. #define CMD_RELEASE_PWRDWN 0xAB
  19. #define CMD_PWRDWN 0xB9
  20. #define CMD_ID 0x4B
  21. #define PACKET_FULL_LEN FLASH_PAGE_SIZE
  22. /*-------------------------------------------------------------------
  23. NOTE: bsp_spi0_flash文件下的变量要放在SHRAM0区域.
  24. -------------------------------------------------------------------*/
  25. //uint8_t __attribute__((aligned(4))) txbuff[(PACKET_FULL_LEN+4)];
  26. //uint8_t __attribute__((aligned(4))) rxbuff[(PACKET_FULL_LEN+4)];
  27. uint8_t __attribute__((at(127*1024+0x10000000))) txbuff[(PACKET_FULL_LEN+4)];
  28. uint8_t __attribute__((at(127*1024+512+0x10000000))) rxbuff[(PACKET_FULL_LEN+4)];
  29. /* ---------------------------------------------------------------------------------------------------
  30. - 函数名称: Init_spi_master
  31. - 函数功能: 初始化spi主模式
  32. - 创建日期: 2015-09-14
  33. ----------------------------------------------------------------------------------------------------*/
  34. void Init_spi_master(uint32_t ch, uint32_t freq)
  35. {
  36. uint32_t val;
  37. __write_hw_reg32(CPR_SPIx_MCLK_CTL(ch), 0x110010);//1分频 //- spi(x)_mclk = 32Mhz(When TXCO=32Mhz).
  38. __write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL , (0x1000100<<ch)); //- 打开spi(x) pclk.
  39. __read_hw_reg32(CPR_SSI_CTRL, val);
  40. val |= (ch==0)? 0x01: 0x30;
  41. __write_hw_reg32(CPR_SSI_CTRL, val);
  42. __write_hw_reg32(SSIx_EN(ch), 0x00);
  43. __write_hw_reg32(SSIx_IE(ch), 0x00);
  44. __write_hw_reg32(SSIx_CTRL0(ch) , 0x0F); /* 16bit SPI data */
  45. __write_hw_reg32(SSIx_SE(ch), 0x01);
  46. __write_hw_reg32(SSIx_BAUD(ch), freq); //- spix_mclk 分频.
  47. __write_hw_reg32(SSIx_RXFTL(ch), 0x00);
  48. __write_hw_reg32(SSIx_TXFTL(ch), 0x00);
  49. //__write_hw_reg32(SSIx_EN(ch) , 0x01);
  50. }
  51. /* ---------------------------------------------------------------------------------------------------
  52. - 函数名称: spi_flash_Read_128bitsID
  53. - 函数功能: 读取flash 128bits ID 读独立的ID序列 该指令可以读取一个芯片已经固化的只读的128位ID
  54. - 创建日期: 2015-09-14
  55. ----------------------------------------------------------------------------------------------------*/
  56. void spi_flash_Read_128bitsID(uint8_t *buff)
  57. {
  58. while(spi_flash_wait_till_ready());
  59. uint32_t iWK = 0;
  60. memset(txbuff,0,PACKET_FULL_LEN+4);
  61. memset(rxbuff,0,PACKET_FULL_LEN+4);
  62. txbuff[1] = CMD_ID;
  63. __write_hw_reg32(SSI0_EN , 0x00);
  64. __write_hw_reg32(SSI0_DMAS , 0x03);
  65. __write_hw_reg32(SSI0_DMATDL, 0x4); //-
  66. __write_hw_reg32(SSI0_DMARDL, 0x4); //- 1/4 FIFO
  67. __write_hw_reg32(SSI0_EN , 0x01);
  68. //- RX Channel
  69. __write_hw_reg32(DMAS_CHx_SAR(10) , 0x40013060);
  70. __write_hw_reg32(DMAS_CHx_DAR(10) , (uint32_t)rxbuff);
  71. __write_hw_reg32(DMAS_CHx_CTL1(10) ,((2 << 8)| 1));
  72. __write_hw_reg32(DMAS_CHx_CTL0(10) ,24);
  73. __write_hw_reg32(DMAS_EN , 10);
  74. //- TX Channel
  75. __write_hw_reg32(DMAS_CHx_SAR(2) , (uint32_t)txbuff);
  76. __write_hw_reg32(DMAS_CHx_DAR(2) , 0x40013060);
  77. __write_hw_reg32(DMAS_CHx_CTL1(2) ,((2 << 8)| 1));
  78. __write_hw_reg32(DMAS_CHx_CTL0(2) ,24);//接收缓冲区首地址必须是4的倍数而且大小必须是四的倍数
  79. __write_hw_reg32(DMAS_EN , 2);
  80. do {
  81. __read_hw_reg32(DMAS_INT_RAW , iWK);
  82. }while((iWK&0x404) != 0x404);
  83. __write_hw_reg32(DMAS_INT_RAW, 0x404);
  84. __write_hw_reg32(DMAS_CLR , 10);
  85. __write_hw_reg32(DMAS_CLR , 2);
  86. __write_hw_reg32(SSI0_EN , 0x00);
  87. for(int i=0;i<12;i++)
  88. {
  89. uint8_t temp=rxbuff[2*i+1];
  90. rxbuff[2*i+1]=rxbuff[2*i];
  91. rxbuff[2*i]=temp;
  92. }
  93. for(int i=0;i<16;i++)
  94. buff[i]=rxbuff[5+i];
  95. }
  96. /* ---------------------------------------------------------------------------------------------------
  97. - 函数名称: spi_flash_Read_Page
  98. - 函数功能: 从SPI FLASH中读取一页数据到指定地址
  99. - 创建日期: 2015-09-14
  100. ----------------------------------------------------------------------------------------------------*/
  101. void spi_flash_Read_Page(uint32_t PageAddR, uint8_t *buff)
  102. {
  103. uint32_t addr = PageAddR;
  104. uint32_t iWK = 0;
  105. txbuff[0] = (uint8_t)(addr>>16);
  106. txbuff[1] = CMD_READ_DATA;
  107. txbuff[2] = (uint8_t)(addr);
  108. txbuff[3] = (uint8_t)(addr>>8);
  109. __write_hw_reg32(SSI0_EN , 0x00);
  110. __write_hw_reg32(SSI0_DMAS , 0x03);
  111. __write_hw_reg32(SSI0_DMATDL, 0x4); //-
  112. __write_hw_reg32(SSI0_DMARDL, 0x4); //- 1/4 FIFO
  113. __write_hw_reg32(SSI0_EN , 0x01);
  114. //- RX Channel
  115. __write_hw_reg32(DMAS_CHx_SAR(10) , 0x40013060);
  116. __write_hw_reg32(DMAS_CHx_DAR(10) , (uint32_t)buff);
  117. __write_hw_reg32(DMAS_CHx_CTL1(10) ,((2 << 8)| 1));
  118. __write_hw_reg32(DMAS_CHx_CTL0(10) ,(PACKET_FULL_LEN+4));
  119. __write_hw_reg32(DMAS_EN , 10);
  120. //- TX Channel
  121. __write_hw_reg32(DMAS_CHx_SAR(2) , (uint32_t)txbuff);
  122. __write_hw_reg32(DMAS_CHx_DAR(2) , 0x40013060);
  123. __write_hw_reg32(DMAS_CHx_CTL1(2) ,((2 << 8)| 1));
  124. __write_hw_reg32(DMAS_CHx_CTL0(2) ,(PACKET_FULL_LEN+4));
  125. __write_hw_reg32(DMAS_EN , 2);
  126. do {
  127. __read_hw_reg32(DMAS_INT_RAW , iWK);
  128. }while((iWK&0x404) != 0x404);
  129. __write_hw_reg32(DMAS_INT_RAW, 0x404);
  130. __write_hw_reg32(DMAS_CLR , 10);
  131. __write_hw_reg32(DMAS_CLR , 2);
  132. __write_hw_reg32(SSI0_EN , 0x00);
  133. }
  134. /* ---------------------------------------------------------------------------------------------------
  135. - 函数名称: spi_flash_wait_till_ready
  136. - 函数功能: 检查spi flash处于ready状态
  137. - 创建日期: 2015-09-14
  138. ----------------------------------------------------------------------------------------------------*/
  139. uint8_t spi_flash_wait_till_ready (void)
  140. {
  141. uint16_t cmd = (CMD_READ_STATUS<<8);
  142. uint32_t iWK = 0;
  143. uint16_t dWK = 0;
  144. __write_hw_reg32(SSI0_EN , 0x00);
  145. __write_hw_reg32(SSI0_DMAS , 0x00); /* turn off dma*/
  146. __write_hw_reg32(SSI0_DMATDL, 0x0); //-
  147. __write_hw_reg32(SSI0_DMARDL, 0x0); //-
  148. __write_hw_reg32(SSI0_EN , 0x01);
  149. __write_hw_reg32(SSI0_DATA , cmd);
  150. do {
  151. __read_hw_reg32(SSI0_STS, iWK);
  152. }while((iWK&0x05) != 0x04);
  153. __read_hw_reg32(SSI0_DATA , dWK);
  154. __write_hw_reg32(SSI0_EN , 0x00);
  155. return (uint8_t)(dWK&0x01);
  156. }
  157. /* ---------------------------------------------------------------------------------------------------
  158. - 函数名称: spi_flash_chip_erase
  159. - 函数功能: 擦除整个芯片的内容
  160. - 创建日期: 2015-09-16
  161. ----------------------------------------------------------------------------------------------------*/
  162. void spi_flash_chip_erase(void)
  163. {
  164. uint32_t bWk, cWk;
  165. __read_hw_reg32(SSI0_CTRL0 , bWk);
  166. __write_hw_reg32(SSI0_EN , 0x00);
  167. __write_hw_reg32(SSI0_DMAS , 0x00);
  168. __write_hw_reg32(SSI0_CTRL0 , 0x07); /* 8bit SPI data */
  169. __write_hw_reg32(SSI0_EN , 0x01);
  170. __write_hw_reg32(SSI0_DATA, CMD_CHIP_ERASE);
  171. do {
  172. __read_hw_reg32(SSI0_STS, cWk);
  173. }while((cWk&0x05) != 0x04);
  174. __write_hw_reg32(SSI0_EN , 0x00);
  175. __write_hw_reg32(SSI0_CTRL0 , bWk);
  176. }
  177. /* ---------------------------------------------------------------------------------------------------
  178. - 函数名称: spi_flash_erase_block_num
  179. - 函数功能: 计算需擦除block的数目
  180. - 创建日期: 2015-09-16
  181. ----------------------------------------------------------------------------------------------------*/
  182. uint32_t spi_flash_block_num(uint32_t size)
  183. {
  184. uint32_t blk = 0;
  185. blk = size/FLASH_BLOCK_SIZE;
  186. if(size % FLASH_BLOCK_SIZE) blk++;
  187. return blk;
  188. }
  189. /* ---------------------------------------------------------------------------------------------------
  190. - 函数名称: spi_flash_block_erase
  191. - 函数功能: 擦除芯片指定block的内容
  192. - 创建日期: 2015-09-16
  193. ----------------------------------------------------------------------------------------------------*/
  194. void spi_flash_block_erase(uint32_t blknum)
  195. {
  196. uint32_t addr = (blknum*FLASH_BLOCK_SIZE);
  197. uint32_t iWK = 0;
  198. txbuff[0] = (uint8_t)(addr>>16);
  199. txbuff[1] = CMD_BLOCK_ERASE;
  200. txbuff[2] = (uint8_t)(addr);
  201. txbuff[3] = (uint8_t)(addr>>8);
  202. __write_hw_reg32(SSI0_EN , 0x00);
  203. __write_hw_reg32(SSI0_DMAS , 0x03);
  204. __write_hw_reg32(SSI0_DMATDL, 0x4); //-
  205. __write_hw_reg32(SSI0_DMARDL, 0x4); //- 1/4 FIFO
  206. __write_hw_reg32(SSI0_EN , 0x01);
  207. //- RX Channel
  208. __write_hw_reg32(DMAS_CHx_SAR(10) , 0x40013060);
  209. __write_hw_reg32(DMAS_CHx_DAR(10) , (uint32_t)rxbuff);
  210. __write_hw_reg32(DMAS_CHx_CTL1(10) ,((2 << 8)| 1));
  211. __write_hw_reg32(DMAS_CHx_CTL0(10) ,4);
  212. __write_hw_reg32(DMAS_EN , 10);
  213. //- TX Channel
  214. __write_hw_reg32(DMAS_CHx_SAR(2) , (uint32_t)txbuff);
  215. __write_hw_reg32(DMAS_CHx_DAR(2) , 0x40013060);
  216. __write_hw_reg32(DMAS_CHx_CTL1(2) ,((2 << 8)| 1));
  217. __write_hw_reg32(DMAS_CHx_CTL0(2) ,4);
  218. __write_hw_reg32(DMAS_EN , 2);
  219. do {
  220. __read_hw_reg32(DMAS_INT_RAW , iWK);
  221. }while((iWK&0x404) != 0x404);
  222. __write_hw_reg32(DMAS_INT_RAW, 0x404);
  223. __write_hw_reg32(DMAS_CLR , 10);
  224. __write_hw_reg32(DMAS_CLR , 2);
  225. __write_hw_reg32(SSI0_EN , 0x00);
  226. }
  227. /* ---------------------------------------------------------------------------------------------------
  228. - 函数名称: spi_flash_write_enable
  229. - 函数功能: 使能对芯片的写操作
  230. - 创建日期: 2015-09-16
  231. ----------------------------------------------------------------------------------------------------*/
  232. void spi_flash_write_enable(void)
  233. {
  234. uint32_t bWk, cWk;
  235. __read_hw_reg32(SSI0_CTRL0 , bWk);
  236. __write_hw_reg32(SSI0_EN, 0x00);
  237. __write_hw_reg32(SSI0_DMAS , 0x00);
  238. __write_hw_reg32(SSI0_CTRL0 , 0x07); /* 8bit SPI data */
  239. __write_hw_reg32(SSI0_EN, 0x01);
  240. __write_hw_reg32(SSI0_DATA, CMD_WRITE_ENABLE);
  241. do {
  242. __read_hw_reg32(SSI0_STS, cWk);
  243. }while((cWk&0x05) != 0x04);
  244. __write_hw_reg32(SSI0_EN, 0x00);
  245. __write_hw_reg32(SSI0_CTRL0, bWk);
  246. }
  247. /* ---------------------------------------------------------------------------------------------------
  248. - 函数名称: spi_flash_write_page
  249. - 函数功能: 向SPI FLASH指定地址写入一页数据
  250. - 创建日期: 2015-09-16
  251. ----------------------------------------------------------------------------------------------------*/
  252. void spi_flash_write_page(uint32_t PageAddR, uint8_t *buff)
  253. {
  254. uint32_t addr = PageAddR;
  255. uint32_t iWK = 0;
  256. uint32_t i;
  257. for(i=0; i<PACKET_FULL_LEN; i++)
  258. {
  259. txbuff[i+4] = buff[i];
  260. }
  261. txbuff[0] = (uint8_t)(addr>>16);
  262. txbuff[1] = CMD_PAGE_PROGRAM;
  263. txbuff[2] = (uint8_t)(addr);
  264. txbuff[3] = (uint8_t)(addr>>8);
  265. __write_hw_reg32(SSI0_EN , 0x00);
  266. __write_hw_reg32(SSI0_DMAS , 0x03);
  267. __write_hw_reg32(SSI0_DMATDL, 0x4); //-
  268. __write_hw_reg32(SSI0_DMARDL, 0x4); //- 1/2FIFO
  269. __write_hw_reg32(SSI0_EN , 0x01);
  270. //- RX Channel
  271. __write_hw_reg32(DMAS_CHx_SAR(10), 0x40013060);
  272. __write_hw_reg32(DMAS_CHx_DAR(10), (uint32_t)rxbuff);
  273. __write_hw_reg32(DMAS_CHx_CTL1(10),((2 << 8)| 1));
  274. __write_hw_reg32(DMAS_CHx_CTL0(10),(PACKET_FULL_LEN+4));
  275. __write_hw_reg32(DMAS_EN, 10);
  276. //- TX Channel
  277. __write_hw_reg32(DMAS_CHx_SAR(2), (uint32_t)txbuff);
  278. __write_hw_reg32(DMAS_CHx_DAR(2), 0x40013060);
  279. __write_hw_reg32(DMAS_CHx_CTL1(2),((2 << 8)| 1));
  280. __write_hw_reg32(DMAS_CHx_CTL0(2),(PACKET_FULL_LEN+4));
  281. __write_hw_reg32(DMAS_EN, 2);
  282. do {
  283. __read_hw_reg32(DMAS_INT_RAW , iWK);
  284. }while((iWK&0x404) != 0x404);
  285. __write_hw_reg32(DMAS_INT_RAW, 0x404);
  286. __write_hw_reg32(DMAS_CLR , 10);
  287. __write_hw_reg32(DMAS_CLR , 2);
  288. __write_hw_reg32(SSI0_EN , 0x00);
  289. }
  290. #ifdef TH25D_20UA //使用紫光青藤flash
  291. /* ---------------------------------------------------------------------------------------------------
  292. - 函数名称: spi_flash_page_erase
  293. - 函数功能: 擦除芯片指定page的内容 ---紫光青藤flash有此功能,GD兆易 和 MD普软 flash没有此功能
  294. - 创建日期: 2016-06-15
  295. ----------------------------------------------------------------------------------------------------*/
  296. void spi_flash_page_erase(uint32_t no)
  297. {
  298. uint32_t addr = (no*FLASH_PAGE_SIZE);
  299. uint32_t iWK = 0;
  300. txbuff[0] = (uint8_t)(addr>>16);
  301. txbuff[1] = CMD_PAGE_ERASE;
  302. txbuff[2] = (uint8_t)(addr);
  303. txbuff[3] = (uint8_t)(addr>>8);
  304. __write_hw_reg32(SSI0_EN, 0x00);
  305. __write_hw_reg32(SSI0_DMAS, 0x03);
  306. __write_hw_reg32(SSI0_DMATDL, 0x4); //-
  307. __write_hw_reg32(SSI0_DMARDL, 0x4); //- 1/4 FIFO
  308. __write_hw_reg32(SSI0_EN, 0x01);
  309. //- RX Channel
  310. __write_hw_reg32(DMAS_CHx_SAR(10), 0x40013060);
  311. __write_hw_reg32(DMAS_CHx_DAR(10), (uint32_t)rxbuff);
  312. __write_hw_reg32(DMAS_CHx_CTL1(10),((2 << 8)| 1));
  313. __write_hw_reg32(DMAS_CHx_CTL0(10),4);
  314. __write_hw_reg32(DMAS_EN , 10);
  315. //- TX Channel
  316. __write_hw_reg32(DMAS_CHx_SAR(2), (uint32_t)txbuff);
  317. __write_hw_reg32(DMAS_CHx_DAR(2), 0x40013060);
  318. __write_hw_reg32(DMAS_CHx_CTL1(2),((2 << 8)| 1));
  319. __write_hw_reg32(DMAS_CHx_CTL0(2),4);
  320. __write_hw_reg32(DMAS_EN, 2);
  321. do {
  322. __read_hw_reg32(DMAS_INT_RAW , iWK);
  323. }while((iWK&0x404) != 0x404);
  324. __write_hw_reg32(DMAS_INT_RAW, 0x404);
  325. __write_hw_reg32(DMAS_CLR, 10);
  326. __write_hw_reg32(DMAS_CLR, 2);
  327. __write_hw_reg32(SSI0_EN, 0x00);
  328. }
  329. #else
  330. /* ---------------------------------------------------------------------------------------------------
  331. - 函数名称: spi_flash_sector_erase
  332. - 函数功能: 擦除芯片指定sector的内容
  333. - 创建日期: 2016-06-15
  334. ----------------------------------------------------------------------------------------------------*/
  335. void spi_flash_sector_erase(uint32_t no)
  336. {
  337. uint32_t addr = (no*FLASH_SECTOR_SIZE);
  338. uint32_t iWK = 0;
  339. txbuff[0] = (uint8_t)(addr>>16);
  340. txbuff[1] = CMD_SECTOR_ERASE;
  341. txbuff[2] = (uint8_t)(addr);
  342. txbuff[3] = (uint8_t)(addr>>8);
  343. __write_hw_reg32(SSI0_EN, 0x00);
  344. __write_hw_reg32(SSI0_DMAS, 0x03);
  345. __write_hw_reg32(SSI0_DMATDL, 0x4); //-
  346. __write_hw_reg32(SSI0_DMARDL, 0x4); //- 1/4 FIFO
  347. __write_hw_reg32(SSI0_EN, 0x01);
  348. //- RX Channel
  349. __write_hw_reg32(DMAS_CHx_SAR(10), 0x40013060);
  350. __write_hw_reg32(DMAS_CHx_DAR(10), (uint32_t)rxbuff);
  351. __write_hw_reg32(DMAS_CHx_CTL1(10),((2 << 8)| 1));
  352. __write_hw_reg32(DMAS_CHx_CTL0(10),4);
  353. __write_hw_reg32(DMAS_EN , 10);
  354. //- TX Channel
  355. __write_hw_reg32(DMAS_CHx_SAR(2), (uint32_t)txbuff);
  356. __write_hw_reg32(DMAS_CHx_DAR(2), 0x40013060);
  357. __write_hw_reg32(DMAS_CHx_CTL1(2),((2 << 8)| 1));
  358. __write_hw_reg32(DMAS_CHx_CTL0(2),4);
  359. __write_hw_reg32(DMAS_EN, 2);
  360. do {
  361. __read_hw_reg32(DMAS_INT_RAW , iWK);
  362. }while((iWK&0x404) != 0x404);
  363. __write_hw_reg32(DMAS_INT_RAW, 0x404);
  364. __write_hw_reg32(DMAS_CLR, 10);
  365. __write_hw_reg32(DMAS_CLR, 2);
  366. __write_hw_reg32(SSI0_EN, 0x00);
  367. }
  368. #endif
  369. /* ---------------------------------------------------------------------------------------------------
  370. - 函数名称: spi_flash_Release_powerdown
  371. - 函数功能: SPI_FLASH Exit Power-Down
  372. - 创建日期: 2016-10-24
  373. ----------------------------------------------------------------------------------------------------*/
  374. void spi_flash_Release_powerdown(void)
  375. {
  376. uint32_t bWk, cWk;
  377. __read_hw_reg32(SSI0_CTRL0, bWk);
  378. __write_hw_reg32(SSI0_EN, 0x00);
  379. __write_hw_reg32(SSI0_DMAS, 0x00);
  380. __write_hw_reg32(SSI0_CTRL0, 0x07); /* 8bit SPI data */
  381. __write_hw_reg32(SSI0_EN, 0x01);
  382. __write_hw_reg32(SSI0_DATA, CMD_RELEASE_PWRDWN);
  383. do {
  384. __read_hw_reg32(SSI0_STS, cWk);
  385. }while((cWk&0x05) != 0x04);
  386. __write_hw_reg32(SSI0_EN, 0x00);
  387. __write_hw_reg32(SSI0_CTRL0, bWk);
  388. }
  389. /* ---------------------------------------------------------------------------------------------------
  390. - 函数名称: spi_flash_powerdown
  391. - 函数功能: SPI_FLASH Enter Power-Down
  392. - 创建日期: 2016-11-07
  393. ----------------------------------------------------------------------------------------------------*/
  394. void spi_flash_Enter_powerdown(void)
  395. {
  396. uint32_t bWk, cWk;
  397. __read_hw_reg32(SSI0_CTRL0, bWk);
  398. __write_hw_reg32(SSI0_EN, 0x00);
  399. __write_hw_reg32(SSI0_DMAS, 0x00);
  400. __write_hw_reg32(SSI0_CTRL0, 0x07); /* 8bit SPI data */
  401. __write_hw_reg32(SSI0_EN, 0x01);
  402. __write_hw_reg32(SSI0_DATA, CMD_PWRDWN);
  403. do {
  404. __read_hw_reg32(SSI0_STS, cWk);
  405. }while((cWk&0x05) != 0x04);
  406. __write_hw_reg32(SSI0_EN, 0x00);
  407. __write_hw_reg32(SSI0_CTRL0, bWk);
  408. }
  409. /* ---------------------------------------------------------------------------------------------------
  410. - 函数名称: spi1_write_read_uint16
  411. - 函数功能: spi1 向外发送两个字节, 并读回两个字节
  412. - 创建日期: 2016-11-07
  413. ----------------------------------------------------------------------------------------------------*/
  414. uint16_t spi1_write_read_uint16(uint16_t val)
  415. {
  416. uint32_t cWk;
  417. __write_hw_reg32(SSI1_EN, 0x00);
  418. __write_hw_reg32(SSI1_DMAS, 0x00);
  419. __write_hw_reg32(SSI1_EN, 0x01);
  420. __write_hw_reg32(SSI1_DATA, val);
  421. do {
  422. __read_hw_reg32(SSI1_STS, cWk);
  423. }while((cWk&0x05) != 0x4);
  424. __read_hw_reg32(SSI1_DATA, val);
  425. __write_hw_reg32(SSI1_EN, 0x00);
  426. return (val);
  427. }
  428. /* ---------------------------------------------------------------------------------------------------
  429. - 函数名称: spi1_write_read_stream
  430. - 函数功能: spi1 向外发送并读回长度为Length的一串16BIT宽度数据.
  431. - 创建日期: 2016-11-07
  432. ----------------------------------------------------------------------------------------------------*/
  433. void spi1_write_read_stream(uint16_t *input, uint16_t *output, uint16_t length)
  434. {
  435. uint32_t iwk;
  436. __write_hw_reg32(SSI1_EN, 0x00);
  437. __write_hw_reg32(SSI1_DMAS, 0x03);
  438. __write_hw_reg32(SSI1_DMATDL, 0x2);
  439. __write_hw_reg32(SSI1_DMARDL, 0x2);
  440. __write_hw_reg32(SSI1_EN, 0x01);
  441. //- RX Channel
  442. __write_hw_reg32(DMAS_CHx_SAR(11), 0x40014060);
  443. __write_hw_reg32(DMAS_CHx_DAR(11), (uint32_t)output);
  444. __write_hw_reg32(DMAS_CHx_CTL1(11),((2 << 8)| 1));
  445. __write_hw_reg32(DMAS_CHx_CTL0(11),(length<<1));
  446. __write_hw_reg32(DMAS_EN, 11);
  447. //- TX Channel
  448. __write_hw_reg32(DMAS_CHx_SAR(3), (uint32_t)input);
  449. __write_hw_reg32(DMAS_CHx_DAR(3), 0x40014060);
  450. __write_hw_reg32(DMAS_CHx_CTL1(3),((2 << 8)| 1));
  451. __write_hw_reg32(DMAS_CHx_CTL0(3),(length<<1));
  452. __write_hw_reg32(DMAS_EN, 3);
  453. do {
  454. __read_hw_reg32(DMAS_INT_RAW, iwk);
  455. }while((iwk&0x808) != 0x808);
  456. __write_hw_reg32(DMAS_INT_RAW, 0x808);
  457. __write_hw_reg32(DMAS_CLR, 11);
  458. __write_hw_reg32(DMAS_CLR, 3);
  459. __write_hw_reg32(SSI1_EN, 0x00);
  460. }
  461. #ifndef TH25D_20UA
  462. /******************************************2019.04.08新增******************************************/
  463. /* ---------------------------------------------------------------------------------------------------
  464. - 函数名称: spi_flash_Read
  465. - 函数功能: 在指定的地址开始读取指定长度的数据
  466. - 创建日期: 2019.04.08
  467. - 作 者:陈俊伟
  468. ----------------------------------------------------------------------------------------------------*/
  469. void spi_flash_Read(uint32_t ReadAddR, uint8_t *buff,uint16_t ReadLength)
  470. {
  471. uint32_t PagePos=ReadAddR/FLASH_PAGE_SIZE;//页地址
  472. uint16_t PageOff=ReadAddR%FLASH_PAGE_SIZE;//页偏移地址
  473. uint16_t i=0,PageMain=FLASH_PAGE_SIZE-PageOff;//页剩余地址
  474. if(ReadLength<=PageMain) PageMain=ReadLength;
  475. while(1)
  476. {
  477. spi_flash_Read_Page(PagePos*FLASH_PAGE_SIZE,rxbuff);
  478. for(i=0;i<PageMain;i++)
  479. {
  480. buff[i]=rxbuff[PageOff+i+4];
  481. }
  482. if(ReadLength==PageMain) break;
  483. else
  484. {
  485. PagePos++;
  486. PageOff=0;
  487. buff+=PageMain;
  488. ReadAddR+=PageMain;
  489. ReadLength-=PageMain;
  490. if(ReadLength>FLASH_PAGE_SIZE) PageMain=FLASH_PAGE_SIZE;
  491. else PageMain=ReadLength;
  492. }
  493. }
  494. }
  495. /* ---------------------------------------------------------------------------------------------------
  496. - 函数名称: spi_flash_Read_Sector
  497. - 函数功能: 从SPI FLASH中读取一个扇区数据到指定地址
  498. - 创建日期: 2019.04.08
  499. - 作 者:陈俊伟
  500. ----------------------------------------------------------------------------------------------------*/
  501. void spi_flash_Read_Sector(uint32_t ReadAddR, uint8_t *buff)
  502. {
  503. uint8_t i=0,j=FLASH_SECTOR_SIZE/FLASH_PAGE_SIZE;
  504. uint16_t k=0;
  505. for(i=0;i<j;i++)
  506. {
  507. spi_flash_Read_Page(ReadAddR,rxbuff);
  508. for(k=0;k<FLASH_PAGE_SIZE;k++)
  509. {
  510. *buff=rxbuff[4+k];
  511. buff++;
  512. }
  513. ReadAddR+=FLASH_PAGE_SIZE;
  514. }
  515. }
  516. /* ---------------------------------------------------------------------------------------------------
  517. - 函数名称: spi_flash_write_Sector
  518. - 函数功能: 向SPI FLASH指定扇区写入数据
  519. - 创建日期: 2019.04.08
  520. - 作 者:陈俊伟
  521. ---------------------------------------------------------------*/
  522. void spi_flash_write_Sector(uint32_t WriteAddR, uint8_t *buff)
  523. {
  524. uint8_t i=0,j=FLASH_SECTOR_SIZE/FLASH_PAGE_SIZE;
  525. for(i=0;i<j;i++)
  526. {
  527. spi_flash_write_enable();
  528. spi_flash_write_page(WriteAddR,buff);
  529. while(spi_flash_wait_till_ready());
  530. WriteAddR+=FLASH_PAGE_SIZE;
  531. buff+=FLASH_PAGE_SIZE;
  532. }
  533. }
  534. /* ---------------------------------------------------------------------------------------------------
  535. - 函数名称: spi_flash_write
  536. - 函数功能: 在指定的地址开始写入指定长度的数据
  537. - 创建日期: 2019.04.08
  538. - 作 者:陈俊伟
  539. ----------------------------------------------------------------------------------------------------*/
  540. static volatile uint8_t FlashBuf[FLASH_SECTOR_SIZE];
  541. void spi_flash_write(uint32_t WriteAddR, uint8_t *buff,uint16_t WriteLength)
  542. {
  543. uint32_t sectorpos;//扇区地址
  544. uint16_t sectoroff;//扇区偏移地址
  545. uint16_t sectorremain;//扇区剩余地址
  546. uint16_t i,j;
  547. sectorpos=WriteAddR/FLASH_SECTOR_SIZE;
  548. sectoroff=WriteAddR%FLASH_SECTOR_SIZE;
  549. sectorremain=FLASH_SECTOR_SIZE-sectoroff;
  550. if(WriteLength<=sectorremain) sectorremain=WriteLength;
  551. while(1)
  552. {
  553. spi_flash_Read_Sector(sectorpos*FLASH_SECTOR_SIZE,FlashBuf);
  554. for(i=0;i<sectorremain;i++)
  555. {
  556. FlashBuf[sectoroff+i]=buff[i];
  557. }
  558. spi_flash_write_enable();
  559. spi_flash_sector_erase(sectorpos);
  560. while(spi_flash_wait_till_ready());
  561. spi_flash_write_Sector(sectorpos*FLASH_SECTOR_SIZE,FlashBuf);
  562. if(WriteLength==sectorremain) break;
  563. else
  564. {
  565. sectorpos++;
  566. sectoroff=0;
  567. buff+=sectorremain;
  568. WriteAddR+=sectorremain;
  569. WriteLength-=sectorremain;
  570. if(WriteLength>FLASH_SECTOR_SIZE) sectorremain=FLASH_SECTOR_SIZE;
  571. else sectorremain=WriteLength;
  572. }
  573. }
  574. }
  575. #else //使用紫光青藤flash
  576. /******2020.10.14新增 以下接口目前适用于紫光青藤flash 以下接口目的是为省掉读写扇区所需要的大的缓冲区********/
  577. /* ---------------------------------------------------------------------------------------------------
  578. - 函数名称: spi_flash_Read
  579. - 函数功能: 在指定的地址开始读取指定长度的数据
  580. - 创建日期: 2020.10.14
  581. ----------------------------------------------------------------------------------------------------*/
  582. void spi_flash_Read(uint32_t ReadAddR, uint8_t *buff,uint16_t ReadLength)
  583. {
  584. uint32_t PagePos=ReadAddR/FLASH_PAGE_SIZE;//页地址
  585. uint16_t PageOff=ReadAddR%FLASH_PAGE_SIZE;//页偏移地址
  586. uint16_t i=0,PageMain=FLASH_PAGE_SIZE-PageOff;//页剩余地址
  587. if(ReadLength<=PageMain) PageMain=ReadLength;
  588. while(1)
  589. {
  590. spi_flash_Read_Page(PagePos*FLASH_PAGE_SIZE,rxbuff);
  591. for(i=0;i<PageMain;i++)
  592. {
  593. buff[i]=rxbuff[PageOff+i+4];
  594. }
  595. if(ReadLength==PageMain) break;
  596. else
  597. {
  598. PagePos++;
  599. PageOff=0;
  600. buff+=PageMain;
  601. ReadAddR+=PageMain;
  602. ReadLength-=PageMain;
  603. if(ReadLength>FLASH_PAGE_SIZE) PageMain=FLASH_PAGE_SIZE;
  604. else PageMain=ReadLength;
  605. }
  606. }
  607. }
  608. /* ---------------------------------------------------------------------------------------------------
  609. - 函数名称: spi_flash_write
  610. - 函数功能: 在指定的地址开始写入指定长度的数据
  611. - 创建日期:2020.10.14
  612. ----------------------------------------------------------------------------------------------------*/
  613. void spi_flash_write(uint32_t WriteAddR, uint8_t *buff,uint16_t WriteLength)
  614. {
  615. uint8_t FlashBuf[FLASH_PAGE_SIZE ];
  616. uint32_t PagePos=WriteAddR/FLASH_PAGE_SIZE;//页地址
  617. uint16_t PageOff=WriteAddR%FLASH_PAGE_SIZE;//页偏移地址
  618. uint16_t i=0,PageMain=FLASH_PAGE_SIZE-PageOff;//页剩余地址
  619. if(WriteLength<=PageMain) PageMain=WriteLength;
  620. while(1)
  621. {
  622. spi_flash_Read_Page(PagePos*FLASH_PAGE_SIZE,rxbuff);
  623. for(i=0;i<FLASH_PAGE_SIZE;i++) FlashBuf[i]=rxbuff[i+4];
  624. for(i=0;i<PageMain;i++) FlashBuf[PageOff+i]=buff[i];
  625. spi_flash_write_enable();
  626. spi_flash_page_erase(PagePos);
  627. while(spi_flash_wait_till_ready());
  628. spi_flash_write_enable();
  629. spi_flash_write_page(PagePos*FLASH_PAGE_SIZE,FlashBuf );
  630. while(spi_flash_wait_till_ready());
  631. if(WriteLength==PageMain) break;
  632. else
  633. {
  634. PagePos++;
  635. PageOff=0;
  636. buff+=PageMain;
  637. WriteAddR+=PageMain;
  638. WriteLength-=PageMain;
  639. if(WriteLength>FLASH_PAGE_SIZE) PageMain=FLASH_PAGE_SIZE;
  640. else PageMain=WriteLength;
  641. }
  642. }
  643. }
  644. #endif
  645. /* END */
  646. #if 0
  647. #define SPI_CS_HIGHT while(((*(SSI1_STS))&0x05)!=0x04);gpio_output_high(0)
  648. #define SPI_CS_LOW while(((*(SSI1_STS))&0x05)!=0x04);gpio_output_low(0)
  649. void Init_spi1_mode3_master(uint32_t freq)
  650. {
  651. uint32_t val;
  652. __write_hw_reg32(CPR_SPIx_MCLK_CTL(1), 0x110010);//1分频 //- spi(x)_mclk = 32Mhz(When TXCO=32Mhz).
  653. __write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL , (0x1000100<<1)); //- 打开spi(x) pclk.
  654. __read_hw_reg32(CPR_SSI_CTRL, val);
  655. val |= (1==0)? 0x01: 0x30;
  656. __write_hw_reg32(CPR_SSI_CTRL, val);
  657. __write_hw_reg32(SSIx_EN(1), 0x00);
  658. __write_hw_reg32(SSIx_IE(1), 0x00);
  659. __write_hw_reg32(SSIx_CTRL0(1) , 0xC7); /* 8bit SPI data */
  660. __write_hw_reg32(SSIx_SE(1), 0x01);
  661. __write_hw_reg32(SSIx_BAUD(1), freq); //- spix_mclk 分频.
  662. __write_hw_reg32(SSIx_RXFTL(1), 0x00);
  663. __write_hw_reg32(SSIx_TXFTL(1), 0x00);
  664. __write_hw_reg32(SSIx_EN(1) , 0x01);
  665. //cs线由GPIO0手动拉低拉高 手动模拟
  666. gpio_mux_ctl(0,0);gpio_fun_inter(0,0);gpio_fun_sel(0,0);gpio_direction_output(0);gpio_output_high(0);
  667. //sclk(GPIO1)
  668. gpio_mux_ctl(1,0);gpio_fun_inter(1,0);gpio_fun_sel(1,14);
  669. //miso(GPIO4)
  670. gpio_mux_ctl(4,0);gpio_fun_inter(4,0);gpio_fun_sel(4,16);
  671. //mosi(GPIO5)
  672. gpio_mux_ctl(5,0);gpio_fun_inter(5,0);gpio_fun_sel(5,17);
  673. }
  674. uint8_t SPI_Send_Dat(uint8_t dat)
  675. {
  676. __write_hw_reg32(SSI1_DATA, dat);
  677. while(((*(SSI1_STS))&0xC)!=0xC);
  678. return (*(SSI1_DATA));
  679. }
  680. uint8_t SPI_Receiver_Dat(void)
  681. {
  682. __write_hw_reg32(SSI1_DATA, 0xFF);
  683. while(((*(SSI1_STS))&0xC)!=0xC);
  684. return (*(SSI1_DATA));
  685. }
  686. void w25qxx_Release_powerdown(void)
  687. {
  688. SPI_CS_LOW;
  689. SPI_Send_Dat(0xAB);
  690. SPI_CS_HIGHT;
  691. }
  692. void w25qxx_Enter_powerdown(void)
  693. {
  694. SPI_CS_LOW;
  695. SPI_Send_Dat(0xB9);
  696. SPI_CS_HIGHT;
  697. }
  698. uint8_t W25QXX_ReadSR(void)
  699. {
  700. uint8_t byte=0;
  701. SPI_CS_LOW; //使能器件
  702. SPI_Send_Dat(0x05); //发送读取状态寄存器命令
  703. byte=SPI_Receiver_Dat(); //读取一个字节
  704. SPI_CS_HIGHT; //取消片选
  705. return byte;
  706. }
  707. void W25QXX_Write_SR(uint8_t sr)
  708. {
  709. SPI_CS_LOW; //使能器件
  710. SPI_Send_Dat(0x01); //发送写取状态寄存器命令
  711. SPI_Send_Dat(sr); //写入一个字节
  712. SPI_CS_HIGHT; //取消片选
  713. }
  714. #endif