Krolyxon
Commit 3120783

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8U8g2srcclibu8x8_d_st7586s_erc240160.c

261 lines · 8.9 KB · C

1/*
2 u8x8_d_st7586s_erc240160.c
3
4 Display: 240x160 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_erc240160_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(0x0C8), /* COM159 -> COM0 SEG383 -> SEG0 */
58 U8X8_C(0x037), /* Start line 0 */
59 U8X8_A(0x000),
60 U8X8_C(0x02A), /* Column Address Setting */
61 U8X8_A(0x000), /* COL8 -> COL127 */
62 U8X8_A(0x008),
63 U8X8_A(0x000),
64 U8X8_A(0x07F), /* 120*3=240 pixels + 120 unused */
65 U8X8_END_TRANSFER(), /* disable chip */
66 U8X8_END() /* end of sequence */
67};
68
69static const uint8_t u8x8_d_st7586s_erc240160_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_C(0x02A), /* Column Address Setting */
76 U8X8_A(0x000), /* COL0 -> COL119 */
77 U8X8_A(0x000),
78 U8X8_A(0x000),
79 U8X8_A(0x077), /* 120*3=240 pixels + 120 unused */
80 U8X8_END_TRANSFER(), /* disable chip */
81 U8X8_END() /* end of sequence */
82};
83
84static const uint8_t u8x8_d_st7586s_erc240160_init_seq[] = {
85 U8X8_START_TRANSFER(),/* enable chip */
86 U8X8_END_TRANSFER(),/* disable chip */
87 // U8G_ESC_RST(1), /* hardware reset */
88 U8X8_DLY(60), /* Delay 60 ms */
89 U8X8_START_TRANSFER(),/* enable chip */
90
91 U8X8_C(0x001), // Soft reset
92 U8X8_DLY(60), // Delay 120 ms
93
94 U8X8_C(0x011), // Sleep Out
95 U8X8_C(0x028), // Display OFF
96 U8X8_DLY(25), // Delay 50 ms
97
98 U8X8_CAA(0x0C0,0x036,0x01),// Vop = 136h data sheet suggested 0x0145 but this caused streaks
99
100 U8X8_CA(0x0C3,0x000), // BIAS = 1/14
101
102 U8X8_CA(0x0C4,0x007), // Booster = x8
103
104 U8X8_CA(0x0D0,0x01D), // Enable Analog Circuit
105
106 U8X8_CA(0x0B3,0x000), // Set FOSC divider
107
108 U8X8_CA(0x0B5,0x000), // N-Line = 0
109
110 U8X8_C(0x039), // 0x39 Monochrome mode. 0x38 - gray Mode
111
112 U8X8_C(0x03A), // Enable DDRAM Interface
113 U8X8_A(0x002), // monochrome and 4-level
114
115 U8X8_C(0x036), // Scan Direction Setting
116 U8X8_A(0x0C8), // COM:C159->C0 SEG: SEG383->SEG0
117
118 U8X8_C(0x0B1), // First output COM
119 U8X8_A(0x000), //
120
121 U8X8_C(0x0B0), // Duty Setting (num rows - 1)
122 U8X8_A(0x09F),
123
124 U8X8_C(0x020), // Display inversion off
125
126 U8X8_C(0x02A), // Column Address Setting
127 U8X8_A(0x000), // COL0 -> COL127
128 U8X8_A(0x008), //
129 U8X8_A(0x000), //
130 U8X8_A(0x07F), // 80*3=240 pixels
131
132 U8X8_C(0x02B), // Row Address Setting
133 U8X8_A(0x000), // ROW0 -> ROW159
134 U8X8_A(0x000), //
135 U8X8_A(0x000), //
136 U8X8_A(0x09F), // 160 pixels
137
138 U8X8_C(0x029), // Display ON
139 U8X8_END_TRANSFER(),/* disable chip */
140 U8X8_END() /* end of sequence */
141};
142
143static const u8x8_display_info_t u8x8_st7586s_erc240160_display_info =
144{
145 /* chip_enable_level = */ 0,
146 /* chip_disable_level = */ 1,
147
148 /* post_chip_enable_wait_ns = */ 5,
149 /* pre_chip_disable_wait_ns = */ 5,
150 /* reset_pulse_width_ms = */ 1,
151 /* post_reset_wait_ms = */ 6,
152 /* sda_setup_time_ns = */ 20,
153 /* sck_pulse_width_ns = */ 100, /* datasheet ST7586S */
154 /* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
155 /* ST7586+Atmega128RFA1 works with 8MHz */
156 /* spi_mode = */ 3, /* active high, rising edge */
157 /* i2c_bus_clock_100kHz = */ 4,
158 /* data_setup_time_ns = */ 20, /* datasheet suggests min 20 */
159 /* write_pulse_width_ns = */ 40,
160 /* tile_width = */ 30,
161 /* tile_height = */ 20,
162 /* default_x_offset = */ 0, /* abused as flag to know if we are flipped */
163 /* flipmode_x_offset = */ 1, /* as pixel order different for normal/flipped */
164 /* pixel_width = */ 240,
165 /* pixel_height = */ 160
166};
167
168/*******************************************************************************
169 * st7586s_erc240160 driver. ST7586 based display from buydisplay.com
170 ******************************************************************************/
171uint8_t u8x8_d_st7586s_erc240160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
172
173 uint8_t c;
174 uint8_t *ptr;
175 uint8_t i, byte;
176 uint32_t input;
177 uint8_t output[4];
178 switch (msg) {
179 case U8X8_MSG_DISPLAY_DRAW_TILE:
180 u8x8_cad_StartTransfer(u8x8); // OK Start transfer
181 u8x8_cad_SendCmd(u8x8, 0x02B); /* Row Address Setting */
182 u8x8_cad_SendArg(u8x8, 0x000);
183 u8x8_cad_SendArg(u8x8, 0x008 * ((u8x8_tile_t *)arg_ptr)->y_pos);
184 u8x8_cad_SendArg(u8x8, 0x000);
185 u8x8_cad_SendArg(u8x8, 0x09F); // should set end row based on display dimensions
186 u8x8_cad_SendCmd(u8x8, 0x02C); /* cmd write display data to ram */
187 c = ((u8x8_tile_t *) arg_ptr)->cnt; //
188 c *= 8;
189 ptr = ((u8x8_tile_t *) arg_ptr)->tile_ptr; //
190
191// The ST7586S has an unusual 3 pixels per byte format the ERC240160 is even more annoying
192// as it has every 3rd COM line disconnected for extra oddness so here we read in a byte
193// (8 pixels) and pack that into 4 bytes of 2 pixels + 1 unused each. This has to be done
194// in a different order for flipped, normal UUx11x22 flipped 11x22xUU
195 while (c > 0) {
196 input = ((uint8_t)ptr[0]);
197
198 for (i=0; i<4; i++)
199 {
200 byte = 0;
201 if (u8x8->x_offset ==0){
202 if (input & 0x80) // if bit 7
203 byte = byte | 0x18; //set pixel 1
204 if (input & 0x40) // if bit 6
205 byte = byte | 0x3; //set pixel 2
206 }
207 if (u8x8->x_offset ==1){
208 if (input & 0x80) // if bit 7
209 byte = byte | 0xC0; //set pixel 1
210 if (input & 0x40) // if bit 6
211 byte = byte | 0x18; //set pixel 2
212 }
213 output[i] = byte;
214 input <<= 2;
215 }
216
217 u8x8_cad_SendData(u8x8, 4, output);
218 ptr += 1;
219 c -= 1;
220 }
221 u8x8_cad_EndTransfer(u8x8);
222 break;
223 case U8X8_MSG_DISPLAY_INIT:
224 u8x8_d_helper_display_init(u8x8);
225 u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_erc240160_init_seq);
226 break;
227 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
228 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7586s_erc240160_display_info);
229 break;
230 case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
231 if ( arg_int == 0 )
232 {
233 u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_erc240160_flip0_seq);
234 u8x8->x_offset = u8x8->display_info->default_x_offset;
235 }
236 else
237 {
238 u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_erc240160_flip1_seq);
239 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
240 }
241 break;
242 case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
243 if (arg_int == 0)
244 u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_sleep_off);
245 else
246 u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_sleep_on);
247 break;
248#ifdef U8X8_WITH_SET_CONTRAST
249 case U8X8_MSG_DISPLAY_SET_CONTRAST:
250 u8x8_cad_StartTransfer(u8x8);
251 u8x8_cad_SendCmd(u8x8, 0x0C0);
252 u8x8_cad_SendArg(u8x8, arg_int);
253 u8x8_cad_SendArg(u8x8, 1);
254 u8x8_cad_EndTransfer(u8x8);
255 break;
256#endif
257 default:
258 return 0;
259 }
260 return 1;
261}