c8e2f44087
https://code.google.com/p/u8glib/ Universal Graphics Library for 8 Bit Embedded Systems
456 lines
12 KiB
C
456 lines
12 KiB
C
/*
|
|
|
|
u8g_ll_api.c
|
|
|
|
low level api
|
|
|
|
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 <stddef.h>
|
|
#include "u8g.h"
|
|
|
|
uint8_t u8g_call_dev_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg)
|
|
{
|
|
return dev->dev_fn(u8g, dev, msg, arg);
|
|
}
|
|
|
|
/*====================================================================*/
|
|
|
|
uint8_t u8g_InitLL(u8g_t *u8g, u8g_dev_t *dev)
|
|
{
|
|
uint8_t r;
|
|
u8g->state_cb(U8G_STATE_MSG_BACKUP_ENV);
|
|
r = u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_INIT, NULL);
|
|
u8g->state_cb(U8G_STATE_MSG_BACKUP_U8G);
|
|
u8g->state_cb(U8G_STATE_MSG_RESTORE_ENV);
|
|
return r;
|
|
}
|
|
|
|
void u8g_FirstPageLL(u8g_t *u8g, u8g_dev_t *dev)
|
|
{
|
|
u8g->state_cb(U8G_STATE_MSG_BACKUP_ENV);
|
|
u8g->state_cb(U8G_STATE_MSG_RESTORE_U8G);
|
|
u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_PAGE_FIRST, NULL);
|
|
u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_GET_PAGE_BOX, &(u8g->current_page));
|
|
u8g->state_cb(U8G_STATE_MSG_RESTORE_ENV);
|
|
}
|
|
|
|
uint8_t u8g_NextPageLL(u8g_t *u8g, u8g_dev_t *dev)
|
|
{
|
|
uint8_t r;
|
|
u8g->state_cb(U8G_STATE_MSG_BACKUP_ENV);
|
|
u8g->state_cb(U8G_STATE_MSG_RESTORE_U8G);
|
|
r = u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_PAGE_NEXT, NULL);
|
|
if ( r != 0 )
|
|
{
|
|
u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_GET_PAGE_BOX, &(u8g->current_page));
|
|
}
|
|
u8g->state_cb(U8G_STATE_MSG_RESTORE_ENV);
|
|
return r;
|
|
}
|
|
|
|
uint8_t u8g_SetContrastLL(u8g_t *u8g, u8g_dev_t *dev, uint8_t contrast)
|
|
{
|
|
return u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_CONTRAST, &contrast);
|
|
}
|
|
|
|
void u8g_DrawPixelLL(u8g_t *u8g, u8g_dev_t *dev, u8g_uint_t x, u8g_uint_t y)
|
|
{
|
|
u8g_dev_arg_pixel_t *arg = &(u8g->arg_pixel);
|
|
arg->x = x;
|
|
arg->y = y;
|
|
u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_SET_PIXEL, arg);
|
|
}
|
|
|
|
void u8g_Draw8PixelLL(u8g_t *u8g, u8g_dev_t *dev, u8g_uint_t x, u8g_uint_t y, uint8_t dir, uint8_t pixel)
|
|
{
|
|
u8g_dev_arg_pixel_t *arg = &(u8g->arg_pixel);
|
|
arg->x = x;
|
|
arg->y = y;
|
|
arg->dir = dir;
|
|
arg->pixel = pixel;
|
|
u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_SET_8PIXEL, arg);
|
|
}
|
|
|
|
#ifdef U8G_DEV_MSG_IS_BBX_INTERSECTION
|
|
uint8_t u8g_IsBBXIntersectionLL(u8g_t *u8g, u8g_dev_t *dev, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h)
|
|
{
|
|
return u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_IS_BBX_INTERSECTION, &arg);
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
u8g_uint_t u8g_GetWidthLL(u8g_t *u8g, u8g_dev_t *dev)
|
|
{
|
|
u8g_uint_t r;
|
|
u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_GET_WIDTH, &r);
|
|
return r;
|
|
}
|
|
|
|
u8g_uint_t u8g_GetHeightLL(u8g_t *u8g, u8g_dev_t *dev)
|
|
{
|
|
u8g_uint_t r;
|
|
u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_GET_HEIGHT, &r);
|
|
return r;
|
|
}
|
|
|
|
u8g_uint_t u8g_GetModeLL(u8g_t *u8g, u8g_dev_t *dev)
|
|
{
|
|
return u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_GET_MODE, NULL);
|
|
}
|
|
|
|
|
|
|
|
/*====================================================================*/
|
|
|
|
void u8g_UpdateDimension(u8g_t *u8g)
|
|
{
|
|
u8g->width = u8g_GetWidthLL(u8g, u8g->dev);
|
|
u8g->height = u8g_GetHeightLL(u8g, u8g->dev);
|
|
u8g->mode = u8g_GetModeLL(u8g, u8g->dev);
|
|
/* 9 Dec 2012: u8g_scale.c requires update of current page */
|
|
u8g_call_dev_fn(u8g, u8g->dev, U8G_DEV_MSG_GET_PAGE_BOX, &(u8g->current_page));
|
|
}
|
|
|
|
static void u8g_init_data(u8g_t *u8g)
|
|
{
|
|
uint8_t i;
|
|
u8g->font = NULL;
|
|
u8g->cursor_font = NULL;
|
|
u8g->cursor_bg_color = 0;
|
|
u8g->cursor_fg_color = 1;
|
|
u8g->cursor_encoding = 34;
|
|
u8g->cursor_fn = (u8g_draw_cursor_fn)0;
|
|
|
|
for( i = 0; i < U8G_PIN_LIST_LEN; i++ )
|
|
u8g->pin_list[i] = U8G_PIN_NONE;
|
|
|
|
u8g_SetColorIndex(u8g, 1);
|
|
|
|
u8g_SetFontPosBaseline(u8g);
|
|
|
|
u8g->font_height_mode = U8G_FONT_HEIGHT_MODE_XTEXT;
|
|
u8g->font_ref_ascent = 0;
|
|
u8g->font_ref_descent = 0;
|
|
u8g->font_line_spacing_factor = 64; /* 64 = 1.0, 77 = 1.2 line spacing factor */
|
|
u8g->line_spacing = 0;
|
|
|
|
u8g->state_cb = u8g_state_dummy_cb;
|
|
|
|
}
|
|
|
|
uint8_t u8g_Begin(u8g_t *u8g)
|
|
{
|
|
/* call and init low level driver and com device */
|
|
if ( u8g_InitLL(u8g, u8g->dev) == 0 )
|
|
return 0;
|
|
/* fetch width and height from the low level */
|
|
u8g_UpdateDimension(u8g);
|
|
return 1;
|
|
}
|
|
|
|
uint8_t u8g_Init(u8g_t *u8g, u8g_dev_t *dev)
|
|
{
|
|
u8g_init_data(u8g);
|
|
u8g->dev = dev;
|
|
|
|
/* On the Arduino Environment this will lead to two calls to u8g_Begin(), the following line will be called first (by U8glib constructors) */
|
|
/* if - in future releases - this is removed, then still call u8g_UpdateDimension() */
|
|
/* if Arduino call u8g_UpdateDimension else u8g_Begin */
|
|
/* issue 146 */
|
|
return u8g_Begin(u8g);
|
|
}
|
|
|
|
uint8_t u8g_InitSPI(u8g_t *u8g, u8g_dev_t *dev, uint8_t sck, uint8_t mosi, uint8_t cs, uint8_t a0, uint8_t reset)
|
|
{
|
|
|
|
/* fill data structure with some suitable values */
|
|
u8g_init_data(u8g);
|
|
u8g->dev = dev;
|
|
|
|
/* assign user pins */
|
|
u8g->pin_list[U8G_PI_SCK] = sck;
|
|
u8g->pin_list[U8G_PI_MOSI] = mosi;
|
|
u8g->pin_list[U8G_PI_CS] = cs;
|
|
u8g->pin_list[U8G_PI_A0] = a0;
|
|
u8g->pin_list[U8G_PI_RESET] = reset;
|
|
|
|
/* On the Arduino Environment this will lead to two calls to u8g_Begin(), the following line will be called first (by U8glib constructors) */
|
|
/* if - in future releases - this is removed, then still call u8g_UpdateDimension() */
|
|
/* if Arduino call u8g_UpdateDimension else u8g_Begin */
|
|
/* issue 146 */
|
|
return u8g_Begin(u8g);
|
|
}
|
|
|
|
uint8_t u8g_InitHWSPI(u8g_t *u8g, u8g_dev_t *dev, uint8_t cs, uint8_t a0, uint8_t reset)
|
|
{
|
|
/* fill data structure with some suitable values */
|
|
u8g_init_data(u8g);
|
|
u8g->dev = dev;
|
|
|
|
|
|
/* assign user pins */
|
|
u8g->pin_list[U8G_PI_CS] = cs;
|
|
u8g->pin_list[U8G_PI_A0] = a0;
|
|
u8g->pin_list[U8G_PI_RESET] = reset;
|
|
|
|
return u8g_Begin(u8g);
|
|
}
|
|
|
|
uint8_t u8g_InitI2C(u8g_t *u8g, u8g_dev_t *dev, uint8_t options)
|
|
{
|
|
/* fill data structure with some suitable values */
|
|
u8g_init_data(u8g);
|
|
u8g->dev = dev;
|
|
|
|
u8g->pin_list[U8G_PI_I2C_OPTION] = options;
|
|
|
|
return u8g_Begin(u8g);
|
|
}
|
|
|
|
|
|
uint8_t u8g_Init8BitFixedPort(u8g_t *u8g, u8g_dev_t *dev, uint8_t en, uint8_t cs, uint8_t di, uint8_t rw, uint8_t reset)
|
|
{
|
|
|
|
/* fill data structure with some suitable values */
|
|
u8g_init_data(u8g);
|
|
u8g->dev = dev;
|
|
|
|
/* assign user pins */
|
|
|
|
u8g->pin_list[U8G_PI_EN] = en;
|
|
u8g->pin_list[U8G_PI_CS] = cs;
|
|
u8g->pin_list[U8G_PI_DI] = di;
|
|
u8g->pin_list[U8G_PI_RW] = rw;
|
|
u8g->pin_list[U8G_PI_RESET] = reset;
|
|
|
|
return u8g_Begin(u8g);
|
|
}
|
|
|
|
uint8_t u8g_Init8Bit(u8g_t *u8g, u8g_dev_t *dev, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7,
|
|
uint8_t en, uint8_t cs1, uint8_t cs2, uint8_t di, uint8_t rw, uint8_t reset)
|
|
{
|
|
|
|
/* fill data structure with some suitable values */
|
|
u8g_init_data(u8g);
|
|
u8g->dev = dev;
|
|
|
|
/* assign user pins */
|
|
|
|
u8g->pin_list[U8G_PI_D0] = d0;
|
|
u8g->pin_list[U8G_PI_D1] = d1;
|
|
u8g->pin_list[U8G_PI_D2] = d2;
|
|
u8g->pin_list[U8G_PI_D3] = d3;
|
|
u8g->pin_list[U8G_PI_D4] = d4;
|
|
u8g->pin_list[U8G_PI_D5] = d5;
|
|
u8g->pin_list[U8G_PI_D6] = d6;
|
|
u8g->pin_list[U8G_PI_D7] = d7;
|
|
|
|
u8g->pin_list[U8G_PI_EN] = en;
|
|
u8g->pin_list[U8G_PI_CS1] = cs1;
|
|
u8g->pin_list[U8G_PI_CS2] = cs2;
|
|
u8g->pin_list[U8G_PI_DI] = di;
|
|
u8g->pin_list[U8G_PI_RW] = rw;
|
|
u8g->pin_list[U8G_PI_RESET] = reset;
|
|
|
|
return u8g_Begin(u8g);
|
|
}
|
|
|
|
/*
|
|
|
|
PIN_D0 8
|
|
PIN_D1 9
|
|
PIN_D2 10
|
|
PIN_D3 11
|
|
PIN_D4 4
|
|
PIN_D5 5
|
|
PIN_D6 6
|
|
PIN_D7 7
|
|
|
|
PIN_CS 14
|
|
PIN_A0 15
|
|
PIN_RESET 16
|
|
PIN_WR 17
|
|
PIN_RD 18
|
|
|
|
u8g_InitRW8Bit(u8g, dev, d0, d1, d2, d3, d4, d5, d6, d7, cs, a0, wr, rd, reset)
|
|
u8g_InitRW8Bit(u8g, dev, 8, 9, 10, 11, 4, 5, 6, 7, 14, 15, 17, 18, 16)
|
|
|
|
*/
|
|
|
|
uint8_t u8g_InitRW8Bit(u8g_t *u8g, u8g_dev_t *dev, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7,
|
|
uint8_t cs, uint8_t a0, uint8_t wr, uint8_t rd, uint8_t reset)
|
|
{
|
|
|
|
/* fill data structure with some suitable values */
|
|
u8g_init_data(u8g);
|
|
u8g->dev = dev;
|
|
|
|
/* assign user pins */
|
|
|
|
u8g->pin_list[U8G_PI_D0] = d0;
|
|
u8g->pin_list[U8G_PI_D1] = d1;
|
|
u8g->pin_list[U8G_PI_D2] = d2;
|
|
u8g->pin_list[U8G_PI_D3] = d3;
|
|
u8g->pin_list[U8G_PI_D4] = d4;
|
|
u8g->pin_list[U8G_PI_D5] = d5;
|
|
u8g->pin_list[U8G_PI_D6] = d6;
|
|
u8g->pin_list[U8G_PI_D7] = d7;
|
|
|
|
u8g->pin_list[U8G_PI_CS] = cs;
|
|
u8g->pin_list[U8G_PI_A0] = a0;
|
|
u8g->pin_list[U8G_PI_WR] = wr;
|
|
u8g->pin_list[U8G_PI_RD] = rd;
|
|
u8g->pin_list[U8G_PI_RESET] = reset;
|
|
|
|
return u8g_Begin(u8g);
|
|
}
|
|
|
|
void u8g_FirstPage(u8g_t *u8g)
|
|
{
|
|
u8g_FirstPageLL(u8g, u8g->dev);
|
|
}
|
|
|
|
uint8_t u8g_NextPage(u8g_t *u8g)
|
|
{
|
|
if ( u8g->cursor_fn != (u8g_draw_cursor_fn)0 )
|
|
{
|
|
u8g->cursor_fn(u8g);
|
|
}
|
|
return u8g_NextPageLL(u8g, u8g->dev);
|
|
}
|
|
|
|
uint8_t u8g_SetContrast(u8g_t *u8g, uint8_t contrast)
|
|
{
|
|
return u8g_SetContrastLL(u8g, u8g->dev, contrast);
|
|
}
|
|
|
|
void u8g_SleepOn(u8g_t *u8g)
|
|
{
|
|
u8g_call_dev_fn(u8g, u8g->dev, U8G_DEV_MSG_SLEEP_ON, NULL);
|
|
}
|
|
|
|
void u8g_SleepOff(u8g_t *u8g)
|
|
{
|
|
u8g_call_dev_fn(u8g, u8g->dev, U8G_DEV_MSG_SLEEP_OFF, NULL);
|
|
}
|
|
|
|
|
|
void u8g_DrawPixel(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y)
|
|
{
|
|
u8g_DrawPixelLL(u8g, u8g->dev, x, y);
|
|
}
|
|
|
|
void u8g_Draw8Pixel(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, uint8_t pixel)
|
|
{
|
|
u8g_Draw8PixelLL(u8g, u8g->dev, x, y, dir, pixel);
|
|
}
|
|
|
|
/* u8g_IsBBXIntersection() has been moved to u8g_clip.c */
|
|
#ifdef OBSOLETE_CODE
|
|
uint8_t u8g_IsBBXIntersection(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h)
|
|
{
|
|
/* new code */
|
|
u8g_dev_arg_bbx_t arg;
|
|
arg.x = x;
|
|
arg.y = y;
|
|
arg.w = w;
|
|
arg.h = h;
|
|
return u8g_is_box_bbx_intersection(&(u8g->current_page), &arg);
|
|
|
|
/* old code */
|
|
//return u8g_IsBBXIntersectionLL(u8g, u8g->dev, x, y, w, h);
|
|
}
|
|
#endif
|
|
|
|
void u8g_SetColorIndex(u8g_t *u8g, uint8_t idx)
|
|
{
|
|
u8g->arg_pixel.color = idx;
|
|
/*u8g->color_index = idx; */ /* must be removed */
|
|
}
|
|
|
|
uint8_t u8g_GetColorIndex(u8g_t *u8g)
|
|
{
|
|
return u8g->arg_pixel.color;
|
|
}
|
|
|
|
uint8_t u8g_GetDefaultForegroundColor(u8g_t *u8g)
|
|
{
|
|
uint8_t mode;
|
|
mode = u8g_GetMode(u8g);
|
|
if ( mode == U8G_MODE_R3G3B2 )
|
|
return 255; /* white */
|
|
else if ( u8g_GetMode(u8g) == U8G_MODE_GRAY2BIT )
|
|
return 3; /* max intensity */
|
|
else /* if ( u8g.getMode() == U8G_MODE_BW ) */
|
|
return 1; /* pixel on */
|
|
return 1;
|
|
}
|
|
|
|
void u8g_SetDefaultForegroundColor(u8g_t *u8g)
|
|
{
|
|
u8g_SetColorIndex(u8g, u8g_GetDefaultForegroundColor(u8g));
|
|
}
|
|
|
|
uint8_t u8g_GetDefaultBackgroundColor(u8g_t *u8g)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void u8g_SetDefaultBackgroundColor(u8g_t *u8g)
|
|
{
|
|
u8g_SetColorIndex(u8g, u8g_GetDefaultBackgroundColor(u8g)); /* pixel on / black */
|
|
}
|
|
|
|
uint8_t u8g_GetDefaultMidColor(u8g_t *u8g)
|
|
{
|
|
uint8_t mode;
|
|
mode = u8g_GetMode(u8g);
|
|
if ( mode == U8G_MODE_R3G3B2 )
|
|
return 0x06d; /* gray: 01101101 */
|
|
else if ( u8g_GetMode(u8g) == U8G_MODE_GRAY2BIT )
|
|
return 1; /* low mid intensity */
|
|
else /* if ( u8g.getMode() == U8G_MODE_BW ) */
|
|
return 1; /* pixel on */
|
|
return 1; /* default */
|
|
}
|
|
|
|
void u8g_SetDefaultMidColor(u8g_t *u8g)
|
|
{
|
|
u8g_SetColorIndex(u8g, u8g_GetDefaultMidColor(u8g));
|
|
}
|
|
|
|
|
|
|
|
|