memspi_host_driver.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*
  2. * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "soc/soc_caps.h"
  7. #include "spi_flash_defs.h"
  8. #include "memspi_host_driver.h"
  9. #include "string.h"
  10. #include "esp_log.h"
  11. #include "esp_private/cache_utils.h"
  12. #include "esp_flash_partitions.h"
  13. #include "esp_memory_utils.h"
  14. #define SPI_FLASH_HAL_MAX_WRITE_BYTES 64
  15. #define SPI_FLASH_HAL_MAX_READ_BYTES 64
  16. DRAM_ATTR static const spi_flash_host_driver_t esp_flash_default_host = ESP_FLASH_DEFAULT_HOST_DRIVER();
  17. #if SOC_MEMSPI_IS_INDEPENDENT
  18. extern void spi_flash_hal_gpspi_poll_cmd_done(spi_flash_host_inst_t *host);
  19. extern esp_err_t spi_flash_hal_gpspi_device_config(spi_flash_host_inst_t *host);
  20. esp_err_t spi_flash_hal_gpspi_configure_host_io_mode(
  21. spi_flash_host_inst_t *host,
  22. uint32_t command,
  23. uint32_t addr_bitlen,
  24. int dummy_cyclelen_base,
  25. esp_flash_io_mode_t io_mode);
  26. extern esp_err_t spi_flash_hal_gpspi_common_command(spi_flash_host_inst_t *host, spi_flash_trans_t *trans);
  27. extern esp_err_t spi_flash_hal_gpspi_read(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len);
  28. extern uint32_t spi_flash_hal_gpspi_check_status(spi_flash_host_inst_t *host);
  29. extern bool spi_flash_hal_gpspi_supports_direct_write(spi_flash_host_inst_t *host, const void *p);
  30. extern bool spi_flash_hal_gpspi_supports_direct_read(spi_flash_host_inst_t *host, const void *p);
  31. /** Default configuration for GPSPI */
  32. static const spi_flash_host_driver_t esp_flash_gpspi_host = {
  33. .dev_config = spi_flash_hal_gpspi_device_config,
  34. .common_command = spi_flash_hal_gpspi_common_command,
  35. .read_id = memspi_host_read_id_hs,
  36. .erase_chip = memspi_host_erase_chip,
  37. .erase_sector = memspi_host_erase_sector,
  38. .erase_block = memspi_host_erase_block,
  39. .read_status = memspi_host_read_status_hs,
  40. .set_write_protect = memspi_host_set_write_protect,
  41. .supports_direct_write = spi_flash_hal_gpspi_supports_direct_write,
  42. .supports_direct_read = spi_flash_hal_gpspi_supports_direct_read,
  43. .program_page = memspi_host_program_page,
  44. .write_data_slicer = memspi_host_write_data_slicer,
  45. .read = spi_flash_hal_gpspi_read,
  46. .read_data_slicer = memspi_host_read_data_slicer,
  47. .host_status = spi_flash_hal_gpspi_check_status,
  48. .configure_host_io_mode = spi_flash_hal_gpspi_configure_host_io_mode,
  49. .poll_cmd_done = spi_flash_hal_gpspi_poll_cmd_done,
  50. .flush_cache = NULL,
  51. .check_suspend = NULL,
  52. .resume = spi_flash_hal_resume,
  53. .suspend = spi_flash_hal_suspend,
  54. };
  55. #endif
  56. esp_err_t memspi_host_init_pointers(memspi_host_inst_t *host, const memspi_host_config_t *cfg)
  57. {
  58. if (!esp_ptr_internal(host) && cfg->host_id == SPI1_HOST) {
  59. return ESP_ERR_INVALID_ARG;
  60. }
  61. #if SOC_MEMSPI_IS_INDEPENDENT
  62. if (cfg->host_id == SPI1_HOST)
  63. host->inst.driver = &esp_flash_default_host;
  64. else {
  65. host->inst.driver = &esp_flash_gpspi_host;
  66. }
  67. #else
  68. host->inst.driver = &esp_flash_default_host;
  69. #endif
  70. esp_err_t err = spi_flash_hal_init(host, cfg);
  71. return err;
  72. }
  73. #ifndef CONFIG_SPI_FLASH_ROM_IMPL
  74. static const char TAG[] = "memspi";
  75. esp_err_t memspi_host_read_id_hs(spi_flash_host_inst_t *host, uint32_t *id)
  76. {
  77. uint32_t id_buf = 0;
  78. spi_flash_trans_t t = {
  79. .command = CMD_RDID,
  80. .miso_len = 3,
  81. .miso_data = ((uint8_t*) &id_buf),
  82. };
  83. host->driver->common_command(host, &t);
  84. uint32_t raw_flash_id = id_buf;
  85. ESP_EARLY_LOGV(TAG, "raw_chip_id: %X\n", raw_flash_id);
  86. if (raw_flash_id == 0xFFFFFF || raw_flash_id == 0) {
  87. ESP_EARLY_LOGE(TAG, "no response\n");
  88. return ESP_ERR_FLASH_NO_RESPONSE;
  89. }
  90. // Byte swap the flash id as it's usually written the other way around
  91. uint8_t mfg_id = raw_flash_id & 0xFF;
  92. uint16_t flash_id = (raw_flash_id >> 16) | (raw_flash_id & 0xFF00);
  93. *id = ((uint32_t)mfg_id << 16) | flash_id;
  94. ESP_EARLY_LOGV(TAG, "chip_id: %X\n", *id);
  95. return ESP_OK;
  96. }
  97. esp_err_t memspi_host_read_status_hs(spi_flash_host_inst_t *host, uint8_t *out_sr)
  98. {
  99. //NOTE: we do have a read id function, however it doesn't work in high freq
  100. uint32_t stat_buf = 0;
  101. spi_flash_trans_t t = {
  102. .command = CMD_RDSR,
  103. .miso_data = ((uint8_t*) &stat_buf),
  104. .miso_len = 1
  105. };
  106. esp_err_t err = host->driver->common_command(host, &t);
  107. if (err != ESP_OK) {
  108. return err;
  109. }
  110. *out_sr = stat_buf;
  111. return ESP_OK;
  112. }
  113. esp_err_t memspi_host_flush_cache(spi_flash_host_inst_t *host, uint32_t addr, uint32_t size)
  114. {
  115. if ((void*)((memspi_host_inst_t*)host)->spi == (void*) spi_flash_ll_get_hw(SPI1_HOST)) {
  116. spi_flash_check_and_flush_cache(addr, size);
  117. }
  118. return ESP_OK;
  119. }
  120. void memspi_host_erase_chip(spi_flash_host_inst_t *host)
  121. {
  122. spi_flash_trans_t t = { 0 };
  123. t.command = CMD_CHIP_ERASE;
  124. host->driver->common_command(host, &t);
  125. }
  126. // Only support 24bit address
  127. void memspi_host_erase_sector(spi_flash_host_inst_t *host, uint32_t start_address)
  128. {
  129. assert(start_address < 0x1000000);
  130. spi_flash_trans_t t = {
  131. .command = CMD_SECTOR_ERASE,
  132. .address_bitlen = 24,
  133. .address = start_address
  134. };
  135. host->driver->common_command(host, &t);
  136. }
  137. // Only support 24bit address
  138. void memspi_host_erase_block(spi_flash_host_inst_t *host, uint32_t start_address)
  139. {
  140. assert(start_address < 0x1000000);
  141. spi_flash_trans_t t = {
  142. .command = CMD_LARGE_BLOCK_ERASE,
  143. .address_bitlen = 24,
  144. .address = start_address,
  145. };
  146. host->driver->common_command(host, &t);
  147. }
  148. // Only support 24bit address
  149. void memspi_host_program_page(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length)
  150. {
  151. assert(address + length <= 0x1000000);
  152. spi_flash_trans_t t = {
  153. .command = CMD_PROGRAM_PAGE,
  154. .address_bitlen = 24,
  155. .address = address,
  156. .mosi_len = length,
  157. .mosi_data = buffer
  158. };
  159. host->driver->common_command(host, &t);
  160. }
  161. esp_err_t memspi_host_read(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len)
  162. {
  163. spi_flash_trans_t t = {
  164. .command = CMD_READ,
  165. .address_bitlen = 24,
  166. .address = address,
  167. .miso_len = read_len,
  168. .miso_data = buffer
  169. };
  170. host->driver->common_command(host, &t);
  171. return ESP_OK;
  172. }
  173. esp_err_t memspi_host_set_write_protect(spi_flash_host_inst_t *host, bool wp)
  174. {
  175. spi_flash_trans_t t = {
  176. .command = wp ? CMD_WRDI : CMD_WREN
  177. };
  178. host->driver->common_command(host, &t);
  179. return ESP_OK;
  180. }
  181. // When encryption is enabled, etc. the data slicer may be complicated
  182. // This is the simple case where the hardware has no other requirements than the size and page boundary
  183. int memspi_host_write_data_slicer(spi_flash_host_inst_t *host, uint32_t address, uint32_t len, uint32_t *align_address, uint32_t page_size)
  184. {
  185. uint32_t slicer_flag = ((spi_flash_hal_context_t*)host)->slicer_flags;
  186. uint32_t align_addr = address;
  187. if (slicer_flag & SPI_FLASH_HOST_CONTEXT_SLICER_FLAG_DTR) {
  188. if (((align_addr % 2) != 0) && ((len % 2) != 0)) {
  189. align_addr -= 1;
  190. len += 1;
  191. } else if (((align_addr % 2) != 0) && ((len % 2) == 0)) {
  192. align_addr -= 1;
  193. len += 2;
  194. } else if (((align_addr % 2) == 0) && ((len % 2) != 0)) {
  195. len += 1;
  196. }
  197. }
  198. uint32_t end_bound = (align_addr/page_size + 1) * page_size;
  199. // Shouldn't program cross the page, or longer than SPI_FLASH_HAL_MAX_WRITE_BYTES
  200. uint32_t max_len = MIN(end_bound - align_addr, SPI_FLASH_HAL_MAX_WRITE_BYTES);
  201. *align_address = align_addr;
  202. return MIN(max_len, len);
  203. }
  204. int memspi_host_read_data_slicer(spi_flash_host_inst_t *host, uint32_t address, uint32_t len, uint32_t *align_address, uint32_t page_size)
  205. {
  206. // Shouldn't read longer than SPI_FLASH_HAL_MAX_READ_BYTES
  207. uint32_t slicer_flag = ((spi_flash_hal_context_t*)host)->slicer_flags;
  208. uint32_t align_addr = address;
  209. if (slicer_flag & SPI_FLASH_HOST_CONTEXT_SLICER_FLAG_DTR) {
  210. if (((align_addr % 2) != 0) && ((len % 2) != 0)) {
  211. align_addr -= 1;
  212. len += 1;
  213. } else if (((align_addr % 2) != 0) && ((len % 2) == 0)) {
  214. align_addr -= 1;
  215. len += 2;
  216. } else if (((align_addr % 2) == 0) && ((len % 2) != 0)) {
  217. len += 1;
  218. }
  219. }
  220. uint32_t max_len = SPI_FLASH_HAL_MAX_READ_BYTES;
  221. *align_address = align_addr;
  222. return MIN(max_len, len);
  223. }
  224. #endif // CONFIG_SPI_FLASH_ROM_IMPL