Skip to content

Commit aa30e8f

Browse files
committed
Initial code for Linux it8951 support
1 parent 3471430 commit aa30e8f

3 files changed

Lines changed: 191 additions & 14 deletions

File tree

src/FastEPD.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,11 @@ int FASTEPD::setPanelSize(int iPanel)
745745
int FASTEPD::setPanelSize(int width, int height, int flags, int iVCOM) {
746746
return bbepSetPanelSize(&_state, width, height, flags, iVCOM);
747747
} /* setPanelSize() */
748-
748+
//
749+
// On Linux, the SPI bus is specified as a #.# for bus and chip select
750+
// Use MOSI for the bus number and MISO for the chip select
751+
// e.g. on Raspberry Pi, the default bus is 0 and CS0/CS1 are available
752+
//
749753
int FASTEPD::initIT8951(uint8_t u8MOSI, uint8_t u8MISO, uint8_t u8CLK, uint8_t u8CS, uint8_t u8Busy, uint8_t u8RST, uint8_t u8EN, uint8_t u8ITE_EN)
750754
{
751755
return bbepInitIT8951(&_state, u8MOSI, u8MISO, u8CLK, u8CS, u8Busy, u8RST, u8EN, u8ITE_EN);

src/FastEPD.inl

Lines changed: 116 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,17 @@
2929
#if PSRAM != enabled && !defined(CONFIG_ESP32_SPIRAM_SUPPORT) && !defined(CONFIG_ESP32S3_SPIRAM_SUPPORT) && !defined(CONFIG_ESP32C5_SPIRAM_SUPPORT)
3030
#error "Please enable PSRAM support"
3131
#endif
32+
#else // __LINUX__
33+
void linux_spi_init(int iMISOPin, int iMOSIPin, int iCLKPin);
34+
void yield(void) {}
35+
void delay(int iMS);
36+
void vTaskDelay(int iDelay);
37+
void pinMode(int iPin, int iMode);
38+
int digitalRead(int iPin);
39+
void digitalWrite(int iPin, int iState);
40+
void linux_spi_write(uint8_t *pBuf, int iLen, uint32_t iSPISpeed);
41+
void linux_spi_write16(const uint16_t *pBuf, int iLen, uint32_t iSPISpeed);
42+
void linux_spi_read16(uint16_t *pBuf, int iLen, uint32_t iSPISpeed);
3243
#endif // !__LINUX__
3344

3445
#ifndef __BB_EP__
@@ -1916,6 +1927,13 @@ void it8951WaitForReady(FASTEPDSTATE *pState)
19161927

19171928
void it8951WriteNData(FASTEPDSTATE *pState, const uint16_t *buf, uint32_t word_count) {
19181929
digitalWrite(pState->u8CS, LOW);
1930+
#ifdef __LINUX__
1931+
uint16_t u16 = 0;
1932+
it8951WaitForReady(pState);
1933+
linux_spi_write16((uint16_t *)&u16, 1, pState->spi_frequency); // data preamble
1934+
it8951WaitForReady(pState);
1935+
linux_spi_write16(buf, word_count, pState->spi_frequency);
1936+
#else
19191937
SPI.beginTransaction(SPISettings(pState->spi_frequency, MSBFIRST, SPI_MODE0));
19201938
//it8951GetSystemInfo(pState);
19211939
it8951WaitForReady(pState);
@@ -1925,28 +1943,45 @@ void it8951WriteNData(FASTEPDSTATE *pState, const uint16_t *buf, uint32_t word_c
19251943
SPI.transfer16(buf[i]);
19261944
}
19271945
SPI.endTransaction();
1946+
#endif
19281947
digitalWrite(pState->u8CS, HIGH);
19291948
} /* i8951WriteNData() */
19301949

19311950
void it8951WriteData(FASTEPDSTATE *pState, uint16_t data) {
19321951
digitalWrite(pState->u8CS, LOW);
1952+
#ifdef __LINUX__
1953+
uint16_t u16 = 0;
1954+
it8951WaitForReady(pState);
1955+
linux_spi_write16(&u16, 1, pState->spi_frequency);
1956+
it8951WaitForReady(pState);
1957+
linux_spi_write16(&data, 1, pState->spi_frequency);
1958+
#else
19331959
SPI.beginTransaction(SPISettings(pState->spi_frequency, MSBFIRST, SPI_MODE0));
19341960
it8951WaitForReady(pState);
19351961
SPI.transfer16(0x0000); // data preamble
19361962
it8951WaitForReady(pState);
19371963
SPI.transfer16(data);
19381964
SPI.endTransaction();
1965+
#endif // !__LINUX__
19391966
digitalWrite(pState->u8CS, HIGH);
19401967
} /* it8951WriteData() */
19411968

19421969
void it8951WriteCmdCode(FASTEPDSTATE *pState, uint16_t cmd) {
19431970
digitalWrite(pState->u8CS, LOW);
1971+
#ifdef __LINUX__
1972+
uint16_t u16 = 0x6000; // command preamble
1973+
it8951WaitForReady(pState);
1974+
linux_spi_write16(&u16, 1, pState->spi_frequency);
1975+
it8951WaitForReady(pState);
1976+
linux_spi_write16(&cmd, 1, pState->spi_frequency);
1977+
#else
19441978
SPI.beginTransaction(SPISettings(pState->spi_frequency, MSBFIRST, SPI_MODE0));
19451979
it8951WaitForReady(pState);
19461980
SPI.transfer16(0x6000); // command preamble
19471981
it8951WaitForReady(pState);
19481982
SPI.transfer16(cmd);
19491983
SPI.endTransaction();
1984+
#endif // !__LINUX__
19501985
digitalWrite(pState->u8CS, HIGH);
19511986
} /* it8951WriteCmdCode() */
19521987

@@ -1966,21 +2001,42 @@ void it8951WriteVcom(FASTEPDSTATE *pState, uint16_t selector, uint16_t value)
19662001
}
19672002

19682003
uint16_t it8951ReadData(FASTEPDSTATE *pState) {
2004+
uint16_t data;
2005+
19692006
digitalWrite(pState->u8CS, LOW);
2007+
#ifdef __LINUX__
2008+
uint16_t u16 = 0x1000; // read preamble
2009+
it8951WaitForReady(pState);
2010+
linux_spi_write16(&u16, 1, pState->spi_frequency);
2011+
u16 = 0; // dummy read
2012+
linux_spi_write16(&u16, 1, pState->spi_frequency);
2013+
it8951WaitForReady(pState);
2014+
linux_spi_read16(&data, 1, pState->spi_frequency);
2015+
#else
19702016
SPI.beginTransaction(SPISettings(pState->spi_frequency, MSBFIRST, SPI_MODE0));
19712017
it8951WaitForReady(pState);
19722018
SPI.transfer16(0x1000); // read preamble
19732019
SPI.transfer16(0); // dummy read
19742020
it8951WaitForReady(pState);
1975-
const uint16_t data = SPI.transfer16(0);
2021+
data = SPI.transfer16(0);
19762022
SPI.endTransaction();
2023+
#endif // !__LINUX__
19772024
digitalWrite(pState->u8CS, HIGH);
19782025
return data;
19792026
} /* it8951ReadData() */
19802027

19812028
void it8951ReadNData(FASTEPDSTATE *pState, uint16_t *buf, uint32_t word_count)
19822029
{
19832030
digitalWrite(pState->u8CS, LOW);
2031+
#ifdef __LINUX__
2032+
uint16_t u16 = 0x1000; // read preamble
2033+
it8951WaitForReady(pState);
2034+
linux_spi_write16(&u16, 1, pState->spi_frequency);
2035+
u16 = 0; // dummy read
2036+
linux_spi_write16(&u16, 1, pState->spi_frequency);
2037+
it8951WaitForReady(pState);
2038+
linux_spi_read16(buf, word_count, pState->spi_frequency);
2039+
#else
19842040
SPI.beginTransaction(SPISettings(pState->spi_frequency, MSBFIRST, SPI_MODE0));
19852041
it8951WaitForReady(pState);
19862042
SPI.transfer16(0x1000); // read preamble
@@ -1991,6 +2047,7 @@ void it8951ReadNData(FASTEPDSTATE *pState, uint16_t *buf, uint32_t word_count)
19912047
buf[i] = SPI.transfer16(0);
19922048
}
19932049
SPI.endTransaction();
2050+
#endif // !__LINUX__
19942051
digitalWrite(pState->u8CS, HIGH);
19952052
} /* it8951ReadNData() */
19962053

@@ -2112,9 +2169,14 @@ int iPitch;
21122169

21132170
//Serial.println("About to start data");
21142171
digitalWrite(pState->u8CS, LOW);
2115-
SPI.beginTransaction(SPISettings(pState->spi_frequency, MSBFIRST, SPI_MODE0));
21162172
it8951WaitForReady(pState);
2173+
#ifdef __LINUX__
2174+
uint16_t u16 = 0;
2175+
linux_spi_write16(&u16, 1, pState->spi_frequency);
2176+
#else
2177+
SPI.beginTransaction(SPISettings(pState->spi_frequency, MSBFIRST, SPI_MODE0));
21172178
SPI.transfer16(0x0000); // data preamble
2179+
#endif
21182180
it8951WaitForReady(pState);
21192181

