|
| 1 | +/* |
| 2 | + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD |
| 3 | + * |
| 4 | + * SPDX-License-Identifier: Apache-2.0 |
| 5 | + */ |
| 6 | + |
| 7 | +#include <stdio.h> |
| 8 | +#include <string.h> |
| 9 | + |
| 10 | +#include <bootutil/bootutil_log.h> |
| 11 | + |
| 12 | +#include <esp_rom_uart.h> |
| 13 | +#include <esp_rom_gpio.h> |
| 14 | +#include <esp_rom_sys.h> |
| 15 | +#include <esp_rom_caps.h> |
| 16 | +#include <soc/uart_periph.h> |
| 17 | +#include <soc/gpio_struct.h> |
| 18 | +#include <soc/io_mux_reg.h> |
| 19 | +#include <soc/rtc.h> |
| 20 | +#include <hal/gpio_types.h> |
| 21 | +#include <hal/gpio_ll.h> |
| 22 | +#include <hal/uart_ll.h> |
| 23 | +#include <hal/clk_gate_ll.h> |
| 24 | +#include <hal/gpio_hal.h> |
| 25 | +#include <hal/usb_serial_jtag_ll.h> |
| 26 | + |
| 27 | +#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT |
| 28 | +#define SERIAL_BOOT_GPIO_DETECT CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT |
| 29 | +#else |
| 30 | +#define SERIAL_BOOT_GPIO_DETECT GPIO_NUM_5 |
| 31 | +#endif |
| 32 | + |
| 33 | +#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL |
| 34 | +#define SERIAL_BOOT_GPIO_DETECT_VAL CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL |
| 35 | +#else |
| 36 | +#define SERIAL_BOOT_GPIO_DETECT_VAL 1 |
| 37 | +#endif |
| 38 | + |
| 39 | +#ifdef CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S |
| 40 | +#define SERIAL_BOOT_DETECT_DELAY_S CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S |
| 41 | +#else |
| 42 | +#define SERIAL_BOOT_DETECT_DELAY_S 5 |
| 43 | +#endif |
| 44 | + |
| 45 | +#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE |
| 46 | +#define SERIAL_BOOT_GPIO_INPUT_TYPE CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE |
| 47 | +#else |
| 48 | +// pull-down |
| 49 | +#define SERIAL_BOOT_GPIO_INPUT_TYPE 0 |
| 50 | +#endif |
| 51 | + |
| 52 | +#ifndef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG |
| 53 | + |
| 54 | +#ifdef CONFIG_ESP_SERIAL_BOOT_UART_NUM |
| 55 | +#define SERIAL_BOOT_UART_NUM CONFIG_ESP_SERIAL_BOOT_UART_NUM |
| 56 | +#else |
| 57 | +#define SERIAL_BOOT_UART_NUM ESP_ROM_UART_1 |
| 58 | +#endif |
| 59 | + |
| 60 | +#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_RX |
| 61 | +#define SERIAL_BOOT_GPIO_RX CONFIG_ESP_SERIAL_BOOT_GPIO_RX |
| 62 | +#else |
| 63 | +#define SERIAL_BOOT_GPIO_RX GPIO_NUM_18 |
| 64 | +#endif |
| 65 | + |
| 66 | +#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_TX |
| 67 | +#define SERIAL_BOOT_GPIO_TX CONFIG_ESP_SERIAL_BOOT_GPIO_TX |
| 68 | +#else |
| 69 | +#define SERIAL_BOOT_GPIO_TX GPIO_NUM_17 |
| 70 | +#endif |
| 71 | + |
| 72 | +static uart_dev_t *serial_boot_uart_dev = (SERIAL_BOOT_UART_NUM == 0) ? |
| 73 | + &UART0 : |
| 74 | + &UART1; |
| 75 | + |
| 76 | +#endif |
| 77 | + |
| 78 | +void console_write(const char *str, int cnt) |
| 79 | +{ |
| 80 | +#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG |
| 81 | + usb_serial_jtag_ll_txfifo_flush(); |
| 82 | + while (!usb_serial_jtag_ll_txfifo_writable()) { |
| 83 | + MCUBOOT_WATCHDOG_FEED(); |
| 84 | + } |
| 85 | + usb_serial_jtag_ll_write_txfifo((const uint8_t *)str, cnt); |
| 86 | + usb_serial_jtag_ll_txfifo_flush(); |
| 87 | +#else |
| 88 | + uint32_t tx_len; |
| 89 | + uint32_t write_len; |
| 90 | + |
| 91 | + do { |
| 92 | + tx_len = uart_ll_get_txfifo_len(serial_boot_uart_dev); |
| 93 | + if (tx_len > 0) { |
| 94 | + write_len = tx_len < cnt ? tx_len : cnt; |
| 95 | + uart_ll_write_txfifo(serial_boot_uart_dev, (const uint8_t *)str, write_len); |
| 96 | + cnt -= write_len; |
| 97 | + } |
| 98 | + MCUBOOT_WATCHDOG_FEED(); |
| 99 | + esp_rom_delay_us(1000); |
| 100 | + } while (cnt > 0); |
| 101 | +#endif |
| 102 | +} |
| 103 | + |
| 104 | +int console_read(char *str, int cnt, int *newline) |
| 105 | +{ |
| 106 | +#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG |
| 107 | + |
| 108 | + uint32_t read_len = 0; |
| 109 | + |
| 110 | + esp_rom_delay_us(1000); |
| 111 | + do { |
| 112 | + if (usb_serial_jtag_ll_rxfifo_data_available()) { |
| 113 | + usb_serial_jtag_ll_read_rxfifo((uint8_t *)&str[read_len], 1); |
| 114 | + read_len++; |
| 115 | + } |
| 116 | + MCUBOOT_WATCHDOG_FEED(); |
| 117 | + esp_rom_delay_us(1000); |
| 118 | + } while (!(read_len == cnt || str[read_len - 1] == '\n')); |
| 119 | + *newline = (str[read_len - 1] == '\n') ? 1 : 0; |
| 120 | + |
| 121 | + return read_len; |
| 122 | +#else |
| 123 | + uint32_t len = 0; |
| 124 | + uint32_t read_len = 0; |
| 125 | + bool stop = false; |
| 126 | + |
| 127 | + do { |
| 128 | + len = uart_ll_get_rxfifo_len(serial_boot_uart_dev); |
| 129 | + |
| 130 | + if (len > 0) { |
| 131 | + for (uint32_t i = 0; i < len; i++) { |
| 132 | + /* Read the character from the RX FIFO */ |
| 133 | + uart_ll_read_rxfifo(serial_boot_uart_dev, (uint8_t *)&str[read_len], 1); |
| 134 | + read_len++; |
| 135 | + if (read_len == cnt - 1|| str[read_len - 1] == '\n') { |
| 136 | + stop = true; |
| 137 | + break; |
| 138 | + } |
| 139 | + } |
| 140 | + } |
| 141 | + MCUBOOT_WATCHDOG_FEED(); |
| 142 | + esp_rom_delay_us(1000); |
| 143 | + } while (!stop); |
| 144 | + |
| 145 | + *newline = (str[read_len - 1] == '\n') ? 1 : 0; |
| 146 | + return read_len; |
| 147 | +#endif |
| 148 | +} |
| 149 | + |
| 150 | +int boot_console_init(void) |
| 151 | +{ |
| 152 | + BOOT_LOG_INF("Initializing serial boot pins"); |
| 153 | + |
| 154 | +#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG |
| 155 | + usb_serial_jtag_ll_txfifo_flush(); |
| 156 | + esp_rom_uart_tx_wait_idle(0); |
| 157 | +#else |
| 158 | + /* Enable GPIO for UART RX */ |
| 159 | + esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_RX); |
| 160 | + esp_rom_gpio_connect_in_signal(SERIAL_BOOT_GPIO_RX, |
| 161 | + UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_RX_PIN_IDX), |
| 162 | + 0); |
| 163 | + gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_RX); |
| 164 | + esp_rom_gpio_pad_pullup_only(SERIAL_BOOT_GPIO_RX); |
| 165 | + |
| 166 | + /* Enable GPIO for UART TX */ |
| 167 | + esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_TX); |
| 168 | + esp_rom_gpio_connect_out_signal(SERIAL_BOOT_GPIO_TX, |
| 169 | + UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_TX_PIN_IDX), |
| 170 | + 0, 0); |
| 171 | + gpio_ll_output_enable(&GPIO, SERIAL_BOOT_GPIO_TX); |
| 172 | + |
| 173 | + uart_ll_set_sclk(serial_boot_uart_dev, UART_SCLK_APB); |
| 174 | + uart_ll_set_mode_normal(serial_boot_uart_dev); |
| 175 | + uart_ll_set_baudrate(serial_boot_uart_dev, 115200); |
| 176 | + uart_ll_set_stop_bits(serial_boot_uart_dev, 1u); |
| 177 | + uart_ll_set_parity(serial_boot_uart_dev, UART_PARITY_DISABLE); |
| 178 | + uart_ll_set_rx_tout(serial_boot_uart_dev, 16); |
| 179 | + uart_ll_set_data_bit_num(serial_boot_uart_dev, UART_DATA_8_BITS); |
| 180 | + uart_ll_set_tx_idle_num(serial_boot_uart_dev, 0); |
| 181 | + uart_ll_set_hw_flow_ctrl(serial_boot_uart_dev, UART_HW_FLOWCTRL_DISABLE, 100); |
| 182 | + periph_ll_enable_clk_clear_rst(PERIPH_UART0_MODULE + SERIAL_BOOT_UART_NUM); |
| 183 | + |
| 184 | + uart_ll_txfifo_rst(serial_boot_uart_dev); |
| 185 | + uart_ll_rxfifo_rst(serial_boot_uart_dev); |
| 186 | + esp_rom_delay_us(50000); |
| 187 | +#endif |
| 188 | + return 0; |
| 189 | +} |
| 190 | + |
| 191 | +bool boot_serial_detect_pin(void) |
| 192 | +{ |
| 193 | + bool detected = false; |
| 194 | + int pin_value = 0; |
| 195 | + |
| 196 | + esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_DETECT); |
| 197 | + gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_DETECT); |
| 198 | + switch (SERIAL_BOOT_GPIO_INPUT_TYPE) { |
| 199 | + // Pull-down |
| 200 | + case 0: |
| 201 | + gpio_ll_pulldown_en(&GPIO, SERIAL_BOOT_GPIO_DETECT); |
| 202 | + break; |
| 203 | + // Pull-up |
| 204 | + case 1: |
| 205 | + gpio_ll_pullup_en(&GPIO, SERIAL_BOOT_GPIO_DETECT); |
| 206 | + break; |
| 207 | + } |
| 208 | + esp_rom_delay_us(50000); |
| 209 | + |
| 210 | + pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT); |
| 211 | + detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL); |
| 212 | + esp_rom_delay_us(50000); |
| 213 | + |
| 214 | + if (detected) { |
| 215 | + if (SERIAL_BOOT_DETECT_DELAY_S > 0) { |
| 216 | + /* The delay time is an approximation */ |
| 217 | + for (int i = 0; i < (SERIAL_BOOT_DETECT_DELAY_S * 100); i++) { |
| 218 | + esp_rom_delay_us(10000); |
| 219 | + pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT); |
| 220 | + detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL); |
| 221 | + if (!detected) { |
| 222 | + break; |
| 223 | + } |
| 224 | + } |
| 225 | + } |
| 226 | + } |
| 227 | + return detected; |
| 228 | +} |
0 commit comments