spi_flash_emulation.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Copyright 2015-2016 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. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. #include "esp_spi_flash.h"
  14. #include "esp_flash.h"
  15. #include "spi_flash_emulation.h"
  16. static SpiFlashEmulator* s_emulator = nullptr;
  17. static esp_flash_t esp_flash_default_chip_instance;
  18. esp_flash_t *esp_flash_default_chip = &esp_flash_default_chip_instance;
  19. void spi_flash_emulator_set(SpiFlashEmulator* e)
  20. {
  21. s_emulator = e;
  22. }
  23. esp_err_t spi_flash_erase_sector(size_t sec)
  24. {
  25. if (!s_emulator) {
  26. return ESP_ERR_FLASH_OP_TIMEOUT;
  27. }
  28. if (!s_emulator->erase(sec)) {
  29. return ESP_ERR_FLASH_OP_FAIL;
  30. }
  31. return ESP_OK;
  32. }
  33. esp_err_t spi_flash_write(size_t des_addr, const void *src_addr, size_t size)
  34. {
  35. if (!s_emulator) {
  36. return ESP_ERR_FLASH_OP_TIMEOUT;
  37. }
  38. if (!s_emulator->write(des_addr, reinterpret_cast<const uint32_t*>(src_addr), size)) {
  39. return ESP_ERR_FLASH_OP_FAIL;
  40. }
  41. return ESP_OK;
  42. }
  43. esp_err_t spi_flash_read(size_t src_addr, void *des_addr, size_t size)
  44. {
  45. if (!s_emulator) {
  46. return ESP_ERR_FLASH_OP_TIMEOUT;
  47. }
  48. if (!s_emulator->read(reinterpret_cast<uint32_t*>(des_addr), src_addr, size)) {
  49. return ESP_ERR_FLASH_OP_FAIL;
  50. }
  51. return ESP_OK;
  52. }
  53. // timing data for ESP8266, 160MHz CPU frequency, 80MHz flash requency
  54. // all values in microseconds
  55. // values are for block sizes starting at 4 bytes and going up to 4096 bytes
  56. static size_t readTimes[] = {7, 5, 6, 7, 11, 18, 32, 60, 118, 231, 459};
  57. static size_t writeTimes[] = {19, 23, 35, 57, 106, 205, 417, 814, 1622, 3200, 6367};
  58. static size_t blockEraseTime = 37142;
  59. static size_t timeInterp(uint32_t bytes, size_t* lut)
  60. {
  61. const int lut_size = sizeof(readTimes)/sizeof(readTimes[0]);
  62. int lz = __builtin_clz(bytes / 4);
  63. int log_size = 32 - lz;
  64. size_t x2 = 1 << (log_size + 2);
  65. size_t y2 = lut[std::min(log_size, lut_size - 1)];
  66. size_t x1 = 1 << (log_size + 1);
  67. size_t y1 = lut[log_size - 1];
  68. return (bytes - x1) * (y2 - y1) / (x2 - x1) + y1;
  69. }
  70. size_t SpiFlashEmulator::getReadOpTime(uint32_t bytes)
  71. {
  72. return timeInterp(bytes, readTimes);
  73. }
  74. size_t SpiFlashEmulator::getWriteOpTime(uint32_t bytes)
  75. {
  76. return timeInterp(bytes, writeTimes);
  77. }
  78. size_t SpiFlashEmulator::getEraseOpTime()
  79. {
  80. return blockEraseTime;
  81. }