21202182
s = pState->pCurrent;
@@ -2125,16 +2187,26 @@ int iPitch;
21252187
for (int x = 0; x<iPitch; x++) {
21262188
d[iPitch - 1 - x] = s[x];
21272189
}
2190+
#ifdef __LINUX__
2191+
linux_spi_write(d, iPitch, pState->spi_frequency);
2192+
#else
21282193
SPI.writeBytes(d, iPitch);
2194+
#endif // !__LINUX__
21292195
} else {
2196+
#ifdef __LINUX__
2197+
linux_spi_write(s, iPitch, pState->spi_frequency);
2198+
#else
21302199
SPI.writeBytes(s, iPitch);
2200+
#endif // !__LINUX__
21312201
}
21322202
if ((y & 0x07) == 0) {
21332203
yield();
21342204
}
21352205
s += iPitch;
21362206
}
2207+
#ifndef __LINUX__
21372208
SPI.endTransaction();
2209+
#endif
21382210
digitalWrite(pState->u8CS, HIGH);
21392211
//Serial.println("Data sent");
21402212
// finish the operation
@@ -2162,9 +2234,14 @@ int iPitch;
21622234

21632235

21642236
digitalWrite(pState->u8CS, LOW);
2165-
SPI.beginTransaction(SPISettings(pState->spi_frequency, MSBFIRST, SPI_MODE0));
21662237
it8951WaitForReady(pState);
2238+
#ifdef __LINUX__
2239+
uint16_t u16 = 0;
2240+
linux_spi_write16(&u16, 1, pState->spi_frequency);
2241+
#else
2242+
SPI.beginTransaction(SPISettings(pState->spi_frequency, MSBFIRST, SPI_MODE0));
21672243
SPI.transfer16(0x0000); // data preamble
2244+
#endif // !__LINUX__
21682245
it8951WaitForReady(pState);
21692246

21702247
s = pState->pCurrent;
@@ -2175,17 +2252,26 @@ int iPitch;
21752252
for (int x = 0; x<iPitch; x++) {
21762253
d[iPitch - 1 - x] = (s[x] >> 4) | (s[x] << 4);
21772254
}
2255+
#ifdef __LINUX__
2256+
linux_spi_write(d, iPitch, pState->spi_frequency);
2257+
#else
21782258
SPI.writeBytes(d, iPitch);
2259+
#endif
21792260
} else {
2261+
#ifdef __LINUX__
2262+
linux_spi_write(s, iPitch, pState->spi_frequency);
2263+
#else
21802264
SPI.writeBytes(s, iPitch);
2265+
#endif
21812266
}
21822267
if ((y & 0x07) == 0) {
21832268
yield();
21842269
}
21852270
s += iPitch;
21862271
}
2187-
2272+
#ifndef __LINUX__
21882273
SPI.endTransaction();
2274+
#endif
21892275
digitalWrite(pState->u8CS, HIGH);
21902276
it8951WriteCmdCode(pState, IT8951_TCON_LD_IMG_END);
21912277
it8951DisplayArea(pState, 0, 0, pState->native_width, pState->native_height, 2);
@@ -2209,9 +2295,14 @@ int iPitch;
22092295

22102296

22112297
digitalWrite(pState->u8CS, LOW);
2212-
SPI.beginTransaction(SPISettings(pState->spi_frequency, MSBFIRST, SPI_MODE0));
22132298
it8951WaitForReady(pState);
2299+
#ifdef __LINUX__
2300+
uint16_t u16 = 0;
2301+
linux_spi_write16(&u16, 1, pState->spi_frequency);
2302+
#else
2303+
SPI.beginTransaction(SPISettings(pState->spi_frequency, MSBFIRST, SPI_MODE0));
22142304
SPI.transfer16(0x0000); // data preamble
2305+
#endif // !__LINUX__
22152306
it8951WaitForReady(pState);
22162307

