|
1 /* |
|
2 |
|
3 u8x8_d_ssd1607_200x200.c |
|
4 |
|
5 Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) |
|
6 |
|
7 Copyright (c) 2016, olikraus@gmail.com |
|
8 All rights reserved. |
|
9 |
|
10 Redistribution and use in source and binary forms, with or without modification, |
|
11 are permitted provided that the following conditions are met: |
|
12 |
|
13 * Redistributions of source code must retain the above copyright notice, this list |
|
14 of conditions and the following disclaimer. |
|
15 |
|
16 * Redistributions in binary form must reproduce the above copyright notice, this |
|
17 list of conditions and the following disclaimer in the documentation and/or other |
|
18 materials provided with the distribution. |
|
19 |
|
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
|
21 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
|
22 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
|
23 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
|
25 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
26 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
27 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
|
29 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
|
30 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
31 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
|
32 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
33 |
|
34 SSD1607: 200x300x1 |
|
35 |
|
36 command |
|
37 0x22: assign actions |
|
38 0x20: execute actions |
|
39 |
|
40 action for command 0x022 are (more or less guessed) |
|
41 bit 7: Enable Clock |
|
42 bit 6: Enable Charge Pump |
|
43 bit 5: Load Temparture Value (???) |
|
44 bit 4: Load LUT (???) |
|
45 bit 3: Initial Display (???) |
|
46 bit 2: Pattern Display --> Requires about 945ms with the LUT from below |
|
47 bit 1: Disable Charge Pump |
|
48 bit 0: Disable Clock |
|
49 |
|
50 Disable Charge Pump and Clock require about 267ms |
|
51 Enable Charge Pump and Clock require about 10ms |
|
52 |
|
53 Notes: |
|
54 - Introduced a refresh display message, which copies RAM to display |
|
55 - Charge pump and clock are only enabled for the transfer RAM to display |
|
56 - U8x8 will not really work because of the two buffers in the SSD1606, however U8g2 should be ok. |
|
57 |
|
58 */ |
|
59 |
|
60 |
|
61 #include "u8x8.h" |
|
62 |
|
63 /*=================================================*/ |
|
64 |
|
65 static const u8x8_display_info_t u8x8_ssd1607_200x200_display_info = |
|
66 { |
|
67 /* chip_enable_level = */ 0, |
|
68 /* chip_disable_level = */ 1, |
|
69 |
|
70 /* values from SSD1606 */ |
|
71 /* post_chip_enable_wait_ns = */ 120, |
|
72 /* pre_chip_disable_wait_ns = */ 60, |
|
73 /* reset_pulse_width_ms = */ 100, |
|
74 /* post_reset_wait_ms = */ 100, |
|
75 /* sda_setup_time_ns = */ 50, /* SSD1606: */ |
|
76 /* sck_pulse_width_ns = */ 100, /* SSD1606: 100ns */ |
|
77 /* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ |
|
78 /* spi_mode = */ 0, /* active high, rising edge */ |
|
79 /* i2c_bus_clock_100kHz = */ 4, |
|
80 /* data_setup_time_ns = */ 40, |
|
81 /* write_pulse_width_ns = */ 150, |
|
82 /* tile_width = */ 25, /* 25*8 = 200 */ |
|
83 /* tile_hight = */ 25, |
|
84 /* default_x_offset = */ 0, |
|
85 /* flipmode_x_offset = */ 0, |
|
86 /* pixel_width = */ 200, |
|
87 /* pixel_height = */ 200 |
|
88 }; |
|
89 |
|
90 |
|
91 static const uint8_t u8x8_d_ssd1607_200x200_powersave0_seq[] = { |
|
92 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
93 U8X8_CA(0x22, 0xc0), /* enable clock and charge pump */ |
|
94 U8X8_C(0x20), /* execute sequence */ |
|
95 U8X8_DLY(200), /* according to my measures it may take up to 150ms */ |
|
96 U8X8_DLY(100), /* but it might take longer */ |
|
97 U8X8_END_TRANSFER(), /* disable chip */ |
|
98 U8X8_END() /* end of sequence */ |
|
99 }; |
|
100 |
|
101 static const uint8_t u8x8_d_ssd1607_200x200_powersave1_seq[] = { |
|
102 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
103 /* disable clock and charge pump only, deep sleep is not entered, because we will loose RAM content */ |
|
104 U8X8_CA(0x22, 0x02), /* only disable charge pump, HW reset seems to be required if the clock is disabled */ |
|
105 U8X8_C(0x20), /* execute sequence */ |
|
106 U8X8_DLY(20), |
|
107 U8X8_END_TRANSFER(), /* disable chip */ |
|
108 U8X8_END() /* end of sequence */ |
|
109 }; |
|
110 |
|
111 |
|
112 static const uint8_t u8x8_d_ssd1607_200x200_exec_1000dly_seq[] = { |
|
113 // assumes, that the start transfer has happend |
|
114 U8X8_CA(0x22, 0x04), /* display update seq. option: pattern display */ |
|
115 U8X8_C(0x20), /* execute sequence */ |
|
116 U8X8_DLY(250), |
|
117 U8X8_DLY(250), |
|
118 U8X8_DLY(250), |
|
119 U8X8_DLY(250), |
|
120 U8X8_END_TRANSFER(), /* disable chip */ |
|
121 U8X8_END() /* end of sequence */ |
|
122 }; |
|
123 |
|
124 |
|
125 static void u8x8_d_ssd1607_200x200_first_init(u8x8_t *u8x8) |
|
126 { |
|
127 u8x8_ClearDisplay(u8x8); |
|
128 |
|
129 u8x8_cad_StartTransfer(u8x8); |
|
130 u8x8_cad_SendCmd(u8x8, 0x032); // program update sequence |
|
131 u8x8_cad_SendMultipleArg(u8x8, 8, 0x055); // all black |
|
132 u8x8_cad_SendMultipleArg(u8x8, 12, 0x0aa); // all white |
|
133 u8x8_cad_SendMultipleArg(u8x8, 10, 0x022); // 830ms |
|
134 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_exec_1000dly_seq); |
|
135 |
|
136 } |
|
137 |
|
138 static uint8_t *u8x8_convert_tile_for_ssd1607(uint8_t *t) |
|
139 { |
|
140 uint8_t i; |
|
141 static uint8_t buf[8]; |
|
142 uint8_t *pbuf = buf; |
|
143 |
|
144 for( i = 0; i < 8; i++ ) |
|
145 { |
|
146 *pbuf++ = ~(*t++); |
|
147 } |
|
148 return buf; |
|
149 } |
|
150 |
|
151 static void u8x8_d_ssd1607_draw_tile(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr) U8X8_NOINLINE; |
|
152 static void u8x8_d_ssd1607_draw_tile(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr) |
|
153 { |
|
154 uint16_t x; |
|
155 uint8_t c, page; |
|
156 uint8_t *ptr; |
|
157 u8x8_cad_StartTransfer(u8x8); |
|
158 |
|
159 page = u8x8->display_info->tile_height; |
|
160 page --; |
|
161 page -= (((u8x8_tile_t *)arg_ptr)->y_pos); |
|
162 |
|
163 x = ((u8x8_tile_t *)arg_ptr)->x_pos; |
|
164 x *= 8; |
|
165 x += u8x8->x_offset; |
|
166 |
|
167 |
|
168 |
|
169 u8x8_cad_SendCmd(u8x8, 0x045 ); /* window start column */ |
|
170 u8x8_cad_SendArg(u8x8, x&255); |
|
171 u8x8_cad_SendArg(u8x8, x>>8); |
|
172 u8x8_cad_SendArg(u8x8, 199); /* end of display */ |
|
173 u8x8_cad_SendArg(u8x8, 0); |
|
174 |
|
175 u8x8_cad_SendCmd(u8x8, 0x044 ); /* window end page */ |
|
176 u8x8_cad_SendArg(u8x8, page); |
|
177 u8x8_cad_SendArg(u8x8, page); |
|
178 |
|
179 u8x8_cad_SendCmd(u8x8, 0x04f ); /* window column */ |
|
180 u8x8_cad_SendArg(u8x8, x&255); |
|
181 u8x8_cad_SendArg(u8x8, x>>8); |
|
182 |
|
183 u8x8_cad_SendCmd(u8x8, 0x04e ); /* window row */ |
|
184 u8x8_cad_SendArg(u8x8, page); |
|
185 |
|
186 u8x8_cad_SendCmd(u8x8, 0x024 ); |
|
187 |
|
188 do |
|
189 { |
|
190 c = ((u8x8_tile_t *)arg_ptr)->cnt; |
|
191 ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; |
|
192 do |
|
193 { |
|
194 u8x8_cad_SendData(u8x8, 8, u8x8_convert_tile_for_ssd1607(ptr)); |
|
195 ptr += 8; |
|
196 x += 8; |
|
197 c--; |
|
198 } while( c > 0 ); |
|
199 |
|
200 arg_int--; |
|
201 } while( arg_int > 0 ); |
|
202 |
|
203 u8x8_cad_EndTransfer(u8x8); |
|
204 } |
|
205 |
|
206 |
|
207 |
|
208 /*=================================================*/ |
|
209 |
|
210 |
|
211 #define L(a,b,c,d) (((a)<<6)|((b)<<4)|((c)<<2)|(d)) |
|
212 |
|
213 |
|
214 /* https://github.com/embeddedadventures/SSD1607/blob/master/SSD1607.cpp */ |
|
215 static const uint8_t u8x8_d_ssd1607_200x200_init_seq[] = { |
|
216 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
217 |
|
218 //U8X8_CA(0x10, 0x00), /* Deep Sleep mode Control: Disable */ |
|
219 U8X8_C(0x01), |
|
220 U8X8_A(199),U8X8_A(0),U8X8_A(0), |
|
221 |
|
222 |
|
223 U8X8_CA(0x03, 0x00), /* Gate Driving voltage: 15V (lowest value)*/ |
|
224 U8X8_CA(0x04, 0x0a), /* Source Driving voltage: 15V (mid value and POR)*/ |
|
225 |
|
226 U8X8_CA(0x0f, 0x00), /* scan start ? */ |
|
227 |
|
228 U8X8_CA(0xf0, 0x1f), /* set booster feedback to internal */ |
|
229 |
|
230 U8X8_CA(0x2c, 0xa8), /* write vcom value*/ |
|
231 U8X8_CA(0x3a, 0x1a), /* dummy lines */ |
|
232 U8X8_CA(0x3b, 0x08), /* gate time */ |
|
233 U8X8_CA(0x3c, 0x33), /* select boarder waveform */ |
|
234 |
|
235 U8X8_CA(0x11, 0x03), /* cursor increment mode */ |
|
236 U8X8_CAA(0x44, 0, 24), /* RAM x start & end, each byte has 8 pixel, 25*4=200 */ |
|
237 U8X8_CAAAA(0x45, 0, 0, 299&255, 299>>8), /* RAM y start & end, 0..299 */ |
|
238 |
|
239 U8X8_END_TRANSFER(), /* disable chip */ |
|
240 U8X8_END() /* end of sequence */ |
|
241 }; |
|
242 |
|
243 static const uint8_t u8x8_d_ssd1607_to_display_seq[] = { |
|
244 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
245 |
|
246 U8X8_C(0x32), /* write LUT register*/ |
|
247 |
|
248 |
|
249 /* according to the command table, the lut has 240 bits (=30 bytes * 8 bits) */ |
|
250 |
|
251 /* Waveform part of the LUT (20 bytes) */ |
|
252 /* bit 7/6: 1 - 1 transition */ |
|
253 /* bit 5/4: 1 - 0 transition */ |
|
254 /* bit 3/2: 0 - 1 transition */ |
|
255 /* bit 1/0: 0 - 0 transition */ |
|
256 /* 00 – VSS */ |
|
257 /* 01 – VSH */ |
|
258 /* 10 – VSL */ |
|
259 /* 11 – NA */ |
|
260 |
|
261 /* original values */ |
|
262 /* |
|
263 U8X8_A(0x02), |
|
264 U8X8_A(0x02), |
|
265 U8X8_A(0x01), |
|
266 U8X8_A(0x11), |
|
267 U8X8_A(0x12), |
|
268 U8X8_A(0x12), |
|
269 U8X8_A(0x22), |
|
270 U8X8_A(0x22), |
|
271 U8X8_A(0x66), |
|
272 U8X8_A(0x69), |
|
273 U8X8_A(0x69), |
|
274 U8X8_A(0x59), |
|
275 U8X8_A(0x58), |
|
276 U8X8_A(0x99), |
|
277 U8X8_A(0x99), |
|
278 U8X8_A(0x88), |
|
279 U8X8_A(0x00), |
|
280 U8X8_A(0x00), |
|
281 U8X8_A(0x00), |
|
282 U8X8_A(0x00), |
|
283 */ |
|
284 |
|
285 /* original values, L-macro */ |
|
286 U8X8_A(L(0,0,0,2)), // 0x02 |
|
287 U8X8_A(L(0,0,0,2)), // 0x02 |
|
288 U8X8_A(L(0,0,0,1)), // 0x01 |
|
289 U8X8_A(L(0,1,0,1)), // 0x11 |
|
290 U8X8_A(L(0,1,0,2)), // 0x12 |
|
291 U8X8_A(L(0,1,0,2)), // 0x12 |
|
292 U8X8_A(L(0,2,0,2)), // 0x22 |
|
293 U8X8_A(L(0,2,0,2)), // 0x22 |
|
294 U8X8_A(L(1,2,1,2)), // 0x66 |
|
295 U8X8_A(L(1,2,2,1)), // 0x69 |
|
296 U8X8_A(L(1,2,2,1)), // 0x69 |
|
297 U8X8_A(L(1,1,2,1)), // 0x59 |
|
298 U8X8_A(L(1,1,2,0)), // 0x58 |
|
299 U8X8_A(L(2,1,2,1)), // 0x99 |
|
300 U8X8_A(L(2,1,2,1)), // 0x99 |
|
301 U8X8_A(L(2,0,2,0)), // 0x88 |
|
302 U8X8_A(L(0,0,0,0)), // 0x00 |
|
303 U8X8_A(L(0,0,0,0)), // 0x00 |
|
304 U8X8_A(L(0,0,0,0)), // 0x00 |
|
305 U8X8_A(L(0,0,0,0)), // 0x00 |
|
306 |
|
307 |
|
308 /* orginal values without 0-0 and 1-1 transition */ |
|
309 /* |
|
310 U8X8_A(L(3,0,0,3)), // 0x02 |
|
311 U8X8_A(L(3,0,0,3)), // 0x02 |
|
312 U8X8_A(L(3,0,0,3)), // 0x01 |
|
313 U8X8_A(L(3,1,0,3)), // 0x11 |
|
314 U8X8_A(L(3,1,0,3)), // 0x12 |
|
315 U8X8_A(L(3,1,0,3)), // 0x12 |
|
316 U8X8_A(L(3,2,0,3)), // 0x22 |
|
317 U8X8_A(L(3,2,0,3)), // 0x22 |
|
318 U8X8_A(L(3,2,1,3)), // 0x66 |
|
319 U8X8_A(L(3,2,2,3)), // 0x69 |
|
320 U8X8_A(L(3,2,2,3)), // 0x69 |
|
321 U8X8_A(L(3,1,2,3)), // 0x59 |
|
322 U8X8_A(L(3,1,2,3)), // 0x58 |
|
323 U8X8_A(L(3,1,2,3)), // 0x99 |
|
324 U8X8_A(L(3,1,2,3)), // 0x99 |
|
325 U8X8_A(L(3,0,2,3)), // 0x88 |
|
326 U8X8_A(L(3,0,0,3)), // 0x00 |
|
327 U8X8_A(L(3,0,0,3)), // 0x00 |
|
328 U8X8_A(L(3,0,0,3)), // 0x00 |
|
329 U8X8_A(L(3,0,0,3)), // 0x00 |
|
330 */ |
|
331 |
|
332 |
|
333 /* Timing part of the LUT, 20 Phases with 4 bit each: 10 bytes */ |
|
334 U8X8_A(0xF8), |
|
335 U8X8_A(0xB4), |
|
336 U8X8_A(0x13), |
|
337 U8X8_A(0x51), |
|
338 U8X8_A(0x35), |
|
339 U8X8_A(0x51), |
|
340 U8X8_A(0x51), |
|
341 U8X8_A(0x19), |
|
342 U8X8_A(0x01), |
|
343 U8X8_A(0x00), |
|
344 |
|
345 |
|
346 U8X8_CA(0x22, 0x04), /* display update seq. option: clk -> CP -> LUT -> initial display -> pattern display */ |
|
347 U8X8_C(0x20), /* execute sequence */ |
|
348 U8X8_DLY(250), /* the sequence above requires about 1200ms for the 200x200 display*/ |
|
349 U8X8_DLY(250), |
|
350 U8X8_DLY(250), |
|
351 U8X8_DLY(250), |
|
352 U8X8_DLY(250), |
|
353 U8X8_DLY(250), |
|
354 U8X8_DLY(250), |
|
355 |
|
356 U8X8_END_TRANSFER(), /* disable chip */ |
|
357 U8X8_END() /* end of sequence */ |
|
358 }; |
|
359 |
|
360 |
|
361 uint8_t u8x8_d_ssd1607_200x200(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) |
|
362 { |
|
363 switch(msg) |
|
364 { |
|
365 case U8X8_MSG_DISPLAY_SETUP_MEMORY: |
|
366 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1607_200x200_display_info); |
|
367 break; |
|
368 case U8X8_MSG_DISPLAY_INIT: |
|
369 u8x8_d_helper_display_init(u8x8); |
|
370 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_init_seq); |
|
371 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave0_seq); |
|
372 u8x8_d_ssd1607_200x200_first_init(u8x8); |
|
373 break; |
|
374 case U8X8_MSG_DISPLAY_SET_POWER_SAVE: |
|
375 if ( arg_int == 0 ) |
|
376 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave0_seq); |
|
377 else |
|
378 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave1_seq); |
|
379 break; |
|
380 case U8X8_MSG_DISPLAY_SET_FLIP_MODE: |
|
381 break; |
|
382 case U8X8_MSG_DISPLAY_DRAW_TILE: |
|
383 u8x8_d_ssd1607_draw_tile(u8x8, arg_int, arg_ptr); |
|
384 break; |
|
385 case U8X8_MSG_DISPLAY_REFRESH: |
|
386 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_to_display_seq); |
|
387 break; |
|
388 default: |
|
389 return 0; |
|
390 } |
|
391 return 1; |
|
392 } |
|
393 |
|
394 |
|
395 /*=================================================*/ |
|
396 /* there is no improvement possible... so i consider the v2 version as obsolete */ |
|
397 |
|
398 |
|
399 static const uint8_t u8x8_d_ssd1607_v2_to_display_seq[] = { |
|
400 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
401 |
|
402 /* |
|
403 0xaa, 0x09, 0x09, 0x19, 0x19, |
|
404 0x11, 0x11, 0x11, 0x11, 0x00, |
|
405 0x00, 0x00, 0x00, 0x00, 0x00, |
|
406 0x00, 0x00, 0x00, 0x00, 0x00, |
|
407 |
|
408 0x75, 0x77, 0x77, 0x77, 0x07, |
|
409 0x00, 0x00, 0x00, 0x00, 0x00 |
|
410 measured 1240 ms with IL3830 196x128 |
|
411 |
|
412 |
|
413 0x02, 0x02, 0x01, 0x11, 0x12, |
|
414 0x12, 0x12, 0x22, 0x22, 0x66, |
|
415 0x69, 0x59, 0x58, 0x99, 0x99, |
|
416 0x88, 0x00, 0x00, 0x00, 0x00, |
|
417 |
|
418 0xf8, 0xb4, 0x13, 0x51, 0x35, |
|
419 0x51, 0x51, 0xe9, 0x04, 0x00 |
|
420 |
|
421 */ |
|
422 |
|
423 U8X8_C(0x32), /* write LUT register*/ |
|
424 |
|
425 /* https://github.com/olikraus/u8g2/issues/347 */ |
|
426 U8X8_A(0x02), |
|
427 U8X8_A(0x02), |
|
428 U8X8_A(0x01), |
|
429 U8X8_A(0x11), |
|
430 U8X8_A(0x12), |
|
431 U8X8_A(0x12), |
|
432 U8X8_A(0x22), |
|
433 U8X8_A(0x22), |
|
434 U8X8_A(0x66), |
|
435 U8X8_A(0x69), |
|
436 U8X8_A(0x69), |
|
437 U8X8_A(0x59), |
|
438 U8X8_A(0x58), |
|
439 U8X8_A(0x99), |
|
440 U8X8_A(0x99), |
|
441 |
|
442 U8X8_A(0x88), |
|
443 U8X8_A(0x00), |
|
444 U8X8_A(0x00), |
|
445 U8X8_A(0x00), |
|
446 U8X8_A(0x00), |
|
447 |
|
448 /* Timing part of the LUT, 20 Phases with 4 bit each: 10 bytes */ |
|
449 U8X8_A(0xF8), |
|
450 U8X8_A(0xB4), |
|
451 U8X8_A(0x13), |
|
452 U8X8_A(0x51), |
|
453 U8X8_A(0x35), |
|
454 |
|
455 U8X8_A(0x51), |
|
456 U8X8_A(0x51), |
|
457 U8X8_A(0xe9), |
|
458 U8X8_A(0x04), |
|
459 U8X8_A(0x00), |
|
460 |
|
461 U8X8_CA(0x22, 0x04), /* display update seq. option: clk -> CP -> LUT -> initial display -> pattern display */ |
|
462 U8X8_C(0x20), /* execute sequence */ |
|
463 |
|
464 U8X8_DLY(250), /* delay for 1500ms. The current sequence takes 1300ms */ |
|
465 U8X8_DLY(250), |
|
466 U8X8_DLY(250), |
|
467 U8X8_DLY(250), |
|
468 |
|
469 U8X8_DLY(250), |
|
470 U8X8_DLY(250), |
|
471 |
|
472 |
|
473 U8X8_END_TRANSFER(), /* disable chip */ |
|
474 U8X8_END() /* end of sequence */ |
|
475 }; |
|
476 |
|
477 |
|
478 uint8_t u8x8_d_ssd1607_v2_200x200(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) |
|
479 { |
|
480 switch(msg) |
|
481 { |
|
482 case U8X8_MSG_DISPLAY_SETUP_MEMORY: |
|
483 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1607_200x200_display_info); |
|
484 break; |
|
485 case U8X8_MSG_DISPLAY_INIT: |
|
486 u8x8_d_helper_display_init(u8x8); |
|
487 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_init_seq); |
|
488 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave0_seq); |
|
489 u8x8_d_ssd1607_200x200_first_init(u8x8); |
|
490 break; |
|
491 case U8X8_MSG_DISPLAY_SET_POWER_SAVE: |
|
492 if ( arg_int == 0 ) |
|
493 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave0_seq); |
|
494 else |
|
495 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave1_seq); |
|
496 break; |
|
497 case U8X8_MSG_DISPLAY_SET_FLIP_MODE: |
|
498 break; |
|
499 case U8X8_MSG_DISPLAY_DRAW_TILE: |
|
500 u8x8_d_ssd1607_draw_tile(u8x8, arg_int, arg_ptr); |
|
501 break; |
|
502 case U8X8_MSG_DISPLAY_REFRESH: |
|
503 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_v2_to_display_seq); |
|
504 break; |
|
505 default: |
|
506 return 0; |
|
507 } |
|
508 return 1; |
|
509 } |
|
510 |
|
511 |
|
512 /*=================================================*/ |
|
513 /* GDEP015OC1 */ |
|
514 /* https://github.com/olikraus/u8g2/issues/454 */ |
|
515 |
|
516 |
|
517 static const uint8_t u8x8_d_ssd1607_gd_to_display_seq[] = { |
|
518 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
519 |
|
520 /* |
|
521 0xaa, 0x09, 0x09, 0x19, 0x19, |
|
522 0x11, 0x11, 0x11, 0x11, 0x00, |
|
523 0x00, 0x00, 0x00, 0x00, 0x00, |
|
524 0x00, 0x00, 0x00, 0x00, 0x00, |
|
525 |
|
526 0x75, 0x77, 0x77, 0x77, 0x07, |
|
527 0x00, 0x00, 0x00, 0x00, 0x00 |
|
528 measured 1240 ms with IL3830 196x128 |
|
529 |
|
530 |
|
531 0x02, 0x02, 0x01, 0x11, 0x12, |
|
532 0x12, 0x12, 0x22, 0x22, 0x66, |
|
533 0x69, 0x59, 0x58, 0x99, 0x99, |
|
534 0x88, 0x00, 0x00, 0x00, 0x00, |
|
535 |
|
536 0xf8, 0xb4, 0x13, 0x51, 0x35, |
|
537 0x51, 0x51, 0xe9, 0x04, 0x00 |
|
538 |
|
539 */ |
|
540 |
|
541 U8X8_C(0x32), /* write LUT register*/ |
|
542 |
|
543 /* |
|
544 U8X8_A(0x50), U8X8_A(0xAA), U8X8_A(0x55), U8X8_A(0xAA), U8X8_A(0x11), |
|
545 U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), |
|
546 U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), |
|
547 U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), |
|
548 |
|
549 U8X8_A(0xFF), U8X8_A(0xFF), U8X8_A(0x1F), U8X8_A(0x00), U8X8_A(0x00), |
|
550 U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), |
|
551 */ |
|
552 U8X8_A(0x10), U8X8_A(0x18), U8X8_A(0x18), U8X8_A(0x08), U8X8_A(0x18), // numbers based on Waveshare demo code |
|
553 U8X8_A(0x18), U8X8_A(0x08), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), |
|
554 U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), |
|
555 U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), |
|
556 |
|
557 U8X8_A(0x13), U8X8_A(0x14), U8X8_A(0x44), U8X8_A(0x12), U8X8_A(0x00), |
|
558 U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), |
|
559 |
|
560 U8X8_CA(0x22, 0xc4), /* display update seq. option: clk -> CP -> LUT -> initial display -> pattern display */ |
|
561 U8X8_C(0x20), /* execute sequence */ |
|
562 |
|
563 U8X8_DLY(250), /* delay for 1500ms. The current sequence takes 1300ms */ |
|
564 U8X8_DLY(250), |
|
565 U8X8_DLY(250), |
|
566 // U8X8_DLY(250), |
|
567 |
|
568 // U8X8_DLY(250), |
|
569 // U8X8_DLY(250), |
|
570 |
|
571 |
|
572 U8X8_END_TRANSFER(), /* disable chip */ |
|
573 U8X8_END() /* end of sequence */ |
|
574 }; |
|
575 |
|
576 uint8_t u8x8_d_ssd1607_gd_200x200(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) |
|
577 { |
|
578 switch(msg) |
|
579 { |
|
580 case U8X8_MSG_DISPLAY_SETUP_MEMORY: |
|
581 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1607_200x200_display_info); |
|
582 break; |
|
583 case U8X8_MSG_DISPLAY_INIT: |
|
584 u8x8_d_helper_display_init(u8x8); |
|
585 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_init_seq); |
|
586 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave0_seq); |
|
587 u8x8_d_ssd1607_200x200_first_init(u8x8); |
|
588 break; |
|
589 case U8X8_MSG_DISPLAY_SET_POWER_SAVE: |
|
590 if ( arg_int == 0 ) |
|
591 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave0_seq); |
|
592 else |
|
593 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave1_seq); |
|
594 break; |
|
595 case U8X8_MSG_DISPLAY_SET_FLIP_MODE: |
|
596 break; |
|
597 case U8X8_MSG_DISPLAY_DRAW_TILE: |
|
598 u8x8_d_ssd1607_draw_tile(u8x8, arg_int, arg_ptr); |
|
599 break; |
|
600 case U8X8_MSG_DISPLAY_REFRESH: |
|
601 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_gd_to_display_seq); |
|
602 break; |
|
603 default: |
|
604 return 0; |
|
605 } |
|
606 return 1; |
|
607 } |
|
608 |
|
609 |
|
610 |
|
611 /*=================================================*/ |
|
612 |
|
613 static const uint8_t u8x8_d_ssd1607_ws_to_display_seq[] = { |
|
614 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
615 |
|
616 |
|
617 U8X8_C(0x32), /* write LUT register*/ |
|
618 |
|
619 U8X8_A(0x10), U8X8_A(0x18), U8X8_A(0x18), U8X8_A(0x08), U8X8_A(0x18), // numbers based on Waveshare demo code |
|
620 U8X8_A(0x18), U8X8_A(0x08), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), |
|
621 U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), |
|
622 U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), |
|
623 |
|
624 U8X8_A(0x13), U8X8_A(0x14), U8X8_A(0x44), U8X8_A(0x12), U8X8_A(0x00), |
|
625 U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), |
|
626 |
|
627 U8X8_CA(0x22, 0xc4), /* display update seq. option: clk -> CP -> LUT -> initial display -> pattern display */ |
|
628 U8X8_C(0x20), /* execute sequence */ |
|
629 |
|
630 U8X8_DLY(250), /* delay for 1250ms. */ |
|
631 U8X8_DLY(250), |
|
632 U8X8_DLY(250), |
|
633 U8X8_DLY(250), |
|
634 U8X8_DLY(250), |
|
635 |
|
636 |
|
637 U8X8_END_TRANSFER(), /* disable chip */ |
|
638 U8X8_END() /* end of sequence */ |
|
639 }; |
|
640 |
|
641 |
|
642 static const uint8_t u8x8_d_ssd1607_ws_to_refresh_seq[] = { |
|
643 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
644 |
|
645 |
|
646 U8X8_CA(0x22, 0x04), /* display update seq. option: clk -> CP -> LUT -> initial display -> pattern display */ |
|
647 U8X8_C(0x20), /* execute sequence */ |
|
648 |
|
649 // U8X8_DLY(250), |
|
650 // U8X8_DLY(250), |
|
651 |
|
652 |
|
653 U8X8_END_TRANSFER(), /* disable chip */ |
|
654 U8X8_END() /* end of sequence */ |
|
655 }; |
|
656 |
|
657 |
|
658 /* waveshare 200x200 */ |
|
659 static const uint8_t u8x8_d_ssd1607_ws_200x200_init_seq[] = { |
|
660 // suggested code from https://github.com/olikraus/u8g2/issues/637 |
|
661 |
|
662 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
663 |
|
664 U8X8_C(0x01), /* DRIVER_OUTPUT_CONTROL: LO(EPD_HEIGHT-1), HI(EPD_HEIGHT-1). GD = 0; SM = 0; TB = 0; */ |
|
665 U8X8_A(199),U8X8_A(0),U8X8_A(0), |
|
666 |
|
667 U8X8_C(0x0C), /* BOOSTER_SOFT_START_CONTROL */ |
|
668 U8X8_A(0xd7),U8X8_A(0xd6),U8X8_A(0x9d), |
|
669 |
|
670 U8X8_CA(0x2c, 0xa8), /* WRITE_VCOM_REGISTER: VCOM 7C */ |
|
671 U8X8_CA(0x3a, 0x1a), /* SET_DUMMY_LINE_PERIOD: 4 dummy lines per gate */ |
|
672 U8X8_CA(0x3b, 0x08), /* SET_GATE_TIME: 2us per line */ |
|
673 U8X8_CA(0x11, 0x03), /* DATA_ENTRY_MODE_SETTING: X increment; Y increment */ |
|
674 U8X8_CAA(0x44, 0, 24), /* SET_RAM_X_ADDRESS_START_END_POSITION: LO(x >> 3), LO((w-1) >> 3) */ |
|
675 U8X8_CAAAA(0x45, 0, 0, 199&255, 199>>8), /* SET_RAM_Y_ADDRESS_START_END_POSITION: LO(y), HI(y), LO(h - 1), HI(h - 1) */ |
|
676 U8X8_CA(0x4e, 0), /* LO(x >> 3) */ |
|
677 U8X8_CAA(0x4f, 0, 0), /* LO(y), HI(y >> 8) */ |
|
678 |
|
679 U8X8_END_TRANSFER(), /* disable chip */ |
|
680 U8X8_END() /* end of sequence */ |
|
681 |
|
682 }; |
|
683 |
|
684 |
|
685 uint8_t u8x8_d_ssd1607_ws_200x200(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) |
|
686 { |
|
687 switch(msg) |
|
688 { |
|
689 case U8X8_MSG_DISPLAY_SETUP_MEMORY: |
|
690 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1607_200x200_display_info); |
|
691 break; |
|
692 case U8X8_MSG_DISPLAY_INIT: |
|
693 u8x8_d_helper_display_init(u8x8); |
|
694 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_ws_200x200_init_seq); |
|
695 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave0_seq); |
|
696 u8x8_d_ssd1607_200x200_first_init(u8x8); |
|
697 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_ws_to_display_seq);; // to setup LUT |
|
698 break; |
|
699 case U8X8_MSG_DISPLAY_SET_POWER_SAVE: |
|
700 if ( arg_int == 0 ) |
|
701 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave0_seq); |
|
702 else |
|
703 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave1_seq); |
|
704 break; |
|
705 case U8X8_MSG_DISPLAY_SET_FLIP_MODE: |
|
706 break; |
|
707 case U8X8_MSG_DISPLAY_DRAW_TILE: |
|
708 u8x8_d_ssd1607_draw_tile(u8x8, arg_int, arg_ptr); |
|
709 break; |
|
710 case U8X8_MSG_DISPLAY_REFRESH: |
|
711 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_ws_to_refresh_seq); |
|
712 break; |
|
713 default: |
|
714 return 0; |
|
715 } |
|
716 return 1; |
|
717 } |
|
718 |