Unverified Commit c6f6c54b authored by Terry Ellison's avatar Terry Ellison Committed by GitHub
Browse files

Merge pull request #2184 from devsaurus/u8g2_port

Replace u8glib with u8g2
parents 4c6c9d33 c03df2b4
/*
u8g_pb8v2.c
8bit height 2 bit per pixel page buffer
byte has vertical orientation
Universal 8bit Graphics Library
Copyright (c) 2011, 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 "u8g.h"
#include <string.h>
void u8g_pb8v2_Init(u8g_pb_t *b, void *buf, u8g_uint_t width)
{
b->buf = buf;
b->width = width;
u8g_pb_Clear(b);
}
void u8g_pb8v2_set_pixel(u8g_pb_t *b, u8g_uint_t x, u8g_uint_t y, uint8_t color_index)
{
register uint8_t mask;
uint8_t *ptr = b->buf;
y -= b->p.page_y0;
mask = 0x03;
y &= 0x03;
y <<= 1;
mask <<= y;
mask ^=0xff;
color_index &= 3;
color_index <<= y;
ptr += x;
*ptr &= mask;
*ptr |= color_index;
}
void u8g_pb8v2_SetPixel(u8g_pb_t *b, const u8g_dev_arg_pixel_t * const arg_pixel)
{
if ( arg_pixel->y < b->p.page_y0 )
return;
if ( arg_pixel->y > b->p.page_y1 )
return;
if ( arg_pixel->x >= b->width )
return;
u8g_pb8v2_set_pixel(b, arg_pixel->x, arg_pixel->y, arg_pixel->color);
}
void u8g_pb8v2_Set8PixelStd(u8g_pb_t *b, u8g_dev_arg_pixel_t *arg_pixel)
{
register uint8_t pixel = arg_pixel->pixel;
do
{
if ( pixel & 128 )
{
u8g_pb8v2_SetPixel(b, arg_pixel);
}
switch( arg_pixel->dir )
{
case 0: arg_pixel->x++; break;
case 1: arg_pixel->y++; break;
case 2: arg_pixel->x--; break;
case 3: arg_pixel->y--; break;
}
pixel <<= 1;
} while( pixel != 0 );
}
uint8_t u8g_dev_pb8v2_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg)
{
u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem);
switch(msg)
{
case U8G_DEV_MSG_SET_8PIXEL:
if ( u8g_pb_Is8PixelVisible(pb, (u8g_dev_arg_pixel_t *)arg) )
{
u8g_pb8v2_Set8PixelStd(pb, (u8g_dev_arg_pixel_t *)arg);
}
break;
case U8G_DEV_MSG_SET_PIXEL:
u8g_pb8v2_SetPixel(pb, (u8g_dev_arg_pixel_t *)arg);
break;
case U8G_DEV_MSG_INIT:
break;
case U8G_DEV_MSG_STOP:
break;
case U8G_DEV_MSG_PAGE_FIRST:
u8g_pb_Clear(pb);
u8g_page_First(&(pb->p));
break;
case U8G_DEV_MSG_PAGE_NEXT:
if ( u8g_page_Next(&(pb->p)) == 0 )
return 0;
u8g_pb_Clear(pb);
break;
#ifdef U8G_DEV_MSG_IS_BBX_INTERSECTION
case U8G_DEV_MSG_IS_BBX_INTERSECTION:
return u8g_pb_IsIntersection(pb, (u8g_dev_arg_bbx_t *)arg);
#endif
case U8G_DEV_MSG_GET_PAGE_BOX:
u8g_pb_GetPageBox(pb, (u8g_box_t *)arg);
break;
case U8G_DEV_MSG_GET_WIDTH:
*((u8g_uint_t *)arg) = pb->width;
break;
case U8G_DEV_MSG_GET_HEIGHT:
*((u8g_uint_t *)arg) = pb->p.total_height;
break;
case U8G_DEV_MSG_SET_COLOR_ENTRY:
break;
case U8G_DEV_MSG_SET_XY_CB:
break;
case U8G_DEV_MSG_GET_MODE:
return U8G_MODE_GRAY2BIT;
}
return 1;
}
/*
u8g_pbxh16.c
x lines per page, horizontal, 16 bits per pixel (hi color modes)
Universal 8bit 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.
struct _u8g_pb_t
{
u8g_page_t p;
u8g_uint_t width;
void *buf;
};
typedef struct _u8g_pb_t u8g_pb_t;
uint8_t u8g_index_color_xh16_buf[2*WIDTH*PAGE_HEIGHT] U8G_NOCOMMON ;
u8g_pb_t u8g_index_color_xh16_pb = { {PAGE_HEIGHT, HEIGHT, 0, 0, 0}, WIDTH, u8g_index_color_xh16_buf};
u8g_dev_t name = { dev_fn, &u8g_index_color_xh16_pb , com_fn }
*/
#include "u8g.h"
/*
#define WIDTH_BITS 7
#define WIDTH (1<<WIDTH_BITS)
#define PAGE_HEIGHT_BITS 3
#define PAGE_HEIGHT (1<<PAGE_HEIGHT_BITS)
*/
void u8g_pbxh16_Clear(u8g_pb_t *b)
{
uint8_t *ptr = (uint8_t *)b->buf;
uint8_t *end_ptr = ptr;
uint8_t cnt = b->p.page_height;
do
{
end_ptr += b->width*2;
cnt--;
} while( cnt > 0 );
do
{
*ptr++ = 0;
} while( ptr != end_ptr );
}
void u8g_pbxh16_Init(u8g_pb_t *b, void *buf, u8g_uint_t width)
{
b->buf = buf;
b->width = width;
u8g_pbxh16_Clear(b);
}
static void u8g_pbxh16_set_pixel(u8g_pb_t *b, u8g_uint_t x, u8g_uint_t y, uint8_t low, uint8_t high)
{
uint16_t tmp;
uint8_t *ptr = b->buf;
y -= b->p.page_y0;
tmp = y;
tmp *= b->width;
tmp += x;
tmp <<= 1;
ptr += tmp;
*ptr = low;
ptr++;
*ptr = high;
}
void u8g_pbxh16_SetPixel(u8g_pb_t *b, const u8g_dev_arg_pixel_t * const arg_pixel)
{
if ( arg_pixel->y < b->p.page_y0 )
return;
if ( arg_pixel->y > b->p.page_y1 )
return;
if ( arg_pixel->x >= b->width )
return;
u8g_pbxh16_set_pixel(b, arg_pixel->x, arg_pixel->y, arg_pixel->color, arg_pixel->hi_color);
}
void u8g_pbxh16_Set8Pixel(u8g_pb_t *b, u8g_dev_arg_pixel_t *arg_pixel)
{
register uint8_t pixel = arg_pixel->pixel;
u8g_uint_t dx = 0;
u8g_uint_t dy = 0;
switch( arg_pixel->dir )
{
case 0: dx++; break;
case 1: dy++; break;
case 2: dx--; break;
case 3: dy--; break;
}
do
{
if ( pixel & 128 )
u8g_pbxh16_SetPixel(b, arg_pixel);
arg_pixel->x += dx;
arg_pixel->y += dy;
pixel <<= 1;
} while( pixel != 0 );
}
uint8_t u8g_dev_pbxh16_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg)
{
u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem);
switch(msg)
{
case U8G_DEV_MSG_SET_8PIXEL:
if ( u8g_pb_Is8PixelVisible(pb, (u8g_dev_arg_pixel_t *)arg) )
u8g_pbxh16_Set8Pixel(pb, (u8g_dev_arg_pixel_t *)arg);
break;
case U8G_DEV_MSG_SET_PIXEL:
u8g_pbxh16_SetPixel(pb, (u8g_dev_arg_pixel_t *)arg);
break;
case U8G_DEV_MSG_INIT:
break;
case U8G_DEV_MSG_STOP:
break;
case U8G_DEV_MSG_PAGE_FIRST:
u8g_pbxh16_Clear(pb);
u8g_page_First(&(pb->p));
break;
case U8G_DEV_MSG_PAGE_NEXT:
if ( u8g_page_Next(&(pb->p)) == 0 )
return 0;
u8g_pbxh16_Clear(pb);
break;
#ifdef U8G_DEV_MSG_IS_BBX_INTERSECTION
case U8G_DEV_MSG_IS_BBX_INTERSECTION:
return u8g_pb_IsIntersection(pb, (u8g_dev_arg_bbx_t *)arg);
#endif
case U8G_DEV_MSG_GET_PAGE_BOX:
u8g_pb_GetPageBox(pb, (u8g_box_t *)arg);
break;
case U8G_DEV_MSG_GET_WIDTH:
*((u8g_uint_t *)arg) = pb->width;
break;
case U8G_DEV_MSG_GET_HEIGHT:
*((u8g_uint_t *)arg) = pb->p.total_height;
break;
case U8G_DEV_MSG_SET_COLOR_ENTRY:
break;
case U8G_DEV_MSG_SET_XY_CB:
break;
case U8G_DEV_MSG_GET_MODE:
return U8G_MODE_HICOLOR;
}
return 1;
}
/*
u8g_pbxh24.c
x lines per page, horizontal, 24 bits per pixel (true color modes)
Universal 8bit 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.
struct _u8g_pb_t
{
u8g_page_t p;
u8g_uint_t width;
void *buf;
};
typedef struct _u8g_pb_t u8g_pb_t;
uint8_t u8g_index_color_xh16_buf[2*WIDTH*PAGE_HEIGHT] U8G_NOCOMMON ;
u8g_pb_t u8g_index_color_xh16_pb = { {PAGE_HEIGHT, HEIGHT, 0, 0, 0}, WIDTH, u8g_index_color_xh16_buf};
u8g_dev_t name = { dev_fn, &u8g_index_color_xh16_pb , com_fn }
*/
#include "u8g.h"
/*
#define WIDTH_BITS 7
#define WIDTH (1<<WIDTH_BITS)
#define PAGE_HEIGHT_BITS 3
#define PAGE_HEIGHT (1<<PAGE_HEIGHT_BITS)
*/
void u8g_pbxh24_Clear(u8g_pb_t *b)
{
uint8_t *ptr = (uint8_t *)b->buf;
uint8_t *end_ptr = ptr;
uint8_t cnt = b->p.page_height;
do
{
end_ptr += b->width*3;
cnt--;
} while( cnt > 0 );
do
{
*ptr++ = 0;
} while( ptr != end_ptr );
}
void u8g_pbxh24_Init(u8g_pb_t *b, void *buf, u8g_uint_t width)
{
b->buf = buf;
b->width = width;
u8g_pbxh24_Clear(b);
}
#ifdef OBSOLETE
static void u8g_pbxh24_set_pixel(u8g_pb_t *b, u8g_uint_t x, u8g_uint_t y, uint8_t r, uint8_t g, uint8_t b)
{
uint16_t tmp;
uint8_t *ptr = b->buf;
y -= b->p.page_y0;
tmp = y;
tmp *= b->width;
tmp += x;
tmp *= 3;
ptr += tmp;
*ptr = r;
ptr++;
*ptr = g;
ptr++;
*ptr = b;
}
#endif
/*
intensity
0..3 intensity value
4 replace color
*/
static void u8g_pbxh24_set_tpixel(u8g_pb_t *b, u8g_uint_t x, u8g_uint_t y, uint8_t red, uint8_t green, uint8_t blue, uint8_t intensity)
{
uint16_t tmp;
uint8_t *ptr = b->buf;
if ( intensity == 0 )
return;
y -= b->p.page_y0;
tmp = y;
tmp *= b->width;
tmp += x;
tmp *= 3;
ptr += tmp;
if ( intensity == 4 )
{
*ptr = red;
ptr++;
*ptr = green;
ptr++;
*ptr = blue;
return;
}
if ( intensity == 2 )
{
/*
red = red/4 + red/2;
green = green/4 + green/2;
blue = blue/4 + blue/2;
*/
red >>= 1;
green >>= 1;
blue >>= 1;
}
else if ( intensity == 1 )
{
red >>= 2;
green >>= 2;
blue >>= 2;
}
if ( *ptr >= 255-red ) *ptr = 255;
else *ptr += red;
ptr++;
if ( *ptr >= 255-green ) *ptr = 255;
else *ptr += green;
ptr++;
if ( *ptr >= 255-blue ) *ptr = 255;
else *ptr += blue;
/*
if ( *ptr < red ) *ptr = red;
ptr++;
if ( *ptr < green ) *ptr = green;
ptr++;
if ( *ptr < blue ) *ptr = blue;
*/
}
void u8g_pbxh24_SetTPixel(u8g_pb_t *b, const u8g_dev_arg_pixel_t * const arg_pixel, uint8_t intensity)
{
if ( arg_pixel->y < b->p.page_y0 )
return;
if ( arg_pixel->y > b->p.page_y1 )
return;
if ( arg_pixel->x >= b->width )
return;
u8g_pbxh24_set_tpixel(b, arg_pixel->x, arg_pixel->y, arg_pixel->color, arg_pixel->hi_color, arg_pixel->blue, intensity);
}
void u8g_pbxh24_Set8Pixel(u8g_pb_t *b, u8g_dev_arg_pixel_t *arg_pixel)
{
register uint8_t pixel = arg_pixel->pixel;
u8g_uint_t dx = 0;
u8g_uint_t dy = 0;
switch( arg_pixel->dir )
{
case 0: dx++; break;
case 1: dy++; break;
case 2: dx--; break;
case 3: dy--; break;
}
do
{
if ( pixel & 128 )
u8g_pbxh24_SetTPixel(b, arg_pixel, 4);
arg_pixel->x += dx;
arg_pixel->y += dy;
pixel <<= 1;
} while( pixel != 0 );
}
void u8g_pbxh24_Set4TPixel(u8g_pb_t *b, u8g_dev_arg_pixel_t *arg_pixel)
{
register uint8_t pixel = arg_pixel->pixel;
u8g_uint_t dx = 0;
u8g_uint_t dy = 0;
switch( arg_pixel->dir )
{
case 0: dx++; break;
case 1: dy++; break;
case 2: dx--; break;
case 3: dy--; break;
}
do
{
u8g_pbxh24_SetTPixel(b, arg_pixel, pixel >> 6);
arg_pixel->x += dx;
arg_pixel->y += dy;
pixel <<= 2;
} while( pixel != 0 );
}
uint8_t u8g_dev_pbxh24_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg)
{
u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem);
switch(msg)
{
case U8G_DEV_MSG_SET_8PIXEL:
if ( u8g_pb_Is8PixelVisible(pb, (u8g_dev_arg_pixel_t *)arg) )
u8g_pbxh24_Set8Pixel(pb, (u8g_dev_arg_pixel_t *)arg);
break;
case U8G_DEV_MSG_SET_PIXEL:
u8g_pbxh24_SetTPixel(pb, (u8g_dev_arg_pixel_t *)arg, 4);
break;
case U8G_DEV_MSG_SET_4TPIXEL:
u8g_pbxh24_Set4TPixel(pb, (u8g_dev_arg_pixel_t *)arg);
break;
case U8G_DEV_MSG_SET_TPIXEL:
u8g_pbxh24_SetTPixel(pb, (u8g_dev_arg_pixel_t *)arg, ((u8g_dev_arg_pixel_t *)arg)->pixel&3);
break;
case U8G_DEV_MSG_INIT:
break;
case U8G_DEV_MSG_STOP:
break;
case U8G_DEV_MSG_PAGE_FIRST:
u8g_pbxh24_Clear(pb);
u8g_page_First(&(pb->p));
break;
case U8G_DEV_MSG_PAGE_NEXT:
if ( u8g_page_Next(&(pb->p)) == 0 )
return 0;
u8g_pbxh24_Clear(pb);
break;
#ifdef U8G_DEV_MSG_IS_BBX_INTERSECTION
case U8G_DEV_MSG_IS_BBX_INTERSECTION:
return u8g_pb_IsIntersection(pb, (u8g_dev_arg_bbx_t *)arg);
#endif
case U8G_DEV_MSG_GET_PAGE_BOX:
u8g_pb_GetPageBox(pb, (u8g_box_t *)arg);
break;
case U8G_DEV_MSG_GET_WIDTH:
*((u8g_uint_t *)arg) = pb->width;
break;
case U8G_DEV_MSG_GET_HEIGHT:
*((u8g_uint_t *)arg) = pb->p.total_height;
break;
case U8G_DEV_MSG_SET_COLOR_ENTRY:
break;
case U8G_DEV_MSG_SET_XY_CB:
break;
case U8G_DEV_MSG_GET_MODE:
return U8G_MODE_TRUECOLOR;
}
return 1;
}
/*
u8g_polygon.c
Implementation of a polygon draw algorithm for "convex" polygons.
Universal 8bit 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.
See also:
http://www.angelfire.com/linux/myp/ConvexPolRas/ConvexPolRas.html
Computer Graphics, Principles and Practice, Foley, van Dam, Feiner, Hughes (pp 92)
Michael Abrash's Graphics Programming Black Book, Special Edition (Chapter 38 and 39)
Optimized for embedded systems
- static memory usage only
- consistent data types
- low flash ROM consumption
*/
#include "u8g.h"
/*===========================================*/
/* procedures, which should not be inlined (save as much flash ROM as possible */
static uint8_t pge_Next(struct pg_edge_struct *pge) PG_NOINLINE;
static uint8_t pg_inc(pg_struct *pg, uint8_t i) PG_NOINLINE;
static uint8_t pg_dec(pg_struct *pg, uint8_t i) PG_NOINLINE;
static void pg_expand_min_y(pg_struct *pg, pg_word_t min_y, uint8_t pge_idx) PG_NOINLINE;
static void pg_line_init(pg_struct * const pg, uint8_t pge_index) PG_NOINLINE;
/*===========================================*/
/* line draw algorithm */
static uint8_t pge_Next(struct pg_edge_struct *pge)
{
if ( pge->current_y >= pge->max_y )
return 0;
pge->current_x += pge->current_x_offset;
pge->error += pge->error_offset;
if ( pge->error > 0 )
{
pge->current_x += pge->x_direction;
pge->error -= pge->height;
}
pge->current_y++;
return 1;
}
/* assumes y2 > y1 */
static void pge_Init(struct pg_edge_struct *pge, pg_word_t x1, pg_word_t y1, pg_word_t x2, pg_word_t y2)
{
pg_word_t dx = x2 - x1;
pg_word_t width;
pge->height = y2 - y1;
pge->max_y = y2;
pge->current_y = y1;
pge->current_x = x1;
if ( dx >= 0 )
{
pge->x_direction = 1;
width = dx;
pge->error = 0;
}
else
{
pge->x_direction = -1;
width = -dx;
pge->error = 1 - pge->height;
}
pge->current_x_offset = dx / pge->height;
pge->error_offset = width % pge->height;
}
/*===========================================*/
/* convex polygon algorithm */
static uint8_t pg_inc(pg_struct *pg, uint8_t i)
{
i++;
if ( i >= pg->cnt )
i = 0;
return i;
}
static uint8_t pg_dec(pg_struct *pg, uint8_t i)
{
i--;
if ( i >= pg->cnt )
i = pg->cnt-1;
return i;
}
static void pg_expand_min_y(pg_struct *pg, pg_word_t min_y, uint8_t pge_idx)
{
uint8_t i = pg->pge[pge_idx].curr_idx;
for(;;)
{
i = pg->pge[pge_idx].next_idx_fn(pg, i);
if ( pg->list[i].y != min_y )
break;
pg->pge[pge_idx].curr_idx = i;
}
}
static uint8_t pg_prepare(pg_struct *pg)
{
pg_word_t max_y;
pg_word_t min_y;
uint8_t i;
/* setup the next index procedures */
pg->pge[PG_RIGHT].next_idx_fn = pg_inc;
pg->pge[PG_LEFT].next_idx_fn = pg_dec;
/* search for highest and lowest point */
max_y = pg->list[0].y;
min_y = pg->list[0].y;
pg->pge[PG_LEFT].curr_idx = 0;
for( i = 1; i < pg->cnt; i++ )
{
if ( max_y < pg->list[i].y )
{
max_y = pg->list[i].y;
}
if ( min_y > pg->list[i].y )
{
pg->pge[PG_LEFT].curr_idx = i;
min_y = pg->list[i].y;
}
}
/* calculate total number of scan lines */
pg->total_scan_line_cnt = max_y;
pg->total_scan_line_cnt -= min_y;
/* exit if polygon height is zero */
if ( pg->total_scan_line_cnt == 0 )
return 0;
/* if the minimum y side is flat, try to find the lowest and highest x points */
pg->pge[PG_RIGHT].curr_idx = pg->pge[PG_LEFT].curr_idx;
pg_expand_min_y(pg, min_y, PG_RIGHT);
pg_expand_min_y(pg, min_y, PG_LEFT);
/* check if the min side is really flat (depends on the x values) */
pg->is_min_y_not_flat = 1;
if ( pg->list[pg->pge[PG_LEFT].curr_idx].x != pg->list[pg->pge[PG_RIGHT].curr_idx].x )
{
pg->is_min_y_not_flat = 0;
}
else
{
pg->total_scan_line_cnt--;
if ( pg->total_scan_line_cnt == 0 )
return 0;
}
return 1;
}
static void pg_hline(pg_struct *pg, u8g_t *u8g)
{
pg_word_t x1, x2, y;
x1 = pg->pge[PG_LEFT].current_x;
x2 = pg->pge[PG_RIGHT].current_x;
y = pg->pge[PG_RIGHT].current_y;
if ( y < 0 )
return;
if ( y >= u8g_GetHeight(u8g) )
return;
if ( x1 < x2 )
{
if ( x2 < 0 )
return;
if ( x1 >= u8g_GetWidth(u8g) )
return;
if ( x1 < 0 )
x1 = 0;
if ( x2 >= u8g_GetWidth(u8g) )
x2 = u8g_GetWidth(u8g);
u8g_DrawHLine(u8g, x1, y, x2 - x1);
}
else
{
if ( x1 < 0 )
return;
if ( x2 >= u8g_GetWidth(u8g) )
return;
if ( x2 < 0 )
x1 = 0;
if ( x1 >= u8g_GetWidth(u8g) )
x1 = u8g_GetWidth(u8g);
u8g_DrawHLine(u8g, x2, y, x1 - x2);
}
}
static void pg_line_init(pg_struct * pg, uint8_t pge_index)
{
struct pg_edge_struct *pge = pg->pge+pge_index;
uint8_t idx;
pg_word_t x1;
pg_word_t y1;
pg_word_t x2;
pg_word_t y2;
idx = pge->curr_idx;
y1 = pg->list[idx].y;
x1 = pg->list[idx].x;
idx = pge->next_idx_fn(pg, idx);
y2 = pg->list[idx].y;
x2 = pg->list[idx].x;
pge->curr_idx = idx;
pge_Init(pge, x1, y1, x2, y2);
}
static void pg_exec(pg_struct *pg, u8g_t *u8g)
{
pg_word_t i = pg->total_scan_line_cnt;
/* first line is skipped if the min y line is not flat */
pg_line_init(pg, PG_LEFT);
pg_line_init(pg, PG_RIGHT);
if ( pg->is_min_y_not_flat != 0 )
{
pge_Next(&(pg->pge[PG_LEFT]));
pge_Next(&(pg->pge[PG_RIGHT]));
}
do
{
pg_hline(pg, u8g);
while ( pge_Next(&(pg->pge[PG_LEFT])) == 0 )
{
pg_line_init(pg, PG_LEFT);
}
while ( pge_Next(&(pg->pge[PG_RIGHT])) == 0 )
{
pg_line_init(pg, PG_RIGHT);
}
i--;
} while( i > 0 );
}
/*===========================================*/
/* API procedures */
void pg_ClearPolygonXY(pg_struct *pg)
{
pg->cnt = 0;
}
void pg_AddPolygonXY(pg_struct *pg, u8g_t *u8g, int16_t x, int16_t y)
{
if ( pg->cnt < PG_MAX_POINTS )
{
pg->list[pg->cnt].x = x;
pg->list[pg->cnt].y = y;
pg->cnt++;
}
}
void pg_DrawPolygon(pg_struct *pg, u8g_t *u8g)
{
if ( pg_prepare(pg) == 0 )
return;
pg_exec(pg, u8g);
}
pg_struct u8g_pg;
void u8g_ClearPolygonXY(void)
{
pg_ClearPolygonXY(&u8g_pg);
}
void u8g_AddPolygonXY(u8g_t *u8g, int16_t x, int16_t y)
{
pg_AddPolygonXY(&u8g_pg, u8g, x, y);
}
void u8g_DrawPolygon(u8g_t *u8g)
{
pg_DrawPolygon(&u8g_pg, u8g);
}
void u8g_DrawTriangle(u8g_t *u8g, int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2)
{
u8g_ClearPolygonXY();
u8g_AddPolygonXY(u8g, x0, y0);
u8g_AddPolygonXY(u8g, x1, y1);
u8g_AddPolygonXY(u8g, x2, y2);
u8g_DrawPolygon(u8g);
}
/*
u8g_rect.c
U8G high level interface for horizontal and vertical things
Universal 8bit Graphics Library
Copyright (c) 2011, 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 "u8g.h"
void u8g_draw_hline(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w)
{
uint8_t pixel = 0x0ff;
while( w >= 8 )
{
u8g_Draw8Pixel(u8g, x, y, 0, pixel);
w-=8;
x+=8;
}
if ( w != 0 )
{
w ^=7;
w++;
pixel <<= w&7;
u8g_Draw8Pixel(u8g, x, y, 0, pixel);
}
}
void u8g_draw_vline(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t h)
{
uint8_t pixel = 0x0ff;
while( h >= 8 )
{
u8g_Draw8Pixel(u8g, x, y, 1, pixel);
h-=8;
y+=8;
}
if ( h != 0 )
{
h ^=7;
h++;
pixel <<= h&7;
u8g_Draw8Pixel(u8g, x, y, 1, pixel);
}
}
void u8g_DrawHLine(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w)
{
if ( u8g_IsBBXIntersection(u8g, x, y, w, 1) == 0 )
return;
u8g_draw_hline(u8g, x, y, w);
}
void u8g_DrawVLine(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w)
{
if ( u8g_IsBBXIntersection(u8g, x, y, 1, w) == 0 )
return;
u8g_draw_vline(u8g, x, y, w);
}
/* restrictions: w > 0 && h > 0 */
void u8g_DrawFrame(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h)
{
u8g_uint_t xtmp = x;
if ( u8g_IsBBXIntersection(u8g, x, y, w, h) == 0 )
return;
u8g_draw_hline(u8g, x, y, w);
u8g_draw_vline(u8g, x, y, h);
x+=w;
x--;
u8g_draw_vline(u8g, x, y, h);
y+=h;
y--;
u8g_draw_hline(u8g, xtmp, y, w);
}
void u8g_draw_box(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h)
{
do
{
u8g_draw_hline(u8g, x, y, w);
y++;
h--;
} while( h != 0 );
}
/* restrictions: h > 0 */
void u8g_DrawBox(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h)
{
if ( u8g_IsBBXIntersection(u8g, x, y, w, h) == 0 )
return;
u8g_draw_box(u8g, x, y, w, h);
}
void u8g_DrawRFrame(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h, u8g_uint_t r)
{
u8g_uint_t xl, yu;
if ( u8g_IsBBXIntersection(u8g, x, y, w, h) == 0 )
return;
xl = x;
xl += r;
yu = y;
yu += r;
{
u8g_uint_t yl, xr;
xr = x;
xr += w;
xr -= r;
xr -= 1;
yl = y;
yl += h;
yl -= r;
yl -= 1;
u8g_draw_circle(u8g, xl, yu, r, U8G_DRAW_UPPER_LEFT);
u8g_draw_circle(u8g, xr, yu, r, U8G_DRAW_UPPER_RIGHT);
u8g_draw_circle(u8g, xl, yl, r, U8G_DRAW_LOWER_LEFT);
u8g_draw_circle(u8g, xr, yl, r, U8G_DRAW_LOWER_RIGHT);
}
{
u8g_uint_t ww, hh;
ww = w;
ww -= r;
ww -= r;
ww -= 2;
hh = h;
hh -= r;
hh -= r;
hh -= 2;
xl++;
yu++;
h--;
w--;
u8g_draw_hline(u8g, xl, y, ww);
u8g_draw_hline(u8g, xl, y+h, ww);
u8g_draw_vline(u8g, x, yu, hh);
u8g_draw_vline(u8g, x+w, yu, hh);
}
}
void u8g_DrawRBox(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h, u8g_uint_t r)
{
u8g_uint_t xl, yu;
u8g_uint_t yl, xr;
if ( u8g_IsBBXIntersection(u8g, x, y, w, h) == 0 )
return;
xl = x;
xl += r;
yu = y;
yu += r;
xr = x;
xr += w;
xr -= r;
xr -= 1;
yl = y;
yl += h;
yl -= r;
yl -= 1;
u8g_draw_disc(u8g, xl, yu, r, U8G_DRAW_UPPER_LEFT);
u8g_draw_disc(u8g, xr, yu, r, U8G_DRAW_UPPER_RIGHT);
u8g_draw_disc(u8g, xl, yl, r, U8G_DRAW_LOWER_LEFT);
u8g_draw_disc(u8g, xr, yl, r, U8G_DRAW_LOWER_RIGHT);
{
u8g_uint_t ww, hh;
ww = w;
ww -= r;
ww -= r;
ww -= 2;
hh = h;
hh -= r;
hh -= r;
hh -= 2;
xl++;
yu++;
h--;
u8g_draw_box(u8g, xl, y, ww, r+1);
u8g_draw_box(u8g, xl, yl, ww, r+1);
//u8g_draw_hline(u8g, xl, y+h, ww);
u8g_draw_box(u8g, x, yu, w, hh);
//u8g_draw_vline(u8g, x+w, yu, hh);
}
}
/*
u8g_rot.c
Universal 8bit Graphics Library
Copyright (c) 2011, 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 "u8g.h"
uint8_t u8g_dev_rot90_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg);
uint8_t u8g_dev_rot180_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg);
uint8_t u8g_dev_rot270_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg);
uint8_t u8g_dev_rot_dummy_fn(u8g_t *u8g, u8g_dev_t*dev, uint8_t msg, void *arg)
{
return 0;
}
u8g_dev_t u8g_dev_rot = { u8g_dev_rot_dummy_fn, NULL, NULL };
void u8g_UndoRotation(u8g_t *u8g)
{
if ( u8g->dev != &u8g_dev_rot )
return;
u8g->dev = u8g_dev_rot.dev_mem;
u8g_UpdateDimension(u8g);
}
void u8g_SetRot90(u8g_t *u8g)
{
if ( u8g->dev != &u8g_dev_rot )
{
u8g_dev_rot.dev_mem = u8g->dev;
u8g->dev = &u8g_dev_rot;
}
u8g_dev_rot.dev_fn = u8g_dev_rot90_fn;
u8g_UpdateDimension(u8g);
}
void u8g_SetRot180(u8g_t *u8g)
{
if ( u8g->dev != &u8g_dev_rot )
{
u8g_dev_rot.dev_mem = u8g->dev;
u8g->dev = &u8g_dev_rot;
}
u8g_dev_rot.dev_fn = u8g_dev_rot180_fn;
u8g_UpdateDimension(u8g);
}
void u8g_SetRot270(u8g_t *u8g)
{
if ( u8g->dev != &u8g_dev_rot )
{
u8g_dev_rot.dev_mem = u8g->dev;
u8g->dev = &u8g_dev_rot;
}
u8g_dev_rot.dev_fn = u8g_dev_rot270_fn;
u8g_UpdateDimension(u8g);
}
uint8_t u8g_dev_rot90_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg)
{
u8g_dev_t *rotation_chain = (u8g_dev_t *)(dev->dev_mem);
switch(msg)
{
default:
/*
case U8G_DEV_MSG_INIT:
case U8G_DEV_MSG_STOP:
case U8G_DEV_MSG_PAGE_FIRST:
case U8G_DEV_MSG_PAGE_NEXT:
case U8G_DEV_MSG_SET_COLOR_ENTRY:
case U8G_DEV_MSG_SET_XY_CB:
*/
return u8g_call_dev_fn(u8g, rotation_chain, msg, arg);
#ifdef U8G_DEV_MSG_IS_BBX_INTERSECTION
case U8G_DEV_MSG_IS_BBX_INTERSECTION:
{
u8g_dev_arg_bbx_t *bbx = (u8g_dev_arg_bbx_t *)arg;
u8g_uint_t x, y, tmp;
/* transform the reference point */
y = bbx->x;
x = u8g->height;
/* x = u8g_GetWidthLL(u8g, rotation_chain); */
x -= bbx->y;
x--;
/* adjust point to be the uppler left corner again */
x -= bbx->h;
x++;
/* swap box dimensions */
tmp = bbx->w;
bbx->w = bbx->h;
bbx->h = tmp;
/* store x,y */
bbx->x = x;
bbx->y = y;
}
return u8g_call_dev_fn(u8g, rotation_chain, msg, arg);
#endif /* U8G_DEV_MSG_IS_BBX_INTERSECTION */
case U8G_DEV_MSG_GET_PAGE_BOX:
/* get page size from next device in the chain */
u8g_call_dev_fn(u8g, rotation_chain, msg, arg);
//printf("pre x: %3d..%3d y: %3d..%3d ", ((u8g_box_t *)arg)->x0, ((u8g_box_t *)arg)->x1, ((u8g_box_t *)arg)->y0, ((u8g_box_t *)arg)->y1);
{
u8g_box_t new_box;
//new_box.x0 = u8g_GetHeightLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->y1 - 1;
//new_box.x1 = u8g_GetHeightLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->y0 - 1;
new_box.x0 = ((u8g_box_t *)arg)->y0;
new_box.x1 = ((u8g_box_t *)arg)->y1;
new_box.y0 = ((u8g_box_t *)arg)->x0;
new_box.y1 = ((u8g_box_t *)arg)->x1;
*((u8g_box_t *)arg) = new_box;
//printf("post x: %3d..%3d y: %3d..%3d\n", ((u8g_box_t *)arg)->x0, ((u8g_box_t *)arg)->x1, ((u8g_box_t *)arg)->y0, ((u8g_box_t *)arg)->y1);
}
break;
case U8G_DEV_MSG_GET_WIDTH:
*((u8g_uint_t *)arg) = u8g_GetHeightLL(u8g,rotation_chain);
break;
case U8G_DEV_MSG_GET_HEIGHT:
*((u8g_uint_t *)arg) = u8g_GetWidthLL(u8g, rotation_chain);
break;
case U8G_DEV_MSG_SET_PIXEL:
case U8G_DEV_MSG_SET_TPIXEL:
{
u8g_uint_t x, y;
y = ((u8g_dev_arg_pixel_t *)arg)->x;
x = u8g_GetWidthLL(u8g, rotation_chain);
x -= ((u8g_dev_arg_pixel_t *)arg)->y;
x--;
((u8g_dev_arg_pixel_t *)arg)->x = x;
((u8g_dev_arg_pixel_t *)arg)->y = y;
}
u8g_call_dev_fn(u8g, rotation_chain, msg, arg);
break;
case U8G_DEV_MSG_SET_8PIXEL:
case U8G_DEV_MSG_SET_4TPIXEL:
{
u8g_uint_t x, y;
//uint16_t x,y;
y = ((u8g_dev_arg_pixel_t *)arg)->x;
x = u8g_GetWidthLL(u8g, rotation_chain);
x -= ((u8g_dev_arg_pixel_t *)arg)->y;
x--;
((u8g_dev_arg_pixel_t *)arg)->x = x;
((u8g_dev_arg_pixel_t *)arg)->y = y;
((u8g_dev_arg_pixel_t *)arg)->dir+=1;
((u8g_dev_arg_pixel_t *)arg)->dir &= 3;
}
u8g_call_dev_fn(u8g, rotation_chain, msg, arg);
break;
}
return 1;
}
uint8_t u8g_dev_rot180_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg)
{
u8g_dev_t *rotation_chain = (u8g_dev_t *)(dev->dev_mem);
switch(msg)
{
default:
/*
case U8G_DEV_MSG_INIT:
case U8G_DEV_MSG_STOP:
case U8G_DEV_MSG_PAGE_FIRST:
case U8G_DEV_MSG_PAGE_NEXT:
case U8G_DEV_MSG_SET_COLOR_ENTRY:
case U8G_DEV_MSG_SET_XY_CB:
*/
return u8g_call_dev_fn(u8g, rotation_chain, msg, arg);
#ifdef U8G_DEV_MSG_IS_BBX_INTERSECTION
case U8G_DEV_MSG_IS_BBX_INTERSECTION:
{
u8g_dev_arg_bbx_t *bbx = (u8g_dev_arg_bbx_t *)arg;
u8g_uint_t x, y;
/* transform the reference point */
//y = u8g_GetHeightLL(u8g, rotation_chain);
y = u8g->height;
y -= bbx->y;
y--;
//x = u8g_GetWidthLL(u8g, rotation_chain);
x = u8g->width;
x -= bbx->x;
x--;
/* adjust point to be the uppler left corner again */
y -= bbx->h;
y++;
x -= bbx->w;
x++;
/* store x,y */
bbx->x = x;
bbx->y = y;
}
return u8g_call_dev_fn(u8g, rotation_chain, msg, arg);
#endif /* U8G_DEV_MSG_IS_BBX_INTERSECTION */
case U8G_DEV_MSG_GET_PAGE_BOX:
/* get page size from next device in the chain */
u8g_call_dev_fn(u8g, rotation_chain, msg, arg);
//printf("pre x: %3d..%3d y: %3d..%3d ", ((u8g_box_t *)arg)->x0, ((u8g_box_t *)arg)->x1, ((u8g_box_t *)arg)->y0, ((u8g_box_t *)arg)->y1);
{
u8g_box_t new_box;
new_box.x0 = u8g_GetWidthLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->x1 - 1;
new_box.x1 = u8g_GetWidthLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->x0 - 1;
new_box.y0 = u8g_GetHeightLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->y1 - 1;
new_box.y1 = u8g_GetHeightLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->y0 - 1;
*((u8g_box_t *)arg) = new_box;
//printf("post x: %3d..%3d y: %3d..%3d\n", ((u8g_box_t *)arg)->x0, ((u8g_box_t *)arg)->x1, ((u8g_box_t *)arg)->y0, ((u8g_box_t *)arg)->y1);
}
break;
case U8G_DEV_MSG_GET_WIDTH:
*((u8g_uint_t *)arg) = u8g_GetWidthLL(u8g,rotation_chain);
break;
case U8G_DEV_MSG_GET_HEIGHT:
*((u8g_uint_t *)arg) = u8g_GetHeightLL(u8g, rotation_chain);
break;
case U8G_DEV_MSG_SET_PIXEL:
case U8G_DEV_MSG_SET_TPIXEL:
{
u8g_uint_t x, y;
y = u8g_GetHeightLL(u8g, rotation_chain);
y -= ((u8g_dev_arg_pixel_t *)arg)->y;
y--;
x = u8g_GetWidthLL(u8g, rotation_chain);
x -= ((u8g_dev_arg_pixel_t *)arg)->x;
x--;
((u8g_dev_arg_pixel_t *)arg)->x = x;
((u8g_dev_arg_pixel_t *)arg)->y = y;
}
u8g_call_dev_fn(u8g, rotation_chain, msg, arg);
break;
case U8G_DEV_MSG_SET_8PIXEL:
case U8G_DEV_MSG_SET_4TPIXEL:
{
u8g_uint_t x, y;
y = u8g_GetHeightLL(u8g, rotation_chain);
y -= ((u8g_dev_arg_pixel_t *)arg)->y;
y--;
x = u8g_GetWidthLL(u8g, rotation_chain);
x -= ((u8g_dev_arg_pixel_t *)arg)->x;
x--;
((u8g_dev_arg_pixel_t *)arg)->x = x;
((u8g_dev_arg_pixel_t *)arg)->y = y;
((u8g_dev_arg_pixel_t *)arg)->dir+=2;
((u8g_dev_arg_pixel_t *)arg)->dir &= 3;
}
u8g_call_dev_fn(u8g, rotation_chain, msg, arg);
break;
}
return 1;
}
uint8_t u8g_dev_rot270_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg)
{
u8g_dev_t *rotation_chain = (u8g_dev_t *)(dev->dev_mem);
switch(msg)
{
default:
/*
case U8G_DEV_MSG_INIT:
case U8G_DEV_MSG_STOP:
case U8G_DEV_MSG_PAGE_FIRST:
case U8G_DEV_MSG_PAGE_NEXT:
case U8G_DEV_MSG_SET_COLOR_ENTRY:
case U8G_DEV_MSG_SET_XY_CB:
*/
return u8g_call_dev_fn(u8g, rotation_chain, msg, arg);
#ifdef U8G_DEV_MSG_IS_BBX_INTERSECTION
case U8G_DEV_MSG_IS_BBX_INTERSECTION:
{
u8g_dev_arg_bbx_t *bbx = (u8g_dev_arg_bbx_t *)arg;
u8g_uint_t x, y, tmp;
/* transform the reference point */
x = bbx->y;
y = u8g->width;
/* y = u8g_GetHeightLL(u8g, rotation_chain); */
y -= bbx->x;
y--;
/* adjust point to be the uppler left corner again */
y -= bbx->w;
y++;
/* swap box dimensions */
tmp = bbx->w;
bbx->w = bbx->h;
bbx->h = tmp;
/* store x,y */
bbx->x = x;
bbx->y = y;
}
return u8g_call_dev_fn(u8g, rotation_chain, msg, arg);
#endif /* U8G_DEV_MSG_IS_BBX_INTERSECTION */
case U8G_DEV_MSG_GET_PAGE_BOX:
/* get page size from next device in the chain */
u8g_call_dev_fn(u8g, rotation_chain, msg, arg);
//printf("pre x: %3d..%3d y: %3d..%3d ", ((u8g_box_t *)arg)->x0, ((u8g_box_t *)arg)->x1, ((u8g_box_t *)arg)->y0, ((u8g_box_t *)arg)->y1);
{
u8g_box_t new_box;
new_box.x0 = u8g_GetHeightLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->y1 - 1;
new_box.x1 = u8g_GetHeightLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->y0 - 1;
new_box.y0 = u8g_GetWidthLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->x1 - 1;
new_box.y1 = u8g_GetWidthLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->x0 - 1;
*((u8g_box_t *)arg) = new_box;
//printf("post x: %3d..%3d y: %3d..%3d\n", ((u8g_box_t *)arg)->x0, ((u8g_box_t *)arg)->x1, ((u8g_box_t *)arg)->y0, ((u8g_box_t *)arg)->y1);
}
break;
case U8G_DEV_MSG_GET_WIDTH:
*((u8g_uint_t *)arg) = u8g_GetHeightLL(u8g,rotation_chain);
break;
case U8G_DEV_MSG_GET_HEIGHT:
*((u8g_uint_t *)arg) = u8g_GetWidthLL(u8g, rotation_chain);
break;
case U8G_DEV_MSG_SET_PIXEL:
case U8G_DEV_MSG_SET_TPIXEL:
{
u8g_uint_t x, y;
x = ((u8g_dev_arg_pixel_t *)arg)->y;
y = u8g_GetHeightLL(u8g, rotation_chain);
y -= ((u8g_dev_arg_pixel_t *)arg)->x;
y--;
/*
x = u8g_GetWidthLL(u8g, rotation_chain);
x -= ((u8g_dev_arg_pixel_t *)arg)->y;
x--;
*/
((u8g_dev_arg_pixel_t *)arg)->x = x;
((u8g_dev_arg_pixel_t *)arg)->y = y;
}
u8g_call_dev_fn(u8g, rotation_chain, msg, arg);
break;
case U8G_DEV_MSG_SET_8PIXEL:
case U8G_DEV_MSG_SET_4TPIXEL:
{
u8g_uint_t x, y;
x = ((u8g_dev_arg_pixel_t *)arg)->y;
y = u8g_GetHeightLL(u8g, rotation_chain);
y -= ((u8g_dev_arg_pixel_t *)arg)->x;
y--;
/*
x = u8g_GetWidthLL(u8g, rotation_chain);
x -= ((u8g_dev_arg_pixel_t *)arg)->y;
x--;
*/
((u8g_dev_arg_pixel_t *)arg)->x = x;
((u8g_dev_arg_pixel_t *)arg)->y = y;
((u8g_dev_arg_pixel_t *)arg)->dir+=3;
((u8g_dev_arg_pixel_t *)arg)->dir &= 3;
}
u8g_call_dev_fn(u8g, rotation_chain, msg, arg);
break;
}
return 1;
}
/*
u8g_scale.c
Universal 8bit Graphics Library
Copyright (c) 2012, 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.
Scale screen by some constant factors. Usefull for making bigger fonts wiht less
memory consumption
*/
#include "u8g.h"
uint8_t u8g_dev_scale_2x2_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg);
u8g_dev_t u8g_dev_scale = { u8g_dev_scale_2x2_fn, NULL, NULL };
void u8g_UndoScale(u8g_t *u8g)
{
if ( u8g->dev != &u8g_dev_scale )
return;
u8g->dev = u8g_dev_scale.dev_mem;
u8g_UpdateDimension(u8g);
}
void u8g_SetScale2x2(u8g_t *u8g)
{
if ( u8g->dev != &u8g_dev_scale )
{
u8g_dev_scale.dev_mem = u8g->dev;
u8g->dev = &u8g_dev_scale;
}
u8g_dev_scale.dev_fn = u8g_dev_scale_2x2_fn;
u8g_UpdateDimension(u8g);
}
uint8_t u8g_dev_scale_2x2_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg)
{
u8g_dev_t *chain = (u8g_dev_t *)(dev->dev_mem);
uint8_t pixel;
uint16_t scaled_pixel;
uint8_t i;
uint8_t dir;
u8g_uint_t x, y, xx,yy;
switch(msg)
{
default:
return u8g_call_dev_fn(u8g, chain, msg, arg);
case U8G_DEV_MSG_GET_WIDTH:
*((u8g_uint_t *)arg) = u8g_GetWidthLL(u8g, chain) / 2;
break;
case U8G_DEV_MSG_GET_HEIGHT:
*((u8g_uint_t *)arg) = u8g_GetHeightLL(u8g, chain) / 2;
break;
case U8G_DEV_MSG_GET_PAGE_BOX:
/* get page size from next device in the chain */
u8g_call_dev_fn(u8g, chain, msg, arg);
((u8g_box_t *)arg)->x0 /= 2;
((u8g_box_t *)arg)->x1 /= 2;
((u8g_box_t *)arg)->y0 /= 2;
((u8g_box_t *)arg)->y1 /= 2;
return 1;
case U8G_DEV_MSG_SET_PIXEL:
x = ((u8g_dev_arg_pixel_t *)arg)->x;
x *= 2;
y = ((u8g_dev_arg_pixel_t *)arg)->y;
y *= 2;
((u8g_dev_arg_pixel_t *)arg)->x = x;
((u8g_dev_arg_pixel_t *)arg)->y = y;
u8g_call_dev_fn(u8g, chain, msg, arg);
x++;
((u8g_dev_arg_pixel_t *)arg)->x = x;
((u8g_dev_arg_pixel_t *)arg)->y = y;
u8g_call_dev_fn(u8g, chain, msg, arg);
y++;
((u8g_dev_arg_pixel_t *)arg)->x = x;
((u8g_dev_arg_pixel_t *)arg)->y = y;
u8g_call_dev_fn(u8g, chain, msg, arg);
x--;
((u8g_dev_arg_pixel_t *)arg)->x = x;
((u8g_dev_arg_pixel_t *)arg)->y = y;
u8g_call_dev_fn(u8g, chain, msg, arg);
break;
case U8G_DEV_MSG_SET_8PIXEL:
pixel = ((u8g_dev_arg_pixel_t *)arg)->pixel;
dir = ((u8g_dev_arg_pixel_t *)arg)->dir;
scaled_pixel = 0;
for( i = 0; i < 8; i++ )
{
scaled_pixel<<=2;
if ( pixel & 128 )
{
scaled_pixel |= 3;
}
pixel<<=1;
}
x = ((u8g_dev_arg_pixel_t *)arg)->x;
x *= 2;
xx = x;
y = ((u8g_dev_arg_pixel_t *)arg)->y;
y *= 2;
yy = y;
if ( ((u8g_dev_arg_pixel_t *)arg)->dir & 1 )
{
xx++;
}
else
{
yy++;
}
((u8g_dev_arg_pixel_t *)arg)->pixel = scaled_pixel>>8;
((u8g_dev_arg_pixel_t *)arg)->x = x;
((u8g_dev_arg_pixel_t *)arg)->y = y;
((u8g_dev_arg_pixel_t *)arg)->dir = dir;
u8g_call_dev_fn(u8g, chain, msg, arg);
((u8g_dev_arg_pixel_t *)arg)->x = xx;
((u8g_dev_arg_pixel_t *)arg)->y = yy;
((u8g_dev_arg_pixel_t *)arg)->dir = dir;
u8g_call_dev_fn(u8g, chain, msg, arg);
((u8g_dev_arg_pixel_t *)arg)->pixel = scaled_pixel&255;
//((u8g_dev_arg_pixel_t *)arg)->pixel = 0x00;
switch(dir)
{
case 0:
x+=8;
xx+=8;
break;
case 1:
y+=8;
yy+=8;
break;
case 2:
x-=8;
xx-=8;
break;
case 3:
y-=8;
yy-=8;
break;
}
((u8g_dev_arg_pixel_t *)arg)->x = x;
((u8g_dev_arg_pixel_t *)arg)->y = y;
((u8g_dev_arg_pixel_t *)arg)->dir = dir;
u8g_call_dev_fn(u8g, chain, msg, arg);
((u8g_dev_arg_pixel_t *)arg)->x = xx;
((u8g_dev_arg_pixel_t *)arg)->y = yy;
((u8g_dev_arg_pixel_t *)arg)->dir = dir;
u8g_call_dev_fn(u8g, chain, msg, arg);
break;
}
return 1;
}
/*
u8g_state.c
backup and restore hardware state
Universal 8bit Graphics Library
Copyright (c) 2011, 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.
state callback: backup env U8G_STATE_MSG_BACKUP_ENV
device callback: DEV_MSG_INIT
state callback: backup u8g U8G_STATE_MSG_BACKUP_U8G
state callback: restore env U8G_STATE_MSG_RESTORE_ENV
state callback: backup env U8G_STATE_MSG_BACKUP_ENV
state callback: retore u8g U8G_STATE_MSG_RESTORE_U8G
DEV_MSG_PAGE_FIRST or DEV_MSG_PAGE_NEXT
state callback: restore env U8G_STATE_MSG_RESTORE_ENV
*/
#include <stddef.h>
#include "u8g.h"
void u8g_state_dummy_cb(uint8_t msg)
{
/* the dummy procedure does nothing */
}
void u8g_SetHardwareBackup(u8g_t *u8g, u8g_state_cb backup_cb)
{
u8g->state_cb = backup_cb;
/* in most cases the init message was already sent, so this will backup the */
/* current u8g state */
backup_cb(U8G_STATE_MSG_BACKUP_U8G);
}
/*===============================================================*/
/* register variable for restoring interrupt state */
#if defined(__AVR__)
uint8_t global_SREG_backup;
#endif
/*===============================================================*/
/* AVR */
#if defined(__AVR_XMEGA__)
#elif defined(__AVR__)
#define U8G_ATMEGA_HW_SPI
/* remove the definition for attiny */
#if __AVR_ARCH__ == 2
#undef U8G_ATMEGA_HW_SPI
#endif
#if __AVR_ARCH__ == 25
#undef U8G_ATMEGA_HW_SPI
#endif
#endif
#if defined(U8G_ATMEGA_HW_SPI)
#include <avr/interrupt.h>
static uint8_t u8g_state_avr_spi_memory[2];
void u8g_backup_spi(uint8_t msg)
{
if ( U8G_STATE_MSG_IS_BACKUP(msg) )
{
u8g_state_avr_spi_memory[U8G_STATE_MSG_GET_IDX(msg)] = SPCR;
}
else
{
uint8_t tmp = SREG;
cli();
SPCR = 0;
SPCR = u8g_state_avr_spi_memory[U8G_STATE_MSG_GET_IDX(msg)];
SREG = tmp;
}
}
#elif defined (U8G_RASPBERRY_PI)
#include <stdio.h>
void u8g_backup_spi(uint8_t msg) {
printf("u8g_backup_spi %d\r\n",msg);
}
#elif defined(ARDUINO) && defined(__SAM3X8E__) // Arduino Due, maybe we should better check for __SAM3X8E__
#include "sam.h"
struct sam_backup_struct
{
uint32_t mr;
uint32_t sr;
uint32_t csr[4];
} sam_backup[2];
void u8g_backup_spi(uint8_t msg)
{
uint8_t idx = U8G_STATE_MSG_GET_IDX(msg);
if ( U8G_STATE_MSG_IS_BACKUP(msg) )
{
sam_backup[idx].mr = SPI0->SPI_MR;
sam_backup[idx].sr = SPI0->SPI_SR;
sam_backup[idx].csr[0] = SPI0->SPI_CSR[0];
sam_backup[idx].csr[1] = SPI0->SPI_CSR[1];
sam_backup[idx].csr[2] = SPI0->SPI_CSR[2];
sam_backup[idx].csr[3] = SPI0->SPI_CSR[3];
}
else
{
SPI0->SPI_MR = sam_backup[idx].mr;
SPI0->SPI_CSR[0] = sam_backup[idx].csr[0];
SPI0->SPI_CSR[1] = sam_backup[idx].csr[1];
SPI0->SPI_CSR[2] = sam_backup[idx].csr[2];
SPI0->SPI_CSR[3] = sam_backup[idx].csr[3];
}
}
#else
void u8g_backup_spi(uint8_t msg)
{
}
#endif
/*
u8g_u16toa.c
Universal 8bit Graphics Library
Copyright (c) 2012, 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 "u8g.h"
const char *u8g_u16toap(char * dest, uint16_t v)
{
uint8_t pos;
uint8_t d;
uint16_t c;
c = 10000;
for( pos = 0; pos < 5; pos++ )
{
d = '0';
while( v >= c )
{
v -= c;
d++;
}
dest[pos] = d;
c /= 10;
}
dest[5] = '\0';
return dest;
}
/* v = value, d = number of digits */
const char *u8g_u16toa(uint16_t v, uint8_t d)
{
static char buf[6];
d = 5-d;
return u8g_u16toap(buf, v) + d;
}
/*
u8g_u8toa.c
Universal 8bit Graphics Library
Copyright (c) 2011, 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 "u8g.h"
static const unsigned char u8g_u8toa_tab[3] = { 100, 10, 1 } ;
const char *u8g_u8toap(char * dest, uint8_t v)
{
uint8_t pos;
uint8_t d;
uint8_t c;
for( pos = 0; pos < 3; pos++ )
{
d = '0';
c = *(u8g_u8toa_tab+pos);
while( v >= c )
{
v -= c;
d++;
}
dest[pos] = d;
}
dest[3] = '\0';
return dest;
}
/* v = value, d = number of digits */
const char *u8g_u8toa(uint8_t v, uint8_t d)
{
static char buf[4];
d = 3-d;
return u8g_u8toap(buf, v) + d;
}
/*
u8g_virtual_screen.c
Universal 8bit Graphics Library
Copyright (c) 2012, 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 "u8g.h"
struct _u8g_vs_t
{
u8g_uint_t x;
u8g_uint_t y;
u8g_t *u8g;
};
typedef struct _u8g_vs_t u8g_vs_t;
#define U8g_VS_MAX 4
uint8_t u8g_vs_cnt = 0;
u8g_vs_t u8g_vs_list[U8g_VS_MAX];
uint8_t u8g_vs_current;
u8g_uint_t u8g_vs_width;
u8g_uint_t u8g_vs_height;
uint8_t u8g_dev_vs_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg)
{
switch(msg)
{
default:
{
uint8_t i;
for( i = 0; i < u8g_vs_cnt; i++ )
{
u8g_call_dev_fn(u8g_vs_list[i].u8g, u8g_vs_list[i].u8g->dev, msg, arg);
}
}
return 1;
case U8G_DEV_MSG_PAGE_FIRST:
u8g_vs_current = 0;
if ( u8g_vs_cnt != 0 )
return u8g_call_dev_fn(u8g_vs_list[u8g_vs_current].u8g, u8g_vs_list[u8g_vs_current].u8g->dev, msg, arg);
return 0;
case U8G_DEV_MSG_PAGE_NEXT:
{
uint8_t ret = 0;
if ( u8g_vs_cnt != 0 )
ret = u8g_call_dev_fn(u8g_vs_list[u8g_vs_current].u8g, u8g_vs_list[u8g_vs_current].u8g->dev, msg, arg);
if ( ret != 0 )
return ret;
u8g_vs_current++; /* next device */
if ( u8g_vs_current >= u8g_vs_cnt ) /* reached end? */
return 0;
return u8g_call_dev_fn(u8g_vs_list[u8g_vs_current].u8g, u8g_vs_list[u8g_vs_current].u8g->dev, U8G_DEV_MSG_PAGE_FIRST, arg);
}
case U8G_DEV_MSG_GET_WIDTH:
*((u8g_uint_t *)arg) = u8g_vs_width;
break;
case U8G_DEV_MSG_GET_HEIGHT:
*((u8g_uint_t *)arg) = u8g_vs_height;
break;
case U8G_DEV_MSG_GET_PAGE_BOX:
if ( u8g_vs_current < u8g_vs_cnt )
{
u8g_call_dev_fn(u8g_vs_list[u8g_vs_current].u8g, u8g_vs_list[u8g_vs_current].u8g->dev, msg, arg);
((u8g_box_t *)arg)->x0 += u8g_vs_list[u8g_vs_current].x;
((u8g_box_t *)arg)->x1 += u8g_vs_list[u8g_vs_current].x;
((u8g_box_t *)arg)->y0 += u8g_vs_list[u8g_vs_current].y;
((u8g_box_t *)arg)->y1 += u8g_vs_list[u8g_vs_current].y;
}
else
{
((u8g_box_t *)arg)->x0 = 0;
((u8g_box_t *)arg)->x1 = 0;
((u8g_box_t *)arg)->y0 = 0;
((u8g_box_t *)arg)->y1 = 0;
}
return 1;
case U8G_DEV_MSG_SET_PIXEL:
case U8G_DEV_MSG_SET_8PIXEL:
if ( u8g_vs_current < u8g_vs_cnt )
{
((u8g_dev_arg_pixel_t *)arg)->x -= u8g_vs_list[u8g_vs_current].x;
((u8g_dev_arg_pixel_t *)arg)->y -= u8g_vs_list[u8g_vs_current].y;
return u8g_call_dev_fn(u8g_vs_list[u8g_vs_current].u8g, u8g_vs_list[u8g_vs_current].u8g->dev, msg, arg);
}
break;
}
return 1;
}
u8g_dev_t u8g_dev_vs = { u8g_dev_vs_fn, NULL, NULL };
void u8g_SetVirtualScreenDimension(u8g_t *vs_u8g, u8g_uint_t width, u8g_uint_t height)
{
if ( vs_u8g->dev != &u8g_dev_vs )
return; /* abort if there is no a virtual screen device */
u8g_vs_width = width;
u8g_vs_height = height;
}
uint8_t u8g_AddToVirtualScreen(u8g_t *vs_u8g, u8g_uint_t x, u8g_uint_t y, u8g_t *child_u8g)
{
if ( vs_u8g->dev != &u8g_dev_vs )
return 0; /* abort if there is no a virtual screen device */
if ( u8g_vs_cnt >= U8g_VS_MAX )
return 0; /* maximum number of child u8g's reached */
u8g_vs_list[u8g_vs_cnt].u8g = child_u8g;
u8g_vs_list[u8g_vs_cnt].x = x;
u8g_vs_list[u8g_vs_cnt].y = y;
u8g_vs_cnt++;
return 1;
}
......@@ -11,6 +11,13 @@ Occasional NodeMCU firmware hackers don't need full control over the complete to
### Linux Build Environment
NodeMCU firmware developers commit or contribute to the project on GitHub and might want to build their own full fledged build environment with the complete tool chain. There is a [post in the esp8266.com Wiki](http://www.esp8266.com/wiki/doku.php?id=toolchain#how_to_setup_a_vm_to_host_your_toolchain) that describes this.
### git
If you decide to build with either the Docker image or the native environment then use git to clone the firmware sources instead of downloading the zip file from GitHub. Only cloning with git will retrieve the referenced submodules:
```
git clone --recurse-submodules -b <branch> https://github.com/nodemcu/nodemcu-firmware.git
```
Omitting the optional `-b <branch>` will clone master.
## Build Options
The following sections explain some of the options you have if you want to build your own NodeMCU firmware.
......@@ -24,7 +31,6 @@ Edit `app/include/user_modules.h` and comment-out the `#define` statement for mo
...
#define LUA_USE_MODULES_MQTT
// #define LUA_USE_MODULES_COAP
// #define LUA_USE_MODULES_U8G
...
```
......@@ -81,8 +87,8 @@ Identify your firmware builds by editing `app/include/user_version.h`
#endif
```
### u8g Module Configuration
Display drivers and embedded fonts are compiled into the firmware image based on the settings in `app/include/u8g_config.h`. See the [`u8g` documentation](modules/u8g.md#displays) for details.
### u8g2 Module Configuration
Display drivers and embedded fonts are compiled into the firmware image based on the settings in `app/include/u8g2_displays.h` and `app/include/u8g2_fonts.h`. See the [`u8g2` documentation](modules/u8g2.md#displays) for details.
### ucg Module Configuration
Display drivers and embedded fonts are compiled into the firmware image based on the settings in `app/include/ucg_config.h`. See the [`ucg` documentation](modules/ucg.md#displays) for details.
# u8g Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2015-01-30 | [Oli Kraus](https://github.com/olikraus/u8glib), [Arnim Läuger](https://github.com/devsaurus) | [Arnim Läuger](https://github.com/devsaurus) | [u8glib](../../../app/u8glib/)|
U8glib is a graphics library developed at [olikraus/u8glib](https://github.com/olikraus/u8glib) with support for many different displays. The NodeMCU firmware supports a subset of these.
I²C and SPI mode:
- sh1106_128x64
- ssd1306 - 128x32, 128x64, and 64x48 variants
- ssd1309_128x64
- ssd1327_96x96_gr
- uc1611 - dogm240 and dogxl240 variants
SPI only:
- ld7032_60x32
- pcd8544_84x48
- pcf8812_96x65
- ssd1322_nhd31oled - bw and gr variants
- ssd1325_nhd27oled - bw and gr variants
- ssd1351_128x128 - gh and hicolor variants
- st7565_64128n - variants 64128n, dogm128/132, lm6059/lm6063, c12832/c12864
- uc1601_c128032
- uc1608 - 240x128 and 240x64 variants
- uc1610_dogxl160 - bw and gr variants
- uc1611 - dogm240 and dogxl240 variants
- uc1701 - dogs102 and mini12864 variants
This integration is based on [v1.19.1](https://github.com/olikraus/U8glib_Arduino/releases/tag/1.19.1).
## Overview
### I²C Connection
Hook up SDA and SCL to any free GPIOs. Eg. [u8g_graphics_test.lua](https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_examples/u8glib/u8g_graphics_test.lua) expects SDA=5 (GPIO14) and SCL=6 (GPIO12). They are used to set up nodemcu's I²C driver before accessing the display:
```lua
sda = 5
scl = 6
i2c.setup(0, sda, scl, i2c.SLOW)
```
### SPI connection
The HSPI module is used ([more information](http://d.av.id.au/blog/esp8266-hardware-spi-hspi-general-info-and-pinout/)), so certain pins are fixed:
- HSPI CLK = GPIO14
- HSPI MOSI = GPIO13
- HSPI MISO = GPIO12 (not used)
All other pins can be assigned to any available GPIO:
- CS
- D/C
- RES (optional for some displays)
Also refer to the initialization sequence eg in [u8g_graphics_test.lua](https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_examples/u8glib/u8g_graphics_test.lua):
```lua
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
```
### Library Usage
The Lua bindings for this library closely follow u8glib's object oriented C++ API. Based on the u8g class, you create an object for your display type.
SSD1306 via I²C:
```lua
sla = 0x3c
disp = u8g.ssd1306_128x64_i2c(sla)
```
SSD1306 via SPI:
```lua
cs = 8 -- GPIO15, pull-down 10k to GND
dc = 4 -- GPIO2
res = 0 -- GPIO16, RES is optional YMMV
disp = u8g.ssd1306_128x64_hw_spi(cs, dc, res)
```
This object provides all of u8glib's methods to control the display. Again, refer to [u8g_graphics_test.lua](https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_examples/u8glib/u8g_graphics_test.lua) to get an impression how this is achieved with Lua code. Visit the [u8glib homepage](https://github.com/olikraus/u8glib) for technical details.
### Displays
I²C and HW SPI based displays with support in u8glib can be enabled. To get access to the respective constructors, add the desired entries to the I²C or SPI display tables in [app/include/u8g_config.h](https://github.com/nodemcu/nodemcu-firmware/blob/master/app/include/u8g_config.h):
```c
#define U8G_DISPLAY_TABLE_I2C \
U8G_DISPLAY_TABLE_ENTRY(ssd1306_128x64_i2c) \
#define U8G_DISPLAY_TABLE_SPI \
U8G_DISPLAY_TABLE_ENTRY(ssd1306_128x64_hw_spi) \
U8G_DISPLAY_TABLE_ENTRY(pcd8544_84x48_hw_spi) \
U8G_DISPLAY_TABLE_ENTRY(pcf8812_96x65_hw_spi) \
```
### Fonts
u8glib comes with a wide range of fonts for small displays. Since they need to be compiled into the firmware image, you'd need to include them in [app/include/u8g_config.h](https://github.com/nodemcu/nodemcu-firmware/blob/master/app/include/u8g_config.h) and recompile. Simply add the desired fonts to the font table:
```c
#define U8G_FONT_TABLE \
U8G_FONT_TABLE_ENTRY(font_6x10) \
U8G_FONT_TABLE_ENTRY(font_chikita)
```
They'll become available as `u8g.<font_name>` in Lua.
### Bitmaps
Bitmaps and XBMs are supplied as strings to `drawBitmap()` and `drawXBM()`. This off-loads all data handling from the u8g module to generic methods for binary files. See [u8g_bitmaps.lua](https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_examples/u8glib/u8g_bitmaps.lua).
In contrast to the source code based inclusion of XBMs into u8glib, it's required to provide precompiled binary files. This can be performed online with [Online-Utility's Image Converter](http://www.online-utility.org/image_converter.jsp): Convert from XBM to MONO format and upload the binary result with [nodemcu-uploader.py](https://github.com/kmpm/nodemcu-uploader).
## I²C Display Drivers
Initialize a display via I²C.
The init sequence would insert delays to match the display specs. These can destabilize the overall system if wifi service is blocked for too long. It is therefore advisable to disable such delays unless the specific use case can exclude wifi traffic while initializing the display driver.
- `u8g.sh1106_128x64_i2c()`
- `u8g.ssd1306_128x32_i2c()`
- `u8g.ssd1306_128x64_i2c()`
- `u8g.ssd1306_64x48_i2c()`
- `u8g.ssd1309_128x64_i2c()`
- `u8g.ssd1327_96x96_gr_i2c()`
- `u8g.uc1611_dogm240_i2c()`
- `u8g.uc1611_dogxl240_i2c()`
####Syntax
`u8g.ssd1306_128x64_i2c(address[, use_delay])`
####Parameters
- `address` I²C slave address of display
- `use_delay` '1': use delays in init sequence, '0' if omitted
####Returns
u8g display object
####Example
```lua
sda = 5
scl = 6
i2c.setup(0, sda, scl, i2c.SLOW)
sla = 0x3c
disp = u8g.ssd1306_128x64_i2c(sla)
```
####See also
[SPI Display Drivers](#spi-display-drivers)
## SPI Display Drivers
Initialize a display via Hardware SPI.
The init sequence would insert delays to match the display specs. These can destabilize the overall system if wifi service is blocked for too long. It is therefore advisable to disable such delays unless the specific use case can exclude wifi traffic while initializing the display driver.
- `u8g.ld7032_60x32_hw_spi()`
- `u8g.pcd8544_84x48_hw_spi()`
- `u8g.pcf8812_96x65_hw_spi()`
- `u8g.sh1106_128x64_hw_spi()`
- `u8g.ssd1306_128x32_hw_spi()`
- `u8g.ssd1306_128x64_hw_spi()`
- `u8g.ssd1306_64x48_hw_spi()`
- `u8g.ssd1309_128x64_hw_spi()`
- `u8g.ssd1322_nhd31oled_bw_hw_spi()`
- `u8g.ssd1322_nhd31oled_gr_hw_spi()`
- `u8g.ssd1325_nhd27oled_bw_hw_spi()`
- `u8g.ssd1325_nhd27oled_gr_hw_spi()`
- `u8g.ssd1327_96x96_gr_hw_spi()`
- `u8g.ssd1351_128x128_332_hw_spi()`
- `u8g.ssd1351_128x128gh_332_hw_spi()`
- `u8g.ssd1351_128x128_hicolor_hw_spi()`
- `u8g.ssd1351_128x128gh_hicolor_hw_spi()`
- `u8g.ssd1353_160x128_332_hw_spi()`
- `u8g.ssd1353_160x128_hicolor_hw_spi()`
- `u8g.st7565_64128n_hw_spi()`
- `u8g.st7565_dogm128_hw_spi()`
- `u8g.st7565_dogm132_hw_spi()`
- `u8g.st7565_lm6059_hw_spi()`
- `u8g.st7565_lm6063_hw_spi()`
- `u8g.st7565_nhd_c12832_hw_spi()`
- `u8g.st7565_nhd_c12864_hw_spi()`
- `u8g.uc1601_c128032_hw_spi()`
- `u8g.uc1608_240x128_hw_spi()`
- `u8g.uc1608_240x64_hw_spi()`
- `u8g.uc1610_dogxl160_bw_hw_spi()`
- `u8g.uc1610_dogxl160_gr_hw_spi()`
- `u8g.uc1611_dogm240_hw_spi()`
- `u8g.uc1611_dogxl240_hw_spi()`
- `u8g.uc1701_dogs102_hw_spi()`
- `u8g.uc1701_mini12864_hw_spi()`
#### Syntax
`u8g.ssd1306_128x64_spi(cs, dc[, res[, use_delay]])`
#### Parameters
- `cs` GPIO pin for /CS
- `dc` GPIO pin for DC
- `res` GPIO pin for /RES, none if omitted
- `use_delay` '1': use delays in init sequence, '0' if omitted
#### Returns
u8g display object
#### Example
```lua
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
cs = 8 -- GPIO15, pull-down 10k to GND
dc = 4 -- GPIO2
res = 0 -- GPIO16, RES is optional YMMV
disp = u8g.ssd1306_128x64_hw_spi(cs, dc, res)
```
#### See also
[I²C Display Drivers](#i2c-display-drivers)
## u8g.fb_rle
Initialize a virtual display that provides run-length encoded framebuffer contents to a Lua callback.
The callback function can be used to process the framebuffer line by line. It's called with either `nil` as parameter to indicate the start of a new frame or with a string containing a line of the framebuffer with run-length encoding. First byte in the string specifies how many pairs of (x, len) follow, while each pair defines the start (leftmost x-coordinate) and length of a sequence of lit pixels. All other pixels in the line are dark.
```lua
n = struct.unpack("B", rle_line)
print(n.." pairs")
for i = 0,n-1 do
print(string.format(" x: %d len: %d", struct.unpack("BB", rle_line, 1+1 + i*2)))
end
```
#### Syntax
`u8g.fb_rle(cb_fn, width, height)`
#### Parameters
- `cb_fn([rle_line])` callback function. `rle_line` is a string containing a run-length encoded framebuffer line, or `nil` to indicate start of frame.
- `width` of display. Must be a multiple of 8, less than or equal to 248.
- `height` of display. Must be a multiple of 8, less than or equal to 248.
#### Returns
u8g display object
___
## Constants
Constants for various functions.
`u8g.DRAW_UPPER_RIGHT`, `u8g.DRAW_UPPER_LEFT`, `u8g.DRAW_LOWER_RIGHT`, `u8g.DRAW_LOWER_LEFT`, `u8g.DRAW_ALL`,
`u8g.MODE_BW`, `u8g.MODE_GRAY2BIT`
`u8g.font_6x10`, ...
# u8g.disp Sub-Module
## u8g.disp:begin()
See [u8glib begin()](https://github.com/olikraus/u8glib/wiki/userreference#begin).
## u8g.disp:drawBitmap()
Draw a bitmap at the specified x/y position (upper left corner of the bitmap).
Parts of the bitmap may be outside the display boundaries. The bitmap is specified by the array bitmap. A cleared bit means: Do not draw a pixel. A set bit inside the array means: Write pixel with the current color index. For a monochrome display, the color index 0 will usually clear a pixel and the color index 1 will set a pixel.
#### Syntax
`disp:drawBitmap(x, y, cnt, h, bitmap)`
#### Parameters
- `x` X-position (left position of the bitmap)
- `y` Y-position (upper position of the bitmap)
- `cnt` number of bytes of the bitmap in horizontal direction. The width of the bitmap is cnt*8.
- `h` height of the bitmap
- `bitmap` bitmap data supplied as string
#### Returns
`nil`
#### See also
- [u8glib drawBitmap()](https://github.com/olikraus/u8glib/wiki/userreference#drawbitmap)
- [lua_examples/u8glib/u8g_bitmaps.lua](https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_examples/u8glib/u8g_bitmaps.lua)
- [u8g.disp:drawXBM()](#u8gdispdrawxbm)
## u8g.disp:drawBox()
See [u8glib drawBox()](https://github.com/olikraus/u8glib/wiki/userreference#drawbox).
## u8g.disp:drawCircle()
See [u8glib drawCircle()](https://github.com/olikraus/u8glib/wiki/userreference#drawcircle).
## u8g.disp:drawDisc()
See [u8glib drawDisc()](https://github.com/olikraus/u8glib/wiki/userreference#drawdisc).
## u8g.disp:drawEllipse()
See [u8glib drawEllipse()](https://github.com/olikraus/u8glib/wiki/userreference#drawellipse).
## u8g.disp:drawFilledEllipse()
See [u8glib drawFilledEllipse](https://github.com/olikraus/u8glib/wiki/userreference#drawfilledellipse).
## u8g.disp:drawFrame()
See [u8glib drawFrame()](https://github.com/olikraus/u8glib/wiki/userreference#drawframe).
## u8g.disp:drawHLine()
See [u8glib drawHLine()](https://github.com/olikraus/u8glib/wiki/userreference#drawhline).
## u8g.disp:drawLine()
See [u8glib drawLine()](https://github.com/olikraus/u8glib/wiki/userreference#drawline).
## u8g.disp:drawPixel()
See [u8glib drawPixel()](https://github.com/olikraus/u8glib/wiki/userreference#drawpixel).
## u8g.disp:drawRBox()
See [u8glib drawRBox()](https://github.com/olikraus/u8glib/wiki/userreference#drawrbox).
## u8g.disp:drawRFrame()
See [u8glib drawRFrame()](https://github.com/olikraus/u8glib/wiki/userreference#drawrframe).
## u8g.disp:drawStr()
See [u8glib drawStr()](https://github.com/olikraus/u8glib/wiki/userreference#drawstr).
## u8g.disp:drawStr90()
See [u8glib drawStr90](https://github.com/olikraus/u8glib/wiki/userreference#drawstr90).
## u8g.disp:drawStr180()
See [u8glib drawStr180()](https://github.com/olikraus/u8glib/wiki/userreference#drawstr180).
## u8g.disp:drawStr270()
See [u8glib drawStr270()](https://github.com/olikraus/u8glib/wiki/userreference#drawstr270).
## u8g.disp:drawTriangle()
See [u8glib drawTriangle()](https://github.com/olikraus/u8glib/wiki/userreference#drawtriangle).
## u8g.disp:drawVLine()
See [u8glib drawVLine()](https://github.com/olikraus/u8glib/wiki/userreference#drawvline).
## u8g.disp:drawXBM()
Draw a XBM Bitmap. Position (x,y) is the upper left corner of the bitmap.
XBM contains monochrome, 1-bit bitmaps. This procedure only draws pixel values 1. The current color index is used for drawing (see setColorIndex). Pixel with value 0 are not drawn (transparent).
Bitmaps and XBMs are supplied as strings to `drawBitmap()` and `drawXBM()`. This off-loads all data handling from the u8g module to generic methods for binary files. In contrast to the source code based inclusion of XBMs into u8glib, it's required to provide precompiled binary files. This can be performed online with [Online-Utility's Image Converter](http://www.online-utility.org/image_converter.jsp): Convert from XBM to MONO format and upload the binary result with [nodemcu-uploader.py](https://github.com/kmpm/nodemcu-uploader) or [ESPlorer](http://esp8266.ru/esplorer/).
#### Syntax
`disp:drawXBM(x, y, w, h, bitmap)`
#### Parameters
- `x` X-position (left position of the bitmap)
- `y` Y-position (upper position of the bitmap)
- `w` width of the bitmap
- `h` height of the bitmap
- `bitmap` XBM data supplied as string
#### Returns
`nil`
#### See also
- [u8glib drawXBM()](https://github.com/olikraus/u8glib/wiki/userreference#drawxbm)
- [lua_examples/u8glib/u8g_bitmaps.lua](https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_examples/u8glib/u8g_bitmaps.lua)
- [u8g.disp:drawBitmap()](#u8gdispdrawbitmap)
## u8g.disp:firstPage()
See [u8glib firstPage()](https://github.com/olikraus/u8glib/wiki/userreference#firstpage).
## u8g.disp:getColorIndex()
See [u8glib getColorIndex()](https://github.com/olikraus/u8glib/wiki/userreference#getcolorindex).
## u8g.disp:getFontAscent()
See [u8glib getFontAscent()](https://github.com/olikraus/u8glib/wiki/userreference#getfontascent).
## u8g.disp:getFontDescent()
See [u8glib getFontDescent()](https://github.com/olikraus/u8glib/wiki/userreference#getfontdescent).
## u8g.disp:getFontLineSpacing()
See [u8glib getFontLineSpacing()](https://github.com/olikraus/u8glib/wiki/userreference#getfontlinespacing).
## u8g.disp:getHeight()
See [u8glib getHeight()](https://github.com/olikraus/u8glib/wiki/userreference#getheight).
## u8g.disp:getMode()
See [u8glib getMode()](https://github.com/olikraus/u8glib/wiki/userreference#getmode).
## u8g.disp:getWidth()
See [u8glib getWidth()](https://github.com/olikraus/u8glib/wiki/userreference#getwidth).
## u8g.disp:getStrWidth()
See [u8glib getStrWidth](https://github.com/olikraus/u8glib/wiki/userreference#getstrwidth).
## u8g.disp:nextPage()
See [u8glib nextPage()](https://github.com/olikraus/u8glib/wiki/userreference#nextpage).
## u8g.disp:setColorIndex()
See [u8glib setColorIndex()](https://github.com/olikraus/u8glib/wiki/userreference#setcolortndex).
## u8g.disp:setContrast()
See [u8glib setContrast()](https://github.com/olikraus/u8glib/wiki/userreference#setcontrast).
## u8g.disp:setDefaultBackgroundColor()
See [u8glib setDefaultBackgroundColor()](https://github.com/olikraus/u8glib/wiki/userreference#setdefaultbackgroundcolor).
## u8g.disp:setDefaultForegroundColor()
See [u8glib setDefaultForegroundColor()](https://github.com/olikraus/u8glib/wiki/userreference#setdefaultforegroundcolor).
## u8g.disp:setFont()
u8glib comes with a wide range of fonts for small displays.
Since they need to be compiled into the firmware image, you'd need to include them in `app/include/u8g_config.h` and recompile. Simply add the desired fonts to the font table:
```c
#define U8G_FONT_TABLE \
U8G_FONT_TABLE_ENTRY(font_6x10) \
U8G_FONT_TABLE_ENTRY(font_chikita)
```
They'll be available as `u8g.<font_name>` in Lua.
#### Syntax
`disp:setFont(font)`
#### Parameters
`font` Constant to indentify pre-compiled font
#### Returns
`nil`
#### Example
```lua
disp:setFont(u8g.font_6x10)
```
#### See also
- [u8glib setFont()](https://github.com/olikraus/u8glib/wiki/userreference#setfont)
## u8g.disp:setFontLineSpacingFactor()
See [u8glib setFontLineSpacingFactor()](https://github.com/olikraus/u8glib/wiki/userreference#setfontlinespacingfactor).
## u8g.disp:setFontPosBaseline()
See [u8glib setFontPosBaseline()](https://github.com/olikraus/u8glib/wiki/userreference#setfontposbaseline).
## u8g.disp:setFontPosBottom()
See [u8glib setFontPosBottom()](https://github.com/olikraus/u8glib/wiki/userreference#setfontposbottom).
## u8g.disp:setFontPosCenter()
See [u8glib setFontPosCenter()](https://github.com/olikraus/u8glib/wiki/userreference#setfontposcenter).
## u8g.disp:setFontPosTop()
See [u8glib setFontPosTop()](https://github.com/olikraus/u8glib/wiki/userreference#setfontpostop).
## u8g.disp:setFontRefHeightAll()
See [u8glib setFontRefHeightAll()](https://github.com/olikraus/u8glib/wiki/userreference#setfontrefheightall).
## u8g.disp:setFontRefHeightExtendedText()
See [u8glib setFontRefHeightExtendedText()](https://github.com/olikraus/u8glib/wiki/userreference#setfontrefheightextendedtext).
## u8g.disp:setFontRefHeightText()
See [u8glib setFontRefHeightText()](https://github.com/olikraus/u8glib/wiki/userreference#setfontrefheighttext).
## u8g.disp:setRot90()
See [u8glib setRot90()](https://github.com/olikraus/u8glib/wiki/userreference#setrot90).
## u8g.disp:setRot180()
See [u8glib setRot180()](https://github.com/olikraus/u8glib/wiki/userreference#setrot180).
## u8g.disp:setRot270()
See [u8glib setRot270()](https://github.com/olikraus/u8glib/wiki/userreference#setrot270).
## u8g.disp:setScale2x2()
See [u8glib setScale2x2()](https://github.com/olikraus/u8glib/wiki/userreference#setscale2x2).
## u8g.disp:sleepOn()
See [u8glib sleepOn()](https://github.com/olikraus/u8glib/wiki/userreference#sleepon).
## u8g.disp:sleepOff()
See [u8glib sleepOff()](https://github.com/olikraus/u8glib/wiki/userreference#sleepoff).
## u8g.disp:undoRotation()
See [u8glib undoRotation()](https://github.com/olikraus/u8glib/wiki/userreference#undorotation).
## u8g.disp:undoScale()
See [u8glib undoScale()](https://github.com/olikraus/u8glib/wiki/userreference#undoscale).
## Unimplemented Functions
- Cursor handling
- disableCursor()
- enableCursor()
- setCursorColor()
- setCursorFont()
- setCursorPos()
- setCursorStyle()
- General functions
- setPrintPos()
- setHardwareBackup()
- setRGB()
- setDefaultMidColor()
# u8g2 Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2017-06-02 | [Oli Kraus](https://github.com/olikraus/u8glib), [Arnim Läuger](https://github.com/devsaurus) | [Arnim Läuger](https://github.com/devsaurus) | [u8g2.c](../../../apps/modules/u8g2.c)|
U8g2 is a graphics library developed at [olikraus/u8g2](https://github.com/olikraus/u8g2) with support for many different displays. It is the successor of [U8glib](https://github.com/olikraus/u8glib) which is not developed any further. Please see [How to port U8g code](https://github.com/olikraus/u8g2/wiki/u8gvsu8g2) for generic porting instructions.
!!! note "BSD License for U8g2lib Code"
Universal 8bit Graphics Library (http://code.google.com/p/u8g2/)
Copyright (c) 2016, 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.
The NodeMCU firmware supports the following displays in I²C and SPI mode:
- ld7032 60x32
- sh1106 128x64
- ssd1305 128x32
- ssd1306 - variants 128x32, 128x64, 64x48, and 96x16
- ssd1309 128x64
- ssd1325 128x63
- ssd1327 96x96
- st7588 jlx12864
- uc1601 128x32
- uc1604 jlx19264
- uc1608 - 240x180 and erc24064 variants
- ux1610 dogxl160
- uc1611 - variants dogm240, dogxl240, and ew50850
SPI only:
- il3820 v2 296x128
- ist3020 erc19264
- ls013b7dh03 128x128
- max7219 32x8
- nt7534 tg12864r
- pcd8544 84x48
- pcf8812 96x65
- sed1520 122x32
- ssd1322 nhd 256x64
- ssd1329 128x96
- ssd1606 172x72
- ssd1607 200x200
- st7565 - variants 64128n, dogm128/132, erc12864, lm6059, c12832/c12864, and zolen 128x64
- st7567 - 132x64 and jlx12864 variants
- st75256 - jlx172104 and jlx256128 variants
- uc1701 - dogs102 and mini12864 variants
This integration uses full "RAM" memory buffer without picture loop and calls u8g2's `begin()` internally when creating a display object. It is based on [v2.19.8](https://github.com/olikraus/U8g2_Arduino/releases/tag/2.19.8).
## Overview
### Library Usage
The Lua bindings for this library closely follow u8g2's object oriented C++ API. Based on the u8g2 class, you create an object for your display type. The communication interface has to be initialized up front, refer to the examples below on how to do this.
SSD1306 via I²C:
```lua
sla = 0x3c
disp = u8g2.ssd1306_i2c_128x64_noname(id, sla)
```
SSD1306 via SPI:
```lua
cs = 22
dc = 16
res = 0 -- RES is optional YMMV
disp = u8g2.ssd1306_128x64_noname(bus, cs, dc, res)
```
This object provides all of u8g2's methods to control the display. Refer to [graphics_test.lua](../../../lua_examples/u8g2/graphics_test.lua) to get an impression how this is achieved with Lua code. Visit the [u8g2 homepage](https://github.com/olikraus/u8g2) for technical details.
### Displays selection
I²C and HW SPI based displays with support in u8g2 can be enabled.
The procedure is different for ESP8266 and ESP32 platforms.
#### ESP8266
Add the desired entries to the I²C or SPI display tables in [app/include/u8g2_displays.h](../../../app/include/u8g2_displays.h):
```c
#define U8G2_DISPLAY_TABLE_I2C \
U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_i2c_128x64_noname_f, ssd1306_i2c_128x64_noname) \
#define U8G2_DISPLAY_TABLE_SPI \
U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_128x64_noname_f, ssd1306_128x64_noname) \
U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_pcd8544_84x48_f, pcd8544_84x48) \
U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_pcf8812_96x65_f, pcf8812_96x65) \
```
Alternatively, you can define them as `U8G2_DISPLAY_TABLE_I2C_EXTRA` and `U8G2_DISPLAY_TABLE_SPI_EXTRA` in an external file to avoid changing the source tree. Include the extra file on the `make` command line:
```
make EXTRA_CCFLAGS='-include $(TOP_DIR)/my_extras.h'
```
#### ESP32
Enable the desired entries for I²C and SPI displays in u8g2's sub-menu (run `make menuconfig`).
### Fonts selection
U8g2 comes with a wide range of fonts for small displays. Fonts can be supplied as strings or compiled into the firmware image to decrease the RAM footprint. If compiled into the firmware they become available as `u8g2.<font_name>` in Lua.
The procedure is different for ESP8266 and ESP32 platforms.
#### ESP8266
Add the desired fonts to the font table in [app/include/u8g2_fonts.h](../../../app/include/u8g2_fonts.h):
```c
#define U8G2_FONT_TABLE \
U8G2_FONT_TABLE_ENTRY(font_6x10_tf) \
U8G2_FONT_TABLE_ENTRY(font_unifont_t_symbols) \
```
Alternatively, you can define this as `U8G2_FONT_TABLE_EXTRA` in an external file to avoid changing the source tree. Include the extra file on the `make` command line:
```
make EXTRA_CCFLAGS='-include $(TOP_DIR)/my_extras.h'
```
#### ESP32
Add the desired fonts to the font selection sub-entry via `make menuconfig`.
### Bitmaps
XBM bitmaps are supplied as strings to `drawXBM()` in contrast to the source code based inclusion of XBMs in upstream u8g2 library. This off-loads all data handling from the u8g2 module to generic methods for binary files. See [graphics_test.lua](../../../lua_examples/u8g2/graphics_test.lua).
Conversion of XBM bitmaps can be performed online with [Online-Utility's Image Converter](http://www.online-utility.org/image_converter.jsp): Convert from XBM to MONO format and upload the binary result.
## I²C Display Drivers
Initialize a display via I²C.
- `u8g2.ld7032_i2c_60x32()`
- `u8g2.sh1106_i2c_128x64_noname()`
- `u8g2.sh1106_i2c_128x64_vcomh0()`
- `u8g2.ssd1305_i2c_128x32_noname()`
- `u8g2.ssd1306_i2c_128x32_univision()`
- `u8g2.ssd1306_i2c_128x64_noname()`
- `u8g2.ssd1306_i2c_128x64_vcomh0()`
- `u8g2.ssd1309_i2c_128x64_noname0()`
- `u8g2.ssd1309_i2c_128x64_noname2()`
- `u8g2.ssd1306_i2c_64x48_er()`
- `u8g2.ssd1306_i2c_96x16_er()`
- `u8g2.ssd1325_i2c_nhd_128x64()`
- `u8g2.ssd1327_i2c_seeed_96x96()`
- `u8g2.st7588_i2c_jlx12864()`
- `u8g2.uc1602_i2c_128X32()`
- `u8g2.uc1604_i2c_jlx19264()`
- `u8g2.uc1608_i2c_erc24064()`
- `u8g2.uc1608_i2c_240x128()`
- `u8g2.uc1610_i2c_ea_dogxl160()`
- `u8g2.uc1611_i2c_ea_dogm240()`
- `u8g2.uc1611_i2c_ea_dogxl240()`
- `u8g2.uc1611_i2c_ew50850()`
#### Syntax
`u8g2.ssd1306_i2c_128x64_noname(id, address[, cb_fn])`
#### Parameters
- `id` i2c interface id, see [i2c module](i2c.md)
- `address` I²C slave address of display (unshifted)
- `cb_fn` optional callback function, see [Framebuffer callback](#framebuffer-callback)
#### Returns
u8g2 display object
#### Example for ESP8266
```lua
id = 0
sda = 5 -- GPIO14
scl = 6 -- GPIO12
sla = 0x3c
i2c.setup(id, sda, scl, i2c.SLOW)
disp = u8g2.ssd1306_i2c_128x64_noname(id, sla)
```
#### Example for ESP32
```lua
id = i2c.HW0
sda = 16
scl = 17
sla = 0x3c
i2c.setup(id, sda, scl, i2c.FAST)
disp = u8g2.ssd1306_i2c_128x64_noname(id, sla)
```
## SPI Display Drivers
Initialize a display via Hardware SPI.
- `u8g2.il3820_v2_296x128()`
- `u8g2.ist3020_erc19264()`
- `u8g2.ld7032_60x32()`
- `u8g2.ls013b7dh03_128x128()`
- `u8g2.max7219_32x8()`
- `u8g2.nt7534_tg12864r()`
- `u8g2.pcd8544_84x48()`
- `u8g2.pcf8812_96x65()`
- `u8g2.sh1106_128x64_noname()`
- `u8g2.sh1106_128x64_vcomh0()`
- `u8g2.ssd1305_128x32_noname()`
- `u8g2.ssd1306_128x32_univision()`
- `u8g2.ssd1306_128x64_noname()`
- `u8g2.ssd1306_128x64_vcomh0()`
- `u8g2.ssd1306_64x48_er()`
- `u8g2.ssd1306_96x16_er()`
- `u8g2.ssd1309_128x64_noname0()`
- `u8g2.ssd1309_128x64_noname2()`
- `u8g2.sed1520_122x32()`
- `u8g2.ssd1322_nhd_256x64()`
- `u8g2.ssd1325_nhd_128x64()`
- `u8g2.ssd1327_seeed_96x96()`
- `u8g2.ssd1329_128x96_noname()`
- `u8g2.ssd1606_172x72()`
- `u8g2.ssd1607_200x200()`
- `u8g2.st7565_64128n()`
- `u8g2.st7565_ea_dogm128()`
- `u8g2.st7565_ea_dogm132()`
- `u8g2.st7565_erc12864()`
- `u8g2.st7565_lm6059()`
- `u8g2.st7565_nhd_c12832()`
- `u8g2.st7565_nhd_c12864()`
- `u8g2.st7565_zolen_128x64()`
- `u8g2.st7567_jxl12864()`
- `u8g2.st7567_pi_132x64()`
- `u8g2.st7588_jlx12864()`
- `u8g2.st7920_s_128x64()`
- `u8g2.st7920_s_192x32()`
- `u8g2.st75256_jlx172104()`
- `u8g2.st75256_jlx256128()`
- `u8g2.uc1601_128X32()`
- `u8g2.uc1604_jlx19264()`
- `u8g2.uc1608_240x128()`
- `u8g2.uc1608_erc24064()`
- `u8g2.uc1610_ea_dogxl160()`
- `u8g2.uc1611_ea_dogm240()`
- `u8g2.uc1611_ea_dogxl240()`
- `u8g2.uc1611_ew50850()`
- `u8g2.uc1701_ea_dogs102()`
- `u8g2.uc1701_mini12864()`
#### Syntax
`u8g2.ssd1306_128x64_noname(bus, cs, dc[, [res][, cb_fn]])`
#### Parameters
- `bus` SPI master bus
- `cs` GPIO pin for CS
- `dc` GPIO pin for DC
- `res` GPIO pin for RES, none if omitted
- `cb_fn` optional callback function, see [Framebuffer callback](#framebuffer-callback)
#### Returns
u8g2 display object
#### Example for ESP8266
```lua
-- Hardware SPI CLK = GPIO14
-- Hardware SPI MOSI = GPIO13
-- Hardware SPI MISO = GPIO12 (not used)
-- Hardware SPI /CS = GPIO15 (not used)
cs = 8 -- GPIO15, pull-down 10k to GND
dc = 4 -- GPIO2
res = 0 -- GPIO16
bus = 1
spi.setup(bus, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
-- we won't be using the HSPI /CS line, so disable it again
gpio.mode(8, gpio.INPUT, gpio.PULLUP)
disp = u8g2.ssd1306_128x64_noname(bus, cs, dc, res)
```
#### Example for ESP32
```lua
sclk = 19
mosi = 23
cs = 22
dc = 16
res = 17
bus = spi.master(spi.HSPI, {sclk=sclk, mosi=mosi})
disp = u8g2.ssd1306_128x64_noname(bus, cs, dc, res)
```
## Framebuffer callback
Each display type can be initialized to provide the framebuffer contents in run-length encoded format to a Lua callback. This mode is enabled when a callback function is specified for the setup function. Hardware display and framebuffer callback can be operated in parallel. If the callback function is the only parameter then no signals for a hardware display are generated, leaving a virtual display.
The callback function can be used to process the framebuffer line by line. It's called with either `nil` as parameter to indicate the start of a new frame or with a string containing a line of the framebuffer with run-length encoding. First byte in the string specifies how many pairs of (x, len) follow, while each pair defines the start (leftmost x-coordinate) and length of a sequence of lit pixels. All other pixels in the line are dark.
```lua
n = struct.unpack("B", rle_line)
print(n.." pairs")
for i = 0,n-1 do
print(string.format(" x: %d len: %d", struct.unpack("BB", rle_line, 1+1 + i*2)))
end
```
#### Syntax
```lua
u8g2.ssd1306_i2c_128x64_noname(id, address[, cb_fn])
u8g2.ssd1306_i2c_128x64_noname(cb_fn)
u8g2.ssd1306_128x64_noname(bus, cs, dc[, [res][, cb_fn]])
u8g2.ssd1306_128x64_noname(cb_fn)
```
#### Parameters
- `id`, `address`, `bus`, `cs`, `dc`, `res` see above
- `cb_fn([rle_line])` callback function. `rle_line` is a string containing a run-length encoded framebuffer line, or `nil` to indicate start of frame.
## Constants
Constants for various functions.
`u8g2.DRAW_UPPER_RIGHT`, `u8g2.DRAW_UPPER_LEFT`, `u8g2.DRAW_LOWER_RIGHT`, `u8g2.DRAW_LOWER_LEFT`, `u8g2.DRAW_ALL`,
`u8g2.R0`, `u8g2.R1`, `u8g2.R2`, `u8g2.R3`, `u8g2.MIRROR`,
`u8g2.font_6x10`, ...
# u8g2.disp Sub-Module
## u8g2.disp:clearBuffer()
Clears all pixel in the memory frame buffer.
See [u8g2 clearBuffer()](https://github.com/olikraus/u8g2/wiki/u8g2reference#clearbuffer).
## u8g2.disp:drawBox()
Draw a box (filled frame).
See [u8g2 drawBox()](https://github.com/olikraus/u8g2/wiki/u8g2reference#drawbox).
## u8g2.disp:drawCircle()
Draw a circle.
See [u8g2 drawCircle()](https://github.com/olikraus/u8g2/wiki/u8g2reference#drawcircle).
Note that parameter `opt` is optional and defaults to `u8g2.DRAW_ALL` if omitted.
## u8g2.disp:drawDisc()
Draw a filled circle.
See [u8g2 drawDisc()](https://github.com/olikraus/u8g2/wiki/u8g2reference#drawdisc).
Note that parameter `opt` is optional and defaults to `u8g2.DRAW_ALL` if omitted.
## u8g2.disp:drawEllipse()
Draw an ellipse.
See [u8g2 drawEllipse()](https://github.com/olikraus/u8g2/wiki/u8g2reference#drawellipse).
Note that parameter `opt` is optional and defaults to `u8g2.DRAW_ALL` if omitted.
## u8g2.disp:drawFilledEllipse()
Draw a filled ellipse.
See [u8g2 drawFilledEllipse()](https://github.com/olikraus/u8g2/wiki/u8g2reference#drawfilledellipse).
Note that parameter `opt` is optional and defaults to `u8g2.DRAW_ALL` if omitted.
## u8g2.disp:drawFrame()
Draw a frame (empty box).
See [u8g2 drawFrame()](https://github.com/olikraus/u8g2/wiki/u8g2reference#drawframe).
## u8g2.disp:drawGlyph()
Draw a single character.
See [u8g2 drawGlyph()](https://github.com/olikraus/u8g2/wiki/u8g2reference#drawglyph).
## u8g2.disp:drawHLine()
Draw a horizontal line.
See [u8g2 drawHLine()](https://github.com/olikraus/u8g2/wiki/u8g2reference#drawhline).
## u8g2.disp:drawLine()
Draw a line between two points.
See [u8g2 drawLine()](https://github.com/olikraus/u8g2/wiki/u8g2reference#drawline).
## u8g2.disp:drawPixel()
Draw a pixel.
See [u8g2 drawPixel()](https://github.com/olikraus/u8g2/wiki/u8g2reference#drawpixel).
## u8g2.disp:drawRBox()
Draw a box with round edges.
See [u8g2 drawRBox()](https://github.com/olikraus/u8g2/wiki/u8g2reference#drawrbox).
## u8g2.disp:drawRFrame()
Draw a frame with round edges.
See [u8g2 drawRFrame()](https://github.com/olikraus/u8g2/wiki/u8g2reference#drawrframe).
## u8g2.disp:drawStr()
Draw a string.
See [u8g2 drawStr()](https://github.com/olikraus/u8g2/wiki/u8g2reference#drawstr).
## u8g2.disp:drawTriangle()
Draw a triangle (filled polygon).
See [u8g2 drawTriangle()](https://github.com/olikraus/u8g2/wiki/u8g2reference#drawtriangle).
## u8g2.disp:drawUTF8()
Draw a string which is encoded as UTF-8.
See [u8g2 drawUTF8()](https://github.com/olikraus/u8g2/wiki/u8g2reference#drawutf8).
## u8g2.disp:drawVLine()
Draw a vertical line.
See [u8g2 drawVLine()](https://github.com/olikraus/u8g2/wiki/u8g2reference#drawvline).
## u8g2.disp:drawXBM()
Draw a XBM Bitmap.
See [u8g2 drawXBM()](https://github.com/olikraus/u8g2/wiki/u8g2reference#drawxbm).
XBM bitmaps are supplied as strings to `drawXBM()`. This off-loads all data handling from the u8g2 module to generic methods for binary files. See [graphics_test.lua](../../../lua_examples/u8glib/u8g_graphics_test.lua).
In contrast to the source code based inclusion of XBMs in upstream u8g2 library, it's required to provide precompiled binary files. This can be performed online with [Online-Utility's Image Converter](http://www.online-utility.org/image_converter.jsp): Convert from XBM to MONO format and upload the binary result.
## u8g2.disp:getAscent()
Returns the reference height of the glyphs above the baseline (ascent).
See [u8g2 getAscent()](https://github.com/olikraus/u8g2/wiki/u8g2reference#getascent).
## u8g2.disp:getDescent()
Returns the reference height of the glyphs below the baseline (descent).
See [u8g2 getDescent()](https://github.com/olikraus/u8g2/wiki/u8g2reference#getdescent).
## u8g2.disp:getStrWidth()
Return the pixel width of string.
See [u8g2 getStrWidth()](https://github.com/olikraus/u8g2/wiki/u8g2reference#getstrwidth).
## u8g2.disp:getUTF8Width()
Return the pixel width of an UTF-8 encoded string.
See [u8g2 getUTF8Width()](https://github.com/olikraus/u8g2/wiki/u8g2reference#getutf8width).
## u8g2.disp:sendBuffer()
Send the content of the memory frame buffer to the display.
See [u8g2 sendBuffer()](https://github.com/olikraus/u8g2/wiki/u8g2reference#sendbuffer).
## u8g2.disp:setBitmapMode()
Define bitmap background color mode.
See [u8g2 setBitmapMode()](https://github.com/olikraus/u8g2/wiki/u8g2reference#setbitmapmode).
## u8g2.disp:setContrast()
Set the contrast or brightness.
See [u8g2 setContrast()](https://github.com/olikraus/u8g2/wiki/u8g2reference#setconstrast).
## u8g2.disp:setDisplayRotation()
Changes the display rotation.
See [u8g2 setDisplayRotation()](https://github.com/olikraus/u8g2/wiki/u8g2reference#setdisplayrotation).
## u8g2.disp:setDrawColor()
Defines the bit value (color index) for all drawing functions.
See [u8g2 setDrawColor()](https://github.com/olikraus/u8g2/wiki/u8g2reference#setdrawcolor).
## u8g2.disp:setFlipMode()
Set flip (180 degree rotation) mode.
See [u8g2 setFlipMode()](https://github.com/olikraus/u8g2/wiki/u8g2reference#setflipmode).
## u8g2.disp:setFont()
Define a u8g2 font for the glyph and string drawing functions. They can be supplied as strings or compiled into the firmware image. They are available as `u8g2.<font_name>` in Lua.
See [u8g2 setFont()](https://github.com/olikraus/u8g2/wiki/u8g2reference#setfont).
## u8g2.disp:setFontDirection()
Set the drawing direction of all strings or glyphs.
See [u8g2 setFontDirection()](https://github.com/olikraus/u8g2/wiki/u8g2reference#setfontdirection).
## u8g2.disp:setFontMode()
Define font background color mode.
See [u8g2 setFontMode()](https://github.com/olikraus/u8g2/wiki/u8g2reference#setfontmode).
## u8g2.disp:setFontPosBaseline()
Change the reference position for the glyph and string draw functions to "baseline".
See [u8g2 setFontPosBaseline()](https://github.com/olikraus/u8g2/wiki/u8g2reference#setfontposbaseline).
## u8g2.disp:setFontPosBottom()
Change the reference position for the glyph and string draw functions to "bottom".
See [u8g2 setFontPosBottom()](https://github.com/olikraus/u8g2/wiki/u8g2reference#setfontposbottom).
## u8g2.disp:setFontPosTop()
Change the reference position for the glyph and string draw functions to "top".
See [u8g2 setFontPosTop()](https://github.com/olikraus/u8g2/wiki/u8g2reference#setfontpostop).
## u8g2.disp:setFontPosCenter()
Change the reference position for the glyph and string draw functions to "center".
See [u8g2 setFontPosCenter()](https://github.com/olikraus/u8g2/wiki/u8g2reference#setfontposcenter).
## u8g2.disp:setFontRefHeightAll()
Set ascent and descent calculation mode to "highest and lowest glyph".
See [u8g2 setFontRefHeightAll()](https://github.com/olikraus/u8g2/wiki/u8g2reference#setfontrefheightall).
## u8g2.disp:setFontRefHeightExtendedText()
Set ascent and descent calculation mode to "highest of [A1(], lowest of [g(]".
See [u8g2 setFontRefHeightExtendedText()](https://github.com/olikraus/u8g2/wiki/u8g2reference#setfontrefheightextendedtext).
## u8g2.disp:setFontRefHeightText()
Set ascent and descent calculation mode to "highest of [A1], lowest of [g]".
See [u8g2 setFontRefHeightText()](https://github.com/olikraus/u8g2/wiki/u8g2reference#setfontrefheighttext).
## u8g2.disp:setPowerSave()
Activate or disable power save mode of the display.
See [u8g2 setPowerSave()](https://github.com/olikraus/u8g2/wiki/u8g2reference#setpowersave).
-- ***************************************************************************
-- Graphics Test
--
-- This script executes several features of u8glib to test their Lua bindings.
--
-- Note: It is prepared for SSD1306-based displays. Select your connectivity
-- type by calling either init_i2c_display() or init_spi_display() at
-- the bottom of this file.
--
-- ***************************************************************************
-- setup I2c and connect display
function init_i2c_display()
-- SDA and SCL can be assigned freely to available GPIOs
local sda = 5 -- GPIO14
local scl = 6 -- GPIO12
local sla = 0x3c
i2c.setup(0, sda, scl, i2c.SLOW)
disp = u8g2.ssd1306_i2c_128x64_noname(0, sla)
end
-- setup SPI and connect display
function init_spi_display()
-- Hardware SPI CLK = GPIO14
-- Hardware SPI MOSI = GPIO13
-- Hardware SPI MISO = GPIO12 (not used)
-- Hardware SPI /CS = GPIO15 (not used)
-- CS, D/C, and RES can be assigned freely to available GPIOs
local cs = 8 -- GPIO15, pull-down 10k to GND
local dc = 4 -- GPIO2
local res = 0 -- GPIO16
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
-- we won't be using the HSPI /CS line, so disable it again
gpio.mode(8, gpio.INPUT, gpio.PULLUP)
disp = u8g2.ssd1306_128x64_noname(1, cs, dc, res)
end
function u8g2_prepare()
disp:setFont(u8g2.font_6x10_tf)
disp:setFontRefHeightExtendedText()
disp:setDrawColor(1)
disp:setFontPosTop()
disp:setFontDirection(0)
end
function u8g2_box_frame(a)
disp:drawStr( 0, 0, "drawBox")
disp:drawBox(5,10,20,10)
disp:drawBox(10+a,15,30,7)
disp:drawStr( 0, 30, "drawFrame")
disp:drawFrame(5,10+30,20,10)
disp:drawFrame(10+a,15+30,30,7)
end
function u8g2_disc_circle(a)
disp:drawStr( 0, 0, "drawDisc")
disp:drawDisc(10,18,9)
disp:drawDisc(24+a,16,7)
disp:drawStr( 0, 30, "drawCircle")
disp:drawCircle(10,18+30,9)
disp:drawCircle(24+a,16+30,7)
end
function u8g2_r_frame(a)
disp:drawStr( 0, 0, "drawRFrame/Box")
disp:drawRFrame(5, 10,40,30, a+1)
disp:drawRBox(50, 10,25,40, a+1)
end
function u8g2_string(a)
disp:setFontDirection(0)
disp:drawStr(30+a,31, " 0")
disp:setFontDirection(1)
disp:drawStr(30,31+a, " 90")
disp:setFontDirection(2)
disp:drawStr(30-a,31, " 180")
disp:setFontDirection(3)
disp:drawStr(30,31-a, " 270")
end
function u8g2_line(a)
disp:drawStr( 0, 0, "drawLine")
disp:drawLine(7+a, 10, 40, 55)
disp:drawLine(7+a*2, 10, 60, 55)
disp:drawLine(7+a*3, 10, 80, 55)
disp:drawLine(7+a*4, 10, 100, 55)
end
function u8g2_triangle(a)
local offset = a
disp:drawStr( 0, 0, "drawTriangle")
disp:drawTriangle(14,7, 45,30, 10,40)
disp:drawTriangle(14+offset,7-offset, 45+offset,30-offset, 57+offset,10-offset)
disp:drawTriangle(57+offset*2,10, 45+offset*2,30, 86+offset*2,53)
disp:drawTriangle(10+offset,40+offset, 45+offset,30+offset, 86+offset,53+offset)
end
function u8g2_ascii_1()
disp:drawStr( 0, 0, "ASCII page 1")
for y = 0, 5 do
for x = 0, 15 do
disp:drawStr(x*7, y*10+10, string.char(y*16 + x + 32))
end
end
end
function u8g2_ascii_2()
disp:drawStr( 0, 0, "ASCII page 2")
for y = 0, 5 do
for x = 0, 15 do
disp:drawStr(x*7, y*10+10, string.char(y*16 + x + 160))
end
end
end
function u8g2_extra_page(a)
disp:drawStr( 0, 0, "Unicode")
disp:setFont(u8g2.font_unifont_t_symbols)
disp:setFontPosTop()
disp:drawUTF8(0, 24, "☀ ☁")
if a <= 3 then
disp:drawUTF8(a*3, 36, "☂")
else
disp:drawUTF8(a*3, 36, "☔")
end
end
cross_width = 24
cross_height = 24
cross_bits = string.char(
0x00, 0x18, 0x00, 0x00, 0x24, 0x00, 0x00, 0x24, 0x00, 0x00, 0x42, 0x00,
0x00, 0x42, 0x00, 0x00, 0x42, 0x00, 0x00, 0x81, 0x00, 0x00, 0x81, 0x00,
0xC0, 0x00, 0x03, 0x38, 0x3C, 0x1C, 0x06, 0x42, 0x60, 0x01, 0x42, 0x80,
0x01, 0x42, 0x80, 0x06, 0x42, 0x60, 0x38, 0x3C, 0x1C, 0xC0, 0x00, 0x03,
0x00, 0x81, 0x00, 0x00, 0x81, 0x00, 0x00, 0x42, 0x00, 0x00, 0x42, 0x00,
0x00, 0x42, 0x00, 0x00, 0x24, 0x00, 0x00, 0x24, 0x00, 0x00, 0x18, 0x00)
cross_fill_width = 24
cross_fill_height = 24
cross_fill_bits = string.char(
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x64, 0x00, 0x26,
0x84, 0x00, 0x21, 0x08, 0x81, 0x10, 0x08, 0x42, 0x10, 0x10, 0x3C, 0x08,
0x20, 0x00, 0x04, 0x40, 0x00, 0x02, 0x80, 0x00, 0x01, 0x80, 0x18, 0x01,
0x80, 0x18, 0x01, 0x80, 0x00, 0x01, 0x40, 0x00, 0x02, 0x20, 0x00, 0x04,
0x10, 0x3C, 0x08, 0x08, 0x42, 0x10, 0x08, 0x81, 0x10, 0x84, 0x00, 0x21,
0x64, 0x00, 0x26, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
cross_block_width = 14
cross_block_height = 14
cross_block_bits = string.char(
0xFF, 0x3F, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20,
0xC1, 0x20, 0xC1, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20,
0x01, 0x20, 0xFF, 0x3F)
function u8g2_bitmap_overlay(a)
local frame_size = 28
disp:drawStr(0, 0, "Bitmap overlay")
disp:drawStr(0, frame_size + 12, "Solid / transparent")
disp:setBitmapMode(0) -- solid
disp:drawFrame(0, 10, frame_size, frame_size)
disp:drawXBM(2, 12, cross_width, cross_height, cross_bits)
if bit.band(a, 4) > 0 then
disp:drawXBM(7, 17, cross_block_width, cross_block_height, cross_block_bits)
end
disp:setBitmapMode(1) -- transparent
disp:drawFrame(frame_size + 5, 10, frame_size, frame_size)
disp:drawXBM(frame_size + 7, 12, cross_width, cross_height, cross_bits)
if bit.band(a, 4) then
disp:drawXBM(frame_size + 12, 17, cross_block_width, cross_block_height, cross_block_bits)
end
end
function u8g2_bitmap_modes(transparent)
local frame_size = 24
disp:drawBox(0, frame_size * 0.5, frame_size * 5, frame_size)
disp:drawStr(frame_size * 0.5, 50, "Black")
disp:drawStr(frame_size * 2, 50, "White")
disp:drawStr(frame_size * 3.5, 50, "XOR")
if transparent == 0 then
disp:setBitmapMode(0) -- solid
disp:drawStr(0, 0, "Solid bitmap")
else
disp:setBitmapMode(1) -- transparent
disp:drawStr(0, 0, "Transparent bitmap")
end
disp:setDrawColor(0) -- Black
disp:drawXBM(frame_size * 0.5, 24, cross_width, cross_height, cross_bits)
disp:setDrawColor(1) -- White
disp:drawXBM(frame_size * 2, 24, cross_width, cross_height, cross_bits)
disp:setDrawColor(2) -- XOR
disp:drawXBM(frame_size * 3.5, 24, cross_width, cross_height, cross_bits)
end
function draw()
u8g2_prepare()
local d3 = bit.rshift(draw_state, 3)
local d7 = bit.band(draw_state, 7)
if d3 == 0 then
u8g2_box_frame(d7)
elseif d3 == 1 then
u8g2_disc_circle(d7)
elseif d3 == 2 then
u8g2_r_frame(d7)
elseif d3 == 3 then
u8g2_string(d7)
elseif d3 == 4 then
u8g2_line(d7)
elseif d3 == 5 then
u8g2_triangle(d7)
elseif d3 == 6 then
u8g2_ascii_1()
elseif d3 == 7 then
u8g2_ascii_2()
elseif d3 == 8 then
u8g2_extra_page(d7)
elseif d3 == 9 then
u8g2_bitmap_modes(0)
elseif d3 == 10 then
u8g2_bitmap_modes(1)
elseif d3 == 11 then
u8g2_bitmap_overlay(d7)
end
end
function loop()
-- picture loop
disp:clearBuffer()
draw()
disp:sendBuffer()
-- increase the state
draw_state = draw_state + 1
if draw_state >= 12*8 then
draw_state = 0
end
-- delay between each frame
loop_tmr:start()
end
draw_state = 0
loop_tmr = tmr.create()
loop_tmr:register(100, tmr.ALARM_SEMI, loop)
init_i2c_display()
--init_spi_display()
print("--- Starting Graphics Test ---")
loop_tmr:start()
-- ***************************************************************************
-- Bitmaps Test
--
-- This script executes the bitmap features of u8glib to test their Lua
-- integration.
--
-- Note: It is prepared for SSD1306-based displays. Select your connectivity
-- type by calling either init_i2c_display() or init_spi_display() at
-- the bottom of this file.
--
-- ***************************************************************************
-- setup I2c and connect display
function init_i2c_display()
-- SDA and SCL can be assigned freely to available GPIOs
local sda = 5 -- GPIO14
local scl = 6 -- GPIO12
local sla = 0x3c
i2c.setup(0, sda, scl, i2c.SLOW)
disp = u8g.ssd1306_128x64_i2c(sla)
end
-- setup SPI and connect display
function init_spi_display()
-- Hardware SPI CLK = GPIO14
-- Hardware SPI MOSI = GPIO13
-- Hardware SPI MISO = GPIO12 (not used)
-- Hardware SPI /CS = GPIO15 (not used)
-- CS, D/C, and RES can be assigned freely to available GPIOs
local cs = 8 -- GPIO15, pull-down 10k to GND
local dc = 4 -- GPIO2
local res = 0 -- GPIO16
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
-- we won't be using the HSPI /CS line, so disable it again
gpio.mode(8, gpio.INPUT, gpio.PULLUP)
disp = u8g.ssd1306_128x64_hw_spi(cs, dc, res)
end
function xbm_picture()
disp:setFont(u8g.font_6x10)
disp:drawStr( 0, 10, "XBM picture")
disp:drawXBM( 0, 20, 38, 24, xbm_data )
end
function bitmap_picture(state)
disp:setFont(u8g.font_6x10)
disp:drawStr( 0, 10, "Bitmap picture")
disp:drawBitmap( 0 + (state * 10), 20 + (state * 4), 1, 8, bm_data )
end
-- the draw() routine
function draw(draw_state)
local component = bit.rshift(draw_state, 3)
if (component == 0) then
xbm_picture(bit.band(draw_state, 7))
elseif (component == 1) then
bitmap_picture(bit.band(draw_state, 7))
end
end
function draw_loop()
-- Draws one page and schedules the next page, if there is one
local function draw_pages()
draw(draw_state)
if disp:nextPage() then
node.task.post(draw_pages)
else
node.task.post(bitmap_test)
end
end
-- Restart the draw loop and start drawing pages
disp:firstPage()
node.task.post(draw_pages)
end
function bitmap_test()
if (draw_state <= 7 + 1*8) then
draw_state = draw_state + 1
else
print("--- Restarting Bitmap Test ---")
draw_state = 1
end
print("Heap: " .. node.heap())
-- retrigger draw_loop
node.task.post(draw_loop)
end
draw_state = 1
init_i2c_display()
--init_spi_display()
-- read XBM picture
file.open("u8glib_logo.xbm", "r")
xbm_data = file.read()
file.close()
-- read Bitmap picture
file.open("u8g_rook.bm", "r")
bm_data = file.read()
file.close()
print("--- Starting Bitmap Test ---")
node.task.post(draw_loop)
------------------------------------------------------------------------------
-- u8glib example which shows how to implement the draw loop without causing
-- timeout issues with the WiFi stack. This is done by drawing one page at
-- a time, allowing the ESP SDK to do its house keeping between the page
-- draws.
--
-- This example assumes you have an SSD1306 display connected to pins 4 and 5
-- using I2C and that the profont22r is compiled into the firmware.
-- Please edit the init_display function to match your setup.
--
-- Example:
-- dofile("u8g_drawloop.lua")
------------------------------------------------------------------------------
local disp
local font
function init_display()
local sda = 4
local sdl = 5
local sla = 0x3c
i2c.setup(0,sda,sdl, i2c.SLOW)
disp = u8g.ssd1306_128x64_i2c(sla)
font = u8g.font_profont22r
end
local function setLargeFont()
disp:setFont(font)
disp:setFontRefHeightExtendedText()
disp:setDefaultForegroundColor()
disp:setFontPosTop()
end
-- Start the draw loop with the draw implementation in the provided function callback
function updateDisplay(func)
-- Draws one page and schedules the next page, if there is one
local function drawPages()
func()
if (disp:nextPage() == true) then
node.task.post(drawPages)
end
end
-- Restart the draw loop and start drawing pages
disp:firstPage()
node.task.post(drawPages)
end
function drawHello()
setLargeFont()
disp:drawStr(30,22, "Hello")
end
function drawWorld()
setLargeFont()
disp:drawStr(30,22, "World")
end
local drawDemo = { drawHello, drawWorld }
function demoLoop()
-- Start the draw loop with one of the demo functions
local f = table.remove(drawDemo,1)
updateDisplay(f)
table.insert(drawDemo,f)
end
-- Initialise the display
init_display()
-- Draw demo page immediately and then schedule an update every 5 seconds.
-- To test your own drawXYZ function, disable the next two lines and call updateDisplay(drawXYZ) instead.
demoLoop()
tmr.alarm(4, 5000, 1, demoLoop)
-- ***************************************************************************
-- Graphics Test
--
-- This script executes several features of u8glib to test their Lua bindings.
--
-- Note: It is prepared for SSD1306-based displays. Select your connectivity
-- type by calling either init_i2c_display() or init_spi_display() at
-- the bottom of this file.
--
-- ***************************************************************************
-- setup I2c and connect display
function init_i2c_display()
-- SDA and SCL can be assigned freely to available GPIOs
local sda = 5 -- GPIO14
local scl = 6 -- GPIO12
local sla = 0x3c
i2c.setup(0, sda, scl, i2c.SLOW)
disp = u8g.ssd1306_128x64_i2c(sla)
end
-- setup SPI and connect display
function init_spi_display()
-- Hardware SPI CLK = GPIO14
-- Hardware SPI MOSI = GPIO13
-- Hardware SPI MISO = GPIO12 (not used)
-- Hardware SPI /CS = GPIO15 (not used)
-- CS, D/C, and RES can be assigned freely to available GPIOs
local cs = 8 -- GPIO15, pull-down 10k to GND
local dc = 4 -- GPIO2
local res = 0 -- GPIO16
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
-- we won't be using the HSPI /CS line, so disable it again
gpio.mode(8, gpio.INPUT, gpio.PULLUP)
disp = u8g.ssd1306_128x64_hw_spi(cs, dc, res)
end
-- graphic test components
function prepare()
disp:setFont(u8g.font_6x10)
disp:setFontRefHeightExtendedText()
disp:setDefaultForegroundColor()
disp:setFontPosTop()
end
function box_frame(a)
disp:drawStr(0, 0, "drawBox")
disp:drawBox(5, 10, 20, 10)
disp:drawBox(10+a, 15, 30, 7)
disp:drawStr(0, 30, "drawFrame")
disp:drawFrame(5, 10+30, 20, 10)
disp:drawFrame(10+a, 15+30, 30, 7)
end
function disc_circle(a)
disp:drawStr(0, 0, "drawDisc")
disp:drawDisc(10, 18, 9)
disp:drawDisc(24+a, 16, 7)
disp:drawStr(0, 30, "drawCircle")
disp:drawCircle(10, 18+30, 9)
disp:drawCircle(24+a, 16+30, 7)
end
function r_frame(a)
disp:drawStr(0, 0, "drawRFrame/Box")
disp:drawRFrame(5, 10, 40, 30, a+1)
disp:drawRBox(50, 10, 25, 40, a+1)
end
function stringtest(a)
disp:drawStr(30+a, 31, " 0")
disp:drawStr90(30, 31+a, " 90")
disp:drawStr180(30-a, 31, " 180")
disp:drawStr270(30, 31-a, " 270")
end
function line(a)
disp:drawStr(0, 0, "drawLine")
disp:drawLine(7+a, 10, 40, 55)
disp:drawLine(7+a*2, 10, 60, 55)
disp:drawLine(7+a*3, 10, 80, 55)
disp:drawLine(7+a*4, 10, 100, 55)
end
function triangle(a)
local offset = a
disp:drawStr(0, 0, "drawTriangle")
disp:drawTriangle(14,7, 45,30, 10,40)
disp:drawTriangle(14+offset,7-offset, 45+offset,30-offset, 57+offset,10-offset)
disp:drawTriangle(57+offset*2,10, 45+offset*2,30, 86+offset*2,53)
disp:drawTriangle(10+offset,40+offset, 45+offset,30+offset, 86+offset,53+offset)
end
function ascii_1()
local x, y, s
disp:drawStr(0, 0, "ASCII page 1")
for y = 0, 5, 1 do
for x = 0, 15, 1 do
s = y*16 + x + 32
disp:drawStr(x*7, y*10+10, string.char(s))
end
end
end
function extra_page(a)
disp:drawStr(0, 12, "setScale2x2")
disp:setScale2x2()
disp:drawStr(0, 6+a, "setScale2x2")
disp:undoScale()
end
-- the draw() routine
function draw(draw_state)
local component = bit.rshift(draw_state, 3)
prepare()
if (component == 0) then
box_frame(bit.band(draw_state, 7))
elseif (component == 1) then
disc_circle(bit.band(draw_state, 7))
elseif (component == 2) then
r_frame(bit.band(draw_state, 7))
elseif (component == 3) then
stringtest(bit.band(draw_state, 7))
elseif (component == 4) then
line(bit.band(draw_state, 7))
elseif (component == 5) then
triangle(bit.band(draw_state, 7))
elseif (component == 6) then
ascii_1()
elseif (component == 7) then
extra_page(bit.band(draw_state, 7))
end
end
function draw_loop()
-- Draws one page and schedules the next page, if there is one
local function draw_pages()
draw(draw_state)
if disp:nextPage() then
node.task.post(draw_pages)
else
node.task.post(graphics_test)
end
end
-- Restart the draw loop and start drawing pages
disp:firstPage()
node.task.post(draw_pages)
end
function graphics_test()
if (draw_state <= 7 + 8*8) then
draw_state = draw_state + 1
else
print("--- Restarting Graphics Test ---")
draw_state = 0
end
print("Heap: " .. node.heap())
-- retrigger draw_loop
node.task.post(draw_loop)
end
draw_state = 0
init_i2c_display()
--init_spi_display()
print("--- Starting Graphics Test ---")
node.task.post(draw_loop)
-- ***************************************************************************
-- Rotation Test
--
-- This script executes the rotation features of u8glib to test their Lua
-- integration.
--
-- Note: It is prepared for SSD1306-based displays. Select your connectivity
-- type by calling either init_i2c_display() or init_spi_display() at
-- the bottom of this file.
--
-- ***************************************************************************
-- setup I2c and connect display
function init_i2c_display()
-- SDA and SCL can be assigned freely to available GPIOs
local sda = 5 -- GPIO14
local scl = 6 -- GPIO12
local sla = 0x3c
i2c.setup(0, sda, scl, i2c.SLOW)
disp = u8g.ssd1306_128x64_i2c(sla)
end
-- setup SPI and connect display
function init_spi_display()
-- Hardware SPI CLK = GPIO14
-- Hardware SPI MOSI = GPIO13
-- Hardware SPI MISO = GPIO12 (not used)
-- Hardware SPI /CS = GPIO15 (not used)
-- CS, D/C, and RES can be assigned freely to available GPIOs
local cs = 8 -- GPIO15, pull-down 10k to GND
local dc = 4 -- GPIO2
local res = 0 -- GPIO16
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
-- we won't be using the HSPI /CS line, so disable it again
gpio.mode(8, gpio.INPUT, gpio.PULLUP)
disp = u8g.ssd1306_128x64_hw_spi(cs, dc, res)
end
-- the draw() routine
function draw()
disp:setFont(u8g.font_6x10)
disp:drawStr( 0+0, 20+0, "Hello!")
disp:drawStr( 0+2, 20+16, "Hello!")
disp:drawBox(0, 0, 3, 3)
disp:drawBox(disp:getWidth()-6, 0, 6, 6)
disp:drawBox(disp:getWidth()-9, disp:getHeight()-9, 9, 9)
disp:drawBox(0, disp:getHeight()-12, 12, 12)
end
function rotate()
if (next_rotation < tmr.now() / 1000) then
if (dir == 0) then
disp:undoRotation()
elseif (dir == 1) then
disp:setRot90()
elseif (dir == 2) then
disp:setRot180()
elseif (dir == 3) then
disp:setRot270()
end
dir = dir + 1
dir = bit.band(dir, 3)
-- schedule next rotation step in 1000ms
next_rotation = tmr.now() / 1000 + 1000
end
end
function rotation_test()
print("--- Starting Rotation Test ---")
dir = 0
next_rotation = 0
local loopcnt
for loopcnt = 1, 100, 1 do
rotate()
disp:firstPage()
repeat
draw(draw_state)
until disp:nextPage() == false
tmr.delay(100000)
tmr.wdclr()
end
print("--- Rotation Test done ---")
end
--init_i2c_display()
init_spi_display()
rotation_test()
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