Hi,
I am having some difficulty getting GxEPD2 working on a Seeed XIAO ESP32-C3 development board. I have an Espressif S3 dev board that the same sketch works on. Here is the sketch that works on the S3 but not on the C3.
#define MAX_DISPLAY_BUFFER_SIZE 65536ul
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
GxEPD2_BW<GxEPD2_750_T7, MAX_HEIGHT(GxEPD2_750_T7)> display(GxEPD2_750_T7(...));
SPIClass hspi(HSPI);
void fill_black() {
display.setFullWindow();
display.firstPage();
do
{
display.fillScreen(GxEPD_BLACK);
}
while (display.nextPage());
}
void display_init() {
hspi.setHwCs(false);
hspi.begin(...);
display.epd2.selectSPI(hspi, SPISettings(4000000, MSBFIRST, SPI_MODE0));
display.init(115200);
display.setRotation(1); // portrait
Serial.println("display initialized");
}
void setup() {
Serial.begin(9600);
while(!Serial) {};
delay(3000);
display_init();
fill_black();
}
For the S3 development board, the sketch works properly with the following display constructor and SPI initialization call:
GxEPD2_BW<GxEPD2_750_T7, MAX_HEIGHT(GxEPD2_750_T7)> display(GxEPD2_750_T7(15, 1, 26, 4));
hspi.begin(13, 12, 14, 15);
For the XIAO C3 board, I've tried a few different things. I've tried to read the code for GxEPD2 very thoroughly to figure out what is going on at each step, but I must be missing something important. The current constructor I am using for the C3 is:
GxEPD2_BW<GxEPD2_750_T7, MAX_HEIGHT(GxEPD2_750_T7)> display(GxEPD2_750_T7(/* CS */ D7, /* DC */ D4, /* RST */ D5, /* BUSY */ D6));
D7 corresponds to GPIO 20, which is the hardware SPI chip/slave select. This is confirmed by following the define to Pins_Arduino.h, where both D7 == 20 and SS = 20 The other pin choices are pins that are not mapped to hardware SPI as far as I can tell (however, some of them are mapped to hardware I2C).
For the SPI initializer, I have tried the following to no success:
hspi.begin(13, 12, 14, 15);
hspi.begin(SCK, MISO, MOSI, SS);
hspi.begin(-1, -1, -1, -1);
hspi.begin(D8, D9, D10, D7);
My reasoning for the -1, -1, -1, -1 constructor was that in hspi.begin(), if all four pin arguments are -1, the function defaults to this branch:
#elif CONFIG_IDF_TARGET_ESP32C3
_sck = SCK;
_miso = MISO;
_mosi = MOSI;
_ss = SS;
Otherwise, it does this:
} else {
_sck = sck;
_miso = miso;
_mosi = mosi;
_ss = ss;
}
The two lines below should be equivalent.
hspi.begin(SCK, MISO, MOSI, SS);
hspi.begin(D8, D9, D10, D7);
I am at a loss at how to get this working on this board. If anyone has any other ideas, or if there is some other problem with the code, please let me know. I can't figure out what the different SPI_MODEs mean (there are no comments in source), and I am almost wondering if there is a byte ordering issue since the C3 is RISC-V and the S3 is Xtensa. Thanks in advance.

