esp_loader.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /* Copyright 2020 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. */
  15. #include "serial_comm.h"
  16. #include "serial_io.h"
  17. #include "esp_loader.h"
  18. #ifndef MAX
  19. #define MAX(a, b) ((a) > (b)) ? (a) : (b)
  20. #endif
  21. static const uint32_t DEFAULT_TIMEOUT = 500;
  22. static const uint32_t SPI_PIN_CONFIG_DEFAULT = 0;
  23. static const uint32_t DEFAULT_FLASH_TIMEOUT = 3000; // timeout for most flash operations
  24. static const uint32_t ERASE_REGION_TIMEOUT_PER_MB = 3000; // timeout (per megabyte) for erasing a region
  25. static const uint8_t PADDING_PATTERN = 0xFF;
  26. static uint32_t s_flash_write_size = 0;
  27. static uint32_t timeout_per_mb(uint32_t size_bytes)
  28. {
  29. uint32_t timeout = ERASE_REGION_TIMEOUT_PER_MB * (size_bytes / 1e6);
  30. return MAX(timeout, DEFAULT_FLASH_TIMEOUT);
  31. }
  32. esp_loader_error_t esp_loader_connect(esp_loader_connect_args_t *connect_args)
  33. {
  34. int32_t trials = connect_args->trials;
  35. loader_port_enter_bootloader();
  36. do {
  37. loader_port_start_timer(connect_args->sync_timeout);
  38. esp_loader_error_t err = loader_sync_cmd();
  39. if (err != ESP_LOADER_ERROR_TIMEOUT) {
  40. return err;
  41. }
  42. if (--trials > 0) {
  43. loader_port_delay_ms(100);
  44. }
  45. } while (trials > 0);
  46. return ESP_LOADER_ERROR_TIMEOUT;
  47. }
  48. esp_loader_error_t esp_loader_flash_start(uint32_t offset, uint32_t image_size, uint32_t block_size)
  49. {
  50. uint32_t blocks_to_write = (image_size + block_size - 1) / block_size;
  51. uint32_t erase_size = block_size * blocks_to_write;
  52. s_flash_write_size = block_size;
  53. loader_port_start_timer(DEFAULT_TIMEOUT);
  54. RETURN_ON_ERROR( loader_spi_attach_cmd(SPI_PIN_CONFIG_DEFAULT) );
  55. loader_port_start_timer(timeout_per_mb(erase_size));
  56. return loader_flash_begin_cmd(offset, erase_size, block_size, blocks_to_write);
  57. }
  58. esp_loader_error_t esp_loader_flash_write(void *payload, uint32_t size)
  59. {
  60. uint32_t padding_bytes = s_flash_write_size - size;
  61. uint8_t *data = (uint8_t *)payload;
  62. while (padding_bytes--) {
  63. data[size++] = PADDING_PATTERN;
  64. }
  65. loader_port_start_timer(DEFAULT_TIMEOUT);
  66. return loader_flash_data_cmd(data, s_flash_write_size);
  67. }
  68. esp_loader_error_t esp_loader_flash_finish(bool reboot)
  69. {
  70. loader_port_start_timer(DEFAULT_TIMEOUT);
  71. return loader_flash_end_cmd(!reboot);
  72. }
  73. esp_loader_error_t esp_loader_read_register(uint32_t address, uint32_t *reg_value)
  74. {
  75. loader_port_start_timer(DEFAULT_TIMEOUT);
  76. return loader_read_reg_cmd(address, reg_value);
  77. }
  78. esp_loader_error_t esp_loader_write_register(uint32_t address, uint32_t reg_value)
  79. {
  80. loader_port_start_timer(DEFAULT_TIMEOUT);
  81. return loader_write_reg_cmd(address, reg_value, 0xFFFFFFFF, 0);
  82. }
  83. void esp_loader_reset_target(void)
  84. {
  85. loader_port_reset_target();
  86. }