Skip to content

Conversation

@Y334275
Copy link
Contributor

@Y334275 Y334275 commented Feb 4, 2026

Summary

PSRAM buffers require explicit cache management when used with DMA, as DMA accesses physical memory directly, bypassing the CPU cache.

Before starting DMA transfer:

  • For an OUTGOING transfer (PSRAM -> Device): Call cache_writeback_addr() to flush dirty data from cache to PSRAM.
  • For an INCOMING transfer (Device -> PSRAM): Call cache_invalidate_addr() to invalidate cache lines, ensuring DMA can write to PSRAM.

This ensures cache coherence and correct data transmission in burst mode.

Impact

  • esp32s3 dma and dma-capable peripherals

Testing

Environment

  • OS/Framework: px4 with nuttx 12.12.0
  • Hardware: esp32s3 with icm42688p connected via spi

Test method

Added temporary debug logs in esp32s3_spi_dma_exchange to monitor transfer behavior.

Here is the code:

static void esp32s3_spi_dma_exchange(struct esp32s3_spi_priv_s *priv,
                                     const void *txbuffer,
                                     void *rxbuffer,
                                     uint32_t nwords)
{
  // ... existing code

  infodumpbuffer("transferred buffer", priv->dma_txdesc[0].pbuf, priv->dma_txdesc[0].ctrl & 0xfff);
  infodumpbuffer("received buffer", priv->dma_rxdesc[0].pbuf, priv->dma_rxdesc[0].ctrl & 0xfff);

  esp32s3_spi_clr_regbits(SPI_DMA_INT_ENA_REG(priv->config->id),
                          SPI_TRANS_DONE_INT_ENA_M);
}
Logs before fix
ESP-ROM:esp32s3-20210327
Build:Mar 27 202�ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0xb (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:2
load:0x3fc94eb0,len:0x22d0
load:0x40374000,len:0x8dac
load:0x50000000,len:0x20
SHA-256 comparison failed:
Calculated: 2e1352ca0449987b8cafdad9ab8bc6dc5b3724a77b06fdca48188b9d9771be73
Expected: 00000000204f0000000000000000000000000000000000000000000000000000
Attempting to boot anyway...
entry 0x40374a38
*** Booting NuttX ***
I (70) boot: chip revision: v0.2
I (70) boot: efuse block revision: v1.3
I (70) boot.esp32s3: Boot SPI Speed : 40MHz
I (71) boot.esp32s3: SPI Mode       : DIO
I (75) boot.esp32s3: SPI Flash Size : 4MB
I (78) boot: Enabling RNG early entropy source...
dram: lma 0x00000020 vma 0x3fc94eb0 len 0x22d0   (8912)
iram: lma 0x000022f8 vma 0x40374000 len 0x8dac   (36268)
rtc: lma 0x0000b0ac vma 0x50000000 len 0x20     (32)
padd: lma 0x0000b0d8 vma 0x00000000 len 0x4f20   (20256)
imap: lma 0x00010000 vma 0x42010000 len 0x14fd54 (1375572)
padd: lma 0x0015fd5c vma 0x00000000 len 0x29c    (668)
dmap: lma 0x00160000 vma 0x3c170000 len 0x59c64  (367716)
total segments stored 7
ABI (799) app_init: Application information:
I (799) app_init: Compile time:     Feb  4 2026 17:24:39
I (804) app_init: ELF file SHA256:  000000000...
I (804) app_init: ESP-IDF:          
I (805) sleep_gpio: Configure to isolate all GPIO pins in sleep state
I (812) sleep_gpio: Enable automatic switching of GPIO sleep configuration
esp32s3_spi_setfrequency: frequency=400000, actual=400000
esp32s3_spi_setbits: nbits=8
esp32s3_spi_setmode: mode=0
esp32s3_spi_setfrequency: frequency=400000, actual=400000
esp32s3_spi_setbits: nbits=8
esp32s3_spi_setmode: mode=0
esp32s3_spi_setmode: mode=0
esp32s3_spi_setbits: nbits=8
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0x40 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x95 and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0x1
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0x48 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x1 and recv=0xff
esp32s3_spi_poll_send: send=0xaa and recv=0xff
esp32s3_spi_poll_send: send=0x87 and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0x1
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0x1
esp32s3_spi_poll_send: send=0xff and recv=0xaa
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0x77 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0x1
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0x69 and recv=0xff
esp32s3_spi_poll_send: send=0x40 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0x1
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0x77 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0x1
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0x69 and recv=0xff
esp32s3_spi_poll_send: send=0x40 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0x7a and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0xc0
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0x80
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0x49 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xfe
esp32s3_spi_poll_send: send=0xff and recv=0x40
esp32s3_spi_poll_send: send=0xff and recv=0xe
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0x32
esp32s3_spi_poll_send: send=0xff and recv=0x5b
esp32s3_spi_poll_send: send=0xff and recv=0x59
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0x74
esp32s3_spi_poll_send: send=0xff and recv=0x7b
esp32s3_spi_poll_send: send=0xff and recv=0x7f
esp32s3_spi_poll_send: send=0xff and recv=0x80
esp32s3_spi_poll_send: send=0xff and recv=0xa
esp32s3_spi_poll_send: send=0xff and recv=0x40
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0x9d
esp32s3_spi_poll_send: send=0xff and recv=0xa6
esp32s3_spi_poll_send: send=0xff and recv=0x66
esp32s3_spi_setfrequency: frequency=20000000, actual=20000000
esp32s3_spi_poll_send: send=0xff and recv=0xff

NuttShell (NSH) NuttX-11.0.0
nsh> icm42688p start -s
esp32s3_spi_setfrequency: frequency=24000000, actual=26666666
esp32s3_spi_setmode: mode=3
esp32s3_spi_setbits: nbits=8
esp32s3_spi_dma_exchange: nwords=2
transferred buffer (0x3c1d53a0):
0000  f5 00                                            ..              
received buffer (0x3c1d53a0):
0000  f5 00 a0 41 d0 53 1d 3c 80 58 1d 3c 48 7b 17 3c  ...A.S.<.X.<H{.<
icm42688p unexpected WHO_AM_I 0x00
esp32s3_spi_setmode: mode=3
esp32s3_spi_setbits: nbits=8
esp32s3_spi_dma_exchange: nwords=2
transferred buffer (0x3c1d53a0):
0000  f6 00                                            ..              
received buffer (0x3c1d53a0):
0000  f6 00 a0 41 d0 53 1d 3c 80 58 1d 3c 48 7b 17 3c  ...A.S.<.X.<H{.<
esp32s3_spi_setmode: mode=3
esp32s3_spi_setbits: nbits=8
esp32s3_spi_dma_exchange: nwords=2
transferred buffer (0x3c1d53a0):
0000  f5 00                                            ..              
received buffer (0x3c1d53a0):
0000  f5 00 a0 41 d0 53 1d 3c 80 58 1d 3c 48 7b 17 3c  ...A.S.<.X.<H{.<
icm42688p unexpected WHO_AM_I 0x00
esp32s3_spi_setmode: mode=3
esp32s3_spi_setbits: nbits=8
esp32s3_spi_dma_exchange: nwords=2
transferred buffer (0x3c1d53a0):
0000  f6 00                                            ..              
received buffer (0x3c1d53a0):
0000  f6 00 a0 41 d0 53 1d 3c 80 58 1d 3c 48 7b 17 3c  ...A.S.<.X.<H{.<
esp32s3_spi_setmode: mode=3
esp32s3_spi_setbits: nbits=8
esp32s3_spi_dma_exchange: nwords=2
transferred buffer (0x3c1d53a0):
0000  f5 00                                            ..              
received buffer (0x3c1d53a0):
0000  f5 00 a0 41 d0 53 1d 3c 80 58 1d 3c 48 7b 17 3c  ...A.S.<.X.<H{.<
icm42688p unexpected WHO_AM_I 0x00
esp32s3_spi_setmode: mode=3
esp32s3_spi_setbits: nbits=8
esp32s3_spi_dma_exchange: nwords=2
transferred buffer (0x3c1d53a0):
0000  f6 00                                            ..              
received buffer (0x3c1d53a0):
0000  f6 00 a0 41 d0 53 1d 3c 80 58 1d 3c 48 7b 17 3c  ...A.S.<.X.<H{.<
icm42688p probe failed
icm42688p SPI::init failed (-1)
ERROR [SPI_I2C] icm42688p: no instance started (no device on bus?)
nsh> 
Logs after fix
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0xb (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:2
load:0x3fc94eb0,len:0x22d0
load:0x40374000,len:0x8dac
load:0x50000000,len:0x20
SHA-256 comparison failed:
Calculated: ee29b22b9d8744b1bf5168fc0818892967f8c1a94ea69183a22d6aa00d2b0674
Expected: 00000000204f0000000000000000000000000000000000000000000000000000
Attempting to boot anyway...
entry 0x40374a38
*** Booting NuttX ***
I (70) boot: chip revision: v0.2
I (70) boot: efuse block revision: v1.3
I (70) boot.esp32s3: Boot SPI Speed : 40MHz
I (71) boot.esp32s3: SPI Mode       : DIO
I (75) boot.esp32s3: SPI Flash Size : 4MB
I (78) boot: Enabling RNG early entropy source...
dram: lma 0x00000020 vma 0x3fc94eb0 len 0x22d0   (8912)
iram: lma 0x000022f8 vma 0x40374000 len 0x8dac   (36268)
rtc: lma 0x0000b0ac vma 0x50000000 len 0x20     (32)
padd: lma 0x0000b0d8 vma 0x00000000 len 0x4f20   (20256)
imap: lma 0x00010000 vma 0x42010000 len 0x14fd88 (1375624)
padd: lma 0x0015fd90 vma 0x00000000 len 0x268    (616)
dmap: lma 0x00160000 vma 0x3c170000 len 0x59c64  (367716)
total segments stored 7
ABI (799) app_init: Application information:
I (799) app_init: Compile time:     Feb  4 2026 17:29:18
I (804) app_init: ELF file SHA256:  000000000...
I (804) app_init: ESP-IDF:          
I (805) sleep_gpio: Configure to isolate all GPIO pins in sleep state
I (812) sleep_gpio: Enable automatic switching of GPIO sleep configuration
esp32s3_spi_setfrequency: frequency=400000, actual=400000
esp32s3_spi_setbits: nbits=8
esp32s3_spi_setmode: mode=0
esp32s3_spi_setfrequency: frequency=400000, actual=400000
esp32s3_spi_setbits: nbits=8
esp32s3_spi_setmode: mode=0
esp32s3_spi_setmode: mode=0
esp32s3_spi_setbits: nbits=8
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0x40 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x95 and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0x1
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0x48 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x1 and recv=0xff
esp32s3_spi_poll_send: send=0xaa and recv=0xff
esp32s3_spi_poll_send: send=0x87 and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0x1
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0x1
esp32s3_spi_poll_send: send=0xff and recv=0xaa
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0x77 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0x1
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0x69 and recv=0xff
esp32s3_spi_poll_send: send=0x40 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0x1
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0x77 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0x1
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0x69 and recv=0xff
esp32s3_spi_poll_send: send=0x40 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0x7a and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0xc0
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0x80
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0x49 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0x0 and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0xff
esp32s3_spi_poll_send: send=0xff and recv=0xfe
esp32s3_spi_poll_send: send=0xff and recv=0x40
esp32s3_spi_poll_send: send=0xff and recv=0xe
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0x32
esp32s3_spi_poll_send: send=0xff and recv=0x5b
esp32s3_spi_poll_send: send=0xff and recv=0x59
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0x74
esp32s3_spi_poll_send: send=0xff and recv=0x7b
esp32s3_spi_poll_send: send=0xff and recv=0x7f
esp32s3_spi_poll_send: send=0xff and recv=0x80
esp32s3_spi_poll_send: send=0xff and recv=0xa
esp32s3_spi_poll_send: send=0xff and recv=0x40
esp32s3_spi_poll_send: send=0xff and recv=0x0
esp32s3_spi_poll_send: send=0xff and recv=0x9d
esp32s3_spi_poll_send: send=0xff and recv=0xa6
esp32s3_spi_poll_send: send=0xff and recv=0x66
esp32s3_spi_setfrequency: frequency=20000000, actual=20000000
esp32s3_spi_poll_send: send=0xff and recv=0xff

NuttShell (NSH) NuttX-11.0.0
nsh> icm42688p start -s
esp32s3_spi_setfrequency: frequency=24000000, actual=26666666
esp32s3_spi_setmode: mode=3
esp32s3_spi_setbits: nbits=8
esp32s3_spi_dma_exchange: nwords=2
transferred buffer (0x3c1d53a0):
0000  00 00                                            ..              
received buffer (0x3c1d53a0):
0000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
icm42688p unexpected WHO_AM_I 0x00
esp32s3_spi_setmode: mode=3
esp32s3_spi_setbits: nbits=8
esp32s3_spi_dma_exchange: nwords=2
transferred buffer (0x3c1d53a0):
0000  00 00                                            ..              
received buffer (0x3c1d53a0):
0000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
esp32s3_spi_setmode: mode=3
esp32s3_spi_setbits: nbits=8
esp32s3_spi_dma_exchange: nwords=2
transferred buffer (0x3c1d53a0):
0000  00 47                                            .G              
received buffer (0x3c1d53a0):
0000  00 47 00 00 00 00 00 00 00 00 00 00 00 00 00 00  .G..............
icm42688p on SPI bus 2 at 38 (24000 KHz)
esp32s3_spi_setmode: mode=3
esp32s3_spi_setbits: nbits=8
esp32s3_spi_dma_exchange: nwords=2
transferred buffer (0x3c1d5418):
0000  00 00                                            ..              
received buffer (0x3c1d5418):
0000  00 00 00 00 00 00 00 00 dd d0 14 82 50 54 1d 3c  ............PT.<
icm42688p #0 on SPI bus 2
esp32s3_spi_setmode: mode=3
esp32s3_spi_setbits: nbits=8
esp32s3_spi_dma_exchange: nwords=2
transferred buffer (0x3c1d5410):
0000  00 07                                            ..              
received buffer (0x3c1d5410):
0000  00 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
nsh> esp32s3_spi_setmode: mode=3

Log comparison shows the fix is working:

  • Before fix: The buffer content remains unchanged (0xf5 0x00 and 0xf6 0x00), indicating DMA failed to write data to the buffer (or read from it).
  • After fix: The buffer content is overwritten with new data, confirming that DMA successfully transferred data to/from the buffer.

defconfig shown below:

defconfig
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_MMCSD_HAVE_CARDDETECT is not set
# CONFIG_MMCSD_HAVE_WRITEPROTECT is not set
# CONFIG_MMCSD_MMCSUPPORT is not set
# CONFIG_NSH_DISABLE_DATE is not set
# CONFIG_SPI_CALLBACK is not set
CONFIG_ALLOW_BSD_COMPONENTS=y
CONFIG_ARCH="xtensa"
CONFIG_ARCH_BOARD_COMMON=y
CONFIG_ARCH_BOARD_CUSTOM=y
CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/espressif/esp32s3/nuttx-config"
CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y
CONFIG_ARCH_BOARD_CUSTOM_NAME=""
CONFIG_ARCH_CHIP="esp32s3"
CONFIG_ARCH_CHIP_ESP32S3=y
CONFIG_ARCH_CHIP_ESP32S3WROOM1N4=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_STACKDUMP=y
CONFIG_ARCH_XTENSA=y
CONFIG_BOARDCTL_MKRD=y
CONFIG_BOARDCTL_RESET=y
CONFIG_BOARD_LOOPSPERMSEC=16717
CONFIG_BUILTIN=y
CONFIG_CDCACM=y
CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_SPI=y
CONFIG_DEBUG_SPI_ERROR=y
CONFIG_DEBUG_SPI_INFO=y
CONFIG_DEBUG_SPI_WARN=y
CONFIG_DEFAULT_TASK_STACKSIZE=3072
CONFIG_DEV_FIFO_SIZE=0
CONFIG_DEV_PIPE_MAXSIZE=1024
CONFIG_DEV_PIPE_SIZE=70
CONFIG_DEV_URANDOM=y
CONFIG_DRIVERS_IEEE80211=y
CONFIG_DRIVERS_WIRELESS=y
CONFIG_ELF=y
CONFIG_ESP32S3_GPIO_IRQ=y
CONFIG_ESP32S3_I2C0=y
CONFIG_ESP32S3_I2C1=y
CONFIG_ESP32S3_I2CTIMEOSEC=1
CONFIG_ESP32S3_OTG=y
CONFIG_ESP32S3_RT_TIMER=y
CONFIG_ESP32S3_SPI2=y
CONFIG_ESP32S3_SPI2_CLKPIN=7
CONFIG_ESP32S3_SPI2_CSPIN=6
CONFIG_ESP32S3_SPI2_MISOPIN=16
CONFIG_ESP32S3_SPI2_MOSIPIN=15
CONFIG_ESP32S3_SPI3=y
CONFIG_ESP32S3_SPI3_CLKPIN=40
CONFIG_ESP32S3_SPI3_CSPIN=38
CONFIG_ESP32S3_SPI3_MISOPIN=41
CONFIG_ESP32S3_SPI3_MOSIPIN=39
CONFIG_ESP32S3_SPIFLASH=y
CONFIG_ESP32S3_SPIRAM=y
CONFIG_ESP32S3_SPIRAM_MODE_OCT=y
CONFIG_ESP32S3_SPI_DMA=y
CONFIG_ESP32S3_SPI_DMATHRESHOLD=0
CONFIG_ESP32S3_SPI_SWCS=y
CONFIG_ESP32S3_SPI_UDCS=y
CONFIG_ESP32S3_UART0=y
CONFIG_ESP32S3_UART1=y
CONFIG_ESP32S3_UART1_RXPIN=42
CONFIG_ESP32S3_UART1_TXPIN=45
CONFIG_ESP32S3_UART2=y
CONFIG_ESP32S3_UART2_RXPIN=3
CONFIG_ESP32S3_UART2_TXPIN=8
CONFIG_ETC_CROMFS=y
CONFIG_ETC_ROMFS=y
CONFIG_EXAMPLES_CALIB_UDELAY=y
CONFIG_FAT_DMAMEMORY=y
CONFIG_FAT_LCNAMES=y
CONFIG_FAT_LFN=y
CONFIG_FAT_LFN_ALIAS_HASH=y
CONFIG_FAT_LFN_UTF8=y
CONFIG_FS_BINFS=y
CONFIG_FS_CROMFS=y
CONFIG_FS_FAT=y
CONFIG_FS_FATTIME=y
CONFIG_FS_PROCFS=y
CONFIG_FS_PROCFS_REGISTER=y
CONFIG_FS_ROMFS=y
CONFIG_FS_SPIFFS=y
CONFIG_GRAN=y
CONFIG_GRAN_INTR=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_I2C_DRIVER=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=3072
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INIT_STACKSIZE=6144
CONFIG_INTELHEX_BINARY=y
CONFIG_IOB_NBUFFERS=36
CONFIG_IOB_NCHAINS=36
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_MMCSD=y
CONFIG_MM_IOB=y
CONFIG_MM_REGIONS=2
CONFIG_MTD_RAMTRON=y
CONFIG_NAME_MAX=48
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_DISABLE_BASENAME=y
CONFIG_NSH_DISABLE_CMP=y
CONFIG_NSH_DISABLE_DIRNAME=y
CONFIG_NSH_DISABLE_HEXDUMP=y
CONFIG_NSH_DISABLE_LOSETUP=y
CONFIG_NSH_DISABLE_MKFIFO=y
CONFIG_NSH_DISABLE_MKRD=y
CONFIG_NSH_DISABLE_PRINTF=y
CONFIG_NSH_DISABLE_PUT=y
CONFIG_NSH_DISABLE_TRUNCATE=y
CONFIG_NSH_DISABLE_UNAME=y
CONFIG_NSH_DISABLE_WGET=y
CONFIG_NSH_DISABLE_XD=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_MAXARGUMENTS=15
CONFIG_NSH_NESTDEPTH=8
CONFIG_NSH_READLINE=y
CONFIG_NSH_VARS=y
CONFIG_PIPES=y
CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_TYPES=y
CONFIG_PTHREAD_STACK_MIN=512
CONFIG_PWM=y
CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=10
CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=10
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=114688
CONFIG_RAM_START=0x20000000
CONFIG_RAW_BINARY=y
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_READLINE_CMD_HISTORY_LEN=4
CONFIG_READLINE_CMD_HISTORY_LINELEN=64
CONFIG_READLINE_TABCOMPLETION=y
CONFIG_SCHED_BACKTRACE=y
CONFIG_SCHED_HPWORK=y
CONFIG_SCHED_HPWORKPRIORITY=249
CONFIG_SCHED_INSTRUMENTATION=y
CONFIG_SCHED_INSTRUMENTATION_SWITCH=y
CONFIG_SCHED_LPWORK=y
CONFIG_SCHED_LPWORKPRIOMAX=178
CONFIG_SCHED_LPWORKSTACKSIZE=2048
CONFIG_SCHED_WAITPID=y
CONFIG_SEM_PREALLOCHOLDERS=32
CONFIG_SERIAL_TERMIOS=y
CONFIG_SIG_DEFAULT=y
CONFIG_SIG_SIGALRM_ACTION=y
CONFIG_SIG_SIGUSR1_ACTION=y
CONFIG_SIG_SIGUSR2_ACTION=y
CONFIG_SPIFFS_NAME_MAX=48
CONFIG_SPINLOCK=y
CONFIG_SPI_DRIVER=y
CONFIG_STACK_COLORATION=y
CONFIG_START_DAY=30
CONFIG_START_MONTH=11
CONFIG_STDIO_BUFFER_SIZE=32
CONFIG_SYSTEM_CDCACM=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_NSH_STACKSIZE=2000
CONFIG_TASK_NAME_SIZE=24
CONFIG_TLS_TASK_NELEM=4
CONFIG_UART0_SERIAL_CONSOLE=y
CONFIG_USEC_PER_TICK=1000
CONFIG_WQUEUE_NOTIFIER=y

PSRAM buffers require explicit cache management when used with DMA,
as DMA accesses physical memory directly, bypassing the CPU cache.

Before starting DMA transfer:
- For an **OUTGOING** transfer (PSRAM -> Device):
  Call `cache_writeback_addr()` to flush dirty data from cache to PSRAM.
- For an **INCOMING** transfer (Device -> PSRAM):
  Call `cache_invalidate_addr()` to invalidate cache lines, ensuring DMA can write to PSRAM.

This ensures cache coherence and correct data transmission in burst mode.

Signed-off-by: liu <liu334275@gmail.com>
@github-actions github-actions bot added Arch: xtensa Issues related to the Xtensa architecture Size: XS The size of the change in this PR is very small labels Feb 4, 2026
@jerpelea jerpelea changed the title arch/esp32s3/dma: Fix data transmission failure when buffer is in PSRAM arch/xtensa/esp32s3: Fix data transmission failure when buffer is in PSRAM Feb 4, 2026
@Y334275
Copy link
Contributor Author

Y334275 commented Feb 4, 2026

Don't merge yet, seems like there is another issue.

@tmedicci tmedicci marked this pull request as draft February 4, 2026 14:56
@tmedicci
Copy link
Contributor

tmedicci commented Feb 4, 2026

Don't merge yet, seems like there is another issue.

I converted to Draft to avoid it being merged. Please let me know if you find out the new issue and I will proceed to review it ;)

@Y334275
Copy link
Contributor Author

Y334275 commented Feb 4, 2026

According to ESP32-S3 Technical Reference Manual section 3.4.9 "Accessing External RAM":

Note: For receive descriptors, if the data length received are not aligned with block size, GDMA will pad the
data received with 0 until they are aligned to initiate burst transfer. You can read the length field in receive
descriptors to obtain the length of valid data received.

This behavior can overwrite bytes after pbuf when len is not aligned to the block size.
Therefore, we need a way to preserve/restore the overwritten data.
Currently, I don't have a good solution for this.

@linguini1
Copy link
Contributor

Today I learned about those arrow drop-downs you used for the logs. Great idea, makes it much easier to scroll! Thank you :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Arch: xtensa Issues related to the Xtensa architecture Size: XS The size of the change in this PR is very small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants