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
[submodule "app/u8g2lib/u8g2"]
path = app/u8g2lib/u8g2
url = https://github.com/olikraus/U8g2_Arduino.git
......@@ -308,11 +308,11 @@ endif
$(OBJODIR)/%.o: %.c
@mkdir -p $(OBJODIR);
@mkdir -p $(dir $@);
$(CC) $(if $(findstring $<,$(DSRCS)),$(DFLAGS),$(CFLAGS)) $(COPTS_$(*F)) -o $@ -c $<
$(OBJODIR)/%.d: %.c
@mkdir -p $(OBJODIR);
@mkdir -p $(dir $@);
@echo DEPEND: $(CC) -M $(CFLAGS) $<
@set -e; rm -f $@; \
$(CC) -M $(CFLAGS) $< > $@.$$$$; \
......@@ -331,22 +331,22 @@ $(OBJODIR)/%.d: %.cpp
rm -f $@.$$$$
$(OBJODIR)/%.o: %.s
@mkdir -p $(OBJODIR);
@mkdir -p $(dir $@);
$(CC) $(CFLAGS) -o $@ -c $<
$(OBJODIR)/%.d: %.s
@mkdir -p $(OBJODIR); \
@mkdir -p $(dir $@); \
set -e; rm -f $@; \
$(CC) -M $(CFLAGS) $< > $@.$$$$; \
sed 's,\($*\.o\)[ :]*,$(OBJODIR)/\1 $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
$(OBJODIR)/%.o: %.S
@mkdir -p $(OBJODIR);
@mkdir -p $(dir $@);
$(CC) $(CFLAGS) -D__ASSEMBLER__ -o $@ -c $<
$(OBJODIR)/%.d: %.S
@mkdir -p $(OBJODIR); \
@mkdir -p $(dir $@); \
set -e; rm -f $@; \
$(CC) -M $(CFLAGS) $< > $@.$$$$; \
sed 's,\($*\.o\)[ :]*,$(OBJODIR)/\1 $@ : ,g' < $@.$$$$ > $@; \
......
......@@ -21,7 +21,7 @@ ifndef PDIR # {
GEN_IMAGES= eagle.app.v6.out
GEN_BINS= eagle.app.v6.bin
OPT_MKTARGETS := coap crypto dht http mqtt pcm sjson sqlite3 tsl2561 websocket
OPT_MKLIBTARGETS := u8g ucg
OPT_MKLIBTARGETS := u8g2 ucg
SEL_MKTARGETS := $(shell $(CC) -E -dM include/user_modules.h | sed -n '/^\#define LUA_USE_MODULES_/{s/.\{24\}\(.*\)/\L\1/; p}')
OPT_SEL_MKLIBTARGETS := $(foreach tgt,$(OPT_MKLIBTARGETS),$(findstring $(tgt), $(SEL_MKTARGETS)))
OPT_SEL_MKTARGETS := $(foreach tgt,$(OPT_MKTARGETS),$(findstring $(tgt), $(SEL_MKTARGETS))) \
......
#ifndef _U8G2_DISPLAYS_H
#define _U8G2_DISPLAYS_H
#define U8G2_DISPLAY_TABLE_ENTRY(function, binding)
// ***************************************************************************
// Enable display drivers
//
// Uncomment the U8G2_DISPLAY_TABLE_ENTRY for the device(s) you want to
// compile into the firmware.
// Stick to the assignments to *_I2C and *_SPI tables.
#ifndef U8G2_DISPLAY_TABLE_I2C_EXTRA
// I2C based displays go into here:
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1610_i2c_ea_dogxl160_f, uc1610_i2c_ea_dogxl160) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1325_i2c_nhd_128x64_f, ssd1325_i2c_nhd_128x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_i2c_64x48_er_f, ssd1306_i2c_64x48_er) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1608_i2c_erc24064_f, uc1608_i2c_erc24064) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7588_i2c_jlx12864_f, st7588_i2c_jlx12864) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1309_i2c_128x64_noname0_f, ssd1309_i2c_128x64_noname0) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1611_i2c_ea_dogxl240_f, uc1611_i2c_ea_dogxl240) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1305_i2c_128x32_noname_f, ssd1305_i2c_128x32_noname) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_i2c_128x32_univision_f, ssd1306_i2c_128x32_univision) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1608_i2c_240x128_f, uc1608_i2c_240x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ld7032_i2c_60x32_f, ld7032_i2c_60x32) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1611_i2c_ew50850_f, uc1611_i2c_ew50850) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1604_i2c_jlx19264_f, uc1604_i2c_jlx19264) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1601_i2c_128x32_f, uc1601_i2c_128x32) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1106_i2c_128x64_vcomh0_f, sh1106_i2c_128x64_vcomh0) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_i2c_96x16_er_f, ssd1306_i2c_96x16_er) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1106_i2c_128x64_noname_f, sh1106_i2c_128x64_noname) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_i2c_128x64_vcomh0_f, ssd1306_i2c_128x64_vcomh0) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_i2c_128x64_noname_f, ssd1306_i2c_128x64_noname) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1309_i2c_128x64_noname2_f, ssd1309_i2c_128x64_noname2) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1611_i2c_ea_dogm240_f, uc1611_i2c_ea_dogm240) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1327_i2c_seeed_96x96_f, ssd1327_i2c_seeed_96x96) \
#define U8G2_DISPLAY_TABLE_I2C \
U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_i2c_128x64_noname_f, ssd1306_i2c_128x64_noname) \
#else
// I2C displays can be defined in an external file.
#define U8G2_DISPLAY_TABLE_I2C \
U8G2_DISPLAY_TABLE_I2C_EXTRA
#endif
#ifndef U8G2_DISPLAY_TABLE_SPI_EXTRA
// SPI based displays go into here:
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1606_172x72_f, ssd1606_172x72) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1608_240x128_f, uc1608_240x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7565_erc12864_f, st7565_erc12864) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1309_128x64_noname0_f, ssd1309_128x64_noname0) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1601_128x32_f, uc1601_128x32) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1608_erc24064_f, uc1608_erc24064) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7565_lm6059_f, st7565_lm6059) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1611_ea_dogxl240_f, uc1611_ea_dogxl240) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7565_nhd_c12864_f, st7565_nhd_c12864) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_128x64_vcomh0_f, ssd1306_128x64_vcomh0) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1305_128x32_noname_f, ssd1305_128x32_noname) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_max7219_32x8_f, max7219_32x8) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ls013b7dh03_128x128_f, ls013b7dh03_128x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_il3820_v2_296x128_f, il3820_v2_296x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1610_ea_dogxl160_f, uc1610_ea_dogxl160) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1611_ea_dogm240_f, uc1611_ea_dogm240) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1604_jlx19264_f, uc1604_jlx19264) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7920_s_192x32_f, st7920_s_192x32) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1325_nhd_128x64_f, ssd1325_nhd_128x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_128x64_noname_f, ssd1306_128x64_noname) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sed1520_122x32_f, sed1520_122x32) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7565_ea_dogm128_f, st7565_ea_dogm128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ld7032_60x32_f, ld7032_60x32) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1607_200x200_f, ssd1607_200x200) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1309_128x64_noname2_f, ssd1309_128x64_noname2) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1106_128x64_noname_f, sh1106_128x64_noname) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_128x32_univision_f, ssd1306_128x32_univision) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7920_s_128x64_f, st7920_s_128x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7565_64128n_f, st7565_64128n) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1701_ea_dogs102_f, uc1701_ea_dogs102) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1611_ew50850_f, uc1611_ew50850) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1322_nhd_256x64_f, ssd1322_nhd_256x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7565_ea_dogm132_f, st7565_ea_dogm132) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1329_128x96_noname_f, ssd1329_128x96_noname) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7565_zolen_128x64_f, st7565_zolen_128x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st75256_jlx256128_f, st75256_jlx256128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_96x16_er_f, ssd1306_96x16_er) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ist3020_erc19264_f, ist3020_erc19264) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7588_jlx12864_f, st7588_jlx12864) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1327_seeed_96x96_f, ssd1327_seeed_96x96) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st75256_jlx172104_f, st75256_jlx172104) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7565_nhd_c12832_f, st7565_nhd_c12832) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_64x48_er_f, ssd1306_64x48_er) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_pcf8812_96x65_f, pcf8812_96x65) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7567_pi_132x64_f, st7567_pi_132x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7567_jlx12864_f, st7567_jlx12864) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_pcd8544_84x48_f, pcd8544_84x48) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1106_128x64_vcomh0_f, sh1106_128x64_vcomh0) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_nt7534_tg12864r_f, nt7534_tg12864r) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1701_mini12864_f, uc1701_mini12864) \
#define U8G2_DISPLAY_TABLE_SPI \
U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_128x64_noname_f, ssd1306_128x64_noname) \
#else
// SPI displays can be defined in an external file.
#define U8G2_DISPLAY_TABLE_SPI \
U8G2_DISPLAY_TABLE_SPI_EXTRA
#endif
//
// ***************************************************************************
#endif /* _U8G2_DISPLAYS_H */
#ifndef _U8G2_FONTS_H
#define _U8G2_FONTS_H
#define U8G2_FONT_TABLE_ENTRY(font)
// ***************************************************************************
// Configure U8glib fonts
//
#ifndef U8G2_FONT_TABLE_EXTRA
//
// Add a U8G2_FONT_TABLE_ENTRY for each font you want to compile into the image
#define U8G2_FONT_TABLE \
U8G2_FONT_TABLE_ENTRY(font_6x10_tf) \
U8G2_FONT_TABLE_ENTRY(font_unifont_t_symbols) \
#else
//
// The font table can be defined in an external file.
#define U8G2_FONT_TABLE \
U8G2_FONT_TABLE_EXTRA
#endif
// ***************************************************************************
#endif /* _U8G2_FONTS_H */
#ifndef __U8G_CONFIG_H__
#define __U8G_CONFIG_H__
// ***************************************************************************
// Configure U8glib fonts
//
// 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
//
// 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:
// U8G_DISPLAY_TABLE_ENTRY(sh1106_128x64_i2c) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1306_128x32_i2c) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1306_128x64_i2c) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1306_64x48_i2c) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1309_128x64_i2c) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1327_96x96_gr_i2c) \
// U8G_DISPLAY_TABLE_ENTRY(uc1611_dogm240_i2c) \
// U8G_DISPLAY_TABLE_ENTRY(uc1611_dogxl240_i2c) \
#define U8G_DISPLAY_TABLE_ENTRY(device)
#define U8G_DISPLAY_TABLE_I2C \
U8G_DISPLAY_TABLE_ENTRY(ssd1306_128x64_i2c) \
// SPI based displays go into here:
// U8G_DISPLAY_TABLE_ENTRY(ld7032_60x32_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(pcd8544_84x48_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(pcf8812_96x65_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(sh1106_128x64_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1306_128x32_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1306_128x64_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1306_64x48_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1309_128x64_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1322_nhd31oled_bw_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1322_nhd31oled_gr_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1325_nhd27oled_bw_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1325_nhd27oled_gr_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1327_96x96_gr_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1351_128x128_332_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1351_128x128gh_332_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1351_128x128_hicolor_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1351_128x128gh_hicolor_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1353_160x128_332_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(ssd1353_160x128_hicolor_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(st7565_64128n_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(st7565_dogm128_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(st7565_dogm132_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(st7565_lm6059_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(st7565_lm6063_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(st7565_nhd_c12832_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(st7565_nhd_c12864_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(uc1601_c128032_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(uc1608_240x128_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(uc1608_240x64_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(uc1610_dogxl160_bw_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(uc1610_dogxl160_gr_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(uc1611_dogm240_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(uc1611_dogxl240_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(uc1701_dogs102_hw_spi) \
// U8G_DISPLAY_TABLE_ENTRY(uc1701_mini12864_hw_spi) \
#define U8G_DISPLAY_TABLE_SPI \
U8G_DISPLAY_TABLE_ENTRY(ssd1306_128x64_hw_spi) \
#undef U8G_DISPLAY_TABLE_ENTRY
// Special display device to provide run-length encoded framebuffer contents
// to a Lua callback:
//#define U8G_DISPLAY_FB_RLE
//
// ***************************************************************************
#endif /* __U8G_CONFIG_H__ */
......@@ -64,8 +64,8 @@
//#define LUA_USE_MODULES_TLS
#define LUA_USE_MODULES_TMR
//#define LUA_USE_MODULES_TSL2561
//#define LUA_USE_MODULES_U8G
#define LUA_USE_MODULES_UART
//#define LUA_USE_MODULES_U8G2
//#define LUA_USE_MODULES_UCG
//#define LUA_USE_MODULES_WEBSOCKET
#define LUA_USE_MODULES_WIFI
......
......@@ -43,7 +43,7 @@ INCLUDES += -I ./
INCLUDES += -I ../libc
INCLUDES += -I ../coap
INCLUDES += -I ../mqtt
INCLUDES += -I ../u8glib
INCLUDES += -I ../u8g2lib/u8g2/src/clib
INCLUDES += -I ../ucglib
INCLUDES += -I ../lua
INCLUDES += -I ../pcm
......
This diff is collapsed.
This diff is collapsed.
/*
Functions for integrating U8glib into the nodemcu platform.
*/
#include "lauxlib.h"
#include "platform.h"
#include "c_stdlib.h"
#include "u8g.h"
#include "u8g_glue.h"
// ------------------------------------------------------------
// comm functions
//
#define I2C_CMD_MODE 0x000
#define I2C_DATA_MODE 0x040
#define ESP_I2C_ID 0
static uint8_t do_i2c_start(uint8_t id, uint8_t sla)
{
platform_i2c_send_start( id );
// ignore return value -> tolerate missing ACK
platform_i2c_send_address( id, sla, PLATFORM_I2C_DIRECTION_TRANSMITTER );
return 1;
}
static uint8_t u8g_com_esp8266_ssd_start_sequence(struct _lu8g_userdata_t *lu8g)
{
/* are we requested to set the a0 state? */
if ( lu8g->u8g.pin_list[U8G_PI_SET_A0] == 0 )
return 1;
/* setup bus, might be a repeated start */
if ( do_i2c_start( ESP_I2C_ID, lu8g->i2c_addr ) == 0 )
return 0;
if ( lu8g->u8g.pin_list[U8G_PI_A0_STATE] == 0 )
{
// ignore return value -> tolerate missing ACK
if ( platform_i2c_send_byte( ESP_I2C_ID, I2C_CMD_MODE ) == 0 )
; //return 0;
}
else
{
platform_i2c_send_byte( ESP_I2C_ID, I2C_DATA_MODE );
}
lu8g->u8g.pin_list[U8G_PI_SET_A0] = 0;
return 1;
}
static void lu8g_digital_write( struct _lu8g_userdata_t *lu8g, uint8_t pin_index, uint8_t value )
{
uint8_t pin;
pin = lu8g->u8g.pin_list[pin_index];
if ( pin != U8G_PIN_NONE )
platform_gpio_write( pin, value );
}
void u8g_Delay(u8g_t *u8g, uint16_t msec)
{
struct _lu8g_userdata_t *lu8g = (struct _lu8g_userdata_t *)u8g;
const uint16_t chunk = 50;
if (lu8g->use_delay == 0)
return;
while (msec > chunk)
{
os_delay_us( chunk*1000 );
msec -= chunk;
}
if (msec > 0)
os_delay_us( msec*1000 );
}
void u8g_MicroDelay(void)
{
os_delay_us( 1 );
}
void u8g_10MicroDelay(void)
{
os_delay_us( 10 );
}
uint8_t u8g_com_esp8266_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr)
{
struct _lu8g_userdata_t *lu8g = (struct _lu8g_userdata_t *)u8g;
switch(msg)
{
case U8G_COM_MSG_STOP:
break;
case U8G_COM_MSG_INIT:
// we assume that the SPI interface was already initialized
// just care for the /CS and D/C pins
lu8g_digital_write( lu8g, U8G_PI_CS, PLATFORM_GPIO_HIGH );
platform_gpio_mode( lu8g->u8g.pin_list[U8G_PI_CS], PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT );
platform_gpio_mode( lu8g->u8g.pin_list[U8G_PI_A0], PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT );
break;
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
lu8g_digital_write( lu8g, U8G_PI_A0, arg_val == 0 ? PLATFORM_GPIO_LOW : PLATFORM_GPIO_HIGH );
break;
case U8G_COM_MSG_CHIP_SELECT:
if (arg_val == 0)
{
/* disable */
lu8g_digital_write( lu8g, U8G_PI_CS, PLATFORM_GPIO_HIGH );
}
else
{
/* enable */
lu8g_digital_write( lu8g, U8G_PI_CS, PLATFORM_GPIO_LOW );
}
break;
case U8G_COM_MSG_RESET:
if ( lu8g->u8g.pin_list[U8G_PI_RESET] != U8G_PIN_NONE )
lu8g_digital_write( lu8g, U8G_PI_RESET, arg_val == 0 ? PLATFORM_GPIO_LOW : PLATFORM_GPIO_HIGH );
break;
case U8G_COM_MSG_WRITE_BYTE:
platform_spi_send( 1, 8, arg_val );
break;
case U8G_COM_MSG_WRITE_SEQ:
case U8G_COM_MSG_WRITE_SEQ_P:
{
register uint8_t *ptr = arg_ptr;
while( arg_val > 0 )
{
platform_spi_send( 1, 8, *ptr++ );
arg_val--;
}
}
break;
}
return 1;
}
uint8_t u8g_com_esp8266_ssd_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr)
{
struct _lu8g_userdata_t *lu8g = (struct _lu8g_userdata_t *)u8g;
switch(msg)
{
case U8G_COM_MSG_INIT:
// we assume that the i2c bus was already initialized
//u8g_i2c_init(u8g->pin_list[U8G_PI_I2C_OPTION]);
break;
case U8G_COM_MSG_STOP:
break;
case U8G_COM_MSG_RESET:
/* Currently disabled, but it could be enable. Previous restrictions have been removed */
/* u8g_com_arduino_digital_write(u8g, U8G_PI_RESET, arg_val); */
break;
case U8G_COM_MSG_CHIP_SELECT:
lu8g->u8g.pin_list[U8G_PI_A0_STATE] = 0;
lu8g->u8g.pin_list[U8G_PI_SET_A0] = 1; /* force a0 to set again, also forces start condition */
if ( arg_val == 0 )
{
/* disable chip, send stop condition */
platform_i2c_send_stop( ESP_I2C_ID );
}
else
{
/* enable, do nothing: any byte writing will trigger the i2c start */
}
break;
case U8G_COM_MSG_WRITE_BYTE:
//u8g->pin_list[U8G_PI_SET_A0] = 1;
if ( u8g_com_esp8266_ssd_start_sequence(lu8g) == 0 )
return platform_i2c_send_stop( ESP_I2C_ID ), 0;
// ignore return value -> tolerate missing ACK
if ( platform_i2c_send_byte( ESP_I2C_ID, arg_val) == 0 )
; //return platform_i2c_send_stop( ESP_I2C_ID ), 0;
// platform_i2c_send_stop( ESP_I2C_ID );
break;
case U8G_COM_MSG_WRITE_SEQ:
case U8G_COM_MSG_WRITE_SEQ_P:
//u8g->pin_list[U8G_PI_SET_A0] = 1;
if ( u8g_com_esp8266_ssd_start_sequence(lu8g) == 0 )
return platform_i2c_send_stop( ESP_I2C_ID ), 0;
{
register uint8_t *ptr = arg_ptr;
while( arg_val > 0 )
{
// ignore return value -> tolerate missing ACK
if ( platform_i2c_send_byte( ESP_I2C_ID, *ptr++) == 0 )
; //return platform_i2c_send_stop( ESP_I2C_ID ), 0;
arg_val--;
}
}
// platform_i2c_send_stop( ESP_I2C_ID );
break;
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
lu8g->u8g.pin_list[U8G_PI_A0_STATE] = arg_val;
lu8g->u8g.pin_list[U8G_PI_SET_A0] = 1; /* force a0 to set again */
break;
}
return 1;
}
// ***************************************************************************
// Generic framebuffer device and RLE comm driver
//
uint8_t u8g_dev_gen_fb_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg)
{
switch(msg)
{
case U8G_DEV_MSG_PAGE_FIRST:
// tell comm driver to start new framebuffer
u8g_SetChipSelect(u8g, dev, 1);
break;
case U8G_DEV_MSG_PAGE_NEXT:
{
u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem);
if ( u8g_pb_WriteBuffer(pb, u8g, dev) == 0 )
return 0;
}
break;
}
return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg);
}
static int bit_at( uint8_t *buf, int line, int x )
{
uint8_t byte = buf[x];
return buf[x] & (1 << line) ? 1 : 0;
}
struct _lu8g_fbrle_item
{
uint8_t start_x;
uint8_t len;
};
struct _lu8g_fbrle_line
{
uint8_t num_valid;
struct _lu8g_fbrle_item items[0];
};
uint8_t u8g_com_esp8266_fbrle_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr)
{
struct _lu8g_userdata_t *lud = (struct _lu8g_userdata_t *)u8g;
switch(msg)
{
case U8G_COM_MSG_INIT:
// allocate memory -> done
// init buffer
break;
case U8G_COM_MSG_CHIP_SELECT:
if (arg_val == 1) {
// new frame starts
if (lud->cb_ref != LUA_NOREF) {
// fire callback with nil argument
lua_State *L = lua_getstate();
lua_rawgeti( L, LUA_REGISTRYINDEX, lud->cb_ref );
lua_pushnil( L );
lua_call( L, 1, 0 );
}
}
break;
case U8G_COM_MSG_WRITE_SEQ:
case U8G_COM_MSG_WRITE_SEQ_P:
{
uint8_t xwidth = u8g->pin_list[U8G_PI_EN];
size_t fbrle_line_size = sizeof( struct _lu8g_fbrle_line ) + sizeof( struct _lu8g_fbrle_item ) * (xwidth/2);
int num_lines = arg_val / (xwidth/8);
uint8_t *buf = (uint8_t *)arg_ptr;
struct _lu8g_fbrle_line *fbrle_line;
if (!(fbrle_line = (struct _lu8g_fbrle_line *)c_malloc( fbrle_line_size ))) {
break;
}
for (int line = 0; line < num_lines; line++) {
int start_run = -1;
fbrle_line->num_valid = 0;
for (int x = 0; x < xwidth; x++) {
if (bit_at( buf, line, x ) == 0) {
if (start_run >= 0) {
// inside run, end it and enter result
fbrle_line->items[fbrle_line->num_valid].start_x = start_run;
fbrle_line->items[fbrle_line->num_valid++].len = x - start_run;
//NODE_ERR( " line: %d x: %d len: %d\n", line, start_run, x - start_run );
start_run = -1;
}
} else {
if (start_run < 0) {
// outside run, start it
start_run = x;
}
}
if (fbrle_line->num_valid >= xwidth/2) break;
}
// active run?
if (start_run >= 0 && fbrle_line->num_valid < xwidth/2) {
fbrle_line->items[fbrle_line->num_valid].start_x = start_run;
fbrle_line->items[fbrle_line->num_valid++].len = xwidth - start_run;
}
// line done, trigger callback
if (lud->cb_ref != LUA_NOREF) {
lua_State *L = lua_getstate();
lua_rawgeti( L, LUA_REGISTRYINDEX, lud->cb_ref );
lua_pushlstring( L, (const char *)fbrle_line, fbrle_line_size );
lua_call( L, 1, 0 );
}
}
c_free( fbrle_line );
}
break;
}
return 1;
}
#ifndef _U8G_GLUE_H_
#define _U8G_GLUE_H_
#include "u8g.h"
struct _lu8g_userdata_t
{
u8g_t u8g;
uint8_t i2c_addr;
uint8_t use_delay;
int cb_ref;
};
typedef struct _lu8g_userdata_t lu8g_userdata_t;
// shorthand macro for the u8g structure inside the userdata
#define LU8G (&(lud->u8g))
uint8_t u8g_com_esp8266_fbrle_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
uint8_t u8g_dev_gen_fb_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg);
#endif
......@@ -43,6 +43,7 @@ INCLUDES += -I ./
INCLUDES += -I ../spiffs
INCLUDES += -I ../libc
INCLUDES += -I ../lua
INCLUDES += -I ../u8g2lib/u8g2/src/clib
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
#include <string.h>
#include "c_stdlib.h"
#include "platform.h"
#define U8X8_USE_PINS
#include "u8x8_nodemcu_hal.h"
uint8_t u8x8_gpio_and_delay_nodemcu(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint32_t temp;
switch(msg)
{
case U8X8_MSG_GPIO_AND_DELAY_INIT: // called once during init phase of u8g2/u8x8
// can be used to setup pins
for (int idx = 0; idx < U8X8_PIN_OUTPUT_CNT; idx++) {
if (u8x8->pins[idx] != U8X8_PIN_NONE) {
// configure pin as output
if (idx == U8X8_PIN_I2C_CLOCK || idx == U8X8_PIN_I2C_DATA) {
platform_gpio_mode( u8x8->pins[idx], PLATFORM_GPIO_OPENDRAIN, PLATFORM_GPIO_PULLUP );
} else {
platform_gpio_mode( u8x8->pins[idx], PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT );
}
}
}
break;
case U8X8_MSG_DELAY_NANO: // delay arg_int * 1 nano second
os_delay_us( 1 );
break;
case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds
temp = arg_int * 100;
temp /= 1000;
os_delay_us( temp > 0 ? temp : 1 );
break;
case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds
os_delay_us( arg_int * 10 );
break;
case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second
os_delay_us( arg_int * 1000 );
break;
case U8X8_MSG_DELAY_I2C: // arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHz
temp = 5000 / arg_int; // arg_int=1: delay by 5us, arg_int = 4: delay by 1.25us
temp /= 1000;
os_delay_us( temp > 0 ? temp : 1 );
break;
case U8X8_MSG_GPIO_D0: // D0 or SPI clock pin: Output level in arg_int
//case U8X8_MSG_GPIO_SPI_CLOCK:
break;
case U8X8_MSG_GPIO_D1: // D1 or SPI data pin: Output level in arg_int
//case U8X8_MSG_GPIO_SPI_DATA:
break;
case U8X8_MSG_GPIO_D2: // D2 pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_D3: // D3 pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_D4: // D4 pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_D5: // D5 pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_D6: // D6 pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_D7: // D7 pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_E: // E/WR pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_CS: // CS (chip select) pin: Output level in arg_int
platform_gpio_write( u8x8_GetPinValue( u8x8, msg ), arg_int );
break;
case U8X8_MSG_GPIO_DC: // DC (data/cmd, A0, register select) pin: Output level in arg_int
platform_gpio_write( u8x8_GetPinValue( u8x8, msg ), arg_int );
break;
case U8X8_MSG_GPIO_RESET: // Reset pin: Output level in arg_int
if (u8x8_GetPinValue( u8x8, msg ) != U8X8_PIN_NONE)
platform_gpio_write( u8x8_GetPinValue(u8x8, msg), arg_int );
break;
case U8X8_MSG_GPIO_CS1: // CS1 (chip select) pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_CS2: // CS2 (chip select) pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_I2C_CLOCK: // arg_int=0: Output low at I2C clock pin
// arg_int=1: Input dir with pullup high for I2C clock pin
// for SW comm routine
platform_gpio_write( u8x8_GetPinValue( u8x8, msg ), arg_int );
break;
case U8X8_MSG_GPIO_I2C_DATA: // arg_int=0: Output low at I2C data pin
// arg_int=1: Input dir with pullup high for I2C data pin
// for SW comm routine
platform_gpio_write( u8x8_GetPinValue( u8x8, msg ), arg_int );
break;
case U8X8_MSG_GPIO_MENU_SELECT:
case U8X8_MSG_GPIO_MENU_NEXT:
case U8X8_MSG_GPIO_MENU_PREV:
case U8X8_MSG_GPIO_MENU_HOME:
u8x8_SetGPIOResult( u8x8, /* get menu select pin state */ 0 );
break;
default:
u8x8_SetGPIOResult( u8x8, 1 ); // default return value
break;
}
return 1;
}
// static variables containing info about the i2c link
// TODO: move to user space in u8x8_t once available
typedef struct {
uint8_t id;
} hal_i2c_t;
uint8_t u8x8_byte_nodemcu_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t *data;
hal_i2c_t *hal = ((u8g2_nodemcu_t *)u8x8)->hal;
switch(msg) {
case U8X8_MSG_BYTE_SEND:
if (hal->id == 0) {
data = (uint8_t *)arg_ptr;
while( arg_int > 0 ) {
platform_i2c_send_byte( 0, *data );
data++;
arg_int--;
}
} else {
// invalid id
return 0;
}
break;
case U8X8_MSG_BYTE_INIT:
{
// the hal member initially contains the i2c id
int id = (int)hal;
if (!(hal = c_malloc( sizeof ( hal_i2c_t ) )))
return 0;
hal->id = id;
((u8g2_nodemcu_t *)u8x8)->hal = hal;
}
break;
case U8X8_MSG_BYTE_SET_DC:
break;
case U8X8_MSG_BYTE_START_TRANSFER:
if (hal->id == 0) {
platform_i2c_send_start( 0 );
platform_i2c_send_address( 0, u8x8_GetI2CAddress(u8x8), PLATFORM_I2C_DIRECTION_TRANSMITTER );
} else {
// invalid id
return 0;
}
break;
case U8X8_MSG_BYTE_END_TRANSFER:
if (hal->id == 0) {
platform_i2c_send_stop( 0 );
} else {
// invalid id
return 0;
}
break;
default:
return 0;
}
return 1;
}
// static variables containing info about the spi link
// TODO: move to user space in u8x8_t once available
typedef struct {
uint8_t host;
//spi_device_handle_t device;
uint8_t last_dc;
struct {
uint8_t *data;
size_t size, used;
} buffer;
} hal_spi_t;
static void flush_buffer_spi( hal_spi_t *hal )
{
if (hal->buffer.used > 0) {
platform_spi_blkwrite( hal->host, hal->buffer.used, hal->buffer.data );
hal->buffer.used = 0;
}
}
uint8_t u8x8_byte_nodemcu_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
hal_spi_t *hal = ((u8g2_nodemcu_t *)u8x8)->hal;
switch(msg) {
case U8X8_MSG_BYTE_INIT:
{
/* disable chipselect */
u8x8_gpio_SetCS( u8x8, u8x8->display_info->chip_disable_level );
// the hal member initially contains the spi host id
int host = (int)hal;
if (!(hal = c_malloc( sizeof ( hal_spi_t ) )))
return 0;
hal->host = host;
((u8g2_nodemcu_t *)u8x8)->hal = hal;
hal->last_dc = 0;
}
break;
case U8X8_MSG_BYTE_SET_DC:
if (hal->last_dc != arg_int)
flush_buffer_spi( hal );
u8x8_gpio_SetDC( u8x8, arg_int );
hal->last_dc = arg_int;
break;
case U8X8_MSG_BYTE_START_TRANSFER:
hal->buffer.size = 256;
if (!(hal->buffer.data = (uint8_t *)c_malloc( hal->buffer.size )))
return 0;
hal->buffer.used = 0;
u8x8_gpio_SetCS( u8x8, u8x8->display_info->chip_enable_level );
break;
case U8X8_MSG_BYTE_SEND:
if (!hal->buffer.data)
return 0;
while (hal->buffer.size - hal->buffer.used < arg_int) {
hal->buffer.size *= 2;
uint8_t *tmp;
if (!(tmp = (uint8_t *)c_malloc( hal->buffer.size ))) {
c_free( hal->buffer.data );
hal->buffer.data = NULL;
return 0;
}
os_memcpy( tmp, hal->buffer.data, hal->buffer.used );
c_free( hal->buffer.data );
hal->buffer.data = tmp;
}
os_memcpy( hal->buffer.data + hal->buffer.used, arg_ptr, arg_int );
hal->buffer.used += arg_int;
break;
case U8X8_MSG_BYTE_END_TRANSFER:
if (!hal->buffer.data)
return 0;
flush_buffer_spi( hal );
u8x8_gpio_SetCS( u8x8, u8x8->display_info->chip_disable_level );
c_free( hal->buffer.data );
break;
default:
return 0;
}
return 1;
}
#ifndef _U8X8_NODEMCU_HAL_H
#define _U8X8_NODEMCU_HAL_H
#include "u8g2.h"
// extend standard u8g2_t struct with info that's needed in the communication callbacks
typedef struct {
u8g2_t u8g2;
void *hal;
// elements for the overlay display driver
struct {
u8x8_msg_cb hardware_display_cb, template_display_cb;
int rfb_cb_ref;
uint8_t fb_update_ongoing;
} overlay;
} u8g2_nodemcu_t;
uint8_t u8x8_gpio_and_delay_nodemcu(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
uint8_t u8x8_byte_nodemcu_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
uint8_t u8x8_byte_nodemcu_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
#endif /* _U8X8_NODEMCU_HAL_H */
......@@ -12,7 +12,7 @@
# a generated lib/image xxx.a ()
#
ifndef PDIR
GEN_LIBS = libu8glib.a
GEN_LIBS = libu8g2lib.a
endif
STD_CFLAGS=-std=gnu11 -Wimplicit
......@@ -24,7 +24,7 @@ STD_CFLAGS=-std=gnu11 -Wimplicit
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#DEFINES +=
DEFINES += -DU8X8_USE_PINS
#############################################################
# Recursion Magic - Don't touch this!!
......@@ -38,9 +38,13 @@ STD_CFLAGS=-std=gnu11 -Wimplicit
# Required for each makefile to inherit from the parent
#
CSRCS := $(wildcard u8g2/src/clib/*.c *.c)
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
INCLUDES += -I u8g2/src/clib
INCLUDES += -I ../libc
INCLUDES += -I ../lua
INCLUDES += -I ../platform
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
Subproject commit 7f2fc42af3d01fdfe2cc19320bdcfe693dd2b20d
// Note: This file is intended to be shared between esp8266 and esp32 platform
#include "u8x8.h"
#include "lauxlib.h"
#include "u8x8_nodemcu_hal.h"
#include "c_stdlib.h"
static const u8x8_display_info_t u8x8_fbrle_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 0,
/* pre_chip_disable_wait_ns = */ 0,
/* reset_pulse_width_ms = */ 0,
/* post_reset_wait_ms = */ 0,
/* sda_setup_time_ns = */ 0,
/* sck_pulse_width_ns = */ 0,
/* sck_clock_hz = */ 0,
/* spi_mode = */ 0,
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 0,
/* write_pulse_width_ns = */ 0,
/* tile_width = */ 16,
/* tile_hight = */ 8,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 128,
/* pixel_height = */ 64
};
static int bit_at( uint8_t *buf, int line, int x )
{
return buf[x] & (1 << line) ? 1 : 0;
}
struct fbrle_item
{
uint8_t start_x;
uint8_t len;
};
struct fbrle_line
{
uint8_t num_valid;
struct fbrle_item items[0];
};
static uint8_t u8x8_d_fbrle(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
u8g2_nodemcu_t *ext_u8g2 = (u8g2_nodemcu_t *)u8x8;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
// forward to template display driver
return ext_u8g2->overlay.template_display_cb(u8x8, msg, arg_int, arg_ptr);
case U8X8_MSG_DISPLAY_INIT:
//u8x8_d_helper_display_init(u8x8);
ext_u8g2->overlay.fb_update_ongoing = 0;
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
break;
#endif
case U8X8_MSG_DISPLAY_REFRESH:
ext_u8g2->overlay.fb_update_ongoing = 0;
break;
case U8X8_MSG_DISPLAY_DRAW_TILE:
if (ext_u8g2->overlay.fb_update_ongoing == 0) {
// tell rfb callback that a new framebuffer starts
if (ext_u8g2->overlay.rfb_cb_ref != LUA_NOREF) {
// fire callback with nil argument
lua_State *L = lua_getstate();
lua_rawgeti( L, LUA_REGISTRYINDEX, ext_u8g2->overlay.rfb_cb_ref );
lua_pushnil( L );
lua_call( L, 1, 0 );
}
// and note ongoing framebuffer update
ext_u8g2->overlay.fb_update_ongoing = 1;
}
{
// TODO: transport tile_y, needs structural change!
uint8_t tile_x = ((u8x8_tile_t *)arg_ptr)->x_pos;
tile_x *= 8;
tile_x += u8x8->x_offset;
uint8_t tile_w = ((u8x8_tile_t *)arg_ptr)->cnt * 8;
size_t fbrle_line_size = sizeof( struct fbrle_line ) + sizeof( struct fbrle_item ) * (tile_w/2);
int num_lines = 8; /*arg_val / (xwidth/8);*/
uint8_t *buf = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
struct fbrle_line *fbrle_line;
if (!(fbrle_line = (struct fbrle_line *)c_malloc( fbrle_line_size ))) {
break;
}
for (int line = 0; line < num_lines; line++) {
int start_run = -1;
fbrle_line->num_valid = 0;
for (int x = tile_x; x < tile_x+tile_w; x++) {
if (bit_at( buf, line, x ) == 0) {
if (start_run >= 0) {
// inside run, end it and enter result
fbrle_line->items[fbrle_line->num_valid].start_x = start_run;
fbrle_line->items[fbrle_line->num_valid++].len = x - start_run;
//NODE_ERR( " line: %d x: %d len: %d\n", line, start_run, x - start_run );
start_run = -1;
}
} else {
if (start_run < 0) {
// outside run, start it
start_run = x;
}
}
if (fbrle_line->num_valid >= tile_w/2) break;
}
// active run?
if (start_run >= 0 && fbrle_line->num_valid < tile_w/2) {
fbrle_line->items[fbrle_line->num_valid].start_x = start_run;
fbrle_line->items[fbrle_line->num_valid++].len = tile_w - start_run;
}
// line done, trigger callback
if (ext_u8g2->overlay.rfb_cb_ref != LUA_NOREF) {
lua_State *L = lua_getstate();
lua_rawgeti( L, LUA_REGISTRYINDEX, ext_u8g2->overlay.rfb_cb_ref );
lua_pushlstring( L, (const char *)fbrle_line, fbrle_line_size );
lua_call( L, 1, 0 );
}
}
c_free( fbrle_line );
}
break;
default:
return 0;
break;
}
return 1;
}
uint8_t u8x8_d_overlay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t res = 1;
u8g2_nodemcu_t *ext_u8g2 = (u8g2_nodemcu_t *)u8x8;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
// only call for hardware display
if (ext_u8g2->overlay.hardware_display_cb)
return ext_u8g2->overlay.hardware_display_cb(u8x8, msg, arg_int, arg_ptr);
break;
default:
// forward all messages first to hardware display and then to fbrle
if (ext_u8g2->overlay.hardware_display_cb)
res = ext_u8g2->overlay.hardware_display_cb(u8x8, msg, arg_int, arg_ptr);
u8x8_d_fbrle(u8x8, msg, arg_int, arg_ptr);
break;
}
return res;
}
##U8glib package
Ported from https://github.com/olikraus/u8glib
Here is black magic with ImageMagic package for image conversion:
```bash
#!/bin/bash
mkdir out
for icon in *png; do
convert $icon -depth 1 ./out/$(basename $icon .png)_1bpp.png
if [[ "$icon" == *"black"* ]]; then
convert ./out/$(basename $icon .png)_1bpp.png -background white -alpha Background ./out/$(basename $icon .png)_1bpp.xbm
else
convert ./out/$(basename $icon .png)_1bpp.png -background black -alpha Background ./out/$(basename $icon .png)_1bpp.xbm
fi
cat ./out/$(basename $icon .png)_1bpp.xbm | tr '\n' ' ' | tr -d " " |sed -e s'#^.*{##g' | sed s'#,}##' |sed s'/;//' | xxd -r -p > ./out/$(basename $icon .png).xbm.mono
done
rm out/*png out/*xbm
```
Convert all the png in the current folder and put resulting .mono to ./out
The convert binary is a part of ImageMagic package. You need to install it.
```
sudo apt-get install imagemagick
```
for Debian/Ubuntu.
\ No newline at end of file
This diff is collapsed.
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