serial_comm.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  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_prv.h"
  16. #include "serial_comm.h"
  17. #include "serial_io.h"
  18. #include <stddef.h>
  19. #include <string.h>
  20. #define CMD_SIZE(cmd) ( sizeof(cmd) - sizeof(command_common_t) )
  21. static uint32_t s_sequence_number = 0;
  22. static const uint8_t DELIMITER = 0xC0;
  23. static const uint8_t C0_REPLACEMENT[2] = {0xDB, 0xDC};
  24. static const uint8_t DB_REPLACEMENT[2] = {0xDB, 0xDD};
  25. static esp_loader_error_t check_response(command_t cmd, uint32_t *reg_value, void* resp, uint32_t resp_size);
  26. static inline esp_loader_error_t serial_read(uint8_t *buff, size_t size)
  27. {
  28. return loader_port_serial_read(buff, size, loader_port_remaining_time());
  29. }
  30. static inline esp_loader_error_t serial_write(const uint8_t *buff, size_t size)
  31. {
  32. return loader_port_serial_write(buff, size, loader_port_remaining_time());
  33. }
  34. static uint8_t compute_checksum(const uint8_t *data, uint32_t size)
  35. {
  36. uint8_t checksum = 0xEF;
  37. while (size--) {
  38. checksum ^= *data++;
  39. }
  40. return checksum;
  41. }
  42. static esp_loader_error_t SLIP_receive_data(uint8_t *buff, uint32_t size)
  43. {
  44. uint8_t ch;
  45. for (uint32_t i = 0; i < size; i++) {
  46. RETURN_ON_ERROR( serial_read(&ch, 1) );
  47. if (ch == 0xDB) {
  48. RETURN_ON_ERROR( serial_read(&ch, 1) );
  49. if (ch == 0xDC) {
  50. buff[i] = 0xC0;
  51. } else if (ch == 0xDD) {
  52. buff[i] = 0xDB;
  53. } else {
  54. return ESP_LOADER_ERROR_INVALID_RESPONSE;
  55. }
  56. } else {
  57. buff[i] = ch;
  58. }
  59. }
  60. return ESP_LOADER_SUCCESS;
  61. }
  62. static esp_loader_error_t SLIP_receive_packet(uint8_t *buff, uint32_t size)
  63. {
  64. uint8_t ch;
  65. // Wait for delimiter
  66. do {
  67. RETURN_ON_ERROR( serial_read(&ch, 1) );
  68. } while (ch != DELIMITER);
  69. // Workaround: bootloader sends two dummy(0xC0) bytes after response when baud rate is changed.
  70. do {
  71. RETURN_ON_ERROR( serial_read(&ch, 1) );
  72. } while (ch == DELIMITER);
  73. buff[0] = ch;
  74. RETURN_ON_ERROR( SLIP_receive_data(&buff[1], size - 1) );
  75. // Wait for delimiter
  76. do {
  77. RETURN_ON_ERROR( serial_read(&ch, 1) );
  78. } while (ch != DELIMITER);
  79. return ESP_LOADER_SUCCESS;
  80. }
  81. static esp_loader_error_t SLIP_send(const uint8_t *data, uint32_t size)
  82. {
  83. uint32_t to_write = 0; // Bytes ready to write as they are
  84. uint32_t written = 0; // Bytes already written
  85. for (uint32_t i = 0; i < size; i++) {
  86. if (data[i] != 0xC0 && data[i] != 0xDB) {
  87. to_write++; // Queue this byte for writing
  88. continue;
  89. }
  90. // We have a byte that needs encoding, write the queue first
  91. if (to_write > 0) {
  92. RETURN_ON_ERROR( serial_write(&data[written], to_write) );
  93. }
  94. // Write the encoded byte
  95. if (data[i] == 0xC0) {
  96. RETURN_ON_ERROR( serial_write(C0_REPLACEMENT, 2) );
  97. } else {
  98. RETURN_ON_ERROR( serial_write(DB_REPLACEMENT, 2) );
  99. }
  100. // Update to start again after the encoded byte
  101. written = i + 1;
  102. to_write = 0;
  103. }
  104. // Write the rest of the bytes that didn't need encoding
  105. if (to_write > 0) {
  106. RETURN_ON_ERROR( serial_write(&data[written], to_write) );
  107. }
  108. return ESP_LOADER_SUCCESS;
  109. }
  110. static esp_loader_error_t SLIP_send_delimiter(void)
  111. {
  112. return serial_write(&DELIMITER, 1);
  113. }
  114. static esp_loader_error_t send_cmd(const void *cmd_data, uint32_t size, uint32_t *reg_value)
  115. {
  116. response_t response;
  117. command_t command = ((command_common_t *)cmd_data)->command;
  118. RETURN_ON_ERROR( SLIP_send_delimiter() );
  119. RETURN_ON_ERROR( SLIP_send((const uint8_t *)cmd_data, size) );
  120. RETURN_ON_ERROR( SLIP_send_delimiter() );
  121. return check_response(command, reg_value, &response, sizeof(response));
  122. }
  123. static esp_loader_error_t send_cmd_with_data(const void *cmd_data, size_t cmd_size,
  124. const void *data, size_t data_size)
  125. {
  126. response_t response;
  127. command_t command = ((command_common_t *)cmd_data)->command;
  128. RETURN_ON_ERROR( SLIP_send_delimiter() );
  129. RETURN_ON_ERROR( SLIP_send((const uint8_t *)cmd_data, cmd_size) );
  130. RETURN_ON_ERROR( SLIP_send(data, data_size) );
  131. RETURN_ON_ERROR( SLIP_send_delimiter() );
  132. return check_response(command, NULL, &response, sizeof(response));
  133. }
  134. static esp_loader_error_t send_cmd_md5(const void *cmd_data, size_t cmd_size, uint8_t md5_out[MD5_SIZE])
  135. {
  136. rom_md5_response_t response;
  137. command_t command = ((command_common_t *)cmd_data)->command;
  138. RETURN_ON_ERROR( SLIP_send_delimiter() );
  139. RETURN_ON_ERROR( SLIP_send((const uint8_t *)cmd_data, cmd_size) );
  140. RETURN_ON_ERROR( SLIP_send_delimiter() );
  141. RETURN_ON_ERROR( check_response(command, NULL, &response, sizeof(response)) );
  142. memcpy(md5_out, response.md5, MD5_SIZE);
  143. return ESP_LOADER_SUCCESS;
  144. }
  145. static void log_loader_internal_error(error_code_t error)
  146. {
  147. loader_port_debug_print("Error: ");
  148. switch (error) {
  149. case INVALID_CRC: loader_port_debug_print("INVALID_CRC"); break;
  150. case INVALID_COMMAND: loader_port_debug_print("INVALID_COMMAND"); break;
  151. case COMMAND_FAILED: loader_port_debug_print("COMMAND_FAILED"); break;
  152. case FLASH_WRITE_ERR: loader_port_debug_print("FLASH_WRITE_ERR"); break;
  153. case FLASH_READ_ERR: loader_port_debug_print("FLASH_READ_ERR"); break;
  154. case READ_LENGTH_ERR: loader_port_debug_print("READ_LENGTH_ERR"); break;
  155. case DEFLATE_ERROR: loader_port_debug_print("DEFLATE_ERROR"); break;
  156. default: loader_port_debug_print("UNKNOWN ERROR"); break;
  157. }
  158. loader_port_debug_print("\n");
  159. }
  160. static esp_loader_error_t check_response(command_t cmd, uint32_t *reg_value, void* resp, uint32_t resp_size)
  161. {
  162. esp_loader_error_t err;
  163. common_response_t *response = (common_response_t *)resp;
  164. do {
  165. err = SLIP_receive_packet(resp, resp_size);
  166. if (err != ESP_LOADER_SUCCESS) {
  167. return err;
  168. }
  169. } while ((response->direction != READ_DIRECTION) || (response->command != cmd));
  170. response_status_t *status = (response_status_t *)((uint8_t *)resp + resp_size - sizeof(response_status_t));
  171. if (status->failed) {
  172. log_loader_internal_error(status->error);
  173. return ESP_LOADER_ERROR_INVALID_RESPONSE;
  174. }
  175. if (reg_value != NULL) {
  176. *reg_value = response->value;
  177. }
  178. return ESP_LOADER_SUCCESS;
  179. }
  180. static inline uint32_t encryption_field_size(target_chip_t target)
  181. {
  182. return (target == ESP32S2_CHIP || target == ESP32C3_CHIP) ? 0 : sizeof(uint32_t);
  183. }
  184. esp_loader_error_t loader_flash_begin_cmd(uint32_t offset,
  185. uint32_t erase_size,
  186. uint32_t block_size,
  187. uint32_t blocks_to_write,
  188. target_chip_t target)
  189. {
  190. uint32_t encryption_size = encryption_field_size(target);
  191. begin_command_t begin_cmd = {
  192. .common = {
  193. .direction = WRITE_DIRECTION,
  194. .command = FLASH_BEGIN,
  195. .size = CMD_SIZE(begin_cmd) - encryption_size,
  196. .checksum = 0
  197. },
  198. .erase_size = erase_size,
  199. .packet_count = blocks_to_write,
  200. .packet_size = block_size,
  201. .offset = offset,
  202. .encrypted = 0
  203. };
  204. s_sequence_number = 0;
  205. return send_cmd(&begin_cmd, sizeof(begin_cmd) - encryption_size, NULL);
  206. }
  207. esp_loader_error_t loader_flash_data_cmd(const uint8_t *data, uint32_t size)
  208. {
  209. data_command_t data_cmd = {
  210. .common = {
  211. .direction = WRITE_DIRECTION,
  212. .command = FLASH_DATA,
  213. .size = CMD_SIZE(data_cmd) + size,
  214. .checksum = compute_checksum(data, size)
  215. },
  216. .data_size = size,
  217. .sequence_number = s_sequence_number++,
  218. };
  219. return send_cmd_with_data(&data_cmd, sizeof(data_cmd), data, size);
  220. }
  221. esp_loader_error_t loader_flash_end_cmd(bool stay_in_loader)
  222. {
  223. flash_end_command_t end_cmd = {
  224. .common = {
  225. .direction = WRITE_DIRECTION,
  226. .command = FLASH_END,
  227. .size = CMD_SIZE(end_cmd),
  228. .checksum = 0
  229. },
  230. .stay_in_loader = stay_in_loader
  231. };
  232. return send_cmd(&end_cmd, sizeof(end_cmd), NULL);
  233. }
  234. esp_loader_error_t loader_sync_cmd(void)
  235. {
  236. sync_command_t sync_cmd = {
  237. .common = {
  238. .direction = WRITE_DIRECTION,
  239. .command = SYNC,
  240. .size = CMD_SIZE(sync_cmd),
  241. .checksum = 0
  242. },
  243. .sync_sequence = {
  244. 0x07, 0x07, 0x12, 0x20,
  245. 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  246. 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  247. 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  248. 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  249. }
  250. };
  251. return send_cmd(&sync_cmd, sizeof(sync_cmd), NULL);
  252. }
  253. esp_loader_error_t loader_write_reg_cmd(uint32_t address, uint32_t value,
  254. uint32_t mask, uint32_t delay_us)
  255. {
  256. write_reg_command_t write_cmd = {
  257. .common = {
  258. .direction = WRITE_DIRECTION,
  259. .command = WRITE_REG,
  260. .size = CMD_SIZE(write_cmd),
  261. .checksum = 0
  262. },
  263. .address = address,
  264. .value = value,
  265. .mask = mask,
  266. .delay_us = delay_us
  267. };
  268. return send_cmd(&write_cmd, sizeof(write_cmd), NULL);
  269. }
  270. esp_loader_error_t loader_read_reg_cmd(uint32_t address, uint32_t *reg)
  271. {
  272. read_reg_command_t read_cmd = {
  273. .common = {
  274. .direction = WRITE_DIRECTION,
  275. .command = READ_REG,
  276. .size = CMD_SIZE(read_cmd),
  277. .checksum = 0
  278. },
  279. .address = address,
  280. };
  281. return send_cmd(&read_cmd, sizeof(read_cmd), reg);
  282. }
  283. esp_loader_error_t loader_spi_attach_cmd(uint32_t config)
  284. {
  285. spi_attach_command_t attach_cmd = {
  286. .common = {
  287. .direction = WRITE_DIRECTION,
  288. .command = SPI_ATTACH,
  289. .size = CMD_SIZE(attach_cmd),
  290. .checksum = 0
  291. },
  292. .configuration = config,
  293. .zero = 0
  294. };
  295. return send_cmd(&attach_cmd, sizeof(attach_cmd), NULL);
  296. }
  297. esp_loader_error_t loader_change_baudrate_cmd(uint32_t baudrate)
  298. {
  299. change_baudrate_command_t baudrate_cmd = {
  300. .common = {
  301. .direction = WRITE_DIRECTION,
  302. .command = CHANGE_BAUDRATE,
  303. .size = CMD_SIZE(baudrate_cmd),
  304. .checksum = 0
  305. },
  306. .new_baudrate = baudrate,
  307. .old_baudrate = 0 // ESP32 ROM only
  308. };
  309. return send_cmd(&baudrate_cmd, sizeof(baudrate_cmd), NULL);
  310. }
  311. esp_loader_error_t loader_md5_cmd(uint32_t address, uint32_t size, uint8_t *md5_out)
  312. {
  313. spi_flash_md5_command_t md5_cmd = {
  314. .common = {
  315. .direction = WRITE_DIRECTION,
  316. .command = SPI_FLASH_MD5,
  317. .size = CMD_SIZE(md5_cmd),
  318. .checksum = 0
  319. },
  320. .address = address,
  321. .size = size,
  322. .reserved_0 = 0,
  323. .reserved_1 = 0
  324. };
  325. return send_cmd_md5(&md5_cmd, sizeof(md5_cmd), md5_out);
  326. }
  327. esp_loader_error_t loader_spi_parameters(uint32_t total_size)
  328. {
  329. write_spi_command_t spi_cmd = {
  330. .common = {
  331. .direction = WRITE_DIRECTION,
  332. .command = SPI_SET_PARAMS,
  333. .size = 24,
  334. .checksum = 0
  335. },
  336. .id = 0,
  337. .total_size = total_size,
  338. .block_size = 64 * 1024,
  339. .sector_size = 4 * 1024,
  340. .page_size = 0x100,
  341. .status_mask = 0xFFFF,
  342. };
  343. return send_cmd(&spi_cmd, sizeof(spi_cmd), NULL);
  344. }
  345. __attribute__ ((weak)) void loader_port_debug_print(const char *str)
  346. {
  347. }