Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

USB serial JTAG UART echo does not work without ESP_LOGI() #12605

Closed
3 tasks done
jetpax opened this issue Nov 17, 2023 · 1 comment
Closed
3 tasks done

USB serial JTAG UART echo does not work without ESP_LOGI() #12605

jetpax opened this issue Nov 17, 2023 · 1 comment
Labels
Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Type: Bug bugs in IDF

Comments

@jetpax
Copy link

jetpax commented Nov 17, 2023

Answers checklist.

  • I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

IDF version.

v5.1.2

Espressif SoC revision.

ESP32-s3 v0.1

Operating System used.

macOS

How did you build your project?

Command line with idf.py

If you are using Windows, please specify command line type.

None

Development Kit.

Devkit-M

Power Supply used.

USB

What is the expected behavior?

I expected the USB JTAG serial UART to echo received characters back to the esp-idf monitor when using the following program, which is a slightly modified version of the esp-idf uart_echo example

/* UART Echo Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "sdkconfig.h"
#include "esp_log.h"

/**
 * This is an example which echos any data it receives on configured UART back to the sender,
 * with hardware flow control turned off. It does not use UART driver event queue.
 *
 * - Port: configured UART
 * - Receive (Rx) buffer: on
 * - Transmit (Tx) buffer: off
 * - Flow control: off
 * - Event queue: off
 * - Pin assignment: see defines below (See Kconfig)
 */

#define ECHO_TEST_TXD (CONFIG_EXAMPLE_UART_TXD)
#define ECHO_TEST_RXD (CONFIG_EXAMPLE_UART_RXD)
#define ECHO_TEST_RTS (UART_PIN_NO_CHANGE)
#define ECHO_TEST_CTS (UART_PIN_NO_CHANGE)

#define ECHO_UART_PORT_NUM      (CONFIG_EXAMPLE_UART_PORT_NUM)
#define ECHO_UART_BAUD_RATE     (CONFIG_EXAMPLE_UART_BAUD_RATE)
#define ECHO_TASK_STACK_SIZE    (CONFIG_EXAMPLE_TASK_STACK_SIZE)

static const char *TAG = "UART TEST";

#define BUF_SIZE (1024)

#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG

#include "driver/usb_serial_jtag.h"
#include "esp_vfs_usb_serial_jtag.h"
#include "esp_vfs_dev.h"
#include <fcntl.h>

#endif

static void echo_task(void *arg)
{

 // Configure UART

#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
    usb_serial_jtag_driver_config_t usb_serial_jtag_config;
    usb_serial_jtag_config.rx_buffer_size = BUF_SIZE;
    usb_serial_jtag_config.tx_buffer_size = BUF_SIZE;
#else
    /* Configure parameters of an UART driver,
     * communication pins and install the driver */
    uart_config_t uart_config = {
        .baud_rate = ECHO_UART_BAUD_RATE,
        .data_bits = UART_DATA_8_BITS,
        .parity    = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };
    int intr_alloc_flags = 0;

#if CONFIG_UART_ISR_IN_IRAM
    intr_alloc_flags = ESP_INTR_FLAG_IRAM;
#endif

#endif

 // Install UART driver
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
    ESP_ERROR_CHECK(usb_serial_jtag_driver_install(&usb_serial_jtag_config));
#else
    ESP_ERROR_CHECK(uart_driver_install(ECHO_UART_PORT_NUM, BUF_SIZE * 2, 0, 0, NULL, intr_alloc_flags));
    ESP_ERROR_CHECK(uart_param_config(ECHO_UART_PORT_NUM, &uart_config));
    ESP_ERROR_CHECK(uart_set_pin(ECHO_UART_PORT_NUM, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS));
#endif

    // Configure a temporary buffer for the incoming data
    uint8_t *data = (uint8_t *) malloc(BUF_SIZE);

    while (1) {

        // Read data from the UART
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
        int len = usb_serial_jtag_read_bytes( data, (BUF_SIZE - 1), 20 / portTICK_PERIOD_MS);
#else
        int len = uart_read_bytes(ECHO_UART_PORT_NUM, data, (BUF_SIZE - 1), 20 / portTICK_PERIOD_MS);
#endif

        // Write data back to the UART
        if (len) {
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
        usb_serial_jtag_write_bytes((const char *) data, len, 20 / portTICK_PERIOD_MS);
#else
        uart_write_bytes(ECHO_UART_PORT_NUM, (const char *) data, len);
#endif
            data[len] = '\0';
            // ESP_LOGI(TAG, "Recv str: %s", (char *) data);
        }
    }
}

void app_main(void)
{
    xTaskCreate(echo_task, "uart_echo_task", ECHO_TASK_STACK_SIZE, NULL, 10, NULL);
}

What is the actual behavior?

Instead it only works when the line

// ESP_LOGI(TAG, "Recv str: %s", (char *) data);

is uncommented.

If idf.py menuconfig is used to select UART0, the echo works correctly, even with this line commented

Steps to reproduce.

  1. Replace the existing uart echo example code with the code given above, and configure the project with menuconfig for an esp32-s3 and UART0
  2. Build the project with idf.py build flash monitor and confirm that characters are echoed back when the usb cable is plugged into the UART port
  3. Reconfigure the project with CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG using menuconfig and plug the usb cable into the USB port, and observe that no characters are echoed
  4. Rebuild with line 108 ( // ESP_LOGI(TAG, "Recv str: %s", (char *) data);
    ) uncommented and observe that characters are now echoed

Debug Logs.

No response

More Information.

Note that adding
usb_serial_jtag_ll_txfifo_flush();
after
usb_serial_jtag_write_bytes((const char *) data, len, 20 / portTICK_PERIOD_MS);
seems to fix the issue but this requires the inclusion of hal/usb_serial_jtag_ll.h
which is not documented

@jetpax jetpax added the Type: Bug bugs in IDF label Nov 17, 2023
@espressif-bot espressif-bot added the Status: Opened Issue is new label Nov 17, 2023
@github-actions github-actions bot changed the title USB serial JTAG UART echo does not work without ESP_LOGI() USB serial JTAG UART echo does not work without ESP_LOGI() (IDFGH-11478) Nov 17, 2023
@jetpax jetpax changed the title USB serial JTAG UART echo does not work without ESP_LOGI() (IDFGH-11478) USB serial JTAG UART echo does not work without ESP_LOGI() Nov 17, 2023
@igrr
Copy link
Member

igrr commented Nov 18, 2023

Probably very similar issue as #12620 (comment) — you are trying to use the USB_SERIAL_JTAG peripheral simultaneously via the driver functions (usb_serial_jtag_*) and via the higher-level console driver. It is unlikely that this combination will work.

If you need to use the USB_SERIAL_JTAG driver directly, don't enable CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED.

If you enable console via USB_SERIAL_JTAG, don't try to use the lower-level driver and use write or fwrite functions to write bytes to stdout. If you use fwrite, call fflush when you want to flush the stream buffer. In both cases, call fsync(fileno(stdout)) to force the underlying driver to send the data.

@espressif-bot espressif-bot added Status: Done Issue is done internally Resolution: NA Issue resolution is unavailable and removed Status: Opened Issue is new labels Dec 1, 2023
espressif-bot pushed a commit that referenced this issue Apr 9, 2024
espressif-bot pushed a commit that referenced this issue May 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Type: Bug bugs in IDF
Projects
None yet
Development

No branches or pull requests

3 participants