Krolyxon
Commit 1d55752

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8U8g2srcclibu8x8_d_st7586s_jlx320160.c

246 lines · 8.1 KB · C

1/*
2 u8x8_d_st7586s_jlx320160.c
3
4 Display: 320x160 pixel
5 ST7586s: 384 x 160 x 2
6
7 takeover from https://github.com/olikraus/u8g2/issues/1183
8
9 Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
10
11 Copyright (c) 2023, 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
56
57static const uint8_t u8x8_d_st7586s_jlx320160_flip0_seq[] = {
58 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
59 U8X8_C(0x036), /* Scan Direction Setting */
60 U8X8_A(0x000), /* COM159 -> COM0 SEG383 -> SEG0 */
61 U8X8_C(0x037), /* Start line 0 */
62 U8X8_A(0x000),
63 U8X8_END_TRANSFER(), /* disable chip */
64 U8X8_END() /* end of sequence */
65};
66
67/* Flip Mode is not supported, use u8g2 rotation instead */
68
69static const uint8_t u8x8_d_st7586s_jlx320160_flip1_seq[] = {
70 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
71 U8X8_C(0x036), /* Scan Direction Setting */
72 U8X8_A(0x000), /* COM0 -> COM159 SEG0 -> SEG383 */
73 U8X8_C(0x037), /* Start line 0 */
74 U8X8_A(0x000),
75 U8X8_END_TRANSFER(), /* disable chip */
76 U8X8_END() /* end of sequence */
77};
78
79static const uint8_t u8x8_d_st7586s_jlx320160_init_seq[] = {
80 U8X8_START_TRANSFER(),/* enable chip */
81 U8X8_END_TRANSFER(),/* disable chip */
82 // U8G_ESC_RST(1), /* hardware reset */
83 U8X8_DLY(60), /* Delay 60 ms */
84 U8X8_START_TRANSFER(),/* enable chip */
85
86 U8X8_C(0x001), // Soft reset
87 U8X8_DLY(60), // Delay 120 ms
88
89 U8X8_C(0x011), // Sleep Out
90 U8X8_C(0x028), // Display OFF
91 U8X8_DLY(25), // Delay 50 ms
92
93 U8X8_CAA(0x0C0,70,1),// Vop
94
95 U8X8_CA(0x0C3,0x002), // BIAS: 0 = 1/14, 2 = 1/12
96
97 U8X8_CA(0x0C4,0x007), // Booster = x8
98
99 U8X8_CA(0x0D0,0x01D), // Enable Analog Circuit
100
101 U8X8_CA(0x0B3,0x000), // Set FOSC divider
102
103 U8X8_CA(0x0B5,0x000), // N-Line = 0
104
105 U8X8_C(0x039), // 0x39 Monochrome mode. 0x38 - gray Mode
106
107 U8X8_C(0x03A), // Enable DDRAM Interface
108 U8X8_A(0x002), // monochrome and 4-level
109
110 U8X8_C(0x036), // Scan Direction Setting
111 U8X8_A(0x000), // COM:C159->C0 SEG: SEG383->SEG0
112
113 U8X8_C(0x0B1), // First output COM
114 U8X8_A(0x000), //
115
116 U8X8_C(0x0B0), // Duty Setting (num rows - 1)
117 U8X8_A(0x09F),
118
119 U8X8_C(0x020), // Display inversion off
120
121 U8X8_C(0x02A), // Column Address Setting
122 U8X8_A(0), // COL0 -> COL127
123 U8X8_A(0), //
124 U8X8_A(0), //
125 U8X8_A(112-1), // 112*3=336 pixels
126
127 U8X8_C(0x02B), // Row Address Setting
128 U8X8_A(0x000), // ROW0 -> ROW159
129 U8X8_A(0x000), //
130 U8X8_A(0x000), //
131 U8X8_A(0x09F), // 160 pixels
132
133 U8X8_C(0x029), // Display ON
134 U8X8_END_TRANSFER(),/* disable chip */
135 U8X8_END() /* end of sequence */
136};
137
138static const u8x8_display_info_t u8x8_st7586s_jlx320160_display_info =
139{
140 /* chip_enable_level = */ 0,
141 /* chip_disable_level = */ 1,
142
143 /* post_chip_enable_wait_ns = */ 5,
144 /* pre_chip_disable_wait_ns = */ 5,
145 /* reset_pulse_width_ms = */ 1,
146 /* post_reset_wait_ms = */ 6,
147 /* sda_setup_time_ns = */ 20,
148 /* sck_pulse_width_ns = */ 100, /* datasheet ST7586S */
149 /* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
150 /* ST7586+Atmega128RFA1 works with 8MHz */
151 /* spi_mode = */ 3, /* active high, rising edge */
152 /* i2c_bus_clock_100kHz = */ 4,
153 /* data_setup_time_ns = */ 20, /* datasheet suggests min 20 */
154 /* write_pulse_width_ns = */ 40,
155 /* tile_width = */ 42,
156 /* tile_height = */ 20,
157 /* default_x_offset = */ 0, /* abused as flag to know if we are flipped */
158 /* flipmode_x_offset = */ 1, /* as pixel order different for normal/flipped */
159 /* pixel_width = */ 320,
160 /* pixel_height = */ 160
161};
162
163/* https://github.com/olikraus/u8g2/issues/2186 */
164uint8_t u8x8_d_st7586s_jlx320160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
165{
166 uint16_t c;
167 uint8_t *ptr;
168 uint8_t i, byte;
169 uint32_t input;
170 uint8_t output[8];
171// uint8_t output[4];
172 switch (msg) {
173 case U8X8_MSG_DISPLAY_DRAW_TILE:
174 u8x8_cad_StartTransfer(u8x8); // OK Start transfer
175 u8x8_cad_SendCmd(u8x8, 0x02B); /* Row Address Setting */
176 u8x8_cad_SendArg(u8x8, 0x000);
177 u8x8_cad_SendArg(u8x8, 0x008 * ((u8x8_tile_t *)arg_ptr)->y_pos);
178 u8x8_cad_SendArg(u8x8, 0x000);
179// u8x8_cad_SendArg(u8x8, 0x09F); // should set end row based on display dimensions
180 u8x8_cad_SendArg(u8x8, u8x8->display_info->pixel_height - 1); /* should this be u8x8->display_info->pixel_height - 1 */
181 u8x8_cad_SendCmd(u8x8, 0x02C); /* cmd write display data to ram */
182 c = ((u8x8_tile_t *) arg_ptr)->cnt; //
183 c *= 8;
184 ptr = ((u8x8_tile_t *) arg_ptr)->tile_ptr; //
185
186 while (c > 0)
187 {
188 input = (((uint32_t)ptr[0] << 16) | ((uint32_t)ptr[1] << 8) | (uint32_t)ptr[2]);
189 for (i=0; i<8; i++)
190 {
191 byte = 0;
192 if (input & 0x800000) // if bit 23
193 byte = byte | 0xC0; //set pixel 1
194 if (input & 0x400000) // if bit 22
195 byte = byte | 0x18; //set pixel 2
196 if (input & 0x200000) // if bit 22
197 byte = byte | 0x3; //set pixel 3
198 output[i] = byte;
199 input <<= 3;
200 }
201 u8x8_cad_SendData(u8x8, 8, output);
202 ptr += 3;
203 c -= 3;
204 }
205 u8x8_cad_EndTransfer(u8x8);
206 break;
207 case U8X8_MSG_DISPLAY_INIT:
208 u8x8_d_helper_display_init(u8x8);
209 u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_jlx320160_init_seq);
210 break;
211 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
212 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7586s_jlx320160_display_info);
213 break;
214 case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
215 if ( arg_int == 0 )
216 {
217 u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_jlx320160_flip0_seq);
218 u8x8->x_offset = u8x8->display_info->default_x_offset;
219 }
220 else
221 {
222 u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_jlx320160_flip1_seq);
223 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
224 }
225 break;
226 case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
227 if (arg_int == 0)
228 u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_sleep_off);
229 else
230 u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_sleep_on);
231 break;
232#ifdef U8X8_WITH_SET_CONTRAST
233 case U8X8_MSG_DISPLAY_SET_CONTRAST:
234 u8x8_cad_StartTransfer(u8x8);
235 u8x8_cad_SendCmd(u8x8, 0x0C0);
236 u8x8_cad_SendArg(u8x8, arg_int);
237 u8x8_cad_SendArg(u8x8, 1);
238 u8x8_cad_EndTransfer(u8x8);
239 break;
240#endif
241 default:
242 return 0;
243 }
244 return 1;
245}
246