protocol_uart.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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 "protocol.h"
  16. #include "protocol_prv.h"
  17. #include "esp_loader_io.h"
  18. #include "slip.h"
  19. #include <stddef.h>
  20. #include <string.h>
  21. static esp_loader_error_t check_response(command_t cmd, uint32_t *reg_value, void* resp, uint32_t resp_size);
  22. esp_loader_error_t loader_initialize_conn(esp_loader_connect_args_t *connect_args) {
  23. esp_loader_error_t err;
  24. int32_t trials = connect_args->trials;
  25. do {
  26. loader_port_start_timer(connect_args->sync_timeout);
  27. err = loader_sync_cmd();
  28. if (err == ESP_LOADER_ERROR_TIMEOUT) {
  29. if (--trials == 0) {
  30. return ESP_LOADER_ERROR_TIMEOUT;
  31. }
  32. loader_port_delay_ms(100);
  33. } else if (err != ESP_LOADER_SUCCESS) {
  34. return err;
  35. }
  36. } while (err != ESP_LOADER_SUCCESS);
  37. return err;
  38. }
  39. esp_loader_error_t send_cmd(const void *cmd_data, uint32_t size, uint32_t *reg_value)
  40. {
  41. response_t response;
  42. command_t command = ((const command_common_t *)cmd_data)->command;
  43. RETURN_ON_ERROR( SLIP_send_delimiter() );
  44. RETURN_ON_ERROR( SLIP_send((const uint8_t *)cmd_data, size) );
  45. RETURN_ON_ERROR( SLIP_send_delimiter() );
  46. const uint8_t response_cnt = command == SYNC ? 8 : 1;
  47. for (uint8_t recv_cnt = 0; recv_cnt < response_cnt; recv_cnt++) {
  48. RETURN_ON_ERROR(check_response(command, reg_value, &response, sizeof(response)));
  49. }
  50. return ESP_LOADER_SUCCESS;
  51. }
  52. esp_loader_error_t send_cmd_with_data(const void *cmd_data, size_t cmd_size,
  53. const void *data, size_t data_size)
  54. {
  55. response_t response;
  56. command_t command = ((const command_common_t *)cmd_data)->command;
  57. RETURN_ON_ERROR( SLIP_send_delimiter() );
  58. RETURN_ON_ERROR( SLIP_send((const uint8_t *)cmd_data, cmd_size) );
  59. RETURN_ON_ERROR( SLIP_send(data, data_size) );
  60. RETURN_ON_ERROR( SLIP_send_delimiter() );
  61. return check_response(command, NULL, &response, sizeof(response));
  62. }
  63. esp_loader_error_t send_cmd_md5(const void *cmd_data, size_t cmd_size, uint8_t md5_out[MD5_SIZE])
  64. {
  65. rom_md5_response_t response;
  66. command_t command = ((const command_common_t *)cmd_data)->command;
  67. RETURN_ON_ERROR( SLIP_send_delimiter() );
  68. RETURN_ON_ERROR( SLIP_send((const uint8_t *)cmd_data, cmd_size) );
  69. RETURN_ON_ERROR( SLIP_send_delimiter() );
  70. RETURN_ON_ERROR( check_response(command, NULL, &response, sizeof(response)) );
  71. memcpy(md5_out, response.md5, MD5_SIZE);
  72. return ESP_LOADER_SUCCESS;
  73. }
  74. static esp_loader_error_t check_response(command_t cmd, uint32_t *reg_value, void* resp, uint32_t resp_size)
  75. {
  76. esp_loader_error_t err;
  77. common_response_t *response = (common_response_t *)resp;
  78. do {
  79. err = SLIP_receive_packet(resp, resp_size);
  80. if (err != ESP_LOADER_SUCCESS) {
  81. return err;
  82. }
  83. } while ((response->direction != READ_DIRECTION) || (response->command != cmd));
  84. response_status_t *status = (response_status_t *)((uint8_t *)resp + resp_size - sizeof(response_status_t));
  85. if (status->failed) {
  86. log_loader_internal_error(status->error);
  87. return ESP_LOADER_ERROR_INVALID_RESPONSE;
  88. }
  89. if (reg_value != NULL) {
  90. *reg_value = response->value;
  91. }
  92. return ESP_LOADER_SUCCESS;
  93. }