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

[TW#16347] A uart flush on UART1 affects UART2 read #1219

Closed
edkerekes opened this issue Nov 2, 2017 · 2 comments
Closed

[TW#16347] A uart flush on UART1 affects UART2 read #1219

edkerekes opened this issue Nov 2, 2017 · 2 comments

Comments

@edkerekes
Copy link

edkerekes commented Nov 2, 2017

Description:
Calling uart_flush(1) corrupts data received from uart2.
It seems that once corrupted, a hard reset is the only fix.

Note
This issue may be related to issue Calling uart_flush(2) corrupts data thereafter #1202

Steps to reproduce:

  1. I am using the latest esp-idf master 80eb3b6 at this time.

  2. Connect TX2 to RX2 with a jumper wire.

  3. Run the provided code.
    The sample code will reproduce the issue reliably within a few seconds.
    All received data from UART2 after the loop “count == 5” is then corrupted.

The sample code performs the following basic logic:

Initialize UART1
Initialize UART2
uart_write_bytes(MY_UART1, "01234567890123456789", strlen("01234567890123456789"))
while (true) {
     	If (count == 5)  {
       		uart_flush(1).
    	}
       	Send 1 line of text to UART2 “abcdefghijklmnopqrstuvxyz_(xxx)”
       	Read the line of text back from UART2 with RX timeout of 1 second.	
       	Log the received data to the console.
       	Count = Count + 1
}

The board that I am using is an esp-wroom-32 dev kit, but I doubt that it is board dependent.

Code to Reproduce

/* uart_flush_test2
 * This task demonstrates that after sending some characters on uart1 and then
 * calling uart_flush(1) one time, data on UART2 is corrupted.
 * 
 * Requirements:
 * 1. UART1: Available.
 * 2. UART2: Requires a single jumper wire to connect TX2 to RX2 so data
 *     sent on UART2 can be received back.
 * 3. Received test data is Logged to the standard console using ESP_LOGx().
 */
#include <stdio.h>
#include <string.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/uart.h"

static const char *TAG = "uart_flush_test";

#define MY_UART1  UART_NUM_1    /* Uart to flush. */
#define MY_UART2  UART_NUM_2	/* Uart to test. */

/* Use any 2 available I/O pins
 * Note pins 34 and higher can only be inputs.
 */
#define TXD1_PIN  (GPIO_NUM_32)     /* (No connect is fine for this test.) */
#define RXD1_PIN  (GPIO_NUM_35)     /* (No connect is fine for this test.) */

/* Use any 2 available I/O pins and connect them together with a 
 * jumper wire. Note pins 34 and higher can only be inputs. 
 */
#define TXD2_PIN  (GPIO_NUM_33)
#define RXD2_PIN  (GPIO_NUM_34)


#define BUF_SIZE (1024)

/* Configure parameters of UART driver,
 * communication pins and install the driver 
 */
void Configure_Uart(int uart_num, int tx_pin, int rx_pin) {
    uart_config_t uart_config = { 
            .baud_rate = 115200, 
            .data_bits = UART_DATA_8_BITS, 
            .parity = UART_PARITY_DISABLE, 
            .stop_bits = UART_STOP_BITS_1, 
            .flow_ctrl = UART_HW_FLOWCTRL_DISABLE 
    };
    if (uart_param_config(uart_num, &uart_config) < 0) {
        ESP_LOGE(TAG, "uart_param_config() error!");
    }
    if (uart_set_pin(uart_num, tx_pin, rx_pin, UART_PIN_NO_CHANGE,
            UART_PIN_NO_CHANGE) < 0) {
        ESP_LOGE(TAG, "uart_set_pin() error!");
    }
    if (uart_driver_install(uart_num, BUF_SIZE * 2, 0, 0, NULL, 0) < 0) {
        ESP_LOGE(TAG, "uart_driver_install() error!");
    }
}

void app_main() {
    int len;
    uint8_t buf[BUF_SIZE];
    char s[200];
    memset(buf, 0, sizeof(buf));
    memset(s, 0, sizeof(s));

    Configure_Uart(MY_UART1, TXD1_PIN, RXD1_PIN);
    ESP_LOGI(TAG, "MY_UART1 = %d", MY_UART1);

    Configure_Uart(MY_UART2, TXD2_PIN, RXD2_PIN);
    ESP_LOGI(TAG, "MY_UART2 = %d", MY_UART2);

    /* Write any data to UART1 once. */
    len = uart_write_bytes(MY_UART1, "01234567890123456789", strlen("01234567890123456789"));

    int count = 0;
    while (true) {
        if (count == 5) {
            /* Flush uart1 1 time. */
            ESP_LOGI(TAG, "Calling uart_flush(%d)", MY_UART1);
            uart_flush (MY_UART1);
        }

        /* Write constant string with a count to UART2. */
        sprintf(s, "abcdefghijklmnopqrstuvxyz_(%03d)", count);
        len = uart_write_bytes(MY_UART2, s, strlen(s));
        if (len < 0) {
            ESP_LOGE(TAG, "Could not write bytes! (%d)", len);
        }
        
        /* Read string back from the UART2 */
        len = uart_read_bytes(MY_UART2, buf, BUF_SIZE - 1,
                1000 / portTICK_RATE_MS);
        if (len > 0) {
            /* Log received string to the console. */
            buf[len] = '\0';
            ESP_LOGI(TAG, ">%s<", buf);
        } else {
            ESP_LOGE(TAG, "RX Timeout (check tx pin is connected to rx pin");
        }

        count++;
    }
}

Captured Log:

MONITOR
--- idf_monitor on /dev/ttyUSB0 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:5828
load:0x40078000,len:0
load:0x40078000,len:13080
entry 0x400790c0
W (68) rtc_clk: Possibly invalid CONFIG_ESP32_XTAL_FREQ setting (40MHz). Detected 40 MHz.
I (37) boot: ESP-IDF v3.0-dev-1351-g00973d0e-dirty 2nd stage bootloader
I (37) boot: compile time 15:06:43
I (38) boot: Enabling RNG early entropy source...
I (44) boot: SPI Speed      : 40MHz
I (48) boot: SPI Mode       : DIO
I (52) boot: SPI Flash Size : 4MB
I (56) boot: Partition Table:
I (60) boot: ## Label            Usage          Type ST Offset   Length
I (67) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (74) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (82) boot:  2 factory          factory app      00 00 00010000 00100000
I (89) boot: End of partition table
I (93) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x04a34 ( 18996) map
I (109) esp_image: segment 1: paddr=0x00014a5c vaddr=0x3ffb0000 size=0x016e4 (  5860) load
I (114) esp_image: segment 2: paddr=0x00016148 vaddr=0x40080000 size=0x00400 (  1024) load
0x40080000: _iram_start at /cust/ipsolutions/smartplug/esp32/esp-idf/components/freertos/./xtensa_vectors.S:1685

I (121) esp_image: segment 3: paddr=0x00016550 vaddr=0x40080400 size=0x07e98 ( 32408) load
I (143) esp_image: segment 4: paddr=0x0001e3f0 vaddr=0x400c0000 size=0x00000 (     0) load
I (143) esp_image: segment 5: paddr=0x0001e3f8 vaddr=0x00000000 size=0x01c18 (  7192) 
I (151) esp_image: segment 6: paddr=0x00020018 vaddr=0x400d0018 size=0x14b84 ( 84868) map
0x400d0018: _stext at ??:?

I (192) boot: Loaded app from partition at offset 0x10000
I (192) boot: Disabling RNG early entropy source...
I (192) cpu_start: Pro cpu up.
I (196) cpu_start: Single core mode
I (201) heap_init: Initializing. RAM available for dynamic allocation:
I (207) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (214) heap_init: At 3FFB1E60 len 0002E1A0 (184 KiB): DRAM
I (220) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM
I (226) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (233) heap_init: At 40088298 len 00017D68 (95 KiB): IRAM
I (239) cpu_start: Pro cpu start user code
I (256) cpu_start: Starting scheduler on PRO CPU.
I (258) uart_flush_test: MY_UART1 = 1
I (258) uart_flush_test: MY_UART2 = 2
I (1258) uart_flush_test: >abcdefghijklmnopqrstuvxyz_(000)<   <<<< GOOD
I (2258) uart_flush_test: >abcdefghijklmnopqrstuvxyz_(001)<   <<<< GOOD
I (3258) uart_flush_test: >abcdefghijklmnopqrstuvxyz_(002)<   <<<< GOOD
I (4258) uart_flush_test: >abcdefghijklmnopqrstuvxyz_(003)<   <<<< GOOD
I (5258) uart_flush_test: >abcdefghijklmnopqrstuvxyz_(004)<   <<<< GOOD
I (5258) uart_flush_test: Calling uart_flush(1)               <<<< FLUSH THE OTHER CHANNEL
I (6258) uart_flush_test: >efghijklmnopqrstuvxyz_(004)efgh<   <<<< CORRUPTION (Line 4 data repeated)
I (7258) uart_flush_test: >ijklmnopqrstuvxyz_(004)abcdefgh<   <<<< CORRUPTION (Line 4 data repeated)
I (8258) uart_flush_test: >ijklmnopqrstuvxyz_(005)abcdefgh<   <<<< CORRUPTION (Line 5 & 6 data)
I (9258) uart_flush_test: >ijklmnopqrstuvxyz_(006)abcdefgh<   <<<< CORRUPTION (Line 6 & 7 data)
I (10258) uart_flush_test: >ijklmnopqrstuvxyz_(007)abcdefgh<  <<<< CORRUPTION continues...
I (11258) uart_flush_test: >ijklmnopqrstuvxyz_(008)abcdefgh<
I (12258) uart_flush_test: >ijklmnopqrstuvxyz_(009)abcdefgh<
I (13258) uart_flush_test: >ijklmnopqrstuvxyz_(010)abcdefgh<
I (14258) uart_flush_test: >ijklmnopqrstuvxyz_(011)abcdefgh<
I (15258) uart_flush_test: >ijklmnopqrstuvxyz_(012)abcdefgh<
I (16258) uart_flush_test: >ijklmnopqrstuvxyz_(013)abcdefgh<
I (17258) uart_flush_test: >ijklmnopqrstuvxyz_(014)abcdefgh<
I (18258) uart_flush_test: >ijklmnopqrstuvxyz_(015)abcdefgh<
I (19258) uart_flush_test: >ijklmnopqrstuvxyz_(016)abcdefgh<
I (20258) uart_flush_test: >ijklmnopqrstuvxyz_(017)abcdefgh<

@llewellynnu
Copy link

@igrr Thoughts?

@igrr
Copy link
Member

igrr commented Nov 8, 2017

See #1202 (comment).

@FayeY FayeY changed the title A uart flush on UART1 affects UART2 read [TW#16347] A uart flush on UART1 affects UART2 read Nov 10, 2017
igrr pushed a commit that referenced this issue Nov 13, 2017
Reported from github:
#1219
#1202

After providing a simple code to digital team, they confirmed that this is a hardware bug.

Root cause:
The fifo reset signal is incorrectly connected
If we want to reset tx fifo of UART2, we have to set txfifo_rst bit of both UART1 and UART2
If we want to reset rx fifo of UART2, we have to set rxfifo_rst bit of both UART1 and UART2

Workaround:
we don't use fifo rst bit in driver.

Documentation:
Digital team would update TRM and give more explanation about this issue.
@FayeY FayeY closed this as completed Dec 1, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants