From 1bc156e4d15b64970a7652877f65ceabb00d9e29 Mon Sep 17 00:00:00 2001 From: devsaurus Date: Thu, 16 Jul 2015 23:23:43 +0200 Subject: [PATCH] move display constructors into template-based functions + uniform generaration + addition of further displays - slight unneccesary heap allocation when display drivers are included but not used --- app/include/u8g_config.h | 28 ++- app/modules/u8g.c | 217 +++++++--------------- lua_examples/u8glib/u8g_bitmaps.lua | 2 +- lua_examples/u8glib/u8g_graphics_test.lua | 2 +- lua_examples/u8glib/u8g_rotation.lua | 2 +- 5 files changed, 92 insertions(+), 159 deletions(-) diff --git a/app/include/u8g_config.h b/app/include/u8g_config.h index 63986be0..152b2bf3 100644 --- a/app/include/u8g_config.h +++ b/app/include/u8g_config.h @@ -2,20 +2,38 @@ #define __U8G_CONFIG_H__ +// *************************************************************************** // Configure U8glib fonts -// add a U8G_FONT_TABLE_ENTRY for each font you want to compile into the image +// +// Add a U8G_FONT_TABLE_ENTRY for each font you want to compile into the image #define U8G_FONT_TABLE_ENTRY(font) #define U8G_FONT_TABLE \ U8G_FONT_TABLE_ENTRY(font_6x10) \ U8G_FONT_TABLE_ENTRY(font_chikita) #undef U8G_FONT_TABLE_ENTRY +// +// *************************************************************************** +// *************************************************************************** // Enable display drivers -#define U8G_SSD1306_128x64_I2C -//#define U8G_SSD1306_128x64_SPI -// untested -#undef U8G_PCD8544_84x48 +// +// Uncomment the U8G_DISPLAY_TABLE_ENTRY for the device(s) you want to +// compile into the firmware. +// Stick to the assignments to *_I2C and *_SPI tables. +// +// I2C based displays go into here: +#define U8G_DISPLAY_TABLE_ENTRY(device, display) +#define U8G_DISPLAY_TABLE_I2C \ + U8G_DISPLAY_TABLE_ENTRY(ssd1306_128x64_i2c, ssd1306_128x64) + +// SPI based displays go into here: +#define U8G_DISPLAY_TABLE_SPI \ + U8G_DISPLAY_TABLE_ENTRY(ssd1306_128x64_hw_spi, ssd1306_128x64) \ +// U8G_DISPLAY_TABLE_ENTRY(pcd8544_84x48_hw_spi, pcd8544_84x48) +#undef U8G_DISPLAY_TABLE_ENTRY +// +// *************************************************************************** #endif /* __U8G_CONFIG_H__ */ diff --git a/app/modules/u8g.c b/app/modules/u8g.c index db55e75c..7df5fefe 100644 --- a/app/modules/u8g.c +++ b/app/modules/u8g.c @@ -980,148 +980,68 @@ static int lu8g_close_display( lua_State *L ) } -// device constructors - -uint8_t u8g_dev_ssd1306_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); -// Lua: object = u8g.ssd1306_128x64_i2c( i2c_addr ) -static int lu8g_ssd1306_128x64_i2c( lua_State *L ) -{ - unsigned addr = luaL_checkinteger( L, 1 ); - - if (addr == 0) - return luaL_error( L, "i2c address required" ); - - lu8g_userdata_t *lud = (lu8g_userdata_t *) lua_newuserdata( L, sizeof( lu8g_userdata_t ) ); - - lud->u8g.i2c_addr = (uint8_t)addr; - - // Don't use the pre-defined device structure for u8g_dev_ssd1306_128x64_i2c here - // Reason: linking the pre-defined structures allocates RAM for the device/comm structure - // *before* the display is constructed (especially the page buffers) - // this consumes heap even when the device is not used at all -#if 0 - // build device entry - lud->dev = (u8g_dev_t){ u8g_dev_ssd1306_128x64_fn, &(lud->pb), U8G_COM_SSD_I2C }; - - // populate and allocate page buffer - // constants taken from u8g_dev_ssd1306_128x64.c: - // PAGE_HEIGHT - // | Height - // | | WIDTH - // | | | - lud->pb = (u8g_pb_t){ { 8, 64, 0, 0, 0 }, 128, NULL }; - // - if ((lud->pb.buf = (void *)c_zalloc(lud->pb.width)) == NULL) - return luaL_error( L, "out of memory" ); - - // and finally init device using specific interface init function - u8g_InitI2C( LU8G, &(lud->dev), U8G_I2C_OPT_NONE); -#else - u8g_InitI2C( LU8G, &u8g_dev_ssd1306_128x64_i2c, U8G_I2C_OPT_NONE); -#endif - - - // set its metatable - luaL_getmetatable(L, "u8g.display"); - lua_setmetatable(L, -2); - - return 1; -} - -// Lua: object = u8g.ssd1306_128x64_spi( cs, dc, [res] ) -static int lu8g_ssd1306_128x64_spi( lua_State *L ) -{ - unsigned cs = luaL_checkinteger( L, 1 ); - if (cs == 0) - return luaL_error( L, "CS pin required" ); - unsigned dc = luaL_checkinteger( L, 2 ); - if (dc == 0) - return luaL_error( L, "D/C pin required" ); - unsigned res = luaL_optinteger( L, 3, U8G_PIN_NONE ); - - lu8g_userdata_t *lud = (lu8g_userdata_t *) lua_newuserdata( L, sizeof( lu8g_userdata_t ) ); - - // Don't use the pre-defined device structure for u8g_dev_ssd1306_128x64_spi here - // Reason: linking the pre-defined structures allocates RAM for the device/comm structure - // *before* the display is constructed (especially the page buffers) - // this consumes heap even when the device is not used at all -#if 0 - // build device entry - lud->dev = (u8g_dev_t){ u8g_dev_ssd1306_128x64_fn, &(lud->pb), U8G_COM_HW_SPI }; - - // populate and allocate page buffer - // constants taken from u8g_dev_ssd1306_128x64.c: - // PAGE_HEIGHT - // | Height - // | | WIDTH - // | | | - lud->pb = (u8g_pb_t){ { 8, 64, 0, 0, 0 }, 128, NULL }; - // - if ((lud->pb.buf = (void *)c_zalloc(lud->pb.width)) == NULL) - return luaL_error( L, "out of memory" ); - - // and finally init device using specific interface init function - u8g_InitHWSPI( LU8G, &(lud->dev), cs, dc, res ); -#else - u8g_InitHWSPI( LU8G, &u8g_dev_ssd1306_128x64_hw_spi, cs, dc, res ); -#endif - - - // set its metatable - luaL_getmetatable(L, "u8g.display"); - lua_setmetatable(L, -2); - - return 1; -} - -uint8_t u8g_dev_pcd8544_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); -// Lua: object = u8g.pcd8544_84x48( sce, dc, res ) -static int lu8g_pcd8544_84x48( lua_State *L ) -{ - unsigned sce = luaL_checkinteger( L, 1 ); - if (sce == 0) - return luaL_error( L, "SCE pin required" ); - unsigned dc = luaL_checkinteger( L, 2 ); - if (dc == 0) - return luaL_error( L, "D/C pin required" ); - unsigned res = luaL_checkinteger( L, 3 ); - if (res == 0) - return luaL_error( L, "RES pin required" ); - - lu8g_userdata_t *lud = (lu8g_userdata_t *) lua_newuserdata( L, sizeof( lu8g_userdata_t ) ); - - // Don't use the pre-defined device structure for u8g_dev_pcd8544_84x48_hw_spi here - // Reason: linking the pre-defined structures allocates RAM for the device/comm structure - // *before* the display is constructed (especially the page buffers) - // this consumes heap even when the device is not used at all -#if 0 - // build device entry - lud->dev = (u8g_dev_t){ u8g_dev_pcd8544_fn, &(lud->pb), U8G_COM_HW_SPI }; - - // populate and allocate page buffer - // constants taken from u8g_dev_pcd8544_84x48.c: - // PAGE_HEIGHT - // | Height - // | | WIDTH - // | | | - lud->pb = (u8g_pb_t){ { 8, 48, 0, 0, 0 }, 84, NULL }; - // - if ((lud->pb.buf = (void *)c_zalloc(lud->pb.width)) == NULL) - return luaL_error( L, "out of memory" ); - - // and finally init device using specific interface init function - u8g_InitHWSPI( LU8G, &(lud->dev), sce, dc, res ); -#else - u8g_InitHWSPI( LU8G, &u8g_dev_pcd8544_84x48_hw_spi, sce, dc, res ); -#endif - - - // set its metatable - luaL_getmetatable(L, "u8g.display"); - lua_setmetatable(L, -2); - - return 1; -} +// *************************************************************************** +// Device constructors +// +// +// I2C based devices will use this function template to implement the Lua binding. +#undef U8G_DISPLAY_TABLE_ENTRY +#define U8G_DISPLAY_TABLE_ENTRY(device, display) \ + uint8_t u8g_dev_ ## display ## _fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); \ + static int lu8g_ ## device( lua_State *L ) \ + { \ + unsigned addr = luaL_checkinteger( L, 1 ); \ + \ + if (addr == 0) \ + return luaL_error( L, "i2c address required" ); \ + \ + lu8g_userdata_t *lud = (lu8g_userdata_t *) lua_newuserdata( L, sizeof( lu8g_userdata_t ) ); \ + \ + lud->u8g.i2c_addr = (uint8_t)addr; \ + \ + u8g_InitI2C( LU8G, &u8g_dev_ ## device, U8G_I2C_OPT_NONE); \ + \ + /* set its metatable */ \ + luaL_getmetatable(L, "u8g.display"); \ + lua_setmetatable(L, -2); \ + \ + return 1; \ + } +// +// Unroll the display table and insert binding functions for I2C based displays. +U8G_DISPLAY_TABLE_I2C +// +// +// +// SPI based devices will use this function template to implement the Lua binding. +#undef U8G_DISPLAY_TABLE_ENTRY +#define U8G_DISPLAY_TABLE_ENTRY(device, display) \ + uint8_t u8g_dev_ ## display ## _fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); \ + static int lu8g_ ## device( lua_State *L ) \ + { \ + unsigned cs = luaL_checkinteger( L, 1 ); \ + if (cs == 0) \ + return luaL_error( L, "CS pin required" ); \ + unsigned dc = luaL_checkinteger( L, 2 ); \ + if (dc == 0) \ + return luaL_error( L, "D/C pin required" ); \ + unsigned res = luaL_optinteger( L, 3, U8G_PIN_NONE ); \ + \ + lu8g_userdata_t *lud = (lu8g_userdata_t *) lua_newuserdata( L, sizeof( lu8g_userdata_t ) ); \ + \ + u8g_InitHWSPI( LU8G, &u8g_dev_ ## device, cs, dc, res ); \ + \ + /* set its metatable */ \ + luaL_getmetatable(L, "u8g.display"); \ + lua_setmetatable(L, -2); \ + \ + return 1; \ + } +// +// Unroll the display table and insert binding functions for SPI based displays. +U8G_DISPLAY_TABLE_SPI +// +// *************************************************************************** // Module function map @@ -1189,15 +1109,10 @@ static const LUA_REG_TYPE lu8g_display_map[] = const LUA_REG_TYPE lu8g_map[] = { -#ifdef U8G_SSD1306_128x64_I2C - { LSTRKEY( "ssd1306_128x64_i2c" ), LFUNCVAL ( lu8g_ssd1306_128x64_i2c ) }, -#endif -#ifdef U8G_SSD1306_128x64_I2C - { LSTRKEY( "ssd1306_128x64_spi" ), LFUNCVAL ( lu8g_ssd1306_128x64_spi ) }, -#endif -#ifdef U8G_PCD8544_84x48 - { LSTRKEY( "pcd8544_84x48" ), LFUNCVAL ( lu8g_pcd8544_84x48 ) }, -#endif +#undef U8G_DISPLAY_TABLE_ENTRY +#define U8G_DISPLAY_TABLE_ENTRY(device, display) { LSTRKEY( #device ), LFUNCVAL ( lu8g_ ##device ) }, + U8G_DISPLAY_TABLE_I2C + U8G_DISPLAY_TABLE_SPI #if LUA_OPTIMIZE_MEMORY > 0 diff --git a/lua_examples/u8glib/u8g_bitmaps.lua b/lua_examples/u8glib/u8g_bitmaps.lua index 4ac8a60f..30a67020 100644 --- a/lua_examples/u8glib/u8g_bitmaps.lua +++ b/lua_examples/u8glib/u8g_bitmaps.lua @@ -20,7 +20,7 @@ function init_spi_display() local res = 0 -- GPIO16 spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8, 0) - disp = u8g.ssd1306_128x64_spi(cs, dc, res) + disp = u8g.ssd1306_128x64_hw_spi(cs, dc, res) end diff --git a/lua_examples/u8glib/u8g_graphics_test.lua b/lua_examples/u8glib/u8g_graphics_test.lua index 1985b461..41b22ab3 100644 --- a/lua_examples/u8glib/u8g_graphics_test.lua +++ b/lua_examples/u8glib/u8g_graphics_test.lua @@ -20,7 +20,7 @@ function init_spi_display() local res = 0 -- GPIO16 spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8, 0) - disp = u8g.ssd1306_128x64_spi(cs, dc, res) + disp = u8g.ssd1306_128x64_hw_spi(cs, dc, res) end diff --git a/lua_examples/u8glib/u8g_rotation.lua b/lua_examples/u8glib/u8g_rotation.lua index 81d81e6f..df74733a 100644 --- a/lua_examples/u8glib/u8g_rotation.lua +++ b/lua_examples/u8glib/u8g_rotation.lua @@ -20,7 +20,7 @@ function init_spi_display() local res = 0 -- GPIO16 spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8, 0) - disp = u8g.ssd1306_128x64_spi(cs, dc, res) + disp = u8g.ssd1306_128x64_hw_spi(cs, dc, res) end