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

Mismatch Between SPI2_HOST and REG_SPI_BASE Macro Causes Hardware SPI Crash on ESP32-C3 #10908

Closed
1 task done
dsmng54 opened this issue Jan 27, 2025 · 1 comment
Closed
1 task done
Labels
Status: Awaiting triage Issue is waiting for triage

Comments

@dsmng54
Copy link

dsmng54 commented Jan 27, 2025

Board

Custom board based on ESP32-C3

Device Description

A custom-designed board using the ESP32-C3 chip.

Hardware Configuration

  • ST7735 TFT LCD:
    • LED+: GPIO4
    • RESET: GPIO7
    • DC: GPIO5
    • CS: GPIO10 (hardware SPI CS)
    • SDA (MOSI): GPIO2 (hardware SPI MOSI)
    • SCK: GPIO6 (hardware SPI SCK)

Version

latest master (checkout manually)

IDE Name

VSCode + PlatformIO

Operating System

Windows 11

Flash frequency

80Mhz

PSRAM enabled

no

Upload speed

115200

Description

I encountered a crash when using the TFT_eSPI library with hardware SPI on my custom ESP32-C3 board. The issue stems from a mismatch between the SPI2_HOST enumeration value in the HAL headers and the REG_SPI_BASE macro in soc.h. Specifically:

  1. In .platformio\packages\framework-arduinoespressif32\tools\sdk\esp32c3\include\hal\include\hal\spi_types.h:

    typedef enum {
        SPI1_HOST = 0, ///< SPI1
        SPI2_HOST = 1, ///< SPI2
    #if SOC_SPI_PERIPH_NUM > 2
        SPI3_HOST = 2, ///< SPI3
    #endif
    } spi_host_device_t;

    Here, SPI2_HOST is defined as 1.

  2. In .platformio\packages\framework-arduinoespressif32\tools\sdk\esp32c3\include\soc\esp32c3\include\soc\soc.h, the REG_SPI_BASE macro is defined as:

    #define REG_SPI_BASE(i) (((i) == 2) ? (DR_REG_SPI2_BASE) : (0)) // only one GPSPI

    The macro checks for i == 2, which does not align with the value of SPI2_HOST (1). As a result, the base address for SPI2 is incorrectly resolved to 0x00000000, causing invalid memory access.

During initialization of the TFT_eSPI library, the SPI_BUSY_CHECK macro dereferences _spi_cmd, which points to SPI_CMD_REG(SPI_PORT). Since REG_SPI_BASE(SPI_PORT) evaluates to 0x00000000, _spi_cmd becomes a null pointer, leading to a crash.


Expected Behavior

REG_SPI_BASE(SPI2_HOST) should return the correct base address (0x60024000) for SPI2 on ESP32-C3 devices.


Observed Behavior

REG_SPI_BASE(SPI2_HOST) returns 0x00000000, causing invalid memory access during SPI register interaction.


Steps to Reproduce

  1. Use a custom ESP32-C3 board or development module.
  2. Connect an ST7735 display with the following hardware SPI pinout:
    • MOSI: GPIO2
    • SCK: GPIO6
    • CS: GPIO10
    • DC: GPIO5
    • RESET: GPIO7
  3. Use the TFT_eSPI library (latest version) with the ESP32-C3 hardware SPI setup.
  4. Call tft.init(); in the setup code.
  5. Observe the crash during initialization with the following serial output:
    Hello! ST7735 TFT TestGuru Meditation Error: Core  0 panic'ed (Store access fault). Exception was unhandled.
    ......
    

Additional Notes

The relevant macro is in TFT_eSPI\Processors\TFT_eSPI_ESP32_C3.h, where SPI_PORT is defined as:

#define SPI_PORT SPI2_HOST

This sets SPI_PORT to SPI2_HOST, whose value is 1. However, the REG_SPI_BASE macro in soc.h evaluates i == 2 for SPI2 base address resolution, creating the mismatch.

