Unverified Commit 11592951 authored by Arnim Läuger's avatar Arnim Läuger Committed by GitHub
Browse files

Merge pull request #2582 from nodemcu/dev

Next master drop
parents 4095c408 61433c44
/*
ucg_ccs.c
color component slide sub library
Universal uC Color Graphics Library
Copyright (c) 2013, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
e: end
n: steps
f(0) = s
f(n) = e
f(x) = m*x + s
f(n-1) = m*(n-1) + s =!= e
--> m = (e-s)/n
f(x) = (e-s)/(n-1) * x + s
f(0) = s
f(1) = s + (e-s)/(n-1)
*/
#include "ucg.h"
/*
Setup change from "start" to "end" with a specified amount of "steps".
After calling this procedure, ccs->current will contain the "start" value.
*/
void ucg_ccs_init(ucg_ccs_t *ccs, uint8_t start, uint8_t end, ucg_int_t steps)
{
ccs->start = start;
ccs->num = end-start;
ccs->den = steps-1;
ccs->dir = 1;
ccs->quot = ccs->num / ccs->den;
if ( ccs->num < 0 )
{
ccs->num = -ccs->num;
ccs->dir = -1;
}
ccs->rem = ccs->num % ccs->den;
ccs->frac = ccs->den/2;
ccs->current = start;
}
/*
Make one step towards the "end" value.
ccs->curront will contain the updated value.
*/
void ucg_ccs_step(ucg_ccs_t *ccs)
{
ccs->current += ccs->quot;
ccs->frac += ccs->rem;
if ( ccs->frac >= ccs->den )
{
ccs->current += ccs->dir;
ccs->frac -= ccs->den;
}
}
/*
f(x) = (e-s)/(n-1) * x + s
current = (num / den) * (pos / den)
Seek to the specified "pos"ition.
"pos" must be between 0 and "end"-1
*/
void ucg_ccs_seek(ucg_ccs_t *ccs, ucg_int_t pos)
{
ucg_int_t p;
ccs->current = ccs->quot;
ccs->current *= pos;
p = ccs->rem * pos + ccs->den/2;
if ( ccs->dir >= 0 )
ccs->current += p / ccs->den;
else
ccs->current -= p / ccs->den;
ccs->frac = p % ccs->den;
ccs->current += ccs->start;
}
/*
ucg_circle.c
Circle Drawing Procedures
Universal uC Color Graphics Library
Copyright (c) 2014, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
static void ucg_draw_circle_section(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t x0, ucg_int_t y0, uint8_t option) UCG_NOINLINE;
static void ucg_draw_circle_section(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t x0, ucg_int_t y0, uint8_t option)
{
/* upper right */
if ( option & UCG_DRAW_UPPER_RIGHT )
{
ucg_DrawPixel(ucg, x0 + x, y0 - y);
ucg_DrawPixel(ucg, x0 + y, y0 - x);
}
/* upper left */
if ( option & UCG_DRAW_UPPER_LEFT )
{
ucg_DrawPixel(ucg, x0 - x, y0 - y);
ucg_DrawPixel(ucg, x0 - y, y0 - x);
}
/* lower right */
if ( option & UCG_DRAW_LOWER_RIGHT )
{
ucg_DrawPixel(ucg, x0 + x, y0 + y);
ucg_DrawPixel(ucg, x0 + y, y0 + x);
}
/* lower left */
if ( option & UCG_DRAW_LOWER_LEFT )
{
ucg_DrawPixel(ucg, x0 - x, y0 + y);
ucg_DrawPixel(ucg, x0 - y, y0 + x);
}
}
void ucg_draw_circle(ucg_t *ucg, ucg_int_t x0, ucg_int_t y0, ucg_int_t rad, uint8_t option)
{
ucg_int_t f;
ucg_int_t ddF_x;
ucg_int_t ddF_y;
ucg_int_t x;
ucg_int_t y;
f = 1;
f -= rad;
ddF_x = 1;
ddF_y = 0;
ddF_y -= rad;
ddF_y *= 2;
x = 0;
y = rad;
ucg_draw_circle_section(ucg, x, y, x0, y0, option);
while ( x < y )
{
if (f >= 0)
{
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
ucg_draw_circle_section(ucg, x, y, x0, y0, option);
}
}
void ucg_DrawCircle(ucg_t *ucg, ucg_int_t x0, ucg_int_t y0, ucg_int_t rad, uint8_t option)
{
/* check for bounding box */
/*
{
ucg_int_t radp, radp2;
radp = rad;
radp++;
radp2 = radp;
radp2 *= 2;
if ( ucg_IsBBXIntersection(ucg, x0-radp, y0-radp, radp2, radp2) == 0)
return;
}
*/
/* draw circle */
ucg_draw_circle(ucg, x0, y0, rad, option);
}
static void ucg_draw_disc_section(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t x0, ucg_int_t y0, uint8_t option) UCG_NOINLINE;
static void ucg_draw_disc_section(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t x0, ucg_int_t y0, uint8_t option)
{
/* upper right */
if ( option & UCG_DRAW_UPPER_RIGHT )
{
ucg_DrawVLine(ucg, x0+x, y0-y, y+1);
ucg_DrawVLine(ucg, x0+y, y0-x, x+1);
}
/* upper left */
if ( option & UCG_DRAW_UPPER_LEFT )
{
ucg_DrawVLine(ucg, x0-x, y0-y, y+1);
ucg_DrawVLine(ucg, x0-y, y0-x, x+1);
}
/* lower right */
if ( option & UCG_DRAW_LOWER_RIGHT )
{
ucg_DrawVLine(ucg, x0+x, y0, y+1);
ucg_DrawVLine(ucg, x0+y, y0, x+1);
}
/* lower left */
if ( option & UCG_DRAW_LOWER_LEFT )
{
ucg_DrawVLine(ucg, x0-x, y0, y+1);
ucg_DrawVLine(ucg, x0-y, y0, x+1);
}
}
void ucg_draw_disc(ucg_t *ucg, ucg_int_t x0, ucg_int_t y0, ucg_int_t rad, uint8_t option)
{
ucg_int_t f;
ucg_int_t ddF_x;
ucg_int_t ddF_y;
ucg_int_t x;
ucg_int_t y;
f = 1;
f -= rad;
ddF_x = 1;
ddF_y = 0;
ddF_y -= rad;
ddF_y *= 2;
x = 0;
y = rad;
ucg_draw_disc_section(ucg, x, y, x0, y0, option);
while ( x < y )
{
if (f >= 0)
{
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
ucg_draw_disc_section(ucg, x, y, x0, y0, option);
}
}
void ucg_DrawDisc(ucg_t *ucg, ucg_int_t x0, ucg_int_t y0, ucg_int_t rad, uint8_t option)
{
/* check for bounding box */
/*
{
ucg_int_t radp, radp2;
radp = rad;
radp++;
radp2 = radp;
radp2 *= 2;
if ( ucg_IsBBXIntersection(ucg, x0-radp, y0-radp, radp2, radp2) == 0)
return;
}
*/
/* draw disc */
ucg_draw_disc(ucg, x0, y0, rad, option);
}
/*
ucg_clip.c
Clipping procedures for the device funktions
Universal uC Color Graphics Library
Copyright (c) 2013, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
static ucg_int_t ucg_clip_is_x_visible(ucg_t *ucg) UCG_NOINLINE;
static ucg_int_t ucg_clip_is_y_visible(ucg_t *ucg) UCG_NOINLINE;
static ucg_int_t ucg_clip_is_x_visible(ucg_t *ucg)
{
ucg_int_t t;
t = ucg->arg.pixel.pos.x;
t -= ucg->clip_box.ul.x;
if ( t < 0 )
return 0;
if ( t >= ucg->clip_box.size.w )
return 0;
return 1;
}
static ucg_int_t ucg_clip_is_y_visible(ucg_t *ucg)
{
ucg_int_t t;
t = ucg->arg.pixel.pos.y;
t -= ucg->clip_box.ul.y;
if ( t < 0 )
return 0;
if ( t >= ucg->clip_box.size.h )
return 0;
return 1;
}
/*
Description:
clip range from a (included) to b (excluded) agains c (included) to d (excluded)
Assumptions:
a <= b
c <= d
*/
static ucg_int_t ucg_clip_intersection(ucg_int_t *ap, ucg_int_t *bp, ucg_int_t c, ucg_int_t d)
{
ucg_int_t a = *ap;
ucg_int_t b = *bp;
if ( a >= d )
return 0;
if ( b <= c )
return 0;
if ( a < c )
*ap = c;
if ( b > d )
*bp = d;
return 1;
}
ucg_int_t ucg_clip_is_pixel_visible(ucg_t *ucg)
{
if ( ucg_clip_is_x_visible(ucg) == 0 )
return 0;
if ( ucg_clip_is_y_visible(ucg) == 0 )
return 0;
return 1;
}
/*
assumes, that ucg->arg contains data for l90fx and does clipping
against ucg->clip_box
*/
ucg_int_t ucg_clip_l90fx(ucg_t *ucg)
{
ucg_int_t a;
ucg_int_t b;
ucg->arg.offset = 0;
switch(ucg->arg.dir)
{
case 0:
if ( ucg_clip_is_y_visible(ucg) == 0 )
return 0;
a = ucg->arg.pixel.pos.x;
b = a;
b += ucg->arg.len;
if ( ucg_clip_intersection(&a, &b, ucg->clip_box.ul.x, ucg->clip_box.ul.x+ucg->clip_box.size.w) == 0 )
return 0;
ucg->arg.offset = a - ucg->arg.pixel.pos.x;
ucg->arg.pixel.pos.x = a;
b -= a;
ucg->arg.len = b;
break;
case 1:
if ( ucg_clip_is_x_visible(ucg) == 0 )
return 0;
a = ucg->arg.pixel.pos.y;
b = a;
b += ucg->arg.len;
if ( ucg_clip_intersection(&a, &b, ucg->clip_box.ul.y, ucg->clip_box.ul.y+ucg->clip_box.size.h) == 0 )
return 0;
ucg->arg.offset = a - ucg->arg.pixel.pos.y;
ucg->arg.pixel.pos.y = a;
b -= a;
ucg->arg.len = b;
break;
case 2:
if ( ucg_clip_is_y_visible(ucg) == 0 )
return 0;
b = ucg->arg.pixel.pos.x;
b++;
a = b;
a -= ucg->arg.len;
if ( ucg_clip_intersection(&a, &b, ucg->clip_box.ul.x, ucg->clip_box.ul.x+ucg->clip_box.size.w) == 0 )
return 0;
ucg->arg.len = b-a;
b--;
ucg->arg.offset = ucg->arg.pixel.pos.x-b;
ucg->arg.pixel.pos.x = b;
break;
case 3:
if ( ucg_clip_is_x_visible(ucg) == 0 )
return 0;
b = ucg->arg.pixel.pos.y;
b++;
a = b;
a -= ucg->arg.len;
if ( ucg_clip_intersection(&a, &b, ucg->clip_box.ul.y, ucg->clip_box.ul.y+ucg->clip_box.size.h) == 0 )
return 0;
ucg->arg.len = b-a;
b--;
ucg->arg.offset = ucg->arg.pixel.pos.y-b;
ucg->arg.pixel.pos.y = b;
break;
}
return 1;
}
ucg_int_t ucg_clip_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90fx(ucg) == 0 )
return 0;
ucg->arg.pixel_skip = ucg->arg.offset & 0x07;
ucg->arg.bitmap += (ucg->arg.offset >>3);
return 1;
}
/* old code
ucg_int_t ucg_clip_l90tc(ucg_t *ucg)
{
ucg_int_t t;
switch(ucg->arg.dir)
{
case 0:
t = ucg->arg.pixel.pos.x;
if ( ucg_clip_l90fx(ucg) == 0 )
return 0;
t = ucg->arg.pixel.pos.x - t;
break;
case 1:
t = ucg->arg.pixel.pos.y;
if ( ucg_clip_l90fx(ucg) == 0 )
return 0;
t = ucg->arg.pixel.pos.y - t;
break;
case 2:
t = ucg->arg.pixel.pos.x;
if ( ucg_clip_l90fx(ucg) == 0 )
return 0;
t -= ucg->arg.pixel.pos.x;
break;
case 3:
t = ucg->arg.pixel.pos.y;
if ( ucg_clip_l90fx(ucg) == 0 )
return 0;
t -= ucg->arg.pixel.pos.y;
break;
}
ucg->arg.pixel_skip = t & 0x07;
ucg->arg.bitmap += (t >>3);
return 1;
}
*/
ucg_int_t ucg_clip_l90se(ucg_t *ucg)
{
uint8_t i;
if ( ucg_clip_l90fx(ucg) == 0 )
return 0;
for ( i = 0; i < 3; i++ )
{
ucg_ccs_seek(ucg->arg.ccs_line+i, ucg->arg.offset);
}
return 1;
}
/*
ucg_com_msg_api.c
Universal uC Color Graphics Library
Copyright (c) 2014, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
int16_t ucg_com_template_cb(ucg_t *ucg, int16_t msg, uint32_t arg, uint8_t *data)
{
switch(msg)
{
case UCG_COM_MSG_POWER_UP:
break;
case UCG_COM_MSG_POWER_DOWN:
break;
case UCG_COM_MSG_DELAY:
break;
case UCG_COM_MSG_CHANGE_RESET_LINE:
break;
case UCG_COM_MSG_CHANGE_CS_LINE:
break;
case UCG_COM_MSG_CHANGE_CD_LINE:
break;
case UCG_COM_MSG_SEND_BYTE:
break;
case UCG_COM_MSG_REPEAT_1_BYTE:
break;
case UCG_COM_MSG_REPEAT_2_BYTES:
break;
case UCG_COM_MSG_REPEAT_3_BYTES:
break;
case UCG_COM_MSG_SEND_STR:
break;
case UCG_COM_MSG_SEND_CD_DATA_SEQUENCE:
break;
}
return 1;
}
void ucg_com_PowerDown(ucg_t *ucg)
{
if ( (ucg->com_status & UCG_COM_STATUS_MASK_POWER) != 0 )
ucg->com_cb(ucg, UCG_COM_MSG_POWER_DOWN, 0, NULL);
ucg->com_status &= ~UCG_COM_STATUS_MASK_POWER;
}
/*
clk_speed in nano-seconds, range: 0..4095
*/
int16_t ucg_com_PowerUp(ucg_t *ucg, uint16_t serial_clk_speed, uint16_t parallel_clk_speed)
{
int16_t r;
ucg_com_info_t com_info;
com_info.serial_clk_speed = serial_clk_speed;
com_info.parallel_clk_speed = parallel_clk_speed;
ucg_com_PowerDown(ucg);
ucg->com_initial_change_sent = 0;
r = ucg->com_cb(ucg, UCG_COM_MSG_POWER_UP, 0UL, (uint8_t *)&com_info);
if ( r != 0 )
{
ucg->com_status |= UCG_COM_STATUS_MASK_POWER;
}
return r;
}
void ucg_com_SetLineStatus(ucg_t *ucg, uint8_t level, uint8_t mask, uint8_t msg)
{
if ( level == 0 )
{
if ( (ucg->com_initial_change_sent & mask) == 0 || (ucg->com_status & mask) == mask )
{
ucg->com_cb(ucg, msg, level, NULL);
ucg->com_status &= ~mask;
ucg->com_initial_change_sent |= mask;
}
}
else
{
if ( (ucg->com_initial_change_sent & mask) == 0 || (ucg->com_status & mask) == 0 )
{
ucg->com_cb(ucg, msg, level, NULL);
ucg->com_status |= mask;
ucg->com_initial_change_sent |= mask;
}
}
}
void ucg_com_SetResetLineStatus(ucg_t *ucg, uint8_t level)
{
ucg_com_SetLineStatus(ucg, level, UCG_COM_STATUS_MASK_RESET, UCG_COM_MSG_CHANGE_RESET_LINE);
}
void ucg_com_SetCSLineStatus(ucg_t *ucg, uint8_t level)
{
ucg_com_SetLineStatus(ucg, level, UCG_COM_STATUS_MASK_CS, UCG_COM_MSG_CHANGE_CS_LINE);
}
void ucg_com_SetCDLineStatus(ucg_t *ucg, uint8_t level)
{
ucg_com_SetLineStatus(ucg, level, UCG_COM_STATUS_MASK_CD, UCG_COM_MSG_CHANGE_CD_LINE);
}
/* delay in microseconds */
void ucg_com_DelayMicroseconds(ucg_t *ucg, uint16_t delay)
{
ucg->com_cb(ucg, UCG_COM_MSG_DELAY, delay, NULL);
}
/* delay in milliseconds */
void ucg_com_DelayMilliseconds(ucg_t *ucg, uint16_t delay)
{
while( delay > 0 )
{
ucg_com_DelayMicroseconds(ucg, 1000);
delay--;
}
}
#ifndef ucg_com_SendByte
void ucg_com_SendByte(ucg_t *ucg, uint8_t byte)
{
ucg->com_cb(ucg, UCG_COM_MSG_SEND_BYTE, byte, NULL);
}
#endif
void ucg_com_SendRepeatByte(ucg_t *ucg, uint16_t cnt, uint8_t byte)
{
ucg->com_cb(ucg, UCG_COM_MSG_REPEAT_1_BYTE, cnt, &byte);
}
void ucg_com_SendRepeat2Bytes(ucg_t *ucg, uint16_t cnt, uint8_t *byte_ptr)
{
ucg->com_cb(ucg, UCG_COM_MSG_REPEAT_2_BYTES, cnt, byte_ptr);
}
#ifndef ucg_com_SendRepeat3Bytes
void ucg_com_SendRepeat3Bytes(ucg_t *ucg, uint16_t cnt, uint8_t *byte_ptr)
{
ucg->com_cb(ucg, UCG_COM_MSG_REPEAT_3_BYTES, cnt, byte_ptr);
}
#endif
void ucg_com_SendString(ucg_t *ucg, uint16_t cnt, const uint8_t *byte_ptr)
{
ucg->com_cb(ucg, UCG_COM_MSG_SEND_STR, cnt, (uint8_t *)byte_ptr);
}
void ucg_com_SendStringP(ucg_t *ucg, uint16_t cnt, const ucg_pgm_uint8_t *byte_ptr)
{
uint8_t b;
while( cnt > 0 )
{
b = ucg_pgm_read(byte_ptr);
//b = *byte_ptr;
ucg->com_cb(ucg, UCG_COM_MSG_SEND_BYTE, b, NULL);
byte_ptr++;
cnt--;
}
}
void ucg_com_SendCmdDataSequence(ucg_t *ucg, uint16_t cnt, const uint8_t *byte_ptr, uint8_t cd_line_status_at_end)
{
ucg->com_cb(ucg, UCG_COM_MSG_SEND_CD_DATA_SEQUENCE, cnt, (uint8_t *)byte_ptr);
ucg_com_SetCDLineStatus(ucg, cd_line_status_at_end); // ensure that the status is set correctly for the CD line */
}
/*
Command-Sequence Language
CMD10 1x CMD Byte, 0x Argument Data Bytes
CMD20 2x CMD Byte, 0x Argument Data Bytes
CMD11 1x CMD Byte, 1x Argument Data Bytes
CMD21 2x CMD Byte, 1x Argument Data Bytes
CMD12 1x CMD Byte, 2x Argument Data Bytes
CMD22 2x CMD Byte, 2x Argument Data Bytes
CMD13 1x CMD Byte, 3x Argument Data Bytes
CMD23 2x CMD Byte, 3x Argument Data Bytes
CMD14 1x CMD Byte, 4x Argument Data Bytes
CMD24 2x CMD Byte, 4x Argument Data Bytes
DATA1 1x Data Bytes
DATA2 2x Data Bytes
DATA3 3x Data Bytes
DATA4 4x Data Bytes
DATA5 5x Data Bytes
DATA6 6x Data Bytes
RST_LOW Output 0 on reset line
RST_HIGH Output 1 on reset line
CS_LOW Output 0 on chip select line
CS_HIGH Output 1 on chip select line
DLY_MS Delay for specified amount of milliseconds (0..2000)
DLY_US Delay for specified amount of microconds (0..2000)
Configuration
CFG_CD(c,a) Configure CMD/DATA line: "c" logic level CMD, "a" logic level CMD Args
0000xxxx End Marker
0001xxxx 1x CMD Byte, 0..15 Argument Data Bytes
0010xxxx 2x CMD Byte, 0..15 Argument Data Bytes
0011xxxx 3x CMD Byte, 0..15 Argument Data Bytes
0100xxxx
0101xxxx
0110xxxx Arg Bytes 0..15
0111xxxx Data Bytes 0...15
1000xxxx xxxxxxxx DLY MS
1001xxxx xxxxxxxx DLY US
1010sssss aaaaaaaa oooooooo (var0>>s)&a|o, send as argument
1011sssss aaaaaaaa oooooooo (var1>>s)&a|o, send as argument
1100xxxx
1101xxxx
1110xxxx
11110000 RST_LOW
11110001 RST_HIGH
1111001x
11110100 CS_LOW
11110101 CS_HIGH
1111011x
111110xx
111111ca CFG_CD(c,a)
#define C10(c0) 0x010, (c0)
#define C20(c0,c1) 0x020, (c0),(c1)
#define C11(c0,a0) 0x011, (c0),(a0)
#define C21(c0,c1,a0) 0x021, (c0),(c1),(a0)
#define C12(c0,a0,a1) 0x012, (c0),(a0),(a1)
#define C22(c0,c1,a0,a1) 0x022, (c0),(c1),(a0),(a1)
#define C13(c0,a0,a1,a2) 0x013, (c0),(a0),(a1),(a2)
#define C23(c0,c1,a0,a1,a2) 0x023, (c0),(c1),(a0),(a1),(a2)
#define C14(c0,a0,a1,a2,a3) 0x013, (c0),(a0),(a1),(a2),(a3)
#define C24(c0,c1,a0,a1,a2,a3) 0x023, (c0),(c1),(a0),(a1),(a2),(a3)
#define UCG_DATA() 0x070
#define D1(d0) 0x071, (d0)
#define D2(d0,d1) 0x072, (d0),(d1)
#define D3(d0,d1,d3) 0x073, (d0),(d1),(d2)
#define D4(d0,d1,d3,d4) 0x074, (d0),(d1),(d2),(d3)
#define D5(d0,d1,d3,d4,d5) 0x075, (d0),(d1),(d2),(d3),(d5)
#define D6(d0,d1,d3,d4,d5,d6) 0x076, (d0),(d1),(d2),(d3),(d5),(d6)
#define DLY_MS(t) 0x080 | (((t)>>8)&15), (t)&255
#define DLY_US(t) 0x090 | (((t)>>8)&15), (t)&255
s: Shift right
a: And mask
o: Or mask
#define UCG_VARX(s,a,o) 0x0a0 | ((s)&15), (a), (o)
#define UCG_VARY(s,a,o) 0x0b0 | ((s)&15), (a), (o)
#define RST(level) 0x0f0 | ((level)&1)
#define CS(level) 0x0f4 | ((level)&1)
#define CFG_CD(c,a) 0x0fc | (((c)&1)<<1) | ((a)&1)
#define END() 0x00
*/
static void ucg_com_SendCmdArg(ucg_t *ucg, const ucg_pgm_uint8_t *data, uint8_t cmd_cnt, uint8_t arg_cnt)
{
ucg_com_SetCDLineStatus(ucg, (ucg->com_cfg_cd>>1)&1 );
ucg_com_SendStringP(ucg, cmd_cnt, data);
if ( arg_cnt > 0 )
{
data += cmd_cnt;
ucg_com_SetCDLineStatus(ucg, (ucg->com_cfg_cd)&1 );
ucg_com_SendStringP(ucg, arg_cnt, data);
}
}
//void ucg_com_SendCmdSeq(ucg_t *ucg, const ucg_pgm_uint8_t *data)
void ucg_com_SendCmdSeq(ucg_t *ucg, const ucg_pgm_uint8_t *data)
{
uint8_t b;
uint8_t bb;
uint8_t hi;
uint8_t lo;
for(;;)
{
b = ucg_pgm_read(data);
//b = *data;
hi = (b) >> 4;
lo = (b) & 0x0f;
switch( hi )
{
case 0:
return; /* end marker */
case 1:
case 2:
case 3:
ucg_com_SendCmdArg(ucg, data+1, hi, lo);
data+=1+hi+lo;
break;
case 6:
ucg_com_SetCDLineStatus(ucg, (ucg->com_cfg_cd)&1 );
ucg_com_SendStringP(ucg, lo, data+1);
data+=1+lo;
break;
case 7: /* note: 0x070 is used to set data line status */
ucg_com_SetCDLineStatus(ucg, ((ucg->com_cfg_cd>>1)&1)^1 );
if ( lo > 0 )
ucg_com_SendStringP(ucg, lo, data+1);
data+=1+lo;
break;
case 8:
data++;
b = ucg_pgm_read(data);
//b = *data;
ucg_com_DelayMilliseconds(ucg, (((uint16_t)lo)<<8) + b );
data++;
break;
case 9:
data++;
b = ucg_pgm_read(data);
//b = *data;
ucg_com_DelayMicroseconds(ucg, (((uint16_t)lo)<<8) + b );
data++;
break;
case 10:
data++;
b = ucg_pgm_read(data);
data++;
bb = ucg_pgm_read(data);
data++;
//b = data[0];
//bb = data[1];
ucg_com_SetCDLineStatus(ucg, (ucg->com_cfg_cd)&1 );
ucg_com_SendByte(ucg, (((uint8_t)(((ucg->arg.pixel.pos.x)>>lo)))&b)|bb );
//data+=2;
break;
case 11:
data++;
b = ucg_pgm_read(data);
data++;
bb = ucg_pgm_read(data);
data++;
//b = data[0];
//bb = data[1];
ucg_com_SetCDLineStatus(ucg, (ucg->com_cfg_cd)&1 );
ucg_com_SendByte(ucg, (((uint8_t)(((ucg->arg.pixel.pos.y)>>lo)))&b)|bb );
//data+=2;
break;
case 15:
hi = lo >> 2;
lo &= 3;
switch(hi)
{
case 0:
ucg_com_SetResetLineStatus(ucg, lo&1);
break;
case 1:
ucg_com_SetCSLineStatus(ucg, lo&1);
break;
case 3:
ucg->com_cfg_cd = lo;
break;
}
data++;
break;
default:
return;
}
}
}
/*
ucg_dev_default_cb.c
Universal uC Color Graphics Library
Copyright (c) 2013, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
/*
default device callback
this should be (finally) called by any other device callback to handle
messages, which are not yet handled.
*/
ucg_int_t ucg_dev_default_cb(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
case UCG_MSG_SET_CLIP_BOX:
ucg->clip_box = *(ucg_box_t *)data;
break;
}
return 1; /* all ok */
}
/*
will be used as default cb if no extentions callback is provided
*/
ucg_int_t ucg_ext_none(ucg_t *ucg, ucg_int_t msg, void *data)
{
return 1; /* all ok */
}
/*
handle UCG_MSG_DRAW_L90FX message and make calls to "dev_cb" with UCG_MSG_DRAW_PIXEL
return 1 if something has been drawn
*/
ucg_int_t ucg_handle_l90fx(ucg_t *ucg, ucg_dev_fnptr dev_cb)
{
if ( ucg_clip_l90fx(ucg) != 0 )
{
ucg_int_t dx, dy;
ucg_int_t i;
switch(ucg->arg.dir)
{
case 0: dx = 1; dy = 0; break;
case 1: dx = 0; dy = 1; break;
case 2: dx = -1; dy = 0; break;
case 3: dx = 0; dy = -1; break;
default: dx = 1; dy = 0; break; /* avoid compiler warning */
}
for( i = 0; i < ucg->arg.len; i++ )
{
dev_cb(ucg, UCG_MSG_DRAW_PIXEL, NULL);
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
}
return 1;
}
return 0;
}
/*
handle UCG_MSG_DRAW_L90TC message and make calls to "dev_cb" with UCG_MSG_DRAW_PIXEL
return 1 if something has been drawn
*/
ucg_int_t ucg_handle_l90tc(ucg_t *ucg, ucg_dev_fnptr dev_cb)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
switch(ucg->arg.dir)
{
case 0: dx = 1; dy = 0; break;
case 1: dx = 0; dy = 1; break;
case 2: dx = -1; dy = 0; break;
case 3: dx = 0; dy = -1; break;
default: dx = 1; dy = 0; break; /* avoid compiler warning */
}
//pixmap = *(ucg->arg.bitmap);
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
dev_cb(ucg, UCG_MSG_DRAW_PIXEL, NULL);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
//pixmap = *(ucg->arg.bitmap);
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
return 1;
}
return 0;
}
/*
handle UCG_MSG_DRAW_L90FB message and make calls to "dev_cb" with UCG_MSG_DRAW_PIXEL
return 1 if something has been drawn
*/
ucg_int_t ucg_handle_l90bf(ucg_t *ucg, ucg_dev_fnptr dev_cb)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
ucg_int_t dx, dy;
ucg_int_t i, y;
unsigned char pixmap;
uint8_t bitcnt;
switch(ucg->arg.dir)
{
case 0: dx = 1; dy = 0; break;
case 1: dx = 0; dy = 1; break;
case 2: dx = -1; dy = 0; break;
case 3: dx = 0; dy = -1; break;
default: dx = 1; dy = 0; break; /* avoid compiler warning */
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
for( i = 0; i < ucg->arg.len; i++ )
{
for( y = 0; y < ucg->arg.scale; y++ )
{
if ( (pixmap & 128) == 0 )
{
ucg->arg.pixel.rgb = ucg->arg.rgb[1];
dev_cb(ucg, UCG_MSG_DRAW_PIXEL, NULL);
}
else
{
ucg->arg.pixel.rgb = ucg->arg.rgb[0];
dev_cb(ucg, UCG_MSG_DRAW_PIXEL, NULL);
}
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
}
pixmap<<=1;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
return 1;
}
return 0;
}
/*
handle UCG_MSG_DRAW_L90SE message and make calls to "dev_cb" with UCG_MSG_DRAW_PIXEL
return 1 if something has been drawn
*/
ucg_int_t ucg_handle_l90se(ucg_t *ucg, ucg_dev_fnptr dev_cb)
{
uint8_t i;
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t dx, dy;
ucg_int_t i, j;
switch(ucg->arg.dir)
{
case 0: dx = 1; dy = 0; break;
case 1: dx = 0; dy = 1; break;
case 2: dx = -1; dy = 0; break;
case 3: dx = 0; dy = -1; break;
default: dx = 1; dy = 0; break; /* avoid compiler warning */
}
for( i = 0; i < ucg->arg.len; i++ )
{
ucg->arg.pixel.rgb.color[0] = ucg->arg.ccs_line[0].current;
ucg->arg.pixel.rgb.color[1] = ucg->arg.ccs_line[1].current;
ucg->arg.pixel.rgb.color[2] = ucg->arg.ccs_line[2].current;
dev_cb(ucg, UCG_MSG_DRAW_PIXEL, NULL);
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
for ( j = 0; j < 3; j++ )
{
ucg_ccs_step(ucg->arg.ccs_line+j);
}
}
return 1;
}
return 0;
}
/*
l90rl run lenth encoded constant color pattern
yyllllll wwwwbbbb wwwwbbbb wwwwbbbb wwwwbbbb ...
sequence terminates if wwwwbbbb = 0
wwww: number of pixel to skip
bbbb: number of pixel to draw with color
llllll: number of bytes which follow, can be 0
*/
#ifdef ON_HOLD
void ucg_handle_l90rl(ucg_t *ucg, ucg_dev_fnptr dev_cb)
{
ucg_int_t dx, dy;
uint8_t i, cnt;
uint8_t rl_code;
ucg_int_t skip;
switch(ucg->arg.dir)
{
case 0: dx = 1; dy = 0; break;
case 1: dx = 0; dy = 1; break;
case 2: dx = -1; dy = 0; break;
case 3: dx = 0; dy = -1; break;
default: dx = 1; dy = 0; break; /* avoid compiler warning */
}
cnt = ucg_pgm_read(ucg->arg.bitmap);
cnt &= 63;
ucg->arg.bitmap++;
for( i = 0; i < cnt; i++ )
{
rl_code = ucg_pgm_read(ucg->arg.bitmap);
if ( rl_code == 0 )
break;
skip = (ucg_int_t)(rl_code >> 4);
switch(ucg->arg.dir)
{
case 0: ucg->arg.pixel.pos.x+=skip; break;
case 1: ucg->arg.pixel.pos.y+=skip; break;
case 2: ucg->arg.pixel.pos.x-=skip; break;
default:
case 3: ucg->arg.pixel.pos.y-=skip; break;
}
rl_code &= 15;
while( rl_code )
{
dev_cb(ucg, UCG_MSG_DRAW_PIXEL, NULL);
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
rl_code--;
}
ucg->arg.bitmap++;
}
}
#endif
\ No newline at end of file
/*
ucg_dev_ic_ili9163.c
Specific code for the ili9163 controller (TFT displays)
Code is for 128x128 display which is shifted by 32 pixel within the controller RAM
Universal uC Color Graphics Library
Copyright (c) 2015, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
const ucg_pgm_uint8_t ucg_ili9163_set_pos_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11( 0x036, 0x008),
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_D2(0x000, 0x07f), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x00, 0), UCG_VARY(0,0x0ff, 0), UCG_D2(0x000, 0x0a1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ili9163_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x008 horizontal increment (dir = 0) */
/* 0x008 vertical increment (dir = 1) */
/* 0x048 horizontal deccrement (dir = 2) */
/* 0x088 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x008),
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_D2(0x000, 0x083), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x00, 0), UCG_VARY(0,0x0ff, 0), UCG_D2(0x000, 0x0a1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ili9163_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x008 horizontal increment (dir = 0) */
/* 0x008 vertical increment (dir = 1) */
/* 0x048 horizontal deccrement (dir = 2) */
/* 0x088 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x008),
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x00, 0), UCG_VARY(0,0x0ff, 0), UCG_D2(0x000, 0x0a1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ili9163_set_pos_dir2_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x008 horizontal increment (dir = 0) */
/* 0x008 vertical increment (dir = 1) */
/* 0x048 horizontal deccrement (dir = 2) */
/* 0x088 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x048),
UCG_C11( 0x036, 0x048), /* it seems that this command needs to be sent twice */
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_D2(0x000, 0x083), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x00, 0), UCG_VARY(0,0x0ff, 0), UCG_D2(0x000, 0x0a1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ili9163_set_pos_dir3_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x008 horizontal increment (dir = 0) */
/* 0x008 vertical increment (dir = 1) */
/* 0x0c8 horizontal deccrement (dir = 2) */
/* 0x0c8 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x088),
UCG_C11( 0x036, 0x088), /* it seems that this command needs to be sent twice */
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x00, 0), UCG_VARY(0,0x0ff, 0), UCG_D2(0x000, 0x0a1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
ucg_int_t ucg_handle_ili9163_l90fx(ucg_t *ucg)
{
uint8_t c[3];
ucg_int_t tmp;
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg->arg.pixel.pos.y += 32;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_dir0_seq);
ucg->arg.pixel.pos.y -= 32;
break;
case 1:
ucg->arg.pixel.pos.y += 32;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_dir1_seq);
ucg->arg.pixel.pos.y -= 32;
break;
case 2:
tmp = ucg->arg.pixel.pos.x;
ucg->arg.pixel.pos.x = 127-tmp;
ucg->arg.pixel.pos.y += 32;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_dir2_seq);
ucg->arg.pixel.pos.y -= 32;
ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
tmp = ucg->arg.pixel.pos.y;
ucg->arg.pixel.pos.y = 127-tmp;
//ucg->arg.pixel.pos.y += 32;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_dir3_seq);
ucg->arg.pixel.pos.y = tmp;
break;
}
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Glyph Output)
*/
/* with CmdDataSequence */
ucg_int_t ucg_handle_ili9163_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[16];
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg->arg.pixel.pos.y += 32;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_seq);
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x02a; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // upper part x
buf[4] = 0x000; // no change
buf[5] = 0x000; // will be overwritten by x value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x02c; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
buf[1] = 0x02a; // set x
break;
case 1:
dx = 0; dy = 1;
buf[1] = 0x02b; // set y
break;
case 2:
dx = -1; dy = 0;
buf[1] = 0x02a; // set x
break;
case 3:
default:
dx = 0; dy = -1;
buf[1] = 0x02b; // set y
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[9] = ucg->arg.pixel.rgb.color[0];
buf[11] = ucg->arg.pixel.rgb.color[1];
buf[13] = ucg->arg.pixel.rgb.color[2];
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
if ( (ucg->arg.dir&1) == 0 )
{
buf[5] = ucg->arg.pixel.pos.x;
}
else
{
buf[3] = ucg->arg.pixel.pos.y>>8;
buf[5] = ucg->arg.pixel.pos.y&255;
}
ucg_com_SendCmdDataSequence(ucg, 7, buf, 0);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_handle_ili9163_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
ucg_int_t tmp;
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t i;
switch(ucg->arg.dir)
{
case 0:
ucg->arg.pixel.pos.y += 32;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_dir0_seq);
ucg->arg.pixel.pos.y -= 32;
break;
case 1:
ucg->arg.pixel.pos.y += 32;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_dir1_seq);
ucg->arg.pixel.pos.y -= 32;
break;
case 2:
tmp = ucg->arg.pixel.pos.x;
ucg->arg.pixel.pos.x = 127-tmp;
ucg->arg.pixel.pos.y += 32;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_dir2_seq);
ucg->arg.pixel.pos.y -= 32;
ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
tmp = ucg->arg.pixel.pos.y;
ucg->arg.pixel.pos.y = 127-tmp;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_dir3_seq);
ucg->arg.pixel.pos.y = tmp;
break;
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = ucg->arg.ccs_line[0].current;
c[1] = ucg->arg.ccs_line[1].current;
c[2] = ucg->arg.ccs_line[2].current;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_ccs_step(ucg->arg.ccs_line+0);
ucg_ccs_step(ucg->arg.ccs_line+1);
ucg_ccs_step(ucg->arg.ccs_line+2);
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static const ucg_pgm_uint8_t ucg_ili9163_power_down_seq[] = {
UCG_CS(0), /* enable chip */
UCG_C10(0x010), /* sleep in */
UCG_C10(0x28), /* display off */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ic_ili9163_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 100, 66);
case UCG_MSG_DEV_POWER_DOWN:
ucg_com_SendCmdSeq(ucg, ucg_ili9163_power_down_seq);
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 128;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg->arg.pixel.pos.y += 32;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_seq);
ucg->arg.pixel.pos.y -= 32;
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_ili9163_18);
ucg_handle_ili9163_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
//ucg_handle_l90tc(ucg, ucg_dev_ic_ili9163_18);
ucg_handle_ili9163_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_ili9163_18);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_ili9163_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_ili9163_18);
ucg_handle_ili9163_l90se(ucg);
break;
}
return 1;
}
\ No newline at end of file
/*
ucg_dev_ic_ili9325.c
Specific code for the ili9325 controller (TFT displays)
Universal uC Color Graphics Library
Copyright (c) 2014, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C22(0x000, 0x003, 0xc0 | 0x010, 0x030), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C22(0x000, 0x003, 0xc0 | 0x010, 0x038), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_dir2_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C22(0x000, 0x003, 0xc0 | 0x010, 0x000), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_dir3_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C22(0x000, 0x003, 0xc0 | 0x010, 0x008), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static ucg_int_t ucg_handle_ili9325_l90fx(ucg_t *ucg)
{
uint8_t c[3];
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir1_seq);
break;
case 2:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir2_seq);
break;
case 3:
default:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir3_seq);
break;
}
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Glyph Output)
Because of this for vertical lines the x min and max values in
"ucg_ili9325_set_pos_for_y_seq" are identical to avoid changes of the x position
*/
static const ucg_pgm_uint8_t ucg_ili9325_set_x_pos_seq[] =
{
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_y_pos_seq[] =
{
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
/* without CmdDataSequence */
ucg_int_t xxxxxx_ucg_handle_ili9325_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[3];
ucg_int_t dx, dy;
ucg_int_t i;
const uint8_t *seq;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_seq);
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
seq = ucg_ili9325_set_x_pos_seq;
break;
case 1:
dx = 0; dy = 1;
seq = ucg_ili9325_set_y_pos_seq;
break;
case 2:
dx = -1; dy = 0;
seq = ucg_ili9325_set_x_pos_seq;
break;
case 3:
default:
dx = 0; dy = -1;
seq = ucg_ili9325_set_y_pos_seq;
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[0] = ucg->arg.pixel.rgb.color[0];
buf[1] = ucg->arg.pixel.rgb.color[1];
buf[2] = ucg->arg.pixel.rgb.color[2];
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
ucg_com_SendCmdSeq(ucg, seq);
ucg_com_SendRepeat3Bytes(ucg, 1, buf);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/* with CmdDataSequence */
static ucg_int_t ucg_handle_ili9325_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[20];
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_seq);
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x020; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // upper part x
buf[4] = 0x000; // no change
buf[5] = 0x000; // will be overwritten by x value
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x022; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
break;
case 1:
dx = 0; dy = 1;
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x021; // set y
buf[8] = 0x002; // change to 1 (arg mode)
buf[9] = 0x000; // upper part y
buf[10] = 0x000; // no change
buf[11] = 0x000; // will be overwritten by y value
buf[12] = 0x001; // change to 0 (cmd mode)
buf[13] = 0x022; // write data
buf[14] = 0x002; // change to 1 (data mode)
buf[15] = 0x000; // red value
buf[16] = 0x000; // no change
buf[17] = 0x000; // green value
buf[18] = 0x000; // no change
buf[19] = 0x000; // blue value
break;
case 2:
dx = -1; dy = 0;
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x022; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
break;
case 3:
default:
dx = 0; dy = -1;
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x021; // set y
buf[8] = 0x002; // change to 1 (arg mode)
buf[9] = 0x000; // upper part y
buf[10] = 0x000; // no change
buf[11] = 0x000; // will be overwritten by y value
buf[12] = 0x001; // change to 0 (cmd mode)
buf[13] = 0x022; // write data
buf[14] = 0x002; // change to 1 (data mode)
buf[15] = 0x000; // red value
buf[16] = 0x000; // no change
buf[17] = 0x000; // green value
buf[18] = 0x000; // no change
buf[19] = 0x000; // blue value
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
if ( (ucg->arg.dir&1) == 0 )
{
buf[9] = ucg->arg.pixel.rgb.color[0];
buf[11] = ucg->arg.pixel.rgb.color[1];
buf[13] = ucg->arg.pixel.rgb.color[2];
}
else
{
buf[15] = ucg->arg.pixel.rgb.color[0];
buf[17] = ucg->arg.pixel.rgb.color[1];
buf[19] = ucg->arg.pixel.rgb.color[2];
}
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
if ( (ucg->arg.dir&1) == 0 )
{
buf[5] = ucg->arg.pixel.pos.x;
ucg_com_SendCmdDataSequence(ucg, 7, buf, 1);
}
else
{
buf[5] = ucg->arg.pixel.pos.x;
buf[9] = (ucg->arg.pixel.pos.y>>8)&1;
buf[11] = ucg->arg.pixel.pos.y&255;
ucg_com_SendCmdDataSequence(ucg, 10, buf, 1);
}
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static ucg_int_t ucg_handle_ili9325_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t i;
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir1_seq);
break;
case 2:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir2_seq);
break;
case 3:
default:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir3_seq);
break;
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = ucg->arg.ccs_line[0].current;
c[1] = ucg->arg.ccs_line[1].current;
c[2] = ucg->arg.ccs_line[2].current;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_ccs_step(ucg->arg.ccs_line+0);
ucg_ccs_step(ucg->arg.ccs_line+1);
ucg_ccs_step(ucg->arg.ccs_line+2);
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_dev_ic_ili9325_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 40, 100);
case UCG_MSG_DEV_POWER_DOWN:
/* not yet implemented */
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 240;
((ucg_wh_t *)data)->h = 320;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_seq);
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_ili9325_18);
ucg_handle_ili9325_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
//ucg_handle_l90tc(ucg, ucg_dev_ic_ili9325);
ucg_handle_ili9325_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_ili9325_18);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_ili9325_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_ili9325);
ucg_handle_ili9325_l90se(ucg);
break;
}
return 1;
}
\ No newline at end of file
/*
ucg_dev_ic_ili9325_spi.c
Specific code for the ili9325 controller (TFT displays) with SPI mode (IM3=0, IM2=1, IM1=1, IM0=1)
1 May 2014: Currently, this is not working
Universal uC Color Graphics Library
Copyright (c) 2014, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C12(0x003, 0xc0 | 0x010, 0x030), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C12(0x003, 0xc0 | 0x010, 0x038), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_dir2_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C12(0x003, 0xc0 | 0x010, 0x000), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_dir3_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C12(0x003, 0xc0 | 0x010, 0x008), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static ucg_int_t ucg_handle_ili9325_l90fx(ucg_t *ucg)
{
uint8_t c[3];
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir1_seq);
break;
case 2:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir2_seq);
break;
case 3:
default:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir3_seq);
break;
}
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Glyph Output)
Because of this for vertical lines the x min and max values in
"ucg_ili9325_set_pos_for_y_seq" are identical to avoid changes of the x position
*/
static const ucg_pgm_uint8_t ucg_ili9325_set_x_pos_seq[] =
{
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_y_pos_seq[] =
{
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
/* without CmdDataSequence */
static ucg_int_t xxxxxx_ucg_handle_ili9325_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[3];
ucg_int_t dx, dy;
ucg_int_t i;
const uint8_t *seq;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_seq);
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
seq = ucg_ili9325_set_x_pos_seq;
break;
case 1:
dx = 0; dy = 1;
seq = ucg_ili9325_set_y_pos_seq;
break;
case 2:
dx = -1; dy = 0;
seq = ucg_ili9325_set_x_pos_seq;
break;
case 3:
default:
dx = 0; dy = -1;
seq = ucg_ili9325_set_y_pos_seq;
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[0] = ucg->arg.pixel.rgb.color[0];
buf[1] = ucg->arg.pixel.rgb.color[1];
buf[2] = ucg->arg.pixel.rgb.color[2];
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
ucg_com_SendCmdSeq(ucg, seq);
ucg_com_SendRepeat3Bytes(ucg, 1, buf);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/* with CmdDataSequence */
static ucg_int_t ucg_handle_ili9325_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[20];
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_seq);
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x020; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // upper part x
buf[4] = 0x000; // no change
buf[5] = 0x000; // will be overwritten by x value
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x022; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
break;
case 1:
dx = 0; dy = 1;
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x021; // set y
buf[8] = 0x002; // change to 1 (arg mode)
buf[9] = 0x000; // upper part y
buf[10] = 0x000; // no change
buf[11] = 0x000; // will be overwritten by y value
buf[12] = 0x001; // change to 0 (cmd mode)
buf[13] = 0x022; // write data
buf[14] = 0x002; // change to 1 (data mode)
buf[15] = 0x000; // red value
buf[16] = 0x000; // no change
buf[17] = 0x000; // green value
buf[18] = 0x000; // no change
buf[19] = 0x000; // blue value
break;
case 2:
dx = -1; dy = 0;
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x022; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
break;
case 3:
default:
dx = 0; dy = -1;
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x021; // set y
buf[8] = 0x002; // change to 1 (arg mode)
buf[9] = 0x000; // upper part y
buf[10] = 0x000; // no change
buf[11] = 0x000; // will be overwritten by y value
buf[12] = 0x001; // change to 0 (cmd mode)
buf[13] = 0x022; // write data
buf[14] = 0x002; // change to 1 (data mode)
buf[15] = 0x000; // red value
buf[16] = 0x000; // no change
buf[17] = 0x000; // green value
buf[18] = 0x000; // no change
buf[19] = 0x000; // blue value
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
if ( (ucg->arg.dir&1) == 0 )
{
buf[9] = ucg->arg.pixel.rgb.color[0];
buf[11] = ucg->arg.pixel.rgb.color[1];
buf[13] = ucg->arg.pixel.rgb.color[2];
}
else
{
buf[15] = ucg->arg.pixel.rgb.color[0];
buf[17] = ucg->arg.pixel.rgb.color[1];
buf[19] = ucg->arg.pixel.rgb.color[2];
}
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
if ( (ucg->arg.dir&1) == 0 )
{
buf[5] = ucg->arg.pixel.pos.x;
ucg_com_SendCmdDataSequence(ucg, 7, buf, 1);
}
else
{
buf[5] = ucg->arg.pixel.pos.x;
buf[9] = (ucg->arg.pixel.pos.y>>8)&1;
buf[11] = ucg->arg.pixel.pos.y&255;
ucg_com_SendCmdDataSequence(ucg, 10, buf, 1);
}
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static ucg_int_t ucg_handle_ili9325_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t i;
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir1_seq);
break;
case 2:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir2_seq);
break;
case 3:
default:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir3_seq);
break;
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = ucg->arg.ccs_line[0].current;
c[1] = ucg->arg.ccs_line[1].current;
c[2] = ucg->arg.ccs_line[2].current;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_ccs_step(ucg->arg.ccs_line+0);
ucg_ccs_step(ucg->arg.ccs_line+1);
ucg_ccs_step(ucg->arg.ccs_line+2);
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_dev_ic_ili9325_spi_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 40, 100);
case UCG_MSG_DEV_POWER_DOWN:
/* not yet implemented */
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 240;
((ucg_wh_t *)data)->h = 320;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_seq);
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_ili9325_18);
ucg_handle_ili9325_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
//ucg_handle_l90tc(ucg, ucg_dev_ic_ili9325);
ucg_handle_ili9325_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_ili9325_18);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_ili9325_spi_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_ili9325);
ucg_handle_ili9325_l90se(ucg);
break;
}
return 1;
}
\ No newline at end of file
/*
ucg_dev_ic_ili9341.c
Specific code for the ili9341 controller (TFT displays)
Universal uC Color Graphics Library
Copyright (c) 2014, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
const ucg_pgm_uint8_t ucg_ili9341_set_pos_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11( 0x036, 0x008),
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_A2(0x000, 0x0ef), /* set x position */
UCG_C10(0x02b), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x001, 0x03f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ili9341_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x008 horizontal increment (dir = 0) */
/* 0x008 vertical increment (dir = 1) */
/* 0x048 horizontal deccrement (dir = 2) */
/* 0x088 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x008),
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_A2(0x000, 0x0ef), /* set x position */
UCG_C10(0x02b), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x001, 0x03f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ili9341_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x008 horizontal increment (dir = 0) */
/* 0x008 vertical increment (dir = 1) */
/* 0x048 horizontal deccrement (dir = 2) */
/* 0x088 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x008),
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x02b), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x001, 0x03f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ili9341_set_pos_dir2_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x008 horizontal increment (dir = 0) */
/* 0x008 vertical increment (dir = 1) */
/* 0x048 horizontal deccrement (dir = 2) */
/* 0x088 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x048),
UCG_C11( 0x036, 0x048), /* it seems that this command needs to be sent twice */ /* should be check again */
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_A2(0x000, 0x0ef), /* set x position */
UCG_C10(0x02b), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x001, 0x03f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ili9341_set_pos_dir3_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x008 horizontal increment (dir = 0) */
/* 0x008 vertical increment (dir = 1) */
/* 0x0c8 horizontal deccrement (dir = 2) */
/* 0x0c8 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x088),
UCG_C11( 0x036, 0x088), /* it seems that this command needs to be sent twice */ /* should be check again */
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x02b), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x001, 0x03f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
ucg_int_t ucg_handle_ili9341_l90fx(ucg_t *ucg)
{
uint8_t c[3];
ucg_int_t tmp;
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_dir1_seq);
break;
case 2:
tmp = ucg->arg.pixel.pos.x;
ucg->arg.pixel.pos.x = 239-tmp;
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_dir2_seq);
ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
tmp = ucg->arg.pixel.pos.y;
ucg->arg.pixel.pos.y = 319-tmp;
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_dir3_seq);
ucg->arg.pixel.pos.y = tmp;
break;
}
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Glyph Output)
*/
/* with CmdDataSequence */
ucg_int_t ucg_handle_ili9341_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[16];
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_seq);
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x02a; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // upper part x
buf[4] = 0x000; // no change
buf[5] = 0x000; // will be overwritten by x value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x02c; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
buf[1] = 0x02a; // set x
break;
case 1:
dx = 0; dy = 1;
buf[1] = 0x02b; // set y
break;
case 2:
dx = -1; dy = 0;
buf[1] = 0x02a; // set x
break;
case 3:
default:
dx = 0; dy = -1;
buf[1] = 0x02b; // set y
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[9] = ucg->arg.pixel.rgb.color[0];
buf[11] = ucg->arg.pixel.rgb.color[1];
buf[13] = ucg->arg.pixel.rgb.color[2];
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
if ( (ucg->arg.dir&1) == 0 )
{
buf[5] = ucg->arg.pixel.pos.x;
}
else
{
buf[3] = ucg->arg.pixel.pos.y>>8;
buf[5] = ucg->arg.pixel.pos.y&255;
}
ucg_com_SendCmdDataSequence(ucg, 7, buf, 0);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_handle_ili9341_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
ucg_int_t tmp;
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t i;
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_dir1_seq);
break;
case 2:
tmp = ucg->arg.pixel.pos.x;
ucg->arg.pixel.pos.x = 239-tmp;
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_dir2_seq);
ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
tmp = ucg->arg.pixel.pos.y;
ucg->arg.pixel.pos.y = 319-tmp;
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_dir3_seq);
ucg->arg.pixel.pos.y = tmp;
break;
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = ucg->arg.ccs_line[0].current;
c[1] = ucg->arg.ccs_line[1].current;
c[2] = ucg->arg.ccs_line[2].current;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_ccs_step(ucg->arg.ccs_line+0);
ucg_ccs_step(ucg->arg.ccs_line+1);
ucg_ccs_step(ucg->arg.ccs_line+2);
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static const ucg_pgm_uint8_t ucg_ili9341_power_down_seq[] = {
UCG_CS(0), /* enable chip */
UCG_C10(0x010), /* sleep in */
UCG_C10(0x28), /* display off */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ic_ili9341_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 100, 66);
case UCG_MSG_DEV_POWER_DOWN:
ucg_com_SendCmdSeq(ucg, ucg_ili9341_power_down_seq);
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 240;
((ucg_wh_t *)data)->h = 320;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_seq);
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_ili9341_18);
ucg_handle_ili9341_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
//ucg_handle_l90tc(ucg, ucg_dev_ic_ili9341_18);
ucg_handle_ili9341_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_ili9341_18);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_ili9341_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_ili9341_18);
ucg_handle_ili9341_l90se(ucg);
break;
}
return 1;
}
\ No newline at end of file
/*
ucg_dev_ic_ld50t6160.c
Specific code for the ld50t6160 controller (OLED displays)
Universal uC Color Graphics Library
Copyright (c) 2015, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
/*
Graphics Memory Writing Direction: 0x05
Bit 3: RGB/BGR
Bit 0-2: Direction
0x05, 0x00 dir 0
0x05, 0x05 dir 1
0x05, 0x03 dir 2
0x05, 0x06 dir 3
Data Reading/Writing Box: 0x0a
8 bytes as arguments: xs, ys, xe, ye
*/
const ucg_pgm_uint8_t ucg_ld50t6160_set_pos_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11(0x05, 0x00),
UCG_C10(0x0a), UCG_VARX(4,0x0f, 0), UCG_VARX(0,0x0f, 0), UCG_A2(0x007, 0x0f), /* set x position */
UCG_VARY(4,0x0f, 0), UCG_VARY(0,0x0f, 0), UCG_A2(0x09, 0x0f), /* set y position */
UCG_C10(0x0c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ld50t6160_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11(0x05, 0x00),
UCG_C10(0x0a),
UCG_VARX(4,0x0f, 0), UCG_VARX(0,0x0f, 0), UCG_A2(0x007, 0x0f), /* set x position */
UCG_VARY(4,0x0f, 0), UCG_VARY(0,0x0f, 0), UCG_A2(0x09, 0x0f), /* set y position */
UCG_C10(0x0c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ld50t6160_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11(0x05, 0x05),
UCG_C10(0x0a),
//UCG_VARX(4,0x0f, 0), UCG_VARX(0,0x0f, 0), UCG_D2(0x007, 0x0f), /* set x position */
UCG_A2(0x00, 0x00), UCG_VARX(4,0x0f, 0), UCG_VARX(0,0x0f, 0), /* set x position */
UCG_VARY(4,0x0f, 0), UCG_VARY(0,0x0f, 0), UCG_A2(0x09, 0x0f), /* set y position */
UCG_C10(0x0c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ld50t6160_set_pos_dir2_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11(0x05, 0x03),
UCG_C10(0x0a),
UCG_A2(0x00, 0x00), UCG_VARX(4,0x0f, 0), UCG_VARX(0,0x0f, 0), /* set x position */
UCG_A2(0x00, 0x00), UCG_VARY(4,0x0f, 0), UCG_VARY(0,0x0f, 0), /* set y position */
UCG_C10(0x0c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ld50t6160_set_pos_dir3_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11(0x05, 0x06),
UCG_C10(0x0a),
UCG_VARX(4,0x0f, 0), UCG_VARX(0,0x0f, 0), UCG_A2(0x07, 0x0f), /* set x position */
UCG_A2(0x00, 0x00), UCG_VARY(4,0x0f, 0), UCG_VARY(0,0x0f, 0), /* set y position */
UCG_C10(0x0c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static ucg_int_t ucg_handle_ld50t6160_l90fx(ucg_t *ucg)
{
uint8_t c[3];
//ucg_int_t tmp;
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_set_pos_dir1_seq);
break;
case 2:
//tmp = ucg->arg.pixel.pos.x;
//ucg->arg.pixel.pos.x = 127-tmp;
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_set_pos_dir2_seq);
//ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
//tmp = ucg->arg.pixel.pos.y;
//ucg->arg.pixel.pos.y = 159-tmp;
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_set_pos_dir3_seq);
//ucg->arg.pixel.pos.y = tmp;
break;
}
c[0] = ucg->arg.pixel.rgb.color[0]>>2;
c[1] = ucg->arg.pixel.rgb.color[1]>>2;
c[2] = ucg->arg.pixel.rgb.color[2]>>2;
ucg_com_SendRepeat3Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Glyph Output)
*/
#ifdef UCG_MSG_DRAW_L90TC
static ucg_int_t ucg_handle_ld50t6160_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[3];
ucg_int_t dx, dy;
ucg_int_t i;
const uint8_t *seq;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
seq = ucg_ld50t6160_set_pos_dir0_seq;
break;
case 1:
dx = 0; dy = 1;
seq = ucg_ld50t6160_set_pos_dir1_seq;
break;
case 2:
dx = -1; dy = 0;
seq = ucg_ld50t6160_set_pos_dir2_seq;
break;
case 3:
default:
dx = 0; dy = -1;
seq = ucg_ld50t6160_set_pos_dir3_seq;
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[0] = ucg->arg.pixel.rgb.color[0]>>2;
buf[1] = ucg->arg.pixel.rgb.color[1]>>2;
buf[2] = ucg->arg.pixel.rgb.color[2]>>2;
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
ucg_com_SendCmdSeq(ucg, seq);
ucg_com_SendRepeat3Bytes(ucg, 1, buf);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
#endif /* UCG_MSG_DRAW_L90TC */
ucg_int_t ucg_handle_ld50t6160_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
//ucg_int_t tmp;
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t i;
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_set_pos_dir1_seq);
break;
case 2:
//tmp = ucg->arg.pixel.pos.x;
//ucg->arg.pixel.pos.x = 239-tmp;
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_set_pos_dir2_seq);
//ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
//tmp = ucg->arg.pixel.pos.y;
//ucg->arg.pixel.pos.y = 319-tmp;
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_set_pos_dir3_seq);
//ucg->arg.pixel.pos.y = tmp;
break;
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = ucg->arg.ccs_line[0].current>>2;
c[1] = ucg->arg.ccs_line[1].current>>2;
c[2] = ucg->arg.ccs_line[2].current>>2;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_ccs_step(ucg->arg.ccs_line+0);
ucg_ccs_step(ucg->arg.ccs_line+1);
ucg_ccs_step(ucg->arg.ccs_line+2);
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static const ucg_pgm_uint8_t ucg_ld50t6160_power_down_seq[] = {
UCG_CS(0), /* enable chip */
UCG_C11(0x02, 0x00), /* display off */
UCG_C11(0x20, 0x00), /* all ICON off */
UCG_C11(0x20, 0x01), /* stop OSCB */
UCG_C10(0x010), /* sleep in */
UCG_C10(0x28), /* display off */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ic_ld50t6160_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 100, 66);
case UCG_MSG_DEV_POWER_DOWN:
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_power_down_seq);
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 160;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_set_pos_seq);
c[0] = ucg->arg.pixel.rgb.color[0]>>2;
c[1] = ucg->arg.pixel.rgb.color[1]>>2;
c[2] = ucg->arg.pixel.rgb.color[2]>>2;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_ld50t6160_18);
ucg_handle_ld50t6160_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
//ucg_handle_l90tc(ucg, ucg_dev_ic_ld50t6160_18);
ucg_handle_ld50t6160_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_ld50t6160_18);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_ld50t6160_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_ld50t6160_18);
ucg_handle_ld50t6160_l90se(ucg);
break;
}
return 1;
}
\ No newline at end of file
/*
ucg_dev_ic_pcf8833.c
Specific code for the pcf8833 controller (TFT displays)
Universal uC Color Graphics Library
Copyright (c) 2014, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
#define XOFFSET 0
#define WIDTH 132
#define HEIGHT 132
const ucg_pgm_uint8_t ucg_pcf8833_set_pos_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11( 0x036, 0x000),
UCG_C10(0x02a), UCG_VARX(0,0x0ff, 0), UCG_A1(WIDTH-1), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x0ff, 0), UCG_A1(HEIGHT-1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_pcf8833_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
/*
bit 7: my
bit 6: mx
bit 5: x or y increment
bit 4: line order
bit 3: rgb
*/
UCG_C11( 0x036, 0x000),
UCG_C10(0x02a), UCG_VARX(0,0x0ff, 0), UCG_A1(WIDTH-1), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x0ff, 0), UCG_A1(HEIGHT-1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_pcf8833_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
/*
bit 7: my
bit 6: mx
bit 5: x or y increment
bit 4: line order
bit 3: rgb
*/
UCG_C11( 0x036, 0x000),
UCG_C10(0x02a), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x0ff, 0), UCG_A1(HEIGHT-1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_pcf8833_set_pos_dir2_seq[] =
{
UCG_CS(0), /* enable chip */
/*
bit 7: my
bit 6: mx
bit 5: x or y increment
bit 4: line order
bit 3: rgb
*/
UCG_C11( 0x036, 0x040),
//UCG_C11( 0x036, 0x020), /* it seems that this command needs to be sent twice */
UCG_C10(0x02a), UCG_VARX(0,0x0ff, 0), UCG_A1(WIDTH-1), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x0ff, 0), UCG_A1(HEIGHT-1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_pcf8833_set_pos_dir3_seq[] =
{
UCG_CS(0), /* enable chip */
/*
bit 7: my
bit 6: mx
bit 5: x or y increment
bit 4: line order
bit 3: rgb
*/
UCG_C11( 0x036, 0x080),
//UCG_C11( 0x036, 0x0d0), /* it seems that this command needs to be sent twice */
UCG_C10(0x02a), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x0ff, 0), UCG_A1(HEIGHT-1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static uint8_t ucg_pcf8833_get_color_high_byte(ucg_t *ucg)
{
return (ucg->arg.pixel.rgb.color[0]&0x0f8) | (((ucg->arg.pixel.rgb.color[1]) >>5));
}
static uint8_t ucg_pcf8833_get_color_low_byte(ucg_t *ucg)
{
return ((((ucg->arg.pixel.rgb.color[1]))<<3)&0x0e0) | (((ucg->arg.pixel.rgb.color[2]) >>3));
}
ucg_int_t ucg_handle_pcf8833_l90fx(ucg_t *ucg)
{
uint8_t c[3];
ucg_int_t tmp;
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_dir1_seq);
break;
case 2:
tmp = ucg->arg.pixel.pos.x;
ucg->arg.pixel.pos.x = WIDTH-1-tmp;
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_dir2_seq);
ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
tmp = ucg->arg.pixel.pos.y;
ucg->arg.pixel.pos.y = HEIGHT-1-tmp;
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_dir3_seq);
ucg->arg.pixel.pos.y = tmp;
break;
}
c[0] = ucg_pcf8833_get_color_high_byte(ucg);
c[1] = ucg_pcf8833_get_color_low_byte(ucg);
ucg_com_SendRepeat2Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Glyph Output)
*/
/* with CmdDataSequence */
ucg_int_t ucg_handle_pcf8833_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[16];
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_seq);
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x02a; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // x/y
buf[4] = 0x000; // no change
buf[5] = 0x000; // end value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x02c; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = ucg_pcf8833_get_color_high_byte(ucg);
buf[10] = 0x000; // no change
buf[11] = ucg_pcf8833_get_color_low_byte(ucg);
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
buf[1] = 0x02a; // set x
buf[5] = WIDTH-1; // end value
break;
case 1:
dx = 0; dy = 1;
buf[1] = 0x02b; // set y
buf[5] = HEIGHT-1; // end value
break;
case 2:
dx = -1; dy = 0;
buf[1] = 0x02a; // set x
buf[5] = WIDTH-1; // end value
break;
case 3:
default:
dx = 0; dy = -1;
buf[1] = 0x02b; // set y
buf[5] = HEIGHT-1; // end value
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
if ( (ucg->arg.dir&1) == 0 )
{
buf[3] = ucg->arg.pixel.pos.x;
}
else
{
buf[3] = ucg->arg.pixel.pos.y;
}
ucg_com_SendCmdDataSequence(ucg, 6, buf, 0);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_handle_pcf8833_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
ucg_int_t tmp;
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t i;
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_dir1_seq);
break;
case 2:
tmp = ucg->arg.pixel.pos.x;
ucg->arg.pixel.pos.x = WIDTH-1-tmp;
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_dir2_seq);
ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
tmp = ucg->arg.pixel.pos.y;
ucg->arg.pixel.pos.y = HEIGHT-1-tmp;
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_dir3_seq);
ucg->arg.pixel.pos.y = tmp;
break;
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = (ucg->arg.ccs_line[0].current&0x0f8) | (((ucg->arg.ccs_line[1].current) >>5));
c[1] = ((((ucg->arg.ccs_line[1].current))<<3)&0x0e0) | (((ucg->arg.ccs_line[2].current) >>3));
ucg_com_SendRepeat2Bytes(ucg, 1, c);
ucg_ccs_step(ucg->arg.ccs_line+0);
ucg_ccs_step(ucg->arg.ccs_line+1);
ucg_ccs_step(ucg->arg.ccs_line+2);
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static const ucg_pgm_uint8_t ucg_pcf8833_power_down_seq[] = {
UCG_CS(0), /* enable chip */
UCG_C10(0x28), /* display off */
UCG_C10(0x10), /* sleep in */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ic_pcf8833_16(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
//ucg->display_offset.x = 2;
//ucg->display_offset.y = 2;
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 150, 160);
case UCG_MSG_DEV_POWER_DOWN:
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_power_down_seq);
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = WIDTH;
((ucg_wh_t *)data)->h = HEIGHT;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_seq);
c[0] = ucg_pcf8833_get_color_high_byte(ucg);
c[1] = ucg_pcf8833_get_color_low_byte(ucg);
ucg_com_SendRepeat2Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_pcf8833_16);
ucg_handle_pcf8833_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
//ucg_handle_l90tc(ucg, ucg_dev_ic_pcf8833_16);
ucg_handle_pcf8833_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_pcf8833_16);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_pcf8833_16(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_pcf8833_16);
ucg_handle_pcf8833_l90se(ucg);
break;
}
return 1;
}
/*
ucg_dev_ic_seps225.c
Specific code for the SEPS225 controller (OLED displays)
128x128x18 display buffer
Note: Only 65K color support, because 262K mode is not possible with 8 Bit SPI.
Universal uC Color Graphics Library
Copyright (c) 2015, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
static uint8_t ucg_seps225_get_color_high_byte(ucg_t *ucg)
{
return (ucg->arg.pixel.rgb.color[0]&0x0f8) | (((ucg->arg.pixel.rgb.color[1]) >>5));
}
static uint8_t ucg_seps225_get_color_low_byte(ucg_t *ucg)
{
return ((((ucg->arg.pixel.rgb.color[1]))<<3)&0x0e0) | (((ucg->arg.pixel.rgb.color[2]) >>3));
}
/*
Write Memory Mode 0x016
Bit 0: HV
HV= 0, data is continuously written horizontally
HV= 1, data is continuously written vertically
Bit 1: VC
VC= 0, vertical address counter is decreased
VC= 1, vertical address counter is increased
Bit 2: HC
HC= 0, horizontal address counter is decreased
HC= 1, horizontal address counter is increased
Bit 4..6: Dual Transfer, 65K Mode (Bit 4 = 0, Bit 5 = 1, Bit 6 = 1)
*/
static const ucg_pgm_uint8_t ucg_seps255_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x020), UCG_VARX(0,0x07f, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(0,0x07f, 0), /* set y position */
UCG_C11(0x016, 0x064), /* Memory Mode */
UCG_C10(0x022), /* prepare for data */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_seps255_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11(0x016, 0x063), /* Memory Mode */
UCG_C10(0x020), UCG_VARX(0,0x07f, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(0,0x07f, 0), /* set y position */
UCG_C10(0x022), /* prepare for data */
UCG_DATA(), /* change to data mode */
UCG_END()
};
#ifdef NOT_USED
static const ucg_pgm_uint8_t ucg_seps255_pos_dir2_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11(0x016, 0x060), /* Memory Mode */
UCG_C10(0x020), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* prepare for data */
UCG_DATA(), /* change to data mode */
UCG_END()
};
/* it seems that this mode does not work*/
static const ucg_pgm_uint8_t ucg_seps255_pos_dir3_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11(0x016, 0x061), /* Memory Mode */
UCG_C10(0x020), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* prepare for data */
UCG_DATA(), /* change to data mode */
UCG_END()
};
#endif
ucg_int_t ucg_handle_seps225_l90fx(ucg_t *ucg)
{
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir1_seq);
break;
case 2:
ucg->arg.pixel.pos.x -= ucg->arg.len;
ucg->arg.pixel.pos.x++;
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir0_seq);
break;
case 3:
default:
ucg->arg.pixel.pos.y -= ucg->arg.len;
ucg->arg.pixel.pos.y++;
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir1_seq);
break;
}
{
uint8_t c[2];
c[0] = ucg_seps225_get_color_high_byte(ucg);
c[1] = ucg_seps225_get_color_low_byte(ucg);
ucg_com_SendRepeat2Bytes(ucg, ucg->arg.len, c);
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Bitmap Output)
Not implemented for this controller, fallback to standard. However this msg is not used
at all at the moment (Jul 2015)
*/
/*
L2SE Color Change
*/
ucg_int_t ucg_handle_seps225_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
switch(ucg->arg.dir)
{
case 0:
case 1:
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
break;
default:
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[1].color[i], ucg->arg.rgb[0].color[i], ucg->arg.len);
}
break;
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t dx, dy;
ucg_int_t i, j;
//uint8_t r, g, b;
switch(ucg->arg.dir)
{
case 0: dx = 1; dy = 0;
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir0_seq);
break;
case 1: dx = 0; dy = 1;
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir1_seq);
break;
case 2: dx = 1; dy = 0;
ucg->arg.pixel.pos.x -= ucg->arg.len;
ucg->arg.pixel.pos.x++;
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir0_seq);
break;
case 3: dx = 0; dy = 1;
ucg->arg.pixel.pos.y -= ucg->arg.len;
ucg->arg.pixel.pos.y++;
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir1_seq);
break;
default: dx = 1; dy = 0; break; /* avoid compiler warning */
}
for( i = 0; i < ucg->arg.len; i++ )
{
/*
r = ucg->arg.ccs_line[0].current;
r &= 0x0f8;
g = ucg->arg.ccs_line[1].current;
c[0] = g;
c[0] >>= 5;
c[0] |= r;
g <<= 3;
g &= 0x0e0;
b = ucg->arg.ccs_line[2].current;
b >>= 3;
c[1] = g;
c[1] |= b;
*/
c[0] = (ucg->arg.ccs_line[0].current&0x0f8) | (((ucg->arg.ccs_line[1].current) >>5));
c[1] = ((((ucg->arg.ccs_line[1].current))<<3)&0x0e0) | (((ucg->arg.ccs_line[2].current) >>3));
ucg_com_SendRepeat2Bytes(ucg, 1, c);
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
for ( j = 0; j < 3; j++ )
{
ucg_ccs_step(ucg->arg.ccs_line+j);
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static const ucg_pgm_uint8_t ucg_seps225_power_down_seq[] = {
UCG_CS(0), /* enable chip */
UCG_C11(0x006, 0x000), /* SEPS225: display off */
UCG_C11(0x004, 0x001), /* reduce current, power down */
UCG_CS(1), /* disable chip */
/* delay of 100ms is suggested here for full power down */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ic_seps225_16(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 50, 200); /* adjusted for SEPS225 */
case UCG_MSG_DEV_POWER_DOWN:
ucg_com_SendCmdSeq(ucg, ucg_seps225_power_down_seq);
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 128;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir0_seq);
c[0] = ucg_seps225_get_color_high_byte(ucg);
c[1] = ucg_seps225_get_color_low_byte(ucg);
ucg_com_SendRepeat2Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_seps225_16);
ucg_handle_seps225_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
ucg_handle_l90tc(ucg, ucg_dev_ic_seps225_18);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_seps225_18);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_seps225_16(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_seps225_16);
ucg_handle_seps225_l90se(ucg);
break;
}
return 1;
}
/*
ucg_dev_ic_ssd1289.c
Specific code for the ssd1289 controller (TFT displays)
Universal uC Color Graphics Library
Copyright (c) 2014, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
#ifdef NOT_YET_IMPLEMENTED
static const ucg_pgm_uint8_t ucg_ssd1289_set_pos_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x04e), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x04f), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ssd1289_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C22(0x000, 0x011, 0x048, 0x030), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x04e), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x04f), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ssd1289_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C22(0x000, 0x011, 0x048, 0x038), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x04e), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x04f), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ssd1289_set_pos_dir2_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C22(0x000, 0x011, 0x048, 0x000), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ssd1289_set_pos_dir3_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C22(0x000, 0x011, 0x048, 0x008), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
ucg_int_t ucg_handle_ssd1289_l90fx(ucg_t *ucg)
{
uint8_t c[3];
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_dir1_seq);
break;
case 2:
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_dir2_seq);
break;
case 3:
default:
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_dir3_seq);
break;
}
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Glyph Output)
Because of this for vertical lines the x min and max values in
"ucg_ssd1289_set_pos_for_y_seq" are identical to avoid changes of the x position
*/
const ucg_pgm_uint8_t ucg_ssd1289_set_x_pos_seq[] =
{
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ssd1289_set_y_pos_seq[] =
{
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
/* without CmdDataSequence */
ucg_int_t xxxxxx_ucg_handle_ssd1289_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[3];
ucg_int_t dx, dy;
ucg_int_t i;
const uint8_t *seq;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_seq);
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
seq = ucg_ssd1289_set_x_pos_seq;
break;
case 1:
dx = 0; dy = 1;
seq = ucg_ssd1289_set_y_pos_seq;
break;
case 2:
dx = -1; dy = 0;
seq = ucg_ssd1289_set_x_pos_seq;
break;
case 3:
default:
dx = 0; dy = -1;
seq = ucg_ssd1289_set_y_pos_seq;
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[0] = ucg->arg.pixel.rgb.color[0];
buf[1] = ucg->arg.pixel.rgb.color[1];
buf[2] = ucg->arg.pixel.rgb.color[2];
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
ucg_com_SendCmdSeq(ucg, seq);
ucg_com_SendRepeat3Bytes(ucg, 1, buf);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/* with CmdDataSequence */
ucg_int_t ucg_handle_ssd1289_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[16];
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_seq);
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x020; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // upper part x
buf[4] = 0x000; // no change
buf[5] = 0x000; // will be overwritten by x value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x022; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
break;
case 1:
dx = 0; dy = 1;
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x020; // set y
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // upper part y
buf[4] = 0x000; // no change
buf[5] = 0x000; // will be overwritten by y value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x022; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
break;
case 2:
dx = -1; dy = 0;
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x020; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // upper part x
buf[4] = 0x000; // no change
buf[5] = 0x000; // will be overwritten by x value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x022; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
break;
case 3:
default:
dx = 0; dy = -1;
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x020; // set y
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // upper part y
buf[4] = 0x000; // no change
buf[5] = 0x000; // will be overwritten by y value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x022; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[9] = ucg->arg.pixel.rgb.color[0];
buf[11] = ucg->arg.pixel.rgb.color[1];
buf[13] = ucg->arg.pixel.rgb.color[2];
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
if ( (ucg->arg.dir&1) == 0 )
{
buf[5] = ucg->arg.pixel.pos.x;
}
else
{
buf[3] = ucg->arg.pixel.pos.y>>8;
buf[5] = ucg->arg.pixel.pos.y&255;
}
ucg_com_SendCmdDataSequence(ucg, 7, buf);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_handle_ssd1289_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t i;
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_dir1_seq);
break;
case 2:
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_dir2_seq);
break;
case 3:
default:
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_dir3_seq);
break;
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = ucg->arg.ccs_line[0].current;
c[1] = ucg->arg.ccs_line[1].current;
c[2] = ucg->arg.ccs_line[2].current;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_ccs_step(ucg->arg.ccs_line+0);
ucg_ccs_step(ucg->arg.ccs_line+1);
ucg_ccs_step(ucg->arg.ccs_line+2);
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_dev_ic_ssd1289_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 40, 100);
case UCG_MSG_DEV_POWER_DOWN:
/* not yet implemented */
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 240;
((ucg_wh_t *)data)->h = 320;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_seq);
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
ucg_handle_l90fx(ucg, ucg_dev_ic_ssd1289_18);
//ucg_handle_ssd1289_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
ucg_handle_l90tc(ucg, ucg_dev_ic_ssd1289);
//ucg_handle_ssd1289_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_ssd1289);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_ssd1289_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
ucg_handle_l90se(ucg, ucg_dev_ic_ssd1289);
//ucg_handle_ssd1289_l90se(ucg);
break;
}
return 1;
}
#endif
\ No newline at end of file
/*
ucg_dev_ic_ssd1331.c
Specific code for the SSD1331 controller (OLED displays)
96x64x16 display buffer, however 3-byte 18 bit mode is used
Universal uC Color Graphics Library
Copyright (c) 2015, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
//ucg_int_t u8g_dev_ic_ssd1331(ucg_t *ucg, ucg_int_t msg, void *data);
const ucg_pgm_uint8_t ucg_ssd1331_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x015), UCG_VARX(0,0x0ff, 0), UCG_A1(0x07f), /* set x position */
UCG_C10(0x075), UCG_VARY(0,0x0ff, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ssd1331_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x015), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x075), UCG_VARY(0,0x0ff, 0), UCG_A1(0x07f), /* set y position */
UCG_DATA(), /* change to data mode */
UCG_END()
};
ucg_int_t ucg_handle_ssd1331_l90fx(ucg_t *ucg)
{
uint8_t c[3];
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_dir1_seq);
break;
case 2:
ucg->arg.pixel.pos.x -= ucg->arg.len;
ucg->arg.pixel.pos.x++;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_dir0_seq);
break;
case 3:
default:
ucg->arg.pixel.pos.y -= ucg->arg.len;
ucg->arg.pixel.pos.y++;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_dir1_seq);
break;
}
c[0] = ucg->arg.pixel.rgb.color[0]>>2;
c[1] = ucg->arg.pixel.rgb.color[1]>>2;
c[2] = ucg->arg.pixel.rgb.color[2]>>2;
ucg_com_SendRepeat3Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Bitmap Output)
Because of this for vertical lines the x min and max values in
"ucg_ssd1331_set_pos_for_y_seq" are identical to avoid changes of the x position
*/
const ucg_pgm_uint8_t ucg_ssd1331_set_pos_for_x_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x015), UCG_VARX(0,0x0ff, 0), UCG_A1(0x07f), /* set x position */
UCG_C10(0x075), UCG_VARY(0,0x0ff, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ssd1331_set_pos_for_y_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x015), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x075), UCG_VARY(0,0x0ff, 0), UCG_A1(0x07f), /* set y position */
UCG_END()
};
ucg_int_t ucg_handle_ssd1331_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[16];
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x015; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // will be overwritten by x/y value
buf[4] = 0x000; // no change
buf[5] = 0x07f; // max value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x05c; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
buf[14] = 0x001; // change to 0 (cmd mode)
buf[15] = 0x05c; // change to 0 (cmd mode)
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
buf[1] = 0x015;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_for_x_seq);
break;
case 1:
dx = 0; dy = 1;
buf[1] = 0x075;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_for_y_seq);
break;
case 2:
dx = -1; dy = 0;
buf[1] = 0x015;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_for_x_seq);
break;
case 3:
default:
dx = 0; dy = -1;
buf[1] = 0x075;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_for_y_seq);
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[9] = ucg->arg.pixel.rgb.color[0]>>2;
buf[11] = ucg->arg.pixel.rgb.color[1]>>2;
buf[13] = ucg->arg.pixel.rgb.color[2]>>2;
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
if ( (ucg->arg.dir&1) == 0 )
{
buf[3] = ucg->arg.pixel.pos.x;
}
else
{
buf[3] = ucg->arg.pixel.pos.y;
}
//ucg_com_SendCmdSeq(ucg, seq);
//buf[0] = ucg->arg.pixel.rgb.color[0]>>2;
//buf[1] = ucg->arg.pixel.rgb.color[1]>>2;
//buf[2] = ucg->arg.pixel.rgb.color[2]>>2;
//ucg_com_SendRepeat3Bytes(ucg, 1, buf);
ucg_com_SendCmdDataSequence(ucg, 7, buf, 1);
//ucg_com_SetCDLineStatus(ucg, 1);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_handle_ssd1331_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
switch(ucg->arg.dir)
{
case 0:
case 1:
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
break;
default:
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[1].color[i], ucg->arg.rgb[0].color[i], ucg->arg.len);
}
break;
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t dx, dy;
ucg_int_t i, j;
switch(ucg->arg.dir)
{
case 0: dx = 1; dy = 0;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_dir0_seq);
break;
case 1: dx = 0; dy = 1;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_dir1_seq);
break;
case 2: dx = 1; dy = 0;
ucg->arg.pixel.pos.x -= ucg->arg.len;
ucg->arg.pixel.pos.x++;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_dir0_seq);
break;
case 3: dx = 0; dy = 1;
ucg->arg.pixel.pos.y -= ucg->arg.len;
ucg->arg.pixel.pos.y++;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_dir1_seq);
break;
default: dx = 1; dy = 0; break; /* avoid compiler warning */
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = ucg->arg.ccs_line[0].current >> 2;
c[1] = ucg->arg.ccs_line[1].current >> 2;
c[2] = ucg->arg.ccs_line[2].current >> 2;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
for ( j = 0; j < 3; j++ )
{
ucg_ccs_step(ucg->arg.ccs_line+j);
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static const ucg_pgm_uint8_t ucg_ssd1331_power_down_seq[] = {
UCG_CS(0), /* enable chip */
UCG_C10(0x0a6), /* Set display: All pixel off */
UCG_C10(0x0ae), /* Set display off: sleep mode */
//UCG_C11(0x0b0, 0x01a), /* Power Save Mode */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ic_ssd1331_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 50, 300);
case UCG_MSG_DEV_POWER_DOWN:
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_power_down_seq);
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 96;
((ucg_wh_t *)data)->h = 64;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_dir0_seq);
c[0] = ucg->arg.pixel.rgb.color[0]>>2;
c[1] = ucg->arg.pixel.rgb.color[1]>>2;
c[2] = ucg->arg.pixel.rgb.color[2]>>2;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_ssd1331_18);
ucg_handle_ssd1331_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
//ucg_handle_l90tc(ucg, ucg_dev_ic_ssd1331_18);
ucg_handle_ssd1331_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_ssd1331_18);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_ssd1331_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_ssd1331_18);
ucg_handle_ssd1331_l90se(ucg);
break;
}
return 1;
}
\ No newline at end of file
/*
ucg_dev_ic_ssd1351.c
Specific code for the SSD1351 controller (OLED displays)
Universal uC Color Graphics Library
Copyright (c) 2014, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
//ucg_int_t u8g_dev_ic_ssd1351(ucg_t *ucg, ucg_int_t msg, void *data);
const ucg_pgm_uint8_t ucg_ssd1351_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x015), UCG_VARX(0,0x0ff, 0), UCG_D1(0x07f), /* set x position */
UCG_C10(0x075), UCG_VARY(0,0x0ff, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x05c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ssd1351_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x015), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x075), UCG_VARY(0,0x0ff, 0), UCG_D1(0x07f), /* set y position */
UCG_C10(0x05c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
ucg_int_t ucg_handle_ssd1351_l90fx(ucg_t *ucg)
{
uint8_t c[3];
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_dir1_seq);
break;
case 2:
ucg->arg.pixel.pos.x -= ucg->arg.len;
ucg->arg.pixel.pos.x++;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_dir0_seq);
break;
case 3:
default:
ucg->arg.pixel.pos.y -= ucg->arg.len;
ucg->arg.pixel.pos.y++;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_dir1_seq);
break;
}
c[0] = ucg->arg.pixel.rgb.color[0]>>2;
c[1] = ucg->arg.pixel.rgb.color[1]>>2;
c[2] = ucg->arg.pixel.rgb.color[2]>>2;
ucg_com_SendRepeat3Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Glyph Output)
Because of this for vertical lines the x min and max values in
"ucg_ssd1351_set_pos_for_y_seq" are identical to avoid changes of the x position
*/
const ucg_pgm_uint8_t ucg_ssd1351_set_pos_for_x_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x015), UCG_VARX(0,0x0ff, 0), UCG_D1(0x07f), /* set x position */
UCG_C10(0x075), UCG_VARY(0,0x0ff, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ssd1351_set_pos_for_y_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x015), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x075), UCG_VARY(0,0x0ff, 0), UCG_D1(0x07f), /* set y position */
UCG_END()
};
ucg_int_t ucg_handle_ssd1351_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[16];
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x015; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // will be overwritten by x/y value
buf[4] = 0x000; // no change
buf[5] = 0x07f; // max value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x05c; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
buf[14] = 0x001; // change to 0 (cmd mode)
buf[15] = 0x05c; // change to 0 (cmd mode)
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
buf[1] = 0x015;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_for_x_seq);
break;
case 1:
dx = 0; dy = 1;
buf[1] = 0x075;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_for_y_seq);
break;
case 2:
dx = -1; dy = 0;
buf[1] = 0x015;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_for_x_seq);
break;
case 3:
default:
dx = 0; dy = -1;
buf[1] = 0x075;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_for_y_seq);
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[9] = ucg->arg.pixel.rgb.color[0]>>2;
buf[11] = ucg->arg.pixel.rgb.color[1]>>2;
buf[13] = ucg->arg.pixel.rgb.color[2]>>2;
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
if ( (ucg->arg.dir&1) == 0 )
{
buf[3] = ucg->arg.pixel.pos.x;
}
else
{
buf[3] = ucg->arg.pixel.pos.y;
}
//ucg_com_SendCmdSeq(ucg, seq);
//buf[0] = ucg->arg.pixel.rgb.color[0]>>2;
//buf[1] = ucg->arg.pixel.rgb.color[1]>>2;
//buf[2] = ucg->arg.pixel.rgb.color[2]>>2;
//ucg_com_SendRepeat3Bytes(ucg, 1, buf);
ucg_com_SendCmdDataSequence(ucg, 7, buf, 1);
//ucg_com_SetCDLineStatus(ucg, 1);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_handle_ssd1351_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
switch(ucg->arg.dir)
{
case 0:
case 1:
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
break;
default:
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[1].color[i], ucg->arg.rgb[0].color[i], ucg->arg.len);
}
break;
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t dx, dy;
ucg_int_t i, j;
switch(ucg->arg.dir)
{
case 0: dx = 1; dy = 0;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_dir0_seq);
break;
case 1: dx = 0; dy = 1;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_dir1_seq);
break;
case 2: dx = 1; dy = 0;
ucg->arg.pixel.pos.x -= ucg->arg.len;
ucg->arg.pixel.pos.x++;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_dir0_seq);
break;
case 3: dx = 0; dy = 1;
ucg->arg.pixel.pos.y -= ucg->arg.len;
ucg->arg.pixel.pos.y++;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_dir1_seq);
break;
default: dx = 1; dy = 0; break; /* avoid compiler warning */
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = ucg->arg.ccs_line[0].current >> 2;
c[1] = ucg->arg.ccs_line[1].current >> 2;
c[2] = ucg->arg.ccs_line[2].current >> 2;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
for ( j = 0; j < 3; j++ )
{
ucg_ccs_step(ucg->arg.ccs_line+j);
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static const ucg_pgm_uint8_t ucg_ssd1351_power_down_seq[] = {
UCG_CS(0), /* enable chip */
UCG_C11(0x0c7, 0x000), /* Set Master Contrast (0..15), reset default: 0x05 */
UCG_C10(0x0ae), /* Set Display Off */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ic_ssd1351_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 50, 300);
case UCG_MSG_DEV_POWER_DOWN:
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_power_down_seq);
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 128;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_dir0_seq);
c[0] = ucg->arg.pixel.rgb.color[0]>>2;
c[1] = ucg->arg.pixel.rgb.color[1]>>2;
c[2] = ucg->arg.pixel.rgb.color[2]>>2;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_ssd1351_18);
ucg_handle_ssd1351_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
//ucg_handle_l90tc(ucg, ucg_dev_ic_ssd1351_18);
ucg_handle_ssd1351_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_ssd1351_18);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_ssd1351_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_ssd1351_18);
ucg_handle_ssd1351_l90se(ucg);
break;
}
return 1;
}
\ No newline at end of file
/*
ucg_dev_ic_st7735.c
Specific code for the st7735 controller (TFT displays)
Universal uC Color Graphics Library
Copyright (c) 2014, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
const ucg_pgm_uint8_t ucg_st7735_set_pos_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11( 0x036, 0x000),
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_A2(0x000, 0x07f), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x00, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x000, 0x09f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_st7735_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x000 horizontal increment (dir = 0) */
/* 0x000 vertical increment (dir = 1) */
/* 0x040 horizontal deccrement (dir = 2) */
/* 0x080 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x000),
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_A2(0x000, 0x07f), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x00, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x000, 0x09f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_st7735_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x000 horizontal increment (dir = 0) */
/* 0x000 vertical increment (dir = 1) */
/* 0x040 horizontal deccrement (dir = 2) */
/* 0x080 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x000),
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x00, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x000, 0x09f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_st7735_set_pos_dir2_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x000 horizontal increment (dir = 0) */
/* 0x000 vertical increment (dir = 1) */
/* 0x040 horizontal deccrement (dir = 2) */
/* 0x080 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x040),
UCG_C11( 0x036, 0x040), /* it seems that this command needs to be sent twice */
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_A2(0x000, 0x07f), /* set x position */
UCG_C10(0x02b), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x000, 0x09f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_st7735_set_pos_dir3_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x000 horizontal increment (dir = 0) */
/* 0x000 vertical increment (dir = 1) */
/* 0x0c0 horizontal deccrement (dir = 2) */
/* 0x0c0 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x080),
UCG_C11( 0x036, 0x080), /* it seems that this command needs to be sent twice */
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x00, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x000, 0x09f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
ucg_int_t ucg_handle_st7735_l90fx(ucg_t *ucg)
{
uint8_t c[3];
ucg_int_t tmp;
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_dir1_seq);
break;
case 2:
tmp = ucg->arg.pixel.pos.x;
ucg->arg.pixel.pos.x = 127-tmp;
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_dir2_seq);
ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
tmp = ucg->arg.pixel.pos.y;
ucg->arg.pixel.pos.y = 159-tmp;
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_dir3_seq);
ucg->arg.pixel.pos.y = tmp;
break;
}
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Glyph Output)
*/
/* with CmdDataSequence */
ucg_int_t ucg_handle_st7735_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[16];
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_seq);
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x02a; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // upper part x
buf[4] = 0x000; // no change
buf[5] = 0x000; // will be overwritten by x value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x02c; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
buf[1] = 0x02a; // set x
break;
case 1:
dx = 0; dy = 1;
buf[1] = 0x02b; // set y
break;
case 2:
dx = -1; dy = 0;
buf[1] = 0x02a; // set x
break;
case 3:
default:
dx = 0; dy = -1;
buf[1] = 0x02b; // set y
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[9] = ucg->arg.pixel.rgb.color[0];
buf[11] = ucg->arg.pixel.rgb.color[1];
buf[13] = ucg->arg.pixel.rgb.color[2];
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
if ( (ucg->arg.dir&1) == 0 )
{
buf[5] = ucg->arg.pixel.pos.x;
}
else
{
buf[3] = ucg->arg.pixel.pos.y>>8;
buf[5] = ucg->arg.pixel.pos.y&255;
}
ucg_com_SendCmdDataSequence(ucg, 7, buf, 0);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_handle_st7735_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
ucg_int_t tmp;
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t i;
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_dir1_seq);
break;
case 2:
tmp = ucg->arg.pixel.pos.x;
ucg->arg.pixel.pos.x = 127-tmp;
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_dir2_seq);
ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
tmp = ucg->arg.pixel.pos.y;
ucg->arg.pixel.pos.y = 159-tmp;
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_dir3_seq);
ucg->arg.pixel.pos.y = tmp;
break;
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = ucg->arg.ccs_line[0].current;
c[1] = ucg->arg.ccs_line[1].current;
c[2] = ucg->arg.ccs_line[2].current;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_ccs_step(ucg->arg.ccs_line+0);
ucg_ccs_step(ucg->arg.ccs_line+1);
ucg_ccs_step(ucg->arg.ccs_line+2);
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static const ucg_pgm_uint8_t ucg_st7735_power_down_seq[] = {
UCG_CS(0), /* enable chip */
UCG_C10(0x010), /* sleep in */
UCG_C10(0x28), /* display off */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ic_st7735_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 100, 66);
case UCG_MSG_DEV_POWER_DOWN:
ucg_com_SendCmdSeq(ucg, ucg_st7735_power_down_seq);
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 160;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_seq);
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_st7735_18);
ucg_handle_st7735_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
//ucg_handle_l90tc(ucg, ucg_dev_ic_st7735_18);
ucg_handle_st7735_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_st7735_18);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_st7735_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_st7735_18);
ucg_handle_st7735_l90se(ucg);
break;
}
return 1;
}
\ No newline at end of file
/*
ucg_dev_msg_api.c
Universal uC Color Graphics Library
Copyright (c) 2013, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
#include <stddef.h>
void ucg_PowerDown(ucg_t *ucg)
{
if ( ucg->is_power_up != 0 )
{
ucg->device_cb(ucg, UCG_MSG_DEV_POWER_DOWN, NULL);
ucg->is_power_up = 0;
}
}
ucg_int_t ucg_PowerUp(ucg_t *ucg)
{
ucg_int_t r;
/* power down first. will do nothing if power is already down */
ucg_PowerDown(ucg);
/* now try to power up the display */
r = ucg->device_cb(ucg, UCG_MSG_DEV_POWER_UP, NULL);
if ( r != 0 )
{
ucg->is_power_up = 1;
}
return r;
}
void ucg_SetClipBox(ucg_t *ucg, ucg_box_t *clip_box)
{
ucg->device_cb(ucg, UCG_MSG_SET_CLIP_BOX, (void *)(clip_box));
}
void ucg_SetClipRange(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t w, ucg_int_t h)
{
ucg_box_t clip_box;
clip_box.ul.x = x;
clip_box.ul.y = y;
clip_box.size.w = w;
clip_box.size.h = h;
ucg_SetClipBox(ucg, &clip_box);
}
void ucg_SetMaxClipRange(ucg_t *ucg)
{
ucg_box_t new_clip_box;
new_clip_box.size = ucg->dimension;
new_clip_box.ul.x = 0;
new_clip_box.ul.y = 0;
ucg_SetClipBox(ucg, &new_clip_box);
}
/*
Query the display dimension from the driver, reset clip window to maximum
new dimension
*/
void ucg_GetDimension(ucg_t *ucg)
{
ucg->device_cb(ucg, UCG_MSG_GET_DIMENSION, &(ucg->dimension));
ucg_SetMaxClipRange(ucg);
}
void ucg_DrawPixelWithArg(ucg_t *ucg)
{
ucg->device_cb(ucg, UCG_MSG_DRAW_PIXEL, NULL);
}
void ucg_DrawL90FXWithArg(ucg_t *ucg)
{
ucg->device_cb(ucg, UCG_MSG_DRAW_L90FX, &(ucg->arg));
}
#ifdef UCG_MSG_DRAW_L90TC
void ucg_DrawL90TCWithArg(ucg_t *ucg)
{
ucg->device_cb(ucg, UCG_MSG_DRAW_L90TC, &(ucg->arg));
}
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
void ucg_DrawL90BFWithArg(ucg_t *ucg)
{
ucg->device_cb(ucg, UCG_MSG_DRAW_L90BF, &(ucg->arg));
}
#endif /* UCG_MSG_DRAW_L90BF */
void ucg_DrawL90SEWithArg(ucg_t *ucg)
{
ucg->device_cb(ucg, UCG_MSG_DRAW_L90SE, &(ucg->arg));
}
/*
void ucg_DrawL90RLWithArg(ucg_t *ucg)
{
ucg->device_cb(ucg, UCG_MSG_DRAW_L90RL, &(ucg->arg));
}
*/
/*
ucg_dev_oled_128x128_ft.c
Specific code for the FREETRONIC 128x128 OLED module
(differs from the ILSOFT only by GPIO output)
Universal uC Color Graphics Library
Copyright (c) 2014, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
//static const uint8_t ucg_dev_ssd1351_128x128_init_seq[] PROGMEM = {
static const ucg_pgm_uint8_t ucg_ft_ssd1351_init_seq[] = {
UCG_CFG_CD(0,1), /* DC=0 for command mode, DC=1 for data and args */
UCG_RST(1),
UCG_CS(1), /* disable chip */
UCG_DLY_MS(1),
UCG_RST(0),
UCG_DLY_MS(1),
UCG_RST(1),
UCG_DLY_MS(50),
UCG_CS(0), /* enable chip */
//UCG_C11(0x0fd, 0x012), /* Unlock normal commands, reset default: unlocked */
UCG_C11(0x0fd, 0x0b1), /* Unlock extra commands, reset default: locked */
//UCG_C10(0x0ae), /* Set Display Off */
UCG_C10(0x0af), /* Set Display On */
UCG_C10(0x0a6), /* Set Display Mode Reset */
UCG_C11(0x0a0, 0x0b4), /* Set Colour Depth */
UCG_C11(0x0a1, 0x000), /* Set Display Start Line */
UCG_C11(0x0a2, 0x000), /* Set Display Offset */
UCG_C12(0x015, 0x000, 0x07f), /* Set Column Address */
UCG_C12(0x075, 0x000, 0x07f), /* Set Row Address */
UCG_C11(0x0b3, 0x0f1), /* Front Clock Div */
//UCG_C11(0x0ca, 0x07f), /* Set Multiplex Ratio, reset default: 0x7f */
UCG_C11(0x0b5, 0x003), /* Set GPIO for Freetronics OLED Module */
//UCG_C11(0x0ab, 0x001), /* Set Function Selection, reset default: 0x01 */
UCG_C11(0x0b1, 0x032), /* Set Phase Length, reset default: 0x82 */
UCG_C13(0x0b4, 0xa0,0xb5,0x55), /* Set Segment Low Voltage, reset default: 0xa2 0xb5 0x55 */
//UCG_C11(0x0bb, 0x017), /* Set Precharge Voltage, reset default: 0x17 */
//UCG_C11(0x0be, 0x005), /* Set VComH Voltage, reset default: 0x05 */
UCG_C13(0x0c1, 0xc8, 0x80, 0xc8), /* Set Contrast */
UCG_C11(0x0c7, 0x00f), /* Set Master Contrast (0..15), reset default: 0x05 */
UCG_C11(0x0b6, 0x001), /* Set Second Precharge Period */
// UCG_C10(0x0b8), /* Set CMD Grayscale Lookup, 63 Bytes follow */
// UCG_A8(0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c),
// UCG_A8(0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14),
// UCG_A8(0x15,0x16,0x18,0x1a,0x1b,0x1C,0x1D,0x1F),
// UCG_A8(0x21,0x23,0x25,0x27,0x2A,0x2D,0x30,0x33),
// UCG_A8(0x36,0x39,0x3C,0x3F,0x42,0x45,0x48,0x4C),
// UCG_A8(0x50,0x54,0x58,0x5C,0x60,0x64,0x68,0x6C),
// UCG_A8(0x70,0x74,0x78,0x7D,0x82,0x87,0x8C,0x91),
// UCG_A7(0x96,0x9B,0xA0,0xA5,0xAA,0xAF,0xB4),
UCG_C10(0x05c), /* Write RAM */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ssd1351_18x128x128_ft(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* 1. Call to the controller procedures to setup the com interface */
if ( ucg_dev_ic_ssd1351_18(ucg, msg, data) == 0 )
return 0;
/* 2. Send specific init sequence for this display module */
ucg_com_SendCmdSeq(ucg, ucg_ft_ssd1351_init_seq);
return 1;
case UCG_MSG_DEV_POWER_DOWN:
/* let do power down by the conroller procedures */
return ucg_dev_ic_ssd1351_18(ucg, msg, data);
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 128;
return 1;
}
/* all other messages are handled by the controller procedures */
return ucg_dev_ic_ssd1351_18(ucg, msg, data);
}
/*
ucg_dev_oled_128x128_ilsoft.c
Specific code for the ILSOFT 128x128 OLED module
Universal uC Color Graphics Library
Copyright (c) 2014, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
//static const uint8_t ucg_dev_ssd1351_128x128_init_seq[] PROGMEM = {
static const ucg_pgm_uint8_t ucg_ilsoft_ssd1351_init_seq[] = {
UCG_CFG_CD(0,1), /* DC=0 for command mode, DC=1 for data and args */
UCG_RST(1),
UCG_CS(1), /* disable chip */
UCG_DLY_MS(1),
UCG_RST(0),
UCG_DLY_MS(1),
UCG_RST(1),
UCG_DLY_MS(50),
UCG_CS(0), /* enable chip */
//UCG_C11(0x0fd, 0x012), /* Unlock normal commands, reset default: unlocked */
UCG_C11(0x0fd, 0x0b1), /* Unlock extra commands, reset default: locked */
//UCG_C10(0x0ae), /* Set Display Off */
UCG_C10(0x0af), /* Set Display On */
UCG_C10(0x0a6), /* Set Display Mode Reset */
UCG_C11(0x0a0, 0x0b4), /* Set Colour Depth */
UCG_C11(0x0a1, 0x000), /* Set Display Start Line */
UCG_C11(0x0a2, 0x000), /* Set Display Offset */
UCG_C12(0x015, 0x000, 0x07f), /* Set Column Address */
UCG_C12(0x075, 0x000, 0x07f), /* Set Row Address */
UCG_C11(0x0b3, 0x0f1), /* Front Clock Div */
//UCG_C11(0x0ca, 0x07f), /* Set Multiplex Ratio, reset default: 0x7f */
UCG_C11(0x0b5, 0x000), /* Set GPIO */
//UCG_C11(0x0ab, 0x001), /* Set Function Selection, reset default: 0x01 */
UCG_C11(0x0b1, 0x032), /* Set Phase Length, reset default: 0x82 */
UCG_C13(0x0b4, 0xa0,0xb5,0x55), /* Set Segment Low Voltage, reset default: 0xa2 0xb5 0x55 */
//UCG_C11(0x0bb, 0x017), /* Set Precharge Voltage, reset default: 0x17 */
//UCG_C11(0x0be, 0x005), /* Set VComH Voltage, reset default: 0x05 */
UCG_C13(0x0c1, 0xc8, 0x80, 0xc8), /* Set Contrast */
UCG_C11(0x0c7, 0x00f), /* Set Master Contrast (0..15), reset default: 0x05 */
UCG_C11(0x0b6, 0x001), /* Set Second Precharge Period */
// UCG_C10(0x0b8), /* Set CMD Grayscale Lookup, 63 Bytes follow */
// UCG_A8(0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c),
// UCG_A8(0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14),
// UCG_A8(0x15,0x16,0x18,0x1a,0x1b,0x1C,0x1D,0x1F),
// UCG_A8(0x21,0x23,0x25,0x27,0x2A,0x2D,0x30,0x33),
// UCG_A8(0x36,0x39,0x3C,0x3F,0x42,0x45,0x48,0x4C),
// UCG_A8(0x50,0x54,0x58,0x5C,0x60,0x64,0x68,0x6C),
// UCG_A8(0x70,0x74,0x78,0x7D,0x82,0x87,0x8C,0x91),
// UCG_A7(0x96,0x9B,0xA0,0xA5,0xAA,0xAF,0xB4),
UCG_C10(0x05c), /* Write RAM */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ssd1351_18x128x128_ilsoft(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* 1. Call to the controller procedures to setup the com interface */
if ( ucg_dev_ic_ssd1351_18(ucg, msg, data) == 0 )
return 0;
/* 2. Send specific init sequence for this display module */
ucg_com_SendCmdSeq(ucg, ucg_ilsoft_ssd1351_init_seq);
return 1;
case UCG_MSG_DEV_POWER_DOWN:
/* let do power down by the conroller procedures */
return ucg_dev_ic_ssd1351_18(ucg, msg, data);
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 128;
return 1;
}
/* all other messages are handled by the controller procedures */
return ucg_dev_ic_ssd1351_18(ucg, msg, data);
}
/*
ucg_dev_oled_128x128_univision.c
Specific code for the Univision 1.5" OLED (UG2828, 128x128 pixel, 65K Colors, SEPS225)
Note: Only 65K color support, because 262K mode is not possible with 8 Bit SPI.
Universal uC Color Graphics Library
Copyright (c) 2015, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
/* the following code is from the UG2828GDEAF02 Datasheet */
static const ucg_pgm_uint8_t aaa_ucg_univision_seps225_init_seq[] = {
UCG_CFG_CD(0,1), /* First arg: level for commands, Second arg: level for command arguments */
UCG_RST(1),
UCG_CS(1), /* disable chip */
UCG_DLY_MS(1),
UCG_RST(0),
UCG_DLY_MS(1),
UCG_RST(1),
UCG_DLY_MS(50),
UCG_CS(0), /* enable chip */
UCG_C11(0x002, 0x001), /* OSC_CTL: external resistor, internal OSC */
UCG_C11(0x004, 0x000), /* REDUCE_CURRENT: normal operation, no current reduction */
UCG_C11(0x003, 0x030), /* CLK_DIV: 90Hz, ratio 1 */
UCG_C11(0x008, 0x000), /* Precharge time red */
UCG_C11(0x009, 0x000), /* Precharge time green */
UCG_C11(0x00a, 0x000), /* Precharge time blue */
UCG_C11(0x00b, 0x000), /* Precharge current red */
UCG_C11(0x00c, 0x000), /* Precharge current green */
UCG_C11(0x00d, 0x000), /* Precharge current blue */
UCG_C11(0x010, 0x04a), /* Driving current red */
UCG_C11(0x011, 0x025), /* Driving current green, original value 0x011 replaced by 0x025 */
UCG_C11(0x012, 0x02f), /* Driving current blue */
UCG_C11(0x013, 0x000), /* Display mode: RGB,column=0..127,column data display control=Normal Dispaly */
UCG_C11(0x014, 0x001), /* External interface: 18 bit, MPU, Bit size does not matter if MPU is selected*/
//UCG_C11(0x016, 0x076), /* Memory Mode: 6bits triple transfer (would require 6bit words on SPI, 262K support, horizontal inc., vertical inc., data continuously written horizontally */
UCG_C11(0x016, 0x066), /* Memory Mode: dual transfer (2x 8Bit), 65K support, horizontal inc., vertical inc., data continuously written horizontally */
/* memory window */
UCG_C11(0x017, 0x000), /* x0 */
UCG_C11(0x018, 0x07f), /* x1 */
UCG_C11(0x019, 0x000), /* y0 */
UCG_C11(0x01a, 0x07f), /* y1 */
/* memory start */
UCG_C11(0x020, 0x000), /* x */
UCG_C11(0x021, 0x000), /* y */
UCG_C11(0x028, 0x07f), /* Duty */
UCG_C11(0x029, 0x000), /* Display start line */
/* DDRAM start */
UCG_C11(0x02e, 0x000), /* x */
UCG_C11(0x02f, 0x000), /* y */
UCG_C11(0x033, 0x000), /* Display Screen Saver x0 */
UCG_C11(0x034, 0x07f), /* Display Screen Saver x1 */
UCG_C11(0x035, 0x000), /* Display Screen Saver y0 */
UCG_C11(0x036, 0x07f), /* Display Screen Saver y1 */
UCG_C11(0x080, 0x000), /* IREF: External */
UCG_DLY_MS(100), /* as suggested in the Univision manual */
UCG_C11(0x006, 0x001), /* Display on */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
/* init seq. from the .ino example from ZhangFeng, PRC. http://vfdclock.jimdo.com */
static const ucg_pgm_uint8_t ucg_univision_seps225_init_seq[] = {
UCG_CFG_CD(0,1), /* First arg: level for commands, Second arg: level for command arguments */
UCG_RST(1),
UCG_CS(1), /* disable chip */
UCG_DLY_MS(1),
UCG_RST(0),
UCG_DLY_MS(1),
UCG_RST(1),
UCG_DLY_MS(50),
UCG_CS(0), /* enable chip */
UCG_C11(0x006, 0x000), /* Display off */
UCG_C11(0x002, 0x001), /* OSC_CTL: external resistor, internal OSC */
UCG_C11(0x004, 0x000), /* REDUCE_CURRENT: normal operation, no current reduction */
UCG_C11(0x003, 0x030), /* CLK_DIV: 90Hz, ratio 1 */
UCG_C11(0x005, 0x000), /* Software Reset */
UCG_C11(0x008, 0x003), /* Precharge time red */
UCG_C11(0x009, 0x004), /* Precharge time green */
UCG_C11(0x00a, 0x005), /* Precharge time blue */
UCG_C11(0x00b, 0x00b), /* Precharge current red */
UCG_C11(0x00c, 0x00b), /* Precharge current green */
UCG_C11(0x00d, 0x00e), /* Precharge current blue */
UCG_C11(0x010, 0x03e), /* Driving current red */
UCG_C11(0x011, 0x032), /* Driving current green, original value 0x011 replaced by 0x025 */
UCG_C11(0x012, 0x03d), /* Driving current blue */
UCG_C11(0x013, 0x000), /* Display mode: RGB,column=0..127,column data display control=Normal Dispaly */
UCG_C11(0x014, 0x001), /* External interface: 18 bit, MPU, Bit size does not matter if MPU is selected*/
//UCG_C11(0x016, 0x076), /* Memory Mode: 6bits triple transfer (would require 6bit words on SPI, 262K support, horizontal inc., vertical inc., data continuously written horizontally */
UCG_C11(0x015, 0x000),
UCG_C11(0x016, 0x066), /* Memory Mode: dual transfer (2x 8Bit), 65K support, horizontal inc., vertical inc., data continuously written horizontally */
/* memory window */
UCG_C11(0x017, 0x000), /* x0 */
UCG_C11(0x018, 0x07f), /* x1 */
UCG_C11(0x019, 0x000), /* y0 */
UCG_C11(0x01a, 0x07f), /* y1 */
/* memory start */
UCG_C11(0x020, 0x000), /* x */
UCG_C11(0x021, 0x000), /* y */
UCG_C11(0x028, 0x07f), /* Duty */
UCG_C11(0x029, 0x000), /* Display start line */
/* DDRAM start */
UCG_C11(0x02e, 0x000), /* x */
UCG_C11(0x02f, 0x000), /* y */
UCG_C11(0x031, 0x000),
UCG_C11(0x032, 0x000),
UCG_C11(0x033, 0x000), /* Display Screen Saver x0 */
UCG_C11(0x034, 0x07f), /* Display Screen Saver x1 */
UCG_C11(0x035, 0x000), /* Display Screen Saver y0 */
UCG_C11(0x036, 0x07f), /* Display Screen Saver y1 */
UCG_C11(0x080, 0x000), /* IREF: External */
UCG_DLY_MS(100), /* as suggested in the Univision manual */
UCG_C11(0x006, 0x001), /* Display on */
//UCG_C10(0x022),
UCG_CS(1), /* disable chip */
//UCG_DATA(),
UCG_END(), /* end of sequence */
};
static const ucg_pgm_uint8_t ucg_seps255_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11(0x016, 0x066), /* Memory Mode */
UCG_C11(0x020, 0), /* set x position */
UCG_C11(0x021, 0), /* set y position */
UCG_C10(0x022), /* prepare for data */
UCG_DATA(), /* change to data mode */
UCG_END()
};
ucg_int_t ucg_dev_seps225_16x128x128_univision(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* 1. Call to the controller procedures to setup the com interface */
if ( ucg_dev_ic_seps225_16(ucg, msg, data) == 0 )
return 0;
/* 2. Send specific init sequence for this display module */
ucg_com_SendCmdSeq(ucg, ucg_univision_seps225_init_seq);
/* demonstration of the OLED error */
/*
{
uint8_t r,g,b, i;
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir0_seq);
r = 0;
g = 0;
b = 80;
c[0] = (r&0x0f8) | (((g) >>5));
c[1] = ((((g))<<3)&0x0e0) | (((b) >>3));
ucg_com_SendRepeat2Bytes(ucg, 128, c);
r = 0;
g = 0;
b = 0;
c[0] = (r&0x0f8) | (((g) >>5));
c[1] = ((((g))<<3)&0x0e0) | (((b) >>3));
for( i = 0; i < 126; i++ )
{
ucg_com_SendRepeat2Bytes(ucg, 128, c);
}
r = 0;
g = 0;
b = 255;
c[0] = (r&0x0f8) | (((g) >>5));
c[1] = ((((g))<<3)&0x0e0) | (((b) >>3));
ucg_com_SendRepeat2Bytes(ucg, 40, c);
for(;;)
;
}
*/
return 1;
case UCG_MSG_DEV_POWER_DOWN:
/* let do power down by the controller procedures */
return ucg_dev_ic_seps225_16(ucg, msg, data);
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 128;
return 1;
}
/* all other messages are handled by the controller procedures */
return ucg_dev_ic_seps225_16(ucg, msg, data);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment