Krolyxon
Commit 3120783

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8U8g2srcclibu8x8_d_st7586s_jlx384160.c

256 lines · 8.7 KB · C

1/*
2 u8x8_d_st7586s_jlx384160.c
3
4 copyied from u8x8_d_st7586s_s028hn118a.c
5
6 Display: 384x160 pixel, https://github.com/olikraus/u8g2/issues/1932
7 ST7586s: 384 x 160 x 2
8
9 Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
10
11 Copyright (c) 2022, olikraus@gmail.com
12
13 All rights reserved.
14 Redistribution and use in source and binary forms, with or without modification,
15 are permitted provided that the following conditions are met:
16 * Redistributions of source code must retain the above copyright notice, this list
17 of conditions and the following disclaimer.
18
19 * Redistributions in binary form must reproduce the above copyright notice, this
20 list of conditions and the following disclaimer in the documentation and/or other
21 materials provided with the distribution.
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 "u8g2.h"
39
40
41static const uint8_t u8x8_d_st7586s_sleep_on[] = {
42 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
43 U8X8_C(0x010), /* set power save mode */
44 U8X8_END_TRANSFER(), /* disable chip */
45 U8X8_END() /* end of sequence */
46};
47
48static const uint8_t u8x8_d_st7586s_sleep_off[] = {
49 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
50 U8X8_C(0x011), //Sleep out
51 U8X8_DLY(50), /* delay 50 ms */
52 U8X8_END_TRANSFER(), /* disable chip */
53 U8X8_END() /* end of sequence */
54};
55
56static const uint8_t u8x8_d_st7586s_jlx384160_flip0_seq[] = {
57 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
58 U8X8_C(0x036), /* Scan Direction Setting */
59 U8X8_A(0x000), /* COM0 -> COM159 SEG0 -> SEG384 */
60 U8X8_C(0x037), /* Start line 0 */
61 U8X8_A(0x000),
62 U8X8_END_TRANSFER(), /* disable chip */
63 U8X8_END() /* end of sequence */
64};
65
66static const uint8_t u8x8_d_st7586s_jlx384160_flip1_seq[] = {
67 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
68 U8X8_C(0x036), /* Scan Direction Setting */
69 U8X8_A(0x0C8), /* COM159 -> COM0 SEG384 -> SEG0 */
70 U8X8_C(0x037), /* Start line 0 */
71 U8X8_A(0x000),
72 U8X8_END_TRANSFER(), /* disable chip */
73 U8X8_END() /* end of sequence */
74};
75
76static uint8_t u8x8_d_st7586s_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
77 uint8_t c;
78 uint8_t *ptr;
79 uint8_t i, byte;
80 uint32_t input;
81 uint8_t output[8];
82 switch (msg) {
83 case U8X8_MSG_DISPLAY_DRAW_TILE:
84 u8x8_cad_StartTransfer(u8x8); // OK Start transfer
85 u8x8_cad_SendCmd(u8x8, 0x02B); /* Row Address Setting */
86 u8x8_cad_SendArg(u8x8, 0x000);
87 u8x8_cad_SendArg(u8x8, 0x008 * ((u8x8_tile_t *)arg_ptr)->y_pos);
88 u8x8_cad_SendArg(u8x8, 0x000);
89 u8x8_cad_SendArg(u8x8, u8x8->display_info->pixel_height - 1); /* should this be u8x8->display_info->pixel_height - 1 */
90 u8x8_cad_SendCmd(u8x8, 0x02C); /* cmd write display data to ram */
91 c = ((u8x8_tile_t *) arg_ptr)->cnt; //
92 c *= 8;
93 ptr = ((u8x8_tile_t *) arg_ptr)->tile_ptr; //
94
95// The ST7586S has an unusual 3 pixels per byte format so here we read in 3 bytes (24 pixels) and
96// pack that into 8 bytes of 3 pixels each
97 while (c > 0) {
98 input = (((uint32_t)ptr[0] << 16) | ((uint32_t)ptr[1] << 8) | (uint32_t)ptr[2]);
99 for (i=0; i<8; i++)
100 {
101 byte = 0;
102 if (input & 0x800000) // if bit 23
103 byte = byte | 0xC0; //set pixel 1
104 if (input & 0x400000) // if bit 22
105 byte = byte | 0x18; //set pixel 2
106 if (input & 0x200000) // if bit 22
107 byte = byte | 0x3; //set pixel 3
108 output[i] = byte;
109 input <<= 3;
110 }
111 u8x8_cad_SendData(u8x8, 8, output);
112 ptr += 3;
113 c -= 3;
114 }
115 u8x8_cad_EndTransfer(u8x8);
116 break;
117 case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
118 if (arg_int == 0)
119 u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_sleep_off);
120 else
121 u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_sleep_on);
122 break;
123#ifdef U8X8_WITH_SET_CONTRAST
124 case U8X8_MSG_DISPLAY_SET_CONTRAST:
125 u8x8_cad_StartTransfer(u8x8);
126 u8x8_cad_SendCmd(u8x8, 0x0C0);
127 u8x8_cad_SendArg(u8x8, arg_int);
128 u8x8_cad_SendArg(u8x8, 0);
129 u8x8_cad_EndTransfer(u8x8);
130 break;
131#endif
132 default:
133 return 0;
134 }
135 return 1;
136}
137
138static const uint8_t u8x8_d_st7586s_jlx384160_init_seq[] = {
139 U8X8_START_TRANSFER(),/* enable chip */
140 U8X8_END_TRANSFER(),/* disable chip */
141// U8G_ESC_RST(15), /* hardware reset */
142 U8X8_DLY(60), /* Delay 60 ms */
143 U8X8_START_TRANSFER(),/* enable chip */
144
145 U8X8_C(0x001), // Soft reset
146 U8X8_DLY(60), // Delay 120 ms
147
148 U8X8_C(0x011), // Sleep Out
149 U8X8_C(0x028), // Display OFF
150 U8X8_DLY(25), // Delay 50 ms
151
152 U8X8_CAA(0x0C0,0x0E5,0x00),// Vop = F0h in trace a bit too dark
153
154 U8X8_CA(0x0C3,0x004), // BIAS = 1/10 0x04 in trace
155
156 U8X8_CA(0x0C4,0x005), // Booster = x6 0x05 in trace
157
158 U8X8_CA(0x0D0,0x01D), // Enable Analog Circuit
159
160 U8X8_CA(0x0B3,0x000), // Set FOSC divider
161
162 U8X8_CA(0x0B5,0x08B), // N-Line = 0
163
164 U8X8_C(0x039), // 0x39 Monochrome mode. 0x38 - gray Mode
165
166 U8X8_C(0x03A), // Enable DDRAM Interface
167 U8X8_A(0x002), // monochrome and 4-level
168
169 U8X8_C(0x036), // Scan Direction Setting
170 U8X8_A(0x000), // COM0 -> COM159 SEG0 -> SEG384
171
172 U8X8_C(0x0B0), // Duty Setting (num rows - 1)
173 U8X8_A(0x09f), // 160-1
174
175 U8X8_C(0x020), // Display inversion off
176
177 U8X8_C(0x02A), // Column Address Setting
178 U8X8_A(0x000), // COL0 -> COL127
179 U8X8_A(0x000), //
180 U8X8_A(0x000), //
181 U8X8_A(0x07f), // 128*3=384 pixels
182
183 U8X8_C(0x02B), // Row Address Setting
184 U8X8_A(0x000), // ROW0 -> ROW135
185 U8X8_A(0x000), //
186 U8X8_A(0x000), //
187 U8X8_A(159), // 160 pixels
188
189 U8X8_C(0x0F1), // Frame rate monochrome
190 U8X8_A(0x00C), // The factory firmware set this to 49.0 Hz 0x07
191 U8X8_A(0x00C), // This caused a shimmer under 50Hz LED lights
192 U8X8_A(0x00C), // 69.0 Hz (0x0C) fixes this and should avoid the
193 U8X8_A(0x00C), // issue in the US too
194
195 U8X8_C(0x029), // Display ON
196 U8X8_END_TRANSFER(),/* disable chip */
197 U8X8_END() /* end of sequence */
198};
199
200static const u8x8_display_info_t u8x8_st7586s_jlx384160_display_info =
201{
202 /* chip_enable_level = */ 0,
203 /* chip_disable_level = */ 1,
204
205 /* post_chip_enable_wait_ns = */ 5,
206 /* pre_chip_disable_wait_ns = */ 5,
207 /* reset_pulse_width_ms = */ 1,
208 /* post_reset_wait_ms = */ 6,
209 /* sda_setup_time_ns = */ 20,
210 /* sck_pulse_width_ns = */ 100, /* datasheet ST7586S */
211 /* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
212 /* ST7586+Atmega128RFA1 works with 8MHz */
213 /* spi_mode = */ 3, /* active high, rising edge */
214 /* i2c_bus_clock_100kHz = */ 4,
215 /* data_setup_time_ns = */ 20, /* datasheet suggests min 20 */
216 /* write_pulse_width_ns = */ 40,
217 /* tile_width = */ 48,
218 /* tile_height = */ 20,
219 /* default_x_offset = */ 0,
220 /* flipmode_x_offset = */ 0,
221 /* pixel_width = */ 384,
222 /* pixel_height = */ 160
223};
224
225/*******************************************************************************
226 * st7586s_jlx384160 driver. This is the display in the SMART Response XE. This requires 16 bit mode.
227 ******************************************************************************/
228uint8_t u8x8_d_st7586s_jlx384160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
229 if (u8x8_d_st7586s_common(u8x8, msg, arg_int, arg_ptr) != 0)
230 return 1;
231
232 switch (msg) {
233 case U8X8_MSG_DISPLAY_INIT:
234 u8x8_d_helper_display_init(u8x8);
235 u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_jlx384160_init_seq);
236 break;
237 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
238 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7586s_jlx384160_display_info);
239 break;
240 case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
241 if ( arg_int == 0 )
242 {
243 u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_jlx384160_flip0_seq);
244 u8x8->x_offset = u8x8->display_info->default_x_offset;
245 }
246 else
247 {
248 u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_jlx384160_flip1_seq);
249 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
250 }
251 break;
252 default:
253 return 0;
254 }
255 return 1;
256}