22172308
s = pState->pCurrent;
@@ -2223,17 +2314,26 @@ int iPitch;
22232314
uint8_t a = s[x];
22242315
d[iPitch - 1 - x] = (a >> 6) | ((a >> 2) & 0xc) | ((a & 0xc) << 2) | ((a & 3) << 6);
22252316
}
2317+
#ifdef __LINUX__
2318+
linux_spi_write(d, iPitch, pState->spi_frequency);
2319+
#else
22262320
SPI.writeBytes(d, iPitch);
2321+
#endif
22272322
} else {
2323+
#ifdef __LINUX__
2324+
linux_spi_write(s, iPitch, pState->spi_frequency);
2325+
#else
22282326
SPI.writeBytes(s, iPitch);
2327+
#endif
22292328
}
22302329
if ((y & 0x07) == 0) {
22312330
yield();
22322331
}
22332332
s += iPitch;
22342333
}
2235-
2334+
#ifndef __LINUX__
22362335
SPI.endTransaction();
2336+
#endif
22372337
digitalWrite(pState->u8CS, HIGH);
22382338
it8951WriteCmdCode(pState, IT8951_TCON_LD_IMG_END);
22392339
it8951DisplayArea(pState, 0, 0, pState->native_width, pState->native_height, 2);
@@ -2262,7 +2362,12 @@ int bbepInitIT8951(FASTEPDSTATE *pState, uint8_t u8MOSI, uint8_t u8MISO, uint8_t
22622362
digitalWrite(u8RST, HIGH);
22632363
digitalWrite(u8EN, HIGH);
22642364
digitalWrite(u8ITE_EN, HIGH);
2365+
#ifdef __LINUX__
2366+
linux_spi_init(u8CLK, u8MOSI, u8MISO);
2367+
#else
22652368
SPI.begin(u8CLK, u8MISO, u8MOSI, -1);
2369+
#endif // !__LINUX__
2370+
22662371
pState->spi_frequency = IT8951_SPI_PROBE_FREQUENCY;
22672372

22682373
// power cycle
@@ -2484,7 +2589,6 @@ int bbepFixRect(FASTEPDSTATE *pState, BB_RECT *pRect, int *iStartCol, int *iEndC
24842589
//
24852590
void bbepClear(FASTEPDSTATE *pState, uint8_t val, uint8_t count, BB_RECT *pRect)
24862591
{
2487-
uint8_t u8;
24882592
int i, k, dy, iStartCol, iEndCol, iStartRow, iEndRow; // clipping area
24892593
if (val == BB_CLEAR_LIGHTEN) val = 0xaa;
24902594
else if (val == BB_CLEAR_DARKEN) val = 0x55;
@@ -3019,7 +3123,7 @@ int bbepFullUpdate(FASTEPDSTATE *pState, int iClearMode, bool bKeepOn, BB_RECT *
30193123
void bbepConvertPrevBuffer(FASTEPDSTATE *pState)
30203124
{
30213125
uint8_t *s, *d, *c;
3022-
int i, n, x, y, iSrcPitch, iDestPitch;
3126+
int i, n, x, y, iSrcPitch=0, iDestPitch;
30233127

30243128
switch (pState->prev_mode) {
30253129
case BB_MODE_1BPP:
@@ -3244,7 +3348,7 @@ int bbep2BppPartial(FASTEPDSTATE *pState, bool bKeepOn, int iStartLine, int iEnd
32443348
for (k = 0; k < 4; k++) { // 4 pixels per byte
32453349
ucPush <<= 2;
32463350
// convert new+old pixel into correct color pushes
3247-
ucPush |= u8Gray2BW[((ucNew << 2) & 0xc) | ucOld & 3];
3351+
ucPush |= u8Gray2BW[((ucNew << 2) & 0xc) | (ucOld & 3)];
32483352
ucNew >>= 2; ucOld >>= 2;
32493353
}
32503354
*d++ = ucPush;
@@ -3259,7 +3363,7 @@ int bbep2BppPartial(FASTEPDSTATE *pState, bool bKeepOn, int iStartLine, int iEnd
32593363
for (k = 0; k < 4; k++) { // 4 pixels per byte
32603364
ucPush >>= 2;
32613365
// convert new+old pixel into correct color pushes
3262-
ucPush |= (u8Gray2BW[((ucNew << 2) & 0xc) | ucOld & 3]) << 6;
3366+
ucPush |= (u8Gray2BW[((ucNew << 2) & 0xc) | (ucOld & 3)]) << 6;
32633367
ucNew >>= 2; ucOld >>= 2;
32643368
}
32653369
*d++ = ucPush;
@@ -3292,7 +3396,7 @@ int bbep2BppPartial(FASTEPDSTATE *pState, bool bKeepOn, int iStartLine, int iEnd
32923396
for (k = 0; k < 4; k++) { // 4 pixels per byte
32933397
ucPush <<= 2;
32943398
// convert new+old pixel into correct color pushes
3295-
ucPush |= u8Gray2Gray[((ucNew << 2) & 0xc) | ucOld & 3];
3399+
ucPush |= u8Gray2Gray[((ucNew << 2) & 0xc) | (ucOld & 3)];
32963400
ucNew >>= 2; ucOld >>= 2;
32973401
}
32983402
*d++ = ucPush;
@@ -3307,7 +3411,7 @@ int bbep2BppPartial(FASTEPDSTATE *pState, bool bKeepOn, int iStartLine, int iEnd
33073411
for (k = 0; k < 4; k++) { // 4 pixels per byte
33083412
ucPush >>= 2;
33093413
// convert new+old pixel into correct color pushes
3310-
ucPush |= (u8Gray2Gray[((ucNew << 2) & 0xc) | ucOld & 3]) << 6;
3414+
ucPush |= (u8Gray2Gray[((ucNew << 2) & 0xc) | (ucOld & 3)]) << 6;
33113415
ucNew >>= 2; ucOld >>= 2;
33123416
}
33133417
*d++ = ucPush;

0 commit comments

Comments
 (0)