spiflash.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. /**
  2. * @file spiflash.c
  3. * @author chipsea
  4. * @brief
  5. * @version 0.1
  6. * @date 2020-11-30
  7. * @copyright Copyright (c) 2020, CHIPSEA Co., Ltd.
  8. * @note
  9. */
  10. #include "error.h"
  11. #include "spiflash.h"
  12. #include "log.h"
  13. #include "string.h"
  14. #include "dma.h"
  15. uint32_t spiflash_space = 0x80000;
  16. hal_spi_t spiflash_spi ={
  17. .spi_index = SPI0,
  18. };
  19. void spi_cb(spi_evt_t* evt)
  20. {
  21. }
  22. void dma_cb(DMA_CH_t ch)
  23. {
  24. }
  25. spi_Cfg_t spi_cfg = {
  26. .sclk_pin = GPIO_P02,
  27. .ssn_pin = GPIO_P07,
  28. .MOSI = GPIO_P00,
  29. .MISO = GPIO_P03,
  30. .baudrate = 8000000,
  31. .spi_tmod = SPI_TRXD,
  32. .spi_scmod = SPI_MODE0,
  33. .spi_dfsmod = SPI_1BYTE,
  34. #if DMAC_USE
  35. .dma_tx_enable = false,
  36. .dma_rx_enable = false,
  37. #endif
  38. .int_mode = false,
  39. .force_cs = true,
  40. .evt_handler = spi_cb,
  41. };
  42. HAL_DMA_t dma_cfg = {
  43. .dma_channel = DMA_CH_0,
  44. .evt_handler = dma_cb,
  45. };
  46. #define spiflash_cmd_tx_and_rx(mode,tx_buf,rx_buf,tx_len,rx_len) \
  47. hal_spi_transmit(&spiflash_spi,mode,tx_buf,rx_buf,tx_len,rx_len)
  48. //gd25q16 driver
  49. uint32_t spiflash_read_identification(void)//check
  50. {
  51. uint8_t buf_send[1] = {FLASH_RDID};
  52. uint8_t buf_rece[3] = {0x00,0x00,0x00};
  53. hal_spi_dma_set(&spiflash_spi,0,0);
  54. if(SUCCESS == spiflash_cmd_tx_and_rx(SPI_EEPROM,buf_send,buf_rece,1,3))
  55. return (buf_rece[0] << 16)|(buf_rece[1] << 8) | (buf_rece[2]);
  56. else
  57. return 0xFFFFFF;
  58. }
  59. uint16_t spiflash_read_status_register(uint8_t bitsSel)//0~low other~high
  60. {
  61. uint8_t buf_send[1] = {0x00};
  62. uint8_t buf_rece[2] = {0x00,0x00};
  63. if(bitsSel == 0)
  64. buf_send[0] = FLASH_RDSR_LOW;
  65. else
  66. buf_send[0] = FLASH_RDSR_HIGH;
  67. hal_spi_dma_set(&spiflash_spi,0,0);
  68. if(SUCCESS == spiflash_cmd_tx_and_rx(SPI_EEPROM,buf_send,buf_rece,1,2))
  69. return (buf_rece[0] << 8) | (buf_rece[1]);
  70. else
  71. return 0xFFFF;
  72. }
  73. bool spiflash_bus_busy(void)
  74. {
  75. return (spiflash_read_status_register(0) & 0x01);
  76. }
  77. void spiflash_program_erase_suspend(void)
  78. {
  79. uint8_t buf_send[1] = {FLASH_PES};
  80. hal_spi_dma_set(&spiflash_spi,0,0);
  81. if(SUCCESS == spiflash_cmd_tx_and_rx(SPI_TXD,buf_send,NULL,1,0))
  82. {
  83. ;
  84. }
  85. }
  86. void spiflash_program_erase_resume(void)
  87. {
  88. uint8_t buf_send[1] = {FLASH_PER};
  89. hal_spi_dma_set(&spiflash_spi,0,0);
  90. if(SUCCESS == spiflash_cmd_tx_and_rx(SPI_TXD,buf_send,NULL,1,0))
  91. {
  92. ;
  93. }
  94. }
  95. void spiflash_deep_powerdown(void)
  96. {
  97. uint8_t buf_send[1] = {FLASH_DP};
  98. hal_spi_dma_set(&spiflash_spi,0,0);
  99. if(SUCCESS == spiflash_cmd_tx_and_rx(SPI_TXD,buf_send,NULL,1,0))
  100. {
  101. ;
  102. }
  103. }
  104. void spiflash_release_from_powerdown(void)
  105. {
  106. uint8_t buf_send[1] = {FLASH_RDI};
  107. hal_spi_dma_set(&spiflash_spi,0,0);
  108. if(SUCCESS == spiflash_cmd_tx_and_rx(SPI_TXD,buf_send,NULL,1,0))
  109. {
  110. ;
  111. }
  112. }
  113. void spiflash_write_enable(void)
  114. {
  115. uint8_t buf_send[1] = {FLASH_WREN};
  116. while(spiflash_bus_busy());
  117. hal_spi_dma_set(&spiflash_spi,0,0);
  118. if(SUCCESS == spiflash_cmd_tx_and_rx(SPI_TXD,buf_send,NULL,1,0))
  119. {
  120. ;
  121. }
  122. }
  123. void spiflash_write_disable(void)
  124. {
  125. uint8_t buf_send[1] = {FLASH_WRDIS};
  126. //while(spiflash_bus_busy());
  127. hal_spi_dma_set(&spiflash_spi,0,0);
  128. if(SUCCESS == spiflash_cmd_tx_and_rx(SPI_TXD,buf_send,NULL,1,0))
  129. {
  130. ;
  131. }
  132. }
  133. void spiflash_chip_erase(void)
  134. {
  135. uint8_t buf_send[1] = {FLASH_CE};
  136. buf_send[0] = FLASH_CE;
  137. spiflash_write_enable();
  138. hal_spi_dma_set(&spiflash_spi,0,0);
  139. if(SUCCESS == spiflash_cmd_tx_and_rx(SPI_TXD,buf_send,NULL,1,0))
  140. {
  141. ;
  142. }
  143. while(spiflash_bus_busy());
  144. }
  145. void spiflash_sector_erase(uint32_t addr)
  146. {
  147. uint8_t buf_send[4] = {FLASH_SE,0x00,0x00,0x00};
  148. buf_send[1] = (addr>>16) & 0xff;
  149. buf_send[2] = (addr>>8) & 0xff;
  150. buf_send[3] = addr & 0xff;
  151. spiflash_write_enable();
  152. hal_spi_dma_set(&spiflash_spi,0,0);
  153. if(SUCCESS == spiflash_cmd_tx_and_rx(SPI_TXD,buf_send,NULL,4,0))
  154. {
  155. ;
  156. }
  157. while(spiflash_bus_busy());
  158. }
  159. void spiflash_block_erase_32KB(uint32_t addr)
  160. {
  161. uint8_t buf_send[4] = {FLASH_BE_32KB,0x00,0x00,0x00};
  162. buf_send[1] = (addr>>16) & 0xff;
  163. buf_send[2] = (addr>>8) & 0xff;
  164. buf_send[3] = addr & 0xff;
  165. spiflash_write_enable();
  166. hal_spi_dma_set(&spiflash_spi,0,0);
  167. if(SUCCESS == spiflash_cmd_tx_and_rx(SPI_TXD,buf_send,NULL,4,0))
  168. {
  169. ;
  170. }
  171. while(spiflash_bus_busy());
  172. }
  173. void spiflash_block_erase_64KB(uint32_t addr)
  174. {
  175. uint8_t buf_send[4] = {FLASH_BE_64KB,0x00,0x00,0x00};
  176. buf_send[1] = (addr>>16) & 0xff;
  177. buf_send[2] = (addr>>8) & 0xff;
  178. buf_send[3] = addr & 0xff;
  179. spiflash_write_enable();
  180. hal_spi_dma_set(&spiflash_spi,0,0);
  181. if(SUCCESS == spiflash_cmd_tx_and_rx(SPI_TXD,buf_send,NULL,4,0))
  182. {
  183. ;
  184. }
  185. while(spiflash_bus_busy());
  186. }
  187. void spiflash_write_status_register(uint8_t data)
  188. {
  189. uint8_t buf_send[2] = {FLASH_WRSR,0x00};
  190. buf_send[1] = data;
  191. while(spiflash_bus_busy());
  192. spiflash_write_enable();
  193. hal_spi_dma_set(&spiflash_spi,0,0);
  194. if(SUCCESS == spiflash_cmd_tx_and_rx(SPI_TXD,buf_send,NULL,2,0))
  195. {
  196. ;
  197. }
  198. }
  199. static void spiflash_write_unit(uint32_t addr,uint8_t* tx_buf,uint8_t tx_len)//tx_len in [1,4]
  200. {
  201. uint8_t buf_send[8] = {FLASH_PP,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  202. buf_send[1] = (addr>>16)&0xff;
  203. buf_send[2] = (addr>>8)&0xff;
  204. buf_send[3] = addr & 0xff;
  205. switch(tx_len)
  206. {
  207. case 1:
  208. buf_send[4] = *tx_buf;
  209. break;
  210. case 2:
  211. buf_send[4] = *tx_buf;
  212. buf_send[5] = *(tx_buf+1);
  213. break;
  214. case 3:
  215. buf_send[4] = *tx_buf;
  216. buf_send[5] = *(tx_buf+1);
  217. buf_send[6] = *(tx_buf+2);
  218. break;
  219. case 4:
  220. buf_send[4] = *tx_buf;
  221. buf_send[5] = *(tx_buf+1);
  222. buf_send[6] = *(tx_buf+2);
  223. buf_send[7] = *(tx_buf+3);
  224. break;
  225. default:
  226. break;
  227. }
  228. spiflash_write_enable();
  229. hal_spi_dma_set(&spiflash_spi,0,0);
  230. if(SUCCESS == spiflash_cmd_tx_and_rx(SPI_TXD,buf_send,NULL,(tx_len + 4),0))
  231. {
  232. ;
  233. }
  234. }
  235. void spiflash_write(uint32_t addr,uint8_t* tx_buf,uint16_t tx_len)
  236. {
  237. uint16_t offset = 0,ret16;
  238. ret16 = spiflash_read_status_register(0);
  239. if(ret16 != 0)
  240. {
  241. spiflash_write_status_register(0x00);
  242. while(spiflash_bus_busy());
  243. }
  244. while(tx_len > 0)
  245. {
  246. if(tx_len >= 4)
  247. {
  248. spiflash_write_unit((addr + offset),(tx_buf + offset),4);
  249. offset += 4;
  250. tx_len -= 4;
  251. }
  252. else
  253. {
  254. spiflash_write_unit((addr + offset),(tx_buf + offset),tx_len);
  255. tx_len = 0;
  256. }
  257. while(spiflash_bus_busy());
  258. }
  259. //you can process the protect with your requirenment
  260. // if(ret16 != 0)
  261. // {
  262. // spiflash_write_status_register(ret16);
  263. // }
  264. }
  265. void spiflash_write_eeprom(uint32_t addr,uint8_t* tx_buf,uint16_t tx_len)
  266. {
  267. uint8_t buf_send[256+4];
  268. uint16_t ret16;
  269. buf_send[0] = FLASH_PP;
  270. buf_send[1] = (addr>>16)&0xff;
  271. buf_send[2] = (addr>>8)&0xff;
  272. buf_send[3] = addr & 0xff;
  273. memcpy(&buf_send[4],tx_buf,tx_len);
  274. ret16 = spiflash_read_status_register(0);
  275. if(ret16 != 0)
  276. {
  277. spiflash_write_status_register(0x00);
  278. while(spiflash_bus_busy() == TRUE);
  279. }
  280. spiflash_write_enable();
  281. hal_spi_dma_set(&spiflash_spi,1,0);
  282. if(SUCCESS == spiflash_cmd_tx_and_rx(SPI_TXD,buf_send,NULL,(tx_len + 4),0))
  283. {
  284. ;
  285. }
  286. while(spiflash_bus_busy());
  287. }
  288. static void spiflash_read_unit(uint32_t addr,uint8_t* rx_buf,uint8_t rx_len)//rx_len in [1,4]
  289. {
  290. uint8_t buf_send[4] = {FLASH_READ,0x00,0x00,0x00};
  291. uint8_t buf_rece[4] = {0x00,0x00,0x00,0x00};
  292. buf_send[1] = (addr>>16)&0xff;
  293. buf_send[2] = (addr>>8)&0xff;
  294. buf_send[3] = addr & 0xff;
  295. hal_spi_dma_set(&spiflash_spi,0,0);
  296. if(SUCCESS == spiflash_cmd_tx_and_rx(SPI_EEPROM,buf_send,buf_rece,4,rx_len))
  297. {
  298. switch(rx_len)
  299. {
  300. case 1:
  301. *rx_buf = buf_rece[0];
  302. break;
  303. case 2:
  304. *rx_buf = buf_rece[0];
  305. *(rx_buf+1) = buf_rece[1];
  306. break;
  307. case 3:
  308. *rx_buf = buf_rece[0];
  309. *(rx_buf+1) = buf_rece[1];
  310. *(rx_buf+2) = buf_rece[2];
  311. break;
  312. case 4:
  313. *rx_buf = buf_rece[0];
  314. *(rx_buf+1) = buf_rece[1];
  315. *(rx_buf+2) = buf_rece[2];
  316. *(rx_buf+3) = buf_rece[3];
  317. break;
  318. default:
  319. break;
  320. }
  321. }
  322. }
  323. static void spiflash_read_eeprom(uint32_t addr,uint8_t* rx_buf,uint16_t rx_len)//rx_len in [1,4]
  324. {
  325. uint8_t buf_send[4] = {FLASH_READ,0x00,0x00,0x00};
  326. buf_send[1] = (addr>>16)&0xff;
  327. buf_send[2] = (addr>>8)&0xff;
  328. buf_send[3] = addr & 0xff;
  329. hal_spi_dma_set(&spiflash_spi,0,1);
  330. if(SUCCESS == spiflash_cmd_tx_and_rx(SPI_EEPROM,buf_send,rx_buf,4,rx_len))
  331. {
  332. ;
  333. }
  334. }
  335. void spiflash_read(uint32_t addr,uint8_t* rx_buf,uint16_t rx_len)
  336. {
  337. //polling mode=polling
  338. //force_cs=0
  339. uint16_t offset = 0;
  340. while(rx_len > 0)
  341. {
  342. if(rx_len >= 4)
  343. {
  344. spiflash_read_unit((addr + offset),(rx_buf + offset),4);
  345. offset += 4;
  346. rx_len -= 4;
  347. }
  348. else
  349. {
  350. spiflash_read_unit((addr + offset),(rx_buf + offset),rx_len);
  351. rx_len = 0;
  352. }
  353. }
  354. }
  355. int spiflash_init(void)
  356. {
  357. uint8_t retval = SUCCESS;
  358. retval = hal_spi_bus_init(&spiflash_spi,spi_cfg);
  359. if(retval != SUCCESS)
  360. {
  361. LOG("spi init err!please check it!\n");
  362. return retval;
  363. }
  364. retval = HalDMAInitChannel(dma_cfg);
  365. if(retval != SUCCESS)
  366. {
  367. LOG("dma init err!please check it!\n");
  368. return retval;
  369. }
  370. return retval;
  371. }
  372. static void check_flash_space(uint8_t rev)
  373. {
  374. if(rev == 0x11) //128k flash
  375. {
  376. spiflash_space = 0x20000;
  377. }
  378. else if(rev == 0x12) //256k flash
  379. {
  380. spiflash_space = 0x40000;
  381. }
  382. else if(rev == 0x13) //512k flash
  383. {
  384. spiflash_space = 0x80000;
  385. }
  386. else if(rev == 0x14) //1m flash
  387. {
  388. spiflash_space = 0x100000;
  389. }
  390. else if(rev == 0x15) //2m flash
  391. {
  392. spiflash_space = 0x200000;
  393. }
  394. else if(rev == 0x16) //4m flash
  395. {
  396. spiflash_space = 0x400000;
  397. }
  398. else
  399. {
  400. spiflash_space = 0x80000; //default value
  401. }
  402. }
  403. //gd25q16
  404. int vendorflash_init(void)
  405. {
  406. //if(hal_spi_bus_init(&spi,cfg) == SUCCESS)//config and init spi first
  407. // LOG("spi init success!\n");
  408. uint32_t dev = spiflash_read_identification();
  409. if((!dev) || (dev==0xFFFFFF)){
  410. LOG("read flash id error %X\n",dev);
  411. return ERR_INVALID_PARAM;
  412. }
  413. LOG("flash id:0x%x\n",dev);
  414. check_flash_space(dev&0xff);
  415. return SUCCESS;
  416. }
  417. int vendorflash_read(uint32_t addr,uint8_t *data,uint16_t len)
  418. {
  419. if((addr < spiflash_space) && (data != NULL) && (len > 0)){
  420. spiflash_read_eeprom(addr,data,len);
  421. return SUCCESS;
  422. }
  423. return ERR_SPI_FLASH;
  424. }
  425. int vendorflash_erase(uint32_t addr,uint32_t len)
  426. {
  427. uint8_t lockinfo = 0;
  428. uint32_t remainder = 0;
  429. if((addr >= spiflash_space) || (len == 0))
  430. return ERR_INVALID_PARAM;
  431. lockinfo = spiflash_read_status_register(0);
  432. spiflash_write_status_register(0x00);
  433. if((addr == 0) && (len == spiflash_space))
  434. spiflash_chip_erase();
  435. else
  436. {
  437. remainder = addr%0x1000;//4KB
  438. if(remainder){
  439. addr -= remainder;
  440. len += remainder;
  441. }
  442. remainder = len%0x1000;//4KB
  443. if(remainder){
  444. len = len + 0x1000 - remainder;
  445. }
  446. addr = addr/0x1000;
  447. len = len/0x1000;
  448. while(len > 0){
  449. if(((addr %16) == 0) && (len >= 16)){
  450. while(spiflash_bus_busy());
  451. spiflash_block_erase_64KB(addr*0x1000);
  452. addr += 16;
  453. len -= 16;
  454. continue;
  455. }
  456. if(((addr %8) == 0) && (len >= 8)){
  457. while(spiflash_bus_busy());
  458. spiflash_block_erase_32KB(addr*0x1000);
  459. addr += 8;
  460. len -= 8;
  461. continue;
  462. }
  463. if(len >= 1){
  464. while(spiflash_bus_busy());
  465. spiflash_sector_erase(addr*0x1000);
  466. addr += 1;
  467. len -= 1;
  468. continue;
  469. }
  470. }
  471. }
  472. spiflash_write_status_register(lockinfo);
  473. while(spiflash_bus_busy());
  474. return SUCCESS;
  475. }
  476. int vendorflash_write(uint32_t addr,const uint8_t *data,uint16_t len)
  477. {
  478. if((addr < spiflash_space) && (data != NULL) && (len > 0)){
  479. spiflash_write_eeprom(addr,(uint8_t *)data,len);
  480. return SUCCESS;
  481. }
  482. return ERR_SPI_FLASH;
  483. }