Krolyxon
Commit 3120783

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8U8g2srcclibu8x8_d_sh1122.c

290 lines · 8.8 KB · C

1/*
2
3 u8x8_d_sh1122.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
35 Idea: SH1122 is a horizontal device, which doesn't support u8x8
36 However in the similar SSD1362 device, we do the correct tile conversion,
37 so maybe takeover code from SSD1362 to SH1122, so that SH1122 can also
38 support u8x8
39
40
41*/
42#include "u8x8.h"
43
44
45
46
47static const uint8_t u8x8_d_sh1122_powersave0_seq[] = {
48 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
49 U8X8_C(0x0af), /* sh1122: display on */
50 U8X8_END_TRANSFER(), /* disable chip */
51 U8X8_END() /* end of sequence */
52};
53
54static const uint8_t u8x8_d_sh1122_powersave1_seq[] = {
55 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
56 U8X8_C(0x0ae), /* sh1122: display off */
57 U8X8_END_TRANSFER(), /* disable chip */
58 U8X8_END() /* end of sequence */
59};
60
61
62
63
64/*
65 input:
66 one tile (8 Bytes)
67 output:
68 Tile for SH1122 (32 Bytes)
69*/
70
71/*
72static uint8_t u8x8_sh1122_to32_dest_buf[32];
73
74static uint8_t *u8x8_sh1122_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
75{
76 uint8_t v;
77 uint8_t a,b;
78 uint8_t i, j;
79 uint8_t *dest;
80
81 for( j = 0; j < 4; j++ )
82 {
83 dest = u8x8_sh1122_to32_dest_buf;
84 dest += j;
85 a =*ptr;
86 ptr++;
87 b = *ptr;
88 ptr++;
89 for( i = 0; i < 8; i++ )
90 {
91 v = 0;
92 if ( a&1 ) v |= 0xf0;
93 if ( b&1 ) v |= 0x0f;
94 *dest = v;
95 dest+=4;
96 a >>= 1;
97 b >>= 1;
98 }
99 }
100
101 return u8x8_sh1122_to32_dest_buf;
102}
103*/
104
105
106static uint8_t u8x8_write_byte_to_16gr_device(u8x8_t *u8x8, uint8_t b)
107{
108 static uint8_t buf[4];
109 static uint8_t map[4] = { 0, 0x00f, 0x0f0, 0x0ff };
110 buf [3] = map[b & 3];
111 b>>=2;
112 buf [2] = map[b & 3];
113 b>>=2;
114 buf [1] = map[b & 3];
115 b>>=2;
116 buf [0] = map[b & 3];
117 return u8x8_cad_SendData(u8x8, 4, buf);
118}
119
120uint8_t u8x8_d_sh1122_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
121{
122 uint8_t x;
123 uint8_t y, c, i;
124 uint8_t *ptr;
125 switch(msg)
126 {
127 /* U8X8_MSG_DISPLAY_SETUP_MEMORY is handled by the calling function */
128 /*
129 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
130 break;
131 case U8X8_MSG_DISPLAY_INIT:
132 u8x8_d_helper_display_init(u8x8);
133 u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_256x64_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_sh1122_powersave0_seq);
139 else
140 u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_powersave1_seq);
141 break;
142#ifdef U8X8_WITH_SET_CONTRAST
143 case U8X8_MSG_DISPLAY_SET_CONTRAST:
144 u8x8_cad_StartTransfer(u8x8);
145 u8x8_cad_SendCmd(u8x8, 0x081 );
146 u8x8_cad_SendArg(u8x8, arg_int ); /* sh1122 has range from 0 to 255 */
147 u8x8_cad_EndTransfer(u8x8);
148 break;
149#endif
150 case U8X8_MSG_DISPLAY_DRAW_TILE:
151 u8x8_cad_StartTransfer(u8x8);
152 x = ((u8x8_tile_t *)arg_ptr)->x_pos;
153 x *= 2; // 4 Mar 2022: probably this needs to be 4, but this device is call with x=0 only
154 x += u8x8->x_offset;
155
156 y = (((u8x8_tile_t *)arg_ptr)->y_pos);
157 y *= 8;
158
159
160 c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
161 ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* data ptr to the tiles */
162 for( i = 0; i < 8; i++ )
163 {
164 u8x8_cad_SendCmd(u8x8, 0x0b0 ); /* set row address */
165 u8x8_cad_SendArg(u8x8, y);
166 u8x8_cad_SendCmd(u8x8, x & 15 ); /* lower 4 bit*/
167 u8x8_cad_SendCmd(u8x8, 0x010 | (x >> 4) ); /* higher 3 bit */
168 c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
169
170 while ( c > 0 )
171 {
172 u8x8_write_byte_to_16gr_device(u8x8, *ptr);
173 c--;
174 ptr++;
175 }
176 y++;
177 }
178
179
180 u8x8_cad_EndTransfer(u8x8);
181 break;
182 default:
183 return 0;
184 }
185 return 1;
186}
187
188/*=========================================================*/
189
190static const uint8_t u8x8_d_sh1122_256x64_flip0_seq[] = {
191 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
192 U8X8_C(0x0a1), /* remap */
193 U8X8_C(0x0c8), /* remap */
194 U8X8_C(0x060),
195 U8X8_END_TRANSFER(), /* disable chip */
196 U8X8_END() /* end of sequence */
197};
198
199static const uint8_t u8x8_d_sh1122_256x64_flip1_seq[] = {
200 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
201 U8X8_C(0x0a0), /* remap */
202 U8X8_C(0x0c0), /* remap */
203 U8X8_C(0x040),
204 U8X8_END_TRANSFER(), /* disable chip */
205 U8X8_END() /* end of sequence */
206};
207
208static const u8x8_display_info_t u8x8_sh1122_256x64_display_info =
209{
210 /* chip_enable_level = */ 0,
211 /* chip_disable_level = */ 1,
212
213 /* post_chip_enable_wait_ns = */ 20,
214 /* pre_chip_disable_wait_ns = */ 10,
215 /* reset_pulse_width_ms = */ 10, /* sh1122: 10 us */
216 /* post_reset_wait_ms = */ 20, /* */
217 /* sda_setup_time_ns = */ 125, /* sh1122: cycle time is 250ns, so use 250/2 */
218 /* sck_pulse_width_ns = */ 125, /* sh1122: cycle time is 250ns, so use 250/2 */
219 /* sck_clock_hz = */ 40000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
220 /* spi_mode = */ 0, /* active high, rising edge */
221 /* i2c_bus_clock_100kHz = */ 4,
222 /* data_setup_time_ns = */ 10,
223 /* write_pulse_width_ns = */ 150, /* sh1122: cycle time is 300ns, so use 300/2 = 150 */
224 /* tile_width = */ 32, /* 256 pixel, so we require 32 bytes for this */
225 /* tile_height = */ 8,
226 /* default_x_offset = */ 0, /* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
227 /* flipmode_x_offset = */ 0,
228 /* pixel_width = */ 256,
229 /* pixel_height = */ 64
230};
231
232
233static const uint8_t u8x8_d_sh1122_256x64_init_seq[] = {
234
235 U8X8_DLY(1),
236 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
237 U8X8_DLY(1),
238
239 U8X8_C(0xae), /* display off */
240 U8X8_C(0x40), /* display start line */
241 U8X8_C(0x0a0), /* remap */
242 U8X8_C(0x0c0), /* remap */
243 U8X8_CA(0x81, 0x80), /* set display contrast */
244 U8X8_CA(0xa8, 0x3f), /* multiplex ratio 1/64 Duty (0x0F~0x3F) */
245 U8X8_CA(0xad, 0x81), /* use buildin DC-DC with 0.6 * 500 kHz */
246
247 U8X8_CA(0xd5, 0x50), /* set display clock divide ratio (lower 4 bit)/oscillator frequency (upper 4 bit) */
248 U8X8_CA(0xd3, 0x00), /* display offset, shift mapping ram counter */
249 U8X8_CA(0xd9, 0x22), /* pre charge (lower 4 bit) and discharge(higher 4 bit) period */
250 U8X8_CA(0xdb, 0x35), /* VCOM deselect level */
251 U8X8_CA(0xdc, 0x35), /* Pre Charge output voltage */
252 U8X8_C(0x030), /* discharge level */
253
254 U8X8_DLY(1), /* delay */
255
256 U8X8_END_TRANSFER(), /* disable chip */
257 U8X8_END() /* end of sequence */
258};
259
260
261uint8_t u8x8_d_sh1122_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
262{
263 switch(msg)
264 {
265 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
266 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1122_256x64_display_info);
267 break;
268 case U8X8_MSG_DISPLAY_INIT:
269 u8x8_d_helper_display_init(u8x8);
270 u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_256x64_init_seq);
271 break;
272 case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
273 if ( arg_int == 0 )
274 {
275 u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_256x64_flip0_seq);
276 u8x8->x_offset = u8x8->display_info->default_x_offset;
277 }
278 else
279 {
280 u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_256x64_flip1_seq);
281 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
282 }
283 break;
284
285 default:
286 return u8x8_d_sh1122_common(u8x8, msg, arg_int, arg_ptr);
287 }
288 return 1;
289}
290