Skip to content

UART_MODE_RS485_HALF_DUPLEX mode not working on ESP32-S2 (IDFGH-5159) #6937

@jakepu

Description

@jakepu

Environment

  • Module or chip used: ESP32­-S2­-WROVER­-I
  • IDF version: v4.2
  • Build System: idf.py
  • Compiler version: xtensa-esp32-elf-gcc (crosstool-NG esp-2020r3) 8.4.0
  • Operating System: Linux Ubuntu 20.04
  • Using an IDE?: No
  • Power Supply: external 3.3V

Similar Cases

I think this blog has investigated this issue and provide a lot of detailed analysis.

Problem Description

I set the mode to UART_MODE_RS485_HALF_DUPLEX. RTS pin does not pull up when I am sending message through UART. I have used oscilloscope to investigate and the TX is sending correct message while the RTS pin is always low. Thus there is no message transmitted from the RS485 transceiver. There is no error when I monitor the log output.

Expected Behavior

RTS pin should pull when before I send a message and drop back to low when it is finished. The RS485 can therefore send a message.

Steps to reproduce

  1. Setup UART_MODE_RS485_HALF_DUPLEX in uart_config_t
  2. Call uart_param_config(), uart_set_pin(), uart_driver_install() as indicated by the documentation.
  3. Send a message by calling uart_write_bytes()

// If possible, attach a picture of your setup/wiring here.
Circuit B: Manual Switching Transmitter/Receiver Without Collision Detection in the ESP32-S2 online documentation.

Code to reproduce this issue

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "driver/uart.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "sdkconfig.h"
#include "driver/gpio.h"

// #define TAG "RS485_LOCKER_APP"
#define GPIO_LOCK_EN    (23)        // dev kit pin
// #define GPIO_LOCK_EN    (41)        // actual pin on PCB
#define BAUD_RATE       (115200)
#define MSG_LEN         (6)
#define LOCK_OPEN_TICKS (1500 / portTICK_RATE_MS)
#define UART_BUF_SIZE (256)
#define UART_USED               UART_NUM_1
// Read packet timeout
#define PACKET_READ_TICS        (100 / portTICK_RATE_MS)
#define UART_TASK_STACK_SIZE    (2048)
#define UART_TASK_PRIO          (10)                        // max at 24
#define EVENT_QUEUE_SIZE        (20)

static void uart_send(const int port, const uint8_t* str, uint8_t length) 
{    
    if (uart_write_bytes(port, (const char *)str, length) != length) {
        // ESP_LOGE(TAG, "Send data critical failure.");
        // add your code to handle sending failure here
        printf("uart_send failed");
        abort();
    }
}

// /*
//  * Define UART interrupt subroutine to handle parity error
//  */
// static void uart_intr_parity_err_handle(void *arg){
//     uart_flush(UART_USED);
//     uart_clear_intr_status(UART_USED, UART_PARITY_ERR_INT_CLR);
// }

static void monitor_uart_task(void *arg)
{
    uart_config_t uart_config = {
        .baud_rate = BAUD_RATE,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_EVEN,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_MODE_RS485_HALF_DUPLEX,    
        .rx_flow_ctrl_thresh = 122,
        // .source_clk = UART_SCLK_APB,
    };

    // Configure UART parameters
    ESP_ERROR_CHECK(uart_param_config(UART_USED, &uart_config));

    // Set UART pins(TX: IO17 (UART1 default), RX: IO18 (UART1 default), RTS: IO21, CTS: IO33)
    ESP_ERROR_CHECK(uart_set_pin(UART_USED, 17, 18, 21, 33));

    ESP_ERROR_CHECK(uart_driver_install(UART_USED, UART_BUF_SIZE, UART_BUF_SIZE, 0, NULL, 0));

    // Allocate buffers for UART
    uint8_t data[UART_BUF_SIZE] = {0};

    // using WIFI MAC address to create unique ID for each chip
    uint8_t baseMac[MSG_LEN] = {156, 156, 31, 199, 191, 120};

    
    uart_event_t event;
    while(1) {
        vTaskDelay(4000 / portTICK_RATE_MS);
        //Read data from UART
        size_t buffered_len = 0;
        uart_send(UART_USED, baseMac, 6);
        printf("Sent to mac address is: %u, %u, %u, %u, %u, %u\n", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]);
    }
    vTaskDelete(NULL);
}

