spi_flash_os_func_app.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include <stdarg.h>
  15. #include "esp_attr.h"
  16. #include "esp_spi_flash.h" //for ``g_flash_guard_default_ops``
  17. #include "esp_flash.h"
  18. #include "esp_flash_partitions.h"
  19. #include "freertos/FreeRTOS.h"
  20. #include "freertos/task.h"
  21. #include "hal/spi_types.h"
  22. #include "sdkconfig.h"
  23. #if CONFIG_IDF_TARGET_ESP32
  24. #include "esp32/rom/ets_sys.h"
  25. #elif CONFIG_IDF_TARGET_ESP32S2
  26. #include "esp32s2/rom/ets_sys.h"
  27. #endif
  28. #include "driver/spi_common_internal.h"
  29. /*
  30. * OS functions providing delay service and arbitration among chips, and with the cache.
  31. *
  32. * The cache needs to be disabled when chips on the SPI1 bus is under operation, hence these functions need to be put
  33. * into the IRAM,and their data should be put into the DRAM.
  34. */
  35. typedef struct {
  36. spi_bus_lock_dev_handle_t dev_lock;
  37. } app_func_arg_t;
  38. typedef struct {
  39. app_func_arg_t common_arg; //shared args, must be the first item
  40. bool no_protect; //to decide whether to check protected region (for the main chip) or not.
  41. } spi1_app_func_arg_t;
  42. IRAM_ATTR static void cache_enable(void* arg)
  43. {
  44. g_flash_guard_default_ops.end();
  45. }
  46. IRAM_ATTR static void cache_disable(void* arg)
  47. {
  48. g_flash_guard_default_ops.start();
  49. }
  50. static IRAM_ATTR esp_err_t spi_start(void *arg)
  51. {
  52. spi_bus_lock_dev_handle_t dev_lock = ((app_func_arg_t *)arg)->dev_lock;
  53. // wait for other devices (or cache) to finish their operation
  54. esp_err_t ret = spi_bus_lock_acquire_start(dev_lock, portMAX_DELAY);
  55. if (ret != ESP_OK) {
  56. return ret;
  57. }
  58. spi_bus_lock_touch(dev_lock);
  59. return ESP_OK;
  60. }
  61. static IRAM_ATTR esp_err_t spi_end(void *arg)
  62. {
  63. return spi_bus_lock_acquire_end(((app_func_arg_t *)arg)->dev_lock);
  64. }
  65. static IRAM_ATTR esp_err_t spi1_start(void *arg)
  66. {
  67. #if CONFIG_SPI_FLASH_SHARE_SPI1_BUS
  68. //use the lock to disable the cache and interrupts before using the SPI bus
  69. return spi_start(arg);
  70. #else
  71. //directly disable the cache and interrupts when lock is not used
  72. cache_disable(NULL);
  73. #endif
  74. return ESP_OK;
  75. }
  76. static IRAM_ATTR esp_err_t spi1_end(void *arg)
  77. {
  78. #if CONFIG_SPI_FLASH_SHARE_SPI1_BUS
  79. return spi_end(arg);
  80. #else
  81. cache_enable(NULL);
  82. return ESP_OK;
  83. #endif
  84. }
  85. static IRAM_ATTR esp_err_t delay_us(void *arg, unsigned us)
  86. {
  87. ets_delay_us(us);
  88. return ESP_OK;
  89. }
  90. static IRAM_ATTR esp_err_t spi_flash_os_yield(void *arg)
  91. {
  92. #ifdef CONFIG_SPI_FLASH_YIELD_DURING_ERASE
  93. vTaskDelay(CONFIG_SPI_FLASH_ERASE_YIELD_TICKS);
  94. #endif
  95. return ESP_OK;
  96. }
  97. static IRAM_ATTR esp_err_t main_flash_region_protected(void* arg, size_t start_addr, size_t size)
  98. {
  99. if (((spi1_app_func_arg_t*)arg)->no_protect || esp_partition_main_flash_region_safe(start_addr, size)) {
  100. //ESP_OK = 0, also means protected==0
  101. return ESP_OK;
  102. } else {
  103. return ESP_ERR_NOT_SUPPORTED;
  104. }
  105. }
  106. static DRAM_ATTR spi1_app_func_arg_t main_flash_arg = {};
  107. //for SPI1, we have to disable the cache and interrupts before using the SPI bus
  108. static const DRAM_ATTR esp_flash_os_functions_t esp_flash_spi1_default_os_functions = {
  109. .start = spi1_start,
  110. .end = spi1_end,
  111. .region_protected = main_flash_region_protected,
  112. .delay_us = delay_us,
  113. .yield = spi_flash_os_yield,
  114. };
  115. static const esp_flash_os_functions_t esp_flash_spi23_default_os_functions = {
  116. .start = spi_start,
  117. .end = spi_end,
  118. .delay_us = delay_us,
  119. .yield = spi_flash_os_yield
  120. };
  121. static spi_bus_lock_dev_handle_t register_dev(int host_id)
  122. {
  123. spi_bus_lock_handle_t lock = spi_bus_lock_get_by_id(host_id);
  124. spi_bus_lock_dev_handle_t dev_handle;
  125. spi_bus_lock_dev_config_t config = {.flags = SPI_BUS_LOCK_DEV_FLAG_CS_REQUIRED};
  126. esp_err_t err = spi_bus_lock_register_dev(lock, &config, &dev_handle);
  127. if (err != ESP_OK) {
  128. return NULL;
  129. }
  130. return dev_handle;
  131. }
  132. esp_err_t esp_flash_init_os_functions(esp_flash_t *chip, int host_id, int* out_dev_id)
  133. {
  134. spi_bus_lock_dev_handle_t dev_handle = NULL;
  135. // Skip initializing the bus lock when the bus is SPI1 and the bus is not shared with SPI Master
  136. // driver, leaving dev_handle = NULL
  137. bool skip_register_dev = (host_id == SPI_HOST);
  138. #if CONFIG_SPI_FLASH_SHARE_SPI1_BUS
  139. skip_register_dev = false;
  140. #endif
  141. if (!skip_register_dev) {
  142. dev_handle = register_dev(host_id);
  143. }
  144. if (host_id == SPI1_HOST) {
  145. //SPI1
  146. chip->os_func = &esp_flash_spi1_default_os_functions;
  147. chip->os_func_data = heap_caps_malloc(sizeof(spi1_app_func_arg_t),
  148. MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
  149. if (chip->os_func_data == NULL) {
  150. return ESP_ERR_NO_MEM;
  151. }
  152. *(spi1_app_func_arg_t*) chip->os_func_data = (spi1_app_func_arg_t) {
  153. .common_arg = {
  154. .dev_lock = dev_handle,
  155. },
  156. .no_protect = true,
  157. };
  158. } else if (host_id == SPI2_HOST || host_id == SPI3_HOST) {
  159. //SPI2, SPI3
  160. chip->os_func = &esp_flash_spi23_default_os_functions;
  161. chip->os_func_data = heap_caps_malloc(sizeof(app_func_arg_t),
  162. MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
  163. if (chip->os_func_data == NULL) {
  164. return ESP_ERR_NO_MEM;
  165. }
  166. *(app_func_arg_t*) chip->os_func_data = (app_func_arg_t) {
  167. .dev_lock = dev_handle,
  168. };
  169. } else {
  170. return ESP_ERR_INVALID_ARG;
  171. }
  172. // Bus lock not initialized, the device ID should be directly given by application.
  173. if (dev_handle) {
  174. *out_dev_id = spi_bus_lock_get_dev_id(dev_handle);
  175. }
  176. return ESP_OK;
  177. }
  178. esp_err_t esp_flash_deinit_os_functions(esp_flash_t* chip)
  179. {
  180. if (chip->os_func_data) {
  181. spi_bus_lock_dev_handle_t dev_lock = ((app_func_arg_t*)chip->os_func_data)->dev_lock;
  182. // SPI bus lock is possible not used on SPI1 bus
  183. if (dev_lock) {
  184. spi_bus_lock_unregister_dev(dev_lock);
  185. }
  186. free(chip->os_func_data);
  187. }
  188. chip->os_func = NULL;
  189. chip->os_func_data = NULL;
  190. return ESP_OK;
  191. }
  192. esp_err_t esp_flash_init_main_bus_lock(void)
  193. {
  194. spi_bus_lock_init_main_bus();
  195. spi_bus_lock_set_bg_control(g_main_spi_bus_lock, cache_enable, cache_disable, NULL);
  196. esp_err_t err = spi_bus_lock_init_main_dev();
  197. if (err != ESP_OK) {
  198. return err;
  199. }
  200. return ESP_OK;
  201. }
  202. esp_err_t esp_flash_app_enable_os_functions(esp_flash_t* chip)
  203. {
  204. main_flash_arg = (spi1_app_func_arg_t) {
  205. .common_arg = {
  206. .dev_lock = g_spi_lock_main_flash_dev, //for SPI1,
  207. },
  208. .no_protect = false,
  209. };
  210. chip->os_func = &esp_flash_spi1_default_os_functions;
  211. chip->os_func_data = &main_flash_arg;
  212. return ESP_OK;
  213. }