Add ucg module.
This commit is contained in:
parent
c1de414ba1
commit
45c63a8236
|
@ -11,3 +11,6 @@
|
|||
[submodule "components/espmqtt"]
|
||||
path = components/espmqtt
|
||||
url = https://github.com/tuanpmt/espmqtt
|
||||
[submodule "components/ucg/ucg"]
|
||||
path = components/ucg/ucg
|
||||
url = https://github.com/olikraus/Ucglib_Arduino.git
|
||||
|
|
|
@ -175,6 +175,15 @@ config LUA_MODULE_U8G2
|
|||
|
||||
source "$PROJECT_PATH/components/u8g2/u8g2.kconfig"
|
||||
|
||||
config LUA_MODULE_UCG
|
||||
bool "UCG module"
|
||||
default "n"
|
||||
select LUA_MODULE_SPI
|
||||
help
|
||||
Includes the ucg module.
|
||||
|
||||
source "$PROJECT_PATH/components/ucg/ucg.kconfig"
|
||||
|
||||
config LUA_MODULE_WIFI
|
||||
bool "WiFi module"
|
||||
default "y"
|
||||
|
|
|
@ -22,7 +22,7 @@ CFLAGS += \
|
|||
-Werror=unused-but-set-variable \
|
||||
-Werror=unused-variable \
|
||||
|
||||
COMPONENT_EXTRA_CLEAN := u8g2_fonts.h u8g2_displays.h
|
||||
COMPONENT_EXTRA_CLEAN := u8g2_fonts.h u8g2_displays.h ucg_config.h
|
||||
|
||||
u8g2.o: u8g2_fonts.h u8g2_displays.h
|
||||
|
||||
|
@ -31,3 +31,8 @@ u8g2_fonts.h: $(BUILD_DIR_BASE)/include/sdkconfig.h
|
|||
|
||||
u8g2_displays.h: $(BUILD_DIR_BASE)/include/sdkconfig.h
|
||||
perl -w $(PROJECT_PATH)/tools/u8g2_config_displays.pl < $^ > $@
|
||||
|
||||
ucg.o: ucg_config.h
|
||||
|
||||
ucg_config.h: $(BUILD_DIR_BASE)/include/sdkconfig.h
|
||||
perl -w $(PROJECT_PATH)/tools/ucg_config.pl < $^ > $@
|
||||
|
|
|
@ -0,0 +1,770 @@
|
|||
// Module for Ucglib
|
||||
|
||||
#include "module.h"
|
||||
#include "lauxlib.h"
|
||||
|
||||
|
||||
#define USE_PIN_LIST
|
||||
#include "ucg.h"
|
||||
#include "ucg_nodemcu_hal.h"
|
||||
|
||||
|
||||
#include "ucg_config.h"
|
||||
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
// ESP32
|
||||
#include "spi_common.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_LUA_MODULE_U8G2
|
||||
// ignore unused functions if u8g2 module will be skipped anyhow
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ucg_nodemcu_t ucg;
|
||||
|
||||
ucg_dev_fnptr dev_cb;
|
||||
ucg_dev_fnptr ext_cb;
|
||||
|
||||
// For Print() function
|
||||
ucg_int_t tx, ty;
|
||||
uint8_t tdir;
|
||||
|
||||
int font_ref;
|
||||
int host_ref;
|
||||
} ucg_ud_t;
|
||||
|
||||
|
||||
|
||||
|
||||
// shorthand macro for the ucg structure inside the userdata
|
||||
#define GET_UCG() \
|
||||
ucg_ud_t *ud = (ucg_ud_t *)luaL_checkudata( L, 1, "ucg.display" ); \
|
||||
ucg_t *ucg = (ucg_t *)(&(ud->ucg));
|
||||
|
||||
|
||||
// helper function: retrieve given number of integer arguments
|
||||
static void lucg_get_int_args( lua_State *L, uint8_t stack, uint8_t num, ucg_int_t *args)
|
||||
{
|
||||
while (num-- > 0) {
|
||||
*args++ = luaL_checkinteger( L, stack++ );
|
||||
}
|
||||
}
|
||||
|
||||
// Lua: ucg.begin( self, fontmode )
|
||||
static int lucg_begin( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_Init( ucg, ud->dev_cb, ud->ext_cb, ucg_com_nodemcu_hw_spi );
|
||||
|
||||
ucg_int_t fontmode = luaL_checkinteger( L, 2 );
|
||||
|
||||
ucg_SetFontMode( ucg, fontmode );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.clearScreen( self )
|
||||
static int lucg_clearScreen( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_ClearScreen( ucg );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.draw90Line( self, x, y, len, dir, col_idx )
|
||||
static int lucg_draw90Line( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[5];
|
||||
lucg_get_int_args( L, 2, 5, args );
|
||||
|
||||
ucg_Draw90Line( ucg, args[0], args[1], args[2], args[3], args[4] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.drawBox( self, x, y, w, h )
|
||||
static int lucg_drawBox( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[4];
|
||||
lucg_get_int_args( L, 2, 4, args );
|
||||
|
||||
ucg_DrawBox( ucg, args[0], args[1], args[2], args[3] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.drawCircle( self, x0, y0, rad, option )
|
||||
static int lucg_drawCircle( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[4];
|
||||
lucg_get_int_args( L, 2, 4, args );
|
||||
|
||||
ucg_DrawCircle( ucg, args[0], args[1], args[2], args[3] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.drawDisc( self, x0, y0, rad, option )
|
||||
static int lucg_drawDisc( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[4];
|
||||
lucg_get_int_args( L, 2, 4, args );
|
||||
|
||||
ucg_DrawDisc( ucg, args[0], args[1], args[2], args[3] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.drawFrame( self, x, y, w, h )
|
||||
static int lucg_drawFrame( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[4];
|
||||
lucg_get_int_args( L, 2, 4, args );
|
||||
|
||||
ucg_DrawFrame( ucg, args[0], args[1], args[2], args[3] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.drawGradientBox( self, x, y, w, h )
|
||||
static int lucg_drawGradientBox( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[4];
|
||||
lucg_get_int_args( L, 2, 4, args );
|
||||
|
||||
ucg_DrawGradientBox( ucg, args[0], args[1], args[2], args[3] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: width = ucg.drawGlyph( self, x, y, dir, encoding )
|
||||
static int lucg_drawGlyph( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[3];
|
||||
lucg_get_int_args( L, 2, 3, args );
|
||||
|
||||
const char *c = luaL_checkstring( L, (1+3) + 1 );
|
||||
if (c == NULL)
|
||||
return 0;
|
||||
|
||||
lua_pushinteger( L, ucg_DrawGlyph( ucg, args[0], args[1], args[2], *c ) );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Lua: ucg.drawGradientLine( self, x, y, len, dir )
|
||||
static int lucg_drawGradientLine( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[4];
|
||||
lucg_get_int_args( L, 2, 4, args );
|
||||
|
||||
ucg_DrawGradientLine( ucg, args[0], args[1], args[2], args[3] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.drawHLine( self, x, y, len )
|
||||
static int lucg_drawHLine( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[3];
|
||||
lucg_get_int_args( L, 2, 3, args );
|
||||
|
||||
ucg_DrawHLine( ucg, args[0], args[1], args[2] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.drawLine( self, x1, y1, x2, y2 )
|
||||
static int lucg_drawLine( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[4];
|
||||
lucg_get_int_args( L, 2, 4, args );
|
||||
|
||||
ucg_DrawLine( ucg, args[0], args[1], args[2], args[3] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.drawPixel( self, x, y )
|
||||
static int lucg_drawPixel( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[2];
|
||||
lucg_get_int_args( L, 2, 2, args );
|
||||
|
||||
ucg_DrawPixel( ucg, args[0], args[1] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.drawRBox( self, x, y, w, h, r )
|
||||
static int lucg_drawRBox( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[5];
|
||||
lucg_get_int_args( L, 2, 5, args );
|
||||
|
||||
ucg_DrawRBox( ucg, args[0], args[1], args[2], args[3], args[4] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.drawRFrame( self, x, y, w, h, r )
|
||||
static int lucg_drawRFrame( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[5];
|
||||
lucg_get_int_args( L, 2, 5, args );
|
||||
|
||||
ucg_DrawRFrame( ucg, args[0], args[1], args[2], args[3], args[4] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: width = ucg.drawString( self, x, y, dir, str )
|
||||
static int lucg_drawString( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[3];
|
||||
lucg_get_int_args( L, 2, 3, args );
|
||||
|
||||
const char *s = luaL_checkstring( L, (1+3) + 1 );
|
||||
if (s == NULL)
|
||||
return 0;
|
||||
|
||||
lua_pushinteger( L, ucg_DrawString( ucg, args[0], args[1], args[2], s ) );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Lua: ucg.drawTetragon( self, x0, y0, x1, y1, x2, y2, x3, y3 )
|
||||
static int lucg_drawTetragon( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[8];
|
||||
lucg_get_int_args( L, 2, 8, args );
|
||||
|
||||
ucg_DrawTetragon( ucg, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.drawTriangle( self, x0, y0, x1, y1, x2, y2 )
|
||||
static int lucg_drawTriangle( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[6];
|
||||
lucg_get_int_args( L, 2, 6, args );
|
||||
|
||||
ucg_DrawTriangle( ucg, args[0], args[1], args[2], args[3], args[4], args[5] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.drawVLine( self, x, y, len )
|
||||
static int lucg_drawVLine( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[3];
|
||||
lucg_get_int_args( L, 2, 3, args );
|
||||
|
||||
ucg_DrawVLine( ucg, args[0], args[1], args[2] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: height = ucg.getFontAscent( self )
|
||||
static int lucg_getFontAscent( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
lua_pushinteger( L, ucg_GetFontAscent( ucg ) );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Lua: height = ucg.getFontDescent( self )
|
||||
static int lucg_getFontDescent( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
lua_pushinteger( L, ucg_GetFontDescent( ucg ) );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Lua: height = ucg.getHeight( self )
|
||||
static int lucg_getHeight( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
lua_pushinteger( L, ucg_GetHeight( ucg ) );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Lua: width = ucg.getStrWidth( self, string )
|
||||
static int lucg_getStrWidth( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
const char *s = luaL_checkstring( L, 2 );
|
||||
if (s == NULL)
|
||||
return 0;
|
||||
|
||||
lua_pushinteger( L, ucg_GetStrWidth( ucg, s ) );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Lua: width = ucg.getWidth( self )
|
||||
static int lucg_getWidth( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
lua_pushinteger( L, ucg_GetWidth( ucg ) );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Lua: ucg.setClipRange( self, x, y, w, h )
|
||||
static int lucg_setClipRange( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[4];
|
||||
lucg_get_int_args( L, 2, 4, args );
|
||||
|
||||
ucg_SetClipRange( ucg, args[0], args[1], args[2], args[3] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.setColor( self, [idx], r, g, b )
|
||||
static int lucg_setColor( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t args[3];
|
||||
lucg_get_int_args( L, 2, 3, args );
|
||||
|
||||
ucg_int_t opt = luaL_optint( L, (1+3) + 1, -1 );
|
||||
|
||||
if (opt < 0) {
|
||||
ucg_SetColor( ucg, 0, args[0], args[1], args[2] );
|
||||
} else {
|
||||
ucg_SetColor( ucg, args[0], args[1], args[2], opt );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.setFont( self, font )
|
||||
static int lucg_setFont( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_fntpgm_uint8_t *font = (ucg_fntpgm_uint8_t *)lua_touserdata( L, 2 );
|
||||
if (font != NULL)
|
||||
ucg_SetFont( ucg, font );
|
||||
else
|
||||
luaL_argerror(L, 2, "font data expected");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.print( self, str )
|
||||
static int lucg_print( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
const char *s = luaL_checkstring( L, 2 );
|
||||
if (s == NULL)
|
||||
return 0;
|
||||
|
||||
while (*s)
|
||||
{
|
||||
ucg_int_t delta;
|
||||
delta = ucg_DrawGlyph(ucg, ud->tx, ud->ty, ud->tdir, *(s++));
|
||||
switch(ud->tdir) {
|
||||
case 0: ud->tx += delta; break;
|
||||
case 1: ud->ty += delta; break;
|
||||
case 2: ud->tx -= delta; break;
|
||||
default: case 3: ud->ty -= delta; break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.setFontMode( self, fontmode )
|
||||
static int lucg_setFontMode( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_int_t fontmode = luaL_checkinteger( L, 2 );
|
||||
|
||||
ucg_SetFontMode( ucg, fontmode );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.setFontPosBaseline( self )
|
||||
static int lucg_setFontPosBaseline( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_SetFontPosBaseline( ucg );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.setFontPosBottom( self )
|
||||
static int lucg_setFontPosBottom( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_SetFontPosBottom( ucg );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.setFontPosCenter( self )
|
||||
static int lucg_setFontPosCenter( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_SetFontPosCenter( ucg );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.setFontPosTop( self )
|
||||
static int lucg_setFontPosTop( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_SetFontPosTop( ucg );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.setMaxClipRange( self )
|
||||
static int lucg_setMaxClipRange( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_SetMaxClipRange( ucg );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.setPrintPos( self, x, y )
|
||||
static int lucg_setPrintPos( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
(void)ucg;
|
||||
|
||||
ucg_int_t args[2];
|
||||
lucg_get_int_args( L, 2, 2, args );
|
||||
|
||||
ud->tx = args[0];
|
||||
ud->ty = args[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.setPrintDir( self, dir )
|
||||
static int lucg_setPrintDir( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
(void)ucg;
|
||||
|
||||
ud->tdir = luaL_checkinteger( L, 2 );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.setRotate90( self )
|
||||
static int lucg_setRotate90( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_SetRotate90( ucg );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.setRotate180( self )
|
||||
static int lucg_setRotate180( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_SetRotate180( ucg );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.setRotate270( self )
|
||||
static int lucg_setRotate270( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_SetRotate270( ucg );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.setScale2x2( self )
|
||||
static int lucg_setScale2x2( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_SetScale2x2( ucg );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.undoRotate( self )
|
||||
static int lucg_undoRotate( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_UndoRotate( ucg );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: ucg.undoScale( self )
|
||||
static int lucg_undoScale( lua_State *L )
|
||||
{
|
||||
GET_UCG();
|
||||
|
||||
ucg_UndoScale( ucg );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// device destructor
|
||||
static int lucg_close_display( lua_State *L )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
// Device constructors
|
||||
//
|
||||
//
|
||||
static int ldisplay_hw_spi( lua_State *L, ucg_dev_fnptr device, ucg_dev_fnptr extension )
|
||||
{
|
||||
int stack = 0;
|
||||
|
||||
#ifndef ESP_PLATFORM
|
||||
// ESP8266
|
||||
typedef struct {
|
||||
int host;
|
||||
} lspi_host_t;
|
||||
lspi_host_t host_elem;
|
||||
lspi_host_t *host = &host_elem;
|
||||
#else
|
||||
// ESP32
|
||||
lspi_host_t *host = NULL;
|
||||
#endif
|
||||
int host_ref = LUA_NOREF;
|
||||
int cs = -1;
|
||||
int dc = -1;
|
||||
int res = -1;
|
||||
int get_spi_pins;
|
||||
|
||||
if (lua_type( L, ++stack ) == LUA_TUSERDATA) {
|
||||
host = (lspi_host_t *)luaL_checkudata( L, stack, "spi.master" );
|
||||
/* reference host object to avoid automatic gc */
|
||||
lua_pushvalue( L, stack );
|
||||
host_ref = luaL_ref( L, LUA_REGISTRYINDEX );
|
||||
get_spi_pins = 1;
|
||||
} else if (lua_type( L, stack ) == LUA_TNUMBER) {
|
||||
host->host = luaL_checkint( L, stack );
|
||||
get_spi_pins = 1;
|
||||
} else {
|
||||
get_spi_pins = 0;
|
||||
stack--;
|
||||
}
|
||||
|
||||
if (get_spi_pins) {
|
||||
cs = luaL_checkint( L, ++stack );
|
||||
dc = luaL_checkint( L, ++stack );
|
||||
res = luaL_optint( L, ++stack, -1 );
|
||||
}
|
||||
|
||||
ucg_ud_t *ud = (ucg_ud_t *) lua_newuserdata( L, sizeof( ucg_ud_t ) );
|
||||
ucg_nodemcu_t *ext_ucg = &(ud->ucg);
|
||||
ud->font_ref = LUA_NOREF;
|
||||
ud->host_ref = host_ref;
|
||||
ext_ucg->hal = host ? (void *)(host->host) : NULL;
|
||||
|
||||
ucg_t *ucg = (ucg_t *)ext_ucg;
|
||||
|
||||
/* do a dummy init so that something usefull is part of the ucg structure */
|
||||
ucg_Init( ucg, ucg_dev_default_cb, ucg_ext_none, (ucg_com_fnptr)0 );
|
||||
|
||||
/* reset cursor position */
|
||||
ud->tx = 0;
|
||||
ud->ty = 0;
|
||||
ud->tdir = 0; /* default direction */
|
||||
|
||||
uint8_t i;
|
||||
for( i = 0; i < UCG_PIN_COUNT; i++ )
|
||||
ucg->pin_list[i] = UCG_PIN_VAL_NONE;
|
||||
|
||||
ud->dev_cb = device;
|
||||
ud->ext_cb = extension;
|
||||
if (res >= 0)
|
||||
ucg->pin_list[UCG_PIN_RST] = res;
|
||||
ucg->pin_list[UCG_PIN_CD] = dc;
|
||||
ucg->pin_list[UCG_PIN_CS] = cs;
|
||||
|
||||
/* set its metatable */
|
||||
luaL_getmetatable(L, "ucg.display");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
return 1;
|
||||
}
|
||||
#undef UCG_DISPLAY_TABLE_ENTRY
|
||||
#define UCG_DISPLAY_TABLE_ENTRY(binding, device, extension) \
|
||||
static int l ## binding( lua_State *L ) \
|
||||
{ \
|
||||
return ldisplay_hw_spi( L, device, extension ); \
|
||||
}
|
||||
//
|
||||
// Unroll the display table and insert binding functions.
|
||||
UCG_DISPLAY_TABLE
|
||||
//
|
||||
// ***************************************************************************
|
||||
|
||||
|
||||
|
||||
// Module function map
|
||||
static const LUA_REG_TYPE lucg_display_map[] =
|
||||
{
|
||||
{ LSTRKEY( "begin" ), LFUNCVAL( lucg_begin ) },
|
||||
{ LSTRKEY( "clearScreen" ), LFUNCVAL( lucg_clearScreen ) },
|
||||
{ LSTRKEY( "draw90Line" ), LFUNCVAL( lucg_draw90Line ) },
|
||||
{ LSTRKEY( "drawBox" ), LFUNCVAL( lucg_drawBox ) },
|
||||
{ LSTRKEY( "drawCircle" ), LFUNCVAL( lucg_drawCircle ) },
|
||||
{ LSTRKEY( "drawDisc" ), LFUNCVAL( lucg_drawDisc ) },
|
||||
{ LSTRKEY( "drawFrame" ), LFUNCVAL( lucg_drawFrame ) },
|
||||
{ LSTRKEY( "drawGlyph" ), LFUNCVAL( lucg_drawGlyph ) },
|
||||
{ LSTRKEY( "drawGradientBox" ), LFUNCVAL( lucg_drawGradientBox ) },
|
||||
{ LSTRKEY( "drawGradientLine" ), LFUNCVAL( lucg_drawGradientLine ) },
|
||||
{ LSTRKEY( "drawHLine" ), LFUNCVAL( lucg_drawHLine ) },
|
||||
{ LSTRKEY( "drawLine" ), LFUNCVAL( lucg_drawLine ) },
|
||||
{ LSTRKEY( "drawPixel" ), LFUNCVAL( lucg_drawPixel ) },
|
||||
{ LSTRKEY( "drawRBox" ), LFUNCVAL( lucg_drawRBox ) },
|
||||
{ LSTRKEY( "drawRFrame" ), LFUNCVAL( lucg_drawRFrame ) },
|
||||
{ LSTRKEY( "drawString" ), LFUNCVAL( lucg_drawString ) },
|
||||
{ LSTRKEY( "drawTetragon" ), LFUNCVAL( lucg_drawTetragon ) },
|
||||
{ LSTRKEY( "drawTriangle" ), LFUNCVAL( lucg_drawTriangle ) },
|
||||
{ LSTRKEY( "drawVLine" ), LFUNCVAL( lucg_drawVLine ) },
|
||||
{ LSTRKEY( "getFontAscent" ), LFUNCVAL( lucg_getFontAscent ) },
|
||||
{ LSTRKEY( "getFontDescent" ), LFUNCVAL( lucg_getFontDescent ) },
|
||||
{ LSTRKEY( "getHeight" ), LFUNCVAL( lucg_getHeight ) },
|
||||
{ LSTRKEY( "getStrWidth" ), LFUNCVAL( lucg_getStrWidth ) },
|
||||
{ LSTRKEY( "getWidth" ), LFUNCVAL( lucg_getWidth ) },
|
||||
{ LSTRKEY( "print" ), LFUNCVAL( lucg_print ) },
|
||||
{ LSTRKEY( "setClipRange" ), LFUNCVAL( lucg_setClipRange ) },
|
||||
{ LSTRKEY( "setColor" ), LFUNCVAL( lucg_setColor ) },
|
||||
{ LSTRKEY( "setFont" ), LFUNCVAL( lucg_setFont ) },
|
||||
{ LSTRKEY( "setFontMode" ), LFUNCVAL( lucg_setFontMode ) },
|
||||
{ LSTRKEY( "setFontPosBaseline" ), LFUNCVAL( lucg_setFontPosBaseline ) },
|
||||
{ LSTRKEY( "setFontPosBottom" ), LFUNCVAL( lucg_setFontPosBottom ) },
|
||||
{ LSTRKEY( "setFontPosCenter" ), LFUNCVAL( lucg_setFontPosCenter ) },
|
||||
{ LSTRKEY( "setFontPosTop" ), LFUNCVAL( lucg_setFontPosTop ) },
|
||||
{ LSTRKEY( "setMaxClipRange" ), LFUNCVAL( lucg_setMaxClipRange ) },
|
||||
{ LSTRKEY( "setPrintDir" ), LFUNCVAL( lucg_setPrintDir ) },
|
||||
{ LSTRKEY( "setPrintPos" ), LFUNCVAL( lucg_setPrintPos ) },
|
||||
{ LSTRKEY( "setRotate90" ), LFUNCVAL( lucg_setRotate90 ) },
|
||||
{ LSTRKEY( "setRotate180" ), LFUNCVAL( lucg_setRotate180 ) },
|
||||
{ LSTRKEY( "setRotate270" ), LFUNCVAL( lucg_setRotate270 ) },
|
||||
{ LSTRKEY( "setScale2x2" ), LFUNCVAL( lucg_setScale2x2 ) },
|
||||
{ LSTRKEY( "undoClipRange" ), LFUNCVAL( lucg_setMaxClipRange ) },
|
||||
{ LSTRKEY( "undoRotate" ), LFUNCVAL( lucg_undoRotate ) },
|
||||
{ LSTRKEY( "undoScale" ), LFUNCVAL( lucg_undoScale ) },
|
||||
|
||||
{ LSTRKEY( "__gc" ), LFUNCVAL( lucg_close_display ) },
|
||||
{ LSTRKEY( "__index" ), LROVAL ( lucg_display_map ) },
|
||||
{ LNILKEY, LNILVAL }
|
||||
};
|
||||
|
||||
static const LUA_REG_TYPE lucg_map[] =
|
||||
{
|
||||
#undef UCG_DISPLAY_TABLE_ENTRY
|
||||
#define UCG_DISPLAY_TABLE_ENTRY(binding, device, extension) { LSTRKEY( #binding ), LFUNCVAL ( l ## binding ) },
|
||||
UCG_DISPLAY_TABLE
|
||||
|
||||
// Register fonts
|
||||
#undef UCG_FONT_TABLE_ENTRY
|
||||
#define UCG_FONT_TABLE_ENTRY(font) { LSTRKEY( #font ), LUDATA( (void *)(ucg_ ## font) ) },
|
||||
UCG_FONT_TABLE
|
||||
|
||||
// Font modes
|
||||
{ LSTRKEY( "FONT_MODE_TRANSPARENT" ), LNUMVAL( UCG_FONT_MODE_TRANSPARENT ) },
|
||||
{ LSTRKEY( "FONT_MODE_SOLID" ), LNUMVAL( UCG_FONT_MODE_SOLID ) },
|
||||
|
||||
// Options for circle/ disc drawing
|
||||
{ LSTRKEY( "DRAW_UPPER_RIGHT" ), LNUMVAL( UCG_DRAW_UPPER_RIGHT ) },
|
||||
{ LSTRKEY( "DRAW_UPPER_LEFT" ), LNUMVAL( UCG_DRAW_UPPER_LEFT ) },
|
||||
{ LSTRKEY( "DRAW_LOWER_RIGHT" ), LNUMVAL( UCG_DRAW_LOWER_RIGHT ) },
|
||||
{ LSTRKEY( "DRAW_LOWER_LEFT" ), LNUMVAL( UCG_DRAW_LOWER_LEFT ) },
|
||||
{ LSTRKEY( "DRAW_ALL" ), LNUMVAL( UCG_DRAW_ALL ) },
|
||||
|
||||
{ LSTRKEY( "__metatable" ), LROVAL( lucg_map ) },
|
||||
{ LNILKEY, LNILVAL }
|
||||
};
|
||||
|
||||
int luaopen_ucg( lua_State *L )
|
||||
{
|
||||
luaL_rometatable(L, "ucg.display", (void *)lucg_display_map); // create metatable
|
||||
return 0;
|
||||
}
|
||||
|
||||
NODEMCU_MODULE(UCG, "ucg", lucg_map, luaopen_ucg);
|
|
@ -1,3 +1,5 @@
|
|||
COMPONENT_ADD_INCLUDEDIRS:=include
|
||||
# for u8x8
|
||||
CPPFLAGS+=-DU8X8_USE_PINS
|
||||
# for ucg
|
||||
CPPFLAGS+=-DUSE_PIN_LIST
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
#ifndef _UCG_NODEMCU_HAL_H
|
||||
#define _UCG_NODEMCU_HAL_H
|
||||
|
||||
#include "ucg.h"
|
||||
|
||||
|
||||
// extend standard ucg_t struct with info that's needed in the communication callbacks
|
||||
typedef struct {
|
||||
ucg_t ucg;
|
||||
void *hal;
|
||||
} ucg_nodemcu_t;
|
||||
|
||||
|
||||
int16_t ucg_com_nodemcu_hw_spi(ucg_t *ucg, int16_t msg, uint16_t arg, uint8_t *data);
|
||||
|
||||
#endif /* _UCG_NODEMCU_HAL_H */
|
|
@ -0,0 +1,215 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "platform.h"
|
||||
|
||||
#include "ucg_nodemcu_hal.h"
|
||||
|
||||
|
||||
// static variables containing info about the spi link
|
||||
// TODO: move to user space once available
|
||||
typedef struct {
|
||||
uint8_t host;
|
||||
spi_device_handle_t device;
|
||||
uint8_t last_dc;
|
||||
} hal_spi_t;
|
||||
|
||||
|
||||
// transfers with payload smaller than this should be done in
|
||||
// polling mode to save overhead
|
||||
#define SPI_TRANSFER_POLLING_TRESHOLD 16
|
||||
|
||||
static void send_byte( hal_spi_t *hal, uint8_t data ) {
|
||||
spi_transaction_t trans;
|
||||
memset( &trans, 0, sizeof( trans ) );
|
||||
trans.flags = SPI_TRANS_USE_TXDATA;
|
||||
trans.length = 8;
|
||||
trans.tx_data[0] = data;
|
||||
spi_device_polling_transmit( hal->device, &trans );
|
||||
}
|
||||
|
||||
|
||||
// send buffer in DMA'able RAM for caching data in bigger transfers
|
||||
#define SEND_BUFFER_SIZE (2*3 * 20)
|
||||
static DMA_ATTR uint8_t send_buffer[SEND_BUFFER_SIZE];
|
||||
|
||||
int16_t ucg_com_nodemcu_hw_spi(ucg_t *ucg, int16_t msg, uint16_t arg, uint8_t *data)
|
||||
{
|
||||
hal_spi_t *hal = ((ucg_nodemcu_t *)ucg)->hal;
|
||||
|
||||
switch(msg) {
|
||||
case UCG_COM_MSG_POWER_UP:
|
||||
/* "data" is a pointer to ucg_com_info_t structure with the following information: */
|
||||
/* ((ucg_com_info_t *)data)->serial_clk_speed value in nanoseconds */
|
||||
/* ((ucg_com_info_t *)data)->parallel_clk_speed value in nanoseconds */
|
||||
|
||||
/* setup pins */
|
||||
for (int idx = 0; idx < UCG_PIN_COUNT; idx++) {
|
||||
if (ucg->pin_list[idx] != UCG_PIN_VAL_NONE) {
|
||||
// configure pin as output
|
||||
gpio_config_t cfg;
|
||||
memset( (void *)&cfg, 0, sizeof( cfg ) );
|
||||
cfg.pin_bit_mask = 1ULL << ucg->pin_list[idx];
|
||||
cfg.mode = GPIO_MODE_OUTPUT;
|
||||
cfg.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||
cfg.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
cfg.intr_type = GPIO_INTR_DISABLE;
|
||||
gpio_config( &cfg );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// the hal member initially contains the spi host id
|
||||
int host = (int)hal;
|
||||
if (!(hal = malloc( sizeof ( hal_spi_t ) )))
|
||||
return 0;
|
||||
hal->host = host;
|
||||
((ucg_nodemcu_t *)ucg)->hal = hal;
|
||||
|
||||
// set up the spi device
|
||||
spi_device_interface_config_t config;
|
||||
memset( &config, 0, sizeof( config ) );
|
||||
|
||||
config.spics_io_num = -1; // CS is controlled by ucg gpio mechanism
|
||||
config.mode = 0;
|
||||
config.clock_speed_hz = 10000000;
|
||||
config.queue_size = 1;
|
||||
|
||||
spi_bus_add_device( hal->host, &config, &(hal->device) );
|
||||
|
||||
hal->last_dc = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case UCG_COM_MSG_POWER_DOWN:
|
||||
break;
|
||||
|
||||
case UCG_COM_MSG_DELAY:
|
||||
ets_delay_us(arg);
|
||||
break;
|
||||
|
||||
case UCG_COM_MSG_CHANGE_RESET_LINE:
|
||||
if (ucg->pin_list[UCG_PIN_RST] != UCG_PIN_VAL_NONE)
|
||||
gpio_set_level( ucg->pin_list[UCG_PIN_RST], arg );
|
||||
break;
|
||||
|
||||
case UCG_COM_MSG_CHANGE_CS_LINE:
|
||||
if ( ucg->pin_list[UCG_PIN_CS] != UCG_PIN_VAL_NONE )
|
||||
gpio_set_level( ucg->pin_list[UCG_PIN_CS], arg );
|
||||
break;
|
||||
|
||||
case UCG_COM_MSG_CHANGE_CD_LINE:
|
||||
gpio_set_level( ucg->pin_list[UCG_PIN_CD], arg );
|
||||
break;
|
||||
|
||||
case UCG_COM_MSG_SEND_BYTE:
|
||||
send_byte( hal, arg );
|
||||
break;
|
||||
|
||||
case UCG_COM_MSG_REPEAT_1_BYTE:
|
||||
{
|
||||
spi_transaction_t trans;
|
||||
memset( &trans, 0, sizeof( trans ) );
|
||||
trans.tx_buffer = send_buffer;
|
||||
while (arg > 0) {
|
||||
size_t idx;
|
||||
for (idx = 0; (idx < SEND_BUFFER_SIZE) && (arg > 0); idx++, arg--) {
|
||||
send_buffer[idx] = data[0];
|
||||
}
|
||||
trans.length = idx * 8;
|
||||
trans.rxlength = 0;
|
||||
if (idx < SPI_TRANSFER_POLLING_TRESHOLD) {
|
||||
spi_device_polling_transmit( hal->device, &trans );
|
||||
} else {
|
||||
spi_device_transmit( hal->device, &trans );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case UCG_COM_MSG_REPEAT_2_BYTES:
|
||||
{
|
||||
spi_transaction_t trans;
|
||||
memset( &trans, 0, sizeof( trans ) );
|
||||
trans.tx_buffer = send_buffer;
|
||||
while (arg > 0) {
|
||||
size_t idx;
|
||||
for (idx = 0; (idx < SEND_BUFFER_SIZE) && (arg > 0); idx += 2, arg--) {
|
||||
send_buffer[idx] = data[0];
|
||||
send_buffer[idx+1] = data[1];
|
||||
}
|
||||
trans.length = idx * 8;
|
||||
trans.rxlength = 0;
|
||||
if (idx < SPI_TRANSFER_POLLING_TRESHOLD) {
|
||||
spi_device_polling_transmit( hal->device, &trans );
|
||||
} else {
|
||||
spi_device_transmit( hal->device, &trans );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case UCG_COM_MSG_REPEAT_3_BYTES:
|
||||
{
|
||||
spi_transaction_t trans;
|
||||
memset( &trans, 0, sizeof( trans ) );
|
||||
trans.tx_buffer = send_buffer;
|
||||
while (arg > 0) {
|
||||
size_t idx;
|
||||
for (idx = 0; (idx < SEND_BUFFER_SIZE) && (arg > 0); idx += 3, arg--) {
|
||||
send_buffer[idx] = data[0];
|
||||
send_buffer[idx+1] = data[1];
|
||||
send_buffer[idx+2] = data[2];
|
||||
}
|
||||
trans.length = idx * 8;
|
||||
trans.rxlength = 0;
|
||||
if (idx < SPI_TRANSFER_POLLING_TRESHOLD) {
|
||||
spi_device_polling_transmit( hal->device, &trans );
|
||||
} else {
|
||||
spi_device_transmit( hal->device, &trans );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case UCG_COM_MSG_SEND_STR:
|
||||
{
|
||||
spi_transaction_t trans;
|
||||
memset( &trans, 0, sizeof( trans ) );
|
||||
trans.tx_buffer = send_buffer;
|
||||
while (arg > 0) {
|
||||
size_t len = arg > SEND_BUFFER_SIZE ? SEND_BUFFER_SIZE : arg;
|
||||
trans.length = len * 8;
|
||||
trans.rxlength = 0;
|
||||
memcpy( send_buffer, data, len );
|
||||
if (len < SPI_TRANSFER_POLLING_TRESHOLD) {
|
||||
spi_device_polling_transmit( hal->device, &trans );
|
||||
} else {
|
||||
spi_device_transmit( hal->device, &trans );
|
||||
}
|
||||
arg -= len;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case UCG_COM_MSG_SEND_CD_DATA_SEQUENCE:
|
||||
while (arg > 0) {
|
||||
if (*data != 0) {
|
||||
/* set the data line directly, ignore the setting from UCG_CFG_CD */
|
||||
if (*data == 1) {
|
||||
gpio_set_level( ucg->pin_list[UCG_PIN_CD], 0 );
|
||||
} else {
|
||||
gpio_set_level( ucg->pin_list[UCG_PIN_CD], 1 );
|
||||
}
|
||||
}
|
||||
data++;
|
||||
send_byte( hal, *data );
|
||||
data++;
|
||||
arg--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
COMPONENT_SRCDIRS:=ucg/src/clib .
|
||||
COMPONENT_ADD_INCLUDEDIRS:=ucg/src/clib
|
||||
CPPFLAGS+=-DUSE_PIN_LIST
|
|
@ -0,0 +1 @@
|
|||
Subproject commit e21641a6c1ddb0e71f7b9e01501fa739786c68b1
|
|
@ -0,0 +1,66 @@
|
|||
menu "Displays"
|
||||
depends on LUA_MODULE_UCG
|
||||
|
||||
config UCG_DISPLAY_HX8352C_18X240X400
|
||||
depends on LUA_MODULE_SPI
|
||||
bool "hx8352c_18x240x400_hw_spi"
|
||||
default "n"
|
||||
|
||||
config UCG_DISPLAY_ILI9163_18X128X128
|
||||
depends on LUA_MODULE_SPI
|
||||
bool "ili9163_18x128x128_hw_spi"
|
||||
default "n"
|
||||
|
||||
config UCG_DISPLAY_ILI9341_18X240X320
|
||||
depends on LUA_MODULE_SPI
|
||||
bool "ili9341_18x240x320_hw_spi"
|
||||
default "y"
|
||||
|
||||
config UCG_DISPLAY_ILI9486_18X320X480
|
||||
depends on LUA_MODULE_SPI
|
||||
bool "ili9486_18x320x480_hw_spi"
|
||||
default "n"
|
||||
|
||||
config UCG_DISPLAY_PCF8833_16X132X132
|
||||
depends on LUA_MODULE_SPI
|
||||
bool "pcf8833_16x132x132_hw_spi"
|
||||
default "n"
|
||||
|
||||
config UCG_DISPLAY_SEPS225_16X128X128_UNIVISION
|
||||
depends on LUA_MODULE_SPI
|
||||
bool "seps225_16x128x128_uvis_hw_spi"
|
||||
default "n"
|
||||
|
||||
config UCG_DISPLAY_SSD1351_18X128X128_ILSOFT
|
||||
depends on LUA_MODULE_SPI
|
||||
bool "ssd1351_18x128x128_hw_spi"
|
||||
default "n"
|
||||
|
||||
config UCG_DISPLAY_SSD1351_18X128X128_FT
|
||||
depends on LUA_MODULE_SPI
|
||||
bool "ssd1351_18x128x128_ft_hw_spi"
|
||||
default "n"
|
||||
|
||||
config UCG_DISPLAY_SSD1331_18X96X64_UNIVISION
|
||||
depends on LUA_MODULE_SPI
|
||||
bool "ssd1331_18x96x64_uvis_hw_spi"
|
||||
default "n"
|
||||
|
||||
config UCG_DISPLAY_ST7735_18X128X160
|
||||
depends on LUA_MODULE_SPI
|
||||
bool "st7735_18x128x160_hw_spi"
|
||||
default "y"
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Fonts"
|
||||
depends on LUA_MODULE_UCG
|
||||
|
||||
config UCG_FONT_SELECTION
|
||||
depends on LUA_MODULE_UCG
|
||||
string "Font list"
|
||||
default "font_7x13B_tr,font_helvB08_hr,font_helvB10_hr,font_helvB12_hr,font_helvB18_hr,font_ncenB24_tr,font_ncenR12_tr,font_ncenR14_hr"
|
||||
help
|
||||
Enter a comma-separated list of fonts.
|
||||
|
||||
endmenu
|
|
@ -0,0 +1,335 @@
|
|||
# ucg Module
|
||||
| Since | Origin / Contributor | Maintainer | Source |
|
||||
| :----- | :-------------------- | :---------- | :------ |
|
||||
| 2015-08-05 | [Oli Kraus](https://github.com/olikraus/ucglib), [Arnim Läuger](https://github.com/devsaurus) | [Arnim Läuger](https://github.com/devsaurus) | [ucglib](../../../component/ucg/)|
|
||||
|
||||
Ucglib is a graphics library developed at [olikraus/ucglib](https://github.com/olikraus/ucglib) with support for color TFT displays.
|
||||
|
||||
!!! note "BSD License for Ucglib Code"
|
||||
Universal 8bit Graphics Library (http://code.google.com/p/u8glib/)
|
||||
|
||||
Copyright (c) 2014, olikraus@gmail.com
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The NodeMCU firmware supports a subset of these:
|
||||
|
||||
- HX8352C
|
||||
- ILI9163
|
||||
- ILI9341
|
||||
- ILI9486
|
||||
- PCF8833
|
||||
- SEPS225
|
||||
- SSD1331
|
||||
- SSD1351
|
||||
- ST7735
|
||||
|
||||
This integration is based on [v1.5.2](https://github.com/olikraus/Ucglib_Arduino/releases/tag/v1.5.2).
|
||||
|
||||
## Overview
|
||||
|
||||
### 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 [GraphicsTest.lua](https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_examples/ucglib/GraphicsTest.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 ucglib's object oriented C++ API. Based on the ucg class, you create an object for your display type.
|
||||
|
||||
ILI9341 via SPI:
|
||||
```lua
|
||||
cs = 8 -- GPIO15, pull-down 10k to GND
|
||||
dc = 4 -- GPIO2
|
||||
res = 0 -- GPIO16, RES is optional YMMV
|
||||
disp = ucg.ili9341_18x240x320_hw_spi(cs, dc, res)
|
||||
```
|
||||
|
||||
This object provides all of ucglib's methods to control the display.
|
||||
Again, refer to [GraphicsTest.lua](https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_examples/ucglib/GraphicsTest.lua) to get an impression how this is achieved with Lua code. Visit the [ucglib homepage](https://github.com/olikraus/ucglib) for technical details.
|
||||
|
||||
### Display selection
|
||||
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 display table in [app/include/ucg_config.h](../../../app/include/ucg_config.h):
|
||||
```c
|
||||
#define UCG_DISPLAY_TABLE \
|
||||
UCG_DISPLAY_TABLE_ENTRY(ili9341_18x240x320_hw_spi, ucg_dev_ili9341_18x240x320, ucg_ext_ili9341_18) \
|
||||
UCG_DISPLAY_TABLE_ENTRY(st7735_18x128x160_hw_spi, ucg_dev_st7735_18x128x160, ucg_ext_st7735_18) \
|
||||
```
|
||||
|
||||
#### ESP32
|
||||
Enable the desired entries for SPI displays in ucg's sub-menu (run `make menuconfig`).
|
||||
|
||||
### Fonts
|
||||
ucglib comes with a wide range of fonts for small displays. Since they need to be compiled into the firmware image.
|
||||
|
||||
The procedure is different for ESP8266 and ESP32 platforms.
|
||||
|
||||
#### ESP8266
|
||||
|
||||
Add the desired fonts to the font table in [app/include/ucg_config.h](../../../app/include/ucg_config.h):
|
||||
```c
|
||||
#define UCG_FONT_TABLE \
|
||||
UCG_FONT_TABLE_ENTRY(font_7x13B_tr) \
|
||||
UCG_FONT_TABLE_ENTRY(font_helvB12_hr) \
|
||||
UCG_FONT_TABLE_ENTRY(font_helvB18_hr) \
|
||||
UCG_FONT_TABLE_ENTRY(font_ncenR12_tr) \
|
||||
UCG_FONT_TABLE_ENTRY(font_ncenR14_hr)
|
||||
```
|
||||
They will be available as `ucg.<font_name>` in Lua.
|
||||
|
||||
#### ESP32
|
||||
Add the desired fonts to the font selection sub-entry via `make menuconfig`.
|
||||
|
||||
## Display Drivers
|
||||
|
||||
Initialize a display via Hardware SPI.
|
||||
|
||||
- `hx8352c_18x240x400_hw_spi()`
|
||||
- `ili9163_18x128x128_hw_spi()`
|
||||
- `ili9341_18x240x320_hw_spi()`
|
||||
- `ili9486_18x320x480_hw_spi()`
|
||||
- `pcf8833_16x132x132_hw_spi()`
|
||||
- `seps225_16x128x128_uvis_hw_spi()`
|
||||
- `ssd1351_18x128x128_hw_spi()`
|
||||
- `ssd1351_18x128x128_ft_hw_spi()`
|
||||
- `ssd1331_18x96x64_uvis_hw_spi()`
|
||||
- `st7735_18x128x160_hw_spi()`
|
||||
|
||||
#### Syntax
|
||||
`ucg.st7735_18x128x160_hw_spi(bus, cs, dc[, res])`
|
||||
|
||||
#### Parameters
|
||||
- `bus` SPI master bus
|
||||
- `cs` GPIO pin for /CS
|
||||
- `dc` GPIO pin for DC
|
||||
- `res` GPIO pin for /RES, none if omitted
|
||||
|
||||
#### Returns
|
||||
ucg 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, RES is optional YMMV
|
||||
bus = 1
|
||||
spi.setup(bus, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8, 0)
|
||||
-- we won't be using the HSPI /CS line, so disable it again
|
||||
gpio.mode(8, gpio.INPUT, gpio.PULLUP)
|
||||
|
||||
disp = ucg.st7735_18x128x160_hw_spi(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 = ucg.st7735_18x128x160_hw_spi(bus, cs, dc, res)
|
||||
```
|
||||
|
||||
## Constants
|
||||
Constants for various functions.
|
||||
|
||||
`ucg.FONT_MODE_TRANSPARENT`, `ucg.FONT_MODE_SOLID`, `ucg.DRAW_UPPER_RIGHT`,
|
||||
`ucg.DRAW_UPPER_LEFT`, `ucg.DRAW_LOWER_RIGHT`, `ucg.DRAW_LOWER_LEFT`, `ucg.DRAW_ALL`
|
||||
|
||||
`ucg.font_7x13B_tr`, ...
|
||||
|
||||
# ucg.disp Sub-Module
|
||||
|
||||
## ucg.disp:begin()
|
||||
See [ucglib begin()](https://github.com/olikraus/ucglib/wiki/reference#begin).
|
||||
|
||||
## ucg.disp:clearScreen()
|
||||
See [ucglib clearScreen()](https://github.com/olikraus/ucglib/wiki/reference#clearscreen).
|
||||
|
||||
## ucg.disp:draw90Line()
|
||||
See [ucglib draw90Line()](https://github.com/olikraus/ucglib/wiki/reference#draw90line).
|
||||
|
||||
## ucg.disp:drawBox()
|
||||
See [ucglib drawBox()](https://github.com/olikraus/ucglib/wiki/reference#drawbox).
|
||||
|
||||
## ucg.disp:drawCircle()
|
||||
See [ucglib drawCircle()](https://github.com/olikraus/ucglib/wiki/reference#drawcircle).
|
||||
|
||||
## ucg.disp:drawDisc()
|
||||
See [ucglib drawDisc()](https://github.com/olikraus/ucglib/wiki/reference#drawdisc).
|
||||
|
||||
## ucg.disp:drawFrame()
|
||||
See [ucglib drawFrame()](https://github.com/olikraus/ucglib/wiki/reference#drawframe).
|
||||
|
||||
## ucg.disp:drawGlyph()
|
||||
See [ucglib drawGlyph()](https://github.com/olikraus/ucglib/wiki/reference#drawglyph).
|
||||
|
||||
## ucg.disp:drawGradientBox()
|
||||
See [ucglib drawGradientBox()](https://github.com/olikraus/ucglib/wiki/reference#drawgradientbox).
|
||||
|
||||
## ucg.disp:drawGradientLine()
|
||||
See [ucglib drawGradientLine()](https://github.com/olikraus/ucglib/wiki/reference#drawgradientline).
|
||||
|
||||
## ucg.disp:drawHLine()
|
||||
See [ucglib drawHLine()](https://github.com/olikraus/ucglib/wiki/reference#drawhline).
|
||||
|
||||
## ucg.disp:drawLine()
|
||||
See [ucglib drawLine()](https://github.com/olikraus/ucglib/wiki/reference#drawline).
|
||||
|
||||
## ucg.disp:drawPixel()
|
||||
See [ucglib drawPixel()](https://github.com/olikraus/ucglib/wiki/reference#drawpixel).
|
||||
|
||||
## ucg.disp:drawRBox()
|
||||
See [ucglib drawRBox()](https://github.com/olikraus/ucglib/wiki/reference#drawrbox).
|
||||
|
||||
## ucg.disp:drawRFrame()
|
||||
See [ucglib drawRFrame()](https://github.com/olikraus/ucglib/wiki/reference#drawrframe).
|
||||
|
||||
## ucg.disp:drawString()
|
||||
See [ucglib drawString()](https://github.com/olikraus/ucglib/wiki/reference#drawstring).
|
||||
|
||||
## ucg.disp:drawTetragon()
|
||||
See [ucglib drawTetragon()](https://github.com/olikraus/ucglib/wiki/reference#drawtetragon).
|
||||
|
||||
## ucg.disp:drawTriangle()
|
||||
See [ucglib drawTriangle()](https://github.com/olikraus/ucglib/wiki/reference#drawrtiangle).
|
||||
|
||||
## ucg.disp:drawVLine()
|
||||
See [ucglib drawVline()](https://github.com/olikraus/ucglib/wiki/reference#drawvline).
|
||||
|
||||
## ucg.disp:getFontAscent()
|
||||
See [ucglib getFontAscent()](https://github.com/olikraus/ucglib/wiki/reference#getfontascent).
|
||||
|
||||
## ucg.disp:getFontDescent()
|
||||
See [ucglib getFontDescent()](https://github.com/olikraus/ucglib/wiki/reference#getfontdescent).
|
||||
|
||||
## ucg.disp:getHeight()
|
||||
See [ucglib getHeight()](https://github.com/olikraus/ucglib/wiki/reference#getheight).
|
||||
|
||||
## ucg.disp:getStrWidth()
|
||||
See [ucglib getStrWidth()](https://github.com/olikraus/ucglib/wiki/reference#getstrwidth).
|
||||
|
||||
## ucg.disp:getWidth()
|
||||
See [ucglib getWidth()](https://github.com/olikraus/ucglib/wiki/reference#getwidth).
|
||||
|
||||
## ucg.disp:print()
|
||||
See [ucglib print()](https://github.com/olikraus/ucglib/wiki/reference#print).
|
||||
|
||||
## ucg.disp:setClipRange()
|
||||
See [ucglib setClipRange()](https://github.com/olikraus/ucglib/wiki/reference#setcliprange).
|
||||
|
||||
## ucg.disp:setColor()
|
||||
See [ucglib setColor()](https://github.com/olikraus/ucglib/wiki/reference#setcolor).
|
||||
|
||||
## ucg.disp:setFont()
|
||||
Define a ucg font for the glyph and string drawing functions. They are available as `ucg.<font_name>` in Lua.
|
||||
|
||||
#### Syntax
|
||||
`disp:setFont(font)`
|
||||
|
||||
#### Parameters
|
||||
`font` constant to identify pre-compiled font
|
||||
|
||||
#### Returns
|
||||
`nil`
|
||||
|
||||
#### Example
|
||||
```lua
|
||||
disp:setFont(ucg.font_7x13B_tr)
|
||||
```
|
||||
|
||||
#### See also
|
||||
[ucglib setFont()](https://github.com/olikraus/ucglib/wiki/reference#setfont)
|
||||
|
||||
## ucg.disp:setFontMode()
|
||||
See [ucglib setFontMode()](https://github.com/olikraus/ucglib/wiki/reference#setfontmode).
|
||||
|
||||
## ucg.disp:setFontPosBaseline()
|
||||
See [ucglib setFontPosBaseline()](https://github.com/olikraus/ucglib/wiki/reference#setfontposbaseline).
|
||||
|
||||
## ucg.disp:setFontPosBottom()
|
||||
See [ucglib setFontPosBottom()](https://github.com/olikraus/ucglib/wiki/reference#setfontposbottom).
|
||||
|
||||
## ucg.disp:setFontPosCenter()
|
||||
See [ucglib setFontPosCenter()](https://github.com/olikraus/ucglib/wiki/reference#setfontposcenter).
|
||||
|
||||
## ucg.disp:setFontPosTop()
|
||||
See [ucglib setFontPosTop()](https://github.com/olikraus/ucglib/wiki/reference#setfontpostop).
|
||||
|
||||
## ucg.disp:setMaxClipRange()
|
||||
See [ucglib setMaxClipRange()](https://github.com/olikraus/ucglib/wiki/reference#setmaxcliprange).
|
||||
|
||||
## ucg.disp:setPrintDir()
|
||||
See [ucglib setPrintDir()](https://github.com/olikraus/ucglib/wiki/reference#setprintdir).
|
||||
|
||||
## ucg.disp:setPrintPos()
|
||||
See [ucglib setPrintPos()](https://github.com/olikraus/ucglib/wiki/reference#setprintpos).
|
||||
|
||||
## ucg.disp:setRotate90()
|
||||
See [ucglib setRotate90()](https://github.com/olikraus/ucglib/wiki/reference#setrotate90).
|
||||
|
||||
## ucg.disp:setRotate180()
|
||||
See [ucglib setRotate180()](https://github.com/olikraus/ucglib/wiki/reference#setrotate180).
|
||||
|
||||
## ucg.disp:setRotate270()
|
||||
See [ucglib setRotate270()](https://github.com/olikraus/ucglib/wiki/reference#setrotate270).
|
||||
|
||||
## ucg.disp:setScale2x2()
|
||||
See [ucglib setScale2x2()](https://github.com/olikraus/ucglib/wiki/reference#setscale2x2).
|
||||
|
||||
## ucg.disp:undoClipRange()
|
||||
See [ucglib undoClipRange()](https://github.com/olikraus/ucglib/wiki/reference#undocliprange).
|
||||
|
||||
## ucg.disp:undoRotate()
|
||||
See [ucglib undoRotate()](https://github.com/olikraus/ucglib/wiki/reference#undorotate).
|
||||
|
||||
## ucg.disp:undoScale()
|
||||
See [ucglib undoScale()](https://github.com/olikraus/ucglib/wiki/reference#undoscale).
|
|
@ -33,7 +33,6 @@ function M.run()
|
|||
bit.rshift(lcg_rnd() * (disp:getHeight()-20), 8) + 20
|
||||
)
|
||||
|
||||
tmr.wdclr()
|
||||
end
|
||||
|
||||
print("...done")
|
||||
|
|
|
@ -1,19 +1,16 @@
|
|||
-- setup SPI and connect display
|
||||
function init_spi_display()
|
||||
-- Hardware SPI CLK = GPIO14
|
||||
-- Hardware SPI MOSI = GPIO13
|
||||
-- Hardware SPI MISO = GPIO12 (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
|
||||
-- pins can be assigned freely to available GPIOs
|
||||
local sclk = 19
|
||||
local mosi = 23
|
||||
local cs = 22
|
||||
local dc = 16
|
||||
local res = 17
|
||||
|
||||
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
|
||||
local bus = spi.master(spi.HSPI, {sclk=sclk, mosi=mosi})
|
||||
|
||||
-- initialize the matching driver for your display
|
||||
-- see app/include/ucg_config.h
|
||||
--disp = ucg.ili9341_18x240x320_hw_spi(cs, dc, res)
|
||||
disp = ucg.st7735_18x128x160_hw_spi(cs, dc, res)
|
||||
--disp = ucg.ili9341_18x240x320_hw_spi(bus, cs, dc, res)
|
||||
disp = ucg.st7735_18x128x160_hw_spi(bus, cs, dc, res)
|
||||
end
|
||||
|
||||
|
||||
|
@ -50,11 +47,6 @@ function lcg_rnd()
|
|||
end
|
||||
|
||||
|
||||
function millis()
|
||||
local usec = tmr.now()
|
||||
return usec/1000
|
||||
end
|
||||
|
||||
function set_clip_range()
|
||||
local x, y, w, h
|
||||
w = bit.band(lcg_rnd(), 31)
|
||||
|
@ -118,6 +110,12 @@ disp:begin(ucg.FONT_MODE_TRANSPARENT)
|
|||
disp:setFont(ucg.font_ncenR14_hr)
|
||||
disp:clearScreen()
|
||||
|
||||
milli = 0
|
||||
function millis()
|
||||
milli = milli + 30
|
||||
return milli
|
||||
end
|
||||
|
||||
tmr.register(0, 3000, tmr.ALARM_AUTO, function() loop() end)
|
||||
tmr.start(0)
|
||||
t = tmr.create()
|
||||
t:register(5000, tmr.ALARM_AUTO, function() loop() end)
|
||||
t:start()
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
-- setup SPI and connect display
|
||||
function init_spi_display()
|
||||
-- Hardware SPI CLK = GPIO14
|
||||
-- Hardware SPI MOSI = GPIO13
|
||||
-- Hardware SPI MISO = GPIO12 (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
|
||||
-- pins can be assigned freely to available GPIOs
|
||||
local sclk = 19
|
||||
local mosi = 23
|
||||
local cs = 22
|
||||
local dc = 16
|
||||
local res = 17
|
||||
|
||||
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
|
||||
disp = ucg.ili9341_18x240x320_hw_spi(cs, dc, res)
|
||||
local bus = spi.master(spi.HSPI, {sclk=sclk, mosi=mosi})
|
||||
|
||||
--disp = ucg.ili9341_18x240x320_hw_spi(bus, cs, dc, res)
|
||||
disp = ucg.st7735_18x128x160_hw_spi(bus, cs, dc, res)
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
-- setup SPI and connect display
|
||||
function init_spi_display()
|
||||
-- Hardware SPI CLK = GPIO14
|
||||
-- Hardware SPI MOSI = GPIO13
|
||||
-- Hardware SPI MISO = GPIO12 (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
|
||||
-- pins can be assigned freely to available GPIOs
|
||||
local sclk = 19
|
||||
local mosi = 23
|
||||
local cs = 22
|
||||
local dc = 16
|
||||
local res = 17
|
||||
|
||||
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
|
||||
disp = ucg.st7735_18x128x160_hw_spi(cs, dc, res)
|
||||
local bus = spi.master(spi.HSPI, {sclk=sclk, mosi=mosi})
|
||||
|
||||
--disp = ucg.ili9341_18x240x320_hw_spi(bus, cs, dc, res)
|
||||
disp = ucg.st7735_18x128x160_hw_spi(bus, cs, dc, res)
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -52,5 +52,6 @@ pages:
|
|||
- 'tmr': 'en/modules/tmr.md'
|
||||
- 'u8g2': 'en/modules/u8g2.md'
|
||||
- 'uart': 'en/modules/uart.md'
|
||||
- 'ucg': 'en/modules/ucg.md'
|
||||
- 'wifi': 'en/modules/wifi.md'
|
||||
- 'ws2812': 'en/modules/ws2812.md'
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
#!/usr/bin/perl -w
|
||||
|
||||
my (@displays, @font_selection);
|
||||
|
||||
# scan provided header file for CONFIG_UCG_DISPLAY and CONFIG_UCG_FONT_SELECTION entries
|
||||
while (<STDIN>) {
|
||||
if (/^\s*#\s*define\s+CONFIG_UCG_DISPLAY_(\S+)\s+1/) {
|
||||
push(@displays, lc($1));
|
||||
}
|
||||
if (/^\s*#\s*define\s+CONFIG_UCG_FONT_SELECTION\s+"([^"]+)"/) {
|
||||
@font_selection = split(/,/, $1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
print << 'HEADER';
|
||||
|
||||
#ifndef _UCG_CONFIG_H
|
||||
#define _UCG_CONFIG_H
|
||||
|
||||
HEADER
|
||||
|
||||
|
||||
print << 'DISPLAYS';
|
||||
|
||||
#define UCG_DISPLAY_TABLE_ENTRY(binding, device, extension)
|
||||
|
||||
DISPLAYS
|
||||
|
||||
print("#define UCG_DISPLAY_TABLE \\\n");
|
||||
foreach my $display (@displays) {
|
||||
$display =~ /(\S+_\d\d)x/;
|
||||
my $extension = $1;
|
||||
print(" UCG_DISPLAY_TABLE_ENTRY(${display}_hw_spi, ucg_dev_${display}, ucg_ext_${extension}) \\\n");
|
||||
}
|
||||
print("\n");
|
||||
|
||||
|
||||
print << 'FONTS';
|
||||
|
||||
#define UCG_FONT_TABLE_ENTRY(font)
|
||||
|
||||
#define UCG_FONT_TABLE \
|
||||
FONTS
|
||||
|
||||
foreach my $font (@font_selection) {
|
||||
print(" UCG_FONT_TABLE_ENTRY($font) \\\n");
|
||||
}
|
||||
|
||||
|
||||
print << 'FOOTER';
|
||||
|
||||
#endif /* _UCG_CONFIG_H */
|
||||
FOOTER
|
Loading…
Reference in New Issue