2626
2727#include "supervisor/board.h"
2828
29+ #include "mpconfigboard.h"
30+ #include "shared-bindings/busio/SPI.h"
31+ #include "shared-bindings/displayio/FourWire.h"
32+ #include "shared-bindings/microcontroller/Pin.h"
33+ #include "shared-module/displayio/__init__.h"
34+ #include "supervisor/shared/board.h"
35+
36+ #define DELAY 0x80
37+
38+ enum reg {
39+ PSR = 0x00 ,
40+ PWR = 0x01 ,
41+ POF = 0x02 ,
42+ PFS = 0x03 ,
43+ PON = 0x04 ,
44+ PMES = 0x05 ,
45+ BTST = 0x06 ,
46+ DSLP = 0x07 ,
47+ DTM1 = 0x10 ,
48+ DSP = 0x11 ,
49+ DRF = 0x12 ,
50+ DTM2 = 0x13 ,
51+ LUT_VCOM = 0x20 ,
52+ LUT_WW = 0x21 ,
53+ LUT_BW = 0x22 ,
54+ LUT_WB = 0x23 ,
55+ LUT_BB = 0x24 ,
56+ PLL = 0x30 ,
57+ TSC = 0x40 ,
58+ TSE = 0x41 ,
59+ TSR = 0x43 ,
60+ TSW = 0x42 ,
61+ CDI = 0x50 ,
62+ LPD = 0x51 ,
63+ TCON = 0x60 ,
64+ TRES = 0x61 ,
65+ REV = 0x70 ,
66+ FLG = 0x71 ,
67+ AMV = 0x80 ,
68+ VV = 0x81 ,
69+ VDCS = 0x82 ,
70+ PTL = 0x90 ,
71+ PTIN = 0x91 ,
72+ PTOU = 0x92 ,
73+ PGM = 0xa0 ,
74+ APG = 0xa1 ,
75+ ROTP = 0xa2 ,
76+ CCSET = 0xe0 ,
77+ PWS = 0xe3 ,
78+ TSSET = 0xe5
79+ };
80+
81+ enum PSR_FLAGS {
82+ RES_96x230 = 0b00000000 ,
83+ RES_96x252 = 0b01000000 ,
84+ RES_128x296 = 0b10000000 ,
85+ RES_160x296 = 0b11000000 ,
86+
87+ LUT_OTP = 0b00000000 ,
88+ LUT_REG = 0b00100000 ,
89+
90+ FORMAT_BWR = 0b00000000 ,
91+ FORMAT_BW = 0b00010000 ,
92+
93+ SCAN_DOWN = 0b00000000 ,
94+ SCAN_UP = 0b00001000 ,
95+
96+ SHIFT_LEFT = 0b00000000 ,
97+ SHIFT_RIGHT = 0b00000100 ,
98+
99+ BOOSTER_OFF = 0b00000000 ,
100+ BOOSTER_ON = 0b00000010 ,
101+
102+ RESET_SOFT = 0b00000000 ,
103+ RESET_NONE = 0b00000001
104+ };
105+
106+ enum PWR_FLAGS_1 {
107+ VDS_EXTERNAL = 0b00000000 ,
108+ VDS_INTERNAL = 0b00000010 ,
109+
110+ VDG_EXTERNAL = 0b00000000 ,
111+ VDG_INTERNAL = 0b00000001
112+ };
113+
114+ enum PWR_FLAGS_2 {
115+ VCOM_VD = 0b00000000 ,
116+ VCOM_VG = 0b00000100 ,
117+
118+ VGHL_16V = 0b00000000 ,
119+ VGHL_15V = 0b00000001 ,
120+ VGHL_14V = 0b00000010 ,
121+ VGHL_13V = 0b00000011
122+ };
123+
124+ enum BOOSTER_FLAGS {
125+ START_10MS = 0b00000000 ,
126+ START_20MS = 0b01000000 ,
127+ START_30MS = 0b10000000 ,
128+ START_40MS = 0b11000000 ,
129+
130+ STRENGTH_1 = 0b00000000 ,
131+ STRENGTH_2 = 0b00001000 ,
132+ STRENGTH_3 = 0b00010000 ,
133+ STRENGTH_4 = 0b00011000 ,
134+ STRENGTH_5 = 0b00100000 ,
135+ STRENGTH_6 = 0b00101000 ,
136+ STRENGTH_7 = 0b00110000 ,
137+ STRENGTH_8 = 0b00111000 ,
138+
139+ OFF_0_27US = 0b00000000 ,
140+ OFF_0_34US = 0b00000001 ,
141+ OFF_0_40US = 0b00000010 ,
142+ OFF_0_54US = 0b00000011 ,
143+ OFF_0_80US = 0b00000100 ,
144+ OFF_1_54US = 0b00000101 ,
145+ OFF_3_34US = 0b00000110 ,
146+ OFF_6_58US = 0b00000111
147+ };
148+
149+ enum PFS_FLAGS {
150+ FRAMES_1 = 0b00000000 ,
151+ FRAMES_2 = 0b00010000 ,
152+ FRAMES_3 = 0b00100000 ,
153+ FRAMES_4 = 0b00110000
154+ };
155+
156+ enum TSE_FLAGS {
157+ TEMP_INTERNAL = 0b00000000 ,
158+ TEMP_EXTERNAL = 0b10000000 ,
159+
160+ OFFSET_0 = 0b00000000 ,
161+ OFFSET_1 = 0b00000001 ,
162+ OFFSET_2 = 0b00000010 ,
163+ OFFSET_3 = 0b00000011 ,
164+ OFFSET_4 = 0b00000100 ,
165+ OFFSET_5 = 0b00000101 ,
166+ OFFSET_6 = 0b00000110 ,
167+ OFFSET_7 = 0b00000111 ,
168+
169+ OFFSET_MIN_8 = 0b00001000 ,
170+ OFFSET_MIN_7 = 0b00001001 ,
171+ OFFSET_MIN_6 = 0b00001010 ,
172+ OFFSET_MIN_5 = 0b00001011 ,
173+ OFFSET_MIN_4 = 0b00001100 ,
174+ OFFSET_MIN_3 = 0b00001101 ,
175+ OFFSET_MIN_2 = 0b00001110 ,
176+ OFFSET_MIN_1 = 0b00001111
177+ };
178+
179+ enum PLL_FLAGS {
180+ // other frequency options exist but there doesn't seem to be much
181+ // point in including them - this is a fair range of options...
182+ HZ_29 = 0b00111111 ,
183+ HZ_33 = 0b00111110 ,
184+ HZ_40 = 0b00111101 ,
185+ HZ_50 = 0b00111100 ,
186+ HZ_67 = 0b00111011 ,
187+ HZ_100 = 0b00111010 ,
188+ HZ_200 = 0b00111001
189+ };
190+
191+ // This is an UC8151 control chip. The display is a 2.9" grayscale EInk.
192+ const uint8_t display_start_sequence [] = {
193+ PWR , 5 , VDS_INTERNAL | VDG_INTERNAL , VCOM_VD | VGHL_16V , 0b101011 , 0b101011 , 0b101011 , // power setting
194+ PON , DELAY , 200 , // power on and wait 200 ms
195+ BTST , 3 , (START_10MS | STRENGTH_3 | OFF_6_58US ), (START_10MS | STRENGTH_3 | OFF_6_58US ), (START_10MS | STRENGTH_3 | OFF_6_58US ),
196+ PSR , 1 , (RES_128x296 | LUT_REG | FORMAT_BW | SCAN_UP | SHIFT_RIGHT | BOOSTER_ON | RESET_NONE ),
197+ PFS , 1 , FRAMES_1 ,
198+ TSE , 1 , TEMP_INTERNAL | OFFSET_0 ,
199+ TCON , 1 , 0x22 , // tcon setting
200+ CDI , 1 , 0b01001100 , // vcom and data interval
201+ PLL , 1 , HZ_100 , // PLL set to 100 Hz
202+
203+ // Look up tables for voltage sequence for pixel transition
204+ // Common voltage
205+ LUT_VCOM , 44 ,
206+ 0x00 , 0x16 , 0x16 , 0x0d , 0x00 , 0x01 ,
207+ 0x00 , 0x23 , 0x23 , 0x00 , 0x00 , 0x02 ,
208+ 0x00 , 0x16 , 0x16 , 0x0d , 0x00 , 0x01 ,
209+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
210+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
211+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
212+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
213+ 0x00 , 0x00 ,
214+
215+ // White to white
216+ LUT_WW , 42 ,
217+ 0x54 , 0x16 , 0x16 , 0x0d , 0x00 , 0x01 ,
218+ 0x60 , 0x23 , 0x23 , 0x00 , 0x00 , 0x02 ,
219+ 0xa8 , 0x16 , 0x16 , 0x0d , 0x00 , 0x01 ,
220+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
221+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
222+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
223+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
224+
225+ // Black to white
226+ LUT_BW , 42 ,
227+ 0x54 , 0x16 , 0x16 , 0x0d , 0x00 , 0x01 ,
228+ 0x60 , 0x23 , 0x23 , 0x00 , 0x00 , 0x02 ,
229+ 0xa8 , 0x16 , 0x16 , 0x0d , 0x00 , 0x01 ,
230+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
231+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
232+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
233+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
234+
235+ // White to black
236+ LUT_WB , 42 ,
237+ 0xa8 , 0x16 , 0x16 , 0x0d , 0x00 , 0x01 ,
238+ 0x60 , 0x23 , 0x23 , 0x00 , 0x00 , 0x02 ,
239+ 0x54 , 0x16 , 0x16 , 0x0d , 0x00 , 0x01 ,
240+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
241+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
242+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
243+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
244+
245+ // Black to black
246+ LUT_BB , 42 ,
247+ 0xa8 , 0x16 , 0x16 , 0x0d , 0x00 , 0x01 ,
248+ 0x60 , 0x23 , 0x23 , 0x00 , 0x00 , 0x02 ,
249+ 0x54 , 0x16 , 0x16 , 0x0d , 0x00 , 0x01 ,
250+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
251+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
252+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
253+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
254+ };
255+
256+ const uint8_t display_stop_sequence [] = {
257+ POF , 0x00 // Power off
258+ };
259+
29260void board_init (void ) {
261+ busio_spi_obj_t * spi = & displays [0 ].fourwire_bus .inline_bus ;
262+ common_hal_busio_spi_construct (spi , & pin_GPIO18 , & pin_GPIO19 , & pin_GPIO16 , false);
263+ common_hal_busio_spi_never_reset (spi );
264+
265+ displayio_fourwire_obj_t * bus = & displays [0 ].fourwire_bus ;
266+ bus -> base .type = & displayio_fourwire_type ;
267+ common_hal_displayio_fourwire_construct (bus ,
268+ spi ,
269+ & pin_GPIO20 , // EPD_DC Command or data
270+ & pin_GPIO17 , // EPD_CS Chip select
271+ & pin_GPIO21 , // EPD_RST Reset
272+ 1200000 , // Baudrate
273+ 0 , // Polarity
274+ 0 ); // Phase
275+
276+ displayio_epaperdisplay_obj_t * display = & displays [0 ].epaper_display ;
277+ display -> base .type = & displayio_epaperdisplay_type ;
278+ common_hal_displayio_epaperdisplay_construct (
279+ display ,
280+ bus ,
281+ display_start_sequence , sizeof (display_start_sequence ),
282+ display_stop_sequence , sizeof (display_stop_sequence ),
283+ 296 , // width
284+ 128 , // height
285+ 160 , // ram_width
286+ 296 , // ram_height
287+ 0 , // colstart
288+ 0 , // rowstart
289+ 270 , // rotation
290+ NO_COMMAND , // set_column_window_command
291+ NO_COMMAND , // set_row_window_command
292+ NO_COMMAND , // set_current_column_command
293+ NO_COMMAND , // set_current_row_command
294+ DTM2 , // write_black_ram_command
295+ true, // black_bits_inverted
296+ DTM1 , // write_color_ram_command
297+ false, // color_bits_inverted
298+ 0x000000 , // highlight_color
299+ DRF , // refresh_display_command
300+ 1.0 , // refresh_time
301+ & pin_GPIO26 , // busy_pin
302+ false, // busy_state
303+ 2.0 , // seconds_per_frame
304+ false, // always_toggle_chip_select
305+ false, // grayscale
306+ false); // two_byte_sequence_length
30307}
31308
32309bool board_requests_safe_mode (void ) {
@@ -37,4 +314,13 @@ void reset_board(void) {
37314}
38315
39316void board_deinit (void ) {
317+ displayio_epaperdisplay_obj_t * display = & displays [0 ].epaper_display ;
318+ if (display -> base .type == & displayio_epaperdisplay_type ) {
319+ size_t i = 0 ;
320+ while (common_hal_displayio_epaperdisplay_get_busy (display )) {
321+ RUN_BACKGROUND_TASKS ;
322+ i ++ ;
323+ }
324+ }
325+ common_hal_displayio_release_displays ();
40326}
0 commit comments