Skip to content

Commit 35a7e43

Browse files
committed
MagTag: autodetect display type
1 parent 9b72899 commit 35a7e43

File tree

1 file changed

+55
-29
lines changed
  • ports/espressif/boards/adafruit_magtag_2.9_grayscale

1 file changed

+55
-29
lines changed

ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,23 @@ const uint8_t ssd1680_display_refresh_sequence[] = {
135135
0x20, 0x00, 0x00
136136
};
137137

138-
static bool detect_ssd1680(void) {
139-
// Bitbang 4-wire SPI with a bidirectional data line to read register 0x71.
140-
// On the IL0373 it will return 0x13 or similar. On the SSD1680 it is
141-
// unsupported and will be 0xff.
138+
139+
typedef enum {
140+
DISPLAY_IL0373,
141+
DISPLAY_SSD1680_COLSTART_0,
142+
DISPLAY_SSD1680_COLSTART_8,
143+
} display_type_t;
144+
145+
static display_type_t detect_display_type(void) {
146+
// Bitbang 4-wire SPI with a bidirectional data line to read the first word of register 0x2e,
147+
// which is the 10-byte USER ID.
148+
// On the IL0373 it will return 0xff because it's not a valid register.
149+
// With SSD1680, we have seen two types:
150+
// 1. The first batch of displays, labeled "FPC-A005 20.06.15 TRX", which needs colstart=0.
151+
// These have 10 byes of zeros in the User ID
152+
// 2. Second batch, labeled "FPC-7619rev.b", which needs colstart=8.
153+
// The USER ID for these boards is [0x44, 0x0, 0x4, 0x0, 0x25, 0x0, 0x1, 0x78, 0x2b, 0xe]
154+
// So let's distinguish just by the first byte.
142155
digitalio_digitalinout_obj_t data;
143156
digitalio_digitalinout_obj_t clock;
144157
digitalio_digitalinout_obj_t chip_select;
@@ -163,7 +176,7 @@ static bool detect_ssd1680(void) {
163176
common_hal_digitalio_digitalinout_switch_to_output(&reset, true, DRIVE_MODE_PUSH_PULL);
164177
common_hal_digitalio_digitalinout_switch_to_output(&clock, false, DRIVE_MODE_PUSH_PULL);
165178

166-
uint8_t status_read = 0x71;
179+
uint8_t status_read = 0x2e; // SSD1680 User ID register. Not a valid register on IL0373.
167180
for (int i = 0; i < 8; i++) {
168181
common_hal_digitalio_digitalinout_set_value(&data, (status_read & (1 << (7 - i))) != 0);
169182
common_hal_digitalio_digitalinout_set_value(&clock, true);
@@ -192,11 +205,20 @@ static bool detect_ssd1680(void) {
192205
common_hal_digitalio_digitalinout_deinit(&chip_select);
193206
common_hal_digitalio_digitalinout_deinit(&data_command);
194207
common_hal_digitalio_digitalinout_deinit(&reset);
195-
return status == 0xff;
208+
209+
switch (status) {
210+
case 0xff:
211+
return DISPLAY_IL0373;
212+
default: // who knows? Just guess.
213+
case 0x00:
214+
return DISPLAY_SSD1680_COLSTART_0;
215+
case 0x44:
216+
return DISPLAY_SSD1680_COLSTART_8;
217+
}
196218
}
197219

198220
void board_init(void) {
199-
bool is_ssd1680 = detect_ssd1680();
221+
display_type_t display_type = detect_display_type();
200222

201223
fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus;
202224
busio_spi_obj_t *spi = &bus->inline_bus;
@@ -216,8 +238,33 @@ void board_init(void) {
216238
epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display;
217239
display->base.type = &epaperdisplay_epaperdisplay_type;
218240

219-
if (is_ssd1680) {
241+
if (display_type == DISPLAY_IL0373) {
242+
epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS;
243+
args.bus = bus;
244+
args.start_sequence = il0373_display_start_sequence;
245+
args.start_sequence_len = sizeof(il0373_display_start_sequence);
246+
args.stop_sequence = il0373_display_stop_sequence;
247+
args.stop_sequence_len = sizeof(il0373_display_stop_sequence);
248+
args.width = 296;
249+
args.height = 128;
250+
args.ram_width = 160;
251+
args.ram_height = 296;
252+
args.rotation = 270;
253+
args.write_black_ram_command = 0x10;
254+
args.write_color_ram_command = 0x13;
255+
args.refresh_sequence = il0373_display_refresh_sequence;
256+
args.refresh_sequence_len = sizeof(il0373_display_refresh_sequence);
257+
args.refresh_time = 1.0;
258+
args.busy_pin = &pin_GPIO5;
259+
args.seconds_per_frame = 5.0;
260+
args.grayscale = true;
261+
common_hal_epaperdisplay_epaperdisplay_construct(display, &args);
262+
} else {
220263
epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS;
264+
// Default colstart is 0.
265+
if (display_type == DISPLAY_SSD1680_COLSTART_8) {
266+
args.colstart = 8;
267+
}
221268
args.bus = bus;
222269
args.start_sequence = ssd1680_display_start_sequence;
223270
args.start_sequence_len = sizeof(ssd1680_display_start_sequence);
@@ -244,27 +291,6 @@ void board_init(void) {
244291
args.two_byte_sequence_length = true;
245292
args.address_little_endian = true;
246293
common_hal_epaperdisplay_epaperdisplay_construct(display, &args);
247-
} else {
248-
epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS;
249-
args.bus = bus;
250-
args.start_sequence = il0373_display_start_sequence;
251-
args.start_sequence_len = sizeof(il0373_display_start_sequence);
252-
args.stop_sequence = il0373_display_stop_sequence;
253-
args.stop_sequence_len = sizeof(il0373_display_stop_sequence);
254-
args.width = 296;
255-
args.height = 128;
256-
args.ram_width = 160;
257-
args.ram_height = 296;
258-
args.rotation = 270;
259-
args.write_black_ram_command = 0x10;
260-
args.write_color_ram_command = 0x13;
261-
args.refresh_sequence = il0373_display_refresh_sequence;
262-
args.refresh_sequence_len = sizeof(il0373_display_refresh_sequence);
263-
args.refresh_time = 1.0;
264-
args.busy_pin = &pin_GPIO5;
265-
args.seconds_per_frame = 5.0;
266-
args.grayscale = true;
267-
common_hal_epaperdisplay_epaperdisplay_construct(display, &args);
268294
}
269295
}
270296

0 commit comments

Comments
 (0)