Merge pull request #2582 from nodemcu/dev

Next master drop
This commit is contained in:
Arnim Läuger 2018-12-07 22:47:49 +01:00 committed by GitHub
commit 11592951b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
125 changed files with 4076 additions and 213613 deletions

6
.gitignore vendored
View File

@ -1,10 +1,14 @@
.gdb_history
sdk/
cache/
.ccache/
local/
luac.cross
user_config.h
server-ca.crt
luac.cross
uz_unzip
uz_zip
tools/toolchains/
#ignore Eclipse project files
.cproject

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "app/u8g2lib/u8g2"]
path = app/u8g2lib/u8g2
url = https://github.com/olikraus/U8g2_Arduino.git
[submodule "app/ucglib/ucg"]
path = app/ucglib/ucg
url = https://github.com/olikraus/Ucglib_Arduino.git

View File

@ -1,4 +1,3 @@
sudo: false
language: cpp
addons:
apt:
@ -8,9 +7,6 @@ addons:
cache:
- directories:
- cache
install:
- tar -Jxvf tools/esp-open-sdk.tar.xz
- export PATH=$PATH:$PWD/esp-open-sdk/xtensa-lx106-elf/bin
script:
- export BUILD_DATE=$(date +%Y%m%d)
- make EXTRA_CCFLAGS="-DBUILD_DATE='\"'$BUILD_DATE'\"'" all

View File

@ -2,6 +2,8 @@
#
.NOTPARALLEL:
TOOLCHAIN_VERSION:=20181106.0
# SDK base version, as released by Espressif
SDK_BASE_VER:=2.2.1
@ -47,7 +49,7 @@ ifeq ($(OS),Windows_NT)
OBJCOPY = xt-objcopy
#MAKE = xt-make
CCFLAGS += --rename-section .text=.irom0.text --rename-section .literal=.irom0.literal
else
else
# It is gcc, may be cygwin
# Can we use -fdata-sections?
CCFLAGS += -ffunction-sections -fno-jump-tables -fdata-sections
@ -73,11 +75,13 @@ ifeq ($(OS),Windows_NT)
else
# We are under other system, may be Linux. Assume using gcc.
# Can we use -fdata-sections?
PLATFORM:=linux-x86_64
ifndef COMPORT
ESPPORT = /dev/ttyUSB0
else
ESPPORT = $(COMPORT)
endif
export PATH := $(PATH):$(TOP_DIR)/tools/toolchains/esp8266-$(PLATFORM)-$(TOOLCHAIN_VERSION)/bin/
CCFLAGS += -ffunction-sections -fno-jump-tables -fdata-sections
AR = xtensa-lx106-elf-ar
CC = $(WRAPCC) xtensa-lx106-elf-gcc
@ -145,9 +149,9 @@ endif
endif
#
# Note:
# Note:
# https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
# If you add global optimize options like "-O2" here
# If you add global optimize options like "-O2" here
# they will override "-Os" defined above.
# "-Os" should be used to reduce code size
#
@ -161,7 +165,7 @@ CCFLAGS += \
-nostdlib \
-mlongcalls \
-mtext-section-literals
# -Wall
# -Wall
CFLAGS = $(CCFLAGS) $(DEFINES) $(EXTRA_CCFLAGS) $(STD_CFLAGS) $(INCLUDES)
DFLAGS = $(CCFLAGS) $(DDEFINES) $(EXTRA_CCFLAGS) $(STD_CFLAGS) $(INCLUDES)
@ -191,7 +195,7 @@ DEP_LIBS_$(1) = $$(foreach lib,$$(filter %.a,$$(COMPONENTS_$(1))),$$(dir $$(lib)
DEP_OBJS_$(1) = $$(foreach obj,$$(filter %.o,$$(COMPONENTS_$(1))),$$(dir $$(obj))$$(OBJODIR)/$$(notdir $$(obj)))
$$(IMAGEODIR)/$(1).out: $$(OBJS) $$(DEP_OBJS_$(1)) $$(DEP_LIBS_$(1)) $$(DEPENDS_$(1))
@mkdir -p $$(IMAGEODIR)
$$(CC) $$(LDFLAGS) $$(if $$(LINKFLAGS_$(1)),$$(LINKFLAGS_$(1)),$$(LINKFLAGS_DEFAULT) $$(OBJS) $$(DEP_OBJS_$(1)) $$(DEP_LIBS_$(1))) -o $$@
$$(CC) $$(LDFLAGS) $$(if $$(LINKFLAGS_$(1)),$$(LINKFLAGS_$(1)),$$(LINKFLAGS_DEFAULT) $$(OBJS) $$(DEP_OBJS_$(1)) $$(DEP_LIBS_$(1))) -o $$@
endef
$(BINODIR)/%.bin: $(IMAGEODIR)/%.out
@ -204,16 +208,32 @@ $(BINODIR)/%.bin: $(IMAGEODIR)/%.out
# Should be done in top-level makefile only
#
all: sdk_pruned pre_build .subdirs $(OBJS) $(OLIBS) $(OIMAGES) $(OBINS) $(SPECIAL_MKTARGETS)
all: toolchain sdk_pruned pre_build .subdirs $(OBJS) $(OLIBS) $(OIMAGES) $(OBINS) $(SPECIAL_MKTARGETS)
.PHONY: sdk_extracted
.PHONY: sdk_patched
.PHONY: sdk_pruned
.PHONY: toolchain
sdk_extracted: $(TOP_DIR)/sdk/.extracted-$(SDK_BASE_VER)
sdk_patched: sdk_extracted $(TOP_DIR)/sdk/.patched-$(SDK_VER)
sdk_pruned: $(SDK_DIR_DEPENDS) $(TOP_DIR)/sdk/.pruned-$(SDK_VER)
ifeq ($(OS),Windows_NT)
toolchain:
else
toolchain: $(TOP_DIR)/tools/toolchains/esp8266-$(PLATFORM)-$(TOOLCHAIN_VERSION)/bin/xtensa-lx106-elf-gcc
$(TOP_DIR)/tools/toolchains/esp8266-$(PLATFORM)-$(TOOLCHAIN_VERSION)/bin/xtensa-lx106-elf-gcc: $(TOP_DIR)/cache/toolchain-esp8266-$(PLATFORM)-$(TOOLCHAIN_VERSION).tar.xz
mkdir -p $(TOP_DIR)/tools/toolchains/
tar -xJf $< -C $(TOP_DIR)/tools/toolchains/
touch $@
$(TOP_DIR)/cache/toolchain-esp8266-$(PLATFORM)-$(TOOLCHAIN_VERSION).tar.xz:
mkdir -p $(TOP_DIR)/cache
wget --tries=10 --timeout=15 --waitretry=30 --read-timeout=20 --retry-connrefused https://github.com/jmattsson/esp-toolchains/releases/download/$(PLATFORM)-$(TOOLCHAIN_VERSION)/toolchain-esp8266-$(PLATFORM)-$(TOOLCHAIN_VERSION).tar.xz -O $@ || { rm -f "$@"; exit 1; }
endif
$(TOP_DIR)/sdk/.extracted-$(SDK_BASE_VER): $(TOP_DIR)/cache/v$(SDK_FILE_VER).zip
mkdir -p "$(dir $@)"
(cd "$(dir $@)" && rm -fr esp_iot_sdk_v$(SDK_VER) ESP8266_NONOS_SDK-$(SDK_BASE_VER) && unzip $(TOP_DIR)/cache/v$(SDK_FILE_VER).zip ESP8266_NONOS_SDK-$(SDK_BASE_VER)/lib/* ESP8266_NONOS_SDK-$(SDK_BASE_VER)/ld/eagle.rom.addr.v6.ld ESP8266_NONOS_SDK-$(SDK_BASE_VER)/include/* ESP8266_NONOS_SDK-$(SDK_BASE_VER)/bin/esp_init_data_default_v05.bin)

View File

@ -20,7 +20,7 @@ FLAVOR = debug
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_MKTARGETS := coap dht http mqtt pcm sjson sqlite3 tsl2561 websocket
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)))
@ -31,6 +31,7 @@ SPECIAL_MKTARGETS :=$(APP_MKTARGETS)
SUBDIRS= \
user \
crypto \
driver \
mbedtls \
platform \
@ -45,6 +46,7 @@ SUBDIRS= \
fatfs \
esp-gdbstub \
pm \
uzlib \
$(OPT_SEL_MKTARGETS)
endif # } PDIR
@ -62,6 +64,7 @@ LD_FILE = $(LDDIR)/nodemcu.ld
COMPONENTS_eagle.app.v6 = \
user/libuser.a \
crypto/libcrypto.a \
driver/libdriver.a \
platform/libplatform.a \
task/libtask.a \
@ -76,6 +79,8 @@ COMPONENTS_eagle.app.v6 = \
net/libnodemcu_net.a \
mbedtls/libmbedtls.a \
modules/libmodules.a \
smart/smart.a \
uzlib/libuzlib.a \
$(OPT_SEL_COMPONENTS)

View File

@ -210,7 +210,7 @@ static void ICACHE_FLASH_ATTR http_connect_callback( void * arg )
char ua_header[32] = "";
int ua_len = 0;
if (os_strstr( req->headers, "User-Agent:" ) == NULL && os_strstr( req->headers, "user-agent:" ) == NULL)
if (strcasestr( req->headers, "User-Agent:" ) == NULL )
{
os_sprintf( ua_header, "User-Agent: %s\r\n", "ESP8266" );
ua_len = strlen(ua_header);
@ -218,7 +218,7 @@ static void ICACHE_FLASH_ATTR http_connect_callback( void * arg )
char * host_header = "";
int host_len = 0;
if ( os_strstr( req->headers, "Host:" ) == NULL && os_strstr( req->headers, "host:" ) == NULL)
if ( strcasestr( req->headers, "Host:" ) == NULL )
{
int max_header_len = 9 + strlen(req->hostname); // 9 is fixed size of "Host:[space][cr][lf]\0"
if ((req->port == 80)
@ -328,10 +328,7 @@ static void ICACHE_FLASH_ATTR http_disconnect_callback( void * arg )
{
http_status = atoi( req->buffer + strlen( version_1_0 ) );
char *locationOffset = (char *) os_strstr( req->buffer, "Location:" );
if ( locationOffset == NULL ) {
locationOffset = (char *) os_strstr( req->buffer, "location:" );
}
char *locationOffset = (char *) strcasestr( req->buffer, "Location:" );
if ( locationOffset != NULL && http_status >= 300 && http_status <= 308 ) {
if (req->redirect_follow_count < REDIRECTION_FOLLOW_MAX) {
@ -414,7 +411,7 @@ static void ICACHE_FLASH_ATTR http_disconnect_callback( void * arg )
body = body + 4;
}
if ( os_strstr( req->buffer, "Transfer-Encoding: chunked" ) || os_strstr( req->buffer, "transfer-encoding: chunked" ) )
if ( strcasestr( req->buffer, "Transfer-Encoding: chunked" ) )
{
int body_size = req->buffer_size - (body - req->buffer);
char chunked_decode_buffer[body_size];

View File

@ -57,18 +57,8 @@
const LOCK_IN_SECTION(libs) \
luaL_Reg MODULE_PASTE_(lua_lib_,cfgname) = { luaname, initfunc }; \
const LOCK_IN_SECTION(rotable) \
luaR_table MODULE_EXPAND_PASTE_(cfgname,MODULE_EXPAND_PASTE_(_module_selected,MODULE_PASTE_(LUA_USE_MODULES_,cfgname))) \
= { luaname, map }
/* System module registration support, not using LUA_USE_MODULES_XYZ. */
#define BUILTIN_LIB_INIT(name, luaname, initfunc) \
const LOCK_IN_SECTION(libs) \
luaL_Reg MODULE_PASTE_(lua_lib_,name) = { luaname, initfunc }
#define BUILTIN_LIB(name, luaname, map) \
const LOCK_IN_SECTION(rotable) \
luaR_table MODULE_PASTE_(lua_rotable_,name) = { luaname, map }
luaR_entry MODULE_EXPAND_PASTE_(cfgname,MODULE_EXPAND_PASTE_(_module_selected,MODULE_PASTE_(LUA_USE_MODULES_,cfgname))) \
= {LSTRKEY(luaname), LROVAL(map)}
#if !defined(LUA_CROSS_COMPILER) && !(MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2)
# error "NodeMCU modules must be built with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)"

View File

@ -31,11 +31,26 @@
// 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_sh1107_i2c_64x128_f, sh1107_i2c_64x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1107_i2c_seeed_96x96_f, sh1107_i2c_seeed_96x96) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1107_i2c_128x128_f, sh1107_i2c_128x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1108_i2c_160x160_f, sh1108_i2c_160x160) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1122_i2c_256x64_f, sh1122_i2c_256x64) \
// 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_ssd1306_i2c_128x64_alt0_f, ssd1306_i2c_128x64_alt0) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1611_i2c_ea_dogm240_f, uc1611_i2c_ea_dogm240) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1326_i2c_er_256x32_f, ssd1326_i2c_er_256x32 )\
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1327_i2c_seeed_96x96_f, ssd1327_i2c_seeed_96x96) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1327_i2c_ea_w128128_f, ssd1327_i2c_ea_w128128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1327_i2c_midas_128x128_f, ssd1327_i2c_midas_128x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7567_i2c_64x32_f, st7567_i2c_64x32) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st75256_i2c_jlx256128_f, st75256_i2c_jlx256128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st75256_i2c_jlx256160_f, st75256_i2c_jlx256160) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st75256_i2c_jlx240160_f, st75256_i2c_jlx240160) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st75256_i2c_jlx25664_f, st75256_i2c_jlx25664) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st75256_i2c_jlx172104_f, st75256_i2c_jlx172104) \
#define U8G2_DISPLAY_TABLE_I2C \
U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_i2c_128x64_noname_f, ssd1306_i2c_128x64_noname) \
@ -72,18 +87,25 @@
// 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_ssd1306_128x64_alt0_f, ssd1306_128x64_alt0) \
// 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_sh1107_64x128_f, sh1107_64x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1107_seeed_96x96_f, sh1107_seeed_96x96) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1107_128x128_f, sh1107_128x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1108_160x160_f, sh1108_160x160) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1122_256x64_f, sh1122_256x64) \
// 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_ssd1322_nhd_128x64_f, ssd1322_nhd_128x64) \
// 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) \
@ -91,17 +113,37 @@
// 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_ssd1326_er_256x32_f, ssd1326_er_256x32 )\
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1327_seeed_96x96_f, ssd1327_seeed_96x96) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1327_ea_w128128_f, ssd1327_ea_w128128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1327_midas_128x128_f, ssd1327_midas_128x128) \
// 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_st75256_jlx256160_f, st75256_jlx256160) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st75256_jlx240160_f, st75256_jlx240160) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st75256_jlx25664_f, st75256_jlx25664) \
// 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_st7567_enh_dg128064i_f, st7567_enh_dg128064i) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7567_64x32_f, st7567_64x32) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7586s_s028hn118a_f, st7586s_s028hn118a) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7586s_erc240160_f, st7586s_erc240160) \
// 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) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_t6963_240x128_f, t6963_240x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_t6963_240x64_f, t6963_240x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_t6963_256x64_f, t6963_256x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_t6963_128x64_f, t6963_128x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_t6963_160x80_f, t6963_160x80) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_lc7981_160x80_f, lc7981_160x80) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_lc7981_160x160_f, lc7981_160x160) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_lc7981_240x128_f, lc7981_240x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_lc7981_240x64_f, lc7981_240x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_hx1230_96x68_f, hx1230_96x68) \
#define U8G2_DISPLAY_TABLE_SPI \
U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_128x64_noname_f, ssd1306_128x64_noname) \

View File

@ -27,8 +27,10 @@
// Uncomment the UCG_DISPLAY_TABLE_ENTRY for the device(s) you want to
// compile into the firmware.
//
// UCG_DISPLAY_TABLE_ENTRY(hx8352c_18x240x400_hw_spi, ucg_dev_hx8352c_18x240x400, ucg_ext_hx8352c_18) \
// UCG_DISPLAY_TABLE_ENTRY(ili9163_18x128x128_hw_spi, ucg_dev_ili9163_18x128x128, ucg_ext_ili9163_18) \
// UCG_DISPLAY_TABLE_ENTRY(ili9341_18x240x320_hw_spi, ucg_dev_ili9341_18x240x320, ucg_ext_ili9341_18) \
// UCG_DISPLAY_TABLE_ENTRY(ili9486_18x320x480_hw_spi, ucg_dev_ili9486_18x320x480, ucg_ext_ili9486_18) \
// UCG_DISPLAY_TABLE_ENTRY(pcf8833_16x132x132_hw_spi, ucg_dev_pcf8833_16x132x132, ucg_ext_pcf8833_16) \
// UCG_DISPLAY_TABLE_ENTRY(seps225_16x128x128_uvis_hw_spi, ucg_dev_seps225_16x128x128_univision, ucg_ext_seps225_16) \
// UCG_DISPLAY_TABLE_ENTRY(ssd1351_18x128x128_hw_spi, ucg_dev_ssd1351_18x128x128_ilsoft, ucg_ext_ssd1351_18) \

View File

@ -110,7 +110,7 @@
// firmware to manage timer rescheduling over sleeps (the CPU clock is
// suspended so timers get out of sync) then enable the following options
//#define ENABLE_TIMER_SUSPEND
//#define TIMER_SUSPEND_ENABLE
//#define PMSLEEP_ENABLE

View File

@ -46,6 +46,7 @@ INCLUDES += -I ../spiffs
INCLUDES += -I ../libc
INCLUDES += -I ../modules
INCLUDES += -I ../platform
INCLUDES += -I ../uzlib
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile

View File

@ -25,8 +25,6 @@
#define lauxlib_c
#define LUA_LIB
#include "lrotable.h"
#include "lauxlib.h"
#include "lgc.h"
#include "ldo.h"
@ -555,14 +553,7 @@ LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
if (e == NULL) e = fname + c_strlen(fname);
lua_pushlstring(L, fname, e - fname);
lua_rawget(L, -2);
if (lua_isnil(L, -1)) {
/* If looking for a global variable, check the rotables too */
void *ptable = luaR_findglobal(fname, e - fname);
if (ptable) {
lua_pop(L, 1);
lua_pushrotable(L, ptable);
}
}
if (lua_isnil(L, -1)) { /* no such field? */
lua_pop(L, 1); /* remove this nil */
lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
@ -967,12 +958,12 @@ LUALIB_API void luaL_assertfail(const char *file, int line, const char *message)
#endif
}
#ifdef DEVELOPMENT_USE_GDB
#if defined(DEVELOPMENT_USE_GDB) && !defined(LUA_CROSS_COMPILER)
/*
* This is a simple stub used by lua_assert() if DEVELOPMENT_USE_GDB is defined.
* Instead of crashing out with an assert error, this hook starts the GDB remote
* stub if not already running and then issues a break. The rationale here is
* that when testing the developer migght be using screen/PuTTY to work ineractively
* that when testing the developer might be using screen/PuTTY to work interactively
* with the Lua Interpreter via UART0. However if an assert triggers, then there
* is the option to exit the interactive session and start the Xtensa remote GDB
* which will then sync up with the remote GDB client to allow forensics of the error.

View File

@ -16,7 +16,7 @@
#include C_HEADER_STDLIB
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#include "lrodefs.h"
@ -462,71 +462,62 @@ static int luaB_newproxy (lua_State *L) {
return 1;
}
#define LUA_BASELIB_FUNCLIST\
{LSTRKEY("assert"), LFUNCVAL(luaB_assert)},\
{LSTRKEY("collectgarbage"), LFUNCVAL(luaB_collectgarbage)},\
{LSTRKEY("dofile"), LFUNCVAL(luaB_dofile)},\
{LSTRKEY("error"), LFUNCVAL(luaB_error)},\
{LSTRKEY("gcinfo"), LFUNCVAL(luaB_gcinfo)},\
{LSTRKEY("getfenv"), LFUNCVAL(luaB_getfenv)},\
{LSTRKEY("getmetatable"), LFUNCVAL(luaB_getmetatable)},\
{LSTRKEY("loadfile"), LFUNCVAL(luaB_loadfile)},\
{LSTRKEY("load"), LFUNCVAL(luaB_load)},\
{LSTRKEY("loadstring"), LFUNCVAL(luaB_loadstring)},\
{LSTRKEY("next"), LFUNCVAL(luaB_next)},\
{LSTRKEY("pcall"), LFUNCVAL(luaB_pcall)},\
{LSTRKEY("print"), LFUNCVAL(luaB_print)},\
{LSTRKEY("rawequal"), LFUNCVAL(luaB_rawequal)},\
{LSTRKEY("rawget"), LFUNCVAL(luaB_rawget)},\
{LSTRKEY("rawset"), LFUNCVAL(luaB_rawset)},\
{LSTRKEY("select"), LFUNCVAL(luaB_select)},\
{LSTRKEY("setfenv"), LFUNCVAL(luaB_setfenv)},\
{LSTRKEY("setmetatable"), LFUNCVAL(luaB_setmetatable)},\
{LSTRKEY("tonumber"), LFUNCVAL(luaB_tonumber)},\
{LSTRKEY("tostring"), LFUNCVAL(luaB_tostring)},\
{LSTRKEY("type"), LFUNCVAL(luaB_type)},\
{LSTRKEY("unpack"), LFUNCVAL(luaB_unpack)},\
{LSTRKEY("xpcall"), LFUNCVAL(luaB_xpcall)}
#if LUA_OPTIMIZE_MEMORY == 2
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
const LUA_REG_TYPE base_funcs_list[] = {
LUA_BASELIB_FUNCLIST,
{LNILKEY, LNILVAL}
};
extern const luaR_entry lua_rotable_base[];
/*
* ESP builds use specific linker directives to marshal all ROTable declarations
* into a single ROTable in the PSECT ".lua_rotable".
*
* This is not practical on Posix builds using a standard link so for cross
* compiler builds, separate ROTables are used for the base functions and library
* ROTables, with the latter chained from the former using its __index meta-method.
* In this case all library ROTables are defined in linit.c.
*/
#ifdef LUA_CROSS_COMPILER
#define BASE_ROTABLE base_func_map
#define LOCK_IN_ROTABLE
static const LUA_REG_TYPE base_func_meta[] = {
LROT_TABENTRY(__index, lua_rotable_base),
LROT_END};
#else
#define BASE_ROTABLE lua_rotable_base
#define LOCK_IN_ROTABLE __attribute__((used,unused,section(".lua_rotable")))
#endif
static int luaB_index(lua_State *L) {
#if LUA_OPTIMIZE_MEMORY == 2
int fres;
if ((fres = luaR_findfunction(L, base_funcs_list)) != 0)
return fres;
#endif
const char *keyname = luaL_checkstring(L, 2);
if (!c_strcmp(keyname, "_VERSION")) {
lua_pushliteral(L, LUA_VERSION);
return 1;
}
void *res = luaR_findglobal(keyname, c_strlen(keyname));
if (!res)
return 0;
else {
lua_pushrotable(L, res);
return 1;
}
}
static const LUA_REG_TYPE LOCK_IN_ROTABLE base_func_map[] = {
LROT_FUNCENTRY(assert, luaB_assert),
LROT_FUNCENTRY(collectgarbage, luaB_collectgarbage),
LROT_FUNCENTRY(dofile, luaB_dofile),
LROT_FUNCENTRY(error, luaB_error),
LROT_FUNCENTRY(gcinfo, luaB_gcinfo),
LROT_FUNCENTRY(getfenv, luaB_getfenv),
LROT_FUNCENTRY(getmetatable, luaB_getmetatable),
LROT_FUNCENTRY(loadfile, luaB_loadfile),
LROT_FUNCENTRY(load, luaB_load),
LROT_FUNCENTRY(loadstring, luaB_loadstring),
LROT_FUNCENTRY(next, luaB_next),
LROT_FUNCENTRY(pcall, luaB_pcall),
LROT_FUNCENTRY(print, luaB_print),
LROT_FUNCENTRY(rawequal, luaB_rawequal),
LROT_FUNCENTRY(rawget, luaB_rawget),
LROT_FUNCENTRY(rawset, luaB_rawset),
LROT_FUNCENTRY(select, luaB_select),
LROT_FUNCENTRY(setfenv, luaB_setfenv),
LROT_FUNCENTRY(setmetatable, luaB_setmetatable),
LROT_FUNCENTRY(tonumber, luaB_tonumber),
LROT_FUNCENTRY(tostring, luaB_tostring),
LROT_FUNCENTRY(type, luaB_type),
LROT_FUNCENTRY(unpack, luaB_unpack),
LROT_FUNCENTRY(xpcall, luaB_xpcall)
#ifdef LUA_CROSS_COMPILER
,LROT_TABENTRY(__metatable, base_func_meta),
LROT_END
#endif
};
static const luaL_Reg base_funcs[] = {
#if LUA_OPTIMIZE_MEMORY != 2
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 0
#include "lrodefs.h"
LUA_BASELIB_FUNCLIST,
#endif
{"__index", luaB_index},
{NULL, NULL}
};
@ -661,7 +652,6 @@ static int luaB_corunning (lua_State *L) {
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 1
#include "lrodefs.h"
const LUA_REG_TYPE co_funcs[] = {
{LSTRKEY("create"), LFUNCVAL(luaB_cocreate)},
{LSTRKEY("resume"), LFUNCVAL(luaB_coresume)},
@ -682,7 +672,6 @@ static void auxopen (lua_State *L, const char *name,
lua_setfield(L, -2, name);
}
static void base_open (lua_State *L) {
/* set global _G */
lua_pushvalue(L, LUA_GLOBALSINDEX);
@ -691,11 +680,12 @@ static void base_open (lua_State *L) {
luaL_register_light(L, "_G", base_funcs);
#if LUA_OPTIMIZE_MEMORY > 0
lua_pushvalue(L, -1);
lua_setmetatable(L, -2);
#else
lua_setmetatable(L, -2);
lua_pushrotable(L, (void *)BASE_ROTABLE);
lua_setglobal(L, "__index");
#endif
lua_pushliteral(L, LUA_VERSION);
lua_setglobal(L, "_VERSION"); /* set global _VERSION */
#endif
/* `ipairs' and `pairs' need auxliliary functions as upvalues */
auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
auxopen(L, "pairs", luaB_pairs, luaB_next);

View File

@ -16,7 +16,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#include "lstring.h"
#include "lflash.h"
#include "user_modules.h"

View File

@ -47,7 +47,7 @@ static void DumpChar(int y, DumpState* D)
static void Align4(DumpState *D)
{
while(D->wrote&3)
while(D->wrote&3 && D->status==0)
DumpChar(0,D);
}

View File

@ -16,6 +16,7 @@
#include "lflash.h"
#include "platform.h"
#include "vfs.h"
#include "uzlib.h"
#include "c_fcntl.h"
#include "c_stdio.h"
@ -34,15 +35,52 @@ static uint32_t flashAddrPhys;
static uint32_t flashSector;
static uint32_t curOffset;
#define ALIGN(s) (((s)+sizeof(size_t)-1) & ((size_t) (- (signed) sizeof(size_t))))
#define ALIGN(s) (((s)+sizeof(size_t)-1) & ((size_t) (- (signed) sizeof(size_t))))
#define ALIGN_BITS(s) (((uint32_t)s) & (sizeof(size_t)-1))
#define ALL_SET cast(uint32_t, -1)
#define FLASH_SIZE LUA_FLASH_STORE
#define ALL_SET (~0)
#define FLASH_SIZE LUA_FLASH_STORE
#define FLASH_PAGE_SIZE INTERNAL_FLASH_SECTOR_SIZE
#define FLASH_PAGES (FLASH_SIZE/FLASH_PAGE_SIZE)
#define FLASH_PAGES (FLASH_SIZE/FLASH_PAGE_SIZE)
#define READ_BLOCKSIZE 1024
#define WRITE_BLOCKSIZE 2048
#define DICTIONARY_WINDOW 16384
#define WORDSIZE (sizeof(int))
#define BITS_PER_WORD 32
#define WRITE_BLOCKS ((DICTIONARY_WINDOW/WRITE_BLOCKSIZE)+1)
#define WRITE_BLOCK_WORDS (WRITE_BLOCKSIZE/WORDSIZE)
char flash_region_base[FLASH_SIZE] ICACHE_FLASH_RESERVED_ATTR;
struct INPUT {
int fd;
int len;
uint8_t block[READ_BLOCKSIZE];
uint8_t *inPtr;
int bytesRead;
int left;
void *inflate_state;
} *in;
typedef struct {
uint8_t byte[WRITE_BLOCKSIZE];
} outBlock;
struct OUTPUT {
lua_State *L;
lu_int32 flash_sig;
int len;
outBlock *block[WRITE_BLOCKS];
outBlock buffer;
int ndx;
uint32_t crc;
int (*fullBlkCB) (void);
int flashLen;
int flagsLen;
int flagsNdx;
uint32_t *flags;
const char *error;
} *out;
#ifdef NODE_DEBUG
extern void dbg_printf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
void dumpStrt(stringtable *tb, const char *type) {
@ -54,11 +92,11 @@ void dumpStrt(stringtable *tb, const char *type) {
for (i=0; i<tb->size; i++)
for(o = tb->hash[i], j=0; o; (o=o->gch.next), j++ ) {
TString *ts =cast(TString *, o);
NODE_DBG("%5d %5d %08x %08x %5d %1s %s\n",
NODE_DBG("%5d %5d %08x %08x %5d %1s %s\n",
i, j, (size_t) ts, ts->tsv.hash, ts->tsv.len,
ts_isreadonly(ts) ? "R" : " ", getstr(ts));
}
}
}
LUA_API void dumpStrings(lua_State *L) {
dumpStrt(&G(L)->strt, "RAM");
@ -70,7 +108,7 @@ LUA_API void dumpStrings(lua_State *L) {
/* =====================================================================================
* The next 4 functions: flashPosition, flashSetPosition, flashBlock and flashErase
* wrap writing to flash. The last two are platform dependent. Also note that any
* writes are suppressed if the global writeToFlash is false. This is used in
* writes are suppressed if the global writeToFlash is false. This is used in
* phase I where the pass is used to size the structures in flash.
*/
static char *flashPosition(void){
@ -104,28 +142,37 @@ static void flashErase(uint32_t start, uint32_t end){
platform_flash_erase_sector( flashSector + i );
}
/* =====================================================================================
* luaN_init(), luaN_reload_reboot() and luaN_index() are exported via lflash.h.
* The first is the startup hook used in lstate.c and the last two are
* implementations of the node.flash API calls.
*/
/*
* Hook in lstate.c:f_luaopen() to set up ROstrt and ROpvmain if needed
*/
*/
LUAI_FUNC void luaN_init (lua_State *L) {
// luaL_dbgbreak();
curOffset = 0;
flashAddr = flash_region_base;
flashAddrPhys = platform_flash_mapped2phys((uint32_t)flashAddr);
flashSector = platform_flash_get_sector_of_address(flashAddrPhys);
curOffset = 0;
flashAddr = flash_region_base;
flashAddrPhys = platform_flash_mapped2phys((uint32_t)flashAddr);
flashSector = platform_flash_get_sector_of_address(flashAddrPhys);
FlashHeader *fh = cast(FlashHeader *, flashAddr);
/*
* For the LFS to be valid, its signature has to be correct for this build variant,
* thr ROhash and main proto fields must be defined and the main proto address
* be within the LFS address bounds. (This last check is primarily to detect the
* direct imaging of an absolute LFS with the wrong base address.
* For the LFS to be valid, its signature has to be correct for this build
* variant, the ROhash and main proto fields must be defined and the main proto
* address be within the LFS address bounds. (This last check is primarily to
* detect the direct imaging of an absolute LFS with the wrong base address.
*/
if (fh->flash_sig == 0 || fh->flash_sig == ~0 ) {
NODE_ERR("No LFS image loaded\n");
return;
}
if ((fh->flash_sig & (~FLASH_SIG_ABSOLUTE)) != FLASH_SIG ) {
NODE_ERR("Flash sig not correct: %p vs %p\n",
fh->flash_sig & (~FLASH_SIG_ABSOLUTE), FLASH_SIG);
fh->flash_sig & (~FLASH_SIG_ABSOLUTE), FLASH_SIG);
return;
}
@ -135,107 +182,89 @@ LUAI_FUNC void luaN_init (lua_State *L) {
fh->mainProto - cast(FlashAddr, fh), fh->flash_size);
return;
}
G(L)->ROstrt.hash = cast(GCObject **, fh->pROhash);
G(L)->ROstrt.nuse = fh->nROuse ;
G(L)->ROstrt.size = fh->nROsize;
G(L)->ROpvmain = cast(Proto *,fh->mainProto);
}
#define BYTE_OFFSET(t,f) cast(size_t, &(cast(t *, NULL)->f))
/*
* Rehook address chain to correct Flash byte addressed within the mapped adress space
* Note that on input each 32-bit address field is split into 2×16-bit subfields
* - the lu_int16 offset of the target address being referenced
* - the lu_int16 offset of the next address pointer.
*/
static int rebuild_core (int fd, uint32_t size, lu_int32 *buf, int is_absolute) {
int bi; /* byte offset into memory mapped LFS of current buffer */
int wNextOffset = BYTE_OFFSET(FlashHeader,mainProto)/sizeof(lu_int32);
int wj; /* word offset into current input buffer */
for (bi = 0; bi < size; bi += FLASH_PAGE_SIZE) {
int wi = bi / sizeof(lu_int32);
int blen = ((bi + FLASH_PAGE_SIZE) < size) ? FLASH_PAGE_SIZE : size - bi;
int wlen = blen / sizeof(lu_int32);
if (vfs_read(fd, buf , blen) != blen)
return 0;
if (!is_absolute) {
for (wj = 0; wj < wlen; wj++) {
if ((wi + wj) == wNextOffset) { /* this word is the next linked address */
int wTargetOffset = buf[wj]&0xFFFF;
wNextOffset = buf[wj]>>16;
lua_assert(!wNextOffset || (wNextOffset>(wi+wj) && wNextOffset<size/sizeof(lu_int32)));
buf[wj] = cast(lu_int32, flashAddr + wTargetOffset*sizeof(lu_int32));
}
}
}
flashBlock(buf, blen);
}
return size;
}
//extern void software_reset(void);
static int loadLFS (lua_State *L);
static int loadLFSgc (lua_State *L);
static int procFirstPass (void);
/*
* Library function called by node.flash.load(filename).
* Library function called by node.flashreload(filename).
*/
LUALIB_API int luaN_reload_reboot (lua_State *L) {
int fd, status, is_absolute;
FlashHeader fh;
// luaL_dbgbreak();
const char *fn = lua_tostring(L, 1), *msg = "";
int status;
/*
* Do a protected call of loadLFS.
*
* - This will normally rewrite the LFS and reboot, with no return.
* - If an error occurs then it is sent to the UART.
* - If this occured in the 1st pass, the previous LFS is unchanged so it is
* safe to return to the calling Lua.
* - If in the 1st pass, then the ESP is rebooted.
*/
status = lua_cpcall(L, &loadLFS, cast(void *,fn));
const char *fn = lua_tostring(L, 1);
if (!fn || !(fd = vfs_open(fn, "r")))
return 0;
if (vfs_read(fd, &fh, sizeof(fh)) != sizeof(fh) ||
(fh.flash_sig & (~FLASH_SIG_ABSOLUTE)) != FLASH_SIG)
return 0;
if (!out || out->fullBlkCB == procFirstPass) {
/*
* Never entered the 2nd pass, so it is safe to return the error. Note
* that I've gone to some trouble to ensure that all dynamically allocated
* working areas have been freed, so that we have no memory leaks.
*/
if (status == LUA_ERRMEM)
msg = "Memory allocation error";
else if (out && out->error)
msg = out->error;
else
msg = "Unknown Error";
if (vfs_lseek(fd, -1, VFS_SEEK_END) != fh.flash_size-1 ||
vfs_lseek(fd, 0, VFS_SEEK_SET) != 0)
return 0;
/* We can clean up and return error */
lua_cpcall(L, &loadLFSgc, NULL);
lua_settop(L, 0);
lua_pushstring(L, msg);
return 1;
}
is_absolute = fh.flash_sig & FLASH_SIG_ABSOLUTE;
lu_int32 *buffer = luaM_newvector(L, FLASH_PAGE_SIZE / sizeof(lu_int32), lu_int32);
/*
* This is the point of no return. We attempt to rebuild the flash. If there
* are any problems them the Flash is going to be corrupt, so the only fallback
* is to erase it and reboot with a clean but blank flash. Otherwise the reboot
* will load the new LFS.
*
* Note that the Lua state is not passed into the lua core because from this
* point on, we make no calls on the Lua RTS.
*/
flashErase(0,-1);
if (rebuild_core(fd, fh.flash_size, buffer, is_absolute) != fh.flash_size)
flashErase(0,-1);
/*
* Issue a break 0,0. This will either enter the debugger or force a restart if
* not installed. Follow this by a H/W timeout is a robust way to insure that
* other interrupts / callbacks don't fire and reference THE old LFS context.
*/
asm("break 0,0" ::);
while (1) {}
if (status == 0) {
/* Successful LFS rewrite */
msg = "LFS region updated. Restarting.";
} else {
/* We have errored during the second pass so clear the LFS and reboot */
if (status == LUA_ERRMEM)
msg = "Memory allocation error";
else if (out->error)
msg = out->error;
else
msg = "Unknown Error";
flashErase(0,-1);
}
NODE_ERR(msg);
while (1) {} // Force WDT as the ROM software_reset() doesn't seem to work
return 0;
}
/*
* In the arg is a valid LFS module name then return the LClosure pointing to it.
* Otherwise return:
* If the arg is a valid LFS module name then return the LClosure
* pointing to it. Otherwise return:
* - The Unix time that the LFS was built
* - The base address and length of the LFS
* - An array of the module names in the the LFS
* - An array of the module names in the LFS
*/
LUAI_FUNC int luaN_index (lua_State *L) {
int i;
int n = lua_gettop(L);
/* Return nil + the LFS base address if the LFS isn't loaded */
/* Return nil + the LFS base address if the LFS isn't loaded */
if(!(G(L)->ROpvmain)) {
lua_settop(L, 0);
lua_pushnil(L);
@ -270,5 +299,262 @@ LUAI_FUNC int luaN_index (lua_State *L) {
lua_insert(L, 4);
return 5;
}
/* =====================================================================================
* The following routines use my uzlib which was based on pfalcon's inflate and
* deflate routines. The standard NodeMCU make also makes two host tools uz_zip
* and uz_unzip which also use these and luac.cross uses the deflate. As discussed
* below, The main action routine loadLFS() calls uzlib_inflate() to do the actual
* stream inflation but uses three supplied CBs to abstract input and output
* stream handling.
*
* ESP8266 RAM limitations and heap fragmentation are a key implementation
* constraint and hence these routines use a number of ~2K buffers (11) as
* working storage.
*
* The inflate is done twice, in order to limit storage use and avoid forward /
* backward reference issues. However this has a major advantage that the LFS
* is scanned with the headers, CRC, etc. validated BEFORE the write to flash
* is started, so the only real chance of failure during the second pass
* write is if a power fail occurs during the pass.
*/
static void flash_error(const char *err) {
if (out)
out->error = err;
if (in && in->inflate_state)
uz_free(in->inflate_state);
lua_pushnil(out->L); /* can't use it on a cpcall anyway */
lua_error(out->L);
}
/*
* uzlib_inflate does a stream inflate on an RFC 1951 encoded data stream.
* It uses three application-specific CBs passed in the call to do the work:
*
* - get_byte() CB to return next byte in input stream
* - put_byte() CB to output byte to output buffer
* - recall_byte() CB to output byte to retrieve a historic byte from
* the output buffer.
*
* Note that put_byte() also triggers secondary CBs to do further processing.
*/
static uint8_t get_byte (void) {
if (--in->left < 0) {
/* Read next input block */
int remaining = in->len - in->bytesRead;
int wanted = remaining >= READ_BLOCKSIZE ? READ_BLOCKSIZE : remaining;
if (vfs_read(in->fd, in->block, wanted) != wanted)
flash_error("read error on LFS image file");
system_soft_wdt_feed();
in->bytesRead += wanted;
in->inPtr = in->block;
in->left = wanted-1;
}
return *in->inPtr++;
}
static void put_byte (uint8_t value) {
int offset = out->ndx % WRITE_BLOCKSIZE; /* counts from 0 */
out->block[0]->byte[offset++] = value;
out->ndx++;
if (offset == WRITE_BLOCKSIZE || out->ndx == out->len) {
if (out->fullBlkCB)
out->fullBlkCB();
/* circular shift the block pointers (redundant on last block, but so what) */
outBlock *nextBlock = out->block[WRITE_BLOCKS - 1];
memmove(out->block+1, out->block, (WRITE_BLOCKS-1)*sizeof(void*));
out->block[0] = nextBlock ;
}
}
static uint8_t recall_byte (uint offset) {
if(offset > DICTIONARY_WINDOW || offset >= out->ndx)
flash_error("invalid dictionary offset on inflate");
/* ndx starts at 1. Need relative to 0 */
uint n = out->ndx - offset;
uint pos = n % WRITE_BLOCKSIZE;
uint blockNo = out->ndx / WRITE_BLOCKSIZE - n / WRITE_BLOCKSIZE;
return out->block[blockNo]->byte[pos];
}
/*
* On the first pass the break index is set to call this process at the end
* of each completed output buffer.
* - On the first call, the Flash Header is checked.
* - On each call the CRC is rolled up for that buffer.
* - Once the flags array is in-buffer this is also captured.
* This logic is slightly complicated by the last buffer is typically short.
*/
int procFirstPass (void) {
int len = (out->ndx % WRITE_BLOCKSIZE) ?
out->ndx % WRITE_BLOCKSIZE : WRITE_BLOCKSIZE;
if (out->ndx <= WRITE_BLOCKSIZE) {
uint32_t fl;
/* Process the flash header and cache the FlashHeader fields we need */
FlashHeader *fh = cast(FlashHeader *, out->block[0]);
out->flashLen = fh->flash_size; /* in bytes */
out->flagsLen = (out->len-fh->flash_size)/WORDSIZE; /* in words */
out->flash_sig = fh->flash_sig;
if ((fh->flash_sig & FLASH_FORMAT_MASK) != FLASH_FORMAT_VERSION)
flash_error("Incorrect LFS header version");
if ((fh->flash_sig & FLASH_SIG_B2_MASK) != FLASH_SIG_B2)
flash_error("Incorrect LFS build type");
if ((fh->flash_sig & ~FLASH_SIG_ABSOLUTE) != FLASH_SIG)
flash_error("incorrect LFS header signature");
if (fh->flash_size > FLASH_SIZE)
flash_error("LFS Image too big for configured LFS region");
if ((fh->flash_size & 0x3) ||
fh->flash_size > FLASH_SIZE ||
out->flagsLen != 1 + (out->flashLen/WORDSIZE - 1) / BITS_PER_WORD)
flash_error("LFS length mismatch");
out->flags = luaM_newvector(out->L, out->flagsLen, uint);
}
/* update running CRC */
out->crc = uzlib_crc32(out->block[0], len, out->crc);
/* copy out any flag vector */
if (out->ndx > out->flashLen) {
int start = out->flashLen - (out->ndx - len);
if (start < 0) start = 0;
memcpy(out->flags + out->flagsNdx, out->block[0]->byte + start, len - start);
out->flagsNdx += (len -start) / WORDSIZE; /* flashLen and len are word aligned */
}
return 1;
}
int procSecondPass (void) {
/*
* The length rules are different for the second pass since this only processes
* upto the flashLen and not the full image. This also works in word units.
* (We've already validated these are word multiples.)
*/
int i, len = (out->ndx > out->flashLen) ?
(out->flashLen % WRITE_BLOCKSIZE) / WORDSIZE :
WRITE_BLOCKSIZE / WORDSIZE;
uint32_t *buf = (uint32_t *) out->buffer.byte, flags;
/*
* Relocate all the addresses tagged in out->flags. This can't be done in
* place because the out->blocks are still in use as dictionary content so
* first copy the block to a working buffer and do the relocation in this.
*/
memcpy(out->buffer.byte, out->block[0]->byte, WRITE_BLOCKSIZE);
for (i=0; i<len; i++,flags>>=1 ) {
if ((i&31)==0)
flags = out->flags[out->flagsNdx++];
if (flags&1)
buf[i] = WORDSIZE*buf[i] + cast(uint32_t, flashAddr);
}
/*
* On first block, set the flash_sig has the in progress bit set and this
* is not cleared until end.
*/
if (out->ndx <= WRITE_BLOCKSIZE)
buf[0] = out->flash_sig | FLASH_SIG_IN_PROGRESS;
flashBlock(buf, len*WORDSIZE);
if (out->ndx >= out->flashLen) {
/* we're done so disable CB and rewrite flash sig to complete flash */
flashSetPosition(0);
flashBlock(&out->flash_sig, WORDSIZE);
out->fullBlkCB = NULL;
}
}
/*
* loadLFS)() is protected called from luaN_reload_reboot so that it can recover
* from out of memory and other thrown errors. loadLFSgc() GCs any resources.
*/
static int loadLFS (lua_State *L) {
const char *fn = cast(const char *, lua_touserdata(L, 1));
int i, n, res;
uint32_t crc;
/* Allocate and zero in and out structures */
in = NULL; out = NULL;
in = luaM_new(L, struct INPUT);
memset(in, 0, sizeof(*in));
out = luaM_new(L, struct OUTPUT);
memset(out, 0, sizeof(*out));
out->L = L;
out->fullBlkCB = procFirstPass;
out->crc = ~0;
/* Open LFS image/ file, read unpacked length from last 4 byte and rewind */
if (!(in->fd = vfs_open(fn, "r")))
flash_error("LFS image file not found");
in->len = vfs_size(in->fd);
if (in->len <= 200 || /* size of an empty luac output */
vfs_lseek(in->fd, in->len-4, VFS_SEEK_SET) != in->len-4 ||
vfs_read(in->fd, &out->len, sizeof(uint)) != sizeof(uint))
flash_error("read error on LFS image file");
vfs_lseek(in->fd, 0, VFS_SEEK_SET);
/* Allocate the out buffers */
for(i = 0; i <= WRITE_BLOCKS; i++)
out->block[i] = luaM_new(L, outBlock);
/* first inflate pass */
if (uzlib_inflate (get_byte, put_byte, recall_byte,
in->len, &crc, &in->inflate_state) < 0)
flash_error("read error on LFS image file");
if (crc != ~out->crc)
flash_error("checksum error on LFS image file");
out->fullBlkCB = procSecondPass;
out->flagsNdx = 0;
out->ndx = 0;
in->bytesRead = in->left = 0;
/*
* Once we have completed the 1st pass then the LFS image has passed the
* basic signature, crc and length checks, so now we can reset the counts
* to do the actual write to flash on the second pass.
*/
vfs_lseek(in->fd, 0, VFS_SEEK_SET);
flashErase(0,(out->flashLen - 1)/FLASH_PAGE_SIZE);
flashSetPosition(0);
if (uzlib_inflate(get_byte, put_byte, recall_byte,
in->len, &crc, &in->inflate_state) != UZLIB_OK)
if (res < 0) {
const char *err[] = {"Data_error during decompression",
"Chksum_error during decompression",
"Dictionary error during decompression"
"Memory_error during decompression"};
flash_error(err[UZLIB_DATA_ERROR - res]);
}
return 0;
}
static int loadLFSgc (lua_State *L) {
int i;
if (out) {
for (i = 0; i < WRITE_BLOCKS; i++)
if (out->block[i])
luaM_free(L, out->block[i]);
if (out->flags)
luaM_freearray(L, out->flags, out->flagsLen, uint32_t);
luaM_free(L, out);
}
if (in) {
if (in->fd)
vfs_close(in->fd);
luaM_free(L, in);
}
return 0;
}
#endif

View File

@ -15,7 +15,8 @@
#else
# define FLASH_SIG_B1 0x00
#endif
#define FLASH_FORMAT_VERSION (1 << 8)
#define FLASH_FORMAT_MASK 0xF00
#ifdef LUA_PACK_TVALUES
#ifdef LUA_NUMBER_INTEGRAL
#error "LUA_PACK_TVALUES is only valid for Floating point builds"
@ -24,9 +25,10 @@
#else
# define FLASH_SIG_B2 0x00
#endif
# define FLASH_SIG_B2_MASK 0x04
#define FLASH_SIG_ABSOLUTE 0x01
#define FLASH_SIG_IN_PROGRESS 0x08
#define FLASH_SIG (0xfafaaf50 | FLASH_SIG_B2 | FLASH_SIG_B1)
#define FLASH_SIG (0xfafaa050 | FLASH_FORMAT_VERSION |FLASH_SIG_B2 | FLASH_SIG_B1)
typedef lu_int32 FlashAddr;
typedef struct {

View File

@ -43,7 +43,7 @@
#define stringmark(s) if (!isLFSobject(&(s)->tsv)) {reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT);}
#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT)
#define isfinalized(u) testbit(getmarked(u), FINALIZEDBIT)
#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT)
@ -73,12 +73,12 @@ static void removeentry (Node *n) {
static void reallymarkobject (global_State *g, GCObject *o) {
/* don't mark LFS Protos (or strings) */
if (o->gch.tt == LUA_TPROTO && isLFSobject(&(o->gch)))
if (gettt(&o->gch) == LUA_TPROTO && isLFSobject(&(o->gch)))
return;
lua_assert(iswhite(o) && !isdead(g, o));
white2gray(o);
switch (o->gch.tt) {
switch (gettt(&o->gch)) {
case LUA_TSTRING: {
return;
}
@ -168,10 +168,14 @@ static int traversetable (global_State *g, Table *h) {
int i;
int weakkey = 0;
int weakvalue = 0;
const TValue *mode;
if (h->metatable && !luaR_isrotable(h->metatable))
markobject(g, h->metatable);
mode = gfasttm(g, h->metatable, TM_MODE);
const TValue *mode = luaO_nilobject;
if (h->metatable) {
if (!luaR_isrotable(h->metatable))
markobject(g, h->metatable);
mode = gfasttm(g, h->metatable, TM_MODE);
}
if (mode && ttisstring(mode)) { /* is there a weak mode? */
weakkey = (c_strchr(svalue(mode), 'k') != NULL);
weakvalue = (c_strchr(svalue(mode), 'v') != NULL);
@ -295,7 +299,7 @@ static l_mem propagatemark (global_State *g) {
GCObject *o = g->gray;
lua_assert(isgray(o));
gray2black(o);
switch (o->gch.tt) {
switch (gettt(&o->gch)) {
case LUA_TTABLE: {
Table *h = gco2h(o);
g->gray = h->gclist;
@ -400,7 +404,7 @@ static void cleartable (GCObject *l) {
static void freeobj (lua_State *L, GCObject *o) {
switch (o->gch.tt) {
switch (gettt(&o->gch)) {
case LUA_TPROTO:
lua_assert(!isLFSobject(&(o->gch)));
luaF_freeproto(L, gco2p(o));

View File

@ -102,8 +102,8 @@
#define fixedstack(x) l_setbit((x)->marked, FIXEDSTACKBIT)
#define unfixedstack(x) resetbit((x)->marked, FIXEDSTACKBIT)
#ifdef LUA_FLASH_STORE
#define isLFSobject(x) testbit((x)->marked, LFSBIT)
#define stringfix(s) if (!test2bits((s)->tsv.marked, FIXEDBIT, LFSBIT)) {l_setbit((s)->tsv.marked, FIXEDBIT);}
#define isLFSobject(x) testbit(getmarked(x), LFSBIT)
#define stringfix(s) if (!test2bits(getmarked(&(s)->tsv), FIXEDBIT, LFSBIT)) {l_setbit((s)->tsv.marked, FIXEDBIT);}
#else
#define isLFSobject(x) (0)
#define stringfix(s) {l_setbit((s)->tsv.marked, FIXEDBIT);}

View File

@ -15,60 +15,71 @@
#include "lauxlib.h"
#include "luaconf.h"
#include "module.h"
#if defined(LUA_CROSS_COMPILER)
BUILTIN_LIB( start_list, NULL, NULL);
BUILTIN_LIB_INIT( start_list, NULL, NULL);
#if !defined(LUA_CROSS_COMPILER) && !(MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2)
# error "NodeMCU modules must be built with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)"
#endif
extern const luaR_entry strlib[], tab_funcs[], dblib[],
co_funcs[], math_map[], syslib[];
extern const luaR_entry syslib[], io_funcs[]; // Only used on cross-compile builds
BUILTIN_LIB_INIT( BASE, "", luaopen_base);
BUILTIN_LIB_INIT( LOADLIB, LUA_LOADLIBNAME, luaopen_package);
BUILTIN_LIB( STRING, LUA_STRLIBNAME, strlib);
BUILTIN_LIB_INIT( STRING, LUA_STRLIBNAME, luaopen_string);
BUILTIN_LIB( TABLE, LUA_TABLIBNAME, tab_funcs);
BUILTIN_LIB_INIT( TABLE, LUA_TABLIBNAME, luaopen_table);
BUILTIN_LIB( DBG, LUA_DBLIBNAME, dblib);
BUILTIN_LIB_INIT( DBG, LUA_DBLIBNAME, luaopen_debug);
BUILTIN_LIB( CO, LUA_COLIBNAME, co_funcs);
BUILTIN_LIB( MATH, LUA_MATHLIBNAME, math_map);
/*
* The NodeMCU Lua initalisation has been adapted to use linker-based module
* registration. This uses a PSECT naming convention to allow the lib and rotab
* entries to be collected by the linker into consoliated tables. The linker
* defines lua_libs_base and lua_rotable_base.
*
* This is not practical on Posix builds which use a standard loader declaration
* so for cross compiler builds, separate ROTables are used for the base functions
* and library ROTables, with the latter chained from the former using its __index
* meta-method. In this case all library ROTables are defined here, avoiding the
* need for linker magic is avoided on host builds.
*/
#if defined(LUA_CROSS_COMPILER)
extern const luaR_entry syslib[], iolib[];
BUILTIN_LIB( OS, LUA_OSLIBNAME, syslib);
BUILTIN_LIB_INIT( IO, LUA_IOLIBNAME, luaopen_io);
BUILTIN_LIB( end_list, NULL, NULL);
BUILTIN_LIB_INIT( end_list, NULL, NULL);
/*
* These base addresses are internal to this module for cross compile builds
* This also exploits feature of the GCC code generator that the variables are
* emitted in either normal OR reverse order within PSECT.
*/
#define isascending(n) ((&(n ## _end_list)-&(n ## _start_list))>0)
static const luaL_Reg *lua_libs;
const luaR_table *lua_rotable;
#else
/* These base addresses are Xtensa toolchain linker constants for Firmware builds */
#define LUA_ROTABLES lua_rotable_base
#define LUA_LIBS lua_libs_base
#else /* declare Xtensa toolchain linker defined constants */
extern const luaL_Reg lua_libs_base[];
extern const luaR_table lua_rotable_base[];
static const luaL_Reg *lua_libs = lua_libs_base;
const luaR_table *lua_rotable = lua_rotable_base;
extern const luaR_entry lua_rotable_base[];
#define LUA_ROTABLES lua_rotable_core
#define LUA_LIBS lua_libs_core
#endif
static const LOCK_IN_SECTION(libs) luaL_reg LUA_LIBS[] = {
{"", luaopen_base},
{LUA_LOADLIBNAME, luaopen_package},
{LUA_STRLIBNAME, luaopen_string},
{LUA_TABLIBNAME, luaopen_table},
{LUA_DBLIBNAME, luaopen_debug}
#if defined(LUA_CROSS_COMPILER)
,{LUA_IOLIBNAME, luaopen_io},
{NULL, NULL}
#endif
};
#define ENTRY(n,t) {LSTRKEY(n), LRO_ROVAL(t)}
const LOCK_IN_SECTION(rotable) ROTable LUA_ROTABLES[] = {
ENTRY("ROM", LUA_ROTABLES),
ENTRY(LUA_STRLIBNAME, strlib),
ENTRY(LUA_TABLIBNAME, tab_funcs),
ENTRY(LUA_DBLIBNAME, dblib),
ENTRY(LUA_COLIBNAME, co_funcs),
ENTRY(LUA_MATHLIBNAME, math_map)
#if defined(LUA_CROSS_COMPILER)
,ENTRY(LUA_OSLIBNAME, syslib),
LROT_END
#endif
};
void luaL_openlibs (lua_State *L) {
#if defined(LUA_CROSS_COMPILER)
lua_libs = (isascending(lua_lib) ? &lua_lib_start_list : &lua_lib_end_list) + 1;
lua_rotable = (isascending(lua_rotable) ? &lua_rotable_start_list : &lua_rotable_end_list) + 1;
#endif
const luaL_Reg *lib = lua_libs;
const luaL_Reg *lib = lua_libs_base;
/* loop round and open libraries */
for (; lib->name; lib++) {
if (lib->func)
{
if (lib->func) {
lua_pushcfunction(L, lib->func);
lua_pushstring(L, lib->name);
lua_call(L, 1, 0);

View File

@ -15,7 +15,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#undef PI
#define PI (3.14159265358979323846)

View File

@ -24,7 +24,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
/* prefix for open functions in C libraries */
#define LUA_POF "luaopen_"
@ -474,10 +473,11 @@ static int ll_require (lua_State *L) {
return 1; /* package is already loaded */
}
/* Is this a readonly table? */
void *res = luaR_findglobal(name, c_strlen(name));
if (res) {
lua_pushrotable(L, res);
lua_getfield(L, LUA_GLOBALSINDEX, name);
if(lua_isrotable(L,-1)) {
return 1;
} else {
lua_pop(L, 1);
}
/* else must load it; iterate over available loaders */
lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
@ -563,8 +563,13 @@ static void modinit (lua_State *L, const char *modname) {
static int ll_module (lua_State *L) {
const char *modname = luaL_checkstring(L, 1);
if (luaR_findglobal(modname, c_strlen(modname)))
/* Is this a readonly table? */
lua_getfield(L, LUA_GLOBALSINDEX, modname);
if(lua_isrotable(L,-1)) {
return 0;
} else {
lua_pop(L, 1);
}
int loaded = lua_gettop(L) + 1; /* index of _LOADED table */
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
lua_getfield(L, loaded, modname); /* get _LOADED[modname] */

View File

@ -34,20 +34,33 @@
#define LUA_TUPVAL (LAST_TAG+2)
#define LUA_TDEADKEY (LAST_TAG+3)
#ifdef __XTENSA__
/*
** force aligned access to critical fields in Flash-based structures
** wo is the offset of aligned word in bytes 0,4,8,..
** bo is the field within the word in bits 0..31
*/
#define GET_BYTE_FN(name,t,wo,bo) \
static inline lu_byte get ## name(void *o) { \
lu_byte res; /* extract named field */ \
asm ("l32i %0, %1, " #wo "; extui %0, %0, " #bo ", 8;" : "=r"(res) : "r"(o) : );\
return res; }
#else
#define GET_BYTE_FN(name,t,wo,bo) \
static inline lu_byte get ## name(void *o) { return ((t *)o)->name; }
#endif
/*
** Union of all collectable objects
*/
typedef union GCObject GCObject;
/*
** Common Header for all collectable objects (in macro form, to be
** included in other objects)
*/
#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
/*
** Common header in struct form
*/
@ -55,11 +68,18 @@ typedef struct GCheader {
CommonHeader;
} GCheader;
/*
** Word aligned inline access functions for the CommonHeader tt and marked fields.
** Note that these MUST be consistent with the CommonHeader definition above. Arg
** 3 is a word offset (4 bytes in this case) and arg 4 the bit offset in the word.
*/
GET_BYTE_FN(tt,GCheader,4,0)
GET_BYTE_FN(marked,GCheader,4,8)
#if defined(LUA_PACK_VALUE) || defined(ELUA_ENDIAN_BIG) || defined(ELUA_ENDIAN_SMALL)
# error "NodeMCU does not support the eLua LUA_PACK_VALUE and ELUA_ENDIAN defines"
#endif
/*
** Union of all Lua values
*/
@ -214,7 +234,6 @@ typedef struct lua_TValue {
#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
typedef TValue *StkId; /* index to stack elements */
@ -386,6 +405,7 @@ typedef struct Table {
int sizearray; /* size of `array' array */
} Table;
typedef const struct luaR_entry ROTable;
/*
** `module' operation for hashing (size is always a power of 2)

View File

@ -38,5 +38,10 @@
return 1
#endif
#define LROT_TABENTRY(n,t) {LSTRKEY(#n), LRO_ROVAL(t)}
#define LROT_FUNCENTRY(n,f) {LSTRKEY(#n), LRO_FUNCVAL(f)}
#define LROT_NUMENTRY(n,x) {LSTRKEY(#n), LRO_NUMVAL(x)}
#define LROT_END {LNILKEY, LNILVAL}
#endif /* lrodefs_h */

View File

@ -9,77 +9,139 @@
#include "lobject.h"
#include "lapi.h"
/* Local defines */
#define LUAR_FINDFUNCTION 0
#define LUAR_FINDVALUE 1
#define ALIGNED_STRING (__attribute__((aligned(4))) char *)
#define LA_LINES 16
#define LA_SLOTS 4
//#define COLLECT_STATS
/* Externally defined read-only table array */
extern const luaR_table *lua_rotable;
/*
* All keyed ROtable access passes through luaR_findentry(). ROTables
* are simply a list of <key><TValue value> pairs. The existing algo
* did a linear scan of this vector of pairs looking for a match.
*
* A N×M lookaside cache has been added, with a simple hash on the key's
* TString addr and the ROTable addr to identify one of N lines. Each
* line has M slots which are scanned. This is all done in RAM and is
* perhaps 20x faster than the corresponding random Flash accesses which
* will cause flash faults.
*
* If a match is found and the table addresses match, then this entry is
* probed first. In practice the hit-rate here is over 99% so the code
* rarely fails back to doing the linear scan in ROM.
*
* Note that this hash does a couple of prime multiples and a modulus 2^X
* with is all evaluated in H/W, and adequately randomizes the lookup.
*/
#define HASH(a,b) (519*((size_t)(a)>>4) + 17*((size_t)(b)>>4))
/* Find a global "read only table" in the constant lua_rotable array */
void* luaR_findglobal(const char *name, unsigned len) {
unsigned i;
static struct {
unsigned hash;
unsigned addr:24;
unsigned ndx:8;
} cache[LA_LINES][LA_SLOTS];
if (c_strlen(name) > LUA_MAX_ROTABLE_NAME)
return NULL;
for (i=0; lua_rotable[i].name; i ++)
if (*lua_rotable[i].name != '\0' && c_strlen(lua_rotable[i].name) == len && !c_strncmp(lua_rotable[i].name, name, len)) {
return (void*)(lua_rotable[i].pentries);
#ifdef COLLECT_STATS
unsigned cache_stats[3];
#define COUNT(i) cache_stats[i]++
#else
#define COUNT(i)
#endif
static int lookup_cache(unsigned hash, ROTable *rotable) {
int i = (hash>>2) & (LA_LINES-1), j;
for (j = 0; j<LA_SLOTS; j++) {
if (cache[i][j].hash == hash &&
((size_t)rotable & 0xffffffu) == cache[i][j].addr) {
COUNT(0);
return cache[i][j].ndx;
}
}
COUNT(1);
return -1;
}
static void update_cache(unsigned hash, ROTable *rotable, unsigned ndx) {
int i = (hash)>>2 & (LA_LINES-1), j;
COUNT(2);
if (ndx>0xffu)
return;
for (j = LA_SLOTS-1; j>0; j--)
cache[i][j] = cache[i][j-1];
cache[i][0].hash = hash;
cache[i][0].addr = (size_t) rotable;
cache[i][0].ndx = ndx;
}
/*
* Find a string key entry in a rotable and return it. Note that this internally
* uses a null key to denote a metatable search.
*/
const TValue* luaR_findentry(ROTable *rotable, TString *key, unsigned *ppos) {
const luaR_entry *pentry = rotable;
const char *strkey = key ? getstr(key) : ALIGNED_STRING "__metatable" ;
size_t hash = HASH(rotable, key);
unsigned i = 0;
int j = lookup_cache(hash, rotable);
if (pentry) {
if (j >= 0){
if ((pentry[j].key.type == LUA_TSTRING) &&
!c_strcmp(pentry[j].key.id.strkey, strkey)) {
if (ppos)
*ppos = j;
return &pentry[j].value;
}
}
/*
* The invariants for 1st word comparison are deferred to here since they
* aren't needed if there is a cache hit. Note that the termination null
* is included so a "on\0" has a mask of 0xFFFFFF and "a\0" has 0xFFFF.
*/
unsigned name4 = *(unsigned *)strkey;
unsigned l = key ? key->tsv.len : sizeof("__metatable")-1;
unsigned mask4 = l > 2 ? (~0u) : (~0u)>>((3-l)*8);
for(;pentry->key.type != LUA_TNIL; i++, pentry++) {
if ((pentry->key.type == LUA_TSTRING) &&
((*(unsigned *)pentry->key.id.strkey ^ name4) & mask4) == 0 &&
!c_strcmp(pentry->key.id.strkey, strkey)) {
if (ppos)
*ppos = i;
if (j==-1) {
update_cache(hash, rotable, pentry - rotable);
} else if (j != (pentry - rotable)) {
j = 0;
}
return &pentry->value;
}
}
}
return luaO_nilobject;
}
const TValue* luaR_findentryN(ROTable *rotable, luaR_numkey numkey, unsigned *ppos) {
unsigned i = 0;
const luaR_entry *pentry = rotable;
if (pentry) {
for ( ;pentry->key.type != LUA_TNIL; i++, pentry++) {
if (pentry->key.type == LUA_TNUMBER && (luaR_numkey) pentry->key.id.numkey == numkey) {
if (ppos)
*ppos = i;
return &pentry->value;
}
}
}
return NULL;
}
/* Find an entry in a rotable and return it */
static const TValue* luaR_auxfind(const luaR_entry *pentry, const char *strkey, luaR_numkey numkey, unsigned *ppos) {
const TValue *res = NULL;
unsigned i = 0;
if (pentry == NULL)
return NULL;
while(pentry->key.type != LUA_TNIL) {
if ((strkey && (pentry->key.type == LUA_TSTRING) && (!c_strcmp(pentry->key.id.strkey, strkey))) ||
(!strkey && (pentry->key.type == LUA_TNUMBER) && ((luaR_numkey)pentry->key.id.numkey == numkey))) {
res = &pentry->value;
break;
}
i ++; pentry ++;
}
if (res && ppos)
*ppos = i;
return res;
}
int luaR_findfunction(lua_State *L, const luaR_entry *ptable) {
const TValue *res = NULL;
const char *key = luaL_checkstring(L, 2);
res = luaR_auxfind(ptable, key, 0, NULL);
if (res && ttislightfunction(res)) {
luaA_pushobject(L, res);
return 1;
}
else
return 0;
}
/* Find an entry in a rotable and return its type
If "strkey" is not NULL, the function will look for a string key,
otherwise it will look for a number key */
const TValue* luaR_findentry(void *data, const char *strkey, luaR_numkey numkey, unsigned *ppos) {
return luaR_auxfind((const luaR_entry*)data, strkey, numkey, ppos);
}
/* Find the metatable of a given table */
void* luaR_getmeta(void *data) {
#ifdef LUA_META_ROTABLES
const TValue *res = luaR_auxfind((const luaR_entry*)data, "__metatable", 0, NULL);
void* luaR_getmeta(ROTable *rotable) {
const TValue *res = luaR_findentry(rotable, NULL, NULL);
return res && ttisrotable(res) ? rvalue(res) : NULL;
#else
return NULL;
#endif
}
static void luaR_next_helper(lua_State *L, const luaR_entry *pentries, int pos, TValue *key, TValue *val) {
static void luaR_next_helper(lua_State *L, ROTable *pentries, int pos,
TValue *key, TValue *val) {
setnilvalue(key);
setnilvalue(val);
if (pentries[pos].key.type != LUA_TNIL) {
@ -91,56 +153,24 @@ static void luaR_next_helper(lua_State *L, const luaR_entry *pentries, int pos,
setobj2s(L, val, &pentries[pos].value);
}
}
/* next (used for iteration) */
void luaR_next(lua_State *L, void *data, TValue *key, TValue *val) {
const luaR_entry* pentries = (const luaR_entry*)data;
char strkey[LUA_MAX_ROTABLE_NAME + 1], *pstrkey = NULL;
luaR_numkey numkey = 0;
void luaR_next(lua_State *L, ROTable *rotable, TValue *key, TValue *val) {
unsigned keypos;
/* Special case: if key is nil, return the first element of the rotable */
if (ttisnil(key))
luaR_next_helper(L, pentries, 0, key, val);
if (ttisnil(key))
luaR_next_helper(L, rotable, 0, key, val);
else if (ttisstring(key) || ttisnumber(key)) {
/* Find the previoud key again */
/* Find the previous key again */
if (ttisstring(key)) {
luaR_getcstr(strkey, rawtsvalue(key), LUA_MAX_ROTABLE_NAME);
pstrkey = strkey;
} else
numkey = (luaR_numkey)nvalue(key);
luaR_findentry(data, pstrkey, numkey, &keypos);
luaR_findentry(rotable, rawtsvalue(key), &keypos);
} else {
luaR_findentryN(rotable, (luaR_numkey)nvalue(key), &keypos);
}
/* Advance to next key */
keypos ++;
luaR_next_helper(L, pentries, keypos, key, val);
keypos ++;
luaR_next_helper(L, rotable, keypos, key, val);
}
}
/* Convert a Lua string to a C string */
void luaR_getcstr(char *dest, const TString *src, size_t maxsize) {
if (src->tsv.len+1 > maxsize)
dest[0] = '\0';
else {
c_memcpy(dest, getstr(src), src->tsv.len);
dest[src->tsv.len] = '\0';
}
}
#ifdef LUA_META_ROTABLES
/* Set in RO check depending on platform */
#if defined(LUA_CROSS_COMPILER) && defined(__CYGWIN__)
extern char __end__[];
#define IN_RO_AREA(p) ((p) < __end__)
#elif defined(LUA_CROSS_COMPILER)
extern char _edata[];
#define IN_RO_AREA(p) ((p) < _edata)
#else /* xtensa tool chain for ESP target */
extern char _irom0_text_start[];
extern char _irom0_text_end[];
#define IN_RO_AREA(p) ((p) >= _irom0_text_start && (p) <= _irom0_text_end)
#endif
/* Return 1 if the given pointer is a rotable */
int luaR_isrotable(void *p) {
return IN_RO_AREA((char *)p);
}
#endif

View File

@ -14,7 +14,11 @@
#define LRO_NUMVAL(v) {{.n = v}, LUA_TNUMBER}
#define LRO_ROVAL(v) {{.p = (void*)v}, LUA_TROTABLE}
#define LRO_NILVAL {{.p = NULL}, LUA_TNIL}
#ifdef LUA_CROSS_COMPILER
#define LRO_STRKEY(k) {LUA_TSTRING, {.strkey = k}}
#else
#define LRO_STRKEY(k) {LUA_TSTRING, {.strkey = (STORE_ATTR char *) k}}
#endif
#define LRO_NUMKEY(k) {LUA_TNUMBER, {.numkey = k}}
#define LRO_NILKEY {LUA_TNIL, {.strkey=NULL}}
@ -25,40 +29,58 @@
typedef int luaR_numkey;
/* The next structure defines the type of a key */
typedef struct
{
typedef struct {
int type;
union
{
union {
const char* strkey;
luaR_numkey numkey;
} id;
} luaR_key;
/* An entry in the read only table */
typedef struct
{
typedef struct luaR_entry {
const luaR_key key;
const TValue value;
} luaR_entry;
/* A rotable */
typedef struct
{
const char *name;
const luaR_entry *pentries;
} luaR_table;
/*
* The current ROTable implmentation is a vector of luaR_entry terminated by a
* nil record. The convention is to use ROtable * to refer to the entire vector
* as a logical ROTable.
*/
typedef const struct luaR_entry ROTable;
void* luaR_findglobal(const char *key, unsigned len);
int luaR_findfunction(lua_State *L, const luaR_entry *ptable);
const TValue* luaR_findentry(void *data, const char *strkey, luaR_numkey numkey, unsigned *ppos);
void luaR_getcstr(char *dest, const TString *src, size_t maxsize);
void luaR_next(lua_State *L, void *data, TValue *key, TValue *val);
void* luaR_getmeta(void *data);
#ifdef LUA_META_ROTABLES
const TValue* luaR_findentry(ROTable *tab, TString *key, unsigned *ppos);
const TValue* luaR_findentryN(ROTable *tab, luaR_numkey numkey, unsigned *ppos);
void luaR_next(lua_State *L, ROTable *tab, TValue *key, TValue *val);
void* luaR_getmeta(ROTable *tab);
int luaR_isrotable(void *p);
/*
* Set inRO check depending on platform. Note that this implementation needs
* to work on both the host (luac.cross) and ESP targets. The luac.cross
* VM is used for the -e option, and is primarily used to be able to debug
* VM changes on the more developer-friendly hot gdb environment.
*/
#if defined(LUA_CROSS_COMPILER)
#if defined(__CYGWIN__)
#define _RODATA_END __end__
#else
#define luaR_isrotable(p) (0)
#endif
#define _RODATA_END _edata
#endif
extern const char _RODATA_END[];
#define IN_RODATA_AREA(p) (((const char *)(p)) < _RODATA_END)
#else /* xtensa tool chain for ESP target */
extern const char _irom0_text_start[];
extern const char _irom0_text_end[];
#define IN_RODATA_AREA(p) (((const char *)(p)) >= _irom0_text_start && ((const char *)(p)) <= _irom0_text_end)
#endif
/* Return 1 if the given pointer is a rotable */
#define luaR_isrotable(p) IN_RODATA_AREA(p)
#endif

View File

@ -80,16 +80,12 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
return ts;
}
#ifdef LUA_CROSS_COMPILER
#define IN_RO_AREA(p) (0)
#else /* xtensa tool chain for ESP */
extern char _irom0_text_start[];
extern char _irom0_text_end[];
#define IN_RO_AREA(p) ((p) >= _irom0_text_start && (p) <= _irom0_text_end)
static int lua_is_ptr_in_ro_area(const char *p) {
#ifdef LUA_CROSS_COMPILER
return 0; // TStrings are never in RO in luac.cross
#else
return IN_RODATA_AREA(p);
#endif
int lua_is_ptr_in_ro_area(const char *p) {
return IN_RO_AREA(p);
}
/*

View File

@ -13,7 +13,7 @@
#include "lstate.h"
#define sizestring(s) (sizeof(union TString)+(testbit((s)->marked, READONLYBIT) ? sizeof(char **) : ((s)->len+1)*sizeof(char)))
#define sizestring(s) (sizeof(union TString)+(testbit(getmarked(s), READONLYBIT) ? sizeof(char **) : ((s)->len+1)*sizeof(char)))
#define sizeudata(u) (sizeof(union Udata)+(u)->len)

View File

@ -15,7 +15,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
/* macro to `unsign' a character */
#define uchar(c) ((unsigned char)(c))

View File

@ -580,7 +580,7 @@ const TValue *luaH_getnum (Table *t, int key) {
/* same thing for rotables */
const TValue *luaH_getnum_ro (void *t, int key) {
const TValue *res = luaR_findentry(t, NULL, key, NULL);
const TValue *res = luaR_findentryN(t, key, NULL);
return res ? res : luaO_nilobject;
}
@ -599,14 +599,10 @@ const TValue *luaH_getstr (Table *t, TString *key) {
}
/* same thing for rotables */
const TValue *luaH_getstr_ro (void *t, TString *key) {
char keyname[LUA_MAX_ROTABLE_NAME + 1];
const TValue *res;
if (!t)
const TValue *luaH_getstr_ro (void *t, TString *key) {
if (!t || key->tsv.len>LUA_MAX_ROTABLE_NAME)
return luaO_nilobject;
luaR_getcstr(keyname, key, LUA_MAX_ROTABLE_NAME);
res = luaR_findentry(t, keyname, 0, NULL);
return res ? res : luaO_nilobject;
return luaR_findentry(t, key, NULL);
}
@ -745,7 +741,7 @@ int luaH_getn (Table *t) {
int luaH_getn_ro (void *t) {
int i = 1, len=0;
while(luaR_findentry(t, NULL, i ++, NULL))
while(luaR_findentryN(t, i ++, NULL))
len ++;
return len;
}

View File

@ -13,7 +13,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))

View File

@ -50,14 +50,22 @@ void luaT_init (lua_State *L) {
** tag methods
*/
const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
const TValue *tm = luaR_isrotable(events) ? luaH_getstr_ro(events, ename) : luaH_getstr(events, ename);
const TValue *tm;
lua_assert(event <= TM_EQ);
if (ttisnil(tm)) { /* no tag method? */
if (!luaR_isrotable(events))
if (luaR_isrotable(events)) {
tm = luaH_getstr_ro(events, ename);
if (ttisnil(tm)) { /* no tag method? */
return NULL;
}
} else {
tm = luaH_getstr(events, ename);
if (ttisnil(tm)) { /* no tag method? */
events->flags |= cast_byte(1u<<event); /* cache this fact */
return NULL;
}
else return tm;
return NULL;
}
}
return tm;
}

View File

@ -9,7 +9,7 @@
#include "lobject.h"
#include "lrotable.h"
/*
* WARNING: if you change the order of this enumeration,
@ -36,12 +36,10 @@ typedef enum {
TM_N /* number of elements in the enum */
} TMS;
#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
!luaR_isrotable(et) && ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
(!luaR_isrotable(et) && ((et)->flags & (1u<<(e)))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
#define fasttm(l,et,e) gfasttm(G(l), et, e)
#define fasttm(l,et,e) gfasttm(G(l), et, e)
LUAI_DATA const char *const luaT_typenames[];

View File

@ -1,12 +1,12 @@
#
# This Make file is called from the core Makefile hierarchy which is a hierarchical
# make which uses parent callbacks to implement inheritance. However if luac_cross
# build stands outside this it uses the host toolchain to implement a separate
# This Make file is called from the core Makefile hierarchy with is a hierarchical
# make wwhich uses parent callbacks to implement inheritance. However is luac_cross
# build stands outside this and uses the host toolchain to implement a separate
# host build of the luac.cross image.
#
.NOTPARALLEL:
CCFLAGS:= -I.. -I../../include -I../../../include -I ../../libc
CCFLAGS:= -I.. -I../../include -I../../libc -I../../uzlib
LDFLAGS:= -L$(SDK_DIR)/lib -L$(SDK_DIR)/ld -lm -ldl -Wl,-Map=mapfile
CCFLAGS += -Wall
@ -18,6 +18,7 @@ TARGET = host
ifeq ($(FLAVOR),debug)
CCFLAGS += -O0 -g
TARGET_LDFLAGS += -O0 -g
DEFINES += -DLUA_DEBUG_BUILD
else
FLAVOR = release
CCFLAGS += -O2
@ -31,13 +32,13 @@ LUASRC := lapi.c lauxlib.c lbaselib.c lcode.c ldblib.c ldebug.c
lrotable.c lstate.c lstring.c lstrlib.c ltable.c ltablib.c \
ltm.c lundump.c lvm.c lzio.c
LIBCSRC := c_stdlib.c
UZSRC := uzlib_deflate.c crc32.c
#
# This relies on the files being unique on the vpath
#
SRC := $(LUACSRC) $(LUASRC) $(LIBCSRC)
vpath %.c .:..:../../libc
SRC := $(LUACSRC) $(LUASRC) $(LIBCSRC) $(UZSRC)
vpath %.c .:..:../../libc:../../uzlib
ODIR := .output/$(TARGET)/$(FLAVOR)/obj
@ -51,12 +52,7 @@ CC := $(WRAPCC) gcc
ECHO := echo
BUILD_TYPE := $(shell $(CC) $(EXTRA_CCFLAGS) -E -dM - <../../../app/include/user_config.h | grep LUA_NUMBER_INTEGRAL | wc -l)
ifeq ($(BUILD_TYPE),0)
IMAGE := ../../../luac.cross
else
IMAGE := ../../../luac.cross.int
endif
.PHONY: test clean all
@ -70,7 +66,6 @@ test :
@echo SRC: $(SRC)
@echo OBJS: $(OBJS)
@echo DEPS: $(DEPS)
@echo IMAGE: $(IMAGE)
clean :
$(RM) -r $(ODIR)

View File

@ -1,4 +1,4 @@
/*
/***--
** lflashimg.c
** Dump a compiled Proto hiearchy to a RO (FLash) image file
** See Copyright Notice in lua.h
@ -19,6 +19,7 @@
#undef LUA_FLASH_STORE
#define LUA_FLASH_STORE
#include "lflash.h"
#include "uzlib.h"
//#define LOCAL_DEBUG
@ -46,18 +47,18 @@ typedef unsigned int uint;
* independent image format, which permits the on-device image loader to load the LFS
* image at an appropriate base within the flash address space. As all objects in the
* LFS can be treated as multiples of 4-byte words, also all address fields are both
* word aligned, and any address references within the LFS are also word-aligned,
* such addresses are stored in a special format, where each PI address is two
* 16-bit unsigned offsets:
* word aligned, and any address references within the LFS are also word-aligned.
*
* Bits 0-15 is the offset into the LFS that this address refers to
* Bits 16-31 is the offset linking to the PIC next address.
* This version adds gzip compression of the generated LFS image for more efficient
* over-the-air (OTA) transfer, so the method of tagging address words has been
* replaced by a scheme which achieves better compression: an additional bitmap
* has been added to the image, with each bit corresponding to a word in the image
* and set if the corresponding work is an address. The addresses are stored as
* signed relative word offsets.
*
* Hence the LFS can be up to 256Kb in length and the flash loader can use the forward
* links to chain down PI address from the mainProto address at offet 3 to all image
* addresses during load and convert them to the corresponding correct absolute memory
* addresses. This reloation process is skipped for absolute addressed images (which
* are identified by the FLASH_SIG_ABSOLUTE bit setting in the flash signature.
* The unloader is documented in lflash.c Note that his relocation process is
* skipped for absolute addressed images (which are identified by the
* FLASH_SIG_ABSOLUTE bit setting in the flash signature).
*
* The flash image has a standard header detailed in lflash.h
*
@ -66,7 +67,7 @@ typedef unsigned int uint;
* and int may not have the same size. Hence addresses with the must be declared as
* the FlashAddr type rather than typed C pointers and must be accessed through macros.
*
* ALso note that image built with a given LUA_PACK_TVALUES / LUA_NUNBER_INTEGRAL
* Also note that image built with a given LUA_PACK_TVALUES / LUA_NUNBER_INTEGRAL
* combination must be loaded into a corresponding firmware build. Hence these
* configuration options are also included in the FLash Signature.
*
@ -96,8 +97,19 @@ typedef struct flashts { /* This is the fixed 32-bit equivalent of TString
#endif
static uint curOffset = 0;
static uint flashImage[LUA_MAX_FLASH_SIZE];
static unsigned char flashAddrTag[LUA_MAX_FLASH_SIZE/WORDSIZE];
/*
* The flashAddrTag is a bit array, one bit per flashImage word denoting
* whether the corresponding word is a relative address. The defines
* are access methods for this bit array.
*/
static uint flashImage[LUA_MAX_FLASH_SIZE + LUA_MAX_FLASH_SIZE/32];
static uint *flashAddrTag = flashImage + LUA_MAX_FLASH_SIZE;
#define _TW(v) (v)>>5
#define _TB(v) (1<<((v)&0x1F))
#define setFlashAddrTag(v) flashAddrTag[_TW(v)] |= _TB(v)
#define getFlashAddrTag(v) ((flashAddrTag[_TW(v)]&_TB(v)) != 0)
#define fatal luac_fatal
extern void __attribute__((noreturn)) luac_fatal(const char* message);
@ -115,7 +127,7 @@ static void *flashAlloc(lua_State* L, size_t n) {
void *p = (void *)(flashImage + curOffset);
curOffset += ALIGN(n)>>WORDSHIFT;
if (curOffset > LUA_MAX_FLASH_SIZE) {
fatal("Out of Flash memmory");
fatal("Out of Flash memory");
}
return p;
}
@ -128,8 +140,8 @@ static void *flashAlloc(lua_State* L, size_t n) {
#define toFlashAddr(l, pd, s) _toFlashAddr(l, &(pd), s)
static void _toFlashAddr(lua_State* L, FlashAddr *a, void *p) {
uint doffset = cast(char *, a) - cast(char *,flashImage);
lua_assert(!(doffset & (WORDSIZE-1)));
doffset >>= WORDSHIFT;
lua_assert(!(doffset & (WORDSIZE-1))); // check word aligned
doffset >>= WORDSHIFT; // and convert to a word offset
lua_assert(doffset <= curOffset);
if (p) {
uint poffset = cast(char *, p) - cast(char *,flashImage);
@ -137,10 +149,8 @@ static void _toFlashAddr(lua_State* L, FlashAddr *a, void *p) {
poffset >>= WORDSHIFT;
lua_assert(poffset <= curOffset);
flashImage[doffset] = poffset; // Set the pointer to the offset
flashAddrTag[doffset] = 1; // And tag as an address
} else { // Special case for NULL pointer
flashImage[doffset] = 0;
}
setFlashAddrTag(doffset); // And tag as an address
} /* else leave clear */ // Special case for NULL pointer
}
/*
@ -231,7 +241,7 @@ static void createROstrt(lua_State *L, FlashHeader *fh) {
fts->marked = bitmask(LFSBIT); // LFS string with no Whitebits set
fts->hash = hash; // add hash
fts->len = len; // and length
memcpy(flashAlloc(L, ALIGN(len+1)), p, ALIGN(len+1)); // copy string
memcpy(flashAlloc(L, len+1), p, len+1); // copy string
// include the trailing null char
lua_pop(L, 1); // Junk the value
lua_pushvalue(L, -1); // Dup the key as rawset dumps its copy
@ -308,6 +318,9 @@ static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) {
case 'I':
*d++ = *s++;
break;
case 'H':
*d++ = (*s++) & 0;
break;
case 'S':
newts = resolveTString(L, *cast(TString **, s));
toFlashAddr(L, *d, newts);
@ -318,11 +331,15 @@ static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) {
/* This code has to work for both Integer and Float build variants */
memset(d, 0, TARGET_TV_SIZE);
TValue *sv = cast(TValue *, s);
/* The value is 0, 4 or 8 bytes depending on type */
if (ttisstring(sv)) {
toFlashAddr(L, *d, resolveTString(L, rawtsvalue(sv)));
} else { /* non-collectable types all of size lua_Number */
lua_assert(!iscollectable(sv));
} else if (ttisnumber(sv)) {
*cast(lua_Number*,d) = *cast(lua_Number*,s);
} else if (!ttisnil(sv)){
/* all other types are 4 byte */
lua_assert(!iscollectable(sv));
*cast(uint *,d) = *cast(uint *,s);
}
*cast(int *,cast(lua_Number*,d)+1) = ttype(sv);
s += FLASH_WORDS(TValue);
@ -338,9 +355,9 @@ static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) {
/* The debug optimised version has a different Proto layout */
#ifdef LUA_OPTIMIZE_DEBUG
#define PROTO_COPY_MASK "AIAAAAAASIIIIIIIAI"
#define PROTO_COPY_MASK "AHAAAAAASIIIIIIIAI"
#else
#define PROTO_COPY_MASK "AIAAAAAASIIIIIIIIAI"
#define PROTO_COPY_MASK "AHAAAAAASIIIIIIIIAI"
#endif
/*
@ -378,44 +395,52 @@ static void *functionToFlash(lua_State* L, const Proto* orig) {
return cast(void *, flashCopy(L, 1, PROTO_COPY_MASK, &f));
}
/*
* Scan through the tagged addresses. This operates in one of two modes.
* - If address is non-zero then the offset is converted back into an absolute
* mapped flash address using the specified address base.
*
* - If the address is zero then form a form linked chain with the upper 16 bits
* the link to the last offset. As the scan is backwards, this 'last' address
* becomes forward reference for the on-chip LFS loader.
*/
void linkAddresses(lu_int32 address){
int i, last = 0;
for (i = curOffset-1 ; i >= 0; i--) {
if (flashAddrTag[i]) {
lua_assert(flashImage[i]<curOffset);
if (address) {
flashImage[i] = 4*flashImage[i] + address;
} else {
flashImage[i] |= last<<16;
last = i;
}
}
}
}
uint dumpToFlashImage (lua_State* L, const Proto *main, lua_Writer w,
void* data, int strip, lu_int32 address) {
void* data, int strip,
lu_int32 address, lu_int32 maxSize) {
// parameter strip is ignored for now
lua_newtable(L);
FlashHeader *fh = cast(FlashHeader *, flashAlloc(L, sizeof(FlashHeader)));
int i, status;
lua_newtable(L);
scanProtoStrings(L, main);
createROstrt(L, fh);
toFlashAddr(L, fh->mainProto, functionToFlash(L, main));
fh->flash_sig = FLASH_SIG + (address ? FLASH_SIG_ABSOLUTE : 0);
fh->flash_size = curOffset*WORDSIZE;
linkAddresses(address);
lua_unlock(L);
int status = w(L, flashImage, curOffset * sizeof(uint), data);
if (fh->flash_size>maxSize) {
fatal ("The image is too large for specfied LFS size");
}
if (address) { /* in absolute mode convert addresses to mapped address */
for (i = 0 ; i < curOffset; i++)
if (getFlashAddrTag(i))
flashImage[i] = 4*flashImage[i] + address;
lua_unlock(L);
status = w(L, flashImage, fh->flash_size, data);
} else { /* compressed PI mode */
/*
* In image mode, shift the relocation bitmap down directly above
* the used flashimage. This consolidated array is then gzipped.
*/
uint oLen;
uint8_t *oBuf;
int bmLen = sizeof(uint)*((curOffset+31)/32); /* 32 flags to a word */
memmove(flashImage+curOffset, flashAddrTag, bmLen);
status = uzlib_compress (&oBuf, &oLen,
(const uint8_t *)flashImage, bmLen+fh->flash_size);
if (status != UZLIB_OK) {
luac_fatal("Out of memory during image compression");
}
lua_unlock(L);
#if 0
status = w(L, flashImage, bmLen+fh->flash_size, data);
#else
status = w(L, oBuf, oLen, data);
free(oBuf);
#endif
}
lua_lock(L);
return status;
}

View File

@ -18,7 +18,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#define IO_INPUT 1
#define IO_OUTPUT 2
@ -28,7 +27,11 @@
#define LUA_IO_SETFIELD(f) lua_rawseti(L, LUA_REGISTRYINDEX,(int)(liolib_keys[f]))
/* "Pseudo-random" keys for the registry */
static const size_t liolib_keys[] = {(size_t)&luaL_callmeta, (size_t)&luaL_typerror, (size_t)&luaL_argerror};
static const size_t liolib_keys[] = {
(size_t)&luaL_callmeta,
(size_t)&luaL_typerror,
(size_t)&luaL_argerror
};
static const char *const fnames[] = {"input", "output"};
@ -452,20 +455,6 @@ const LUA_REG_TYPE iolib_funcs[] = {
{LNILKEY, LNILVAL}
};
/* Note that IO objects use a RAM metatable created to allow extensibility */
static int io_index(lua_State *L)
{
return luaR_findfunction(L, iolib_funcs);
}
const luaL_Reg iolib[] = {
{"__index", io_index},
{NULL, NULL}
};
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 1
#include "lrodefs.h"
const LUA_REG_TYPE flib[] = {
{LSTRKEY("close"), LFUNCVAL(io_close)},
@ -481,6 +470,7 @@ const LUA_REG_TYPE flib[] = {
{LNILKEY, LNILVAL}
};
static const luaL_Reg io_base[] = {{NULL, NULL}};
static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
*newfile(L) = f;
@ -490,14 +480,18 @@ static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
lua_setfield(L, -2, fname);
}
LUALIB_API int luaopen_io (lua_State *L) {
luaL_rometatable(L, LUA_FILEHANDLE, (void*)flib); /* create metatable for file handles */
luaL_register_light(L, LUA_IOLIBNAME, iolib);
LUALIB_API int luaopen_io(lua_State *L) {
luaL_rometatable(L, LUA_FILEHANDLE, (void*) flib); /* create metatable for file handles */
luaL_register_light(L, LUA_IOLIBNAME, io_base);
lua_pushvalue(L, -1);
lua_setmetatable(L, -2);
lua_pushliteral(L, "__index");
lua_pushrotable(L, (void *)iolib_funcs);
lua_rawset(L, -3);
/* create (and set) default files */
createstdfile(L, stdin, IO_INPUT, "stdin");
createstdfile(L, stdout, IO_OUTPUT, "stdout");
createstdfile(L, stderr, 0, "stderr");
createstdfile(L, stderr, IO_STDERR, "stderr");
return 1;
}

View File

@ -20,8 +20,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
static int os_pushresult (lua_State *L, int i, const char *filename) {
int en = errno; /* calls to Lua API may change this value */

View File

@ -35,6 +35,7 @@ static int dumping=1; /* dump bytecodes? */
static int stripping=0; /* strip debug information? */
static int flash=0; /* output flash image */
static lu_int32 address=0; /* output flash image at absolute location */
static lu_int32 maxSize=0x40000; /* maximuum uncompressed image size */
static int lookup=0; /* output lookup-style master combination header */
static char Output[]={ OUTPUT }; /* default output file name */
static const char* output=Output; /* actual output file name */
@ -72,6 +73,7 @@ static void usage(const char* message)
" -f output a flash image file\n"
" -a addr generate an absolute, rather than position independent flash image file\n"
" -i generate lookup combination master (default with option -f)\n"
" -m size maximum LFS image in bytes\n"
" -p parse only\n"
" -s strip debug information\n"
" -v show version information\n"
@ -123,6 +125,13 @@ static int doargs(int argc, char* argv[])
lookup = 1;
else if (IS("-l")) /* list */
++listing;
else if (IS("-m")) /* specify a maximum image size */
{
flash=lookup=1;
maxSize=strtol(argv[++i],NULL,0);
if (maxSize & 0xFFF)
usage(LUA_QL("-e") " maximum size must be a multiple of 4,096");
}
else if (IS("-o")) /* output file */
{
output=argv[++i];
@ -264,7 +273,8 @@ struct Smain {
};
extern uint dumpToFlashImage (lua_State* L,const Proto *main, lua_Writer w,
void* data, int strip, lu_int32 address);
void* data, int strip,
lu_int32 address, lu_int32 maxSize);
static int pmain(lua_State* L)
{
@ -302,7 +312,7 @@ static int pmain(lua_State* L)
lua_lock(L);
if (flash)
{
result=dumpToFlashImage(L,f,writer, D, stripping, address);
result=dumpToFlashImage(L,f,writer, D, stripping, address, maxSize);
} else
{
result=luaU_dump_crosscompile(L,f,writer,D,stripping,target);

View File

@ -896,13 +896,6 @@ union luai_Cast { double l_d; long l_l; };
** without modifying the main part of the file.
*/
/* If you define the next macro you'll get the ability to set rotables as
metatables for tables/userdata/types (but the VM might run slower)
*/
#if (LUA_OPTIMIZE_MEMORY == 2)
#define LUA_META_ROTABLES
#endif
#if LUA_OPTIMIZE_MEMORY == 2 && defined(LUA_USE_POPEN)
#error "Pipes not supported in aggresive optimization mode (LUA_OPTIMIZE_MEMORY=2)"
#endif

View File

@ -130,18 +130,29 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
TValue temp;
for (loop = 0; loop < MAXTAGLOOP; loop++) {
const TValue *tm;
if (ttistable(t) || ttisrotable(t)) { /* `t' is a table? */
void *h = ttistable(t) ? hvalue(t) : rvalue(t);
const TValue *res = ttistable(t) ? luaH_get((Table*)h, key) : luaH_get_ro(h, key); /* do a primitive get */
if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t);
const TValue *res = luaH_get(h, key); /* do a primitive get */
if (!ttisnil(res) || /* result is no nil? */
(tm = fasttm(L, ttistable(t) ? ((Table*)h)->metatable : (Table*)luaR_getmeta(h), TM_INDEX)) == NULL) { /* or no TM? */
(tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
setobj2s(L, val, res);
return;
}
}
/* else will try the tag method */
} else if (ttisrotable(t)) { /* `t' is a table? */
void *h = rvalue(t);
const TValue *res = luaH_get_ro(h, key); /* do a primitive get */
if (!ttisnil(res) || /* result is no nil? */
(tm = fasttm(L, (Table*)luaR_getmeta(h), TM_INDEX)) == NULL) { /* or no TM? */
setobj2s(L, val, res);
return;
}
/* else will try the tag method */
}
else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
luaG_typeerror(L, t, "index");
if (ttisfunction(tm) || ttislightfunction(tm)) {
callTMres(L, val, tm, t, key);
return;
@ -161,25 +172,27 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
L->top++;
fixedstack(L);
for (loop = 0; loop < MAXTAGLOOP; loop++) {
const TValue *tm;
if (ttistable(t) || ttisrotable(t)) { /* `t' is a table? */
void *h = ttistable(t) ? hvalue(t) : rvalue(t);
TValue *oldval = ttistable(t) ? luaH_set(L, (Table*)h, key) : NULL; /* do a primitive set */
if ((oldval && !ttisnil(oldval)) || /* result is no nil? */
(tm = fasttm(L, ttistable(t) ? ((Table*)h)->metatable : (Table*)luaR_getmeta(h), TM_NEWINDEX)) == NULL) { /* or no TM? */
if(oldval) {
L->top--;
unfixedstack(L);
setobj2t(L, oldval, val);
((Table *)h)->flags = 0;
luaC_barriert(L, (Table*)h, val);
}
const TValue *tm = NULL;
if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t);
TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
if ((!ttisnil(oldval)) || /* result is no nil? */
(tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) {
L->top--;
unfixedstack(L);
setobj2t(L, oldval, val);
((Table *)h)->flags = 0;
luaC_barriert(L, (Table*)h, val);
return;
}
/* else will try the tag method */
}
else if (ttisrotable(t)) {
luaG_runerror(L, "invalid write to ROM variable");
}
else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
luaG_typeerror(L, t, "index");
if (ttisfunction(tm) || ttislightfunction(tm)) {
L->top--;
unfixedstack(L);
@ -294,7 +307,7 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
case LUA_TROTABLE:
return rvalue(t1) == rvalue(t2);
case LUA_TLIGHTUSERDATA:
case LUA_TLIGHTUSERDATA:
case LUA_TLIGHTFUNCTION:
return pvalue(t1) == pvalue(t2);
case LUA_TUSERDATA: {
@ -321,7 +334,7 @@ void luaV_concat (lua_State *L, int total, int last) {
if (G(L)->memlimit < max_sizet) max_sizet = G(L)->memlimit;
do {
/* Any call which does a memory allocation may trim the stack,
invalidating top unless the stack is fixed duri ng the allocation */
invalidating top unless the stack is fixed during the allocation */
StkId top = L->base + last + 1;
fixedstack(L);
int n = 2; /* number of elements handled in this pass (at least 2) */
@ -570,7 +583,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
case OP_LEN: {
const TValue *rb = RB(i);
switch (ttype(rb)) {
case LUA_TTABLE:
case LUA_TTABLE:
case LUA_TROTABLE: {
setnvalue(ra, ttistable(rb) ? cast_num(luaH_getn(hvalue(rb))) : cast_num(luaH_getn_ro(rvalue(rb))));
break;

View File

@ -44,7 +44,7 @@ INCLUDES += -I ../libc
INCLUDES += -I ../coap
INCLUDES += -I ../mqtt
INCLUDES += -I ../u8g2lib/u8g2/src/clib
INCLUDES += -I ../ucglib
INCLUDES += -I ../ucglib/ucg/src/clib
INCLUDES += -I ../lua
INCLUDES += -I ../pcm
INCLUDES += -I ../platform

View File

@ -32,18 +32,23 @@ static size_t cronent_count = 0;
static uint64_t lcron_parsepart(lua_State *L, char *str, char **end, uint8_t min, uint8_t max) {
uint64_t res = 0;
/* Gobble whitespace before potential stars; no strtol on that path */
while (*str != '\0' && (*str == ' ' || *str == '\t')) {
str++;
}
if (str[0] == '*') {
uint32_t each = 1;
*end = str + 1;
if (str[1] == '/') {
each = strtol(str + 2, end, 10);
if (end != 0)
if (each == 0 || each >= max - min) {
return luaL_error(L, "invalid spec (each %d)", each);
}
}
for (int i = 0; i <= (max - min); i++) {
if (((min + i) % each) == 0) res |= (uint64_t)1 << i;
if ((i % each) == 0) res |= (uint64_t)1 << i;
}
} else {
uint32_t val;
@ -63,14 +68,17 @@ static uint64_t lcron_parsepart(lua_State *L, char *str, char **end, uint8_t min
static int lcron_parsedesc(lua_State *L, char *str, struct cronent_desc *desc) {
char *s = str;
desc->min = lcron_parsepart(L, s, &s, 0, 59);
if (*s != ' ') return luaL_error(L, "invalid spec (separator @%d)", s - str);
if (*s != ' ' && *s != '\t') return luaL_error(L, "invalid spec (separator @%d)", s - str);
desc->hour = lcron_parsepart(L, s + 1, &s, 0, 23);
if (*s != ' ') return luaL_error(L, "invalid spec (separator @%d)", s - str);
if (*s != ' ' && *s != '\t') return luaL_error(L, "invalid spec (separator @%d)", s - str);
desc->dom = lcron_parsepart(L, s + 1, &s, 1, 31);
if (*s != ' ') return luaL_error(L, "invalid spec (separator @%d)", s - str);
if (*s != ' ' && *s != '\t') return luaL_error(L, "invalid spec (separator @%d)", s - str);
desc->mon = lcron_parsepart(L, s + 1, &s, 1, 12);
if (*s != ' ') return luaL_error(L, "invalid spec (separator @%d)", s - str);
if (*s != ' ' && *s != '\t') return luaL_error(L, "invalid spec (separator @%d)", s - str);
desc->dow = lcron_parsepart(L, s + 1, &s, 0, 6);
while (*s != '\0' && (*s == ' ' || *s == '\t')) {
s++;
}
if (*s != 0) return luaL_error(L, "invalid spec (trailing @%d)", s - str);
return 0;
}
@ -78,6 +86,7 @@ static int lcron_parsedesc(lua_State *L, char *str, struct cronent_desc *desc) {
static int lcron_create(lua_State *L) {
// Check arguments
char *strdesc = (char*)luaL_checkstring(L, 1);
void *newlist;
luaL_checkanyfunction(L, 2);
// Parse description
struct cronent_desc desc;
@ -93,8 +102,12 @@ static int lcron_create(lua_State *L) {
// Set entry
ud->desc = desc;
// Store entry
newlist = os_realloc(cronent_list, sizeof(int) * (cronent_count + 1));
if (newlist == NULL) {
return luaL_error(L, "out of memory");
}
lua_pushvalue(L, -1);
cronent_list = os_realloc(cronent_list, sizeof(int) * (cronent_count + 1));
cronent_list = newlist;
cronent_list[cronent_count++] = luaL_ref(L, LUA_REGISTRYINDEX);
return 1;
}
@ -120,8 +133,13 @@ static int lcron_schedule(lua_State *L) {
ud->desc = desc;
size_t i = lcron_findindex(L, ud);
if (i == -1) {
void *newlist;
newlist = os_realloc(cronent_list, sizeof(int) * (cronent_count + 1));
if (newlist == NULL) {
return luaL_error(L, "out of memory");
}
cronent_list = newlist;
lua_pushvalue(L, 1);
cronent_list = os_realloc(cronent_list, sizeof(int) * (cronent_count + 1));
cronent_list[cronent_count++] = lua_ref(L, LUA_REGISTRYINDEX);
}
return 0;

View File

@ -67,6 +67,9 @@ static int ds18b20_lua_readoutdone(void);
// Setup onewire bus for DS18B20 temperature sensors
// Lua: ds18b20.setup(OW_BUS_PIN)
static int ds18b20_lua_setup(lua_State *L) {
platform_print_deprecation_note("ds18b20 C module superseded by Lua implementation", "soon");
// check ow bus pin value
if (!lua_isnumber(L, 1) || lua_isnumber(L, 1) == 0) {
return luaL_error(L, "wrong 1-wire pin");

View File

@ -587,7 +587,7 @@ static int file_mount( lua_State *L )
if (vol->vol = vfs_mount( ldrv, num )) {
/* set its metatable */
luaL_getmetatable(L, "vfs.vol");
luaL_getmetatable(L, "file.vol");
lua_setmetatable(L, -2);
return 1;
} else {

View File

@ -17,7 +17,7 @@
#include "user_interface.h"
#define MQTT_BUF_SIZE 1024
#define MQTT_BUF_SIZE 1460
#define MQTT_DEFAULT_KEEPALIVE 60
#define MQTT_MAX_CLIENT_LEN 64
#define MQTT_MAX_USER_LEN 64
@ -46,17 +46,32 @@ typedef struct mqtt_event_data_t
#define RECONNECT_POSSIBLE 1
#define RECONNECT_ON 2
typedef enum {
MQTT_RECV_NORMAL,
MQTT_RECV_BUFFERING_SHORT,
MQTT_RECV_BUFFERING,
MQTT_RECV_SKIPPING,
} tReceiveState;
typedef struct mqtt_state_t
{
uint16_t port;
uint8_t auto_reconnect; // 0 is not auto_reconnect. 1 is auto reconnect, but never connected. 2 is auto reconnect, but once connected
mqtt_connect_info_t* connect_info;
uint16_t message_length;
uint16_t message_length_read;
mqtt_connection_t mqtt_connection;
msg_queue_t* pending_msg_q;
uint8_t * recv_buffer; // heap buffer for multi-packet rx
uint8_t * recv_buffer_wp; // write pointer in multi-packet rx
union {
uint16_t recv_buffer_size; // size of recv_buffer
uint32_t recv_buffer_skip; // number of bytes left to skip, in skipping state
};
tReceiveState recv_buffer_state;
} mqtt_state_t;
typedef struct lmqtt_userdata
{
struct espconn *pesp_conn;
@ -65,6 +80,7 @@ typedef struct lmqtt_userdata
int cb_connect_fail_ref;
int cb_disconnect_ref;
int cb_message_ref;
int cb_overflow_ref;
int cb_suback_ref;
int cb_unsuback_ref;
int cb_puback_ref;
@ -81,6 +97,9 @@ typedef struct lmqtt_userdata
tConnState connState;
}lmqtt_userdata;
// How large MQTT messages to accept by default
#define DEFAULT_MAX_MESSAGE_LENGTH 1024
static sint8 socket_connect(struct espconn *pesp_conn);
static void mqtt_socket_reconnected(void *arg, sint8_t err);
static void mqtt_socket_connected(void *arg);
@ -110,6 +129,13 @@ static void mqtt_socket_disconnected(void *arg) // tcp only
}
}
if(mud->mqtt_state.recv_buffer) {
c_free(mud->mqtt_state.recv_buffer);
mud->mqtt_state.recv_buffer = NULL;
}
mud->mqtt_state.recv_buffer_size = 0;
mud->mqtt_state.recv_buffer_state = MQTT_RECV_NORMAL;
if(mud->mqtt_state.auto_reconnect == RECONNECT_ON) {
mud->pesp_conn->reverse = mud;
mud->pesp_conn->type = ESPCONN_TCP;
@ -178,9 +204,9 @@ static void mqtt_socket_reconnected(void *arg, sint8_t err)
NODE_DBG("leave mqtt_socket_reconnected.\n");
}
static void deliver_publish(lmqtt_userdata * mud, uint8_t* message, int length)
static void deliver_publish(lmqtt_userdata * mud, uint8_t* message, uint16_t length, uint8_t is_overflow)
{
NODE_DBG("enter deliver_publish.\n");
NODE_DBG("enter deliver_publish (len=%d, overflow=%d).\n", length, is_overflow);
if(mud == NULL)
return;
mqtt_event_data_t event_data;
@ -191,13 +217,15 @@ static void deliver_publish(lmqtt_userdata * mud, uint8_t* message, int length)
event_data.data_length = length;
event_data.data = mqtt_get_publish_data(message, &event_data.data_length);
if(mud->cb_message_ref == LUA_NOREF)
int cb_ref = !is_overflow ? mud->cb_message_ref : mud->cb_overflow_ref;
if(cb_ref == LUA_NOREF)
return;
if(mud->self_ref == LUA_NOREF)
return;
lua_State *L = lua_getstate();
if(event_data.topic && (event_data.topic_length > 0)){
lua_rawgeti(L, LUA_REGISTRYINDEX, mud->cb_message_ref);
lua_rawgeti(L, LUA_REGISTRYINDEX, cb_ref);
lua_rawgeti(L, LUA_REGISTRYINDEX, mud->self_ref); // pass the userdata to callback func in lua
lua_pushlstring(L, event_data.topic, event_data.topic_length);
} else {
@ -265,14 +293,15 @@ static sint8 mqtt_send_if_possible(struct espconn *pesp_conn)
static void mqtt_socket_received(void *arg, char *pdata, unsigned short len)
{
NODE_DBG("enter mqtt_socket_received.\n");
NODE_DBG("enter mqtt_socket_received (rxlen=%u).\n", len);
uint8_t msg_type;
uint8_t msg_qos;
uint16_t msg_id;
int length = (int)len;
// uint8_t in_buffer[MQTT_BUF_SIZE];
uint8_t *in_buffer = (uint8_t *)pdata;
uint16_t in_buffer_length = len;
uint8_t *continuation_buffer = NULL;
uint8_t *temp_pdata = NULL;
struct espconn *pesp_conn = arg;
if(pesp_conn == NULL)
@ -281,11 +310,109 @@ static void mqtt_socket_received(void *arg, char *pdata, unsigned short len)
if(mud == NULL)
return;
READPACKET:
if(length > MQTT_BUF_SIZE || length <= 0)
return;
switch(mud->mqtt_state.recv_buffer_state) {
case MQTT_RECV_NORMAL:
// No previous buffer.
break;
case MQTT_RECV_BUFFERING_SHORT:
// Last buffer had so few byte that we could not determine message length.
// Store in a local heap buffer and operate on this, as if was the regular pdata buffer.
// Avoids having to repeat message size/overflow logic.
temp_pdata = c_zalloc(mud->mqtt_state.recv_buffer_size + len);
if(temp_pdata == NULL) {
NODE_DBG("MQTT[buffering-short]: Failed to allocate %u bytes, disconnecting...\n", mud->mqtt_state.recv_buffer_size + len);
#ifdef CLIENT_SSL_ENABLE
if (mud->secure) {
espconn_secure_disconnect(pesp_conn);
} else
#endif
{
espconn_disconnect(pesp_conn);
}
return;
}
// c_memcpy(in_buffer, pdata, length);
NODE_DBG("MQTT[buffering-short]: Continuing with %u + %u bytes\n", mud->mqtt_state.recv_buffer_size, len);
memcpy(temp_pdata, mud->mqtt_state.recv_buffer, mud->mqtt_state.recv_buffer_size);
memcpy(temp_pdata + mud->mqtt_state.recv_buffer_size, pdata, len);
c_free(mud->mqtt_state.recv_buffer);
mud->mqtt_state.recv_buffer = NULL;
mud->mqtt_state.recv_buffer_state = MQTT_RECV_NORMAL;
in_buffer = temp_pdata;
in_buffer_length = mud->mqtt_state.recv_buffer_size + len;
break;
case MQTT_RECV_BUFFERING: {
// safe cast: we never allow longer buffer.
uint16_t current_length = (uint16_t) (mud->mqtt_state.recv_buffer_wp - mud->mqtt_state.recv_buffer);
NODE_DBG("MQTT[buffering]: appending %u bytes to previous recv buffer (%u out of wanted %u)\n",
in_buffer_length,
current_length,
mud->mqtt_state.recv_buffer_size);
// Copy from rx buffer to heap buffer. Smallest of [remainder of pending message] and [all of buffer]
uint16_t copy_length = LWIP_MIN(mud->mqtt_state.recv_buffer_size - current_length, in_buffer_length);
memcpy(mud->mqtt_state.recv_buffer_wp, pdata, copy_length);
mud->mqtt_state.recv_buffer_wp += copy_length;
in_buffer_length = (uint16_t) (mud->mqtt_state.recv_buffer_wp - mud->mqtt_state.recv_buffer);
if (in_buffer_length < mud->mqtt_state.recv_buffer_size) {
NODE_DBG("MQTT[buffering]: need %u more bytes, waiting for next rx.\n",
mud->mqtt_state.recv_buffer_size - in_buffer_length
);
goto RX_PACKET_FINISHED;
}
NODE_DBG("MQTT[buffering]: Full message received (%u). remainding bytes=%u\n",
mud->mqtt_state.recv_buffer_size,
len - copy_length);
// Point continuation_buffer to any additional data in pdata.
// May become 0 bytes, but used to trigger free!
continuation_buffer = pdata + copy_length;
len -= copy_length; // borrow len instead of having another variable..
in_buffer = mud->mqtt_state.recv_buffer;
// in_buffer_length was set above
mud->mqtt_state.recv_buffer_state = MQTT_RECV_NORMAL;
break;
}
case MQTT_RECV_SKIPPING:
// Last rx had a message which was too large to process, skip it.
if(mud->mqtt_state.recv_buffer_skip > in_buffer_length) {
NODE_DBG("MQTT[skipping]: skip=%u. Skipping full RX buffer (%u).\n",
mud->mqtt_state.recv_buffer_skip,
in_buffer_length
);
mud->mqtt_state.recv_buffer_skip -= in_buffer_length;
goto RX_PACKET_FINISHED;
}
NODE_DBG("MQTT[skipping]: skip=%u. Skipping partial RX buffer, continuing at %u\n",
mud->mqtt_state.recv_buffer_skip,
in_buffer_length
);
in_buffer += mud->mqtt_state.recv_buffer_skip;
in_buffer_length -= mud->mqtt_state.recv_buffer_skip;
mud->mqtt_state.recv_buffer_skip = 0;
mud->mqtt_state.recv_buffer_state = MQTT_RECV_NORMAL;
break;
}
READPACKET:
if(in_buffer_length <= 0)
goto RX_PACKET_FINISHED;
// MQTT publish message can in theory be 256Mb, while we do not support it we need to be
// able to do math on it.
int32_t message_length;
// temp buffer for control messages
uint8_t temp_buffer[MQTT_BUF_SIZE];
mqtt_msg_init(&mud->mqtt_state.mqtt_connection, temp_buffer, MQTT_BUF_SIZE);
mqtt_message_t *temp_msg = NULL;
@ -355,19 +482,107 @@ READPACKET:
break;
case MQTT_DATA:
mud->mqtt_state.message_length_read = length;
mud->mqtt_state.message_length = mqtt_get_total_length(in_buffer, mud->mqtt_state.message_length_read);
message_length = mqtt_get_total_length(in_buffer, in_buffer_length);
msg_type = mqtt_get_type(in_buffer);
msg_qos = mqtt_get_qos(in_buffer);
msg_id = mqtt_get_id(in_buffer, mud->mqtt_state.message_length);
msg_id = mqtt_get_id(in_buffer, in_buffer_length);
NODE_DBG("MQTT_DATA: msg length: %u, buffer length: %u\r\n",
message_length,
in_buffer_length);
if (message_length > mud->connect_info.max_message_length) {
// The pending message length is larger than we was configured to allow
if(msg_qos > 0 && msg_id == 0) {
NODE_DBG("MQTT: msg too long, but not enough data to get msg_id: total=%u, deliver=%u\r\n", message_length, in_buffer_length);
// qos requested, but too short buffer to get a packet ID.
// Trigger the "short buffer" mode
message_length = -1;
// Drop through to partial message handling below.
} else {
NODE_DBG("MQTT: msg too long: total=%u, deliver=%u\r\n", message_length, in_buffer_length);
if (msg_type == MQTT_MSG_TYPE_PUBLISH) {
// In practice we should never get any other types..
deliver_publish(mud, in_buffer, in_buffer_length, 1);
// If qos specified, we should ACK it.
// In theory it might be wrong to ack it before we received all TCP packets, but this avoids
// buffering and special code to handle this corner-case. Server will most likely have
// written all to OS socket anyway, and not be aware that we "should" not have received it all yet.
if(msg_qos == 1){
temp_msg = mqtt_msg_puback(&mud->mqtt_state.mqtt_connection, msg_id);
msg_enqueue(&(mud->mqtt_state.pending_msg_q), temp_msg,
msg_id, MQTT_MSG_TYPE_PUBACK, (int)mqtt_get_qos(temp_msg->data) );
}
else if(msg_qos == 2){
temp_msg = mqtt_msg_pubrec(&mud->mqtt_state.mqtt_connection, msg_id);
msg_enqueue(&(mud->mqtt_state.pending_msg_q), temp_msg,
msg_id, MQTT_MSG_TYPE_PUBREC, (int)mqtt_get_qos(temp_msg->data) );
}
if(msg_qos == 1 || msg_qos == 2){
NODE_DBG("MQTT: Queue response QoS: %d\r\n", msg_qos);
}
}
if (message_length > in_buffer_length) {
// Ignore bytes in subsequent packet(s) too.
NODE_DBG("MQTT: skipping into next rx\n");
mud->mqtt_state.recv_buffer_state = MQTT_RECV_SKIPPING;
mud->mqtt_state.recv_buffer_skip = (uint32_t) message_length - in_buffer_length;
break;
} else {
NODE_DBG("MQTT: Skipping message\n");
mud->mqtt_state.recv_buffer_state = MQTT_RECV_NORMAL;
goto RX_MESSAGE_PROCESSED;
}
}
}
if (message_length == -1 || message_length > in_buffer_length) {
// Partial message in buffer, need to store on heap until next RX. Allocate size for full message directly,
// instead of potential reallocs, to avoid fragmentation.
// If message_length is indicated as -1, we do not have enough data to determine the length properly.
// Just put what we have on heap, and place in state BUFFERING_SHORT.
NODE_DBG("MQTT: Partial message received (%u of %d). Buffering\r\n",
in_buffer_length,
message_length);
// although message_length is 32bit, it should never go above 16bit since
// max_message_length is 16bit.
uint16_t alloc_size = message_length > 0 ? (uint16_t)message_length : in_buffer_length;
mud->mqtt_state.recv_buffer = c_zalloc(alloc_size);
if (mud->mqtt_state.recv_buffer == NULL) {
NODE_DBG("MQTT: Failed to allocate %u bytes, disconnecting...\n", alloc_size);
#ifdef CLIENT_SSL_ENABLE
if (mud->secure) {
espconn_secure_disconnect(pesp_conn);
} else
#endif
{
espconn_disconnect(pesp_conn);
}
return;
}
memcpy(mud->mqtt_state.recv_buffer, in_buffer, in_buffer_length);
mud->mqtt_state.recv_buffer_wp = mud->mqtt_state.recv_buffer + in_buffer_length;
mud->mqtt_state.recv_buffer_state = message_length > 0 ? MQTT_RECV_BUFFERING : MQTT_RECV_BUFFERING_SHORT;
mud->mqtt_state.recv_buffer_size = alloc_size;
NODE_DBG("MQTT: Wait for next recv\n");
break;
}
msg_queue_t *pending_msg = msg_peek(&(mud->mqtt_state.pending_msg_q));
NODE_DBG("MQTT_DATA: type: %d, qos: %d, msg_id: %d, pending_id: %d, msg length: %u, buffer length: %u\r\n",
msg_type,
msg_qos,
msg_id,
(pending_msg)?pending_msg->msg_id:0,
message_length,
in_buffer_length);
NODE_DBG("MQTT_DATA: type: %d, qos: %d, msg_id: %d, pending_id: %d\r\n",
msg_type,
msg_qos,
msg_id,
(pending_msg)?pending_msg->msg_id:0);
switch(msg_type)
{
case MQTT_MSG_TYPE_SUBACK:
@ -411,7 +626,7 @@ READPACKET:
if(msg_qos == 1 || msg_qos == 2){
NODE_DBG("MQTT: Queue response QoS: %d\r\n", msg_qos);
}
deliver_publish(mud, in_buffer, mud->mqtt_state.message_length);
deliver_publish(mud, in_buffer, (uint16_t)message_length, 0);
break;
case MQTT_MSG_TYPE_PUBACK:
if(pending_msg && pending_msg->msg_type == MQTT_MSG_TYPE_PUBLISH && pending_msg->msg_id == msg_id){
@ -472,28 +687,40 @@ READPACKET:
NODE_DBG("MQTT: PINGRESP received\r\n");
break;
}
// NOTE: this is done down here and not in the switch case above
// because the PSOCK_READBUF_LEN() won't work inside a switch
// statement due to the way protothreads resume.
if(msg_type == MQTT_MSG_TYPE_PUBLISH)
{
length = mud->mqtt_state.message_length_read;
RX_MESSAGE_PROCESSED:
if(continuation_buffer != NULL) {
NODE_DBG("MQTT[buffering]: buffered message finished. Continuing with rest of rx buffer (%u)\n",
len);
c_free(mud->mqtt_state.recv_buffer);
mud->mqtt_state.recv_buffer = NULL;
if(mud->mqtt_state.message_length < mud->mqtt_state.message_length_read)
{
length -= mud->mqtt_state.message_length;
in_buffer += mud->mqtt_state.message_length;
NODE_DBG("Get another published message\r\n");
goto READPACKET;
}
in_buffer = continuation_buffer;
in_buffer_length = len;
continuation_buffer = NULL;
}else{
// Message have been fully processed (or ignored). Move pointer ahead
// and continue with next message, if any.
in_buffer_length -= message_length;
in_buffer += message_length;
}
if(in_buffer_length > 0)
{
NODE_DBG("Get another published message\r\n");
goto READPACKET;
}
break;
}
RX_PACKET_FINISHED:
if(temp_pdata != NULL) {
c_free(temp_pdata);
}
mqtt_send_if_possible(pesp_conn);
NODE_DBG("leave mqtt_socket_received.\n");
NODE_DBG("leave mqtt_socket_received\n");
return;
}
@ -580,7 +807,7 @@ static void mqtt_socket_connected(void *arg)
mud->keep_alive_tick = 0;
mud->connState = MQTT_CONNECT_SENDING;
NODE_DBG("leave mqtt_socket_connected.\n");
NODE_DBG("leave mqtt_socket_connectet, heap = %u.\n", system_get_free_heap_size());
return;
}
@ -686,7 +913,7 @@ void mqtt_socket_timer(void *arg)
NODE_DBG("leave mqtt_socket_timer.\n");
}
// Lua: mqtt.Client(clientid, keepalive, user, pass, clean_session)
// Lua: mqtt.Client(clientid, keepalive, user, pass, clean_session, max_message_length)
static int mqtt_socket_client( lua_State* L )
{
NODE_DBG("enter mqtt_socket_client.\n");
@ -703,6 +930,7 @@ static int mqtt_socket_client( lua_State* L )
int keepalive = 0;
int stack = 1;
int clean_session = 1;
int max_message_length = 0;
int top = lua_gettop(L);
// create a object
@ -715,6 +943,7 @@ static int mqtt_socket_client( lua_State* L )
mud->cb_disconnect_ref = LUA_NOREF;
mud->cb_message_ref = LUA_NOREF;
mud->cb_overflow_ref = LUA_NOREF;
mud->cb_suback_ref = LUA_NOREF;
mud->cb_unsuback_ref = LUA_NOREF;
mud->cb_puback_ref = LUA_NOREF;
@ -767,6 +996,16 @@ static int mqtt_socket_client( lua_State* L )
clean_session = 1;
}
if(lua_isnumber( L, stack ))
{
max_message_length = luaL_checkinteger( L, stack);
stack++;
}
if(max_message_length == 0) {
max_message_length = DEFAULT_MAX_MESSAGE_LENGTH;
}
// TODO: check the zalloc result.
mud->connect_info.client_id = (uint8_t *)c_zalloc(idl+1);
mud->connect_info.username = (uint8_t *)c_zalloc(unl + 1);
@ -784,7 +1023,7 @@ static int mqtt_socket_client( lua_State* L )
c_free(mud->connect_info.password);
mud->connect_info.password = NULL;
}
return luaL_error(L, "not enough memory");
return luaL_error(L, "not enough memory");
}
c_memcpy(mud->connect_info.client_id, clientId, idl);
@ -800,11 +1039,15 @@ static int mqtt_socket_client( lua_State* L )
mud->connect_info.will_qos = 0;
mud->connect_info.will_retain = 0;
mud->connect_info.keepalive = keepalive;
mud->connect_info.max_message_length = max_message_length;
mud->mqtt_state.pending_msg_q = NULL;
mud->mqtt_state.auto_reconnect = RECONNECT_OFF;
mud->mqtt_state.port = 1883;
mud->mqtt_state.connect_info = &mud->connect_info;
mud->mqtt_state.recv_buffer = NULL;
mud->mqtt_state.recv_buffer_size = 0;
mud->mqtt_state.recv_buffer_state = MQTT_RECV_NORMAL;
NODE_DBG("leave mqtt_socket_client.\n");
return 1;
@ -852,6 +1095,13 @@ static int mqtt_delete( lua_State* L )
}
// ----
//--------- alloc-ed in mqtt_socket_received()
if(mud->mqtt_state.recv_buffer) {
c_free(mud->mqtt_state.recv_buffer);
mud->mqtt_state.recv_buffer = NULL;
}
// ----
//--------- alloc-ed in mqtt_socket_client()
if(mud->connect_info.client_id){
c_free(mud->connect_info.client_id);
@ -876,6 +1126,8 @@ static int mqtt_delete( lua_State* L )
mud->cb_disconnect_ref = LUA_NOREF;
luaL_unref(L, LUA_REGISTRYINDEX, mud->cb_message_ref);
mud->cb_message_ref = LUA_NOREF;
luaL_unref(L, LUA_REGISTRYINDEX, mud->cb_overflow_ref);
mud->cb_overflow_ref = LUA_NOREF;
luaL_unref(L, LUA_REGISTRYINDEX, mud->cb_suback_ref);
mud->cb_suback_ref = LUA_NOREF;
luaL_unref(L, LUA_REGISTRYINDEX, mud->cb_unsuback_ref);
@ -918,7 +1170,7 @@ static sint8 socket_connect(struct espconn *pesp_conn)
os_timer_arm(&mud->mqttTimer, 1000, 1);
NODE_DBG("leave socket_connect, heap = %u.\n", system_get_free_heap_size());
NODE_DBG("leave socket_connect\n");
return espconn_status;
}
@ -1225,6 +1477,9 @@ static int mqtt_socket_on( lua_State* L )
}else if( sl == 7 && c_strcmp(method, "message") == 0){
luaL_unref(L, LUA_REGISTRYINDEX, mud->cb_message_ref);
mud->cb_message_ref = luaL_ref(L, LUA_REGISTRYINDEX);
}else if( sl == 8 && c_strcmp(method, "overflow") == 0){
luaL_unref(L, LUA_REGISTRYINDEX, mud->cb_overflow_ref);
mud->cb_overflow_ref = luaL_ref(L, LUA_REGISTRYINDEX);
}else{
lua_pop(L, 1);
return luaL_error( L, "method not supported" );

View File

@ -378,22 +378,6 @@ static int tmr_create( lua_State *L ) {
}
#if defined(ENABLE_TIMER_SUSPEND) && defined(SWTMR_DEBUG)
static void tmr_printRegistry(lua_State* L){
swtmr_print_registry();
}
static void tmr_printSuspended(lua_State* L){
swtmr_print_suspended();
}
static void tmr_printTimerlist(lua_State* L){
swtmr_print_timer_list();
}
#endif
// Module function map
static const LUA_REG_TYPE tmr_dyn_map[] = {

File diff suppressed because it is too large Load Diff

View File

@ -570,9 +570,9 @@ static int packet_map_lookup(lua_State *L) {
}
// Now search the packet function map
const TValue *res = luaR_findentry((void *) packet_function_map, field, 0, NULL);
if (res) {
luaA_pushobject(L, res);
lua_pushrotable(L, (void *)packet_function_map);
lua_getfield(L, -1, field);
if (!lua_isnil(L, -1)) {
return 1;
}
}

View File

@ -126,12 +126,16 @@ void mqtt_msg_init(mqtt_connection_t* connection, uint8_t* buffer, uint16_t buff
connection->buffer_length = buffer_length;
}
int mqtt_get_total_length(uint8_t* buffer, uint16_t length)
// Returns total length of message, or -1 if not enough bytes are available
int32_t mqtt_get_total_length(uint8_t* buffer, uint16_t buffer_length)
{
int i;
int totlen = 0;
for(i = 1; i < length; ++i)
if(buffer_length == 1)
return -1;
for(i = 1; i < buffer_length; ++i)
{
totlen += (buffer[i] & 0x7f) << (7 * (i - 1));
if((buffer[i] & 0x80) == 0)
@ -139,19 +143,23 @@ int mqtt_get_total_length(uint8_t* buffer, uint16_t length)
++i;
break;
}
if(i == buffer_length)
return -1;
}
totlen += i;
return totlen;
}
const char* mqtt_get_publish_topic(uint8_t* buffer, uint16_t* length)
const char* mqtt_get_publish_topic(uint8_t* buffer, uint16_t* buffer_length)
{
int i;
int totlen = 0;
int topiclen;
for(i = 1; i < *length; ++i)
for(i = 1; i < *buffer_length; ++i)
{
totlen += (buffer[i] & 0x7f) << (7 * (i -1));
if((buffer[i] & 0x80) == 0)
@ -162,25 +170,25 @@ const char* mqtt_get_publish_topic(uint8_t* buffer, uint16_t* length)
}
totlen += i;
if(i + 2 > *length)
if(i + 2 > *buffer_length)
return NULL;
topiclen = buffer[i++] << 8;
topiclen |= buffer[i++];
if(i + topiclen > *length)
if(i + topiclen > *buffer_length)
return NULL;
*length = topiclen;
*buffer_length = topiclen;
return (const char*)(buffer + i);
}
const char* mqtt_get_publish_data(uint8_t* buffer, uint16_t* length)
const char* mqtt_get_publish_data(uint8_t* buffer, uint16_t* buffer_length)
{
int i;
int totlen = 0;
int topiclen;
for(i = 1; i < *length; ++i)
for(i = 1; i < *buffer_length; ++i)
{
totlen += (buffer[i] & 0x7f) << (7 * (i - 1));
if((buffer[i] & 0x80) == 0)
@ -191,20 +199,20 @@ const char* mqtt_get_publish_data(uint8_t* buffer, uint16_t* length)
}
totlen += i;
if(i + 2 > *length)
if(i + 2 > *buffer_length)
return NULL;
topiclen = buffer[i++] << 8;
topiclen |= buffer[i++];
if(i + topiclen > *length){
*length = 0;
if(i + topiclen > *buffer_length){
*buffer_length = 0;
return NULL;
}
i += topiclen;
if(mqtt_get_qos(buffer) > 0)
{
if(i + 2 > *length)
if(i + 2 > *buffer_length)
return NULL;
i += 2;
}
@ -212,16 +220,16 @@ const char* mqtt_get_publish_data(uint8_t* buffer, uint16_t* length)
if(totlen < i)
return NULL;
if(totlen <= *length)
*length = totlen - i;
if(totlen <= *buffer_length)
*buffer_length = totlen - i;
else
*length = *length - i;
*buffer_length = *buffer_length - i;
return (const char*)(buffer + i);
}
uint16_t mqtt_get_id(uint8_t* buffer, uint16_t length)
uint16_t mqtt_get_id(uint8_t* buffer, uint16_t buffer_length)
{
if(length < 1)
if(buffer_length < 1)
return 0;
switch(mqtt_get_type(buffer))
@ -234,7 +242,7 @@ uint16_t mqtt_get_id(uint8_t* buffer, uint16_t length)
if(mqtt_get_qos(buffer) <= 0)
return 0;
for(i = 1; i < length; ++i)
for(i = 1; i < buffer_length; ++i)
{
if((buffer[i] & 0x80) == 0)
{
@ -243,16 +251,16 @@ uint16_t mqtt_get_id(uint8_t* buffer, uint16_t length)
}
}
if(i + 2 > length)
if(i + 2 > buffer_length)
return 0;
topiclen = buffer[i++] << 8;
topiclen |= buffer[i++];
if(i + topiclen > length)
if(i + topiclen > buffer_length)
return 0;
i += topiclen;
if(i + 2 > length)
if(i + 2 > buffer_length)
return 0;
return (buffer[i] << 8) | buffer[i + 1];
@ -267,7 +275,7 @@ uint16_t mqtt_get_id(uint8_t* buffer, uint16_t length)
{
// This requires the remaining length to be encoded in 1 byte,
// which it should be.
if(length >= 4 && (buffer[1] & 0x80) == 0)
if(buffer_length >= 4 && (buffer[1] & 0x80) == 0)
return (buffer[2] << 8) | buffer[3];
else
return 0;

View File

@ -108,21 +108,22 @@ typedef struct mqtt_connect_info
int will_qos;
int will_retain;
int clean_session;
uint16_t max_message_length;
} mqtt_connect_info_t;
static inline int mqtt_get_type(uint8_t* buffer) { return (buffer[0] & 0xf0) >> 4; }
static inline int mqtt_get_dup(uint8_t* buffer) { return (buffer[0] & 0x08) >> 3; }
static inline int mqtt_get_qos(uint8_t* buffer) { return (buffer[0] & 0x06) >> 1; }
static inline int mqtt_get_retain(uint8_t* buffer) { return (buffer[0] & 0x01); }
static inline int mqtt_get_connect_ret_code(uint8_t* buffer) { return (buffer[3]); }
static inline uint8_t mqtt_get_type(uint8_t* buffer) { return (buffer[0] & 0xf0) >> 4; }
static inline uint8_t mqtt_get_dup(uint8_t* buffer) { return (buffer[0] & 0x08) >> 3; }
static inline uint8_t mqtt_get_qos(uint8_t* buffer) { return (buffer[0] & 0x06) >> 1; }
static inline uint8_t mqtt_get_retain(uint8_t* buffer) { return (buffer[0] & 0x01); }
static inline uint8_t mqtt_get_connect_ret_code(uint8_t* buffer) { return (buffer[3]); }
void mqtt_msg_init(mqtt_connection_t* connection, uint8_t* buffer, uint16_t buffer_length);
int mqtt_get_total_length(uint8_t* buffer, uint16_t length);
const char* mqtt_get_publish_topic(uint8_t* buffer, uint16_t* length);
const char* mqtt_get_publish_data(uint8_t* buffer, uint16_t* length);
uint16_t mqtt_get_id(uint8_t* buffer, uint16_t length);
int32_t mqtt_get_total_length(uint8_t* buffer, uint16_t buffer_length);
const char* mqtt_get_publish_topic(uint8_t* buffer, uint16_t* buffer_length);
const char* mqtt_get_publish_data(uint8_t* buffer, uint16_t* buffer_length);
uint16_t mqtt_get_id(uint8_t* buffer, uint16_t buffer_length);
mqtt_message_t* mqtt_msg_connect(mqtt_connection_t* connection, mqtt_connect_info_t* info);
mqtt_message_t* mqtt_msg_publish(mqtt_connection_t* connection, const char* topic, const char* data, int data_length, int qos, int retain, uint16_t* message_id);

View File

@ -44,6 +44,7 @@ INCLUDES += -I ../spiffs
INCLUDES += -I ../libc
INCLUDES += -I ../lua
INCLUDES += -I ../u8g2lib/u8g2/src/clib
INCLUDES += -I ../ucglib/ucg/src/clib
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile

View File

@ -13,6 +13,42 @@
#define U8X8_USE_PINS
#include "u8x8_nodemcu_hal.h"
// 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;
// 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.data && hal->buffer.used > 0) {
platform_spi_blkwrite( hal->host, hal->buffer.used, hal->buffer.data );
hal->buffer.used = 0;
}
}
static void force_flush_buffer(u8x8_t *u8x8)
{
// spi hal has a buffer that can be flushed
if (u8x8->byte_cb == u8x8_byte_nodemcu_spi) {
hal_spi_t *hal = ((u8g2_nodemcu_t *)u8x8)->hal;
flush_buffer_spi( hal );
}
}
uint8_t u8x8_gpio_and_delay_nodemcu(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
@ -35,24 +71,30 @@ uint8_t u8x8_gpio_and_delay_nodemcu(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,
break;
case U8X8_MSG_DELAY_NANO: // delay arg_int * 1 nano second
force_flush_buffer(u8x8);
os_delay_us( 1 );
break;
case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds
force_flush_buffer(u8x8);
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
force_flush_buffer(u8x8);
os_delay_us( arg_int * 10 );
break;
case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second
force_flush_buffer(u8x8);
os_delay_us( arg_int * 1000 );
system_soft_wdt_feed();
break;
case U8X8_MSG_DELAY_I2C: // arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHz
force_flush_buffer(u8x8);
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 );
@ -119,12 +161,6 @@ uint8_t u8x8_gpio_and_delay_nodemcu(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,
}
// 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;
@ -132,11 +168,11 @@ uint8_t u8x8_byte_nodemcu_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *
switch(msg) {
case U8X8_MSG_BYTE_SEND:
if (hal->id == 0) {
if (hal->id < NUM_I2C) {
data = (uint8_t *)arg_ptr;
while( arg_int > 0 ) {
platform_i2c_send_byte( 0, *data );
platform_i2c_send_byte( hal->id, *data );
data++;
arg_int--;
}
@ -163,9 +199,9 @@ uint8_t u8x8_byte_nodemcu_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *
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 );
if (hal->id < NUM_I2C) {
platform_i2c_send_start( hal->id );
platform_i2c_send_address( hal->id, u8x8_GetI2CAddress(u8x8), PLATFORM_I2C_DIRECTION_TRANSMITTER );
} else {
// invalid id
@ -174,8 +210,8 @@ uint8_t u8x8_byte_nodemcu_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *
break;
case U8X8_MSG_BYTE_END_TRANSFER:
if (hal->id == 0) {
platform_i2c_send_stop( 0 );
if (hal->id < NUM_I2C) {
platform_i2c_send_stop( hal->id );
} else {
// invalid id
@ -191,27 +227,6 @@ uint8_t u8x8_byte_nodemcu_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *
}
// 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;
@ -228,6 +243,7 @@ uint8_t u8x8_byte_nodemcu_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *
return 0;
hal->host = host;
((u8g2_nodemcu_t *)u8x8)->hal = hal;
hal->buffer.data = NULL;
hal->last_dc = 0;
}
@ -279,6 +295,7 @@ uint8_t u8x8_byte_nodemcu_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *
u8x8_gpio_SetCS( u8x8, u8x8->display_info->chip_disable_level );
c_free( hal->buffer.data );
hal->buffer.data = NULL;
break;
default:

View File

@ -0,0 +1,129 @@
// Do not use the code from ucg submodule and skip the complete source here
// if the ucg module is not selected.
// Reason: The whole ucg submodule code tree might not even exist in this case.
#include "user_modules.h"
#ifdef LUA_USE_MODULES_UCG
#include <string.h>
#include "c_stdlib.h"
#include "platform.h"
#define USE_PIN_LIST
#include "ucg_nodemcu_hal.h"
#define delayMicroseconds os_delay_us
static spi_data_type cache;
static uint8_t cached;
#define CACHED_TRANSFER(dat, num) cache = cached = 0; \
while( arg > 0 ) { \
if (cached == 4) { \
platform_spi_transaction( 1, 0, 0, 32, cache, 0, 0, 0 ); \
cache = cached = 0; \
} \
cache = (cache << num*8) | dat; \
cached += num; \
arg--; \
} \
if (cached > 0) { \
platform_spi_transaction( 1, 0, 0, cached * 8, cache, 0, 0, 0 ); \
}
int16_t ucg_com_nodemcu_hw_spi(ucg_t *ucg, int16_t msg, uint16_t arg, uint8_t *data)
{
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 */
// we assume that the SPI interface was already initialized
// just care for the /CS and D/C pins
//platform_gpio_write( ucg->pin_list[0], value );
if ( ucg->pin_list[UCG_PIN_RST] != UCG_PIN_VAL_NONE )
platform_gpio_mode( ucg->pin_list[UCG_PIN_RST], PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT );
platform_gpio_mode( ucg->pin_list[UCG_PIN_CD], PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT );
if ( ucg->pin_list[UCG_PIN_CS] != UCG_PIN_VAL_NONE )
platform_gpio_mode( ucg->pin_list[UCG_PIN_CS], PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT );
break;
case UCG_COM_MSG_POWER_DOWN:
break;
case UCG_COM_MSG_DELAY:
delayMicroseconds(arg);
break;
case UCG_COM_MSG_CHANGE_RESET_LINE:
if ( ucg->pin_list[UCG_PIN_RST] != UCG_PIN_VAL_NONE )
platform_gpio_write( 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 )
platform_gpio_write( ucg->pin_list[UCG_PIN_CS], arg );
break;
case UCG_COM_MSG_CHANGE_CD_LINE:
platform_gpio_write( ucg->pin_list[UCG_PIN_CD], arg );
break;
case UCG_COM_MSG_SEND_BYTE:
platform_spi_send( 1, 8, arg );
break;
case UCG_COM_MSG_REPEAT_1_BYTE:
CACHED_TRANSFER(data[0], 1);
break;
case UCG_COM_MSG_REPEAT_2_BYTES:
CACHED_TRANSFER((data[0] << 8) | data[1], 2);
break;
case UCG_COM_MSG_REPEAT_3_BYTES:
while( arg > 0 ) {
platform_spi_transaction( 1, 0, 0, 24, (data[0] << 16) | (data[1] << 8) | data[2], 0, 0, 0 );
arg--;
}
break;
case UCG_COM_MSG_SEND_STR:
CACHED_TRANSFER(*data++, 1);
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 )
{
platform_gpio_write( ucg->pin_list[UCG_PIN_CD], 0 );
}
else
{
platform_gpio_write( ucg->pin_list[UCG_PIN_CD], 1 );
}
}
data++;
platform_spi_send( 1, 8, *data );
data++;
arg--;
}
break;
}
return 1;
}
#endif /* LUA_USE_MODULES_UCG */

View File

@ -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 */

@ -1 +1 @@
Subproject commit 7f2fc42af3d01fdfe2cc19320bdcfe693dd2b20d
Subproject commit d4da8254220adf39db44faa52a0842967095d230

View File

@ -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 += -DUSE_PIN_LIST
#############################################################
# Recursion Magic - Don't touch this!!
@ -38,7 +38,10 @@ STD_CFLAGS=-std=gnu11 -Wimplicit
# Required for each makefile to inherit from the parent
#
CSRCS := $(wildcard ucg/src/clib/*.c *.c)
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ucg/src/clib
INCLUDES += -I ./
INCLUDES += -I ../libc
PDIR := ../$(PDIR)

1
app/ucglib/ucg Submodule

@ -0,0 +1 @@
Subproject commit e21641a6c1ddb0e71f7b9e01501fa739786c68b1

File diff suppressed because it is too large Load Diff

View File

@ -1,87 +0,0 @@
/*
ucg_bitmap.c
Universal uC Color Graphics Library
Copyright (c) 2013, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
#ifdef UCG_MSG_DRAW_L90TC
void ucg_DrawTransparentBitmapLine(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t dir, ucg_int_t len, const unsigned char *bitmap)
{
ucg->arg.pixel.rgb.color[0] = ucg->arg.rgb[0].color[0];
ucg->arg.pixel.rgb.color[1] = ucg->arg.rgb[0].color[1];
ucg->arg.pixel.rgb.color[2] = ucg->arg.rgb[0].color[2];
ucg->arg.pixel.pos.x = x;
ucg->arg.pixel.pos.y = y;
ucg->arg.dir = dir;
ucg->arg.len = len;
ucg->arg.bitmap = bitmap;
ucg->arg.pixel_skip = 0;
ucg_DrawL90TCWithArg(ucg);
}
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
void ucg_DrawBitmapLine(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t dir, ucg_int_t len, const unsigned char *bitmap)
{
/*
ucg->arg.pixel.rgb.color[0] = ucg->arg.rgb[0].color[0];
ucg->arg.pixel.rgb.color[1] = ucg->arg.rgb[0].color[1];
ucg->arg.pixel.rgb.color[2] = ucg->arg.rgb[0].color[2];
*/
ucg->arg.pixel.pos.x = x;
ucg->arg.pixel.pos.y = y;
ucg->arg.dir = dir;
ucg->arg.len = len;
ucg->arg.bitmap = bitmap;
ucg->arg.pixel_skip = 0;
//ucg->arg.scale = 0;
ucg_DrawL90BFWithArg(ucg);
}
#endif /* UCG_MSG_DRAW_L90BF */
#ifdef ON_HOLD
void ucg_DrawRLBitmap(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t dir, const unsigned char *rl_bitmap)
{
ucg->arg.pixel.rgb.color[0] = ucg->arg.rgb[0].color[0];
ucg->arg.pixel.rgb.color[1] = ucg->arg.rgb[0].color[1];
ucg->arg.pixel.rgb.color[2] = ucg->arg.rgb[0].color[2];
ucg->arg.pixel.pos.x = x;
ucg->arg.pixel.pos.y = y;
ucg->arg.dir = dir;
ucg->arg.len = 0;
ucg->arg.bitmap = rl_bitmap;
ucg_DrawL90RLWithArg(ucg);
}
#endif

View File

@ -1,215 +0,0 @@
/*
ucg_box.c
Universal uC Color Graphics Library
Copyright (c) 2013, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
void ucg_DrawBox(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t w, ucg_int_t h)
{
while( h > 0 )
{
ucg_DrawHLine(ucg, x, y, w);
h--;
y++;
}
}
/*
- clear the screen with black color
- reset clip range to max
- set draw color to white
*/
void ucg_ClearScreen(ucg_t *ucg)
{
ucg_SetColor(ucg, 0, 0, 0, 0);
ucg_SetMaxClipRange(ucg);
ucg_DrawBox(ucg, 0, 0, ucg_GetWidth(ucg), ucg_GetHeight(ucg));
ucg_SetColor(ucg, 0, 255, 255, 255);
}
void ucg_DrawRBox(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t w, ucg_int_t h, ucg_int_t r)
{
ucg_int_t xl, yu;
ucg_int_t yl, xr;
xl = x;
xl += r;
yu = y;
yu += r;
xr = x;
xr += w;
xr -= r;
xr -= 1;
yl = y;
yl += h;
yl -= r;
yl -= 1;
ucg_DrawDisc(ucg, xl, yu, r, UCG_DRAW_UPPER_LEFT);
ucg_DrawDisc(ucg, xr, yu, r, UCG_DRAW_UPPER_RIGHT);
ucg_DrawDisc(ucg, xl, yl, r, UCG_DRAW_LOWER_LEFT);
ucg_DrawDisc(ucg, xr, yl, r, UCG_DRAW_LOWER_RIGHT);
{
ucg_int_t ww, hh;
ww = w;
ww -= r;
ww -= r;
ww -= 2;
hh = h;
hh -= r;
hh -= r;
hh -= 2;
xl++;
yu++;
h--;
ucg_DrawBox(ucg, xl, y, ww, r+1);
ucg_DrawBox(ucg, xl, yl, ww, r+1);
ucg_DrawBox(ucg, x, yu, w, hh);
}
}
ucg_ccs_t ucg_ccs_box[6]; /* color component sliders used by GradientBox */
void ucg_DrawGradientBox(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t w, ucg_int_t h)
{
uint8_t i;
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
/* 8. Jan 2014: correct? */
//printf("%d %d %d\n", ucg->arg.rgb[3].color[0], ucg->arg.rgb[3].color[1], ucg->arg.rgb[3].color[2]);
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg_ccs_box+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[2].color[i], h);
ucg_ccs_init(ucg_ccs_box+i+3, ucg->arg.rgb[1].color[i], ucg->arg.rgb[3].color[i], h);
}
while( h > 0 )
{
ucg->arg.rgb[0].color[0] = ucg_ccs_box[0].current;
ucg->arg.rgb[0].color[1] = ucg_ccs_box[1].current;
ucg->arg.rgb[0].color[2] = ucg_ccs_box[2].current;
ucg->arg.rgb[1].color[0] = ucg_ccs_box[3].current;
ucg->arg.rgb[1].color[1] = ucg_ccs_box[4].current;
ucg->arg.rgb[1].color[2] = ucg_ccs_box[5].current;
//printf("%d %d %d\n", ucg_ccs_box[0].current, ucg_ccs_box[1].current, ucg_ccs_box[2].current);
//printf("%d %d %d\n", ucg_ccs_box[3].current, ucg_ccs_box[4].current, ucg_ccs_box[5].current);
ucg->arg.pixel.pos.x = x;
ucg->arg.pixel.pos.y = y;
ucg->arg.len = w;
ucg->arg.dir = 0;
ucg_DrawL90SEWithArg(ucg);
for ( i = 0; i < 6; i++ )
ucg_ccs_step(ucg_ccs_box+i);
h--;
y++;
}
}
/* restrictions: w > 0 && h > 0 */
void ucg_DrawFrame(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t w, ucg_int_t h)
{
ucg_int_t xtmp = x;
ucg_DrawHLine(ucg, x, y, w);
ucg_DrawVLine(ucg, x, y, h);
x+=w;
x--;
ucg_DrawVLine(ucg, x, y, h);
y+=h;
y--;
ucg_DrawHLine(ucg, xtmp, y, w);
}
void ucg_DrawRFrame(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t w, ucg_int_t h, ucg_int_t r)
{
ucg_int_t xl, yu;
xl = x;
xl += r;
yu = y;
yu += r;
{
ucg_int_t yl, xr;
xr = x;
xr += w;
xr -= r;
xr -= 1;
yl = y;
yl += h;
yl -= r;
yl -= 1;
ucg_DrawCircle(ucg, xl, yu, r, UCG_DRAW_UPPER_LEFT);
ucg_DrawCircle(ucg, xr, yu, r, UCG_DRAW_UPPER_RIGHT);
ucg_DrawCircle(ucg, xl, yl, r, UCG_DRAW_LOWER_LEFT);
ucg_DrawCircle(ucg, xr, yl, r, UCG_DRAW_LOWER_RIGHT);
}
{
ucg_int_t ww, hh;
ww = w;
ww -= r;
ww -= r;
ww -= 2;
hh = h;
hh -= r;
hh -= r;
hh -= 2;
xl++;
yu++;
h--;
w--;
ucg_DrawHLine(ucg, xl, y, ww);
ucg_DrawHLine(ucg, xl, y+h, ww);
ucg_DrawVLine(ucg, x, yu, hh);
ucg_DrawVLine(ucg, x+w, yu, hh);
}
}

View File

@ -1,112 +0,0 @@
/*
ucg_ccs.c
color component slide sub library
Universal uC Color Graphics Library
Copyright (c) 2013, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
e: end
n: steps
f(0) = s
f(n) = e
f(x) = m*x + s
f(n-1) = m*(n-1) + s =!= e
--> m = (e-s)/n
f(x) = (e-s)/(n-1) * x + s
f(0) = s
f(1) = s + (e-s)/(n-1)
*/
#include "ucg.h"
/*
Setup change from "start" to "end" with a specified amount of "steps".
After calling this procedure, ccs->current will contain the "start" value.
*/
void ucg_ccs_init(ucg_ccs_t *ccs, uint8_t start, uint8_t end, ucg_int_t steps)
{
ccs->start = start;
ccs->num = end-start;
ccs->den = steps-1;
ccs->dir = 1;
ccs->quot = ccs->num / ccs->den;
if ( ccs->num < 0 )
{
ccs->num = -ccs->num;
ccs->dir = -1;
}
ccs->rem = ccs->num % ccs->den;
ccs->frac = ccs->den/2;
ccs->current = start;
}
/*
Make one step towards the "end" value.
ccs->curront will contain the updated value.
*/
void ucg_ccs_step(ucg_ccs_t *ccs)
{
ccs->current += ccs->quot;
ccs->frac += ccs->rem;
if ( ccs->frac >= ccs->den )
{
ccs->current += ccs->dir;
ccs->frac -= ccs->den;
}
}
/*
f(x) = (e-s)/(n-1) * x + s
current = (num / den) * (pos / den)
Seek to the specified "pos"ition.
"pos" must be between 0 and "end"-1
*/
void ucg_ccs_seek(ucg_ccs_t *ccs, ucg_int_t pos)
{
ucg_int_t p;
ccs->current = ccs->quot;
ccs->current *= pos;
p = ccs->rem * pos + ccs->den/2;
if ( ccs->dir >= 0 )
ccs->current += p / ccs->den;
else
ccs->current -= p / ccs->den;
ccs->frac = p % ccs->den;
ccs->current += ccs->start;
}

View File

@ -1,217 +0,0 @@
/*
ucg_circle.c
Circle Drawing Procedures
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
static void ucg_draw_circle_section(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t x0, ucg_int_t y0, uint8_t option) UCG_NOINLINE;
static void ucg_draw_circle_section(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t x0, ucg_int_t y0, uint8_t option)
{
/* upper right */
if ( option & UCG_DRAW_UPPER_RIGHT )
{
ucg_DrawPixel(ucg, x0 + x, y0 - y);
ucg_DrawPixel(ucg, x0 + y, y0 - x);
}
/* upper left */
if ( option & UCG_DRAW_UPPER_LEFT )
{
ucg_DrawPixel(ucg, x0 - x, y0 - y);
ucg_DrawPixel(ucg, x0 - y, y0 - x);
}
/* lower right */
if ( option & UCG_DRAW_LOWER_RIGHT )
{
ucg_DrawPixel(ucg, x0 + x, y0 + y);
ucg_DrawPixel(ucg, x0 + y, y0 + x);
}
/* lower left */
if ( option & UCG_DRAW_LOWER_LEFT )
{
ucg_DrawPixel(ucg, x0 - x, y0 + y);
ucg_DrawPixel(ucg, x0 - y, y0 + x);
}
}
void ucg_draw_circle(ucg_t *ucg, ucg_int_t x0, ucg_int_t y0, ucg_int_t rad, uint8_t option)
{
ucg_int_t f;
ucg_int_t ddF_x;
ucg_int_t ddF_y;
ucg_int_t x;
ucg_int_t y;
f = 1;
f -= rad;
ddF_x = 1;
ddF_y = 0;
ddF_y -= rad;
ddF_y *= 2;
x = 0;
y = rad;
ucg_draw_circle_section(ucg, x, y, x0, y0, option);
while ( x < y )
{
if (f >= 0)
{
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
ucg_draw_circle_section(ucg, x, y, x0, y0, option);
}
}
void ucg_DrawCircle(ucg_t *ucg, ucg_int_t x0, ucg_int_t y0, ucg_int_t rad, uint8_t option)
{
/* check for bounding box */
/*
{
ucg_int_t radp, radp2;
radp = rad;
radp++;
radp2 = radp;
radp2 *= 2;
if ( ucg_IsBBXIntersection(ucg, x0-radp, y0-radp, radp2, radp2) == 0)
return;
}
*/
/* draw circle */
ucg_draw_circle(ucg, x0, y0, rad, option);
}
static void ucg_draw_disc_section(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t x0, ucg_int_t y0, uint8_t option) UCG_NOINLINE;
static void ucg_draw_disc_section(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t x0, ucg_int_t y0, uint8_t option)
{
/* upper right */
if ( option & UCG_DRAW_UPPER_RIGHT )
{
ucg_DrawVLine(ucg, x0+x, y0-y, y+1);
ucg_DrawVLine(ucg, x0+y, y0-x, x+1);
}
/* upper left */
if ( option & UCG_DRAW_UPPER_LEFT )
{
ucg_DrawVLine(ucg, x0-x, y0-y, y+1);
ucg_DrawVLine(ucg, x0-y, y0-x, x+1);
}
/* lower right */
if ( option & UCG_DRAW_LOWER_RIGHT )
{
ucg_DrawVLine(ucg, x0+x, y0, y+1);
ucg_DrawVLine(ucg, x0+y, y0, x+1);
}
/* lower left */
if ( option & UCG_DRAW_LOWER_LEFT )
{
ucg_DrawVLine(ucg, x0-x, y0, y+1);
ucg_DrawVLine(ucg, x0-y, y0, x+1);
}
}
void ucg_draw_disc(ucg_t *ucg, ucg_int_t x0, ucg_int_t y0, ucg_int_t rad, uint8_t option)
{
ucg_int_t f;
ucg_int_t ddF_x;
ucg_int_t ddF_y;
ucg_int_t x;
ucg_int_t y;
f = 1;
f -= rad;
ddF_x = 1;
ddF_y = 0;
ddF_y -= rad;
ddF_y *= 2;
x = 0;
y = rad;
ucg_draw_disc_section(ucg, x, y, x0, y0, option);
while ( x < y )
{
if (f >= 0)
{
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
ucg_draw_disc_section(ucg, x, y, x0, y0, option);
}
}
void ucg_DrawDisc(ucg_t *ucg, ucg_int_t x0, ucg_int_t y0, ucg_int_t rad, uint8_t option)
{
/* check for bounding box */
/*
{
ucg_int_t radp, radp2;
radp = rad;
radp++;
radp2 = radp;
radp2 *= 2;
if ( ucg_IsBBXIntersection(ucg, x0-radp, y0-radp, radp2, radp2) == 0)
return;
}
*/
/* draw disc */
ucg_draw_disc(ucg, x0, y0, rad, option);
}

View File

@ -1,252 +0,0 @@
/*
ucg_clip.c
Clipping procedures for the device funktions
Universal uC Color Graphics Library
Copyright (c) 2013, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
static ucg_int_t ucg_clip_is_x_visible(ucg_t *ucg) UCG_NOINLINE;
static ucg_int_t ucg_clip_is_y_visible(ucg_t *ucg) UCG_NOINLINE;
static ucg_int_t ucg_clip_is_x_visible(ucg_t *ucg)
{
ucg_int_t t;
t = ucg->arg.pixel.pos.x;
t -= ucg->clip_box.ul.x;
if ( t < 0 )
return 0;
if ( t >= ucg->clip_box.size.w )
return 0;
return 1;
}
static ucg_int_t ucg_clip_is_y_visible(ucg_t *ucg)
{
ucg_int_t t;
t = ucg->arg.pixel.pos.y;
t -= ucg->clip_box.ul.y;
if ( t < 0 )
return 0;
if ( t >= ucg->clip_box.size.h )
return 0;
return 1;
}
/*
Description:
clip range from a (included) to b (excluded) agains c (included) to d (excluded)
Assumptions:
a <= b
c <= d
*/
static ucg_int_t ucg_clip_intersection(ucg_int_t *ap, ucg_int_t *bp, ucg_int_t c, ucg_int_t d)
{
ucg_int_t a = *ap;
ucg_int_t b = *bp;
if ( a >= d )
return 0;
if ( b <= c )
return 0;
if ( a < c )
*ap = c;
if ( b > d )
*bp = d;
return 1;
}
ucg_int_t ucg_clip_is_pixel_visible(ucg_t *ucg)
{
if ( ucg_clip_is_x_visible(ucg) == 0 )
return 0;
if ( ucg_clip_is_y_visible(ucg) == 0 )
return 0;
return 1;
}
/*
assumes, that ucg->arg contains data for l90fx and does clipping
against ucg->clip_box
*/
ucg_int_t ucg_clip_l90fx(ucg_t *ucg)
{
ucg_int_t a;
ucg_int_t b;
ucg->arg.offset = 0;
switch(ucg->arg.dir)
{
case 0:
if ( ucg_clip_is_y_visible(ucg) == 0 )
return 0;
a = ucg->arg.pixel.pos.x;
b = a;
b += ucg->arg.len;
if ( ucg_clip_intersection(&a, &b, ucg->clip_box.ul.x, ucg->clip_box.ul.x+ucg->clip_box.size.w) == 0 )
return 0;
ucg->arg.offset = a - ucg->arg.pixel.pos.x;
ucg->arg.pixel.pos.x = a;
b -= a;
ucg->arg.len = b;
break;
case 1:
if ( ucg_clip_is_x_visible(ucg) == 0 )
return 0;
a = ucg->arg.pixel.pos.y;
b = a;
b += ucg->arg.len;
if ( ucg_clip_intersection(&a, &b, ucg->clip_box.ul.y, ucg->clip_box.ul.y+ucg->clip_box.size.h) == 0 )
return 0;
ucg->arg.offset = a - ucg->arg.pixel.pos.y;
ucg->arg.pixel.pos.y = a;
b -= a;
ucg->arg.len = b;
break;
case 2:
if ( ucg_clip_is_y_visible(ucg) == 0 )
return 0;
b = ucg->arg.pixel.pos.x;
b++;
a = b;
a -= ucg->arg.len;
if ( ucg_clip_intersection(&a, &b, ucg->clip_box.ul.x, ucg->clip_box.ul.x+ucg->clip_box.size.w) == 0 )
return 0;
ucg->arg.len = b-a;
b--;
ucg->arg.offset = ucg->arg.pixel.pos.x-b;
ucg->arg.pixel.pos.x = b;
break;
case 3:
if ( ucg_clip_is_x_visible(ucg) == 0 )
return 0;
b = ucg->arg.pixel.pos.y;
b++;
a = b;
a -= ucg->arg.len;
if ( ucg_clip_intersection(&a, &b, ucg->clip_box.ul.y, ucg->clip_box.ul.y+ucg->clip_box.size.h) == 0 )
return 0;
ucg->arg.len = b-a;
b--;
ucg->arg.offset = ucg->arg.pixel.pos.y-b;
ucg->arg.pixel.pos.y = b;
break;
}
return 1;
}
ucg_int_t ucg_clip_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90fx(ucg) == 0 )
return 0;
ucg->arg.pixel_skip = ucg->arg.offset & 0x07;
ucg->arg.bitmap += (ucg->arg.offset >>3);
return 1;
}
/* old code
ucg_int_t ucg_clip_l90tc(ucg_t *ucg)
{
ucg_int_t t;
switch(ucg->arg.dir)
{
case 0:
t = ucg->arg.pixel.pos.x;
if ( ucg_clip_l90fx(ucg) == 0 )
return 0;
t = ucg->arg.pixel.pos.x - t;
break;
case 1:
t = ucg->arg.pixel.pos.y;
if ( ucg_clip_l90fx(ucg) == 0 )
return 0;
t = ucg->arg.pixel.pos.y - t;
break;
case 2:
t = ucg->arg.pixel.pos.x;
if ( ucg_clip_l90fx(ucg) == 0 )
return 0;
t -= ucg->arg.pixel.pos.x;
break;
case 3:
t = ucg->arg.pixel.pos.y;
if ( ucg_clip_l90fx(ucg) == 0 )
return 0;
t -= ucg->arg.pixel.pos.y;
break;
}
ucg->arg.pixel_skip = t & 0x07;
ucg->arg.bitmap += (t >>3);
return 1;
}
*/
ucg_int_t ucg_clip_l90se(ucg_t *ucg)
{
uint8_t i;
if ( ucg_clip_l90fx(ucg) == 0 )
return 0;
for ( i = 0; i < 3; i++ )
{
ucg_ccs_seek(ucg->arg.ccs_line+i, ucg->arg.offset);
}
return 1;
}

View File

@ -1,406 +0,0 @@
/*
ucg_com_msg_api.c
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
int16_t ucg_com_template_cb(ucg_t *ucg, int16_t msg, uint32_t arg, uint8_t *data)
{
switch(msg)
{
case UCG_COM_MSG_POWER_UP:
break;
case UCG_COM_MSG_POWER_DOWN:
break;
case UCG_COM_MSG_DELAY:
break;
case UCG_COM_MSG_CHANGE_RESET_LINE:
break;
case UCG_COM_MSG_CHANGE_CS_LINE:
break;
case UCG_COM_MSG_CHANGE_CD_LINE:
break;
case UCG_COM_MSG_SEND_BYTE:
break;
case UCG_COM_MSG_REPEAT_1_BYTE:
break;
case UCG_COM_MSG_REPEAT_2_BYTES:
break;
case UCG_COM_MSG_REPEAT_3_BYTES:
break;
case UCG_COM_MSG_SEND_STR:
break;
case UCG_COM_MSG_SEND_CD_DATA_SEQUENCE:
break;
}
return 1;
}
void ucg_com_PowerDown(ucg_t *ucg)
{
if ( (ucg->com_status & UCG_COM_STATUS_MASK_POWER) != 0 )
ucg->com_cb(ucg, UCG_COM_MSG_POWER_DOWN, 0, NULL);
ucg->com_status &= ~UCG_COM_STATUS_MASK_POWER;
}
/*
clk_speed in nano-seconds, range: 0..4095
*/
int16_t ucg_com_PowerUp(ucg_t *ucg, uint16_t serial_clk_speed, uint16_t parallel_clk_speed)
{
int16_t r;
ucg_com_info_t com_info;
com_info.serial_clk_speed = serial_clk_speed;
com_info.parallel_clk_speed = parallel_clk_speed;
ucg_com_PowerDown(ucg);
ucg->com_initial_change_sent = 0;
r = ucg->com_cb(ucg, UCG_COM_MSG_POWER_UP, 0UL, (uint8_t *)&com_info);
if ( r != 0 )
{
ucg->com_status |= UCG_COM_STATUS_MASK_POWER;
}
return r;
}
void ucg_com_SetLineStatus(ucg_t *ucg, uint8_t level, uint8_t mask, uint8_t msg)
{
if ( level == 0 )
{
if ( (ucg->com_initial_change_sent & mask) == 0 || (ucg->com_status & mask) == mask )
{
ucg->com_cb(ucg, msg, level, NULL);
ucg->com_status &= ~mask;
ucg->com_initial_change_sent |= mask;
}
}
else
{
if ( (ucg->com_initial_change_sent & mask) == 0 || (ucg->com_status & mask) == 0 )
{
ucg->com_cb(ucg, msg, level, NULL);
ucg->com_status |= mask;
ucg->com_initial_change_sent |= mask;
}
}
}
void ucg_com_SetResetLineStatus(ucg_t *ucg, uint8_t level)
{
ucg_com_SetLineStatus(ucg, level, UCG_COM_STATUS_MASK_RESET, UCG_COM_MSG_CHANGE_RESET_LINE);
}
void ucg_com_SetCSLineStatus(ucg_t *ucg, uint8_t level)
{
ucg_com_SetLineStatus(ucg, level, UCG_COM_STATUS_MASK_CS, UCG_COM_MSG_CHANGE_CS_LINE);
}
void ucg_com_SetCDLineStatus(ucg_t *ucg, uint8_t level)
{
ucg_com_SetLineStatus(ucg, level, UCG_COM_STATUS_MASK_CD, UCG_COM_MSG_CHANGE_CD_LINE);
}
/* delay in microseconds */
void ucg_com_DelayMicroseconds(ucg_t *ucg, uint16_t delay)
{
ucg->com_cb(ucg, UCG_COM_MSG_DELAY, delay, NULL);
}
/* delay in milliseconds */
void ucg_com_DelayMilliseconds(ucg_t *ucg, uint16_t delay)
{
while( delay > 0 )
{
ucg_com_DelayMicroseconds(ucg, 1000);
delay--;
}
}
#ifndef ucg_com_SendByte
void ucg_com_SendByte(ucg_t *ucg, uint8_t byte)
{
ucg->com_cb(ucg, UCG_COM_MSG_SEND_BYTE, byte, NULL);
}
#endif
void ucg_com_SendRepeatByte(ucg_t *ucg, uint16_t cnt, uint8_t byte)
{
ucg->com_cb(ucg, UCG_COM_MSG_REPEAT_1_BYTE, cnt, &byte);
}
void ucg_com_SendRepeat2Bytes(ucg_t *ucg, uint16_t cnt, uint8_t *byte_ptr)
{
ucg->com_cb(ucg, UCG_COM_MSG_REPEAT_2_BYTES, cnt, byte_ptr);
}
#ifndef ucg_com_SendRepeat3Bytes
void ucg_com_SendRepeat3Bytes(ucg_t *ucg, uint16_t cnt, uint8_t *byte_ptr)
{
ucg->com_cb(ucg, UCG_COM_MSG_REPEAT_3_BYTES, cnt, byte_ptr);
}
#endif
void ucg_com_SendString(ucg_t *ucg, uint16_t cnt, const uint8_t *byte_ptr)
{
ucg->com_cb(ucg, UCG_COM_MSG_SEND_STR, cnt, (uint8_t *)byte_ptr);
}
void ucg_com_SendStringP(ucg_t *ucg, uint16_t cnt, const ucg_pgm_uint8_t *byte_ptr)
{
uint8_t b;
while( cnt > 0 )
{
b = ucg_pgm_read(byte_ptr);
//b = *byte_ptr;
ucg->com_cb(ucg, UCG_COM_MSG_SEND_BYTE, b, NULL);
byte_ptr++;
cnt--;
}
}
void ucg_com_SendCmdDataSequence(ucg_t *ucg, uint16_t cnt, const uint8_t *byte_ptr, uint8_t cd_line_status_at_end)
{
ucg->com_cb(ucg, UCG_COM_MSG_SEND_CD_DATA_SEQUENCE, cnt, (uint8_t *)byte_ptr);
ucg_com_SetCDLineStatus(ucg, cd_line_status_at_end); // ensure that the status is set correctly for the CD line */
}
/*
Command-Sequence Language
CMD10 1x CMD Byte, 0x Argument Data Bytes
CMD20 2x CMD Byte, 0x Argument Data Bytes
CMD11 1x CMD Byte, 1x Argument Data Bytes
CMD21 2x CMD Byte, 1x Argument Data Bytes
CMD12 1x CMD Byte, 2x Argument Data Bytes
CMD22 2x CMD Byte, 2x Argument Data Bytes
CMD13 1x CMD Byte, 3x Argument Data Bytes
CMD23 2x CMD Byte, 3x Argument Data Bytes
CMD14 1x CMD Byte, 4x Argument Data Bytes
CMD24 2x CMD Byte, 4x Argument Data Bytes
DATA1 1x Data Bytes
DATA2 2x Data Bytes
DATA3 3x Data Bytes
DATA4 4x Data Bytes
DATA5 5x Data Bytes
DATA6 6x Data Bytes
RST_LOW Output 0 on reset line
RST_HIGH Output 1 on reset line
CS_LOW Output 0 on chip select line
CS_HIGH Output 1 on chip select line
DLY_MS Delay for specified amount of milliseconds (0..2000)
DLY_US Delay for specified amount of microconds (0..2000)
Configuration
CFG_CD(c,a) Configure CMD/DATA line: "c" logic level CMD, "a" logic level CMD Args
0000xxxx End Marker
0001xxxx 1x CMD Byte, 0..15 Argument Data Bytes
0010xxxx 2x CMD Byte, 0..15 Argument Data Bytes
0011xxxx 3x CMD Byte, 0..15 Argument Data Bytes
0100xxxx
0101xxxx
0110xxxx Arg Bytes 0..15
0111xxxx Data Bytes 0...15
1000xxxx xxxxxxxx DLY MS
1001xxxx xxxxxxxx DLY US
1010sssss aaaaaaaa oooooooo (var0>>s)&a|o, send as argument
1011sssss aaaaaaaa oooooooo (var1>>s)&a|o, send as argument
1100xxxx
1101xxxx
1110xxxx
11110000 RST_LOW
11110001 RST_HIGH
1111001x
11110100 CS_LOW
11110101 CS_HIGH
1111011x
111110xx
111111ca CFG_CD(c,a)
#define C10(c0) 0x010, (c0)
#define C20(c0,c1) 0x020, (c0),(c1)
#define C11(c0,a0) 0x011, (c0),(a0)
#define C21(c0,c1,a0) 0x021, (c0),(c1),(a0)
#define C12(c0,a0,a1) 0x012, (c0),(a0),(a1)
#define C22(c0,c1,a0,a1) 0x022, (c0),(c1),(a0),(a1)
#define C13(c0,a0,a1,a2) 0x013, (c0),(a0),(a1),(a2)
#define C23(c0,c1,a0,a1,a2) 0x023, (c0),(c1),(a0),(a1),(a2)
#define C14(c0,a0,a1,a2,a3) 0x013, (c0),(a0),(a1),(a2),(a3)
#define C24(c0,c1,a0,a1,a2,a3) 0x023, (c0),(c1),(a0),(a1),(a2),(a3)
#define UCG_DATA() 0x070
#define D1(d0) 0x071, (d0)
#define D2(d0,d1) 0x072, (d0),(d1)
#define D3(d0,d1,d3) 0x073, (d0),(d1),(d2)
#define D4(d0,d1,d3,d4) 0x074, (d0),(d1),(d2),(d3)
#define D5(d0,d1,d3,d4,d5) 0x075, (d0),(d1),(d2),(d3),(d5)
#define D6(d0,d1,d3,d4,d5,d6) 0x076, (d0),(d1),(d2),(d3),(d5),(d6)
#define DLY_MS(t) 0x080 | (((t)>>8)&15), (t)&255
#define DLY_US(t) 0x090 | (((t)>>8)&15), (t)&255
s: Shift right
a: And mask
o: Or mask
#define UCG_VARX(s,a,o) 0x0a0 | ((s)&15), (a), (o)
#define UCG_VARY(s,a,o) 0x0b0 | ((s)&15), (a), (o)
#define RST(level) 0x0f0 | ((level)&1)
#define CS(level) 0x0f4 | ((level)&1)
#define CFG_CD(c,a) 0x0fc | (((c)&1)<<1) | ((a)&1)
#define END() 0x00
*/
static void ucg_com_SendCmdArg(ucg_t *ucg, const ucg_pgm_uint8_t *data, uint8_t cmd_cnt, uint8_t arg_cnt)
{
ucg_com_SetCDLineStatus(ucg, (ucg->com_cfg_cd>>1)&1 );
ucg_com_SendStringP(ucg, cmd_cnt, data);
if ( arg_cnt > 0 )
{
data += cmd_cnt;
ucg_com_SetCDLineStatus(ucg, (ucg->com_cfg_cd)&1 );
ucg_com_SendStringP(ucg, arg_cnt, data);
}
}
//void ucg_com_SendCmdSeq(ucg_t *ucg, const ucg_pgm_uint8_t *data)
void ucg_com_SendCmdSeq(ucg_t *ucg, const ucg_pgm_uint8_t *data)
{
uint8_t b;
uint8_t bb;
uint8_t hi;
uint8_t lo;
for(;;)
{
b = ucg_pgm_read(data);
//b = *data;
hi = (b) >> 4;
lo = (b) & 0x0f;
switch( hi )
{
case 0:
return; /* end marker */
case 1:
case 2:
case 3:
ucg_com_SendCmdArg(ucg, data+1, hi, lo);
data+=1+hi+lo;
break;
case 6:
ucg_com_SetCDLineStatus(ucg, (ucg->com_cfg_cd)&1 );
ucg_com_SendStringP(ucg, lo, data+1);
data+=1+lo;
break;
case 7: /* note: 0x070 is used to set data line status */
ucg_com_SetCDLineStatus(ucg, ((ucg->com_cfg_cd>>1)&1)^1 );
if ( lo > 0 )
ucg_com_SendStringP(ucg, lo, data+1);
data+=1+lo;
break;
case 8:
data++;
b = ucg_pgm_read(data);
//b = *data;
ucg_com_DelayMilliseconds(ucg, (((uint16_t)lo)<<8) + b );
data++;
break;
case 9:
data++;
b = ucg_pgm_read(data);
//b = *data;
ucg_com_DelayMicroseconds(ucg, (((uint16_t)lo)<<8) + b );
data++;
break;
case 10:
data++;
b = ucg_pgm_read(data);
data++;
bb = ucg_pgm_read(data);
data++;
//b = data[0];
//bb = data[1];
ucg_com_SetCDLineStatus(ucg, (ucg->com_cfg_cd)&1 );
ucg_com_SendByte(ucg, (((uint8_t)(((ucg->arg.pixel.pos.x)>>lo)))&b)|bb );
//data+=2;
break;
case 11:
data++;
b = ucg_pgm_read(data);
data++;
bb = ucg_pgm_read(data);
data++;
//b = data[0];
//bb = data[1];
ucg_com_SetCDLineStatus(ucg, (ucg->com_cfg_cd)&1 );
ucg_com_SendByte(ucg, (((uint8_t)(((ucg->arg.pixel.pos.y)>>lo)))&b)|bb );
//data+=2;
break;
case 15:
hi = lo >> 2;
lo &= 3;
switch(hi)
{
case 0:
ucg_com_SetResetLineStatus(ucg, lo&1);
break;
case 1:
ucg_com_SetCSLineStatus(ucg, lo&1);
break;
case 3:
ucg->com_cfg_cd = lo;
break;
}
data++;
break;
default:
return;
}
}
}

View File

@ -1,304 +0,0 @@
/*
ucg_dev_default_cb.c
Universal uC Color Graphics Library
Copyright (c) 2013, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
/*
default device callback
this should be (finally) called by any other device callback to handle
messages, which are not yet handled.
*/
ucg_int_t ucg_dev_default_cb(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
case UCG_MSG_SET_CLIP_BOX:
ucg->clip_box = *(ucg_box_t *)data;
break;
}
return 1; /* all ok */
}
/*
will be used as default cb if no extentions callback is provided
*/
ucg_int_t ucg_ext_none(ucg_t *ucg, ucg_int_t msg, void *data)
{
return 1; /* all ok */
}
/*
handle UCG_MSG_DRAW_L90FX message and make calls to "dev_cb" with UCG_MSG_DRAW_PIXEL
return 1 if something has been drawn
*/
ucg_int_t ucg_handle_l90fx(ucg_t *ucg, ucg_dev_fnptr dev_cb)
{
if ( ucg_clip_l90fx(ucg) != 0 )
{
ucg_int_t dx, dy;
ucg_int_t i;
switch(ucg->arg.dir)
{
case 0: dx = 1; dy = 0; break;
case 1: dx = 0; dy = 1; break;
case 2: dx = -1; dy = 0; break;
case 3: dx = 0; dy = -1; break;
default: dx = 1; dy = 0; break; /* avoid compiler warning */
}
for( i = 0; i < ucg->arg.len; i++ )
{
dev_cb(ucg, UCG_MSG_DRAW_PIXEL, NULL);
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
}
return 1;
}
return 0;
}
/*
handle UCG_MSG_DRAW_L90TC message and make calls to "dev_cb" with UCG_MSG_DRAW_PIXEL
return 1 if something has been drawn
*/
ucg_int_t ucg_handle_l90tc(ucg_t *ucg, ucg_dev_fnptr dev_cb)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
switch(ucg->arg.dir)
{
case 0: dx = 1; dy = 0; break;
case 1: dx = 0; dy = 1; break;
case 2: dx = -1; dy = 0; break;
case 3: dx = 0; dy = -1; break;
default: dx = 1; dy = 0; break; /* avoid compiler warning */
}
//pixmap = *(ucg->arg.bitmap);
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
dev_cb(ucg, UCG_MSG_DRAW_PIXEL, NULL);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
//pixmap = *(ucg->arg.bitmap);
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
return 1;
}
return 0;
}
/*
handle UCG_MSG_DRAW_L90FB message and make calls to "dev_cb" with UCG_MSG_DRAW_PIXEL
return 1 if something has been drawn
*/
ucg_int_t ucg_handle_l90bf(ucg_t *ucg, ucg_dev_fnptr dev_cb)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
ucg_int_t dx, dy;
ucg_int_t i, y;
unsigned char pixmap;
uint8_t bitcnt;
switch(ucg->arg.dir)
{
case 0: dx = 1; dy = 0; break;
case 1: dx = 0; dy = 1; break;
case 2: dx = -1; dy = 0; break;
case 3: dx = 0; dy = -1; break;
default: dx = 1; dy = 0; break; /* avoid compiler warning */
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
for( i = 0; i < ucg->arg.len; i++ )
{
for( y = 0; y < ucg->arg.scale; y++ )
{
if ( (pixmap & 128) == 0 )
{
ucg->arg.pixel.rgb = ucg->arg.rgb[1];
dev_cb(ucg, UCG_MSG_DRAW_PIXEL, NULL);
}
else
{
ucg->arg.pixel.rgb = ucg->arg.rgb[0];
dev_cb(ucg, UCG_MSG_DRAW_PIXEL, NULL);
}
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
}
pixmap<<=1;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
return 1;
}
return 0;
}
/*
handle UCG_MSG_DRAW_L90SE message and make calls to "dev_cb" with UCG_MSG_DRAW_PIXEL
return 1 if something has been drawn
*/
ucg_int_t ucg_handle_l90se(ucg_t *ucg, ucg_dev_fnptr dev_cb)
{
uint8_t i;
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t dx, dy;
ucg_int_t i, j;
switch(ucg->arg.dir)
{
case 0: dx = 1; dy = 0; break;
case 1: dx = 0; dy = 1; break;
case 2: dx = -1; dy = 0; break;
case 3: dx = 0; dy = -1; break;
default: dx = 1; dy = 0; break; /* avoid compiler warning */
}
for( i = 0; i < ucg->arg.len; i++ )
{
ucg->arg.pixel.rgb.color[0] = ucg->arg.ccs_line[0].current;
ucg->arg.pixel.rgb.color[1] = ucg->arg.ccs_line[1].current;
ucg->arg.pixel.rgb.color[2] = ucg->arg.ccs_line[2].current;
dev_cb(ucg, UCG_MSG_DRAW_PIXEL, NULL);
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
for ( j = 0; j < 3; j++ )
{
ucg_ccs_step(ucg->arg.ccs_line+j);
}
}
return 1;
}
return 0;
}
/*
l90rl run lenth encoded constant color pattern
yyllllll wwwwbbbb wwwwbbbb wwwwbbbb wwwwbbbb ...
sequence terminates if wwwwbbbb = 0
wwww: number of pixel to skip
bbbb: number of pixel to draw with color
llllll: number of bytes which follow, can be 0
*/
#ifdef ON_HOLD
void ucg_handle_l90rl(ucg_t *ucg, ucg_dev_fnptr dev_cb)
{
ucg_int_t dx, dy;
uint8_t i, cnt;
uint8_t rl_code;
ucg_int_t skip;
switch(ucg->arg.dir)
{
case 0: dx = 1; dy = 0; break;
case 1: dx = 0; dy = 1; break;
case 2: dx = -1; dy = 0; break;
case 3: dx = 0; dy = -1; break;
default: dx = 1; dy = 0; break; /* avoid compiler warning */
}
cnt = ucg_pgm_read(ucg->arg.bitmap);
cnt &= 63;
ucg->arg.bitmap++;
for( i = 0; i < cnt; i++ )
{
rl_code = ucg_pgm_read(ucg->arg.bitmap);
if ( rl_code == 0 )
break;
skip = (ucg_int_t)(rl_code >> 4);
switch(ucg->arg.dir)
{
case 0: ucg->arg.pixel.pos.x+=skip; break;
case 1: ucg->arg.pixel.pos.y+=skip; break;
case 2: ucg->arg.pixel.pos.x-=skip; break;
default:
case 3: ucg->arg.pixel.pos.y-=skip; break;
}
rl_code &= 15;
while( rl_code )
{
dev_cb(ucg, UCG_MSG_DRAW_PIXEL, NULL);
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
rl_code--;
}
ucg->arg.bitmap++;
}
}
#endif

View File

@ -1,402 +0,0 @@
/*
ucg_dev_ic_ili9163.c
Specific code for the ili9163 controller (TFT displays)
Code is for 128x128 display which is shifted by 32 pixel within the controller RAM
Universal uC Color Graphics Library
Copyright (c) 2015, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
const ucg_pgm_uint8_t ucg_ili9163_set_pos_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11( 0x036, 0x008),
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_D2(0x000, 0x07f), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x00, 0), UCG_VARY(0,0x0ff, 0), UCG_D2(0x000, 0x0a1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ili9163_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x008 horizontal increment (dir = 0) */
/* 0x008 vertical increment (dir = 1) */
/* 0x048 horizontal deccrement (dir = 2) */
/* 0x088 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x008),
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_D2(0x000, 0x083), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x00, 0), UCG_VARY(0,0x0ff, 0), UCG_D2(0x000, 0x0a1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ili9163_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x008 horizontal increment (dir = 0) */
/* 0x008 vertical increment (dir = 1) */
/* 0x048 horizontal deccrement (dir = 2) */
/* 0x088 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x008),
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x00, 0), UCG_VARY(0,0x0ff, 0), UCG_D2(0x000, 0x0a1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ili9163_set_pos_dir2_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x008 horizontal increment (dir = 0) */
/* 0x008 vertical increment (dir = 1) */
/* 0x048 horizontal deccrement (dir = 2) */
/* 0x088 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x048),
UCG_C11( 0x036, 0x048), /* it seems that this command needs to be sent twice */
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_D2(0x000, 0x083), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x00, 0), UCG_VARY(0,0x0ff, 0), UCG_D2(0x000, 0x0a1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ili9163_set_pos_dir3_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x008 horizontal increment (dir = 0) */
/* 0x008 vertical increment (dir = 1) */
/* 0x0c8 horizontal deccrement (dir = 2) */
/* 0x0c8 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x088),
UCG_C11( 0x036, 0x088), /* it seems that this command needs to be sent twice */
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x00, 0), UCG_VARY(0,0x0ff, 0), UCG_D2(0x000, 0x0a1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
ucg_int_t ucg_handle_ili9163_l90fx(ucg_t *ucg)
{
uint8_t c[3];
ucg_int_t tmp;
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg->arg.pixel.pos.y += 32;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_dir0_seq);
ucg->arg.pixel.pos.y -= 32;
break;
case 1:
ucg->arg.pixel.pos.y += 32;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_dir1_seq);
ucg->arg.pixel.pos.y -= 32;
break;
case 2:
tmp = ucg->arg.pixel.pos.x;
ucg->arg.pixel.pos.x = 127-tmp;
ucg->arg.pixel.pos.y += 32;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_dir2_seq);
ucg->arg.pixel.pos.y -= 32;
ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
tmp = ucg->arg.pixel.pos.y;
ucg->arg.pixel.pos.y = 127-tmp;
//ucg->arg.pixel.pos.y += 32;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_dir3_seq);
ucg->arg.pixel.pos.y = tmp;
break;
}
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Glyph Output)
*/
/* with CmdDataSequence */
ucg_int_t ucg_handle_ili9163_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[16];
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg->arg.pixel.pos.y += 32;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_seq);
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x02a; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // upper part x
buf[4] = 0x000; // no change
buf[5] = 0x000; // will be overwritten by x value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x02c; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
buf[1] = 0x02a; // set x
break;
case 1:
dx = 0; dy = 1;
buf[1] = 0x02b; // set y
break;
case 2:
dx = -1; dy = 0;
buf[1] = 0x02a; // set x
break;
case 3:
default:
dx = 0; dy = -1;
buf[1] = 0x02b; // set y
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[9] = ucg->arg.pixel.rgb.color[0];
buf[11] = ucg->arg.pixel.rgb.color[1];
buf[13] = ucg->arg.pixel.rgb.color[2];
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
if ( (ucg->arg.dir&1) == 0 )
{
buf[5] = ucg->arg.pixel.pos.x;
}
else
{
buf[3] = ucg->arg.pixel.pos.y>>8;
buf[5] = ucg->arg.pixel.pos.y&255;
}
ucg_com_SendCmdDataSequence(ucg, 7, buf, 0);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_handle_ili9163_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
ucg_int_t tmp;
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t i;
switch(ucg->arg.dir)
{
case 0:
ucg->arg.pixel.pos.y += 32;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_dir0_seq);
ucg->arg.pixel.pos.y -= 32;
break;
case 1:
ucg->arg.pixel.pos.y += 32;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_dir1_seq);
ucg->arg.pixel.pos.y -= 32;
break;
case 2:
tmp = ucg->arg.pixel.pos.x;
ucg->arg.pixel.pos.x = 127-tmp;
ucg->arg.pixel.pos.y += 32;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_dir2_seq);
ucg->arg.pixel.pos.y -= 32;
ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
tmp = ucg->arg.pixel.pos.y;
ucg->arg.pixel.pos.y = 127-tmp;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_dir3_seq);
ucg->arg.pixel.pos.y = tmp;
break;
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = ucg->arg.ccs_line[0].current;
c[1] = ucg->arg.ccs_line[1].current;
c[2] = ucg->arg.ccs_line[2].current;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_ccs_step(ucg->arg.ccs_line+0);
ucg_ccs_step(ucg->arg.ccs_line+1);
ucg_ccs_step(ucg->arg.ccs_line+2);
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static const ucg_pgm_uint8_t ucg_ili9163_power_down_seq[] = {
UCG_CS(0), /* enable chip */
UCG_C10(0x010), /* sleep in */
UCG_C10(0x28), /* display off */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ic_ili9163_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 100, 66);
case UCG_MSG_DEV_POWER_DOWN:
ucg_com_SendCmdSeq(ucg, ucg_ili9163_power_down_seq);
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 128;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg->arg.pixel.pos.y += 32;
ucg_com_SendCmdSeq(ucg, ucg_ili9163_set_pos_seq);
ucg->arg.pixel.pos.y -= 32;
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_ili9163_18);
ucg_handle_ili9163_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
//ucg_handle_l90tc(ucg, ucg_dev_ic_ili9163_18);
ucg_handle_ili9163_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_ili9163_18);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_ili9163_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_ili9163_18);
ucg_handle_ili9163_l90se(ucg);
break;
}
return 1;
}

View File

@ -1,484 +0,0 @@
/*
ucg_dev_ic_ili9325.c
Specific code for the ili9325 controller (TFT displays)
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C22(0x000, 0x003, 0xc0 | 0x010, 0x030), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C22(0x000, 0x003, 0xc0 | 0x010, 0x038), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_dir2_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C22(0x000, 0x003, 0xc0 | 0x010, 0x000), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_dir3_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C22(0x000, 0x003, 0xc0 | 0x010, 0x008), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static ucg_int_t ucg_handle_ili9325_l90fx(ucg_t *ucg)
{
uint8_t c[3];
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir1_seq);
break;
case 2:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir2_seq);
break;
case 3:
default:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir3_seq);
break;
}
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Glyph Output)
Because of this for vertical lines the x min and max values in
"ucg_ili9325_set_pos_for_y_seq" are identical to avoid changes of the x position
*/
static const ucg_pgm_uint8_t ucg_ili9325_set_x_pos_seq[] =
{
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_y_pos_seq[] =
{
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
/* without CmdDataSequence */
ucg_int_t xxxxxx_ucg_handle_ili9325_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[3];
ucg_int_t dx, dy;
ucg_int_t i;
const uint8_t *seq;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_seq);
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
seq = ucg_ili9325_set_x_pos_seq;
break;
case 1:
dx = 0; dy = 1;
seq = ucg_ili9325_set_y_pos_seq;
break;
case 2:
dx = -1; dy = 0;
seq = ucg_ili9325_set_x_pos_seq;
break;
case 3:
default:
dx = 0; dy = -1;
seq = ucg_ili9325_set_y_pos_seq;
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[0] = ucg->arg.pixel.rgb.color[0];
buf[1] = ucg->arg.pixel.rgb.color[1];
buf[2] = ucg->arg.pixel.rgb.color[2];
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
ucg_com_SendCmdSeq(ucg, seq);
ucg_com_SendRepeat3Bytes(ucg, 1, buf);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/* with CmdDataSequence */
static ucg_int_t ucg_handle_ili9325_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[20];
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_seq);
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x020; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // upper part x
buf[4] = 0x000; // no change
buf[5] = 0x000; // will be overwritten by x value
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x022; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
break;
case 1:
dx = 0; dy = 1;
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x021; // set y
buf[8] = 0x002; // change to 1 (arg mode)
buf[9] = 0x000; // upper part y
buf[10] = 0x000; // no change
buf[11] = 0x000; // will be overwritten by y value
buf[12] = 0x001; // change to 0 (cmd mode)
buf[13] = 0x022; // write data
buf[14] = 0x002; // change to 1 (data mode)
buf[15] = 0x000; // red value
buf[16] = 0x000; // no change
buf[17] = 0x000; // green value
buf[18] = 0x000; // no change
buf[19] = 0x000; // blue value
break;
case 2:
dx = -1; dy = 0;
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x022; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
break;
case 3:
default:
dx = 0; dy = -1;
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x021; // set y
buf[8] = 0x002; // change to 1 (arg mode)
buf[9] = 0x000; // upper part y
buf[10] = 0x000; // no change
buf[11] = 0x000; // will be overwritten by y value
buf[12] = 0x001; // change to 0 (cmd mode)
buf[13] = 0x022; // write data
buf[14] = 0x002; // change to 1 (data mode)
buf[15] = 0x000; // red value
buf[16] = 0x000; // no change
buf[17] = 0x000; // green value
buf[18] = 0x000; // no change
buf[19] = 0x000; // blue value
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
if ( (ucg->arg.dir&1) == 0 )
{
buf[9] = ucg->arg.pixel.rgb.color[0];
buf[11] = ucg->arg.pixel.rgb.color[1];
buf[13] = ucg->arg.pixel.rgb.color[2];
}
else
{
buf[15] = ucg->arg.pixel.rgb.color[0];
buf[17] = ucg->arg.pixel.rgb.color[1];
buf[19] = ucg->arg.pixel.rgb.color[2];
}
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
if ( (ucg->arg.dir&1) == 0 )
{
buf[5] = ucg->arg.pixel.pos.x;
ucg_com_SendCmdDataSequence(ucg, 7, buf, 1);
}
else
{
buf[5] = ucg->arg.pixel.pos.x;
buf[9] = (ucg->arg.pixel.pos.y>>8)&1;
buf[11] = ucg->arg.pixel.pos.y&255;
ucg_com_SendCmdDataSequence(ucg, 10, buf, 1);
}
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static ucg_int_t ucg_handle_ili9325_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t i;
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir1_seq);
break;
case 2:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir2_seq);
break;
case 3:
default:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir3_seq);
break;
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = ucg->arg.ccs_line[0].current;
c[1] = ucg->arg.ccs_line[1].current;
c[2] = ucg->arg.ccs_line[2].current;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_ccs_step(ucg->arg.ccs_line+0);
ucg_ccs_step(ucg->arg.ccs_line+1);
ucg_ccs_step(ucg->arg.ccs_line+2);
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_dev_ic_ili9325_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 40, 100);
case UCG_MSG_DEV_POWER_DOWN:
/* not yet implemented */
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 240;
((ucg_wh_t *)data)->h = 320;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_seq);
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_ili9325_18);
ucg_handle_ili9325_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
//ucg_handle_l90tc(ucg, ucg_dev_ic_ili9325);
ucg_handle_ili9325_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_ili9325_18);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_ili9325_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_ili9325);
ucg_handle_ili9325_l90se(ucg);
break;
}
return 1;
}

View File

@ -1,484 +0,0 @@
/*
ucg_dev_ic_ili9325_spi.c
Specific code for the ili9325 controller (TFT displays) with SPI mode (IM3=0, IM2=1, IM1=1, IM0=1)
1 May 2014: Currently, this is not working
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C12(0x003, 0xc0 | 0x010, 0x030), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C12(0x003, 0xc0 | 0x010, 0x038), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_dir2_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C12(0x003, 0xc0 | 0x010, 0x000), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_pos_dir3_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C12(0x003, 0xc0 | 0x010, 0x008), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static ucg_int_t ucg_handle_ili9325_l90fx(ucg_t *ucg)
{
uint8_t c[3];
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir1_seq);
break;
case 2:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir2_seq);
break;
case 3:
default:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir3_seq);
break;
}
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Glyph Output)
Because of this for vertical lines the x min and max values in
"ucg_ili9325_set_pos_for_y_seq" are identical to avoid changes of the x position
*/
static const ucg_pgm_uint8_t ucg_ili9325_set_x_pos_seq[] =
{
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ili9325_set_y_pos_seq[] =
{
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
/* without CmdDataSequence */
static ucg_int_t xxxxxx_ucg_handle_ili9325_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[3];
ucg_int_t dx, dy;
ucg_int_t i;
const uint8_t *seq;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_seq);
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
seq = ucg_ili9325_set_x_pos_seq;
break;
case 1:
dx = 0; dy = 1;
seq = ucg_ili9325_set_y_pos_seq;
break;
case 2:
dx = -1; dy = 0;
seq = ucg_ili9325_set_x_pos_seq;
break;
case 3:
default:
dx = 0; dy = -1;
seq = ucg_ili9325_set_y_pos_seq;
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[0] = ucg->arg.pixel.rgb.color[0];
buf[1] = ucg->arg.pixel.rgb.color[1];
buf[2] = ucg->arg.pixel.rgb.color[2];
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
ucg_com_SendCmdSeq(ucg, seq);
ucg_com_SendRepeat3Bytes(ucg, 1, buf);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/* with CmdDataSequence */
static ucg_int_t ucg_handle_ili9325_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[20];
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_seq);
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x020; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // upper part x
buf[4] = 0x000; // no change
buf[5] = 0x000; // will be overwritten by x value
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x022; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
break;
case 1:
dx = 0; dy = 1;
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x021; // set y
buf[8] = 0x002; // change to 1 (arg mode)
buf[9] = 0x000; // upper part y
buf[10] = 0x000; // no change
buf[11] = 0x000; // will be overwritten by y value
buf[12] = 0x001; // change to 0 (cmd mode)
buf[13] = 0x022; // write data
buf[14] = 0x002; // change to 1 (data mode)
buf[15] = 0x000; // red value
buf[16] = 0x000; // no change
buf[17] = 0x000; // green value
buf[18] = 0x000; // no change
buf[19] = 0x000; // blue value
break;
case 2:
dx = -1; dy = 0;
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x022; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
break;
case 3:
default:
dx = 0; dy = -1;
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x021; // set y
buf[8] = 0x002; // change to 1 (arg mode)
buf[9] = 0x000; // upper part y
buf[10] = 0x000; // no change
buf[11] = 0x000; // will be overwritten by y value
buf[12] = 0x001; // change to 0 (cmd mode)
buf[13] = 0x022; // write data
buf[14] = 0x002; // change to 1 (data mode)
buf[15] = 0x000; // red value
buf[16] = 0x000; // no change
buf[17] = 0x000; // green value
buf[18] = 0x000; // no change
buf[19] = 0x000; // blue value
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
if ( (ucg->arg.dir&1) == 0 )
{
buf[9] = ucg->arg.pixel.rgb.color[0];
buf[11] = ucg->arg.pixel.rgb.color[1];
buf[13] = ucg->arg.pixel.rgb.color[2];
}
else
{
buf[15] = ucg->arg.pixel.rgb.color[0];
buf[17] = ucg->arg.pixel.rgb.color[1];
buf[19] = ucg->arg.pixel.rgb.color[2];
}
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
if ( (ucg->arg.dir&1) == 0 )
{
buf[5] = ucg->arg.pixel.pos.x;
ucg_com_SendCmdDataSequence(ucg, 7, buf, 1);
}
else
{
buf[5] = ucg->arg.pixel.pos.x;
buf[9] = (ucg->arg.pixel.pos.y>>8)&1;
buf[11] = ucg->arg.pixel.pos.y&255;
ucg_com_SendCmdDataSequence(ucg, 10, buf, 1);
}
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static ucg_int_t ucg_handle_ili9325_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t i;
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir1_seq);
break;
case 2:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir2_seq);
break;
case 3:
default:
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_dir3_seq);
break;
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = ucg->arg.ccs_line[0].current;
c[1] = ucg->arg.ccs_line[1].current;
c[2] = ucg->arg.ccs_line[2].current;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_ccs_step(ucg->arg.ccs_line+0);
ucg_ccs_step(ucg->arg.ccs_line+1);
ucg_ccs_step(ucg->arg.ccs_line+2);
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_dev_ic_ili9325_spi_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 40, 100);
case UCG_MSG_DEV_POWER_DOWN:
/* not yet implemented */
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 240;
((ucg_wh_t *)data)->h = 320;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_ili9325_set_pos_seq);
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_ili9325_18);
ucg_handle_ili9325_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
//ucg_handle_l90tc(ucg, ucg_dev_ic_ili9325);
ucg_handle_ili9325_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_ili9325_18);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_ili9325_spi_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_ili9325);
ucg_handle_ili9325_l90se(ucg);
break;
}
return 1;
}

View File

@ -1,382 +0,0 @@
/*
ucg_dev_ic_ili9341.c
Specific code for the ili9341 controller (TFT displays)
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
const ucg_pgm_uint8_t ucg_ili9341_set_pos_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11( 0x036, 0x008),
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_A2(0x000, 0x0ef), /* set x position */
UCG_C10(0x02b), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x001, 0x03f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ili9341_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x008 horizontal increment (dir = 0) */
/* 0x008 vertical increment (dir = 1) */
/* 0x048 horizontal deccrement (dir = 2) */
/* 0x088 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x008),
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_A2(0x000, 0x0ef), /* set x position */
UCG_C10(0x02b), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x001, 0x03f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ili9341_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x008 horizontal increment (dir = 0) */
/* 0x008 vertical increment (dir = 1) */
/* 0x048 horizontal deccrement (dir = 2) */
/* 0x088 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x008),
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x02b), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x001, 0x03f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ili9341_set_pos_dir2_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x008 horizontal increment (dir = 0) */
/* 0x008 vertical increment (dir = 1) */
/* 0x048 horizontal deccrement (dir = 2) */
/* 0x088 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x048),
UCG_C11( 0x036, 0x048), /* it seems that this command needs to be sent twice */ /* should be check again */
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_A2(0x000, 0x0ef), /* set x position */
UCG_C10(0x02b), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x001, 0x03f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ili9341_set_pos_dir3_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x008 horizontal increment (dir = 0) */
/* 0x008 vertical increment (dir = 1) */
/* 0x0c8 horizontal deccrement (dir = 2) */
/* 0x0c8 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x088),
UCG_C11( 0x036, 0x088), /* it seems that this command needs to be sent twice */ /* should be check again */
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x02b), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x001, 0x03f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
ucg_int_t ucg_handle_ili9341_l90fx(ucg_t *ucg)
{
uint8_t c[3];
ucg_int_t tmp;
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_dir1_seq);
break;
case 2:
tmp = ucg->arg.pixel.pos.x;
ucg->arg.pixel.pos.x = 239-tmp;
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_dir2_seq);
ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
tmp = ucg->arg.pixel.pos.y;
ucg->arg.pixel.pos.y = 319-tmp;
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_dir3_seq);
ucg->arg.pixel.pos.y = tmp;
break;
}
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Glyph Output)
*/
/* with CmdDataSequence */
ucg_int_t ucg_handle_ili9341_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[16];
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_seq);
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x02a; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // upper part x
buf[4] = 0x000; // no change
buf[5] = 0x000; // will be overwritten by x value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x02c; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
buf[1] = 0x02a; // set x
break;
case 1:
dx = 0; dy = 1;
buf[1] = 0x02b; // set y
break;
case 2:
dx = -1; dy = 0;
buf[1] = 0x02a; // set x
break;
case 3:
default:
dx = 0; dy = -1;
buf[1] = 0x02b; // set y
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[9] = ucg->arg.pixel.rgb.color[0];
buf[11] = ucg->arg.pixel.rgb.color[1];
buf[13] = ucg->arg.pixel.rgb.color[2];
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
if ( (ucg->arg.dir&1) == 0 )
{
buf[5] = ucg->arg.pixel.pos.x;
}
else
{
buf[3] = ucg->arg.pixel.pos.y>>8;
buf[5] = ucg->arg.pixel.pos.y&255;
}
ucg_com_SendCmdDataSequence(ucg, 7, buf, 0);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_handle_ili9341_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
ucg_int_t tmp;
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t i;
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_dir1_seq);
break;
case 2:
tmp = ucg->arg.pixel.pos.x;
ucg->arg.pixel.pos.x = 239-tmp;
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_dir2_seq);
ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
tmp = ucg->arg.pixel.pos.y;
ucg->arg.pixel.pos.y = 319-tmp;
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_dir3_seq);
ucg->arg.pixel.pos.y = tmp;
break;
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = ucg->arg.ccs_line[0].current;
c[1] = ucg->arg.ccs_line[1].current;
c[2] = ucg->arg.ccs_line[2].current;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_ccs_step(ucg->arg.ccs_line+0);
ucg_ccs_step(ucg->arg.ccs_line+1);
ucg_ccs_step(ucg->arg.ccs_line+2);
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static const ucg_pgm_uint8_t ucg_ili9341_power_down_seq[] = {
UCG_CS(0), /* enable chip */
UCG_C10(0x010), /* sleep in */
UCG_C10(0x28), /* display off */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ic_ili9341_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 100, 66);
case UCG_MSG_DEV_POWER_DOWN:
ucg_com_SendCmdSeq(ucg, ucg_ili9341_power_down_seq);
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 240;
((ucg_wh_t *)data)->h = 320;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_ili9341_set_pos_seq);
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_ili9341_18);
ucg_handle_ili9341_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
//ucg_handle_l90tc(ucg, ucg_dev_ic_ili9341_18);
ucg_handle_ili9341_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_ili9341_18);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_ili9341_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_ili9341_18);
ucg_handle_ili9341_l90se(ucg);
break;
}
return 1;
}

View File

@ -1,358 +0,0 @@
/*
ucg_dev_ic_ld50t6160.c
Specific code for the ld50t6160 controller (OLED displays)
Universal uC Color Graphics Library
Copyright (c) 2015, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
/*
Graphics Memory Writing Direction: 0x05
Bit 3: RGB/BGR
Bit 0-2: Direction
0x05, 0x00 dir 0
0x05, 0x05 dir 1
0x05, 0x03 dir 2
0x05, 0x06 dir 3
Data Reading/Writing Box: 0x0a
8 bytes as arguments: xs, ys, xe, ye
*/
const ucg_pgm_uint8_t ucg_ld50t6160_set_pos_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11(0x05, 0x00),
UCG_C10(0x0a), UCG_VARX(4,0x0f, 0), UCG_VARX(0,0x0f, 0), UCG_A2(0x007, 0x0f), /* set x position */
UCG_VARY(4,0x0f, 0), UCG_VARY(0,0x0f, 0), UCG_A2(0x09, 0x0f), /* set y position */
UCG_C10(0x0c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ld50t6160_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11(0x05, 0x00),
UCG_C10(0x0a),
UCG_VARX(4,0x0f, 0), UCG_VARX(0,0x0f, 0), UCG_A2(0x007, 0x0f), /* set x position */
UCG_VARY(4,0x0f, 0), UCG_VARY(0,0x0f, 0), UCG_A2(0x09, 0x0f), /* set y position */
UCG_C10(0x0c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ld50t6160_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11(0x05, 0x05),
UCG_C10(0x0a),
//UCG_VARX(4,0x0f, 0), UCG_VARX(0,0x0f, 0), UCG_D2(0x007, 0x0f), /* set x position */
UCG_A2(0x00, 0x00), UCG_VARX(4,0x0f, 0), UCG_VARX(0,0x0f, 0), /* set x position */
UCG_VARY(4,0x0f, 0), UCG_VARY(0,0x0f, 0), UCG_A2(0x09, 0x0f), /* set y position */
UCG_C10(0x0c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ld50t6160_set_pos_dir2_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11(0x05, 0x03),
UCG_C10(0x0a),
UCG_A2(0x00, 0x00), UCG_VARX(4,0x0f, 0), UCG_VARX(0,0x0f, 0), /* set x position */
UCG_A2(0x00, 0x00), UCG_VARY(4,0x0f, 0), UCG_VARY(0,0x0f, 0), /* set y position */
UCG_C10(0x0c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ld50t6160_set_pos_dir3_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11(0x05, 0x06),
UCG_C10(0x0a),
UCG_VARX(4,0x0f, 0), UCG_VARX(0,0x0f, 0), UCG_A2(0x07, 0x0f), /* set x position */
UCG_A2(0x00, 0x00), UCG_VARY(4,0x0f, 0), UCG_VARY(0,0x0f, 0), /* set y position */
UCG_C10(0x0c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static ucg_int_t ucg_handle_ld50t6160_l90fx(ucg_t *ucg)
{
uint8_t c[3];
//ucg_int_t tmp;
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_set_pos_dir1_seq);
break;
case 2:
//tmp = ucg->arg.pixel.pos.x;
//ucg->arg.pixel.pos.x = 127-tmp;
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_set_pos_dir2_seq);
//ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
//tmp = ucg->arg.pixel.pos.y;
//ucg->arg.pixel.pos.y = 159-tmp;
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_set_pos_dir3_seq);
//ucg->arg.pixel.pos.y = tmp;
break;
}
c[0] = ucg->arg.pixel.rgb.color[0]>>2;
c[1] = ucg->arg.pixel.rgb.color[1]>>2;
c[2] = ucg->arg.pixel.rgb.color[2]>>2;
ucg_com_SendRepeat3Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Glyph Output)
*/
#ifdef UCG_MSG_DRAW_L90TC
static ucg_int_t ucg_handle_ld50t6160_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[3];
ucg_int_t dx, dy;
ucg_int_t i;
const uint8_t *seq;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
seq = ucg_ld50t6160_set_pos_dir0_seq;
break;
case 1:
dx = 0; dy = 1;
seq = ucg_ld50t6160_set_pos_dir1_seq;
break;
case 2:
dx = -1; dy = 0;
seq = ucg_ld50t6160_set_pos_dir2_seq;
break;
case 3:
default:
dx = 0; dy = -1;
seq = ucg_ld50t6160_set_pos_dir3_seq;
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[0] = ucg->arg.pixel.rgb.color[0]>>2;
buf[1] = ucg->arg.pixel.rgb.color[1]>>2;
buf[2] = ucg->arg.pixel.rgb.color[2]>>2;
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
ucg_com_SendCmdSeq(ucg, seq);
ucg_com_SendRepeat3Bytes(ucg, 1, buf);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
#endif /* UCG_MSG_DRAW_L90TC */
ucg_int_t ucg_handle_ld50t6160_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
//ucg_int_t tmp;
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t i;
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_set_pos_dir1_seq);
break;
case 2:
//tmp = ucg->arg.pixel.pos.x;
//ucg->arg.pixel.pos.x = 239-tmp;
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_set_pos_dir2_seq);
//ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
//tmp = ucg->arg.pixel.pos.y;
//ucg->arg.pixel.pos.y = 319-tmp;
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_set_pos_dir3_seq);
//ucg->arg.pixel.pos.y = tmp;
break;
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = ucg->arg.ccs_line[0].current>>2;
c[1] = ucg->arg.ccs_line[1].current>>2;
c[2] = ucg->arg.ccs_line[2].current>>2;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_ccs_step(ucg->arg.ccs_line+0);
ucg_ccs_step(ucg->arg.ccs_line+1);
ucg_ccs_step(ucg->arg.ccs_line+2);
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static const ucg_pgm_uint8_t ucg_ld50t6160_power_down_seq[] = {
UCG_CS(0), /* enable chip */
UCG_C11(0x02, 0x00), /* display off */
UCG_C11(0x20, 0x00), /* all ICON off */
UCG_C11(0x20, 0x01), /* stop OSCB */
UCG_C10(0x010), /* sleep in */
UCG_C10(0x28), /* display off */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ic_ld50t6160_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 100, 66);
case UCG_MSG_DEV_POWER_DOWN:
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_power_down_seq);
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 160;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_ld50t6160_set_pos_seq);
c[0] = ucg->arg.pixel.rgb.color[0]>>2;
c[1] = ucg->arg.pixel.rgb.color[1]>>2;
c[2] = ucg->arg.pixel.rgb.color[2]>>2;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_ld50t6160_18);
ucg_handle_ld50t6160_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
//ucg_handle_l90tc(ucg, ucg_dev_ic_ld50t6160_18);
ucg_handle_ld50t6160_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_ld50t6160_18);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_ld50t6160_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_ld50t6160_18);
ucg_handle_ld50t6160_l90se(ucg);
break;
}
return 1;
}

View File

@ -1,409 +0,0 @@
/*
ucg_dev_ic_pcf8833.c
Specific code for the pcf8833 controller (TFT displays)
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
#define XOFFSET 0
#define WIDTH 132
#define HEIGHT 132
const ucg_pgm_uint8_t ucg_pcf8833_set_pos_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11( 0x036, 0x000),
UCG_C10(0x02a), UCG_VARX(0,0x0ff, 0), UCG_A1(WIDTH-1), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x0ff, 0), UCG_A1(HEIGHT-1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_pcf8833_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
/*
bit 7: my
bit 6: mx
bit 5: x or y increment
bit 4: line order
bit 3: rgb
*/
UCG_C11( 0x036, 0x000),
UCG_C10(0x02a), UCG_VARX(0,0x0ff, 0), UCG_A1(WIDTH-1), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x0ff, 0), UCG_A1(HEIGHT-1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_pcf8833_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
/*
bit 7: my
bit 6: mx
bit 5: x or y increment
bit 4: line order
bit 3: rgb
*/
UCG_C11( 0x036, 0x000),
UCG_C10(0x02a), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x0ff, 0), UCG_A1(HEIGHT-1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_pcf8833_set_pos_dir2_seq[] =
{
UCG_CS(0), /* enable chip */
/*
bit 7: my
bit 6: mx
bit 5: x or y increment
bit 4: line order
bit 3: rgb
*/
UCG_C11( 0x036, 0x040),
//UCG_C11( 0x036, 0x020), /* it seems that this command needs to be sent twice */
UCG_C10(0x02a), UCG_VARX(0,0x0ff, 0), UCG_A1(WIDTH-1), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x0ff, 0), UCG_A1(HEIGHT-1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_pcf8833_set_pos_dir3_seq[] =
{
UCG_CS(0), /* enable chip */
/*
bit 7: my
bit 6: mx
bit 5: x or y increment
bit 4: line order
bit 3: rgb
*/
UCG_C11( 0x036, 0x080),
//UCG_C11( 0x036, 0x0d0), /* it seems that this command needs to be sent twice */
UCG_C10(0x02a), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x0ff, 0), UCG_A1(HEIGHT-1), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static uint8_t ucg_pcf8833_get_color_high_byte(ucg_t *ucg)
{
return (ucg->arg.pixel.rgb.color[0]&0x0f8) | (((ucg->arg.pixel.rgb.color[1]) >>5));
}
static uint8_t ucg_pcf8833_get_color_low_byte(ucg_t *ucg)
{
return ((((ucg->arg.pixel.rgb.color[1]))<<3)&0x0e0) | (((ucg->arg.pixel.rgb.color[2]) >>3));
}
ucg_int_t ucg_handle_pcf8833_l90fx(ucg_t *ucg)
{
uint8_t c[3];
ucg_int_t tmp;
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_dir1_seq);
break;
case 2:
tmp = ucg->arg.pixel.pos.x;
ucg->arg.pixel.pos.x = WIDTH-1-tmp;
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_dir2_seq);
ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
tmp = ucg->arg.pixel.pos.y;
ucg->arg.pixel.pos.y = HEIGHT-1-tmp;
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_dir3_seq);
ucg->arg.pixel.pos.y = tmp;
break;
}
c[0] = ucg_pcf8833_get_color_high_byte(ucg);
c[1] = ucg_pcf8833_get_color_low_byte(ucg);
ucg_com_SendRepeat2Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Glyph Output)
*/
/* with CmdDataSequence */
ucg_int_t ucg_handle_pcf8833_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[16];
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_seq);
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x02a; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // x/y
buf[4] = 0x000; // no change
buf[5] = 0x000; // end value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x02c; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = ucg_pcf8833_get_color_high_byte(ucg);
buf[10] = 0x000; // no change
buf[11] = ucg_pcf8833_get_color_low_byte(ucg);
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
buf[1] = 0x02a; // set x
buf[5] = WIDTH-1; // end value
break;
case 1:
dx = 0; dy = 1;
buf[1] = 0x02b; // set y
buf[5] = HEIGHT-1; // end value
break;
case 2:
dx = -1; dy = 0;
buf[1] = 0x02a; // set x
buf[5] = WIDTH-1; // end value
break;
case 3:
default:
dx = 0; dy = -1;
buf[1] = 0x02b; // set y
buf[5] = HEIGHT-1; // end value
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
if ( (ucg->arg.dir&1) == 0 )
{
buf[3] = ucg->arg.pixel.pos.x;
}
else
{
buf[3] = ucg->arg.pixel.pos.y;
}
ucg_com_SendCmdDataSequence(ucg, 6, buf, 0);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_handle_pcf8833_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
ucg_int_t tmp;
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t i;
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_dir1_seq);
break;
case 2:
tmp = ucg->arg.pixel.pos.x;
ucg->arg.pixel.pos.x = WIDTH-1-tmp;
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_dir2_seq);
ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
tmp = ucg->arg.pixel.pos.y;
ucg->arg.pixel.pos.y = HEIGHT-1-tmp;
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_dir3_seq);
ucg->arg.pixel.pos.y = tmp;
break;
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = (ucg->arg.ccs_line[0].current&0x0f8) | (((ucg->arg.ccs_line[1].current) >>5));
c[1] = ((((ucg->arg.ccs_line[1].current))<<3)&0x0e0) | (((ucg->arg.ccs_line[2].current) >>3));
ucg_com_SendRepeat2Bytes(ucg, 1, c);
ucg_ccs_step(ucg->arg.ccs_line+0);
ucg_ccs_step(ucg->arg.ccs_line+1);
ucg_ccs_step(ucg->arg.ccs_line+2);
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static const ucg_pgm_uint8_t ucg_pcf8833_power_down_seq[] = {
UCG_CS(0), /* enable chip */
UCG_C10(0x28), /* display off */
UCG_C10(0x10), /* sleep in */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ic_pcf8833_16(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
//ucg->display_offset.x = 2;
//ucg->display_offset.y = 2;
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 150, 160);
case UCG_MSG_DEV_POWER_DOWN:
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_power_down_seq);
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = WIDTH;
((ucg_wh_t *)data)->h = HEIGHT;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_pcf8833_set_pos_seq);
c[0] = ucg_pcf8833_get_color_high_byte(ucg);
c[1] = ucg_pcf8833_get_color_low_byte(ucg);
ucg_com_SendRepeat2Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_pcf8833_16);
ucg_handle_pcf8833_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
//ucg_handle_l90tc(ucg, ucg_dev_ic_pcf8833_16);
ucg_handle_pcf8833_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_pcf8833_16);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_pcf8833_16(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_pcf8833_16);
ucg_handle_pcf8833_l90se(ucg);
break;
}
return 1;
}

View File

@ -1,321 +0,0 @@
/*
ucg_dev_ic_seps225.c
Specific code for the SEPS225 controller (OLED displays)
128x128x18 display buffer
Note: Only 65K color support, because 262K mode is not possible with 8 Bit SPI.
Universal uC Color Graphics Library
Copyright (c) 2015, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
static uint8_t ucg_seps225_get_color_high_byte(ucg_t *ucg)
{
return (ucg->arg.pixel.rgb.color[0]&0x0f8) | (((ucg->arg.pixel.rgb.color[1]) >>5));
}
static uint8_t ucg_seps225_get_color_low_byte(ucg_t *ucg)
{
return ((((ucg->arg.pixel.rgb.color[1]))<<3)&0x0e0) | (((ucg->arg.pixel.rgb.color[2]) >>3));
}
/*
Write Memory Mode 0x016
Bit 0: HV
HV= 0, data is continuously written horizontally
HV= 1, data is continuously written vertically
Bit 1: VC
VC= 0, vertical address counter is decreased
VC= 1, vertical address counter is increased
Bit 2: HC
HC= 0, horizontal address counter is decreased
HC= 1, horizontal address counter is increased
Bit 4..6: Dual Transfer, 65K Mode (Bit 4 = 0, Bit 5 = 1, Bit 6 = 1)
*/
static const ucg_pgm_uint8_t ucg_seps255_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x020), UCG_VARX(0,0x07f, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(0,0x07f, 0), /* set y position */
UCG_C11(0x016, 0x064), /* Memory Mode */
UCG_C10(0x022), /* prepare for data */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_seps255_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11(0x016, 0x063), /* Memory Mode */
UCG_C10(0x020), UCG_VARX(0,0x07f, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(0,0x07f, 0), /* set y position */
UCG_C10(0x022), /* prepare for data */
UCG_DATA(), /* change to data mode */
UCG_END()
};
#ifdef NOT_USED
static const ucg_pgm_uint8_t ucg_seps255_pos_dir2_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11(0x016, 0x060), /* Memory Mode */
UCG_C10(0x020), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* prepare for data */
UCG_DATA(), /* change to data mode */
UCG_END()
};
/* it seems that this mode does not work*/
static const ucg_pgm_uint8_t ucg_seps255_pos_dir3_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11(0x016, 0x061), /* Memory Mode */
UCG_C10(0x020), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* prepare for data */
UCG_DATA(), /* change to data mode */
UCG_END()
};
#endif
ucg_int_t ucg_handle_seps225_l90fx(ucg_t *ucg)
{
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir1_seq);
break;
case 2:
ucg->arg.pixel.pos.x -= ucg->arg.len;
ucg->arg.pixel.pos.x++;
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir0_seq);
break;
case 3:
default:
ucg->arg.pixel.pos.y -= ucg->arg.len;
ucg->arg.pixel.pos.y++;
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir1_seq);
break;
}
{
uint8_t c[2];
c[0] = ucg_seps225_get_color_high_byte(ucg);
c[1] = ucg_seps225_get_color_low_byte(ucg);
ucg_com_SendRepeat2Bytes(ucg, ucg->arg.len, c);
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Bitmap Output)
Not implemented for this controller, fallback to standard. However this msg is not used
at all at the moment (Jul 2015)
*/
/*
L2SE Color Change
*/
ucg_int_t ucg_handle_seps225_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
switch(ucg->arg.dir)
{
case 0:
case 1:
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
break;
default:
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[1].color[i], ucg->arg.rgb[0].color[i], ucg->arg.len);
}
break;
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t dx, dy;
ucg_int_t i, j;
//uint8_t r, g, b;
switch(ucg->arg.dir)
{
case 0: dx = 1; dy = 0;
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir0_seq);
break;
case 1: dx = 0; dy = 1;
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir1_seq);
break;
case 2: dx = 1; dy = 0;
ucg->arg.pixel.pos.x -= ucg->arg.len;
ucg->arg.pixel.pos.x++;
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir0_seq);
break;
case 3: dx = 0; dy = 1;
ucg->arg.pixel.pos.y -= ucg->arg.len;
ucg->arg.pixel.pos.y++;
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir1_seq);
break;
default: dx = 1; dy = 0; break; /* avoid compiler warning */
}
for( i = 0; i < ucg->arg.len; i++ )
{
/*
r = ucg->arg.ccs_line[0].current;
r &= 0x0f8;
g = ucg->arg.ccs_line[1].current;
c[0] = g;
c[0] >>= 5;
c[0] |= r;
g <<= 3;
g &= 0x0e0;
b = ucg->arg.ccs_line[2].current;
b >>= 3;
c[1] = g;
c[1] |= b;
*/
c[0] = (ucg->arg.ccs_line[0].current&0x0f8) | (((ucg->arg.ccs_line[1].current) >>5));
c[1] = ((((ucg->arg.ccs_line[1].current))<<3)&0x0e0) | (((ucg->arg.ccs_line[2].current) >>3));
ucg_com_SendRepeat2Bytes(ucg, 1, c);
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
for ( j = 0; j < 3; j++ )
{
ucg_ccs_step(ucg->arg.ccs_line+j);
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static const ucg_pgm_uint8_t ucg_seps225_power_down_seq[] = {
UCG_CS(0), /* enable chip */
UCG_C11(0x006, 0x000), /* SEPS225: display off */
UCG_C11(0x004, 0x001), /* reduce current, power down */
UCG_CS(1), /* disable chip */
/* delay of 100ms is suggested here for full power down */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ic_seps225_16(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 50, 200); /* adjusted for SEPS225 */
case UCG_MSG_DEV_POWER_DOWN:
ucg_com_SendCmdSeq(ucg, ucg_seps225_power_down_seq);
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 128;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir0_seq);
c[0] = ucg_seps225_get_color_high_byte(ucg);
c[1] = ucg_seps225_get_color_low_byte(ucg);
ucg_com_SendRepeat2Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_seps225_16);
ucg_handle_seps225_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
ucg_handle_l90tc(ucg, ucg_dev_ic_seps225_18);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_seps225_18);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_seps225_16(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_seps225_16);
ucg_handle_seps225_l90se(ucg);
break;
}
return 1;
}

View File

@ -1,480 +0,0 @@
/*
ucg_dev_ic_ssd1289.c
Specific code for the ssd1289 controller (TFT displays)
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
#ifdef NOT_YET_IMPLEMENTED
static const ucg_pgm_uint8_t ucg_ssd1289_set_pos_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x04e), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x04f), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ssd1289_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C22(0x000, 0x011, 0x048, 0x030), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x04e), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x04f), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
static const ucg_pgm_uint8_t ucg_ssd1289_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C22(0x000, 0x011, 0x048, 0x038), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x04e), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x04f), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ssd1289_set_pos_dir2_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C22(0x000, 0x011, 0x048, 0x000), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ssd1289_set_pos_dir3_seq[] =
{
UCG_CS(0), /* enable chip */
/* last byte: 0x030 horizontal increment (dir = 0) */
/* last byte: 0x038 vertical increment (dir = 1) */
/* last byte: 0x000 horizontal deccrement (dir = 2) */
/* last byte: 0x008 vertical deccrement (dir = 3) */
UCG_C22(0x000, 0x011, 0x048, 0x008), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
ucg_int_t ucg_handle_ssd1289_l90fx(ucg_t *ucg)
{
uint8_t c[3];
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_dir1_seq);
break;
case 2:
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_dir2_seq);
break;
case 3:
default:
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_dir3_seq);
break;
}
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Glyph Output)
Because of this for vertical lines the x min and max values in
"ucg_ssd1289_set_pos_for_y_seq" are identical to avoid changes of the x position
*/
const ucg_pgm_uint8_t ucg_ssd1289_set_x_pos_seq[] =
{
UCG_C10(0x020), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ssd1289_set_y_pos_seq[] =
{
UCG_C10(0x021), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x022), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
/* without CmdDataSequence */
ucg_int_t xxxxxx_ucg_handle_ssd1289_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[3];
ucg_int_t dx, dy;
ucg_int_t i;
const uint8_t *seq;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_seq);
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
seq = ucg_ssd1289_set_x_pos_seq;
break;
case 1:
dx = 0; dy = 1;
seq = ucg_ssd1289_set_y_pos_seq;
break;
case 2:
dx = -1; dy = 0;
seq = ucg_ssd1289_set_x_pos_seq;
break;
case 3:
default:
dx = 0; dy = -1;
seq = ucg_ssd1289_set_y_pos_seq;
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[0] = ucg->arg.pixel.rgb.color[0];
buf[1] = ucg->arg.pixel.rgb.color[1];
buf[2] = ucg->arg.pixel.rgb.color[2];
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
ucg_com_SendCmdSeq(ucg, seq);
ucg_com_SendRepeat3Bytes(ucg, 1, buf);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/* with CmdDataSequence */
ucg_int_t ucg_handle_ssd1289_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[16];
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_seq);
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x020; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // upper part x
buf[4] = 0x000; // no change
buf[5] = 0x000; // will be overwritten by x value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x022; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
break;
case 1:
dx = 0; dy = 1;
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x020; // set y
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // upper part y
buf[4] = 0x000; // no change
buf[5] = 0x000; // will be overwritten by y value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x022; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
break;
case 2:
dx = -1; dy = 0;
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x020; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // upper part x
buf[4] = 0x000; // no change
buf[5] = 0x000; // will be overwritten by x value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x022; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
break;
case 3:
default:
dx = 0; dy = -1;
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x020; // set y
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // upper part y
buf[4] = 0x000; // no change
buf[5] = 0x000; // will be overwritten by y value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x022; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[9] = ucg->arg.pixel.rgb.color[0];
buf[11] = ucg->arg.pixel.rgb.color[1];
buf[13] = ucg->arg.pixel.rgb.color[2];
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
if ( (ucg->arg.dir&1) == 0 )
{
buf[5] = ucg->arg.pixel.pos.x;
}
else
{
buf[3] = ucg->arg.pixel.pos.y>>8;
buf[5] = ucg->arg.pixel.pos.y&255;
}
ucg_com_SendCmdDataSequence(ucg, 7, buf);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_handle_ssd1289_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t i;
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_dir1_seq);
break;
case 2:
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_dir2_seq);
break;
case 3:
default:
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_dir3_seq);
break;
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = ucg->arg.ccs_line[0].current;
c[1] = ucg->arg.ccs_line[1].current;
c[2] = ucg->arg.ccs_line[2].current;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_ccs_step(ucg->arg.ccs_line+0);
ucg_ccs_step(ucg->arg.ccs_line+1);
ucg_ccs_step(ucg->arg.ccs_line+2);
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_dev_ic_ssd1289_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 40, 100);
case UCG_MSG_DEV_POWER_DOWN:
/* not yet implemented */
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 240;
((ucg_wh_t *)data)->h = 320;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_ssd1289_set_pos_seq);
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
ucg_handle_l90fx(ucg, ucg_dev_ic_ssd1289_18);
//ucg_handle_ssd1289_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
ucg_handle_l90tc(ucg, ucg_dev_ic_ssd1289);
//ucg_handle_ssd1289_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_ssd1289);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_ssd1289_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
ucg_handle_l90se(ucg, ucg_dev_ic_ssd1289);
//ucg_handle_ssd1289_l90se(ucg);
break;
}
return 1;
}
#endif

View File

@ -1,372 +0,0 @@
/*
ucg_dev_ic_ssd1331.c
Specific code for the SSD1331 controller (OLED displays)
96x64x16 display buffer, however 3-byte 18 bit mode is used
Universal uC Color Graphics Library
Copyright (c) 2015, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
//ucg_int_t u8g_dev_ic_ssd1331(ucg_t *ucg, ucg_int_t msg, void *data);
const ucg_pgm_uint8_t ucg_ssd1331_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x015), UCG_VARX(0,0x0ff, 0), UCG_A1(0x07f), /* set x position */
UCG_C10(0x075), UCG_VARY(0,0x0ff, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ssd1331_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x015), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x075), UCG_VARY(0,0x0ff, 0), UCG_A1(0x07f), /* set y position */
UCG_DATA(), /* change to data mode */
UCG_END()
};
ucg_int_t ucg_handle_ssd1331_l90fx(ucg_t *ucg)
{
uint8_t c[3];
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_dir1_seq);
break;
case 2:
ucg->arg.pixel.pos.x -= ucg->arg.len;
ucg->arg.pixel.pos.x++;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_dir0_seq);
break;
case 3:
default:
ucg->arg.pixel.pos.y -= ucg->arg.len;
ucg->arg.pixel.pos.y++;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_dir1_seq);
break;
}
c[0] = ucg->arg.pixel.rgb.color[0]>>2;
c[1] = ucg->arg.pixel.rgb.color[1]>>2;
c[2] = ucg->arg.pixel.rgb.color[2]>>2;
ucg_com_SendRepeat3Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Bitmap Output)
Because of this for vertical lines the x min and max values in
"ucg_ssd1331_set_pos_for_y_seq" are identical to avoid changes of the x position
*/
const ucg_pgm_uint8_t ucg_ssd1331_set_pos_for_x_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x015), UCG_VARX(0,0x0ff, 0), UCG_A1(0x07f), /* set x position */
UCG_C10(0x075), UCG_VARY(0,0x0ff, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ssd1331_set_pos_for_y_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x015), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x075), UCG_VARY(0,0x0ff, 0), UCG_A1(0x07f), /* set y position */
UCG_END()
};
ucg_int_t ucg_handle_ssd1331_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[16];
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x015; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // will be overwritten by x/y value
buf[4] = 0x000; // no change
buf[5] = 0x07f; // max value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x05c; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
buf[14] = 0x001; // change to 0 (cmd mode)
buf[15] = 0x05c; // change to 0 (cmd mode)
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
buf[1] = 0x015;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_for_x_seq);
break;
case 1:
dx = 0; dy = 1;
buf[1] = 0x075;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_for_y_seq);
break;
case 2:
dx = -1; dy = 0;
buf[1] = 0x015;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_for_x_seq);
break;
case 3:
default:
dx = 0; dy = -1;
buf[1] = 0x075;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_for_y_seq);
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[9] = ucg->arg.pixel.rgb.color[0]>>2;
buf[11] = ucg->arg.pixel.rgb.color[1]>>2;
buf[13] = ucg->arg.pixel.rgb.color[2]>>2;
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
if ( (ucg->arg.dir&1) == 0 )
{
buf[3] = ucg->arg.pixel.pos.x;
}
else
{
buf[3] = ucg->arg.pixel.pos.y;
}
//ucg_com_SendCmdSeq(ucg, seq);
//buf[0] = ucg->arg.pixel.rgb.color[0]>>2;
//buf[1] = ucg->arg.pixel.rgb.color[1]>>2;
//buf[2] = ucg->arg.pixel.rgb.color[2]>>2;
//ucg_com_SendRepeat3Bytes(ucg, 1, buf);
ucg_com_SendCmdDataSequence(ucg, 7, buf, 1);
//ucg_com_SetCDLineStatus(ucg, 1);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_handle_ssd1331_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
switch(ucg->arg.dir)
{
case 0:
case 1:
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
break;
default:
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[1].color[i], ucg->arg.rgb[0].color[i], ucg->arg.len);
}
break;
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t dx, dy;
ucg_int_t i, j;
switch(ucg->arg.dir)
{
case 0: dx = 1; dy = 0;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_dir0_seq);
break;
case 1: dx = 0; dy = 1;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_dir1_seq);
break;
case 2: dx = 1; dy = 0;
ucg->arg.pixel.pos.x -= ucg->arg.len;
ucg->arg.pixel.pos.x++;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_dir0_seq);
break;
case 3: dx = 0; dy = 1;
ucg->arg.pixel.pos.y -= ucg->arg.len;
ucg->arg.pixel.pos.y++;
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_dir1_seq);
break;
default: dx = 1; dy = 0; break; /* avoid compiler warning */
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = ucg->arg.ccs_line[0].current >> 2;
c[1] = ucg->arg.ccs_line[1].current >> 2;
c[2] = ucg->arg.ccs_line[2].current >> 2;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
for ( j = 0; j < 3; j++ )
{
ucg_ccs_step(ucg->arg.ccs_line+j);
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static const ucg_pgm_uint8_t ucg_ssd1331_power_down_seq[] = {
UCG_CS(0), /* enable chip */
UCG_C10(0x0a6), /* Set display: All pixel off */
UCG_C10(0x0ae), /* Set display off: sleep mode */
//UCG_C11(0x0b0, 0x01a), /* Power Save Mode */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ic_ssd1331_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 50, 300);
case UCG_MSG_DEV_POWER_DOWN:
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_power_down_seq);
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 96;
((ucg_wh_t *)data)->h = 64;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_ssd1331_set_pos_dir0_seq);
c[0] = ucg->arg.pixel.rgb.color[0]>>2;
c[1] = ucg->arg.pixel.rgb.color[1]>>2;
c[2] = ucg->arg.pixel.rgb.color[2]>>2;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_ssd1331_18);
ucg_handle_ssd1331_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
//ucg_handle_l90tc(ucg, ucg_dev_ic_ssd1331_18);
ucg_handle_ssd1331_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_ssd1331_18);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_ssd1331_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_ssd1331_18);
ucg_handle_ssd1331_l90se(ucg);
break;
}
return 1;
}

View File

@ -1,372 +0,0 @@
/*
ucg_dev_ic_ssd1351.c
Specific code for the SSD1351 controller (OLED displays)
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
//ucg_int_t u8g_dev_ic_ssd1351(ucg_t *ucg, ucg_int_t msg, void *data);
const ucg_pgm_uint8_t ucg_ssd1351_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x015), UCG_VARX(0,0x0ff, 0), UCG_D1(0x07f), /* set x position */
UCG_C10(0x075), UCG_VARY(0,0x0ff, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_C10(0x05c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ssd1351_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x015), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x075), UCG_VARY(0,0x0ff, 0), UCG_D1(0x07f), /* set y position */
UCG_C10(0x05c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
ucg_int_t ucg_handle_ssd1351_l90fx(ucg_t *ucg)
{
uint8_t c[3];
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_dir1_seq);
break;
case 2:
ucg->arg.pixel.pos.x -= ucg->arg.len;
ucg->arg.pixel.pos.x++;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_dir0_seq);
break;
case 3:
default:
ucg->arg.pixel.pos.y -= ucg->arg.len;
ucg->arg.pixel.pos.y++;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_dir1_seq);
break;
}
c[0] = ucg->arg.pixel.rgb.color[0]>>2;
c[1] = ucg->arg.pixel.rgb.color[1]>>2;
c[2] = ucg->arg.pixel.rgb.color[2]>>2;
ucg_com_SendRepeat3Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Glyph Output)
Because of this for vertical lines the x min and max values in
"ucg_ssd1351_set_pos_for_y_seq" are identical to avoid changes of the x position
*/
const ucg_pgm_uint8_t ucg_ssd1351_set_pos_for_x_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x015), UCG_VARX(0,0x0ff, 0), UCG_D1(0x07f), /* set x position */
UCG_C10(0x075), UCG_VARY(0,0x0ff, 0), UCG_VARY(0,0x0ff, 0), /* set y position */
UCG_END()
};
const ucg_pgm_uint8_t ucg_ssd1351_set_pos_for_y_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C10(0x015), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x075), UCG_VARY(0,0x0ff, 0), UCG_D1(0x07f), /* set y position */
UCG_END()
};
ucg_int_t ucg_handle_ssd1351_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[16];
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x015; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // will be overwritten by x/y value
buf[4] = 0x000; // no change
buf[5] = 0x07f; // max value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x05c; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
buf[14] = 0x001; // change to 0 (cmd mode)
buf[15] = 0x05c; // change to 0 (cmd mode)
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
buf[1] = 0x015;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_for_x_seq);
break;
case 1:
dx = 0; dy = 1;
buf[1] = 0x075;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_for_y_seq);
break;
case 2:
dx = -1; dy = 0;
buf[1] = 0x015;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_for_x_seq);
break;
case 3:
default:
dx = 0; dy = -1;
buf[1] = 0x075;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_for_y_seq);
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[9] = ucg->arg.pixel.rgb.color[0]>>2;
buf[11] = ucg->arg.pixel.rgb.color[1]>>2;
buf[13] = ucg->arg.pixel.rgb.color[2]>>2;
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
if ( (ucg->arg.dir&1) == 0 )
{
buf[3] = ucg->arg.pixel.pos.x;
}
else
{
buf[3] = ucg->arg.pixel.pos.y;
}
//ucg_com_SendCmdSeq(ucg, seq);
//buf[0] = ucg->arg.pixel.rgb.color[0]>>2;
//buf[1] = ucg->arg.pixel.rgb.color[1]>>2;
//buf[2] = ucg->arg.pixel.rgb.color[2]>>2;
//ucg_com_SendRepeat3Bytes(ucg, 1, buf);
ucg_com_SendCmdDataSequence(ucg, 7, buf, 1);
//ucg_com_SetCDLineStatus(ucg, 1);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_handle_ssd1351_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
switch(ucg->arg.dir)
{
case 0:
case 1:
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
break;
default:
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[1].color[i], ucg->arg.rgb[0].color[i], ucg->arg.len);
}
break;
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t dx, dy;
ucg_int_t i, j;
switch(ucg->arg.dir)
{
case 0: dx = 1; dy = 0;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_dir0_seq);
break;
case 1: dx = 0; dy = 1;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_dir1_seq);
break;
case 2: dx = 1; dy = 0;
ucg->arg.pixel.pos.x -= ucg->arg.len;
ucg->arg.pixel.pos.x++;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_dir0_seq);
break;
case 3: dx = 0; dy = 1;
ucg->arg.pixel.pos.y -= ucg->arg.len;
ucg->arg.pixel.pos.y++;
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_dir1_seq);
break;
default: dx = 1; dy = 0; break; /* avoid compiler warning */
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = ucg->arg.ccs_line[0].current >> 2;
c[1] = ucg->arg.ccs_line[1].current >> 2;
c[2] = ucg->arg.ccs_line[2].current >> 2;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
for ( j = 0; j < 3; j++ )
{
ucg_ccs_step(ucg->arg.ccs_line+j);
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static const ucg_pgm_uint8_t ucg_ssd1351_power_down_seq[] = {
UCG_CS(0), /* enable chip */
UCG_C11(0x0c7, 0x000), /* Set Master Contrast (0..15), reset default: 0x05 */
UCG_C10(0x0ae), /* Set Display Off */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ic_ssd1351_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 50, 300);
case UCG_MSG_DEV_POWER_DOWN:
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_power_down_seq);
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 128;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_ssd1351_set_pos_dir0_seq);
c[0] = ucg->arg.pixel.rgb.color[0]>>2;
c[1] = ucg->arg.pixel.rgb.color[1]>>2;
c[2] = ucg->arg.pixel.rgb.color[2]>>2;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_ssd1351_18);
ucg_handle_ssd1351_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
//ucg_handle_l90tc(ucg, ucg_dev_ic_ssd1351_18);
ucg_handle_ssd1351_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_ssd1351_18);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_ssd1351_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_ssd1351_18);
ucg_handle_ssd1351_l90se(ucg);
break;
}
return 1;
}

View File

@ -1,383 +0,0 @@
/*
ucg_dev_ic_st7735.c
Specific code for the st7735 controller (TFT displays)
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
const ucg_pgm_uint8_t ucg_st7735_set_pos_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11( 0x036, 0x000),
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_A2(0x000, 0x07f), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x00, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x000, 0x09f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_st7735_set_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x000 horizontal increment (dir = 0) */
/* 0x000 vertical increment (dir = 1) */
/* 0x040 horizontal deccrement (dir = 2) */
/* 0x080 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x000),
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_A2(0x000, 0x07f), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x00, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x000, 0x09f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_st7735_set_pos_dir1_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x000 horizontal increment (dir = 0) */
/* 0x000 vertical increment (dir = 1) */
/* 0x040 horizontal deccrement (dir = 2) */
/* 0x080 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x000),
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x00, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x000, 0x09f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_st7735_set_pos_dir2_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x000 horizontal increment (dir = 0) */
/* 0x000 vertical increment (dir = 1) */
/* 0x040 horizontal deccrement (dir = 2) */
/* 0x080 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x040),
UCG_C11( 0x036, 0x040), /* it seems that this command needs to be sent twice */
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_A2(0x000, 0x07f), /* set x position */
UCG_C10(0x02b), UCG_VARY(8,0x01, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x000, 0x09f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
const ucg_pgm_uint8_t ucg_st7735_set_pos_dir3_seq[] =
{
UCG_CS(0), /* enable chip */
/* 0x000 horizontal increment (dir = 0) */
/* 0x000 vertical increment (dir = 1) */
/* 0x0c0 horizontal deccrement (dir = 2) */
/* 0x0c0 vertical deccrement (dir = 3) */
UCG_C11( 0x036, 0x080),
UCG_C11( 0x036, 0x080), /* it seems that this command needs to be sent twice */
UCG_C10(0x02a), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), UCG_VARX(0,0x00, 0), UCG_VARX(0,0x0ff, 0), /* set x position */
UCG_C10(0x02b), UCG_VARY(0,0x00, 0), UCG_VARY(0,0x0ff, 0), UCG_A2(0x000, 0x09f), /* set y position */
UCG_C10(0x02c), /* write to RAM */
UCG_DATA(), /* change to data mode */
UCG_END()
};
ucg_int_t ucg_handle_st7735_l90fx(ucg_t *ucg)
{
uint8_t c[3];
ucg_int_t tmp;
if ( ucg_clip_l90fx(ucg) != 0 )
{
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_dir1_seq);
break;
case 2:
tmp = ucg->arg.pixel.pos.x;
ucg->arg.pixel.pos.x = 127-tmp;
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_dir2_seq);
ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
tmp = ucg->arg.pixel.pos.y;
ucg->arg.pixel.pos.y = 159-tmp;
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_dir3_seq);
ucg->arg.pixel.pos.y = tmp;
break;
}
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, ucg->arg.len, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
/*
L2TC (Glyph Output)
*/
/* with CmdDataSequence */
ucg_int_t ucg_handle_st7735_l90tc(ucg_t *ucg)
{
if ( ucg_clip_l90tc(ucg) != 0 )
{
uint8_t buf[16];
ucg_int_t dx, dy;
ucg_int_t i;
unsigned char pixmap;
uint8_t bitcnt;
ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_seq);
buf[0] = 0x001; // change to 0 (cmd mode)
buf[1] = 0x02a; // set x
buf[2] = 0x002; // change to 1 (arg mode)
buf[3] = 0x000; // upper part x
buf[4] = 0x000; // no change
buf[5] = 0x000; // will be overwritten by x value
buf[6] = 0x001; // change to 0 (cmd mode)
buf[7] = 0x02c; // write data
buf[8] = 0x002; // change to 1 (data mode)
buf[9] = 0x000; // red value
buf[10] = 0x000; // no change
buf[11] = 0x000; // green value
buf[12] = 0x000; // no change
buf[13] = 0x000; // blue value
switch(ucg->arg.dir)
{
case 0:
dx = 1; dy = 0;
buf[1] = 0x02a; // set x
break;
case 1:
dx = 0; dy = 1;
buf[1] = 0x02b; // set y
break;
case 2:
dx = -1; dy = 0;
buf[1] = 0x02a; // set x
break;
case 3:
default:
dx = 0; dy = -1;
buf[1] = 0x02b; // set y
break;
}
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = ucg->arg.pixel_skip;
pixmap <<= bitcnt;
buf[9] = ucg->arg.pixel.rgb.color[0];
buf[11] = ucg->arg.pixel.rgb.color[1];
buf[13] = ucg->arg.pixel.rgb.color[2];
//ucg_com_SetCSLineStatus(ucg, 0); /* enable chip */
for( i = 0; i < ucg->arg.len; i++ )
{
if ( (pixmap & 128) != 0 )
{
if ( (ucg->arg.dir&1) == 0 )
{
buf[5] = ucg->arg.pixel.pos.x;
}
else
{
buf[3] = ucg->arg.pixel.pos.y>>8;
buf[5] = ucg->arg.pixel.pos.y&255;
}
ucg_com_SendCmdDataSequence(ucg, 7, buf, 0);
}
pixmap<<=1;
ucg->arg.pixel.pos.x+=dx;
ucg->arg.pixel.pos.y+=dy;
bitcnt++;
if ( bitcnt >= 8 )
{
ucg->arg.bitmap++;
pixmap = ucg_pgm_read(ucg->arg.bitmap);
bitcnt = 0;
}
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
ucg_int_t ucg_handle_st7735_l90se(ucg_t *ucg)
{
uint8_t i;
uint8_t c[3];
ucg_int_t tmp;
/* Setup ccs for l90se. This will be updated by ucg_clip_l90se if required */
for ( i = 0; i < 3; i++ )
{
ucg_ccs_init(ucg->arg.ccs_line+i, ucg->arg.rgb[0].color[i], ucg->arg.rgb[1].color[i], ucg->arg.len);
}
/* check if the line is visible */
if ( ucg_clip_l90se(ucg) != 0 )
{
ucg_int_t i;
switch(ucg->arg.dir)
{
case 0:
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_dir0_seq);
break;
case 1:
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_dir1_seq);
break;
case 2:
tmp = ucg->arg.pixel.pos.x;
ucg->arg.pixel.pos.x = 127-tmp;
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_dir2_seq);
ucg->arg.pixel.pos.x = tmp;
break;
case 3:
default:
tmp = ucg->arg.pixel.pos.y;
ucg->arg.pixel.pos.y = 159-tmp;
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_dir3_seq);
ucg->arg.pixel.pos.y = tmp;
break;
}
for( i = 0; i < ucg->arg.len; i++ )
{
c[0] = ucg->arg.ccs_line[0].current;
c[1] = ucg->arg.ccs_line[1].current;
c[2] = ucg->arg.ccs_line[2].current;
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_ccs_step(ucg->arg.ccs_line+0);
ucg_ccs_step(ucg->arg.ccs_line+1);
ucg_ccs_step(ucg->arg.ccs_line+2);
}
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
return 1;
}
return 0;
}
static const ucg_pgm_uint8_t ucg_st7735_power_down_seq[] = {
UCG_CS(0), /* enable chip */
UCG_C10(0x010), /* sleep in */
UCG_C10(0x28), /* display off */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ic_st7735_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* setup com interface and provide information on the clock speed */
/* of the serial and parallel interface. Values are nanoseconds. */
return ucg_com_PowerUp(ucg, 100, 66);
case UCG_MSG_DEV_POWER_DOWN:
ucg_com_SendCmdSeq(ucg, ucg_st7735_power_down_seq);
return 1;
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 160;
return 1;
case UCG_MSG_DRAW_PIXEL:
if ( ucg_clip_is_pixel_visible(ucg) !=0 )
{
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_st7735_set_pos_seq);
c[0] = ucg->arg.pixel.rgb.color[0];
c[1] = ucg->arg.pixel.rgb.color[1];
c[2] = ucg->arg.pixel.rgb.color[2];
ucg_com_SendRepeat3Bytes(ucg, 1, c);
ucg_com_SetCSLineStatus(ucg, 1); /* disable chip */
}
return 1;
case UCG_MSG_DRAW_L90FX:
//ucg_handle_l90fx(ucg, ucg_dev_ic_st7735_18);
ucg_handle_st7735_l90fx(ucg);
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
//ucg_handle_l90tc(ucg, ucg_dev_ic_st7735_18);
ucg_handle_st7735_l90tc(ucg);
return 1;
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
ucg_handle_l90bf(ucg, ucg_dev_ic_st7735_18);
return 1;
#endif /* UCG_MSG_DRAW_L90BF */
/* msg UCG_MSG_DRAW_L90SE is handled by ucg_dev_default_cb */
/*
case UCG_MSG_DRAW_L90SE:
return ucg->ext_cb(ucg, msg, data);
*/
}
return ucg_dev_default_cb(ucg, msg, data);
}
ucg_int_t ucg_ext_st7735_18(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DRAW_L90SE:
//ucg_handle_l90se(ucg, ucg_dev_ic_st7735_18);
ucg_handle_st7735_l90se(ucg);
break;
}
return 1;
}

View File

@ -1,131 +0,0 @@
/*
ucg_dev_msg_api.c
Universal uC Color Graphics Library
Copyright (c) 2013, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
#include <stddef.h>
void ucg_PowerDown(ucg_t *ucg)
{
if ( ucg->is_power_up != 0 )
{
ucg->device_cb(ucg, UCG_MSG_DEV_POWER_DOWN, NULL);
ucg->is_power_up = 0;
}
}
ucg_int_t ucg_PowerUp(ucg_t *ucg)
{
ucg_int_t r;
/* power down first. will do nothing if power is already down */
ucg_PowerDown(ucg);
/* now try to power up the display */
r = ucg->device_cb(ucg, UCG_MSG_DEV_POWER_UP, NULL);
if ( r != 0 )
{
ucg->is_power_up = 1;
}
return r;
}
void ucg_SetClipBox(ucg_t *ucg, ucg_box_t *clip_box)
{
ucg->device_cb(ucg, UCG_MSG_SET_CLIP_BOX, (void *)(clip_box));
}
void ucg_SetClipRange(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t w, ucg_int_t h)
{
ucg_box_t clip_box;
clip_box.ul.x = x;
clip_box.ul.y = y;
clip_box.size.w = w;
clip_box.size.h = h;
ucg_SetClipBox(ucg, &clip_box);
}
void ucg_SetMaxClipRange(ucg_t *ucg)
{
ucg_box_t new_clip_box;
new_clip_box.size = ucg->dimension;
new_clip_box.ul.x = 0;
new_clip_box.ul.y = 0;
ucg_SetClipBox(ucg, &new_clip_box);
}
/*
Query the display dimension from the driver, reset clip window to maximum
new dimension
*/
void ucg_GetDimension(ucg_t *ucg)
{
ucg->device_cb(ucg, UCG_MSG_GET_DIMENSION, &(ucg->dimension));
ucg_SetMaxClipRange(ucg);
}
void ucg_DrawPixelWithArg(ucg_t *ucg)
{
ucg->device_cb(ucg, UCG_MSG_DRAW_PIXEL, NULL);
}
void ucg_DrawL90FXWithArg(ucg_t *ucg)
{
ucg->device_cb(ucg, UCG_MSG_DRAW_L90FX, &(ucg->arg));
}
#ifdef UCG_MSG_DRAW_L90TC
void ucg_DrawL90TCWithArg(ucg_t *ucg)
{
ucg->device_cb(ucg, UCG_MSG_DRAW_L90TC, &(ucg->arg));
}
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
void ucg_DrawL90BFWithArg(ucg_t *ucg)
{
ucg->device_cb(ucg, UCG_MSG_DRAW_L90BF, &(ucg->arg));
}
#endif /* UCG_MSG_DRAW_L90BF */
void ucg_DrawL90SEWithArg(ucg_t *ucg)
{
ucg->device_cb(ucg, UCG_MSG_DRAW_L90SE, &(ucg->arg));
}
/*
void ucg_DrawL90RLWithArg(ucg_t *ucg)
{
ucg->device_cb(ucg, UCG_MSG_DRAW_L90RL, &(ucg->arg));
}
*/

View File

@ -1,117 +0,0 @@
/*
ucg_dev_oled_128x128_ft.c
Specific code for the FREETRONIC 128x128 OLED module
(differs from the ILSOFT only by GPIO output)
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
//static const uint8_t ucg_dev_ssd1351_128x128_init_seq[] PROGMEM = {
static const ucg_pgm_uint8_t ucg_ft_ssd1351_init_seq[] = {
UCG_CFG_CD(0,1), /* DC=0 for command mode, DC=1 for data and args */
UCG_RST(1),
UCG_CS(1), /* disable chip */
UCG_DLY_MS(1),
UCG_RST(0),
UCG_DLY_MS(1),
UCG_RST(1),
UCG_DLY_MS(50),
UCG_CS(0), /* enable chip */
//UCG_C11(0x0fd, 0x012), /* Unlock normal commands, reset default: unlocked */
UCG_C11(0x0fd, 0x0b1), /* Unlock extra commands, reset default: locked */
//UCG_C10(0x0ae), /* Set Display Off */
UCG_C10(0x0af), /* Set Display On */
UCG_C10(0x0a6), /* Set Display Mode Reset */
UCG_C11(0x0a0, 0x0b4), /* Set Colour Depth */
UCG_C11(0x0a1, 0x000), /* Set Display Start Line */
UCG_C11(0x0a2, 0x000), /* Set Display Offset */
UCG_C12(0x015, 0x000, 0x07f), /* Set Column Address */
UCG_C12(0x075, 0x000, 0x07f), /* Set Row Address */
UCG_C11(0x0b3, 0x0f1), /* Front Clock Div */
//UCG_C11(0x0ca, 0x07f), /* Set Multiplex Ratio, reset default: 0x7f */
UCG_C11(0x0b5, 0x003), /* Set GPIO for Freetronics OLED Module */
//UCG_C11(0x0ab, 0x001), /* Set Function Selection, reset default: 0x01 */
UCG_C11(0x0b1, 0x032), /* Set Phase Length, reset default: 0x82 */
UCG_C13(0x0b4, 0xa0,0xb5,0x55), /* Set Segment Low Voltage, reset default: 0xa2 0xb5 0x55 */
//UCG_C11(0x0bb, 0x017), /* Set Precharge Voltage, reset default: 0x17 */
//UCG_C11(0x0be, 0x005), /* Set VComH Voltage, reset default: 0x05 */
UCG_C13(0x0c1, 0xc8, 0x80, 0xc8), /* Set Contrast */
UCG_C11(0x0c7, 0x00f), /* Set Master Contrast (0..15), reset default: 0x05 */
UCG_C11(0x0b6, 0x001), /* Set Second Precharge Period */
// UCG_C10(0x0b8), /* Set CMD Grayscale Lookup, 63 Bytes follow */
// UCG_A8(0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c),
// UCG_A8(0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14),
// UCG_A8(0x15,0x16,0x18,0x1a,0x1b,0x1C,0x1D,0x1F),
// UCG_A8(0x21,0x23,0x25,0x27,0x2A,0x2D,0x30,0x33),
// UCG_A8(0x36,0x39,0x3C,0x3F,0x42,0x45,0x48,0x4C),
// UCG_A8(0x50,0x54,0x58,0x5C,0x60,0x64,0x68,0x6C),
// UCG_A8(0x70,0x74,0x78,0x7D,0x82,0x87,0x8C,0x91),
// UCG_A7(0x96,0x9B,0xA0,0xA5,0xAA,0xAF,0xB4),
UCG_C10(0x05c), /* Write RAM */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ssd1351_18x128x128_ft(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* 1. Call to the controller procedures to setup the com interface */
if ( ucg_dev_ic_ssd1351_18(ucg, msg, data) == 0 )
return 0;
/* 2. Send specific init sequence for this display module */
ucg_com_SendCmdSeq(ucg, ucg_ft_ssd1351_init_seq);
return 1;
case UCG_MSG_DEV_POWER_DOWN:
/* let do power down by the conroller procedures */
return ucg_dev_ic_ssd1351_18(ucg, msg, data);
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 128;
return 1;
}
/* all other messages are handled by the controller procedures */
return ucg_dev_ic_ssd1351_18(ucg, msg, data);
}

View File

@ -1,116 +0,0 @@
/*
ucg_dev_oled_128x128_ilsoft.c
Specific code for the ILSOFT 128x128 OLED module
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
//static const uint8_t ucg_dev_ssd1351_128x128_init_seq[] PROGMEM = {
static const ucg_pgm_uint8_t ucg_ilsoft_ssd1351_init_seq[] = {
UCG_CFG_CD(0,1), /* DC=0 for command mode, DC=1 for data and args */
UCG_RST(1),
UCG_CS(1), /* disable chip */
UCG_DLY_MS(1),
UCG_RST(0),
UCG_DLY_MS(1),
UCG_RST(1),
UCG_DLY_MS(50),
UCG_CS(0), /* enable chip */
//UCG_C11(0x0fd, 0x012), /* Unlock normal commands, reset default: unlocked */
UCG_C11(0x0fd, 0x0b1), /* Unlock extra commands, reset default: locked */
//UCG_C10(0x0ae), /* Set Display Off */
UCG_C10(0x0af), /* Set Display On */
UCG_C10(0x0a6), /* Set Display Mode Reset */
UCG_C11(0x0a0, 0x0b4), /* Set Colour Depth */
UCG_C11(0x0a1, 0x000), /* Set Display Start Line */
UCG_C11(0x0a2, 0x000), /* Set Display Offset */
UCG_C12(0x015, 0x000, 0x07f), /* Set Column Address */
UCG_C12(0x075, 0x000, 0x07f), /* Set Row Address */
UCG_C11(0x0b3, 0x0f1), /* Front Clock Div */
//UCG_C11(0x0ca, 0x07f), /* Set Multiplex Ratio, reset default: 0x7f */
UCG_C11(0x0b5, 0x000), /* Set GPIO */
//UCG_C11(0x0ab, 0x001), /* Set Function Selection, reset default: 0x01 */
UCG_C11(0x0b1, 0x032), /* Set Phase Length, reset default: 0x82 */
UCG_C13(0x0b4, 0xa0,0xb5,0x55), /* Set Segment Low Voltage, reset default: 0xa2 0xb5 0x55 */
//UCG_C11(0x0bb, 0x017), /* Set Precharge Voltage, reset default: 0x17 */
//UCG_C11(0x0be, 0x005), /* Set VComH Voltage, reset default: 0x05 */
UCG_C13(0x0c1, 0xc8, 0x80, 0xc8), /* Set Contrast */
UCG_C11(0x0c7, 0x00f), /* Set Master Contrast (0..15), reset default: 0x05 */
UCG_C11(0x0b6, 0x001), /* Set Second Precharge Period */
// UCG_C10(0x0b8), /* Set CMD Grayscale Lookup, 63 Bytes follow */
// UCG_A8(0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c),
// UCG_A8(0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14),
// UCG_A8(0x15,0x16,0x18,0x1a,0x1b,0x1C,0x1D,0x1F),
// UCG_A8(0x21,0x23,0x25,0x27,0x2A,0x2D,0x30,0x33),
// UCG_A8(0x36,0x39,0x3C,0x3F,0x42,0x45,0x48,0x4C),
// UCG_A8(0x50,0x54,0x58,0x5C,0x60,0x64,0x68,0x6C),
// UCG_A8(0x70,0x74,0x78,0x7D,0x82,0x87,0x8C,0x91),
// UCG_A7(0x96,0x9B,0xA0,0xA5,0xAA,0xAF,0xB4),
UCG_C10(0x05c), /* Write RAM */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ssd1351_18x128x128_ilsoft(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* 1. Call to the controller procedures to setup the com interface */
if ( ucg_dev_ic_ssd1351_18(ucg, msg, data) == 0 )
return 0;
/* 2. Send specific init sequence for this display module */
ucg_com_SendCmdSeq(ucg, ucg_ilsoft_ssd1351_init_seq);
return 1;
case UCG_MSG_DEV_POWER_DOWN:
/* let do power down by the conroller procedures */
return ucg_dev_ic_ssd1351_18(ucg, msg, data);
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 128;
return 1;
}
/* all other messages are handled by the controller procedures */
return ucg_dev_ic_ssd1351_18(ucg, msg, data);
}

View File

@ -1,268 +0,0 @@
/*
ucg_dev_oled_128x128_univision.c
Specific code for the Univision 1.5" OLED (UG2828, 128x128 pixel, 65K Colors, SEPS225)
Note: Only 65K color support, because 262K mode is not possible with 8 Bit SPI.
Universal uC Color Graphics Library
Copyright (c) 2015, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
/* the following code is from the UG2828GDEAF02 Datasheet */
static const ucg_pgm_uint8_t aaa_ucg_univision_seps225_init_seq[] = {
UCG_CFG_CD(0,1), /* First arg: level for commands, Second arg: level for command arguments */
UCG_RST(1),
UCG_CS(1), /* disable chip */
UCG_DLY_MS(1),
UCG_RST(0),
UCG_DLY_MS(1),
UCG_RST(1),
UCG_DLY_MS(50),
UCG_CS(0), /* enable chip */
UCG_C11(0x002, 0x001), /* OSC_CTL: external resistor, internal OSC */
UCG_C11(0x004, 0x000), /* REDUCE_CURRENT: normal operation, no current reduction */
UCG_C11(0x003, 0x030), /* CLK_DIV: 90Hz, ratio 1 */
UCG_C11(0x008, 0x000), /* Precharge time red */
UCG_C11(0x009, 0x000), /* Precharge time green */
UCG_C11(0x00a, 0x000), /* Precharge time blue */
UCG_C11(0x00b, 0x000), /* Precharge current red */
UCG_C11(0x00c, 0x000), /* Precharge current green */
UCG_C11(0x00d, 0x000), /* Precharge current blue */
UCG_C11(0x010, 0x04a), /* Driving current red */
UCG_C11(0x011, 0x025), /* Driving current green, original value 0x011 replaced by 0x025 */
UCG_C11(0x012, 0x02f), /* Driving current blue */
UCG_C11(0x013, 0x000), /* Display mode: RGB,column=0..127,column data display control=Normal Dispaly */
UCG_C11(0x014, 0x001), /* External interface: 18 bit, MPU, Bit size does not matter if MPU is selected*/
//UCG_C11(0x016, 0x076), /* Memory Mode: 6bits triple transfer (would require 6bit words on SPI, 262K support, horizontal inc., vertical inc., data continuously written horizontally */
UCG_C11(0x016, 0x066), /* Memory Mode: dual transfer (2x 8Bit), 65K support, horizontal inc., vertical inc., data continuously written horizontally */
/* memory window */
UCG_C11(0x017, 0x000), /* x0 */
UCG_C11(0x018, 0x07f), /* x1 */
UCG_C11(0x019, 0x000), /* y0 */
UCG_C11(0x01a, 0x07f), /* y1 */
/* memory start */
UCG_C11(0x020, 0x000), /* x */
UCG_C11(0x021, 0x000), /* y */
UCG_C11(0x028, 0x07f), /* Duty */
UCG_C11(0x029, 0x000), /* Display start line */
/* DDRAM start */
UCG_C11(0x02e, 0x000), /* x */
UCG_C11(0x02f, 0x000), /* y */
UCG_C11(0x033, 0x000), /* Display Screen Saver x0 */
UCG_C11(0x034, 0x07f), /* Display Screen Saver x1 */
UCG_C11(0x035, 0x000), /* Display Screen Saver y0 */
UCG_C11(0x036, 0x07f), /* Display Screen Saver y1 */
UCG_C11(0x080, 0x000), /* IREF: External */
UCG_DLY_MS(100), /* as suggested in the Univision manual */
UCG_C11(0x006, 0x001), /* Display on */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
/* init seq. from the .ino example from ZhangFeng, PRC. http://vfdclock.jimdo.com */
static const ucg_pgm_uint8_t ucg_univision_seps225_init_seq[] = {
UCG_CFG_CD(0,1), /* First arg: level for commands, Second arg: level for command arguments */
UCG_RST(1),
UCG_CS(1), /* disable chip */
UCG_DLY_MS(1),
UCG_RST(0),
UCG_DLY_MS(1),
UCG_RST(1),
UCG_DLY_MS(50),
UCG_CS(0), /* enable chip */
UCG_C11(0x006, 0x000), /* Display off */
UCG_C11(0x002, 0x001), /* OSC_CTL: external resistor, internal OSC */
UCG_C11(0x004, 0x000), /* REDUCE_CURRENT: normal operation, no current reduction */
UCG_C11(0x003, 0x030), /* CLK_DIV: 90Hz, ratio 1 */
UCG_C11(0x005, 0x000), /* Software Reset */
UCG_C11(0x008, 0x003), /* Precharge time red */
UCG_C11(0x009, 0x004), /* Precharge time green */
UCG_C11(0x00a, 0x005), /* Precharge time blue */
UCG_C11(0x00b, 0x00b), /* Precharge current red */
UCG_C11(0x00c, 0x00b), /* Precharge current green */
UCG_C11(0x00d, 0x00e), /* Precharge current blue */
UCG_C11(0x010, 0x03e), /* Driving current red */
UCG_C11(0x011, 0x032), /* Driving current green, original value 0x011 replaced by 0x025 */
UCG_C11(0x012, 0x03d), /* Driving current blue */
UCG_C11(0x013, 0x000), /* Display mode: RGB,column=0..127,column data display control=Normal Dispaly */
UCG_C11(0x014, 0x001), /* External interface: 18 bit, MPU, Bit size does not matter if MPU is selected*/
//UCG_C11(0x016, 0x076), /* Memory Mode: 6bits triple transfer (would require 6bit words on SPI, 262K support, horizontal inc., vertical inc., data continuously written horizontally */
UCG_C11(0x015, 0x000),
UCG_C11(0x016, 0x066), /* Memory Mode: dual transfer (2x 8Bit), 65K support, horizontal inc., vertical inc., data continuously written horizontally */
/* memory window */
UCG_C11(0x017, 0x000), /* x0 */
UCG_C11(0x018, 0x07f), /* x1 */
UCG_C11(0x019, 0x000), /* y0 */
UCG_C11(0x01a, 0x07f), /* y1 */
/* memory start */
UCG_C11(0x020, 0x000), /* x */
UCG_C11(0x021, 0x000), /* y */
UCG_C11(0x028, 0x07f), /* Duty */
UCG_C11(0x029, 0x000), /* Display start line */
/* DDRAM start */
UCG_C11(0x02e, 0x000), /* x */
UCG_C11(0x02f, 0x000), /* y */
UCG_C11(0x031, 0x000),
UCG_C11(0x032, 0x000),
UCG_C11(0x033, 0x000), /* Display Screen Saver x0 */
UCG_C11(0x034, 0x07f), /* Display Screen Saver x1 */
UCG_C11(0x035, 0x000), /* Display Screen Saver y0 */
UCG_C11(0x036, 0x07f), /* Display Screen Saver y1 */
UCG_C11(0x080, 0x000), /* IREF: External */
UCG_DLY_MS(100), /* as suggested in the Univision manual */
UCG_C11(0x006, 0x001), /* Display on */
//UCG_C10(0x022),
UCG_CS(1), /* disable chip */
//UCG_DATA(),
UCG_END(), /* end of sequence */
};
static const ucg_pgm_uint8_t ucg_seps255_pos_dir0_seq[] =
{
UCG_CS(0), /* enable chip */
UCG_C11(0x016, 0x066), /* Memory Mode */
UCG_C11(0x020, 0), /* set x position */
UCG_C11(0x021, 0), /* set y position */
UCG_C10(0x022), /* prepare for data */
UCG_DATA(), /* change to data mode */
UCG_END()
};
ucg_int_t ucg_dev_seps225_16x128x128_univision(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* 1. Call to the controller procedures to setup the com interface */
if ( ucg_dev_ic_seps225_16(ucg, msg, data) == 0 )
return 0;
/* 2. Send specific init sequence for this display module */
ucg_com_SendCmdSeq(ucg, ucg_univision_seps225_init_seq);
/* demonstration of the OLED error */
/*
{
uint8_t r,g,b, i;
uint8_t c[3];
ucg_com_SendCmdSeq(ucg, ucg_seps255_pos_dir0_seq);
r = 0;
g = 0;
b = 80;
c[0] = (r&0x0f8) | (((g) >>5));
c[1] = ((((g))<<3)&0x0e0) | (((b) >>3));
ucg_com_SendRepeat2Bytes(ucg, 128, c);
r = 0;
g = 0;
b = 0;
c[0] = (r&0x0f8) | (((g) >>5));
c[1] = ((((g))<<3)&0x0e0) | (((b) >>3));
for( i = 0; i < 126; i++ )
{
ucg_com_SendRepeat2Bytes(ucg, 128, c);
}
r = 0;
g = 0;
b = 255;
c[0] = (r&0x0f8) | (((g) >>5));
c[1] = ((((g))<<3)&0x0e0) | (((b) >>3));
ucg_com_SendRepeat2Bytes(ucg, 40, c);
for(;;)
;
}
*/
return 1;
case UCG_MSG_DEV_POWER_DOWN:
/* let do power down by the controller procedures */
return ucg_dev_ic_seps225_16(ucg, msg, data);
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 128;
return 1;
}
/* all other messages are handled by the controller procedures */
return ucg_dev_ic_seps225_16(ucg, msg, data);
}

View File

@ -1,198 +0,0 @@
/*
ucg_dev_oled_160x128_samsung.c
Specific code for the Samsung 160x128 OLED (LD50T6160 Controller)
Universal uC Color Graphics Library
Copyright (c) 2015, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
/*
Samsung 1.8" OLED
VCC_R (4) connected to 4.7uF
VCC_R1 (41) connected to 4.7uF
VCC connected to 18V
VCC3 connected to 18V
==> Internal regulator mit be enabled
==> DC-DC must be switched off
From the Samsung 1.8" OLED datasheet:
PREC_WIDTH = 06h, (pre charge width?)
PEAKDELAY = 01h,
Frame Freq.(*1)) = 02h(90Hz)
Red : PEAKWIDTH = 03h,
Green : PEAKWIDTH = 05h,
Blue : PEAKWIDTH = 03h
Red : DOT CURRENT = 9Ah,
Green : DOT CURRENT = 5Ch,
Blue : DOT CURRENT = B1h
*/
static const ucg_pgm_uint8_t ucg_samsung_160x128_init_seq[] = {
/* init sequence for the Samsung OLED with LD50T6160 controller */
UCG_CFG_CD(0,1), /* DC=0 for command mode, DC=1 for data and args */
UCG_RST(1),
UCG_CS(1), /* disable chip */
UCG_DLY_MS(1),
UCG_RST(0),
UCG_DLY_MS(1),
UCG_RST(1),
UCG_DLY_MS(150),
UCG_CS(0), /* enable chip */
UCG_C10(0x01), /* software reset */
UCG_C11(0x02, 0x00), /* display on/off: display off */
UCG_C11(0x03, 0x00), /* standby off, OSCA start */
UCG_C11(0x04, 0x02), /* set frame rate: 0..7, 60Hz to 150Hz, default is 2=90Hz */
UCG_C11(0x05, 0x00), /* write dir, bit 3: RGB/BGR */
UCG_C11(0x06, 0x00), /* row scan dir (0=default) */
UCG_C11(0x06, 0x00), /* row scan dir (0=default) */
UCG_C10(0x07), /* set screen size */
UCG_A2(0x00, 0x00), /* x min = 0 */
UCG_A2(0x07, 0x0f), /* x max = 127 */
UCG_A2(0x00, 0x00), /* y min = 0 */
UCG_A2(0x09, 0x0f), /* y max = 159 */
UCG_C11(0x08, 0x00), /* interface bus width: 6 bit */
UCG_C11(0x09, 0x07), /* no data (RGB) masking (default) */
UCG_C10(0x0a), /* write box (probably not req. during init */
UCG_A2(0x00, 0x00), /* x min = 0 */
UCG_A2(0x07, 0x0f), /* x max = 127 */
UCG_A2(0x00, 0x00), /* y min = 0 */
UCG_A2(0x09, 0x0f), /* y max = 159 */
UCG_C10(0x0e), /* set some minimal dot current first */
UCG_A2(0x00, 0x03), /* red */
UCG_A2(0x00, 0x03), /* green */
UCG_A2(0x00, 0x03), /* blue */
UCG_C11(0x1b, 0x03), /* Pre-Charge Mode Select:Enable Pre-Charge and Peakboot for the Samsung OLED */
UCG_C12(0x1c, 0x00, 0x06), /* Pre-Charge Width, Samsung OLED: 0x06, controller default is 0x08 */
UCG_C10(0x1d), /* Peak Pulse Width Set */
UCG_A2(0x00, 0x03), /* red */
UCG_A2(0x00, 0x05), /* green */
UCG_A2(0x00, 0x03), /* blue */
UCG_C11(0x1e, 0x01), /* Peak Pulse Delay Set, Samsung OLED: 0x01, controller default is 0x05 */
/*
Row Scan Operation Set (cmd 0x1f)
bits 0, 1: scan mode
mode 00: alternate scan mode (Oliver: not sure if this is true, prob. this is seq. mode)
mode 01: seq. scan mode (Oliver: could be mode 00)
mode 10: simultaneous scan mode (Oliver: No idea what this is)
Samsung OLED: probably mode 00
bit 3:
if set to 1, then all rows are connected to GND
Samsung OLED: must be 0 for normal operation
bit 4,5: row timing setting
00: none
01: pre charge
10: pre charge + peak delay
11: pre charge + peak delay + peak boot
Samsung OLED: No idea, maybe 11 must be set here
*/
UCG_C11(0x1f, 0x30), /* Samsung OLED: pre charge + peak delay + peak boot */
UCG_C11(0x2d, 0x00), /* Write data through system interface (bit 4 = 0) */
/*
ICON Display control
bit 0/1 = 01: ALL ICON ON
bit 0/1 = 10: normal display mode (depends on ICON data)
*/
UCG_C11(0x20, 0x01), /* ICON Display control */
UCG_C11(0x21, 0x00), /* ICON Stand-by Setting, bit 0 = 0: no standby, start OSCB */
UCG_C11(0x29, 0x00), /* DC-DC Control for ICON: bit 0&1 = 01: stop DC-DC, use VICON (Samsung OLED has external 18V) */
UCG_C11(0x2a, 0x04), /* ICON Frame Frequency Set: 89Hz */
UCG_C11(0x30, 0x13), /* Internal Regulator for Row Scan, value taken from Samsung OLED flow chart */
/*
Set full dot current
Red : DOT CURRENT = 9Ah,
Green : DOT CURRENT = 5Ch,
Blue : DOT CURRENT = B1h
*/
UCG_DLY_MS(10),
UCG_C10(0x0e), /* set dot current */
UCG_A2(0x09, 0x0a), /* red */
UCG_A2(0x05, 0x0c), /* green */
UCG_A2(0x0b, 0x01), /* blue */
UCG_DLY_MS(10),
UCG_C11(0x02, 0x01), /* Display on */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ld50t6160_18x160x128_samsung(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* 1. Call to the controller procedures to setup the com interface */
if ( ucg_dev_ic_ld50t6160_18(ucg, msg, data) == 0 )
return 0;
/* 2. Send specific init sequence for this display module */
ucg_com_SendCmdSeq(ucg, ucg_samsung_160x128_init_seq);
return 1;
case UCG_MSG_DEV_POWER_DOWN:
/* let do power down by the controller procedures */
return ucg_dev_ic_ld50t6160_18(ucg, msg, data);
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 160;
return 1;
}
/* all other messages are handled by the controller procedures */
return ucg_dev_ic_ld50t6160_18(ucg, msg, data);
}

View File

@ -1,135 +0,0 @@
/*
ucg_dev_oled_96x64_univision.c
Specific code for the Univision 0.95" OLED (UG-9664, 96x94 pixel, 65536 Colors, SSD1331)
Universal uC Color Graphics Library
Copyright (c) 2015, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
static const ucg_pgm_uint8_t ucg_univision_ssd1331_init_seq[] = {
UCG_CFG_CD(0,0), /* First arg: level for commands, Second arg: level for command arguments */
UCG_RST(1),
UCG_CS(1), /* disable chip */
UCG_DLY_MS(1),
UCG_RST(0),
UCG_DLY_MS(1),
UCG_RST(1),
UCG_DLY_MS(50),
UCG_CS(0), /* enable chip */
//UCG_C11(0x0fd, 0x012), /* Unlock normal commands, reset default: unlocked */
UCG_C10(0x0ae), /* Set Display Off */
//UCG_C10(0x0af), /* Set Display On */
UCG_C11(0x0a0, 0x0b2), /* 65k format 2, RGB Mode */
UCG_C11(0x0a1, 0x000), /* Set Display Start Line */
UCG_C11(0x0a2, 0x000), /* Set Display Offset */
UCG_C11(0x0a8, 0x03f), /* Multiplex, reset value = 0x03f */
UCG_C11(0x0ad, 0x08e), /* select supply (must be set before 0x0af) */
UCG_C11(0x0b0, 0x00b), /* Disable power save mode */
UCG_C11(0x0b1, 0x031), /* Set Phase Length, reset default: 0x74 */
UCG_C11(0x0b3, 0x0f0), /* Display Clock Divider/Osc, reset value=0x0d0 */
UCG_C12(0x015, 0x000, 0x05f), /* Set Column Address */
UCG_C12(0x075, 0x000, 0x03f), /* Set Row Address */
UCG_C11(0x081, 0x080), /* contrast red, Adafruit: 0x091, UC9664: 0x080 */
UCG_C11(0x082, 0x080), /* contrast green, Adafruit: 0x050, UC9664: 0x080 */
UCG_C11(0x083, 0x080), /* contrast blue, Adafruit: 0x07d, UC9664: 0x080 */
UCG_C11(0x087, 0x00f), /* master current/contrast 0x00..0x0f UG-9664: 0x0f, Adafruit: 0x06 */
UCG_C11(0x08a, 0x064), /* second precharge speed red */
UCG_C11(0x08b, 0x078), /* second precharge speed green */
UCG_C11(0x08c, 0x064), /* second precharge speed blue */
UCG_C11(0x0bb, 0x03c), /* set shared precharge level, default = 0x03e */
UCG_C11(0x0be, 0x03e), /* voltage select, default = 0x03e */
UCG_C10(0x0b9), /* Reset internal grayscale lookup */
// UCG_C10(0x0b8), /* Set CMD Grayscale Lookup, 63 Bytes follow */
// UCG_A8(0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c),
// UCG_A8(0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14),
// UCG_A8(0x15,0x16,0x18,0x1a,0x1b,0x1C,0x1D,0x1F),
// UCG_A8(0x21,0x23,0x25,0x27,0x2A,0x2D,0x30,0x33),
// UCG_A8(0x36,0x39,0x3C,0x3F,0x42,0x45,0x48,0x4C),
// UCG_A8(0x50,0x54,0x58,0x5C,0x60,0x64,0x68,0x6C),
// UCG_A8(0x70,0x74,0x78,0x7D,0x82,0x87,0x8C,0x91),
// UCG_A7(0x96,0x9B,0xA0,0xA5,0xAA,0xAF,0xB4),
UCG_C10(0x0a4), /* Normal display mode */
UCG_C10(0x0af), /* Set Display On */
//UCG_C12(0x015, 0x030, 0x05f), /* Set Column Address */
//UCG_C12(0x075, 0x010, 0x03f), /* Set Row Address */
//UCG_D3(0x0ff, 0, 0),
//UCG_D3(0x0ff, 0, 0),
//UCG_D3(0x0ff, 0, 0),
//UCG_D3(0x0ff, 0, 0),
//UCG_D3(0x0ff, 0, 0),
//UCG_D3(0x0ff, 0, 0),
//UCG_D3(0x0ff, 0, 0),
//UCG_D3(0x0ff, 0, 0),
//UCG_D3(0x0ff, 0, 0),
//UCG_D3(0x0ff, 0, 0),
//UCG_D3(0x0ff, 0, 0),
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ssd1331_18x96x64_univision(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* 1. Call to the controller procedures to setup the com interface */
if ( ucg_dev_ic_ssd1331_18(ucg, msg, data) == 0 )
return 0;
/* 2. Send specific init sequence for this display module */
ucg_com_SendCmdSeq(ucg, ucg_univision_ssd1331_init_seq);
return 1;
case UCG_MSG_DEV_POWER_DOWN:
/* let do power down by the controller procedures */
return ucg_dev_ic_ssd1331_18(ucg, msg, data);
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 96;
((ucg_wh_t *)data)->h = 64;
return 1;
}
/* all other messages are handled by the controller procedures */
return ucg_dev_ic_ssd1331_18(ucg, msg, data);
}

View File

@ -1,132 +0,0 @@
/*
ucg_dev_tft_128x128_ili9163.c
ILI9341 with 4-Wire SPI (SCK, SDI, CS, D/C and optional reset)
Universal uC Color Graphics Library
Copyright (c) 2015, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
static const ucg_pgm_uint8_t ucg_tft_128x128_ili9163_init_seq[] = {
UCG_CFG_CD(0,1), /* DC=0 for command mode, DC=1 for data and args */
UCG_RST(1),
UCG_CS(1), /* disable chip */
UCG_DLY_MS(5),
UCG_RST(0),
UCG_DLY_MS(5),
UCG_RST(1),
UCG_DLY_MS(50),
UCG_CS(0), /* enable chip */
UCG_C10(0x011), /* sleep out */
UCG_DLY_MS(10),
//UCG_C10(0x038), /* idle mode off */
UCG_C10(0x013), /* normal display on */
//UCG_C14(0x0ed, 0x055, 0x001, 0x023, 0x001), /* power on sequence control (POR values) */
//UCG_C11(0x0f7, 0x020), /* pump ratio control (POR value) */
UCG_C10(0x20), /* not inverted */
//UCG_C10(0x21), /* inverted */
UCG_C11(0x03a, 0x066), /* set pixel format to 18 bit */
//UCG_C11(0x03a, 0x055), /* set pixel format to 16 bit */
//UCG_C12(0x0b1, 0x000, 0x01b), /* frame rate control (POR values) */
//UCG_C14(0x0b6, 0x00a, 0x082 | (1<<5), 0x027, 0x000), /* display function control (POR values, except for shift direction bit) */
//UCG_C11(0x0b7, 0x006), /* entry mode, bit 0: Low voltage detection control (0=off) */
UCG_C12(0x0c0, 0x00a, 0x002), /* power control 1 */
UCG_C11(0x0c1, 0x002), /* power control 2 (step up factor), POR=2 */
UCG_C11(0x0c7, 0x0d0), /* VCOM control 2, enable VCOM control 1 */
UCG_C12(0x0c5, 0x040, 0x04a), /* VCOM control 1, POR=31,3C */
// UCG_C15(0x0cb, 0x039, 0x02c, 0x000, 0x034, 0x002), /* power control A (POR values) */
// UCG_C13(0x0cf, 0x000, 0x081, 0x030), /* power control B (POR values) */
// UCG_C13(0x0e8, 0x084, 0x011, 0x07a), /* timer driving control A (POR values) */
// UCG_C12(0x0ea, 0x066, 0x000), /* timer driving control B (POR values) */
//UCG_C12(0x0ea, 0x000, 0x000), /* timer driving control B */
//UCG_C10(0x28), /* display off */
//UCG_C11(0x0bf, 0x003), /* backlight control 8 */
UCG_C10(0x029), /* display on */
//UCG_C11(0x051, 0x07f), /* brightness */
//UCG_C11(0x053, 0x02c), /* control brightness */
//UCG_C10(0x028), /* display off */
UCG_C11( 0x036, 0x008),
UCG_C14( 0x02a, 0x000, 0x000, 0x000, 0x07f), /* Horizontal GRAM Address Set */
UCG_C14( 0x02b, 0x000, 0x000, 0x000, 0x07f), /* Vertical GRAM Address Set */
UCG_C10( 0x02c), /* Write Data to GRAM */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ili9163_18x128x128(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* 1. Call to the controller procedures to setup the com interface */
if ( ucg_dev_ic_ili9163_18(ucg, msg, data) == 0 )
return 0;
/* 2. Send specific init sequence for this display module */
ucg_com_SendCmdSeq(ucg, ucg_tft_128x128_ili9163_init_seq);
return 1;
case UCG_MSG_DEV_POWER_DOWN:
/* let do power down by the conroller procedures */
return ucg_dev_ic_ili9163_18(ucg, msg, data);
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 128;
return 1;
}
/* all other messages are handled by the controller procedures */
return ucg_dev_ic_ili9163_18(ucg, msg, data);
}

View File

@ -1,111 +0,0 @@
/*
ucg_dev_tft_128x160_st7735.c
ST7735 with 4-Wire SPI (SCK, SDI, CS, D/C and optional reset)
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
//static const uint8_t ucg_dev_ssd1351_128x128_init_seq[] PROGMEM = {
static const ucg_pgm_uint8_t ucg_tft_128x160_st7735_init_seq[] = {
UCG_CFG_CD(0,1), /* DC=0 for command mode, DC=1 for data and args */
UCG_RST(1),
UCG_CS(1), /* disable chip */
UCG_DLY_MS(5),
UCG_RST(0),
UCG_DLY_MS(5),
UCG_RST(1),
UCG_DLY_MS(50),
UCG_CS(0), /* enable chip */
UCG_C10(0x011), /* sleep out */
UCG_DLY_MS(10),
//UCG_C10(0x038), /* idle mode off */
UCG_C10(0x013), /* normal display on */
UCG_C10(0x20), /* not inverted */
//UCG_C10(0x21), /* inverted */
UCG_C11(0x03a, 0x006), /* set pixel format to 18 bit */
//UCG_C11(0x03a, 0x005), /* set pixel format to 16 bit */
//UCG_C12(0x0b1, 0x000, 0x01b), /* frame rate control (POR values) */
//UCG_C10(0x28), /* display off */
//UCG_C11(0x0bf, 0x003), /* backlight control 8 */
UCG_C10(0x029), /* display on */
//UCG_C11(0x051, 0x07f), /* brightness */
//UCG_C11(0x053, 0x02c), /* control brightness */
//UCG_C10(0x028), /* display off */
UCG_C11( 0x036, 0x000), /* memory control */
UCG_C14( 0x02a, 0x000, 0x000, 0x000, 0x07f), /* Horizontal GRAM Address Set */
UCG_C14( 0x02b, 0x000, 0x000, 0x000, 0x09f), /* Vertical GRAM Address Set */
UCG_C10( 0x02c), /* Write Data to GRAM */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_st7735_18x128x160(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* 1. Call to the controller procedures to setup the com interface */
if ( ucg_dev_ic_st7735_18(ucg, msg, data) == 0 )
return 0;
/* 2. Send specific init sequence for this display module */
ucg_com_SendCmdSeq(ucg, ucg_tft_128x160_st7735_init_seq);
return 1;
case UCG_MSG_DEV_POWER_DOWN:
/* let do power down by the conroller procedures */
return ucg_dev_ic_st7735_18(ucg, msg, data);
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 128;
((ucg_wh_t *)data)->h = 160;
return 1;
}
/* all other messages are handled by the controller procedures */
return ucg_dev_ic_st7735_18(ucg, msg, data);
}

View File

@ -1,151 +0,0 @@
/*
ucg_dev_tft_132x132_pcf8833.c
pcf8833 with 3-Wire SPI (SCK, SDI, CS and optional reset)
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
//static const uint8_t ucg_dev_ssd1351_132x132_init_seq[] PROGMEM = {
static const ucg_pgm_uint8_t ucg_tft_132x132_pcf8833_init_seq_OBSOLETE[] = {
UCG_CFG_CD(0,1), /* DC=0 for command mode, DC=1 for data and args */
UCG_RST(1),
UCG_CS(1), /* disable chip */
UCG_DLY_MS(5),
UCG_RST(0),
UCG_DLY_MS(5),
UCG_RST(1),
UCG_DLY_MS(50),
UCG_CS(0), /* enable chip */
UCG_C10(0x01), /* reset */
UCG_DLY_MS(199),
UCG_C10(0x011), /* sleep out */
UCG_DLY_MS(10),
UCG_C10(0x038), /* idle mode off */
//UCG_C10(0x0b5), /* mirror */
//UCG_C10(0x0b7), /* mirror */
UCG_C10(0x013), /* normal display on */
UCG_C10(0x020), /* not inverted */
UCG_C10(0x029), /* display on */
UCG_C11(0x025, 0x03f), /* set contrast -64 ... 63 */
//UCG_C11(0x03a, 0x003), /* set pixel format to 12 bit per pixel */
UCG_C11(0x03a, 0x005),
//UCG_C10(0x003), /* booster on */
UCG_C10(0x023), /* all pixel on */
UCG_DLY_MS(199),
UCG_C10(0x013), /* normal display on */
UCG_C11( 0x036, 0x000), /* memory control */
UCG_C12( 0x02a, 0x000, 0x07f), /* Horizontal GRAM Address Set */
UCG_C12( 0x02b, 0x000, 0x07f), /* Vertical GRAM Address Set */
UCG_C10( 0x02c), /* Write Data to GRAM */
UCG_DLY_MS(10),
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
static const ucg_pgm_uint8_t ucg_tft_132x132_pcf8833_init_seq[] = {
UCG_CFG_CD(0,1), /* DC=0 for command mode, DC=1 for data and args */
UCG_RST(1),
UCG_CS(1), /* disable chip */
UCG_DLY_MS(5),
UCG_RST(0),
UCG_DLY_MS(5),
UCG_RST(1),
UCG_DLY_MS(50),
UCG_CS(0), /* enable chip */
UCG_C10(0x01), /* reset */
UCG_DLY_MS(199),
UCG_C10(0x011), /* sleep out */
UCG_C10(0x013), /* normal display on */
UCG_C10(0x020), /* not inverted */
UCG_C10(0x029), /* display on */
UCG_C11(0x025, 0x03f), /* set contrast -64 ... 63 */
//UCG_C11(0x03a, 0x003), /* set pixel format to 12 bit per pixel */
UCG_C11(0x03a, 0x005), /* set pixel format to 16 bit per pixel */
UCG_C11( 0x036, 0x000), /* memory control */
UCG_C12( 0x02a, 0x000, 0x07f), /* Horizontal GRAM Address Set */
UCG_C12( 0x02b, 0x000, 0x07f), /* Vertical GRAM Address Set */
UCG_C10( 0x02c), /* Write Data to GRAM */
// UCG_DLY_MS(10),
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_pcf8833_16x132x132(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* 1. Call to the controller procedures to setup the com interface */
if ( ucg_dev_ic_pcf8833_16(ucg, msg, data) == 0 )
return 0;
/* 2. Send specific init sequence for this display module */
ucg_com_SendCmdSeq(ucg, ucg_tft_132x132_pcf8833_init_seq);
return 1;
case UCG_MSG_DEV_POWER_DOWN:
/* let do power down by the conroller procedures */
return ucg_dev_ic_pcf8833_16(ucg, msg, data);
}
/* all other messages are handled by the controller procedures */
return ucg_dev_ic_pcf8833_16(ucg, msg, data);
}

View File

@ -1,160 +0,0 @@
/*
ucg_dev_tft_240x320_ili9325_spi.c
Device for the ILI9325 in 8 bit SPI mode (IM3=0, IM2=1, IM1=1, IM0=1)
All commands are 8 bit width only.
1 May 2014: Currently, this is not working
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
//static const uint8_t ucg_dev_ssd1351_128x128_init_seq[] PROGMEM = {
static const ucg_pgm_uint8_t ucg_tft_240x320_ili9325_spi_init_seq[] = {
UCG_CFG_CD(0,1), /* DC=0 for command mode, DC=1 for data and args */
UCG_RST(1),
UCG_CS(1), /* disable chip */
UCG_DLY_MS(5),
UCG_RST(0),
UCG_DLY_MS(5),
UCG_RST(1),
UCG_DLY_MS(50),
UCG_CS(0), /* enable chip */
UCG_DLY_MS(1), /* delay 1 ms */
UCG_C12(0x001,0x001, 0x000), /* Driver Output Control, bits 8 & 10 */
UCG_C12(0x002, 0x007, 0x000), /* LCD Driving Wave Control, bit 9: Set line inversion */
//UCG_C12(0x003, 0x010, 0x030), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1 (16 bit transfer, 65K Mode)*/
UCG_C12(0x003, 0xc0 | 0x010, 0x030), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
//UCG_C12(0x004, 0x000, 0x000), /* Resize register, all 0: no resize */
UCG_C12(0x008, 0x002, 0x007), /* Display Control 2: set the back porch and front porch */
//UCG_C12(0x009, 0x000, 0x000), /* Display Control 3: normal scan */
//UCG_C12(0x00a, 0x000, 0x000), /* Display Control 4: set to "no FMARK output" */
UCG_C12(0x00c, 0x000, 0x000), /* RGB Display Interface Control 1, RIM=10 (3x6 Bit), 12 Jan 14: RIM=00 */
//UCG_C12(0x00d, 0x000, 0x000), /* Frame Maker Position */
//UCG_C12(0x00f, 0x000, 0x000), /* RGB Display Interface Control 2 */
UCG_C12(0x010, 0x000, 0x000), /* Power Control 1: SAP, BT[3:0], AP, DSTB, SLP, STB, actual setting is done below */
UCG_C12(0x011, 0x000, 0x007), /* Power Control 2: DC1[2:0], DC0[2:0], VC[2:0] */
UCG_C12(0x012, 0x000, 0x000), /* Power Control 3: VREG1OUT voltage */
UCG_C12(0x013, 0x000, 0x000), /* Power Control 4: VDV[4:0] for VCOM amplitude */
//UCG_C12(0x007, 0x000, 0x001), /* Display Control 1: Operate, but do not display */
UCG_C12( 0x007, 0x001, 0x033), /* Display Control 1: Operate, display ON, Partial image off */
UCG_DLY_MS(100), /* delay 100 ms */ /* ITDB02 none D verion: 50ms */
UCG_C12( 0x010, 0x010, 0x090), /* Power Control 1: SAP, BT[3:0], AP, DSTB, SLP, STB */
/* 12. Jan 14. Prev value: 0x016, 0x090 */
/* ITDB02 none D verion: 0x010, 0x090 */
//UCG_C12( 0x010, 0x017, 0x0f0), /* Power Control 1: Setting for max quality & power consumption: SAP(Bit 12)=1, BT[3:0]=7 (max), APE (Bit 8)=1, AP=7 (max), disable sleep: SLP=0, STB=0 */
UCG_C12( 0x011, 0x002, 0x027), /* Power Control 2 VCI ration, step up circuits 1 & 2 */
UCG_DLY_MS(50), /* delay 50 ms */
UCG_C12( 0x012, 0x000, 0x01f), /* Power Control 3: VCI: External, VCI*1.80 */
/* 12. Jan 14. Prev value: 0x000, 0x00d */
UCG_DLY_MS(50), /* delay 50 ms */
UCG_C12( 0x013, 0x015, 0x000), /* Power Control 4: VDV[4:0] for VCOM amplitude */
/* 12. Jan 14. Prev value: 0x012, 0x009 */
UCG_C12( 0x029, 0x000, 0x027), /* Power Control 7 */
/* 12. Jan 14. Prev value: 0x000, 0x00a */
UCG_C12( 0x02b, 0x000, 0x00d), /* Frame Rate: 93 */
//UCG_C12( 0x02b, 0x000, 0x00b), /* Frame Rate: 70, too less, some flicker visible */
UCG_DLY_MS(50), /* delay 50 ms */
/* Gamma Control, values from iteadstudio.com reference software on google code */
/*
UCG_C12(0x30,0x00,0x00),
UCG_C12(0x31,0x07,0x07),
UCG_C12(0x32,0x03,0x07),
UCG_C12(0x35,0x02,0x00),
UCG_C12(0x36,0x00,0x08),
UCG_C12(0x37,0x00,0x04),
UCG_C12(0x38,0x00,0x00),
UCG_C12(0x39,0x07,0x07),
UCG_C12(0x3C,0x00,0x02),
UCG_C12(0x3D,0x1D,0x04),
*/
UCG_C12( 0x020, 0x000, 0x000), /* Horizontal GRAM Address Set */
UCG_C12( 0x021, 0x000, 0x000), /* Vertical GRAM Address Set */
UCG_C12( 0x050, 0x000, 0x000), /* Horizontal GRAM Start Address */
UCG_C12( 0x051, 0x000, 0x0EF), /* Horizontal GRAM End Address: 239 */
UCG_C12( 0x052, 0x000, 0x000), /* Vertical GRAM Start Address */
UCG_C12( 0x053, 0x001, 0x03F), /* Vertical GRAM End Address: 319 */
UCG_C12( 0x060, 0x0a7, 0x000), /* Driver Output Control 2, NL = 0x027 = 320 lines, GS (bit 15) = 1 */
UCG_C12( 0x061, 0x000, 0x001), /* Base Image Display Control: NDL,VLE = 0 (Disbale Vertical Scroll), REV */
//UCG_C12( 0x06a, 0x000, 0x000), /* Vertical Scroll Control */
//UCG_C12( 0x080, 0x000, 0x000), /* Partial Image 1 Display Position */
//UCG_C12( 0x081, 0x000, 0x000), /* Partial Image 1 RAM Start Address */
//UCG_C12( 0x082, 0x000, 0x000), /* Partial Image 1 RAM End Address */
//UCG_C12( 0x083, 0x000, 0x000), /* Partial Image 2 Display Position */
//UCG_C12( 0x084, 0x000, 0x000), /* Partial Image 2 RAM Start Address */
//UCG_C12( 0x085, 0x000, 0x000), /* Partial Image 2 RAM End Address */
UCG_C12( 0x090, 0x000, 0x010), /* Panel Interface Control 1 */
UCG_C12( 0x092, 0x000, 0x000), /* Panel Interface Control 2 */
/* 0x006, 0x000 */
UCG_C12( 0x007, 0x001, 0x033), /* Display Control 1: Operate, display ON, Partial image off */
UCG_DLY_MS(10), /* delay 10 ms */
/* write test pattern */
//UCG_C12( 0x020, 0x000, 0x000), /* Horizontal GRAM Address Set */
//UCG_C12( 0x021, 0x000, 0x011), /* Vertical GRAM Address Set */
UCG_C10( 0x022), /* Write Data to GRAM */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ili9325_spi_18x240x320(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* 1. Call to the controller procedures to setup the com interface */
if ( ucg_dev_ic_ili9325_spi_18(ucg, msg, data) == 0 )
return 0;
/* 2. Send specific init sequence for this display module */
ucg_com_SendCmdSeq(ucg, ucg_tft_240x320_ili9325_spi_init_seq);
return 1;
case UCG_MSG_DEV_POWER_DOWN:
/* let do power down by the conroller procedures */
return ucg_dev_ic_ili9325_spi_18(ucg, msg, data);
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 240;
((ucg_wh_t *)data)->h = 320;
return 1;
}
/* all other messages are handled by the controller procedures */
return ucg_dev_ic_ili9325_spi_18(ucg, msg, data);
}

View File

@ -1,132 +0,0 @@
/*
ucg_dev_tft_240x320_ili9341.c
ILI9341 with 4-Wire SPI (SCK, SDI, CS, D/C and optional reset)
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
//static const uint8_t ucg_dev_ssd1351_128x128_init_seq[] PROGMEM = {
static const ucg_pgm_uint8_t ucg_tft_240x320_ili9341_init_seq[] = {
UCG_CFG_CD(0,1), /* DC=0 for command mode, DC=1 for data and args */
UCG_RST(1),
UCG_CS(1), /* disable chip */
UCG_DLY_MS(5),
UCG_RST(0),
UCG_DLY_MS(5),
UCG_RST(1),
UCG_DLY_MS(50),
UCG_CS(0), /* enable chip */
UCG_C10(0x011), /* sleep out */
UCG_DLY_MS(10),
//UCG_C10(0x038), /* idle mode off */
UCG_C10(0x013), /* normal display on */
//UCG_C14(0x0ed, 0x055, 0x001, 0x023, 0x001), /* power on sequence control (POR values) */
//UCG_C11(0x0f7, 0x020), /* pump ratio control (POR value) */
UCG_C10(0x20), /* not inverted */
//UCG_C10(0x21), /* inverted */
UCG_C11(0x03a, 0x066), /* set pixel format to 18 bit */
//UCG_C11(0x03a, 0x055), /* set pixel format to 16 bit */
//UCG_C12(0x0b1, 0x000, 0x01b), /* frame rate control (POR values) */
UCG_C14(0x0b6, 0x00a, 0x082 | (1<<5), 0x027, 0x000), /* display function control (POR values, except for shift direction bit) */
//UCG_C11(0x0b7, 0x006), /* entry mode, bit 0: Low voltage detection control (0=off) */
UCG_C11(0x0c0, 0x021), /* power control 1 (reference voltage level), POR=21 */
UCG_C11(0x0c1, 0x002), /* power control 2 (step up factor), POR=2 */
UCG_C11(0x0c7, 0x0c0), /* VCOM control 2, enable VCOM control 1 */
UCG_C12(0x0c5, 0x031, 0x03c), /* VCOM control 1, POR=31,3C */
UCG_C15(0x0cb, 0x039, 0x02c, 0x000, 0x034, 0x002), /* power control A (POR values) */
UCG_C13(0x0cf, 0x000, 0x081, 0x030), /* power control B (POR values) */
UCG_C13(0x0e8, 0x084, 0x011, 0x07a), /* timer driving control A (POR values) */
UCG_C12(0x0ea, 0x066, 0x000), /* timer driving control B (POR values) */
//UCG_C12(0x0ea, 0x000, 0x000), /* timer driving control B */
//UCG_C10(0x28), /* display off */
//UCG_C11(0x0bf, 0x003), /* backlight control 8 */
UCG_C10(0x029), /* display on */
//UCG_C11(0x051, 0x07f), /* brightness */
//UCG_C11(0x053, 0x02c), /* control brightness */
//UCG_C10(0x028), /* display off */
UCG_C11( 0x036, 0x008),
UCG_C14( 0x02a, 0x000, 0x000, 0x000, 0x0ef), /* Horizontal GRAM Address Set */
UCG_C14( 0x02b, 0x000, 0x000, 0x001, 0x03f), /* Vertical GRAM Address Set */
UCG_C10( 0x02c), /* Write Data to GRAM */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ili9341_18x240x320(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* 1. Call to the controller procedures to setup the com interface */
if ( ucg_dev_ic_ili9341_18(ucg, msg, data) == 0 )
return 0;
/* 2. Send specific init sequence for this display module */
ucg_com_SendCmdSeq(ucg, ucg_tft_240x320_ili9341_init_seq);
return 1;
case UCG_MSG_DEV_POWER_DOWN:
/* let do power down by the conroller procedures */
return ucg_dev_ic_ili9341_18(ucg, msg, data);
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 240;
((ucg_wh_t *)data)->h = 320;
return 1;
}
/* all other messages are handled by the controller procedures */
return ucg_dev_ic_ili9341_18(ucg, msg, data);
}

View File

@ -1,165 +0,0 @@
/*
ucg_dev_tft_240x320_itdb02.c
ITDB02 Module Shield
Documentation: code.google.com/p/itdb02/
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
//static const uint8_t ucg_dev_ssd1351_128x128_init_seq[] PROGMEM = {
static const ucg_pgm_uint8_t ucg_tft_240x320_ili9325_init_seq[] = {
UCG_CFG_CD(0,1), /* DC=0 for command mode, DC=1 for data and args */
UCG_RST(1),
UCG_CS(1), /* disable chip */
UCG_DLY_MS(5),
UCG_RST(0),
UCG_DLY_MS(5),
UCG_RST(1),
UCG_DLY_MS(50),
UCG_CS(0), /* enable chip */
//UCG_C22(0x000, 0x001,0x001, 0x000), /* Driver Output Control, bits 8 & 10 */
//UCG_C22( 0x000, 0x007, 0x001, 0x033), /* Display Control 1: Operate, display ON, Partial image off */
//UCG_CS(1), /* disable chip */
//UCG_END(), /* end of sequence */
UCG_C22(0x000, 0x001,0x001, 0x000), /* Driver Output Control, bits 8 & 10 */
UCG_C22(0x000, 0x002, 0x007, 0x000), /* LCD Driving Wave Control, bit 9: Set line inversion */
//UCG_C22(0x000, 0x003, 0x010, 0x030), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1 (16 bit transfer, 65K Mode)*/
UCG_C22(0x000, 0x003, 0xc0 | 0x010, 0x030), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1, set TRI (Bit 15) and DFM (Bit 14) --> three byte transfer */
//UCG_C22(0x000, 0x004, 0x000, 0x000), /* Resize register, all 0: no resize */
UCG_C22(0x000, 0x008, 0x002, 0x007), /* Display Control 2: set the back porch and front porch */
//UCG_C22(0x000, 0x009, 0x000, 0x000), /* Display Control 3: normal scan */
//UCG_C22(0x000, 0x00a, 0x000, 0x000), /* Display Control 4: set to "no FMARK output" */
UCG_C22(0x000, 0x00c, 0x000, 0x000), /* RGB Display Interface Control 1, RIM=10 (3x6 Bit), 12 Jan 14: RIM=00 */
//UCG_C22(0x000, 0x00d, 0x000, 0x000), /* Frame Maker Position */
//UCG_C22(0x000, 0x00f, 0x000, 0x000), /* RGB Display Interface Control 2 */
UCG_C22(0x000, 0x010, 0x000, 0x000), /* Power Control 1: SAP, BT[3:0], AP, DSTB, SLP, STB, actual setting is done below */
UCG_C22(0x000, 0x011, 0x000, 0x007), /* Power Control 2: DC1[2:0], DC0[2:0], VC[2:0] */
UCG_C22(0x000, 0x012, 0x000, 0x000), /* Power Control 3: VREG1OUT voltage */
UCG_C22(0x000, 0x013, 0x000, 0x000), /* Power Control 4: VDV[4:0] for VCOM amplitude */
UCG_C22(0x000, 0x007, 0x000, 0x001), /* Display Control 1: Operate, but do not display */
UCG_DLY_MS(100), /* delay 100 ms */ /* ITDB02 none D verion: 50ms */
UCG_C22( 0x000, 0x010, 0x010, 0x090), /* Power Control 1: SAP, BT[3:0], AP, DSTB, SLP, STB */
/* 12. Jan 14. Prev value: 0x016, 0x090 */
/* ITDB02 none D verion: 0x010, 0x090 */
//UCG_C22( 0x000, 0x010, 0x017, 0x0f0), /* Power Control 1: Setting for max quality & power consumption: SAP(Bit 12)=1, BT[3:0]=7 (max), APE (Bit 8)=1, AP=7 (max), disable sleep: SLP=0, STB=0 */
UCG_C22( 0x000, 0x011, 0x002, 0x027), /* Power Control 2 VCI ration, step up circuits 1 & 2 */
UCG_DLY_MS(50), /* delay 50 ms */
UCG_C22( 0x000, 0x012, 0x000, 0x01f), /* Power Control 3: VCI: External, VCI*1.80 */
/* 12. Jan 14. Prev value: 0x000, 0x00d */
UCG_DLY_MS(50), /* delay 50 ms */
UCG_C22( 0x000, 0x013, 0x015, 0x000), /* Power Control 4: VDV[4:0] for VCOM amplitude */
/* 12. Jan 14. Prev value: 0x012, 0x009 */
UCG_C22( 0x000, 0x029, 0x000, 0x027), /* Power Control 7 */
/* 12. Jan 14. Prev value: 0x000, 0x00a */
UCG_C22( 0x000, 0x02b, 0x000, 0x00d), /* Frame Rate: 93 */
//UCG_C22( 0x000, 0x02b, 0x000, 0x00b), /* Frame Rate: 70, too less, some flicker visible */
UCG_DLY_MS(50), /* delay 50 ms */
/* Gamma Control, values from iteadstudio.com reference software on google code */
/*
UCG_C22(0x00,0x30,0x00,0x00),
UCG_C22(0x00,0x31,0x07,0x07),
UCG_C22(0x00,0x32,0x03,0x07),
UCG_C22(0x00,0x35,0x02,0x00),
UCG_C22(0x00,0x36,0x00,0x08),
UCG_C22(0x00,0x37,0x00,0x04),
UCG_C22(0x00,0x38,0x00,0x00),
UCG_C22(0x00,0x39,0x07,0x07),
UCG_C22(0x00,0x3C,0x00,0x02),
UCG_C22(0x00,0x3D,0x1D,0x04),
*/
UCG_C22( 0x000, 0x020, 0x000, 0x000), /* Horizontal GRAM Address Set */
UCG_C22( 0x000, 0x021, 0x000, 0x000), /* Vertical GRAM Address Set */
UCG_C22( 0x000, 0x050, 0x000, 0x000), /* Horizontal GRAM Start Address */
UCG_C22( 0x000, 0x051, 0x000, 0x0EF), /* Horizontal GRAM End Address: 239 */
UCG_C22( 0x000, 0x052, 0x000, 0x000), /* Vertical GRAM Start Address */
UCG_C22( 0x000, 0x053, 0x001, 0x03F), /* Vertical GRAM End Address: 319 */
UCG_C22( 0x000, 0x060, 0x0a7, 0x000), /* Driver Output Control 2, NL = 0x027 = 320 lines, GS (bit 15) = 1 */
UCG_C22( 0x000, 0x061, 0x000, 0x001), /* Base Image Display Control: NDL,VLE = 0 (Disbale Vertical Scroll), REV */
//UCG_C22( 0x000, 0x06a, 0x000, 0x000), /* Vertical Scroll Control */
//UCG_C22( 0x000, 0x080, 0x000, 0x000), /* Partial Image 1 Display Position */
//UCG_C22( 0x000, 0x081, 0x000, 0x000), /* Partial Image 1 RAM Start Address */
//UCG_C22( 0x000, 0x082, 0x000, 0x000), /* Partial Image 1 RAM End Address */
//UCG_C22( 0x000, 0x083, 0x000, 0x000), /* Partial Image 2 Display Position */
//UCG_C22( 0x000, 0x084, 0x000, 0x000), /* Partial Image 2 RAM Start Address */
//UCG_C22( 0x000, 0x085, 0x000, 0x000), /* Partial Image 2 RAM End Address */
UCG_C22( 0x000, 0x090, 0x000, 0x010), /* Panel Interface Control 1 */
UCG_C22( 0x000, 0x092, 0x000, 0x000), /* Panel Interface Control 2 */
/* 0x006, 0x000 */
UCG_C22( 0x000, 0x007, 0x001, 0x033), /* Display Control 1: Operate, display ON, Partial image off */
UCG_DLY_MS(10), /* delay 10 ms */
/* write test pattern */
//UCG_C22( 0x000, 0x020, 0x000, 0x000), /* Horizontal GRAM Address Set */
//UCG_C22( 0x000, 0x021, 0x000, 0x011), /* Vertical GRAM Address Set */
UCG_C20( 0x000, 0x022), /* Write Data to GRAM */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ili9325_18x240x320_itdb02(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* 1. Call to the controller procedures to setup the com interface */
if ( ucg_dev_ic_ili9325_18(ucg, msg, data) == 0 )
return 0;
/* 2. Send specific init sequence for this display module */
ucg_com_SendCmdSeq(ucg, ucg_tft_240x320_ili9325_init_seq);
return 1;
case UCG_MSG_DEV_POWER_DOWN:
/* let do power down by the conroller procedures */
return ucg_dev_ic_ili9325_18(ucg, msg, data);
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 240;
((ucg_wh_t *)data)->h = 320;
return 1;
}
/* all other messages are handled by the controller procedures */
return ucg_dev_ic_ili9325_18(ucg, msg, data);
}

View File

@ -1,158 +0,0 @@
/*
ucg_dev_tft_240x320_ssd1289.c
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
#ifdef NOT_YET_IMPLEMENTED
static const ucg_pgm_uint8_t ucg_tft_240x320_ssd1289_init_seq[] = {
UCG_CFG_CD(0,1), /* DC=0 for command mode, DC=1 for data and args */
UCG_RST(1),
UCG_CS(1), /* disable chip */
UCG_DLY_MS(5),
UCG_RST(0),
UCG_DLY_MS(5),
UCG_RST(1),
UCG_DLY_MS(50),
UCG_CS(0), /* enable chip */
UCG_C22(0x000, 0x000, 0x000, 0x001), /* enable oscilator */
UCG_C22(0x000, 0x003, 0x066, 0x064), /* Power control 1 (POR value) */
//UCG_C22(0x000, 0x002, 0x007, 0x000), /* LCD Driving Wave Control, bit 9: Set line inversion */
//UCG_C22(0x000, 0x003, 0x010, 0x030), /* Entry Mode, GRAM write direction and BGR (Bit 12)=1 (16 bit transfer, 65K Mode)*/
//UCG_C22(0x000, 0x004, 0x000, 0x000), /* Resize register, all 0: no resize */
UCG_C22(0x000, 0x008, 0x002, 0x007), /* Display Control 2: set the back porch and front porch */
//UCG_C22(0x000, 0x009, 0x000, 0x000), /* Display Control 3: normal scan */
//UCG_C22(0x000, 0x00a, 0x000, 0x000), /* Display Control 4: set to "no FMARK output" */
UCG_C22(0x000, 0x00c, 0x000, 0x000), /* RGB Display Interface Control 1, RIM=10 (3x6 Bit), 12 Jan 14: RIM=00 */
//UCG_C22(0x000, 0x00d, 0x000, 0x000), /* Frame Maker Position */
//UCG_C22(0x000, 0x00f, 0x000, 0x000), /* RGB Display Interface Control 2 */
UCG_C22(0x000, 0x010, 0x000, 0x000), /* Power Control 1: SAP, BT[3:0], AP, DSTB, SLP, STB, actual setting is done below */
UCG_C22(0x000, 0x011, 0x000, 0x007), /* Power Control 2: DC1[2:0], DC0[2:0], VC[2:0] */
UCG_C22(0x000, 0x012, 0x000, 0x000), /* Power Control 3: VREG1OUT voltage */
UCG_C22(0x000, 0x013, 0x000, 0x000), /* Power Control 4: VDV[4:0] for VCOM amplitude */
UCG_C22(0x000, 0x007, 0x000, 0x001), /* Display Control 1: Operate, but do not display */
UCG_DLY_MS(100), /* delay 100 ms */ /* ITDB02 none D verion: 50ms */
UCG_C22( 0x000, 0x010, 0x010, 0x090), /* Power Control 1: SAP, BT[3:0], AP, DSTB, SLP, STB */
/* 12. Jan 14. Prev value: 0x016, 0x090 */
/* ITDB02 none D verion: 0x010, 0x090 */
//UCG_C22( 0x000, 0x010, 0x017, 0x0f0), /* Power Control 1: Setting for max quality & power consumption: SAP(Bit 12)=1, BT[3:0]=7 (max), APE (Bit 8)=1, AP=7 (max), disable sleep: SLP=0, STB=0 */
UCG_C22( 0x000, 0x011, 0x002, 0x027), /* Power Control 2 VCI ration, step up circuits 1 & 2 */
UCG_DLY_MS(50), /* delay 50 ms */
UCG_C22( 0x000, 0x012, 0x000, 0x01f), /* Power Control 3: VCI: External, VCI*1.80 */
/* 12. Jan 14. Prev value: 0x000, 0x00d */
UCG_DLY_MS(50), /* delay 50 ms */
UCG_C22( 0x000, 0x013, 0x015, 0x000), /* Power Control 4: VDV[4:0] for VCOM amplitude */
/* 12. Jan 14. Prev value: 0x012, 0x009 */
UCG_C22( 0x000, 0x029, 0x000, 0x027), /* Power Control 7 */
/* 12. Jan 14. Prev value: 0x000, 0x00a */
UCG_C22( 0x000, 0x02b, 0x000, 0x00d), /* Frame Rate: 93 */
//UCG_C22( 0x000, 0x02b, 0x000, 0x00b), /* Frame Rate: 70, too less, some flicker visible */
UCG_DLY_MS(50), /* delay 50 ms */
/* Gamma Control, values from iteadstudio.com reference software on google code */
/*
UCG_C22(0x00,0x30,0x00,0x00),
UCG_C22(0x00,0x31,0x07,0x07),
UCG_C22(0x00,0x32,0x03,0x07),
UCG_C22(0x00,0x35,0x02,0x00),
UCG_C22(0x00,0x36,0x00,0x08),
UCG_C22(0x00,0x37,0x00,0x04),
UCG_C22(0x00,0x38,0x00,0x00),
UCG_C22(0x00,0x39,0x07,0x07),
UCG_C22(0x00,0x3C,0x00,0x02),
UCG_C22(0x00,0x3D,0x1D,0x04),
*/
UCG_C22( 0x000, 0x020, 0x000, 0x000), /* Horizontal GRAM Address Set */
UCG_C22( 0x000, 0x021, 0x000, 0x000), /* Vertical GRAM Address Set */
UCG_C22( 0x000, 0x050, 0x000, 0x000), /* Horizontal GRAM Start Address */
UCG_C22( 0x000, 0x051, 0x000, 0x0EF), /* Horizontal GRAM End Address: 239 */
UCG_C22( 0x000, 0x052, 0x000, 0x000), /* Vertical GRAM Start Address */
UCG_C22( 0x000, 0x053, 0x001, 0x03F), /* Vertical GRAM End Address: 319 */
UCG_C22( 0x000, 0x060, 0x0a7, 0x000), /* Driver Output Control 2, NL = 0x027 = 320 lines, GS (bit 15) = 1 */
UCG_C22( 0x000, 0x061, 0x000, 0x001), /* Base Image Display Control: NDL,VLE = 0 (Disbale Vertical Scroll), REV */
//UCG_C22( 0x000, 0x06a, 0x000, 0x000), /* Vertical Scroll Control */
//UCG_C22( 0x000, 0x080, 0x000, 0x000), /* Partial Image 1 Display Position */
//UCG_C22( 0x000, 0x081, 0x000, 0x000), /* Partial Image 1 RAM Start Address */
//UCG_C22( 0x000, 0x082, 0x000, 0x000), /* Partial Image 1 RAM End Address */
//UCG_C22( 0x000, 0x083, 0x000, 0x000), /* Partial Image 2 Display Position */
//UCG_C22( 0x000, 0x084, 0x000, 0x000), /* Partial Image 2 RAM Start Address */
//UCG_C22( 0x000, 0x085, 0x000, 0x000), /* Partial Image 2 RAM End Address */
UCG_C22( 0x000, 0x090, 0x000, 0x010), /* Panel Interface Control 1 */
UCG_C22( 0x000, 0x092, 0x000, 0x000), /* Panel Interface Control 2 */
/* 0x006, 0x000 */
UCG_C22( 0x000, 0x007, 0x001, 0x033), /* Display Control 1: Operate, display ON, Partial image off */
UCG_DLY_MS(10), /* delay 10 ms */
/* write test pattern */
//UCG_C22( 0x000, 0x020, 0x000, 0x000), /* Horizontal GRAM Address Set */
//UCG_C22( 0x000, 0x021, 0x000, 0x011), /* Vertical GRAM Address Set */
UCG_C20( 0x000, 0x022), /* Write Data to GRAM */
UCG_CS(1), /* disable chip */
UCG_END(), /* end of sequence */
};
ucg_int_t ucg_dev_ssd1289_18x240x320_itdb02(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_DEV_POWER_UP:
/* 1. Call to the controller procedures to setup the com interface */
if ( ucg_dev_ic_ssd1289_18(ucg, msg, data) == 0 )
return 0;
/* 2. Send specific init sequence for this display module */
ucg_com_SendCmdSeq(ucg, ucg_tft_240x320_ssd1289_init_seq);
return 1;
case UCG_MSG_DEV_POWER_DOWN:
/* let do power down by the conroller procedures */
return ucg_dev_ic_ssd1289_18(ucg, msg, data);
case UCG_MSG_GET_DIMENSION:
((ucg_wh_t *)data)->w = 240;
((ucg_wh_t *)data)->h = 320;
return 1;
}
/* all other messages are handled by the controller procedures */
return ucg_dev_ic_ssd1289_18(ucg, msg, data);
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,78 +0,0 @@
/*
ucg_init.c
Universal uC Color Graphics Library
Copyright (c) 2013, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
#include <string.h> /* memset */
#ifdef __AVR__
uint8_t global_SREG_backup; // used by the atomic macros
#endif
void ucg_init_struct(ucg_t *ucg)
{
//memset(ucg, 0, sizeof(ucg_t));
ucg->is_power_up = 0;
ucg->rotate_chain_device_cb = 0;
ucg->arg.scale = 1;
//ucg->display_offset.x = 0;
//ucg->display_offset.y = 0;
ucg->font = 0;
//ucg->font_mode = UCG_FONT_MODE_NONE; Old font procedures
ucg->font_decode.is_transparent = 1; // new font procedures
ucg->com_initial_change_sent = 0;
ucg->com_status = 0;
ucg->com_cfg_cd = 0;
}
ucg_int_t ucg_Init(ucg_t *ucg, ucg_dev_fnptr device_cb, ucg_dev_fnptr ext_cb, ucg_com_fnptr com_cb)
{
ucg_int_t r;
ucg_init_struct(ucg);
if ( ext_cb == (ucg_dev_fnptr)0 )
ucg->ext_cb = ucg_ext_none;
else
ucg->ext_cb = ext_cb;
ucg->device_cb = device_cb;
ucg->com_cb = com_cb;
ucg_SetFontPosBaseline(ucg);
r = ucg_PowerUp(ucg);
ucg_GetDimension(ucg);
return r;
}

View File

@ -1,131 +0,0 @@
/*
ucg_line.c
Universal uC Color Graphics Library
Copyright (c) 2013, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
void ucg_Draw90Line(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t len, ucg_int_t dir, ucg_int_t col_idx)
{
ucg->arg.pixel.rgb.color[0] = ucg->arg.rgb[col_idx].color[0];
ucg->arg.pixel.rgb.color[1] = ucg->arg.rgb[col_idx].color[1];
ucg->arg.pixel.rgb.color[2] = ucg->arg.rgb[col_idx].color[2];
ucg->arg.pixel.pos.x = x;
ucg->arg.pixel.pos.y = y;
ucg->arg.len = len;
ucg->arg.dir = dir;
ucg_DrawL90FXWithArg(ucg);
}
void ucg_DrawHLine(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t len)
{
ucg_Draw90Line(ucg, x, y, len, 0, 0);
}
void ucg_DrawVLine(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t len)
{
ucg_Draw90Line(ucg, x, y, len, 1, 0);
}
void ucg_DrawHRLine(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t len)
{
ucg_Draw90Line(ucg, x, y, len, 2, 0);
}
void ucg_DrawGradientLine(ucg_t *ucg, ucg_int_t x, ucg_int_t y, ucg_int_t len, ucg_int_t dir)
{
/* color goes from ucg->arg.rgb[0] to ucg->arg.rgb[1] */
ucg->arg.pixel.pos.x = x;
ucg->arg.pixel.pos.y = y;
ucg->arg.len = len;
ucg->arg.dir = dir;
ucg_DrawL90SEWithArg(ucg);
}
void ucg_DrawLine(ucg_t *ucg, ucg_int_t x1, ucg_int_t y1, ucg_int_t x2, ucg_int_t y2)
{
ucg_int_t tmp;
ucg_int_t x,y;
ucg_int_t dx, dy;
ucg_int_t err;
ucg_int_t ystep;
uint8_t swapxy = 0;
/* no BBX intersection check at the moment... */
ucg->arg.pixel.rgb.color[0] = ucg->arg.rgb[0].color[0];
ucg->arg.pixel.rgb.color[1] = ucg->arg.rgb[0].color[1];
ucg->arg.pixel.rgb.color[2] = ucg->arg.rgb[0].color[2];
if ( x1 > x2 ) dx = x1-x2; else dx = x2-x1;
if ( y1 > y2 ) dy = y1-y2; else dy = y2-y1;
if ( dy > dx )
{
swapxy = 1;
tmp = dx; dx =dy; dy = tmp;
tmp = x1; x1 =y1; y1 = tmp;
tmp = x2; x2 =y2; y2 = tmp;
}
if ( x1 > x2 )
{
tmp = x1; x1 =x2; x2 = tmp;
tmp = y1; y1 =y2; y2 = tmp;
}
err = dx >> 1;
if ( y2 > y1 ) ystep = 1; else ystep = -1;
y = y1;
for( x = x1; x <= x2; x++ )
{
if ( swapxy == 0 )
{
ucg->arg.pixel.pos.x = x;
ucg->arg.pixel.pos.y = y;
}
else
{
ucg->arg.pixel.pos.x = y;
ucg->arg.pixel.pos.y = x;
}
ucg_DrawPixelWithArg(ucg);
err -= (uint8_t)dy;
if ( err < 0 )
{
y += ystep;
err += dx;
}
}
}

View File

@ -1,59 +0,0 @@
/*
ucg_pixel.c
Universal uC Color Graphics Library
Copyright (c) 2013, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ucg.h"
void ucg_SetColor(ucg_t *ucg, uint8_t idx, uint8_t r, uint8_t g, uint8_t b)
{
//ucg->arg.pixel.rgb.color[0] = r;
//ucg->arg.pixel.rgb.color[1] = g;
//ucg->arg.pixel.rgb.color[2] = b;
ucg->arg.rgb[idx].color[0] = r;
ucg->arg.rgb[idx].color[1] = g;
ucg->arg.rgb[idx].color[2] = b;
}
void ucg_DrawPixel(ucg_t *ucg, ucg_int_t x, ucg_int_t y)
{
ucg->arg.pixel.rgb.color[0] = ucg->arg.rgb[0].color[0];
ucg->arg.pixel.rgb.color[1] = ucg->arg.rgb[0].color[1];
ucg->arg.pixel.rgb.color[2] = ucg->arg.rgb[0].color[2];
ucg->arg.pixel.pos.x = x;
ucg->arg.pixel.pos.y = y;
ucg_DrawPixelWithArg(ucg);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,328 +0,0 @@
/*
ucg_polygon.c
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
/*===========================================*/
/* procedures, which should not be inlined (save as much flash ROM as possible) */
static uint8_t pge_Next(struct pg_edge_struct *pge) PG_NOINLINE;
static uint8_t pg_inc(pg_struct *pg, uint8_t i) PG_NOINLINE;
static uint8_t pg_dec(pg_struct *pg, uint8_t i) PG_NOINLINE;
static void pg_expand_min_y(pg_struct *pg, pg_word_t min_y, uint8_t pge_idx) PG_NOINLINE;
static void pg_line_init(pg_struct * const pg, uint8_t pge_index) PG_NOINLINE;
/*===========================================*/
/* line draw algorithm */
static uint8_t pge_Next(struct pg_edge_struct *pge)
{
if ( pge->current_y >= pge->max_y )
return 0;
pge->current_x += pge->current_x_offset;
pge->error += pge->error_offset;
if ( pge->error > 0 )
{
pge->current_x += pge->x_direction;
pge->error -= pge->height;
}
pge->current_y++;
return 1;
}
/* assumes y2 > y1 */
static void pge_Init(struct pg_edge_struct *pge, pg_word_t x1, pg_word_t y1, pg_word_t x2, pg_word_t y2)
{
pg_word_t dx = x2 - x1;
pg_word_t width;
pge->height = y2 - y1;
pge->max_y = y2;
pge->current_y = y1;
pge->current_x = x1;
if ( dx >= 0 )
{
pge->x_direction = 1;
width = dx;
pge->error = 0;
}
else
{
pge->x_direction = -1;
width = -dx;
pge->error = 1 - pge->height;
}
pge->current_x_offset = dx / pge->height;
pge->error_offset = width % pge->height;
}
/*===========================================*/
/* convex polygon algorithm */
static uint8_t pg_inc(pg_struct *pg, uint8_t i)
{
i++;
if ( i >= pg->cnt )
i = 0;
return i;
}
static uint8_t pg_dec(pg_struct *pg, uint8_t i)
{
i--;
if ( i >= pg->cnt )
i = pg->cnt-1;
return i;
}
static void pg_expand_min_y(pg_struct *pg, pg_word_t min_y, uint8_t pge_idx)
{
uint8_t i = pg->pge[pge_idx].curr_idx;
for(;;)
{
i = pg->pge[pge_idx].next_idx_fn(pg, i);
if ( pg->list[i].y != min_y )
break;
pg->pge[pge_idx].curr_idx = i;
}
}
static uint8_t pg_prepare(pg_struct *pg)
{
pg_word_t max_y;
pg_word_t min_y;
uint8_t i;
/* setup the next index procedures */
pg->pge[PG_RIGHT].next_idx_fn = pg_inc;
pg->pge[PG_LEFT].next_idx_fn = pg_dec;
/* search for highest and lowest point */
max_y = pg->list[0].y;
min_y = pg->list[0].y;
pg->pge[PG_LEFT].curr_idx = 0;
for( i = 1; i < pg->cnt; i++ )
{
if ( max_y < pg->list[i].y )
{
max_y = pg->list[i].y;
}
if ( min_y > pg->list[i].y )
{
pg->pge[PG_LEFT].curr_idx = i;
min_y = pg->list[i].y;
}
}
/* calculate total number of scan lines */
pg->total_scan_line_cnt = max_y;
pg->total_scan_line_cnt -= min_y;
/* exit if polygon height is zero */
if ( pg->total_scan_line_cnt == 0 )
return 0;
/* if the minimum y side is flat, try to find the lowest and highest x points */
pg->pge[PG_RIGHT].curr_idx = pg->pge[PG_LEFT].curr_idx;
pg_expand_min_y(pg, min_y, PG_RIGHT);
pg_expand_min_y(pg, min_y, PG_LEFT);
/* check if the min side is really flat (depends on the x values) */
pg->is_min_y_not_flat = 1;
if ( pg->list[pg->pge[PG_LEFT].curr_idx].x != pg->list[pg->pge[PG_RIGHT].curr_idx].x )
{
pg->is_min_y_not_flat = 0;
}
else
{
pg->total_scan_line_cnt--;
if ( pg->total_scan_line_cnt == 0 )
return 0;
}
return 1;
}
static void pg_hline(pg_struct *pg, ucg_t *ucg)
{
pg_word_t x1, x2, y;
x1 = pg->pge[PG_LEFT].current_x;
x2 = pg->pge[PG_RIGHT].current_x;
y = pg->pge[PG_RIGHT].current_y;
if ( y < 0 )
return;
if ( y >= ucg_GetHeight(ucg) )
return;
if ( x1 < x2 )
{
if ( x2 < 0 )
return;
if ( x1 >= ucg_GetWidth(ucg) )
return;
if ( x1 < 0 )
x1 = 0;
if ( x2 >= ucg_GetWidth(ucg) )
x2 = ucg_GetWidth(ucg);
ucg_DrawHLine(ucg, x1, y, x2 - x1);
}
else
{
if ( x1 < 0 )
return;
if ( x2 >= ucg_GetWidth(ucg) )
return;
if ( x2 < 0 )
x1 = 0;
if ( x1 >= ucg_GetWidth(ucg) )
x1 = ucg_GetWidth(ucg);
ucg_DrawHLine(ucg, x2, y, x1 - x2);
}
}
static void pg_line_init(pg_struct * pg, uint8_t pge_index)
{
struct pg_edge_struct *pge = pg->pge+pge_index;
uint8_t idx;
pg_word_t x1;
pg_word_t y1;
pg_word_t x2;
pg_word_t y2;
idx = pge->curr_idx;
y1 = pg->list[idx].y;
x1 = pg->list[idx].x;
idx = pge->next_idx_fn(pg, idx);
y2 = pg->list[idx].y;
x2 = pg->list[idx].x;
pge->curr_idx = idx;
pge_Init(pge, x1, y1, x2, y2);
}
static void pg_exec(pg_struct *pg, ucg_t *ucg)
{
pg_word_t i = pg->total_scan_line_cnt;
/* first line is skipped if the min y line is not flat */
pg_line_init(pg, PG_LEFT);
pg_line_init(pg, PG_RIGHT);
if ( pg->is_min_y_not_flat != 0 )
{
pge_Next(&(pg->pge[PG_LEFT]));
pge_Next(&(pg->pge[PG_RIGHT]));
}
do
{
pg_hline(pg, ucg);
while ( pge_Next(&(pg->pge[PG_LEFT])) == 0 )
{
pg_line_init(pg, PG_LEFT);
}
while ( pge_Next(&(pg->pge[PG_RIGHT])) == 0 )
{
pg_line_init(pg, PG_RIGHT);
}
i--;
} while( i > 0 );
}
/*===========================================*/
/* API procedures */
void ucg_pg_ClearPolygonXY(pg_struct *pg)
{
pg->cnt = 0;
}
void ucg_pg_AddPolygonXY(pg_struct *pg, ucg_t *ucg, int16_t x, int16_t y)
{
if ( pg->cnt < PG_MAX_POINTS )
{
pg->list[pg->cnt].x = x;
pg->list[pg->cnt].y = y;
pg->cnt++;
}
}
void ucg_pg_DrawPolygon(pg_struct *pg, ucg_t *ucg)
{
if ( pg_prepare(pg) == 0 )
return;
pg_exec(pg, ucg);
}
pg_struct ucg_pg;
void ucg_ClearPolygonXY(void)
{
ucg_pg_ClearPolygonXY(&ucg_pg);
}
void ucg_AddPolygonXY(ucg_t *ucg, int16_t x, int16_t y)
{
ucg_pg_AddPolygonXY(&ucg_pg, ucg, x, y);
}
void ucg_DrawPolygon(ucg_t *ucg)
{
ucg_pg_DrawPolygon(&ucg_pg, ucg);
}
void ucg_DrawTriangle(ucg_t *ucg, int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2)
{
ucg_ClearPolygonXY();
ucg_AddPolygonXY(ucg, x0, y0);
ucg_AddPolygonXY(ucg, x1, y1);
ucg_AddPolygonXY(ucg, x2, y2);
ucg_DrawPolygon(ucg);
}
void ucg_DrawTetragon(ucg_t *ucg, int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t x3, int16_t y3)
{
ucg_ClearPolygonXY();
ucg_AddPolygonXY(ucg, x0, y0);
ucg_AddPolygonXY(ucg, x1, y1);
ucg_AddPolygonXY(ucg, x2, y2);
ucg_AddPolygonXY(ucg, x3, y3);
ucg_DrawPolygon(ucg);
}

View File

@ -1,256 +0,0 @@
/*
ucg_rotate.c
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
#include <assert.h>
/* Side-Effects: Update dimension and reset clip range to max */
void ucg_UndoRotate(ucg_t *ucg)
{
if ( ucg->rotate_chain_device_cb != NULL )
{
ucg->device_cb = ucg->rotate_chain_device_cb;
ucg->rotate_chain_device_cb = NULL;
}
ucg_GetDimension(ucg);
ucg_SetMaxClipRange(ucg);
}
/*================================================*/
/* 90 degree */
static void ucg_rotate_90_xy(ucg_xy_t *xy, ucg_int_t display_width)
{
ucg_int_t x, y;
y = xy->x;
x = display_width;
x -= xy->y;
x--;
xy->x = x;
xy->y = y;
}
ucg_int_t ucg_dev_rotate90(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_GET_DIMENSION:
ucg->rotate_chain_device_cb(ucg, msg, &(ucg->rotate_dimension));
((ucg_wh_t *)data)->h = ucg->rotate_dimension.w;
((ucg_wh_t *)data)->w = ucg->rotate_dimension.h;
//printf("rw=%d rh=%d\n", ucg->rotate_dimension.w, ucg->rotate_dimension.h);
//printf("aw=%d ah=%d\n", ((ucg_wh_t volatile * volatile )data)->w, ((ucg_wh_t volatile * volatile )data)->h);
//printf("dw=%d dh=%d\n", ucg->dimension.w, ucg->dimension.h);
return 1;
case UCG_MSG_SET_CLIP_BOX:
/* to rotate the box, the lower left corner will become the new xy value pair */
/* so the unrotated lower left is put into "ul" */
//printf("pre clipbox x=%d y=%d\n", ((ucg_box_t * )data)->ul.x, ((ucg_box_t * )data)->ul.y);
((ucg_box_t * )data)->ul.y += ((ucg_box_t * )data)->size.h-1;
//printf("pre clipbox lower left x=%d y=%d\n", ((ucg_box_t * )data)->ul.x, ((ucg_box_t * )data)->ul.y);
/* then apply rotation */
ucg_rotate_90_xy(&(((ucg_box_t * )data)->ul), ucg->rotate_dimension.w);
/* finally, swap dimensions */
{
ucg_int_t tmp;
tmp = ((ucg_box_t *)data)->size.w;
((ucg_box_t * )data)->size.w = ((ucg_box_t *)data)->size.h;
((ucg_box_t * )data)->size.h = tmp;
}
//printf("post clipbox x=%d y=%d\n", ((ucg_box_t * )data)->ul.x, ((ucg_box_t * )data)->ul.y);
break;
case UCG_MSG_DRAW_PIXEL:
case UCG_MSG_DRAW_L90FX:
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
#endif /* UCG_MSG_DRAW_L90BF */
case UCG_MSG_DRAW_L90SE:
//case UCG_MSG_DRAW_L90RL:
ucg->arg.dir+=1;
ucg->arg.dir&=3;
//ucg_rotate_90_xy(&(ucg->arg.pixel.pos), ucg->rotate_dimension.w);
//printf("dw=%d dh=%d\n", ucg->dimension.w, ucg->dimension.h);
//printf("pre x=%d y=%d\n", ucg->arg.pixel.pos.x, ucg->arg.pixel.pos.y);
ucg_rotate_90_xy(&(ucg->arg.pixel.pos), ucg->rotate_dimension.w);
//printf("post x=%d y=%d\n", ucg->arg.pixel.pos.x, ucg->arg.pixel.pos.y);
break;
}
return ucg->rotate_chain_device_cb(ucg, msg, data);
}
/* Side-Effects: Update dimension and reset clip range to max */
void ucg_SetRotate90(ucg_t *ucg)
{
ucg_UndoRotate(ucg);
ucg->rotate_chain_device_cb = ucg->device_cb;
ucg->device_cb = ucg_dev_rotate90;
ucg_GetDimension(ucg);
ucg_SetMaxClipRange(ucg);
}
/*================================================*/
/* 180 degree */
static void ucg_rotate_180_xy(ucg_t *ucg, ucg_xy_t *xy)
{
ucg_int_t x, y;
y = ucg->rotate_dimension.h;
y -= xy->y;
y--;
xy->y = y;
x = ucg->rotate_dimension.w;
x -= xy->x;
x--;
xy->x = x;
}
ucg_int_t ucg_dev_rotate180(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_GET_DIMENSION:
ucg->rotate_chain_device_cb(ucg, msg, &(ucg->rotate_dimension));
*((ucg_wh_t *)data) = (ucg->rotate_dimension);
return 1;
case UCG_MSG_SET_CLIP_BOX:
/* calculate and rotate lower right point of the clip box */
((ucg_box_t * )data)->ul.y += ((ucg_box_t * )data)->size.h-1;
((ucg_box_t * )data)->ul.x += ((ucg_box_t * )data)->size.w-1;
ucg_rotate_180_xy(ucg, &(((ucg_box_t * )data)->ul));
/* box dimensions are the same */
break;
case UCG_MSG_DRAW_PIXEL:
case UCG_MSG_DRAW_L90FX:
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
#endif /* UCG_MSG_DRAW_L90BF */
case UCG_MSG_DRAW_L90SE:
//case UCG_MSG_DRAW_L90RL:
ucg->arg.dir+=2;
ucg->arg.dir&=3;
ucg_rotate_180_xy(ucg, &(ucg->arg.pixel.pos));
break;
}
return ucg->rotate_chain_device_cb(ucg, msg, data);
}
/* Side-Effects: Update dimension and reset clip range to max */
void ucg_SetRotate180(ucg_t *ucg)
{
ucg_UndoRotate(ucg);
ucg->rotate_chain_device_cb = ucg->device_cb;
ucg->device_cb = ucg_dev_rotate180;
ucg_GetDimension(ucg);
ucg_SetMaxClipRange(ucg);
}
/*================================================*/
/* 270 degree */
static void ucg_rotate_270_xy(ucg_t *ucg, ucg_xy_t *xy)
{
ucg_int_t x, y;
x = xy->y;
y = ucg->rotate_dimension.h;
y -= xy->x;
y--;
xy->y = y;
xy->x = x;
}
ucg_int_t ucg_dev_rotate270(ucg_t *ucg, ucg_int_t msg, void *data)
{
switch(msg)
{
case UCG_MSG_GET_DIMENSION:
ucg->rotate_chain_device_cb(ucg, msg, &(ucg->rotate_dimension));
((ucg_wh_t *)data)->h = ucg->rotate_dimension.w;
((ucg_wh_t *)data)->w = ucg->rotate_dimension.h;
return 1;
case UCG_MSG_SET_CLIP_BOX:
/* calculate and rotate upper right point of the clip box */
((ucg_box_t * )data)->ul.x += ((ucg_box_t * )data)->size.w-1;
ucg_rotate_270_xy(ucg, &(((ucg_box_t * )data)->ul));
/* finally, swap dimensions */
{
ucg_int_t tmp;
tmp = ((ucg_box_t *)data)->size.w;
((ucg_box_t * )data)->size.w = ((ucg_box_t *)data)->size.h;
((ucg_box_t * )data)->size.h = tmp;
}
break;
case UCG_MSG_DRAW_PIXEL:
case UCG_MSG_DRAW_L90FX:
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
#endif /* UCG_MSG_DRAW_L90BF */
case UCG_MSG_DRAW_L90SE:
// case UCG_MSG_DRAW_L90RL:
ucg->arg.dir+=3;
ucg->arg.dir&=3;
ucg_rotate_270_xy(ucg, &(ucg->arg.pixel.pos));
break;
}
return ucg->rotate_chain_device_cb(ucg, msg, data);
}
/* Side-Effects: Update dimension and reset clip range to max */
void ucg_SetRotate270(ucg_t *ucg)
{
ucg_UndoRotate(ucg);
ucg->rotate_chain_device_cb = ucg->device_cb;
ucg->device_cb = ucg_dev_rotate270;
ucg_GetDimension(ucg);
ucg_SetMaxClipRange(ucg);
}

View File

@ -1,226 +0,0 @@
/*
ucg_scale.c
Universal uC Color Graphics Library
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.
*/
#include "ucg.h"
void ucg_UndoScale(ucg_t *ucg)
{
if ( ucg->scale_chain_device_cb != NULL )
{
ucg->device_cb = ucg->scale_chain_device_cb;
ucg->scale_chain_device_cb = NULL;
}
ucg_GetDimension(ucg);
ucg_SetMaxClipRange(ucg);
}
const ucg_fntpgm_uint8_t ucg_scale_2x2[16] UCG_FONT_SECTION("ucg_scale_2x2") =
{ 0x00, 0x03, 0x0c, 0x0f, 0x30, 0x33, 0x3c, 0x3f, 0xc0, 0xc3, 0xcc, 0xcf, 0xf0, 0xf3, 0xfc, 0xff };
static void ucg_scale_2x2_send_next_half_byte(ucg_t *ucg, ucg_xy_t *xy, ucg_int_t msg, ucg_int_t len, ucg_int_t dir, uint8_t b)
{
b &= 15;
len *=2;
ucg->arg.pixel.pos = *xy;
switch(dir)
{
case 0: break;
case 1: break;
case 2: ucg->arg.pixel.pos.x++; break;
default: case 3: ucg->arg.pixel.pos.y++; break;
}
ucg->arg.bitmap = ucg_scale_2x2+b;
ucg->arg.len = len;
ucg->arg.dir = dir;
ucg->scale_chain_device_cb(ucg, msg, &(ucg->arg));
ucg->arg.pixel.pos = *xy;
switch(dir)
{
case 0: ucg->arg.pixel.pos.y++; break;
case 1: ucg->arg.pixel.pos.x++; break;
case 2: ucg->arg.pixel.pos.y++; ucg->arg.pixel.pos.x++; break;
default: case 3: ucg->arg.pixel.pos.x++; ucg->arg.pixel.pos.y++; break;
}
ucg->arg.bitmap = ucg_scale_2x2+b;
ucg->arg.len = len;
ucg->arg.dir = dir;
ucg->scale_chain_device_cb(ucg, msg, &(ucg->arg));
switch(dir)
{
case 0: xy->x+=len; break;
case 1: xy->y+=len; break;
case 2: xy->x-=len; break;
default: case 3: xy->y-=len; break;
}
}
ucg_int_t ucg_dev_scale2x2(ucg_t *ucg, ucg_int_t msg, void *data)
{
ucg_xy_t xy;
ucg_int_t len;
ucg_int_t dir;
switch(msg)
{
case UCG_MSG_GET_DIMENSION:
ucg->scale_chain_device_cb(ucg, msg, data);
((ucg_wh_t *)data)->h /= 2;
((ucg_wh_t *)data)->w /= 2;
//printf("rw=%d rh=%d\n", ucg->rotate_dimension.w, ucg->rotate_dimension.h);
//printf("aw=%d ah=%d\n", ((ucg_wh_t volatile * volatile )data)->w, ((ucg_wh_t volatile * volatile )data)->h);
//printf("dw=%d dh=%d\n", ucg->dimension.w, ucg->dimension.h);
return 1;
case UCG_MSG_SET_CLIP_BOX:
((ucg_box_t * )data)->ul.y *= 2;
((ucg_box_t * )data)->ul.x *= 2;
((ucg_box_t * )data)->size.h *= 2;
((ucg_box_t * )data)->size.w *= 2;
//printf("post clipbox x=%d y=%d\n", ((ucg_box_t * )data)->ul.x, ((ucg_box_t * )data)->ul.y);
break;
case UCG_MSG_DRAW_PIXEL:
xy = ucg->arg.pixel.pos;
ucg->arg.pixel.pos.x *= 2;
ucg->arg.pixel.pos.y *= 2;
ucg->scale_chain_device_cb(ucg, msg, data);
ucg->arg.pixel.pos.x++;
ucg->scale_chain_device_cb(ucg, msg, data);
ucg->arg.pixel.pos.y++;
ucg->scale_chain_device_cb(ucg, msg, data);
ucg->arg.pixel.pos.x--;
ucg->scale_chain_device_cb(ucg, msg, data);
ucg->arg.pixel.pos = xy;
return 1;
case UCG_MSG_DRAW_L90SE:
case UCG_MSG_DRAW_L90FX:
xy = ucg->arg.pixel.pos;
len = ucg->arg.len;
dir = ucg->arg.dir;
ucg->arg.pixel.pos.x *= 2;
ucg->arg.pixel.pos.y *= 2;
switch(dir)
{
case 0: break;
case 1: break;
case 2: ucg->arg.pixel.pos.x++; break;
default: case 3: ucg->arg.pixel.pos.y++; break;
}
ucg->arg.len *= 2;
ucg->scale_chain_device_cb(ucg, msg, data);
ucg->arg.pixel.pos = xy;
ucg->arg.pixel.pos.x *= 2;
ucg->arg.pixel.pos.y *= 2;
ucg->arg.len = len*2;
ucg->arg.dir = dir;
switch(dir)
{
case 0: ucg->arg.pixel.pos.y++; break;
case 1: ucg->arg.pixel.pos.x++; break;
case 2: ucg->arg.pixel.pos.y++; ucg->arg.pixel.pos.x++; break;
default: case 3: ucg->arg.pixel.pos.x++; ucg->arg.pixel.pos.y++; break;
}
ucg->scale_chain_device_cb(ucg, msg, data);
ucg->arg.pixel.pos = xy;
ucg->arg.len = len;
ucg->arg.dir = dir;
return 1;
#ifdef UCG_MSG_DRAW_L90TC
case UCG_MSG_DRAW_L90TC:
#endif /* UCG_MSG_DRAW_L90TC */
#ifdef UCG_MSG_DRAW_L90BF
case UCG_MSG_DRAW_L90BF:
#endif /* UCG_MSG_DRAW_L90BF */
#if defined(UCG_MSG_DRAW_L90TC) || defined(UCG_MSG_DRAW_L90BF)
xy = ucg->arg.pixel.pos;
len = ucg->arg.len;
dir = ucg->arg.dir;
ucg->arg.pixel.pos.x *= 2;
ucg->arg.pixel.pos.y *= 2;
{
const unsigned char *b = ucg->arg.bitmap;
ucg_xy_t my_xy = ucg->arg.pixel.pos;
ucg_int_t i;
for( i = 8; i < len; i+=8 )
{
ucg_scale_2x2_send_next_half_byte(ucg, &my_xy, msg, 4, dir, ucg_pgm_read(b)>>4);
ucg_scale_2x2_send_next_half_byte(ucg, &my_xy, msg, 4, dir, ucg_pgm_read(b));
b+=1;
}
i = len+8-i;
if ( i > 4 )
{
ucg_scale_2x2_send_next_half_byte(ucg, &my_xy, msg, 4, dir, ucg_pgm_read(b)>>4);
ucg_scale_2x2_send_next_half_byte(ucg, &my_xy, msg, i-4, dir, ucg_pgm_read(b));
}
else
{
ucg_scale_2x2_send_next_half_byte(ucg, &my_xy, msg, i, dir, ucg_pgm_read(b)>>4);
}
}
ucg->arg.pixel.pos = xy;
ucg->arg.len = len;
ucg->arg.dir = dir;
return 1;
#endif
}
return ucg->scale_chain_device_cb(ucg, msg, data);
}
/* Side-Effects: Update dimension and reset clip range to max */
void ucg_SetScale2x2(ucg_t *ucg)
{
ucg_UndoScale(ucg);
ucg->scale_chain_device_cb = ucg->device_cb;
ucg->device_cb = ucg_dev_scale2x2;
ucg_GetDimension(ucg);
ucg_SetMaxClipRange(ucg);
}

File diff suppressed because it is too large Load Diff

View File

@ -33,77 +33,70 @@
#include "user_exceptions.h"
#define LOAD_MASK 0x00f00fu
#define L8UI_MATCH 0x000002u
#define L16UI_MATCH 0x001002u
#define L16SI_MATCH 0x009002u
static exception_handler_fn load_store_handler;
void load_non_32_wide_handler (struct exception_frame *ef, uint32_t cause)
{
/* If this is not EXCCAUSE_LOAD_STORE_ERROR you're doing it wrong! */
(void)cause;
uint32_t epc1 = ef->epc;
uint32_t excvaddr;
uint32_t insn;
uint32_t val, insn;
(void)cause; /* If this is not EXCCAUSE_LOAD_STORE_ERROR you're doing it wrong! */
asm (
"rsr %0, EXCVADDR;" /* read out the faulting address */
"movi a4, ~3;" /* prepare a mask for the EPC */
"and a4, a4, %2;" /* apply mask for 32bit aligned base */
"l32i a5, a4, 0;" /* load part 1 */
"l32i a6, a4, 4;" /* load part 2 */
"ssa8l %2;" /* set up shift register for src op */
"src %1, a6, a5;" /* right shift to get faulting instruction */
:"=r"(excvaddr), "=r"(insn)
:"r"(epc1)
:"a4", "a5", "a6"
);
/*
* Move the aligned content of the exception addr to val
*/
"rsr a6, EXCVADDR;" /* read out the faulting address */
"movi a5, ~3;" /* prepare a mask for the EPC */
"and a5, a5, a6;" /* apply mask for 32bit aligned base */
"l32i a5, a5, 0;" /* load aligned value */
"ssa8l a6;" /* set up shift register for value */
"srl %[val], a5;" /* shift left to align value */
/* we are done with a6 = EXCVADDR */
/*
* Move the aligned instruction to insn
*/
"movi a5, ~3;" /* prepare a mask for the insn */
"and a6, a5, %[epc];" /* apply mask for 32bit aligned base */
"l32i a5, a6, 0;" /* load part 1 */
"l32i a6, a6, 4;" /* load part 2 */
"ssa8l %[epc];" /* set up shift register for src op */
"src %[op], a6, a5;" /* right shift to get faulting instruction */
:[val]"=r"(val), [op]"=r"(insn)
:[epc]"r"(ef->epc)
:"a5", "a6"
);
uint32_t valmask = 0;
uint32_t what = insn & LOAD_MASK;
/* These instructions have the format 0xADSBII where AB = opcode and D = dest reg */
uint32_t regno = (insn>>4)&0x0f; /* pick out nibble D*/
uint32_t opcode = (uint8_t) (((insn>>12)<<4)|(insn&0xf)); /* and nibbles AB */
#define L8UI 0x02u
#define L16UI 0x12u
#define L16SI 0x92u
if (what == L8UI_MATCH)
valmask = 0xffu;
else if (what == L16UI_MATCH || what == L16SI_MATCH)
valmask = 0xffffu;
else
{
die:
/* Turns out we couldn't fix this, so try and chain to the handler
* that was set. (This is typically a remote GDB break). If none
* then trigger a system break instead and hang if the break doesn't
* get handled. This is effectively what would happen if the default
* handler was installed. */
if (load_store_handler) {
load_store_handler(ef, cause);
return;
if (opcode == L8UI) { /* L8UI */
val = (uint8_t) val;
} else {
val = (uint16_t) val; /* assume L16SI or L16UI */
if (opcode == L16SI) {
val = (unsigned)((int)((sint16_t)val)); /* force signed 16->32 bit */
} else if (opcode != L16UI) {
/*
* Anything other than L8UI, L16SI or L16UI then chain to the next handler
* if set (typically a remote GDB break). Otherwise execute the default action
* which is to trigger a system break and hang if the break doesn't get handled
*/
if (load_store_handler) {
load_store_handler(NULL, 0 /* ef , cause */);
return;
} else {
asm ("break 1, 1");
while (1) {}
}
}
asm ("break 1, 1");
while (1) {}
}
/* Load, shift and mask down to correct size */
uint32_t val = (*(uint32_t *)(excvaddr & ~0x3));
val >>= (excvaddr & 0x3) * 8;
val &= valmask;
/* Sign-extend for L16SI, if applicable */
if (what == L16SI_MATCH && (val & 0x8000))
val |= 0xffff0000;
int regno = (insn & 0x0000f0u) >> 4;
if (regno == 1)
goto die; /* we can't support loading into a1, just die */
else if (regno != 0)
--regno; /* account for skipped a1 in exception_frame */
ef->a_reg[regno] = val; /* carry out the load */
ef->epc += 3; /* resume at following instruction */
}
ef->a_reg[regno ? regno-1: regno] = val; /* carry out the load */
ef->epc += 3; /* resume at following instruction */
}
/**
* The SDK's user_main function installs a debugging handler regardless
* of whether there's a proper handler installed for EXCCAUSE_LOAD_STORE_ERROR,

45
app/uzlib/Makefile Normal file
View File

@ -0,0 +1,45 @@
#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
ifndef PDIR
GEN_LIBS = libuzlib.a
SUBDIRS = host
endif
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#DEFINES +=
#############################################################
# Recursion Magic - Don't touch this!!
#
# Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up
# its parent path, and not its siblings
#
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
INCLUDES += -I ../libc
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile

Some files were not shown because too many files have changed in this diff Show More