drv_qspi_flash.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-08-07 NU-LL first version
  9. */
  10. #include <rtthread.h>
  11. #include <board.h>
  12. #include <drv_qspi.h>
  13. #include <rtdevice.h>
  14. #include <rthw.h>
  15. #include <finsh.h>
  16. #ifdef BSP_USING_QSPI_FLASH
  17. #include <fal.h>
  18. #include <sfud.h>
  19. #include "dfs_fs.h"
  20. #include "drv_spi.h"
  21. #include "spi_flash.h"
  22. #include "spi_flash_sfud.h"
  23. //#define DRV_DEBUG
  24. #define LOG_TAG "drv.qspiflash"
  25. #include <drv_log.h>
  26. #define FS_PARTITION_NAME "fs_qspi"
  27. #define FAL_USING_NOR_FLASH_2_DEV_NAME "W25Q64_q"
  28. static sfud_flash_t sfud_dev = NULL;
  29. static int init(void);
  30. static int read(long offset, uint8_t *buf, size_t size);
  31. static int write(long offset, const uint8_t *buf, size_t size);
  32. static int erase(long offset, size_t size);
  33. struct fal_flash_dev nor_flash1 =
  34. {
  35. .name = FAL_USING_NOR_FLASH_2_DEV_NAME,
  36. .addr = 0,
  37. .len = 8 * 1024 * 1024,
  38. .blk_size = 4096,
  39. .ops = {init, read, write, erase},
  40. .write_gran = 4
  41. };
  42. static int init(void)
  43. {
  44. #ifdef RT_USING_SFUD
  45. /* RT-Thread RTOS platform */
  46. sfud_dev = rt_sfud_flash_find_by_dev_name(FAL_USING_NOR_FLASH_2_DEV_NAME);
  47. #else
  48. /* bare metal platform */
  49. extern sfud_flash nor_flash1;
  50. sfud_dev = &nor_flash1;
  51. #endif
  52. if (NULL == sfud_dev)
  53. {
  54. return -1;
  55. }
  56. /* update the flash chip information */
  57. nor_flash1.blk_size = sfud_dev->chip.erase_gran;
  58. nor_flash1.len = sfud_dev->chip.capacity;
  59. return 0;
  60. }
  61. static int read(long offset, uint8_t *buf, size_t size)
  62. {
  63. assert(sfud_dev);
  64. assert(sfud_dev->init_ok);
  65. sfud_read(sfud_dev, nor_flash1.addr + offset, size, buf);
  66. return size;
  67. }
  68. static int write(long offset, const uint8_t *buf, size_t size)
  69. {
  70. assert(sfud_dev);
  71. assert(sfud_dev->init_ok);
  72. if (sfud_write(sfud_dev, nor_flash1.addr + offset, size, buf) != SFUD_SUCCESS)
  73. {
  74. return -1;
  75. }
  76. return size;
  77. }
  78. static int erase(long offset, size_t size)
  79. {
  80. assert(sfud_dev);
  81. assert(sfud_dev->init_ok);
  82. if (sfud_erase(sfud_dev, nor_flash1.addr + offset, size) != SFUD_SUCCESS)
  83. {
  84. return -1;
  85. }
  86. return size;
  87. }
  88. char w25qxx_read_status_register2(struct rt_qspi_device *device)
  89. {
  90. /* 0x35 read status register2 */
  91. char instruction = 0x35, status;
  92. rt_qspi_send_then_recv(device, &instruction, 1, &status, 1);
  93. return status;
  94. }
  95. void w25qxx_write_enable(struct rt_qspi_device *device)
  96. {
  97. /* 0x06 write enable */
  98. char instruction = 0x06;
  99. rt_qspi_send(device, &instruction, 1);
  100. }
  101. void w25qxx_enter_qspi_mode(struct rt_qspi_device *device)
  102. {
  103. char status = 0;
  104. /* 0x38 enter qspi mode */
  105. char instruction = 0x38;
  106. char write_status2_buf[2] = {0};
  107. /* 0x31 write status register2 */
  108. write_status2_buf[0] = 0x31;
  109. status = w25qxx_read_status_register2(device);
  110. if (!(status & 0x02))
  111. {
  112. status |= 1 << 1;
  113. w25qxx_write_enable(device);
  114. write_status2_buf[1] = status;
  115. rt_qspi_send(device, &write_status2_buf, 2);
  116. rt_qspi_send(device, &instruction, 1);
  117. rt_kprintf("flash already enter qspi mode\n");
  118. rt_thread_mdelay(10);
  119. }
  120. }
  121. static int rt_qspi_flash_init(void)
  122. {
  123. extern rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const char *spi_dev_name);
  124. rt_hw_qspi_device_attach("qspi1", "qspi10", RT_NULL, 4, w25qxx_enter_qspi_mode, RT_NULL);
  125. if (RT_NULL == rt_sfud_flash_probe(FAL_USING_NOR_FLASH_2_DEV_NAME, "qspi10"))
  126. {
  127. LOG_E("Failed to probe flash device "FAL_USING_NOR_FLASH_2_DEV_NAME);
  128. return -RT_ERROR;
  129. }
  130. return RT_EOK;
  131. }
  132. INIT_DEVICE_EXPORT(rt_qspi_flash_init);
  133. #endif/* BSP_USING_QSPI_FLASH */