Previous Up No next

Diary, August 2026



Sun Mon Tue Wed Thu Fri Sat
                          1
  2   3   4   5   6   7   8
  9  10  11  12  13  14  15
 16  17  18  19  20  21  22
 23  24  25  26  27  28  29
 30  31


Wednesday, August 5, 2026

UARTs on the ESP32-S3

Here, I present some information about the low-level operation of the Universal Asynchronous Receiver/Transmitters (UARTs) on the ESP32-S3. I want to investigate how to use them without enabling interrupts. I know that for some devices it is possible to enable an interrupt, causing a flag to be set in the interrupt register, but leave the interrupt table empty, such that no actual interrupt is generated. An important source of information is Chapter 26: 'UART Controller' of the Technical Reference Manual. The ESP32-S3 has three UARTs each. The transmit and receive buffers are taken from a shared 1024 byte region of RAM, which is divided into 8 blocks of 128 bytes. The buffers start at fixed block. This makes it possible to have larger transmit and receive buffers for some of the UARTs, but limiting the buffers for others to zero, which basically renders the UART (parly) unusable. The buffers of UART2 can be extended to 256 bytes without affecting the operations of UART0 and UART1 with at least buffers of 128 bytes. (The use of the words 'Reserved' in Figure 26-3 are a bit misleading, because the RAM regions can be used.) There is a possibility to transfer large amounts of data by setting up a Direct Memory Access (DMA) channel in the General Direct Memory Access (GDMA) device, which is described in Chapter 3: 'GMDA Controller'. However the data goes through a Universal Host Controller Interface (UHCI), which, for example, is used with USB. The UHCI performs some encoding and decoding to create a 'clean' data stream surrounded with separators. It is not clear when an UART starts sending data from the buffer. Is it as soon as a character is entered or only when the buffer is filled with a certain number of characters and/or when a certain character (such as a line-feed) is placed in the buffer. In the reference manual it mentions that setting the UART_FORCE_XON bit forces the transmitter to send data. This is only set in the uart_ll_force_xon functions, which is called in sleep_uart_resume function, which is called when the MCU returns from sleep mode. This makes me wonder whether this is the only proper usage of it. For the ESP32-S3 the function uart_ll_force_xon also the sets the UART_SW_FLOW_CON_EN bit. In the reference manual it says: 'Set this bit to enable software flow control.' That is maybe something you do not want to be enabled, because it only works if the other side on the serial connection also has it enabled with the same characters.


Thursday, August 6, 2026

High resolution LCDs with ESP32-S3

ESP-IDF offers various ways to control common LCDs according to the documentation. For full screen updates, the theoretical maximum frame rate is determined by the clock frequency multiplied by the bus width and divided by the product of the number of pixela and the number of bits per pixel. In practice it can be a bit lower, because most protocols also have some overhead. Because for high resolution LCD the required screen buffer is usually too large to fit in RAM, it means that it has to be placed in PSRAM. Depending on the width of the SPI bus used to access PSRAM, this can pose limits on the maximum clock frequency. Modifying the buffer in PSRAM also put some limits on how often one can effectively update the display. ESP-IDF provides only a limited number of LCD device controller drivers out of the box. More drivers are available in the ESP Component Registry. A list of drivers that is supported by LVGL is given in Display and touchpad drivers for ESP32 using LVGL. For the ESP32-S3 there are several interfaces that can be used with displays, such as I2C, SPI, several parallel interfaces, and (the newest) MIPI-DSI, which is not supported by the ESP32-S3. (It is supported by the ESP32-P4, which is now declared end-of-life and followed up by ESP32-P4X.) For the parallel interfaces, I spend some time looking into the LCD controller of the ESP32-S3. According to Chapter 29 '29 LCD and Camera Controller (LCD_CAM)' of the Technical Reference Manual it has three parallel output formats: RGB, MOTO6080, and I8080. There is a choice between 8 or 16 bits data bit. Besides this, each requires a some other signals, 4 for the RGB, 2 for MOTO6800, and 3 for I8080. The number of bins thus ranges from 10 to 20. (It seems that the with the LCD_DE signal in Figure 29-5 'LCD Timing (RGB Format)' is refering to LCD_H_ENABLE.) The maximum data rate is the same for both bus widths, because it is limited by GDMA and further if YUV-RGB format conversion is used. If we assume that 2 bytes per pixel are used, it means that the maximum frame rate for a 800×480 display is 104 without YUV-RGB format conversion and 78 with. In practice this will be bit lower.


This months interesting links


Home | July 2026