wifi_marauder_flasher.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #include "wifi_marauder_flasher.h"
  2. FuriStreamBuffer* flash_rx_stream; // TODO make safe
  3. WifiMarauderApp* global_app; // TODO make safe
  4. FuriTimer* timer; // TODO make
  5. static uint32_t _remaining_time = 0;
  6. static void _timer_callback(void* context) {
  7. UNUSED(context);
  8. if(_remaining_time > 0) {
  9. _remaining_time--;
  10. }
  11. }
  12. static esp_loader_error_t _flash_file(WifiMarauderApp* app, char* filepath, uint32_t addr) {
  13. // TODO cleanup
  14. esp_loader_error_t err;
  15. static uint8_t payload[1024];
  16. File* bin_file = storage_file_alloc(app->storage);
  17. // open file
  18. if(!storage_file_open(bin_file, filepath, FSAM_READ, FSOM_OPEN_EXISTING)) {
  19. storage_file_close(bin_file);
  20. storage_file_free(bin_file);
  21. dialog_message_show_storage_error(app->dialogs, "Cannot open file");
  22. return ESP_LOADER_ERROR_FAIL;
  23. }
  24. uint64_t size = storage_file_size(bin_file);
  25. /*
  26. // TODO packet drops with higher BR?
  27. err = esp_loader_change_transmission_rate(230400);
  28. if (err != ESP_LOADER_SUCCESS) {
  29. char err_msg[256];
  30. snprintf(
  31. err_msg,
  32. sizeof(err_msg),
  33. "Cannot change transmission rate. Error: %u\n",
  34. err);
  35. storage_file_close(bin_file);
  36. storage_file_free(bin_file);
  37. loader_port_debug_print(err_msg);
  38. return;
  39. }
  40. furi_hal_uart_set_br(FuriHalUartIdUSART1, 230400);
  41. // TODO remember to change BR back!
  42. */
  43. loader_port_debug_print("Erasing flash...this may take a while\n");
  44. err = esp_loader_flash_start(addr, size, sizeof(payload));
  45. if(err != ESP_LOADER_SUCCESS) {
  46. storage_file_close(bin_file);
  47. storage_file_free(bin_file);
  48. char err_msg[256];
  49. snprintf(err_msg, sizeof(err_msg), "Erasing flash failed with error %d\n", err);
  50. loader_port_debug_print(err_msg);
  51. return err;
  52. }
  53. loader_port_debug_print("Start programming\n");
  54. while(size > 0) {
  55. size_t to_read = MIN(size, sizeof(payload));
  56. uint16_t num_bytes = storage_file_read(bin_file, payload, to_read);
  57. err = esp_loader_flash_write(payload, num_bytes);
  58. if(err != ESP_LOADER_SUCCESS) {
  59. char err_msg[256];
  60. snprintf(err_msg, sizeof(err_msg), "Packet could not be written! Error: %u\n", err);
  61. storage_file_close(bin_file);
  62. storage_file_free(bin_file);
  63. loader_port_debug_print(err_msg);
  64. return err;
  65. }
  66. size -= num_bytes;
  67. }
  68. loader_port_debug_print("Finished programming\n");
  69. // TODO verify
  70. storage_file_close(bin_file);
  71. storage_file_free(bin_file);
  72. return ESP_LOADER_SUCCESS;
  73. }
  74. static int32_t wifi_marauder_flash_bin(void* context) {
  75. WifiMarauderApp* app = (void*)context;
  76. esp_loader_error_t err;
  77. // alloc global objects
  78. flash_rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1);
  79. timer = furi_timer_alloc(_timer_callback, FuriTimerTypePeriodic, app);
  80. loader_port_debug_print("Connecting\n");
  81. esp_loader_connect_args_t connect_config = ESP_LOADER_CONNECT_DEFAULT();
  82. err = esp_loader_connect(&connect_config);
  83. if(err != ESP_LOADER_SUCCESS) {
  84. char err_msg[256];
  85. snprintf(err_msg, sizeof(err_msg), "Cannot connect to target. Error: %u\n", err);
  86. loader_port_debug_print(err_msg);
  87. }
  88. if(!err) {
  89. loader_port_debug_print("Connected\n");
  90. loader_port_debug_print("Flashing bootloader (1/3)\n");
  91. err = _flash_file(app, app->bin_file_path_boot, 0x1000);
  92. }
  93. if(!err) {
  94. loader_port_debug_print("Flashing partition table (2/3)\n");
  95. err = _flash_file(app, app->bin_file_path_part, 0x8000);
  96. }
  97. if(!err) {
  98. loader_port_debug_print("Flashing app (3/3)\n");
  99. err = _flash_file(app, app->bin_file_path_app, 0x10000);
  100. loader_port_debug_print("Done flashing. Please reset the board manually.\n");
  101. }
  102. // done
  103. // cleanup
  104. furi_stream_buffer_free(flash_rx_stream);
  105. flash_rx_stream = NULL;
  106. furi_timer_free(timer);
  107. return 0;
  108. }
  109. void wifi_marauder_flash_start_thread(WifiMarauderApp* app) {
  110. global_app = app;
  111. app->flash_worker = furi_thread_alloc();
  112. furi_thread_set_name(app->flash_worker, "WifiMarauderFlashWorker");
  113. furi_thread_set_stack_size(app->flash_worker, 2048);
  114. furi_thread_set_context(app->flash_worker, app);
  115. furi_thread_set_callback(app->flash_worker, wifi_marauder_flash_bin);
  116. furi_thread_start(app->flash_worker);
  117. }
  118. void wifi_marauder_flash_stop_thread(WifiMarauderApp* app) {
  119. furi_thread_join(app->flash_worker);
  120. furi_thread_free(app->flash_worker);
  121. }
  122. esp_loader_error_t loader_port_read(uint8_t* data, uint16_t size, uint32_t timeout) {
  123. size_t read = furi_stream_buffer_receive(flash_rx_stream, data, size, pdMS_TO_TICKS(timeout));
  124. if(read < size) {
  125. return ESP_LOADER_ERROR_TIMEOUT;
  126. } else {
  127. return ESP_LOADER_SUCCESS;
  128. }
  129. }
  130. esp_loader_error_t loader_port_write(const uint8_t* data, uint16_t size, uint32_t timeout) {
  131. UNUSED(timeout);
  132. wifi_marauder_uart_tx((uint8_t*)data, size);
  133. return ESP_LOADER_SUCCESS;
  134. }
  135. void loader_port_enter_bootloader(void) {
  136. // unimplemented
  137. }
  138. void loader_port_delay_ms(uint32_t ms) {
  139. furi_delay_ms(ms);
  140. }
  141. void loader_port_start_timer(uint32_t ms) {
  142. _remaining_time = ms;
  143. furi_timer_start(timer, pdMS_TO_TICKS(1));
  144. }
  145. uint32_t loader_port_remaining_time(void) {
  146. return _remaining_time;
  147. }
  148. extern void wifi_marauder_console_output_handle_rx_data_cb(
  149. uint8_t* buf,
  150. size_t len,
  151. void* context); // TODO cleanup
  152. void loader_port_debug_print(const char* str) {
  153. if(global_app)
  154. wifi_marauder_console_output_handle_rx_data_cb((uint8_t*)str, strlen(str), global_app);
  155. }
  156. void loader_port_spi_set_cs(uint32_t level) {
  157. UNUSED(level);
  158. // unimplemented
  159. }
  160. void wifi_marauder_flash_handle_rx_data_cb(uint8_t* buf, size_t len, void* context) {
  161. UNUSED(context);
  162. if(flash_rx_stream) {
  163. furi_stream_buffer_send(flash_rx_stream, buf, len, 0);
  164. } else {
  165. // done flashing
  166. if(global_app) wifi_marauder_console_output_handle_rx_data_cb(buf, len, global_app);
  167. }
  168. }