Krolyxon
Commit 1d55752

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8U8g2srcclibu8x8_d_hd44102.c

352 lines · 10.5 KB · C

1/*
2
3 u8x8_d_hd44102.c
4
5 Support for HD44102 and T7932 controller (https://github.com/olikraus/u8g2/issues/1492)
6
7 Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
8
9 Copyright (c) 2021, olikraus@gmail.com
10 All rights reserved.
11
12 Redistribution and use in source and binary forms, with or without modification,
13 are permitted provided that the following conditions are met:
14
15 * Redistributions of source code must retain the above copyright notice, this list
16 of conditions and the following disclaimer.
17
18 * Redistributions in binary form must reproduce the above copyright notice, this
19 list of conditions and the following disclaimer in the documentation and/or other
20 materials provided with the distribution.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
34 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
36
37*/
38#include "u8x8.h"
39
40
41
42
43static const uint8_t u8x8_d_hd44102_init_seq[] = {
44 U8X8_C(0x03b), /* upcount */
45 U8X8_C(0x03e), /* start at the top */
46 U8X8_END() /* end of sequence */
47};
48
49static const uint8_t u8x8_d_hd44102_powersave0_seq[] = {
50 U8X8_C(0x039), /* display on */
51 U8X8_END() /* end of sequence */
52};
53
54static const uint8_t u8x8_d_hd44102_powersave1_seq[] = {
55 U8X8_C(0x038), /* display off */
56 U8X8_END() /* end of sequence */
57};
58
59/*
60 data: pointer to "cnt" bytes
61 cnt: number of bytes, which should be sent
62 page: 0..3: the current page within the display
63 offset: offset location on the display, where the data should be placed
64 cs_none: 3-bit chip select pattern for not selecting any display
65 cs0: 3-bit chip select pattern for the left display (0..49)
66 cs1: 3-bit chip select pattern for the middle display (50..99)
67 cs2: 3-bit chip select pattern for the right display (100..149)
68
69 The csX bit pattern is:
70 bit 0: CS
71 bit 1: CS1
72 bit 2: CS2
73 see u8x8_byte_set_ks0108_cs() in u8x8_byte.c
74
75*/
76static void u8x8_hd44102_outy(u8x8_t *u8x8, uint8_t *data, uint8_t cnt, uint8_t page, uint8_t offset, uint8_t cs_none, uint8_t cs0, uint8_t cs1, uint8_t cs2)
77{
78 uint8_t pos = offset;
79 uint8_t data_cnt;
80
81 /* write to left display? */
82 if ( pos < 50 && cnt > 0 )
83 {
84 /* calculate number of bytes to sent */
85 data_cnt = 50 - pos;
86 if ( data_cnt > cnt )
87 data_cnt = cnt;
88 if ( data_cnt > 50 )
89 data_cnt = 50;
90
91 /* sent the data */
92 u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, cs0, NULL);
93 u8x8_cad_SendCmd(u8x8, (page << 6) | pos );
94 u8x8_cad_SendData(u8x8, data_cnt, data);
95 u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, cs_none, NULL);
96
97 /* adjust the data */
98 data += data_cnt;
99 pos += data_cnt;
100 cnt -= data_cnt;
101 }
102
103 /* write to middle display? */
104 if ( pos < 100 && cnt > 0 )
105 {
106 /* calculate number of bytes to sent */
107 data_cnt = 100 - pos;
108 if ( data_cnt > cnt )
109 data_cnt = cnt;
110 if ( data_cnt > 50 )
111 data_cnt = 50;
112
113 /* sent the data */
114 u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, cs1, NULL);
115 u8x8_cad_SendCmd(u8x8, (page << 6) | (pos-50) );
116 u8x8_cad_SendData(u8x8, data_cnt, data);
117 u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, cs_none, NULL);
118
119 /* adjust the data */
120 data += data_cnt;
121 pos += data_cnt;
122 cnt -= data_cnt;
123 }
124
125 /* write to right display? */
126 if ( pos < 150 && cnt > 0 )
127 {
128 /* calculate number of bytes to sent */
129 data_cnt = 150 - pos;
130 if ( data_cnt > cnt )
131 data_cnt = cnt;
132 if ( data_cnt > 50 )
133 data_cnt = 50;
134
135 /* sent the data */
136 u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, cs2, NULL);
137 u8x8_cad_SendCmd(u8x8, (page << 6) | (pos-100) );
138 u8x8_cad_SendData(u8x8, data_cnt, data);
139 u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, cs_none, NULL);
140
141 /* adjust the data */
142 data += data_cnt;
143 pos += data_cnt;
144 cnt -= data_cnt;
145 }
146}
147
148
149
150
151static const u8x8_display_info_t u8x8_hd44102_150x32_display_info =
152{
153 /* chip_enable_level = */ 0, /* KS0108/HD44102: Not used */
154 /* chip_disable_level = */ 1, /* KS0108/HD44102: Not used */
155
156 /* post_chip_enable_wait_ns = */ 100,
157 /* pre_chip_disable_wait_ns = */ 20,
158 /* reset_pulse_width_ms = */ 1,
159 /* post_reset_wait_ms = */ 6,
160 /* sda_setup_time_ns = */ 12,
161 /* sck_pulse_width_ns = */ 75, /* KS0108/HD44102: Not used */
162 /* sck_clock_hz = */ 4000000UL, /* KS0108/HD44102: Not used */
163 /* spi_mode = */ 0, /* active high, rising edge */
164 /* i2c_bus_clock_100kHz = */ 4, /* KS0108/HD44102: Not used */
165 /* data_setup_time_ns = */ 200,
166 /* write_pulse_width_ns = */ 250, /* KS0108/HD44102: actially 450 ns, but additional 200 ns are added by the byte transfer function */
167 /* tile_width = */ 19, /* width of 19*8=152 pixel */
168 /* tile_height = */ 4,
169 /* default_x_offset = */ 0,
170 /* flipmode_x_offset = */ 0,
171 /* pixel_width = */ 150,
172 /* pixel_height = */ 32
173};
174
175//uint8_t u8x8_d_hd44102_150x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
176
177uint8_t u8x8_d_t7932_150x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
178{
179 uint8_t cs[4] = {1, 2, 4, 0};
180 uint8_t i;
181 uint8_t x, cnt;
182 switch(msg)
183 {
184 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
185 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_hd44102_150x32_display_info);
186 break;
187 case U8X8_MSG_DISPLAY_INIT:
188 u8x8_d_helper_display_init(u8x8);
189
190 for( i = 0; i < 3; i++ )
191 {
192 u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, cs[i], NULL);
193 u8x8_cad_SendSequence(u8x8, u8x8_d_hd44102_init_seq);
194 u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, cs[3], NULL);
195 }
196
197 break;
198 case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
199
200 for( i = 0; i < 3; i++ )
201 {
202 u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, cs[i], NULL);
203 if ( arg_int == 0 )
204 {
205 u8x8_cad_SendSequence(u8x8, u8x8_d_hd44102_powersave0_seq);
206 }
207 else
208 {
209 u8x8_cad_SendSequence(u8x8, u8x8_d_hd44102_powersave1_seq);
210 }
211 u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, cs[3], NULL);
212 }
213 break;
214// The HD44102 can not mirror the cols and rows, use U8g2 for rotation
215// case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
216// break;
217// The HD44102 has no internal contrast command
218// case U8X8_MSG_DISPLAY_SET_CONTRAST:
219// break;
220 case U8X8_MSG_DISPLAY_DRAW_TILE:
221 x = ((u8x8_tile_t *)arg_ptr)->x_pos;
222 cnt = ((u8x8_tile_t *)arg_ptr)->cnt;
223 x*=8;
224 cnt*=8;
225
226 do
227 {
228 u8x8_hd44102_outy(u8x8,
229 ((u8x8_tile_t *)arg_ptr)->tile_ptr,
230 cnt,
231 ((u8x8_tile_t *)arg_ptr)->y_pos,
232 x,
233 cs[3], cs[0], cs[1], cs[2]);
234 arg_int--;
235 x += cnt;
236 } while (arg_int > 0);
237
238
239 break;
240 default:
241 return 0;
242 }
243 return 1;
244}
245
246static const u8x8_display_info_t u8x8_hd44102_100x64_display_info =
247{
248 /* chip_enable_level = */ 0, /* KS0108/HD44102: Not used */
249 /* chip_disable_level = */ 1, /* KS0108/HD44102: Not used */
250
251 /* post_chip_enable_wait_ns = */ 100,
252 /* pre_chip_disable_wait_ns = */ 20,
253 /* reset_pulse_width_ms = */ 1,
254 /* post_reset_wait_ms = */ 6,
255 /* sda_setup_time_ns = */ 12,
256 /* sck_pulse_width_ns = */ 75, /* KS0108/HD44102: Not used */
257 /* sck_clock_hz = */ 4000000UL, /* KS0108/HD44102: Not used */
258 /* spi_mode = */ 0, /* active high, rising edge */
259 /* i2c_bus_clock_100kHz = */ 4, /* KS0108/HD44102: Not used */
260 /* data_setup_time_ns = */ 200,
261 /* write_pulse_width_ns = */ 250, /* KS0108/HD44102: actially 450 ns, but additional 200 ns are added by the byte transfer function */
262 /* tile_width = */ 13, /* width of 13*8=104 pixel */
263 /* tile_height = */ 8,
264 /* default_x_offset = */ 0,
265 /* flipmode_x_offset = */ 0,
266 /* pixel_width = */ 100,
267 /* pixel_height = */ 64
268};
269
270uint8_t u8x8_d_hd44102_100x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
271{
272 uint8_t i;
273 uint8_t x, cnt, page;
274 switch(msg)
275 {
276 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
277 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_hd44102_100x64_display_info);
278 break;
279 case U8X8_MSG_DISPLAY_INIT:
280 u8x8_d_helper_display_init(u8x8);
281
282 for( i = 0; i < 4; i++ )
283 {
284 u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, i, NULL);
285 u8x8_cad_SendSequence(u8x8, u8x8_d_hd44102_init_seq);
286 u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
287 }
288
289 break;
290 case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
291
292 for( i = 0; i < 4; i++ )
293 {
294 u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, i, NULL);
295 if ( arg_int == 0 )
296 {
297 u8x8_cad_SendSequence(u8x8, u8x8_d_hd44102_powersave0_seq);
298 }
299 else
300 {
301 u8x8_cad_SendSequence(u8x8, u8x8_d_hd44102_powersave1_seq);
302 }
303 u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
304 }
305 break;
306// The HD44102 can not mirror the cols and rows, use U8g2 for rotation
307// case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
308// break;
309// The HD44102 has no internal contrast command
310// case U8X8_MSG_DISPLAY_SET_CONTRAST:
311// break;
312 case U8X8_MSG_DISPLAY_DRAW_TILE:
313 x = ((u8x8_tile_t *)arg_ptr)->x_pos;
314 cnt = ((u8x8_tile_t *)arg_ptr)->cnt;
315 page = ((u8x8_tile_t *)arg_ptr)->y_pos;
316 x*=8;
317 cnt*=8;
318 if ( page < 4 )
319 {
320 do
321 {
322 u8x8_hd44102_outy(u8x8,
323 ((u8x8_tile_t *)arg_ptr)->tile_ptr,
324 cnt,
325 page,
326 x,
327 7, 0, 1, 7);
328 arg_int--;
329 x += cnt;
330 } while (arg_int > 0);
331 }
332 else
333 {
334 do
335 {
336 u8x8_hd44102_outy(u8x8,
337 ((u8x8_tile_t *)arg_ptr)->tile_ptr,
338 cnt,
339 page-4,
340 x,
341 7, 2, 3, 7);
342 arg_int--;
343 x += cnt;
344 } while (arg_int > 0);
345 }
346
347 break;
348 default:
349 return 0;
350 }
351 return 1;
352}