components/u8g2/csrc/u8x8_d_ssd1325.c

changeset 0
88d965579617
equal deleted inserted replaced
-1:000000000000 0:88d965579617
1 /*
2
3 u8x8_d_ssd1325.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 SSD1325:
35 128 x 80, 16 Gray Scale Dot Matrix
36
37 SSD0323: Identical to SSD1325, issue 720
38
39
40 */
41
42
43 #include "u8x8.h"
44
45
46
47 static const uint8_t u8x8_d_ssd1325_128x64_nhd_powersave0_seq[] = {
48 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
49 U8X8_C(0x0af), /* display on */
50 U8X8_END_TRANSFER(), /* disable chip */
51 U8X8_END() /* end of sequence */
52 };
53
54 static const uint8_t u8x8_d_ssd1325_128x64_nhd_powersave1_seq[] = {
55 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
56 U8X8_C(0x0ae), /* display off */
57 U8X8_END_TRANSFER(), /* disable chip */
58 U8X8_END() /* end of sequence */
59 };
60
61 static const uint8_t u8x8_d_ssd1325_128x64_nhd_flip0_seq[] = {
62 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
63 U8X8_CA(0x0a0, 0x052), /* remap */
64 U8X8_END_TRANSFER(), /* disable chip */
65 U8X8_END() /* end of sequence */
66 };
67
68 static const uint8_t u8x8_d_ssd1325_128x64_nhd_flip1_seq[] = {
69 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
70 U8X8_CA(0x0a0, 0x041), /* remap */
71 U8X8_END_TRANSFER(), /* disable chip */
72 U8X8_END() /* end of sequence */
73 };
74
75
76 /*
77 input:
78 one tile (8 Bytes)
79 output:
80 Tile for SSD1325 (32 Bytes)
81 */
82
83 static uint8_t u8x8_ssd1325_8to32_dest_buf[32];
84
85 static uint8_t *u8x8_ssd1325_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
86 {
87 uint8_t v;
88 uint8_t a,b;
89 uint8_t i, j;
90 uint8_t *dest;
91
92 for( j = 0; j < 4; j++ )
93 {
94 dest = u8x8_ssd1325_8to32_dest_buf;
95 dest += j;
96 a =*ptr;
97 ptr++;
98 b = *ptr;
99 ptr++;
100 for( i = 0; i < 8; i++ )
101 {
102 v = 0;
103 if ( a&1 ) v |= 0xf0;
104 if ( b&1 ) v |= 0x0f;
105 *dest = v;
106 dest+=4;
107 a >>= 1;
108 b >>= 1;
109 }
110 }
111
112 return u8x8_ssd1325_8to32_dest_buf;
113 }
114
115
116 /*===================================================================*/
117
118 static uint8_t u8x8_d_ssd1325_128x64_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
119 {
120 uint8_t x, y, c;
121 uint8_t *ptr;
122 switch(msg)
123 {
124 /* handled by the calling function
125 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
126 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1325_128x64_nhd_display_info);
127 break;
128 */
129
130 /* handled by the calling function
131 case U8X8_MSG_DISPLAY_INIT:
132 u8x8_d_helper_display_init(u8x8);
133 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_init_seq);
134 break;
135 */
136 case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
137 if ( arg_int == 0 )
138 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_powersave0_seq);
139 else
140 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_powersave1_seq);
141 break;
142
143 /* handled by the calling function
144 case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
145 if ( arg_int == 0 )
146 {
147 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_flip0_seq);
148 u8x8->x_offset = u8x8->display_info->default_x_offset;
149 }
150 else
151 {
152 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_flip1_seq);
153 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
154 }
155 break;
156 */
157 #ifdef U8X8_WITH_SET_CONTRAST
158 case U8X8_MSG_DISPLAY_SET_CONTRAST:
159 u8x8_cad_StartTransfer(u8x8);
160 u8x8_cad_SendCmd(u8x8, 0x081 );
161 u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1325 has range from 0 to 255 */
162 u8x8_cad_EndTransfer(u8x8);
163 break;
164 #endif
165 case U8X8_MSG_DISPLAY_DRAW_TILE:
166 u8x8_cad_StartTransfer(u8x8);
167 x = ((u8x8_tile_t *)arg_ptr)->x_pos;
168 x *= 4;
169
170 y = (((u8x8_tile_t *)arg_ptr)->y_pos);
171 y *= 8;
172 y += u8x8->x_offset; /* x_offset is used as y offset for the SSD1325 */
173
174
175 u8x8_cad_SendCmd(u8x8, 0x075 ); /* set row address */
176 u8x8_cad_SendArg(u8x8, y);
177 u8x8_cad_SendArg(u8x8, y+7);
178
179 do
180 {
181 c = ((u8x8_tile_t *)arg_ptr)->cnt;
182 ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
183
184 do
185 {
186 if ( ptr[0] | ptr[1] | ptr[2] | ptr[3] | ptr[4] | ptr[5] | ptr[6] | ptr[7] )
187 {
188 /* draw the tile if pattern is not zero for all bytes */
189 u8x8_cad_SendCmd(u8x8, 0x015 ); /* set column address */
190 u8x8_cad_SendArg(u8x8, x ); /* start */
191 u8x8_cad_SendArg(u8x8, x+3 ); /* end */
192
193
194
195 u8x8_cad_SendData(u8x8, 32, u8x8_ssd1325_8to32(u8x8, ptr));
196 }
197 else
198 {
199 /* tile is empty, use the graphics acceleration command */
200 u8x8_cad_SendCmd(u8x8, 0x024 ); // draw rectangle
201 u8x8_cad_SendArg(u8x8, x );
202 u8x8_cad_SendArg(u8x8, y );
203 u8x8_cad_SendArg(u8x8, x+3 );
204 u8x8_cad_SendArg(u8x8, y+7 );
205 u8x8_cad_SendArg(u8x8, 0 ); // clear
206 }
207 ptr += 8;
208 x += 4;
209 c--;
210 } while( c > 0 );
211
212 //x += 4;
213 arg_int--;
214 } while( arg_int > 0 );
215
216 u8x8_cad_SendCmd(u8x8, 0xe3); // no-op needs to be sent after last byte before cs is toggled.
217
218 u8x8_cad_EndTransfer(u8x8);
219 break;
220 default:
221 return 0;
222 }
223 return 1;
224 }
225
226 /*===================================================================*/
227
228 /* http://www.newhavendisplay.com/app_notes/OLED_2_7_12864.txt */
229 static const uint8_t u8x8_d_ssd1325_128x64_nhd_init_seq[] = {
230
231 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
232
233
234 U8X8_C(0x0ae), /* display off */
235 U8X8_CA(0x0b3, 0x091), /* set display clock divide ratio/oscillator frequency (set clock as 135 frames/sec) */
236 U8X8_CA(0x0a8, 0x03f), /* multiplex ratio: 0x03f * 1/64 duty */
237 U8X8_CA(0x0a2, 0x04c), /* display offset, shift mapping ram counter */
238 U8X8_CA(0x0a1, 0x000), /* display start line */
239 U8X8_CA(0x0ad, 0x002), /* master configuration: disable embedded DC-DC, enable internal VCOMH */
240 U8X8_CA(0x0a0, 0x052), /* remap configuration, horizontal address increment (bit 2 = 0), enable nibble remap (upper nibble is left, bit 1 = 1) */
241 U8X8_C(0x086), /* full current range (0x084, 0x085, 0x086) */
242 U8X8_C(0x0b8), /* set gray scale table */
243 U8X8_A(0x001), /* */
244 U8X8_A(0x011), /* */
245 U8X8_A(0x022), /* */
246 U8X8_A(0x032), /* */
247 U8X8_A(0x043), /* */
248 U8X8_A(0x054), /* */
249 U8X8_A(0x065), /* */
250 U8X8_A(0x076), /* */
251
252 U8X8_CA(0x081, 0x070), /* contrast, brightness, 0..128, Newhaven: 0x040 */
253 U8X8_CA(0x0b2, 0x051), /* frame frequency (row period) */
254 U8X8_CA(0x0b1, 0x055), /* phase length */
255 U8X8_CA(0x0bc, 0x010), /* pre-charge voltage level */
256 U8X8_CA(0x0b4, 0x002), /* set pre-charge compensation level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
257 U8X8_CA(0x0b0, 0x028), /* enable pre-charge compensation (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
258 U8X8_CA(0x0be, 0x01c), /* VCOMH voltage */
259 U8X8_CA(0x0bf, 0x002|0x00d), /* VSL voltage level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
260 U8X8_C(0x0a4), /* normal display mode */
261
262 U8X8_CA(0x023, 0x003), /* graphics accelleration: fill pixel */
263
264 U8X8_END_TRANSFER(), /* disable chip */
265 U8X8_END() /* end of sequence */
266 };
267
268 static const u8x8_display_info_t u8x8_nhd_ssd1325_128x64_display_info =
269 {
270 /* chip_enable_level = */ 0,
271 /* chip_disable_level = */ 1,
272
273 /* post_chip_enable_wait_ns = */ 20,
274 /* pre_chip_disable_wait_ns = */ 10,
275 /* reset_pulse_width_ms = */ 100,
276 /* post_reset_wait_ms = */ 100, /**/
277 /* sda_setup_time_ns = */ 100, /* SSD1325 */
278 /* sck_pulse_width_ns = */ 100, /* SSD1325 */
279 /* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
280 /* spi_mode = */ 0, /* active high, rising edge */
281 /* i2c_bus_clock_100kHz = */ 4,
282 /* data_setup_time_ns = */ 40,
283 /* write_pulse_width_ns = */ 60, /* SSD1325 */
284 /* tile_width = */ 16,
285 /* tile_hight = */ 8,
286 /* default_x_offset = */ 0, /* x_offset is used as y offset for the SSD1325 */
287 /* flipmode_x_offset = */ 8, /* x_offset is used as y offset for the SSD1325 */
288 /* pixel_width = */ 128,
289 /* pixel_height = */ 64
290 };
291
292 uint8_t u8x8_d_ssd1325_nhd_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
293 {
294 if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
295 {
296 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_nhd_ssd1325_128x64_display_info);
297 return 1;
298 }
299 else if ( msg == U8X8_MSG_DISPLAY_INIT )
300 {
301 u8x8_d_helper_display_init(u8x8);
302 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_init_seq);
303 return 1;
304 }
305 else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
306 {
307 if ( arg_int == 0 )
308 {
309 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_flip0_seq);
310 u8x8->x_offset = u8x8->display_info->default_x_offset;
311 }
312 else
313 {
314 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_flip1_seq);
315 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
316 }
317 return 1;
318 }
319 return u8x8_d_ssd1325_128x64_generic(u8x8, msg, arg_int, arg_ptr);
320 }
321
322 /*===================================================================*/
323 /* OSRAM Pictiva 128x64 OLED */
324 /* https://github.com/olikraus/u8g2/issues/720 */
325
326 static const uint8_t u8x8_d_ssd0323_os128064_init_seq[] = {
327
328 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
329 U8X8_C(0x0ae), /* display off */
330 U8X8_CA(0x0b3, 0x091), /* set display clock divide ratio/oscillator frequency (set clock as 135 frames/sec) */
331 U8X8_CA(0x0a8, 0x03f), /* multiplex ratio: 0x03f * 1/64 duty */
332 U8X8_CA(0x0a2, 0x040), /* display offset, shift mapping ram counter */
333 U8X8_CA(0x0a1, 0x000), /* display start line */
334 U8X8_CA(0x0ad, 0x002), /* master configuration: disable embedded DC-DC, enable internal VCOMH */
335 U8X8_CA(0x0a0, 0x052), /* remap configuration, horizontal address increment (bit 2 = 0), enable nibble remap (upper nibble is left, bit 1 = 1) */
336 U8X8_C(0x086), /* full current range (0x084, 0x085, 0x086) */
337 U8X8_C(0x0b8), /* set gray scale table */
338 U8X8_A(0x001), /* */
339 U8X8_A(0x011), /* */
340 U8X8_A(0x022), /* */
341 U8X8_A(0x032), /* */
342 U8X8_A(0x043), /* */
343 U8X8_A(0x054), /* */
344 U8X8_A(0x065), /* */
345 U8X8_A(0x076), /* */
346
347 U8X8_CA(0x081, 0x070), /* contrast, brightness, 0..128, Newhaven: 0x040 */
348 U8X8_CA(0x0b2, 0x051), /* frame frequency (row period) */
349 U8X8_CA(0x0b1, 0x055), /* phase length */
350 U8X8_CA(0x0bc, 0x010), /* pre-charge voltage level */
351 U8X8_CA(0x0b4, 0x002), /* set pre-charge compensation level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
352 U8X8_CA(0x0b0, 0x028), /* enable pre-charge compensation (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
353 U8X8_CA(0x0be, 0x01c), /* VCOMH voltage */
354 U8X8_CA(0x0bf, 0x002|0x00d), /* VSL voltage level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
355 U8X8_C(0x0a4), /* normal display mode */
356
357 U8X8_CA(0x023, 0x003), /* graphics accelleration: fill pixel */
358
359 U8X8_END_TRANSFER(), /* disable chip */
360 U8X8_END() /* end of sequence */
361 };
362
363 static const uint8_t u8x8_d_ssd0323_os128064_flip0_seq[] = {
364 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
365 U8X8_CA(0x0a0, 0x052), /* remap */
366 U8X8_CA(0x0a2, 0x040), /* display offset, shift mapping ram counter */
367 U8X8_END_TRANSFER(), /* disable chip */
368 U8X8_END() /* end of sequence */
369 };
370
371 static const uint8_t u8x8_d_ssd0323_os128064_flip1_seq[] = {
372 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
373 U8X8_CA(0x0a0, 0x041), /* remap */
374 U8X8_CA(0x0a2, 0x050), /* display offset, shift mapping ram counter */
375 U8X8_END_TRANSFER(), /* disable chip */
376 U8X8_END() /* end of sequence */
377 };
378
379
380 static const u8x8_display_info_t u8x8_ssd0323_os128064_display_info =
381 {
382 /* chip_enable_level = */ 0,
383 /* chip_disable_level = */ 1,
384
385 /* post_chip_enable_wait_ns = */ 20,
386 /* pre_chip_disable_wait_ns = */ 10,
387 /* reset_pulse_width_ms = */ 100,
388 /* post_reset_wait_ms = */ 100, /**/
389 /* sda_setup_time_ns = */ 100, /* SSD1325 */
390 /* sck_pulse_width_ns = */ 100, /* SSD1325 */
391 /* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
392 /* spi_mode = */ 0, /* active high, rising edge */
393 /* i2c_bus_clock_100kHz = */ 4,
394 /* data_setup_time_ns = */ 40,
395 /* write_pulse_width_ns = */ 60, /* SSD1325 */
396 /* tile_width = */ 16,
397 /* tile_hight = */ 8,
398 /* default_x_offset = */ 0, /* x_offset is used as y offset for the SSD1325 */
399 /* flipmode_x_offset = */ 0, /* x_offset is used as y offset for the SSD1325 */
400 /* pixel_width = */ 128,
401 /* pixel_height = */ 64
402 };
403
404 uint8_t u8x8_d_ssd0323_os128064(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
405 {
406 if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
407 {
408 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd0323_os128064_display_info);
409 return 1;
410 }
411 else if ( msg == U8X8_MSG_DISPLAY_INIT )
412 {
413 u8x8_d_helper_display_init(u8x8);
414 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd0323_os128064_init_seq);
415 return 1;
416 }
417 else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
418 {
419 if ( arg_int == 0 )
420 {
421 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd0323_os128064_flip0_seq);
422 u8x8->x_offset = u8x8->display_info->default_x_offset;
423 }
424 else
425 {
426 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd0323_os128064_flip1_seq);
427 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
428 }
429 return 1;
430 }
431 return u8x8_d_ssd1325_128x64_generic(u8x8, msg, arg_int, arg_ptr);
432 }
433
434
435

mercurial