Debugging confirmed that REG_SPI_BASE(SPI_PORT) resolves to 0x00000000 instead of the expected 0x60024000.


Workaround

Manually redefine the REG_SPI_BASE macro in the local environment to align with the enumeration values:

#define REG_SPI_BASE(i) (((i) == SPI2_HOST) ? (DR_REG_SPI2_BASE) : (0))

This resolves the issue and allows the display to initialize and function correctly.

Sketch

#include <TFT_eSPI.h> // Hardware-specific library
#include <SPI.h>

TFT_eSPI tft = TFT_eSPI();       // Invoke custom library

void setup(void) {
  Serial.begin(9600);
  Serial.print("Hello! ST7735 TFT Test");
  // Use this initializer if you're using a 1.8" TFT
  tft.init();
}

void loop() {
}

Debug Message

ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x3 (RTC_SW_SYS_RST),boot:0xd (SPI_FAST_FLASH_BOOT)
Saved PC:0x40381f68
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5810,len:0x438
load:0x403cc710,len:0x90c
load:0x403ce710,len:0x2624
entry 0x403cc710
Hello! ST7735 TFT TestGuru Meditation Error: Core  0 panic'ed (Store access fault). Exception was unhandled.

Core  0 register dump:
MEPC    : 0x42001d64  RA      : 0x42001d54  SP      : 0x3fc95d70  GP      : 0x3fc8c400
TP      : 0x3fc86dd0  T0      : 0x00000003  T1      : 0xffc3ffff  T2      : 0x00000020
S0/FP   : 0x60004000  S1      : 0x3fc8d960  A0      : 0x00000001  A1      : 0xffffffff
A2      : 0x00000000  A3      : 0x00000000  A4      : 0x08000000  A5      : 0x00000010
A6      : 0xffffffff  A7      : 0x04c4b400  S2      : 0x00000000  S3      : 0x00000001
S4      : 0x00000000  S5      : 0x00000000  S6      : 0x00000000  S7      : 0x00000000
S8      : 0x00000000  S9      : 0x00000000  S10     : 0x00000000  S11     : 0x00000000
T3      : 0x0196e6aa  T4      : 0x0000000f  T5      : 0x003c0000  T6      : 0x00000003
MSTATUS : 0x00001881  MTVEC   : 0x40380001  MCAUSE  : 0x00000007  MTVAL   : 0x00000010
MHARTID : 0x00000000

