Skip to content

Commit 1c481e8

Browse files
committed
add xteink x4 with ssd1677 eink
1 parent 2fbc154 commit 1c481e8

5 files changed

Lines changed: 247 additions & 0 deletions

File tree

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
// This file is part of the CircuitPython project: https://circuitpython.org
2+
//
3+
// SPDX-FileCopyrightText: Copyright (c) 2021 microDev
4+
// SPDX-FileCopyrightText: Copyright (c) 2021 skieast/Bruce Segal
5+
//
6+
// SPDX-License-Identifier: MIT
7+
8+
#include "supervisor/board.h"
9+
10+
#include "mpconfigboard.h"
11+
#include "shared-bindings/busio/SPI.h"
12+
#include "shared-bindings/fourwire/FourWire.h"
13+
#include "shared-bindings/microcontroller/Pin.h"
14+
#include "shared-module/displayio/__init__.h"
15+
#include "supervisor/shared/board.h"
16+
17+
#define DELAY 0x80
18+
19+
// SSD1677 controller driving a GDEQ0426T82 4.26" 800x480 grayscale E-Ink display.
20+
21+
const uint8_t ssd1677_display_start_sequence[] = {
22+
// Software Reset
23+
0x12, DELAY, 0x00, 0x14, // SWRESET + wait 20ms
24+
25+
// Temperature Sensor Control (use internal sensor)
26+
0x18, 0x00, 0x01, 0x80,
27+
28+
// Booster Soft Start
29+
0x0C, 0x00, 0x05, 0xAE, 0xC7, 0xC3, 0xC0, 0x40,
30+
31+
// Driver Output Control: 479 gates (HEIGHT-1 = 0x01DF)
32+
0x01, 0x00, 0x03, 0xDF, 0x01, 0x02,
33+
34+
// Data Entry Mode: X increment, Y increment
35+
0x11, 0x00, 0x01, 0x02,
36+
37+
// Border Waveform Control
38+
0x3C, 0x00, 0x01, 0x01,
39+
40+
// Set RAM X Address Start/End: 0 to 799
41+
42+
// X start = 0 (LE: 0x00, 0x00), X end = 799 (LE: 0x1F, 0x03)
43+
0x44, 0x00, 0x04, 0x00, 0x00, 0x1F, 0x03,
44+
45+
// Set RAM Y Address Start/End: 0 to 479
46+
0x45, 0x00, 0x04, 0x00, 0x00, 0xDF, 0x01,
47+
48+
// Set RAM X Counter to 0
49+
0x4E, 0x00, 0x02, 0x00, 0x00,
50+
51+
// Set RAM Y Counter to 0
52+
0x4F, 0x00, 0x02, 0x00, 0x00,
53+
54+
// Auto Write BW RAM (clear to white)
55+
0x46, DELAY, 0x01, 0xF7, 0xFF, // + wait 255ms
56+
57+
// Display Update Control 1: bypass RED buffer for mono mode
58+
0x21, 0x00, 0x02, 0x40, 0x00,
59+
60+
// Display Update Control 2: full refresh sequence with OTP LUT
61+
0x22, 0x00, 0x01, 0xF7,
62+
};
63+
64+
const uint8_t ssd1677_display_stop_sequence[] = {
65+
// Power off sequence
66+
0x22, 0x00, 0x01, 0x83, // Display update control: power off
67+
0x20, 0x00, 0x00, // Master activation
68+
// Deep sleep
69+
0x10, 0x00, 0x01, 0x01, // Enter deep sleep mode
70+
};
71+
72+
const uint8_t ssd1677_display_refresh_sequence[] = {
73+
0x20, 0x00, 0x00
74+
};
75+
76+
void board_init(void) {
77+
fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus;
78+
busio_spi_obj_t *spi = &bus->inline_bus;
79+
common_hal_busio_spi_construct(spi, &pin_GPIO8, &pin_GPIO10, NULL, false);
80+
common_hal_busio_spi_never_reset(spi);
81+
82+
bus->base.type = &fourwire_fourwire_type;
83+
common_hal_fourwire_fourwire_construct(bus,
84+
spi,
85+
MP_OBJ_FROM_PTR(&pin_GPIO4),
86+
MP_OBJ_FROM_PTR(&pin_GPIO21),
87+
MP_OBJ_FROM_PTR(&pin_GPIO5),
88+
40000000,
89+
0,
90+
0);
91+
92+
epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display;
93+
display->base.type = &epaperdisplay_epaperdisplay_type;
94+
95+
epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS;
96+
args.bus = bus;
97+
args.start_sequence = ssd1677_display_start_sequence;
98+
args.start_sequence_len = sizeof(ssd1677_display_start_sequence);
99+
args.stop_sequence = ssd1677_display_stop_sequence;
100+
args.stop_sequence_len = sizeof(ssd1677_display_stop_sequence);
101+
args.width = 800;
102+
args.height = 480;
103+
args.ram_width = 800;
104+
args.ram_height = 480;
105+
args.rotation = 0;
106+
args.write_black_ram_command = 0x24;
107+
args.black_bits_inverted = true;
108+
args.refresh_sequence = ssd1677_display_refresh_sequence;
109+
args.refresh_sequence_len = sizeof(ssd1677_display_refresh_sequence);
110+
args.refresh_time = 1.6; // ~1600ms full refresh
111+
args.busy_pin = &pin_GPIO6;
112+
args.busy_state = true; // BUSY is active HIGH on SSD1677
113+
args.seconds_per_frame = 5.0;
114+
args.grayscale = false;
115+
args.two_byte_sequence_length = true;
116+
args.address_little_endian = true;
117+
common_hal_epaperdisplay_epaperdisplay_construct(display, &args);
118+
}
119+
120+
bool espressif_board_reset_pin_number(gpio_num_t pin_number) {
121+
return false;
122+
}
123+
124+
void board_deinit(void) {
125+
epaperdisplay_epaperdisplay_obj_t *display = &displays[0].epaper_display;
126+
if (display->base.type == &epaperdisplay_epaperdisplay_type) {
127+
while (common_hal_epaperdisplay_epaperdisplay_get_busy(display)) {
128+
RUN_BACKGROUND_TASKS;
129+
}
130+
}
131+
common_hal_displayio_release_displays();
132+
}
133+
134+
// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// This file is part of the CircuitPython project: https://circuitpython.org
2+
//
3+
// SPDX-FileCopyrightText: Copyright (c) 2021 microDev
4+
// SPDX-FileCopyrightText: Copyright (c) 2021 skieast/Bruce Segal
5+
//
6+
// SPDX-License-Identifier: MIT
7+
8+
#pragma once
9+
10+
// Board setup
11+
#define MICROPY_HW_BOARD_NAME "Xteink X4"
12+
#define MICROPY_HW_MCU_NAME "ESP32-C3"
13+
14+
#define CIRCUITPY_BOARD_SPI (1)
15+
#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO8, .mosi = &pin_GPIO10, .miso = &pin_GPIO7}}
16+
17+
// For entering safe mode
18+
#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO3)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
CIRCUITPY_CREATOR_ID = 0x0000303A
2+
CIRCUITPY_CREATION_ID = 0x00001001
3+
4+
IDF_TARGET = esp32c3
5+
6+
CIRCUITPY_ESP_FLASH_MODE = dio
7+
CIRCUITPY_ESP_FLASH_FREQ = 40m
8+
CIRCUITPY_ESP_FLASH_SIZE = 16MB
9+
10+
CIRCUITPY_ESP_USB_SERIAL_JTAG = 1
11+
12+
CIRCUITPY_PARALLELDISPLAYBUS = 0
13+
CIRCUITPY_RGBMATRIX = 0
14+
CIRCUITPY_AUDIOBUSIO = 0
15+
CIRCUITPY_AUDIOCORE = 0
16+
CIRCUITPY_AUDIOMIXER = 0
17+
CIRCUITPY_AUDIOMP3 = 0
18+
CIRCUITPY_CAMERA = 0
19+
CIRCUITPY_CANIO = 0
20+
CIRCUITPY_DOTCLOCKFRAMEBUFFER = 0
21+
CIRCUITPY_KEYPAD = 0
22+
CIRCUITPY_ROTARYIO = 0
23+
CIRCUITPY_USB_HID = 0
24+
CIRCUITPY_USB_MIDI = 0
25+
CIRCUITPY_ULAB = 0
26+
CIRCUITPY_PULSEIO = 0
27+
CIRCUITPY_PWMIO = 0
28+
CIRCUITPY_RAINBOWIO = 0
29+
CIRCUITPY_SYNTHIO = 0
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// This file is part of the CircuitPython project: https://circuitpython.org
2+
//
3+
// SPDX-FileCopyrightText: Copyright (c) 2021 microDev
4+
// SPDX-FileCopyrightText: Copyright (c) 2021 skieast/Bruce Segal
5+
//
6+
// SPDX-License-Identifier: MIT
7+
8+
#include "shared-bindings/board/__init__.h"
9+
10+
#include "shared-module/displayio/__init__.h"
11+
12+
static const mp_rom_map_elem_t board_module_globals_table[] = {
13+
CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS
14+
15+
{ MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO3) },
16+
{ MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO3) },
17+
18+
{ MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO0) },
19+
20+
{ MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO1) },
21+
{ MP_ROM_QSTR(MP_QSTR_BUTTON_ADC_1), MP_ROM_PTR(&pin_GPIO1) },
22+
23+
{ MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) },
24+
{ MP_ROM_QSTR(MP_QSTR_BUTTON_ADC_2), MP_ROM_PTR(&pin_GPIO2) },
25+
26+
{ MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO20) },
27+
{ MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_GPIO20) },
28+
29+
{ MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO10) },
30+
{ MP_ROM_QSTR(MP_QSTR_EPD_MOSI), MP_ROM_PTR(&pin_GPIO10) },
31+
{ MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) },
32+
33+
{ MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO8) },
34+
{ MP_ROM_QSTR(MP_QSTR_EPD_SCK), MP_ROM_PTR(&pin_GPIO8) },
35+
{ MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) },
36+
37+
{ MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO7) },
38+
{ MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO7) },
39+
40+
{ MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO12) },
41+
42+
{ MP_ROM_QSTR(MP_QSTR_EPD_BUSY), MP_ROM_PTR(&pin_GPIO6) },
43+
{ MP_ROM_QSTR(MP_QSTR_EPD_RESET), MP_ROM_PTR(&pin_GPIO5) },
44+
{ MP_ROM_QSTR(MP_QSTR_EPD_DC), MP_ROM_PTR(&pin_GPIO4) },
45+
{ MP_ROM_QSTR(MP_QSTR_EPD_CS), MP_ROM_PTR(&pin_GPIO21) },
46+
47+
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
48+
49+
{ MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].epaper_display)},
50+
51+
};
52+
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#
2+
# Espressif IoT Development Framework Configuration
3+
#
4+
#
5+
# Component config
6+
#
7+
#
8+
# LWIP
9+
#
10+
# end of LWIP
11+
12+
# end of Component config
13+
14+
# end of Espressif IoT Development Framework Configuration

0 commit comments

Comments
 (0)