zephyr_port.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * Copyright (c) 2022 KT-Elektronik, Klaucke und Partner GmbH
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "zephyr_port.h"
  17. #include <zephyr/drivers/uart.h>
  18. #include <zephyr/console/tty.h>
  19. static const struct device *uart_dev;
  20. static struct gpio_dt_spec enable_spec;
  21. static struct gpio_dt_spec boot_spec;
  22. static struct tty_serial tty;
  23. static char tty_rx_buf[CONFIG_ESP_SERIAL_FLASHER_UART_BUFSIZE];
  24. static char tty_tx_buf[CONFIG_ESP_SERIAL_FLASHER_UART_BUFSIZE];
  25. esp_loader_error_t configure_tty()
  26. {
  27. if (tty_init(&tty, uart_dev) < 0 ||
  28. tty_set_rx_buf(&tty, tty_rx_buf, sizeof(tty_rx_buf)) < 0 ||
  29. tty_set_tx_buf(&tty, tty_tx_buf, sizeof(tty_tx_buf)) < 0) {
  30. return ESP_LOADER_ERROR_FAIL;
  31. }
  32. return ESP_LOADER_SUCCESS;
  33. }
  34. esp_loader_error_t loader_port_serial_read(uint8_t *data, const uint16_t size, const uint32_t timeout)
  35. {
  36. if (!device_is_ready(uart_dev) || data == NULL || size == 0) {
  37. return ESP_LOADER_ERROR_FAIL;
  38. }
  39. ssize_t total_read = 0;
  40. ssize_t remaining = size;
  41. tty_set_rx_timeout(&tty, timeout);
  42. while (remaining > 0) {
  43. const uint16_t chunk_size = remaining < CONFIG_ESP_SERIAL_FLASHER_UART_BUFSIZE ?
  44. remaining : CONFIG_ESP_SERIAL_FLASHER_UART_BUFSIZE;
  45. ssize_t read = tty_read(&tty, &data[total_read], chunk_size);
  46. if (read < 0) {
  47. return ESP_LOADER_ERROR_TIMEOUT;
  48. }
  49. total_read += read;
  50. remaining -= read;
  51. }
  52. return ESP_LOADER_SUCCESS;
  53. }
  54. esp_loader_error_t loader_port_serial_write(const uint8_t *data, const uint16_t size, const uint32_t timeout)
  55. {
  56. if (!device_is_ready(uart_dev) || data == NULL || size == 0) {
  57. return ESP_LOADER_ERROR_FAIL;
  58. }
  59. ssize_t total_written = 0;
  60. ssize_t remaining = size;
  61. tty_set_tx_timeout(&tty, timeout);
  62. while (remaining > 0) {
  63. const uint16_t chunk_size = remaining < CONFIG_ESP_SERIAL_FLASHER_UART_BUFSIZE ?
  64. remaining : CONFIG_ESP_SERIAL_FLASHER_UART_BUFSIZE;
  65. ssize_t written = tty_write(&tty, &data[total_written], chunk_size);
  66. if (written < 0) {
  67. return ESP_LOADER_ERROR_TIMEOUT;
  68. }
  69. total_written += written;
  70. remaining -= written;
  71. }
  72. return ESP_LOADER_SUCCESS;
  73. }
  74. esp_loader_error_t loader_port_zephyr_init(const loader_zephyr_config_t *config)
  75. {
  76. uart_dev = config->uart_dev;
  77. enable_spec = config->enable_spec;
  78. boot_spec = config->boot_spec;
  79. return configure_tty();
  80. }
  81. void loader_port_reset_target(void)
  82. {
  83. gpio_pin_set_dt(&enable_spec, false);
  84. loader_port_delay_ms(CONFIG_SERIAL_FLASHER_RESET_HOLD_TIME_MS);
  85. gpio_pin_set_dt(&enable_spec, true);
  86. }
  87. void loader_port_enter_bootloader(void)
  88. {
  89. gpio_pin_set_dt(&boot_spec, false);
  90. loader_port_reset_target();
  91. loader_port_delay_ms(CONFIG_SERIAL_FLASHER_BOOT_HOLD_TIME_MS);
  92. gpio_pin_set_dt(&boot_spec, true);
  93. }
  94. void loader_port_delay_ms(uint32_t ms)
  95. {
  96. k_msleep(ms);
  97. }
  98. static uint64_t s_time_end;
  99. void loader_port_start_timer(uint32_t ms)
  100. {
  101. s_time_end = sys_clock_timeout_end_calc(Z_TIMEOUT_MS(ms));
  102. }
  103. uint32_t loader_port_remaining_time(void)
  104. {
  105. int64_t remaining = k_ticks_to_ms_floor64(s_time_end - k_uptime_ticks());
  106. return (remaining > 0) ? (uint32_t)remaining : 0;
  107. }
  108. esp_loader_error_t loader_port_change_baudrate(uint32_t baudrate)
  109. {
  110. struct uart_config uart_config;
  111. if (!device_is_ready(uart_dev)) {
  112. return ESP_LOADER_ERROR_FAIL;
  113. }
  114. if (uart_config_get(uart_dev, &uart_config) != 0) {
  115. return ESP_LOADER_ERROR_FAIL;
  116. }
  117. uart_config.baudrate = baudrate;
  118. if (uart_configure(uart_dev, &uart_config) != 0) {
  119. return ESP_LOADER_ERROR_FAIL;
  120. }
  121. /* bitrate-change can require tty re-configuration */
  122. return configure_tty();
  123. }