Krolyxon
Commit 1d55752

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8U8g2srcclibu8x8_d_ld7032_60x32.c

457 lines · 17.0 KB · C

1/*
2
3 u8x8_d_ld7032_60x32.c
4 Note: Flip Mode is NOT supported
5
6 Also contains 128x36 OLED variant
7
8 Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
9
10 Copyright (c) 2023, olikraus@gmail.com
11 All rights reserved.
12
13 Redistribution and use in source and binary forms, with or without modification,
14 are permitted provided that the following conditions are met:
15
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
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
28 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
37*/
38
39
40#include "u8x8.h"
41
42
43/* testboard U8GLIB_LD7032_60x32 u8g(11, 12, 9, 10, 8); // SPI Com: SCK = 11, MOSI = 12, CS = 9, A0 = 10, RST = 8 (SW SPI Nano Board) */
44/* http://www.seeedstudio.com/document/pdf/0.5OLED%20SPEC.pdf */
45#ifdef OBSOLETE
46static const uint8_t u8x8_d_ld7032_60x32_init_seq_old[] = {
47
48 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
49
50 //U8X8_CA(0x002, 0x001), /* Dot Matrix Display ON */
51 U8X8_CA(0x014, 0x000), /* Stand-by OFF */
52 U8X8_CA(0x01a, 0x004), /* Dot Matrix Frame Rate, special value for this OLED from manual*/
53 U8X8_CA(0x01d, 0x000), /* Graphics Memory Writing Direction: reset default (right down, horizontal) */
54 U8X8_CA(0x009, 0x000), /* Display Direction: reset default (x,y: min --> max) */
55 U8X8_CAA(0x030, 0x000, 0x03b), /* Display Size X, Column Start - End*/
56 U8X8_CAA(0x032, 0x000, 0x01f), /* Display Size Y, Row Start - End*/
57 U8X8_CA(0x010, 0x000), /* Peak Pulse Width Set: 0 SCLK */
58 U8X8_CA(0x016, 0x000), /* Peak Pulse Delay Set: 0 SCLK */
59 U8X8_CA(0x012, 0x040), /* Dot Matrix Current Level Set: 0x050 * 1 uA = 80 uA */
60 U8X8_CA(0x018, 0x003), /* Pre-Charge Pulse Width: 3 SCLK */
61 U8X8_CA(0x044, 0x002), /* Pre-Charge Mode: Every Time */
62 U8X8_CA(0x048, 0x003), /* Row overlap timing: Pre-Charge + Peak Delay + Peak boot Timing */
63 U8X8_CA(0x03f, 0x011), /* VCC_R_SEL: ??? */
64 U8X8_CA(0x03d, 0x000), /* VSS selection: 2.8V */
65 //U8X8_CA(0x002, 0x001), /* Dot Matrix Display ON */
66
67
68 U8X8_END_TRANSFER(), /* disable chip */
69 U8X8_END() /* end of sequence */
70};
71#endif
72
73/* new sequence https://github.com/olikraus/u8g2/issues/865 */
74static const uint8_t u8x8_d_ld7032_60x32_init_seq[] = {
75
76 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
77
78 U8X8_CA(0x02, 0x00), /* Dot Matrix Display OFF */
79 U8X8_CA(0x14, 0x00), /* Stand-by OFF, OSCA Start */
80 U8X8_CA(0x1a, 0x04), /* Dot Matrix Frame Rate, special value for this OLED from manual 4 => 120Hz*/
81 U8X8_CA(0x1d, 0x00), /* Graphics Memory Writing Direction: reset default (right down, horizontal) */
82 U8X8_CA(0x09, 0x00), /* Display Direction: reset default (x,y: min --> max) */
83 U8X8_CAA(0x30, 0x00, 0x3B), /* Display Size X, Column Start - End 0-0x3b(59)*/
84 U8X8_CAA(0x32, 0x00, 0x1F), /* Display Size Y, Row Start - End 0-0x1f(31)*/
85 U8X8_CA(0x34, 0x00), /* Data Reading/Writing Box X start */
86 U8X8_CA(0x35, 0x07), /* Data Reading/Writing Box X end */
87 U8X8_CA(0x36, 0x00), /* Data Reading/Writing Box Y start */
88 U8X8_CA(0x37, 0x1F), /* Data Reading/Writing Box Y end */
89 U8X8_CA(0x38, 0x00), /* Display Start Address X */
90 U8X8_CA(0x39, 0x00), /* Display Start Address Y */
91 U8X8_CA(0x10, 0x00), /* Peak Pulse Width Set: 0 SCLK */
92 U8X8_CA(0x16, 0x00), /* Peak Pulse Delay Set: 0 SCLK */
93 U8X8_CA(0x12, 0x40), /* 0x32, 0x50 or 0x40 Dot Matrix Current Level Set: 0x050 * 1 uA = 80 uA */
94 U8X8_CA(0x18, 0x03), /* Pre-Charge Pulse Width: 3 SCLK */
95 U8X8_CA(0x44, 0x02), /* Pre-Charge Mode: Every Time */
96 U8X8_CA(0x48, 0x03), /* Row overlap timing: Pre-Charge + Peak Delay + Peak boot Timing */
97 U8X8_CA(0x17, 0x00), /* Row Scan */
98 U8X8_CA(0x13, 0x00), /* Row Scan Sequence Setting */
99 U8X8_CA(0x1C, 0x00), /* Data Reverse */
100 U8X8_CA(0x3f, 0x11), /* VCC_R_SEL: Internal Regulator enabled(D4=1) and VCC_R=VCC_C*0.7(D0=1) */
101 U8X8_CA(0x3d, 0x00), /* VSS selection: 2.8V */
102
103 U8X8_END_TRANSFER(), /* disable chip */
104 U8X8_END() /* end of sequence */
105};
106
107static const uint8_t u8x8_d_ld7032_60x32_powersave0_seq[] = {
108 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
109 U8X8_CA(0x002, 0x001), /* Dot Matrix Display ON */
110 U8X8_END_TRANSFER(), /* disable chip */
111 U8X8_END() /* end of sequence */
112};
113
114static const uint8_t u8x8_d_ld7032_60x32_powersave1_seq[] = {
115 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
116 U8X8_CA(0x002, 0x000), /* Dot Matrix Display ON */
117 U8X8_END_TRANSFER(), /* disable chip */
118 U8X8_END() /* end of sequence */
119};
120
121static const uint8_t u8x8_d_ld7032_60x32_flip0_seq[] = {
122 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
123 U8X8_CA(0x009, 0x000), /* Display Direction: reset default (x,y: min --> max) */
124 U8X8_END_TRANSFER(), /* disable chip */
125 U8X8_END() /* end of sequence */
126};
127
128static const uint8_t u8x8_d_ld7032_60x32_flip1_seq[] = {
129 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
130 //U8X8_CA(0x009, 0x002), /* Display Direction: reset default (x,y: min --> max) */
131 U8X8_END_TRANSFER(), /* disable chip */
132 U8X8_END() /* end of sequence */
133};
134
135
136static uint8_t u8x8_d_ld7032_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
137{
138 uint8_t x, c;
139 uint8_t *ptr;
140 switch(msg)
141 {
142 /* handled by the calling function
143 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
144 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ld7032_60x32_display_info);
145 break;
146 */
147 case U8X8_MSG_DISPLAY_INIT:
148 u8x8_d_helper_display_init(u8x8);
149 u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_init_seq);
150 break;
151 case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
152 if ( arg_int == 0 )
153 u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_powersave0_seq);
154 else
155 u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_powersave1_seq);
156 break;
157 case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
158 if ( arg_int == 0 )
159 {
160 u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_flip0_seq);
161 u8x8->x_offset = u8x8->display_info->default_x_offset;
162 }
163 else
164 {
165 u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_flip1_seq);
166 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
167 }
168 break;
169#ifdef U8X8_WITH_SET_CONTRAST
170 case U8X8_MSG_DISPLAY_SET_CONTRAST:
171 u8x8_cad_StartTransfer(u8x8);
172 u8x8_cad_SendCmd(u8x8, 0x012 );
173 if ( arg_int > 0x07f ) /* default is 0x040, limit to 0x07f to be on the safe side (hopefully) */
174 arg_int= 0x07f;
175 u8x8_cad_SendArg(u8x8, arg_int ); /* values from 0x00 to 0x0ff are allowed, bit will all values be safe??? */
176 u8x8_cad_EndTransfer(u8x8);
177 break;
178#endif
179 case U8X8_MSG_DISPLAY_DRAW_TILE:
180 u8x8_cad_StartTransfer(u8x8);
181 x = ((u8x8_tile_t *)arg_ptr)->x_pos;
182 x += u8x8->x_offset/8;
183 u8x8_cad_SendCmd(u8x8, 0x034 );
184 u8x8_cad_SendArg(u8x8, x );
185 u8x8_cad_SendCmd(u8x8, 0x035 );
186 u8x8_cad_SendArg(u8x8, 0x007 );
187 u8x8_cad_SendCmd(u8x8, 0x036 );
188 u8x8_cad_SendArg(u8x8, (((u8x8_tile_t *)arg_ptr)->y_pos)*8 );
189 u8x8_cad_SendCmd(u8x8, 0x037 );
190 u8x8_cad_SendArg(u8x8, 0x01f );
191 u8x8_cad_SendCmd(u8x8, 0x008 );
192
193
194 do
195 {
196 c = ((u8x8_tile_t *)arg_ptr)->cnt;
197 ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
198 u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
199 arg_int--;
200 } while( arg_int > 0 );
201
202 u8x8_cad_EndTransfer(u8x8);
203 break;
204 default:
205 return 0;
206 }
207 return 1;
208}
209
210
211static const u8x8_display_info_t u8x8_ld7032_60x32_display_info =
212{
213 /* chip_enable_level = */ 0,
214 /* chip_disable_level = */ 1,
215
216 /* post_chip_enable_wait_ns = */ 15,
217 /* pre_chip_disable_wait_ns = */ 20,
218 /* reset_pulse_width_ms = */ 100,
219 /* post_reset_wait_ms = */ 100,
220 /* sda_setup_time_ns = */ 30, /* 20ns, but cycle time is 60ns, so use 60/2 */
221 /* sck_pulse_width_ns = */ 30, /* 20ns, but cycle time is 60ns, so use 60/2 */
222 /* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
223 /* spi_mode = */ 0, /* active high, rising edge */
224 /* i2c_bus_clock_100kHz = */ 4,
225 /* data_setup_time_ns = */ 20,
226 /* write_pulse_width_ns = */ 40,
227 /* tile_width = */ 8,
228 /* tile_height = */ 4,
229 /* default_x_offset = */ 0,
230 /* flipmode_x_offset = */ 0,
231 /* pixel_width = */ 60,
232 /* pixel_height = */ 32
233};
234
235uint8_t u8x8_d_ld7032_60x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
236{
237 if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
238 {
239 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ld7032_60x32_display_info);
240 return 1;
241 }
242 return u8x8_d_ld7032_generic(u8x8, msg, arg_int, arg_ptr);
243}
244
245
246
247/* alternative version, issue #1189 */
248
249/* new sequence https://github.com/olikraus/u8g2/issues/1189 */
250static const uint8_t u8x8_d_ld7032_60x32_alt_init_seq[] = {
251
252 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
253
254 U8X8_CA(0x02, 0x00),
255 U8X8_CA(0x14, 0x00),
256 U8X8_CA(0x1A, 0x05),
257 U8X8_CA(0x1D, 0x00),
258 U8X8_CA(0x09, 0x00),
259 U8X8_CAA(0x30, 0x00, 0x3F),
260 U8X8_CAA(0x32, 0x08, 0x27),
261 U8X8_CA(0x34, 0x00),
262 U8X8_CA(0x35, 0x07),
263 U8X8_CA(0x36, 0x08),
264 U8X8_CA(0x37, 0x27),
265 U8X8_CA(0x38, 0x00),
266 U8X8_CA(0x39, 0x20),
267 U8X8_CA(0x10, 0x05),
268 U8X8_CA(0x16, 0x00),
269 U8X8_CA(0x18, 0x08),
270 U8X8_CA(0x12, 0x2F),
271 U8X8_CA(0x3D, 0x01),
272 U8X8_CA(0x3F, 0x10),
273 U8X8_CA(0x44, 0x02),
274 U8X8_CA(0x48, 0x03),
275 U8X8_CA(0x17, 0x00),
276 U8X8_CA(0x13, 0x01),
277 U8X8_CA(0x3F, 0x11), // internal regulator enabled, vcc_c * 0.7
278 U8X8_CA(0x3D, 0x00),
279
280 U8X8_END_TRANSFER(), /* disable chip */
281 U8X8_END() /* end of sequence */
282
283 };
284
285uint8_t u8x8_d_ld7032_60x32_alt(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
286{
287 if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
288 {
289 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ld7032_60x32_display_info);
290 return 1;
291 }
292
293 if ( msg ==U8X8_MSG_DISPLAY_INIT )
294 {
295 u8x8_d_helper_display_init(u8x8);
296 u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_alt_init_seq);
297 return 1;
298 }
299
300 return u8x8_d_ld7032_generic(u8x8, msg, arg_int, arg_ptr);
301}
302
303/*==========================================*/
304/*
305 128x36 Flip Mode is NOT supported
306 see https://github.com/olikraus/u8g2/issues/2135
307*/
308
309static uint8_t u8x8_d_ld7032_128_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
310{
311 uint8_t x, c;
312 uint8_t *ptr;
313 switch(msg)
314 {
315 /* handled by the calling function
316 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
317 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ld7032_60x32_display_info);
318 break;
319 */
320 case U8X8_MSG_DISPLAY_INIT:
321 u8x8_d_helper_display_init(u8x8);
322 u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_init_seq);
323 break;
324 case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
325 if ( arg_int == 0 )
326 u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_powersave0_seq);
327 else
328 u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_powersave1_seq);
329 break;
330 case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
331 if ( arg_int == 0 )
332 {
333 u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_flip0_seq);
334 u8x8->x_offset = u8x8->display_info->default_x_offset;
335 }
336 else
337 {
338 u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_flip1_seq);
339 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
340 }
341 break;
342#ifdef U8X8_WITH_SET_CONTRAST
343 case U8X8_MSG_DISPLAY_SET_CONTRAST:
344 u8x8_cad_StartTransfer(u8x8);
345 u8x8_cad_SendCmd(u8x8, 0x012 );
346 if ( arg_int > 0x07f ) /* default is 0x040, limit to 0x07f to be on the safe side (hopefully) */
347 arg_int= 0x07f;
348 u8x8_cad_SendArg(u8x8, arg_int ); /* values from 0x00 to 0x0ff are allowed, bit will all values be safe??? */
349 u8x8_cad_EndTransfer(u8x8);
350 break;
351#endif
352 case U8X8_MSG_DISPLAY_DRAW_TILE:
353 u8x8_cad_StartTransfer(u8x8);
354 x = ((u8x8_tile_t *)arg_ptr)->x_pos;
355 x += u8x8->x_offset/8;
356 u8x8_cad_SendCmd(u8x8, 0x034 );
357 u8x8_cad_SendArg(u8x8, x );
358 u8x8_cad_SendCmd(u8x8, 0x035 );
359 u8x8_cad_SendArg(u8x8, 0x00f );
360 u8x8_cad_SendCmd(u8x8, 0x036 );
361 u8x8_cad_SendArg(u8x8, (((u8x8_tile_t *)arg_ptr)->y_pos)*8 );
362 u8x8_cad_SendCmd(u8x8, 0x037 );
363 u8x8_cad_SendArg(u8x8, 0x027 );
364 u8x8_cad_SendCmd(u8x8, 0x008 );
365
366
367 do
368 {
369 c = ((u8x8_tile_t *)arg_ptr)->cnt;
370 ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
371 u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
372 arg_int--;
373 } while( arg_int > 0 );
374
375 u8x8_cad_EndTransfer(u8x8);
376 break;
377 default:
378 return 0;
379 }
380 return 1;
381}
382
383
384static const u8x8_display_info_t u8x8_ld7032_128x36_display_info =
385{
386 /* chip_enable_level = */ 0,
387 /* chip_disable_level = */ 1,
388
389 /* post_chip_enable_wait_ns = */ 15,
390 /* pre_chip_disable_wait_ns = */ 20,
391 /* reset_pulse_width_ms = */ 100,
392 /* post_reset_wait_ms = */ 100,
393 /* sda_setup_time_ns = */ 30, /* 20ns, but cycle time is 60ns, so use 60/2 */
394 /* sck_pulse_width_ns = */ 30, /* 20ns, but cycle time is 60ns, so use 60/2 */
395 /* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
396 /* spi_mode = */ 0, /* active high, rising edge */
397 /* i2c_bus_clock_100kHz = */ 4,
398 /* data_setup_time_ns = */ 20,
399 /* write_pulse_width_ns = */ 40,
400 /* tile_width = */ 16,
401 /* tile_height = */ 5,
402 /* default_x_offset = */ 0,
403 /* flipmode_x_offset = */ 0,
404 /* pixel_width = */ 128,
405 /* pixel_height = */ 36
406};
407
408static const uint8_t u8x8_d_ld7032_128x36_init_seq[] = {
409
410 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
411
412 U8X8_CA(0x14, 0x00), // standby mode
413 U8X8_CA(0x02, 0x00), // display off
414 U8X8_CA(0x1A, 0x05), // frame frequency
415 U8X8_CA(0x1D, 0x00), // data write direction (datasheet: 1d 0b
416 U8X8_CA(0x09, 0x00), // scan direction
417 U8X8_CAA(0x30, 0x00, 0x7F), // column driver active range
418 U8X8_CAA(0x32, 0x04, 0x27), // row driver active range
419 U8X8_CA(0x34, 0x00), // start line
420 U8X8_CA(0x35, 0x0f), // end line
421 U8X8_CA(0x36, 0x04), // row start line
422 U8X8_CA(0x37, 0x27), // row end line
423 U8X8_CA(0x38, 0x00), // x disp start, default 0
424 U8X8_CA(0x39, 0x00), // y disp start, default 0
425 U8X8_CA(0x10, 0x1f), // peak pulse width
426 U8X8_CA(0x16, 0x05), // pulse delay width
427 U8X8_CA(0x18, 0x1f), // pre charge width
428 U8X8_CA(0x12, 0x3F), // contrast control
429 U8X8_CA(0x44, 0x02), // PreC select, default: 2
430 //U8X8_CA(0x48, 0x00), // row overlap, default: 0 (was 3)
431 U8X8_CA(0x17, 0x00), // row scan, default: 0
432 U8X8_CA(0x13, 0x01), // scan mode sequence
433 //U8X8_CA(0x3F, 0x11), // VCC R Selection, default: 0 (int. reg. disabled, vcc_c*0.8)
434 U8X8_CA(0x3D, 0x01), // vdd selection 0: 2.8V-3.5, 1: 1.8V (1.65-2.5V)
435
436 U8X8_END_TRANSFER(), /* disable chip */
437 U8X8_END() /* end of sequence */
438
439 };
440
441uint8_t u8x8_d_ld7032_128x36(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
442{
443 if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
444 {
445 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ld7032_128x36_display_info);
446 return 1;
447 }
448
449 if ( msg ==U8X8_MSG_DISPLAY_INIT )
450 {
451 u8x8_d_helper_display_init(u8x8);
452 u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_128x36_init_seq);
453 return 1;
454 }
455
456 return u8x8_d_ld7032_128_generic(u8x8, msg, arg_int, arg_ptr);
457}