void app_main(void)
{
    TaskHandle_t uart_task_handle;
    xTaskCreate(monitor_uart_task, "monitor_uart_task", UART_TASK_STACK_SIZE, NULL, UART_TASK_PRIO, &uart_task_handle);
}

Debug Logs

ESP-ROM:esp32s2-rc4-20191025
Build:Oct 25 2019
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3ffe6100,len:0x4
load:0x3ffe6104,len:0x185c
load:0x4004c000,len:0x1688
load:0x40050000,len:0x20fc
entry 0x4004c324
I (46) boot: ESP-IDF v4.2-dirty 2nd stage bootloader
I (46) boot: compile time 20:05:54
I (46) boot: chip revision: 0
I (48) boot.esp32s2: SPI Speed      : 80MHz
I (53) boot.esp32s2: SPI Mode       : DIO
I (57) boot.esp32s2: SPI Flash Size : 2MB
I (62) boot: Enabling RNG early entropy source...
I (68) boot: Partition Table:
I (71) boot: ## Label            Usage          Type ST Offset   Length
I (78) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (86) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (93) boot:  2 factory          factory app      00 00 00010000 00100000
I (101) boot: End of partition table
I (105) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f000020 size=0x05960 ( 22880) map
I (119) esp_image: segment 1: paddr=0x00015988 vaddr=0x3ffbdb20 size=0x01d24 (  7460) load
I (125) esp_image: segment 2: paddr=0x000176b4 vaddr=0x40024000 size=0x00404 (  1028) load
0x40024000: _WindowOverflow4 at /home/jake/esp/esp-idf/components/freertos/xtensa/xtensa_vectors.S:1730

I (132) esp_image: segment 3: paddr=0x00017ac0 vaddr=0x40024404 size=0x08558 ( 34136) load
I (150) esp_image: segment 4: paddr=0x00020020 vaddr=0x40080020 size=0x152bc ( 86716) map
0x40080020: _stext at ??:?

I (168) esp_image: segment 5: paddr=0x000352e4 vaddr=0x4002c95c size=0x011c0 (  4544) load
0x4002c95c: get_spi_dev at /home/jake/esp/esp-idf/components/soc/src/hal/spi_flash_hal_common.inc:26
 (inlined by) spi_flash_hal_erase_chip at /home/jake/esp/esp-idf/components/soc/src/hal/spi_flash_hal_iram.c:19

I (175) boot: Loaded app from partition at offset 0x10000
I (175) boot: Disabling RNG early entropy source...
I (178) cache: Instruction cache 	: size 8KB, 4Ways, cache line size 32Byte
I (185) cpu_start: Pro cpu up.
I (189) cpu_start: Application information:
I (194) cpu_start: Project name:     locker
I (199) cpu_start: App version:      1f17c39-dirty
I (204) cpu_start: Compile time:     Apr 23 2021 20:05:43
I (210) cpu_start: ELF file SHA256:  c0c8f58f74ee70ce...
I (216) cpu_start: ESP-IDF:          v4.2-dirty
I (221) cpu_start: Single core mode
I (226) heap_init: Initializing. RAM available for dynamic allocation:
I (233) heap_init: At 3FFC0000 len 0003C000 (240 KiB): DRAM
I (239) heap_init: At 3FFFC000 len 00003A10 (14 KiB): DRAM
I (245) cpu_start: Pro cpu start user code
I (304) spi_flash: detected chip: generic
I (305) spi_flash: flash io: dio
W (305) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (315) cpu_start: Starting scheduler on PRO CPU.
Sent to mac address is: 156, 156, 31, 199, 191, 120
Sent to mac address is: 156, 156, 31, 199, 191, 120

Other items if possible

  • sdkconfig file (attach the sdkconfig file from your project folder)
  • elf file in the build folder (note this may contain all the code details and symbols of your project.)

other_items.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions