/ components / bootloader_support / src / bootloader_console_loader.c
bootloader_console_loader.c
 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  /**
16   * This file contains console-related functions which should be located in iram_loader_seg,
17   * to be available in the "loader" phase, when iram_seg may be overwritten.
18   */
19  #include <stdint.h>
20  #include <stddef.h>
21  #include "sdkconfig.h"
22  #include "bootloader_console.h"
23  #include "esp_rom_uart.h"
24  #include "esp_rom_sys.h"
25  #if CONFIG_IDF_TARGET_ESP32S2
26  #include "esp32s2/rom/usb/chip_usb_dw_wrapper.h"
27  #include "esp32s2/rom/usb/usb_dc.h"
28  #include "esp32s2/rom/usb/cdc_acm.h"
29  #include "esp32s2/rom/usb/usb_persist.h"
30  #endif
31  
32  #ifdef CONFIG_ESP_CONSOLE_USB_CDC
33  /* The following functions replace esp_rom_uart_putc, esp_rom_uart_tx_one_char,
34   * and uart_tx_one_char_uart ROM functions. The main difference is that
35   * uart_tx_one_char_uart calls cdc_acm_fifo_fill for each byte passed to it,
36   * which results in very slow console output. The version here uses a TX buffer.
37   * It also doesn't handle UART output, only works with USB.
38   */
39  static char cdc_txbuf[ACM_BYTES_PER_TX];
40  static size_t cdc_txpos;
41  
42  static void bootloader_console_flush_usb(void)
43  {
44      cdc_acm_fifo_fill(uart_acm_dev, (const uint8_t *) cdc_txbuf, cdc_txpos);
45      /* return value ignored — if bootloader fails to log something, proceed anyway */
46      cdc_txpos = 0;
47  }
48  
49  static void bootloader_console_write_one_char_usb(char ch)
50  {
51      cdc_txbuf[cdc_txpos++] = ch;
52      if (ch == '\n' || cdc_txpos == sizeof(cdc_txbuf)) {
53          bootloader_console_flush_usb();
54      }
55  }
56  
57  void bootloader_console_write_char_usb(char c)
58  {
59      if (c == '\n') {
60          bootloader_console_write_one_char_usb('\r');
61          bootloader_console_write_one_char_usb('\n');
62      } else if (c == '\r') {
63      } else {
64          bootloader_console_write_one_char_usb(c);
65      }
66  }
67  #endif //CONFIG_ESP_CONSOLE_USB_CDC
68  
69  void bootloader_console_deinit(void)
70  {
71  #ifdef CONFIG_ESP_CONSOLE_UART
72      /* Ensure any buffered log output is displayed */
73      esp_rom_uart_flush_tx(CONFIG_ESP_CONSOLE_UART_NUM);
74  #endif // CONFIG_ESP_CONSOLE_UART
75  
76  #ifdef CONFIG_ESP_CONSOLE_USB_CDC
77      bootloader_console_flush_usb();
78      usb_dc_prepare_persist();
79      chip_usb_set_persist_flags(USBDC_PERSIST_ENA);
80      esp_rom_delay_us(100);
81      for (int i = 0; i < 10; i++) {
82          usb_dc_check_poll_for_interrupts();
83      }
84      esp_rom_install_channel_putc(1, NULL);
85  #endif
86  }