mirror of
https://github.com/nodemcu/nodemcu-firmware.git
synced 2025-01-30 21:12:55 +08:00
commit
11592951b9
6
.gitignore
vendored
6
.gitignore
vendored
@ -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
3
.gitmodules
vendored
@ -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
|
||||
|
@ -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
|
||||
|
32
Makefile
32
Makefile
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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)"
|
||||
|
@ -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) \
|
||||
|
@ -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) \
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -46,6 +46,7 @@ INCLUDES += -I ../spiffs
|
||||
INCLUDES += -I ../libc
|
||||
INCLUDES += -I ../modules
|
||||
INCLUDES += -I ../platform
|
||||
INCLUDES += -I ../uzlib
|
||||
PDIR := ../$(PDIR)
|
||||
sinclude $(PDIR)Makefile
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
#include "lrotable.h"
|
||||
#include "lstring.h"
|
||||
#include "lflash.h"
|
||||
#include "user_modules.h"
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
472
app/lua/lflash.c
472
app/lua/lflash.c
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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));
|
||||
|
@ -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);}
|
||||
|
@ -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);
|
||||
|
@ -15,7 +15,6 @@
|
||||
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
#include "lrotable.h"
|
||||
|
||||
#undef PI
|
||||
#define PI (3.14159265358979323846)
|
||||
|
@ -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] */
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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)
|
||||
|
||||
|
@ -15,7 +15,6 @@
|
||||
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
#include "lrotable.h"
|
||||
|
||||
/* macro to `unsign' a character */
|
||||
#define uchar(c) ((unsigned char)(c))
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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[];
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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 {
|
||||
|
@ -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" );
|
||||
|
@ -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
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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:
|
||||
|
129
app/platform/ucg_nodemcu_hal.c
Normal file
129
app/platform/ucg_nodemcu_hal.c
Normal 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 */
|
17
app/platform/ucg_nodemcu_hal.h
Normal file
17
app/platform/ucg_nodemcu_hal.h
Normal 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
|
@ -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
1
app/ucglib/ucg
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit e21641a6c1ddb0e71f7b9e01501fa739786c68b1
|
2164
app/ucglib/ucg.h
2164
app/ucglib/ucg.h
File diff suppressed because it is too large
Load Diff
@ -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
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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));
|
||||
}
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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
@ -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
45
app/uzlib/Makefile
Normal 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
Loading…
x
Reference in New Issue
Block a user