Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 29 additions & 15 deletions Documentation/components/drivers/special/ioexpander.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,64 +62,78 @@ routine in the header of the same name under
* - Awinic AW9523B
- I2C
- 16
- ``IOEXPANDER_AW9523B``
- ``CONFIG_IOEXPANDER_AW9523B``
* - WCH CH422G
- I2C
- 12
- ``CONFIG_IOEXPANDER_CH422G``
* - iC-Haus iC-JX
- SPI
- 16
- ``IOEXPANDER_ICJX``
- ``CONFIG_IOEXPANDER_ICJX``
* - ISO1H812G
- SPI
- 8
- ``IOEXPANDER_ISO1H812G``
- ``CONFIG_IOEXPANDER_ISO1H812G``
* - ISO1I813T
- SPI
- 8
- ``IOEXPANDER_ISO1I813T``
- ``CONFIG_IOEXPANDER_ISO1I813T``
* - Microchip MCP23008 / MCP23S08
- I2C
- 8
- ``IOEXPANDER_MCP23X08``
- ``CONFIG_IOEXPANDER_MCP23X08``
* - Microchip MCP23017 / MCP23S17
- I2C
- 16
- ``IOEXPANDER_MCP23X17``
- ``CONFIG_IOEXPANDER_MCP23X17``
* - NXP PCA9538
- I2C
- 8
- ``IOEXPANDER_PCA9538``
- ``CONFIG_IOEXPANDER_PCA9538``
* - NXP PCA9555
- I2C
- 16
- ``IOEXPANDER_PCA9555``
- ``CONFIG_IOEXPANDER_PCA9555``
* - NXP PCA9557
- I2C
- 8
- ``IOEXPANDER_PCA9557``
- ``CONFIG_IOEXPANDER_PCA9557``
* - PCF8574
- I2C
- 8
- ``IOEXPANDER_PCF8574``
- ``CONFIG_IOEXPANDER_PCF8574``
* - PCF8575
- I2C
- 16
- ``IOEXPANDER_PCF8575``
- ``CONFIG_IOEXPANDER_PCF8575``
* - Diodes PI4IOE5V6408
- I2C
- 8
- ``IOEXPANDER_PI4IOE5V6408``
- ``CONFIG_IOEXPANDER_PI4IOE5V6408``
* - Semtech SX1509
- I2C
- 16
- ``IOEXPANDER_SX1509``
- ``CONFIG_IOEXPANDER_SX1509``
* - TCA6408 / TCA6416 / TCA6424 / PCAL6416A
- I2C
- 8 / 16 / 24 / 16
- ``IOEXPANDER_TCA64XX``
- ``CONFIG_IOEXPANDER_TCA64XX``

Notes on individual drivers:

- ``IOEXPANDER_TCA64XX`` and ``IOEXPANDER_PCF8574`` additionally depend on
- ``CONFIG_IOEXPANDER_TCA64XX`` and ``CONFIG_IOEXPANDER_PCF8574`` additionally depend on
``CONFIG_EXPERIMENTAL``.
- ``CONFIG_IOEXPANDER_CH422G`` presents the eight bi-directional pins, IO0-IO7, as
pins 0-7 and the four open-drain outputs, OC0-OC3, as pins 8-11, so
``CONFIG_IOEXPANDER_NPINS`` must be at least 12. The device selects a
Comment thread
acassis marked this conversation as resolved.
register by the I2C address a transfer is addressed to rather than by a
register address written ahead of the data, and none of its write-only
registers can be read back, so the driver shadows them. IO0-IO7 share a
single direction control in the hardware: the driver records the direction
asked of each pin and puts the group in output mode once at least one of
them is an output. Reading a pin of a group held in output mode reports
the value last written, because the device cannot report the pin level.
- Drivers with a ``<device>_MULTIPLE`` option support more than one
instance of the same chip on a board.
- Drivers with a ``<device>_SHADOW_MODE`` option keep the output and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,42 @@ The board has a 7-inch LCD:
EXIO2 DISP Backlight enable pin
========= ======== =========================

The panel is an EK9716 driven over a 16-bit parallel RGB565 bus by the
LCD_CAM peripheral. Its timing is:

==================== =======
Parameter Value
==================== =======
Resolution 800x480
Pixel clock 16 MHz
HSYNC pulse width 4
HSYNC back porch 8
HSYNC front porch 8
VSYNC pulse width 4
VSYNC back porch 8
VSYNC front porch 8
==================== =======

The RGB bus takes most of the usable pins, so the panel reset and the
display enable are not wired to GPIOs. They hang off a CH422G I/O
expander, reached over the I2C bus shared with the touch controller:

