@@ -28,25 +28,12 @@ static const std::map<std::string, FnCreateDispDrv> FactoryDrvDisp = {
28
28
int16_t busy) -> dispDrvBase * {
29
29
return new drvDispThinkInkGrayscale4Eaamfgn (dc, rst, cs, sram_cs, busy);
30
30
}},
31
- {" thinkink-magtag-2025" ,
32
- [](int16_t dc, int16_t rst, int16_t cs, int16_t sram_cs,
33
- int16_t busy) -> dispDrvBase * {
34
- return new drvDispThinkInkGrayscale4Eaamfgn (dc, rst, cs, sram_cs, busy);
35
- }},
36
31
{" thinkink-gs4-t5" ,
37
32
[](int16_t dc, int16_t rst, int16_t cs, int16_t sram_cs,
38
33
int16_t busy) -> dispDrvBase * {
39
34
return new dispDrvThinkInkGrayscale4T5 (dc, rst, cs, sram_cs, busy);
40
- }},
41
- {" thinkink-magtag-pre-2025" ,
42
- [](int16_t dc, int16_t rst, int16_t cs, int16_t sram_cs,
43
- int16_t busy) -> dispDrvBase * {
44
- return new dispDrvThinkInkGrayscale4T5 (dc, rst, cs, sram_cs, busy);
45
- }}
46
- };
35
+ }}};
47
36
48
-
49
-
50
37
/* !
51
38
@brief Creates a new display driver instance based on the driver name.
52
39
@param driver_name
@@ -169,6 +156,19 @@ bool DisplayHardware::beginEPD(
169
156
170
157
// TODO: Configure SPI bus selection (UNUSED AS OF RIGHT NOW)
171
158
159
+ // For "magtag" component name, attempt to autodetect the driver
160
+ if (strncmp (_name, " magtag" , 6 ) == 0 ) {
161
+ if (detect_ssd1680 (cs, dc, rst)) {
162
+ // Detected SSD1680, use EAAMFGN driver
163
+ strncpy (_name, " thinkink-gs4-eaamfgn" , sizeof (_name) - 1 );
164
+ _name[sizeof (_name) - 1 ] = ' \0 ' ;
165
+ } else {
166
+ // Did not detect SSD1680, use T5 driver
167
+ strncpy (_name, " thinkink-gs4-t5" , sizeof (_name) - 1 );
168
+ _name[sizeof (_name) - 1 ] = ' \0 ' ;
169
+ }
170
+ }
171
+
172
172
// Create display driver object using the factory function
173
173
_drvDisp = CreateDrvDisp (_name, dc, rst, cs, srcs, busy);
174
174
if (!_drvDisp) {
@@ -210,4 +210,71 @@ void DisplayHardware::writeMessage(const char *message) {
210
210
} else {
211
211
WS_DEBUG_PRINTLN (" [display] No display driver initialized!" );
212
212
}
213
+ }
214
+
215
+ /* !
216
+ @brief Detects if an SSD1680 EPD is connected using bit-banged SPI.
217
+ @param cs
218
+ Chip Select pin number.
219
+ @param dc
220
+ Data/Command pin number.
221
+ @param rst
222
+ Reset pin number.
223
+ @return True if an SSD1680 is detected, False otherwise (IL0373 or different
224
+ EPD).
225
+ */
226
+ bool DisplayHardware::detect_ssd1680 (uint8_t cs, uint8_t dc, uint8_t rst) {
227
+ // note: for a complete implementation reference, see
228
+ // https://github.com/adafruit/circuitpython/commit/f4316cb2491c815b128acca47f1bb75519fe306e
229
+ // Configure SPI pins to bit-bang
230
+ pinMode (MOSI, OUTPUT);
231
+ pinMode (SCK, OUTPUT);
232
+ pinMode (cs, OUTPUT);
233
+ pinMode (dc, OUTPUT);
234
+ pinMode (rst, OUTPUT);
235
+
236
+ // Begin transaction by pulling cs and dc LOW
237
+ digitalWrite (cs, LOW);
238
+ digitalWrite (dc, LOW);
239
+ digitalWrite (SCK, LOW);
240
+ digitalWrite (rst, HIGH);
241
+
242
+ // Write to read register 0x71
243
+ uint8_t cmd = 0x71 ;
244
+ for (int i = 0 ; i < 8 ; i++) {
245
+ digitalWrite (MOSI, (cmd & (1 << (7 - i))) != 0 );
246
+ digitalWrite (SCK, HIGH);
247
+ digitalWrite (SCK, LOW);
248
+ }
249
+
250
+ // Set DC high to indicate data and switch MOSI to input with PUR in case
251
+ // SSD1680 does not send data back
252
+ digitalWrite (dc, HIGH);
253
+ delayMicroseconds (1 );
254
+ pinMode (MOSI, INPUT_PULLUP);
255
+ delayMicroseconds (1 );
256
+
257
+ // Read response from register
258
+ uint8_t status = 0 ;
259
+ for (int i = 0 ; i < 8 ; i++) {
260
+ status <<= 1 ;
261
+ if (digitalRead (MOSI)) {
262
+ status |= 1 ;
263
+ }
264
+ digitalWrite (SCK, HIGH);
265
+ delayMicroseconds (1 );
266
+ digitalWrite (SCK, LOW);
267
+ delayMicroseconds (1 );
268
+ }
269
+
270
+ // End transaction by pulling CS high
271
+ digitalWrite (cs, HIGH);
272
+
273
+ // Put back MOSI pin as an output
274
+ pinMode (MOSI, OUTPUT);
275
+
276
+ WS_DEBUG_PRINT (" [display] Bitbang read 0x71: 0x" );
277
+ WS_DEBUG_PRINTLN (status, HEX);
278
+
279
+ return status == 0xFF ;
213
280
}
0 commit comments