Krolyxon
Commit 3120783

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8U8g2srcclibu8x8_d_ssd1306_72x40.c

266 lines · 9.3 KB · C

1/*
2
3 u8x8_d_ssd1306_72x40.c
4
5 Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
6
7 Copyright (c) 2019, 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*/
35
36
37#include "u8x8.h"
38
39
40
41/*
42EastRising 0.41 OLED
43https://www.buydisplay.com/default/white-0-42-inch-oled-display-panel-72x40-iic-i2c-serial-spi-ssd1306
44
45
46 command(0xae);//--turn off oled panel
47
48 command(0xd5);//--set display clock divide ratio/oscillator frequency
49 command(0x80);//--set divide ratio
50
51 command(0xa8);//--set multiplex ratio
52 command(0x27);//--1/40 duty
53
54 command(0xd3);//-set display offset
55 command(0x00);//-not offset
56
57 command(0xad);//--Internal IREF Setting
58 command(0x30);//--
59
60 command(0x8d);//--set Charge Pump enable/disable
61 command(0x14);//--set(0x10) disable
62
63 command(0x40);//--set start line address
64
65 command(0xa6);//--set normal display
66
67 command(0xa4);//Disable Entire Display On
68
69 command(0xa1);//--set segment re-map 128 to 0
70
71 command(0xC8);//--Set COM Output Scan Direction 64 to 0
72
73 command(0xda);//--set com pins hardware configuration
74 command(0x12);
75
76 command(0x81);//--set contrast control register
77 command(0xaf);
78
79 command(0xd9);//--set pre-charge period
80 command(0x22);
81
82 command(0xdb);//--set vcomh
83 command(0x20);
84
85 command(0xaf);//--turn on oled panel
86
87
88*/
89static const uint8_t u8x8_d_ssd1306_72x40_er_init_seq[] = {
90
91 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
92
93
94 U8X8_C(0x0ae), /* display off */
95 U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
96 U8X8_CA(0x0a8, 0x027), /* multiplex ratio, 0.42 OLED: 0x27*/
97 U8X8_CA(0x0d3, 0x000), /* display offset, 0.42 OLED */
98 U8X8_CA(0x0ad, 0x030), /* Internal IREF Setting for the 0.42 OLED, see also issue https://github.com/olikraus/u8g2/issues/1047 */
99 U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable, 0.66 OLED 0x14*/
100
101 U8X8_C(0x040), /* set display start line to 0, 0.66 OLED */
102 U8X8_C(0x0a6), /* none inverted normal display mode */
103 U8X8_C(0x0a4), /* output ram to display */
104
105 U8X8_CA(0x020, 0x000), /* horizontal addressing mode */
106
107 U8X8_C(0x0a1), /* segment remap a0/a1, 0.66 OLED */
108 U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse, 0.66 OLED */
109 // Flipmode
110 // U8X8_C(0x0a0), /* segment remap a0/a1*/
111 // U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
112
113 U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5), 0.66 OLED */
114 U8X8_CA(0x081, 0x0af), /* [2] set contrast control, 0.42 OLED */
115 U8X8_CA(0x0d9, 0x022), /* [2] pre-charge period 0x022/f1, 0.42 OLED datasheet: 0x22 */
116 U8X8_CA(0x0db, 0x020), /* vcomh deselect level, 0.42 OLED datasheet: 0x20 */
117
118 U8X8_C(0x02e), /* Deactivate scroll */
119
120 U8X8_END_TRANSFER(), /* disable chip */
121 U8X8_END() /* end of sequence */
122};
123
124static const uint8_t u8x8_d_ssd1306_72x40_powersave0_seq[] = {
125 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
126 U8X8_C(0x0af), /* display on */
127 U8X8_END_TRANSFER(), /* disable chip */
128 U8X8_END() /* end of sequence */
129};
130
131static const uint8_t u8x8_d_ssd1306_72x40_powersave1_seq[] = {
132 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
133 U8X8_C(0x0ae), /* display off */
134 U8X8_END_TRANSFER(), /* disable chip */
135 U8X8_END() /* end of sequence */
136};
137
138static const uint8_t u8x8_d_ssd1306_72x40_flip0_seq[] = {
139 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
140 U8X8_C(0x0a1), /* segment remap a0/a1*/
141 U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
142 U8X8_END_TRANSFER(), /* disable chip */
143 U8X8_END() /* end of sequence */
144};
145
146static const uint8_t u8x8_d_ssd1306_72x40_flip1_seq[] = {
147 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
148 U8X8_C(0x0a0), /* segment remap a0/a1*/
149 U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
150 U8X8_END_TRANSFER(), /* disable chip */
151 U8X8_END() /* end of sequence */
152};
153
154
155static uint8_t u8x8_d_ssd1306_72x40_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
156{
157 uint8_t x, c;
158 uint8_t *ptr;
159 switch(msg)
160 {
161 /* handled by the calling function
162 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
163 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_72x40_display_info);
164 break;
165 case U8X8_MSG_DISPLAY_INIT:
166 u8x8_d_helper_display_init(u8x8);
167 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_72x40_er_init_seq);
168 break;
169 */
170 case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
171 if ( arg_int == 0 )
172 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_72x40_powersave0_seq);
173 else
174 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_72x40_powersave1_seq);
175 break;
176 case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
177 if ( arg_int == 0 )
178 {
179 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_72x40_flip0_seq);
180 u8x8->x_offset = u8x8->display_info->default_x_offset;
181 }
182 else
183 {
184 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_72x40_flip1_seq);
185 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
186 }
187 break;
188#ifdef U8X8_WITH_SET_CONTRAST
189 case U8X8_MSG_DISPLAY_SET_CONTRAST:
190 u8x8_cad_StartTransfer(u8x8);
191 u8x8_cad_SendCmd(u8x8, 0x081 );
192 u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1306 has range from 0 to 255 */
193 u8x8_cad_EndTransfer(u8x8);
194 break;
195#endif
196 case U8X8_MSG_DISPLAY_DRAW_TILE:
197 u8x8_cad_StartTransfer(u8x8);
198 x = ((u8x8_tile_t *)arg_ptr)->x_pos;
199 x *= 8;
200 x += u8x8->x_offset;
201 u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
202 u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
203 u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
204
205 do
206 {
207 c = ((u8x8_tile_t *)arg_ptr)->cnt;
208 ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
209 u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
210 arg_int--;
211 } while( arg_int > 0 );
212
213 u8x8_cad_EndTransfer(u8x8);
214 break;
215 default:
216 return 0;
217 }
218 return 1;
219}
220
221
222static const u8x8_display_info_t u8x8_ssd1306_72x40_display_info =
223{
224 /* chip_enable_level = */ 0,
225 /* chip_disable_level = */ 1,
226
227 /* post_chip_enable_wait_ns = */ 20,
228 /* pre_chip_disable_wait_ns = */ 10,
229 /* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
230 /* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
231 /* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
232 /* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
233 /* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
234 /* spi_mode = */ 0, /* active high, rising edge */
235 /* i2c_bus_clock_100kHz = */ 4,
236 /* data_setup_time_ns = */ 40,
237 /* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
238 /* tile_width = */ 9,
239 /* tile_height = */ 5,
240 /* default_x_offset = */ 28,
241 /* flipmode_x_offset = */ 28,
242 /* pixel_width = */ 72,
243 /* pixel_height = */ 40
244};
245
246/*
247EastRising 0.41 OLED
248https://www.buydisplay.com/default/white-0-42-inch-oled-display-panel-72x40-iic-i2c-serial-spi-ssd1306
249*/
250uint8_t u8x8_d_ssd1306_72x40_er(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
251{
252 if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
253 {
254 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_72x40_display_info);
255 return 1;
256 }
257 else if ( msg == U8X8_MSG_DISPLAY_INIT )
258 {
259 u8x8_d_helper_display_init(u8x8);
260 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_72x40_er_init_seq);
261 return 1;
262 }
263 return u8x8_d_ssd1306_72x40_generic(u8x8, msg, arg_int, arg_ptr);
264}
265
266