Krolyxon
Commit 1d55752

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8U8g2srcclibu8x8_d_st7586s_s028hn118a.c

254 lines · 8.7 KB · C

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