========= ============ ==================================
Signal Connection Description
========= ============ ==================================
SDA GPIO8 I2C data, expander and touch
SCL GPIO9 I2C clock, expander and touch
TP_RST CH422G EXIO1 GT911 touch controller reset
DISP CH422G EXIO2 Display and backlight enable
LCD_RST CH422G EXIO3 Panel reset
SD_CS CH422G EXIO4 TF card chip select
USB_SEL CH422G EXIO5 USB / CAN transceiver select
========= ============ ==================================

A 800x480 RGB565 framebuffer is 768000 bytes and does not fit in internal
RAM, so any configuration that drives the panel must also enable the
onboard 8MB octal PSRAM and leave it in the common heap.

Configurations
==============

Expand All @@ -92,6 +128,50 @@ All of the configurations presented below can be tested by running the following
Configuration Directories
-------------------------

lcd
---

Brings up the onboard 7 inch 800x480 panel as a framebuffer character
driver at ``/dev/fb0``, on top of the ``usbnsh`` console. The CH422G I/O
expander is used to take the panel out of reset and to switch the display
on once the framebuffer exists, and the PSRAM the framebuffer is allocated
from is enabled.

Note that the console is on UART0, GPIO43 and GPIO44, reached through the
USB-to-UART bridge on the UART USB-C connector. It is deliberately not on
the native USB peripheral, because that is the connector a USB host
configuration drives.

``apps/examples/fb`` is included to prove the panel out. It reports the
geometry of the framebuffer it found and then draws a series of nested
rectangles over the whole display::

nsh> fb
VideoInfo:
fmt: 11
xres: 800
yres: 480
nplanes: 1
PlaneInfo (plane 0):
fbmem: 0x3c050040
fblen: 1536000
stride: 1600
display: 0
bpp: 16
Mapped FB: 0x3c050040
Use consecutive fbmem2 = 0x3c10b840, yoffset = 480
0: ( 0, 0) (800,480)
1: ( 72, 43) (656,394)
2: (144, 86) (512,308)
3: (216,129) (368,222)
4: (288,172) (224,136)
5: (360,215) ( 80, 50)
Test finished

The framebuffer is in PSRAM, which is why ``fbmem`` is in the 0x3c000000
range, and ``fblen`` is 1536000 rather than 768000 because the driver is
double buffered by default.

usbnsh
------

Expand Down
42 changes: 42 additions & 0 deletions arch/xtensa/src/esp32s3/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2650,6 +2650,48 @@ config ESP32S3_LCD_CLOCK_MHZ
int "LCD Pixel Clock Frequency in MHz"
default 2

config ESP32S3_LCD_BOUNCE_LINES
int "Bounce buffer height in lines (0 to disable)"
default 0
---help---
Scan the panel out of two small buffers in internal RAM, each this
many lines tall, refilled from the framebuffer as they are consumed,
rather than having the DMA read the framebuffer directly.

This matters when the framebuffer is in PSRAM. The DMA then has to
fetch every pixel from PSRAM in real time, and it is competing with
whatever else uses that memory; a CPU writing to the framebuffer, or
flushing it out of the cache, can stall those fetches for long
enough to empty the LCD FIFO. The panel sees the data stream
falter, and what shows up is an image that shakes and then rolls.

With a bounce buffer the only thing on the critical path is internal
RAM, which nothing else can stall. The copy from PSRAM happens in
the interrupt that follows each buffer being consumed and has a
whole buffer's worth of time to complete. This is the arrangement
the ESP-IDF RGB panel driver calls a bounce buffer.

The framebuffer must be a whole number of these buffers, so the
value has to divide the vertical resolution. Two buffers of this
size are taken out of internal RAM. Ten lines of an 800 pixel wide
panel at 16bpp costs 32000 bytes.

config ESP32S3_LCD_PCLK_ACTIVE_NEG
bool "Latch data on the falling edge of the pixel clock"
default n
---help---
By default the pixel clock is low during the first half of a cycle,
so the panel latches the data lines, and DE and the sync signals
with them, on the rising edge. Enable this for a panel that
expects the falling edge instead.

A panel driven on the wrong edge samples the sync signals at the
moment they change, which usually shows up as an image that is
recognisable but will not hold vertical lock.

This is the equivalent of pclk_active_neg in the ESP-IDF RGB panel
driver.

config ESP32S3_LCD_VFRONTPORCH
int "LCD Vertical Front Porch"
default 40
Expand Down
Loading
Loading