Stack memory:
3fc95d70: 0x00000000 0x3fc8f000 0x019bfcc0 0x00000001 0x00000000 0x3fc8f000 0x3fc8d960 0x420022fa
3fc95d90: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x3fc8f000 0x3fc8e000 0x00000000
3fc95db0: 0x00000000 0x3fc8f000 0x00000000 0x42005050 0x00000000 0x00000000 0x00000000 0x40387c8c
3fc95dd0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc95df0: 0xa5a5a5a5 0xa5a5a5a5 0xbaad5678 0x00000160 0xabba1234 0x00000154 0x3fc95c80 0x16a3c07e
3fc95e10: 0x3fc8e6ac 0x3fc8e6ac 0x3fc95e08 0x3fc8e6a4 0x00000018 0x42c8cf71 0x16467c9e 0x3fc95e08
3fc95e30: 0x00000000 0x00000001 0x3fc93df8 0x706f6f6c 0x6b736154 0x367c3a00 0x009b3e1d 0x00000000
3fc95e50: 0x3fc95df0 0x00000001 0x00000002 0x00000000 0x00000000 0x00000000 0x3fc8fda4 0x3fc8fe0c
3fc95e70: 0x3fc8fe74 0x00000000 0x00000000 0x00000001 0x00000000 0x00000000 0x00000000 0x4201d4c2
3fc95e90: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc95eb0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc95ed0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc95ef0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc95f10: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc95f30: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc95f50: 0x00000000 0x00000000 0xe4000000 0xbaad5678 0x00000060 0xabba1234 0x00000054 0x00000000
3fc95f70: 0x3fc95f6c 0x00000000 0x00000000 0x00000000 0x3fc95f84 0xffffffff 0x3fc95f84 0x3fc95f84
3fc95f90: 0x00000000 0x3fc95f98 0xffffffff 0x3fc95f98 0x3fc95f98 0x00000001 0x00000001 0x00000000
3fc95fb0: 0x7f00ffff 0x00000000 0xb33fffff 0x00000000 0xbaad5678 0x00000160 0xabba1234 0x00000154
3fc95fd0: 0x3fc96024 0x3fc96024 0x3fc96124 0x3fc96123 0x00000000 0x3fc95fe8 0xffffffff 0x3fc95fe8
3fc95ff0: 0x3fc95fe8 0x00000000 0x3fc95ffc 0xffffffff 0x3fc95ffc 0x3fc95ffc 0x00000000 0x00000100
3fc96010: 0x00000001 0xbe00ffff 0x00000000 0xb33fffff 0x00000000 0xe17f1fdf 0x2fe2e4e8 0xdc729d1c
3fc96030: 0xadf8d73e 0x13d17e81 0x4c292e24 0x2fe2e22f 0x6a6c69bd 0xa584e84e 0x1f17f15c 0x984b20a2
3fc96050: 0x845fc7c7 0x12fe3e72 0xc05379e1 0x1d35f448 0x50ed8a5d 0xcbf8b80e 0xb522a305 0x3ee70cd5
3fc96070: 0x85fc7fa6 0x481fb091 0x0934a89d 0xf1f256cb 0xe303ed97 0x0dec782f 0x13d6d0b3 0xc6fa617f
3fc96090: 0xf13d6c5f 0xfc4fa617 0x03450b65 0x717f1729 0x4bdc1549 0x77434aac 0xc6392298 0x59b37463
3fc960b0: 0xe0e4a969 0xe20100be 0x3a25cdd3 0xe26a6a9f 0x5a642fe3 0x388bdc20 0x81fd4f41 0x32fc97f1
3fc960d0: 0x49197f14 0x65fc7f7c 0x9ca3a68b 0xf17296f6 0xfe325e97 0x77719238 0x7139a5fc 0x50cbf8d0
3fc960f0: 0xb3c5fc57 0x05fc7fba 0x5fc77678 0xdf6ffca6 0xd94ee2b9 0x0bf8ee1c 0x4b85c7c7 0xdfcf6fa0
3fc96110: 0x49197f17 0x416a5da0 0x2fe203d9 0x876e529e 0xaeded3da 0xbaad5678 0x000000f8 0xabba1234
3fc96130: 0x000000ec 0x00000100 0x00000100 0x00000002 0x40384ee2 0x403849d8 0x403842cc 0x40384e86
3fc96150: 0x40384e6a 0x3fc96246 0x3fc96246 0x3fc96246 0x3fc96246 0x3fc96230 0x3fc96330 0x00000000



ELF file SHA256: fa6ce7040d88d587

Rebooting...

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@dsmng54 dsmng54 added the Status: Awaiting triage Issue is waiting for triage label Jan 27, 2025
@me-no-dev
Copy link
Member

We are aware of this issue and have it fixed locally wherever we also need to access the peripheral directly. The issue though comes from ESP-IDF and there have been attempts to prompt them to fix it in their headers by various parties, but they have so far refused to make the change. I suggest you post an issue there and make another attempt. Maybe with more people involved they will be persuaded to do it, or at least explain why they will not. There is nothing else we can do on our end. There is also the option that the library also adds the changes locally to their code, like we have done on our side https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/Esp.cpp#L76-L81

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Awaiting triage Issue is waiting for triage
Projects
None yet
Development

No branches or pull requests

2 participants